-
-
Save wodka/0e75e036fb9ac1ca3077 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/php | |
<?php | |
/** | |
* GIT Merge Helper | |
* | |
* Installation: | |
* 1. Download / Clone this GIST https://gist.github.com/clops/3ac9cd6c42a66ba65101 into some directory | |
* 2. chmod a+x deploy.php | |
* 3. Add an alias into .bash_profile with a full path to the deploy.php script, mine is: | |
* alias deploy="~/dev/3ac9cd6c42a66ba65101/deploy.php" | |
* 4. Done! | |
* | |
* Usage: | |
* 1. Inside a GIT directory type: deploy | |
* 2. Follow on-screen instructions | |
* | |
* @author Alexey Kulikov <[email protected]> | |
* @since Aug 2014 | |
**/ | |
echo "+++++++++ \e[1mGIT P4T Console Deploy V 1.0\e[0m Author: AK +++++++++\n"; | |
/* 1. ---- COLLECT PARAMETER / USER INPUT --------------------------------------------- */ | |
//what is the branch name that needs to be merged? | |
if(!isset($_SERVER['argv'][1])){ | |
$branchName = readline("Enter branchname to merge: "); | |
}else{ | |
$branchName = $_SERVER['argv'][1]; | |
} | |
//what is the branch type (hotfix/bugfix/feature)? | |
$branchType = explode('/', $branchName); | |
if(count($branchType) != 2){ //yes this is not the full syntax check, branch name is checked for validity later | |
errorMessage("Incorrent branch name \"".$branchName."\", it must be of the form (hotfix|bugfix|feature)/ZEN-XXXXX"); | |
} | |
//is there some special destination or are we doing a special deployment-merge | |
if(!isset($_SERVER['argv'][2])){ | |
$mergeIntoBranchName = trim(readline("Enter branchname to merge into (leave empty for default master/release/development merge): ")); | |
}else{ | |
$mergeIntoBranchName = $_SERVER['argv'][2]; | |
} | |
/* 2. ---- REMEMBER STARTING POINT ---------------------------------------------------- */ | |
//first step --> remember the currently selected branch and stash any changes made | |
$currentState = `git status --porcelain -b`; | |
$currentState = explode("\n", $currentState); | |
$currentBranch = trim(str_replace('##','',$currentState[0])); | |
$currentBranch = explode('...', $currentBranch); | |
$currentBranch = $currentBranch[0]; //weird :) | |
$stashed = false; | |
if(isset($currentState[1]) && !empty($currentState[1])){ //any modified files? stash them! | |
echo "Stashing unsaved changes away...\n"; | |
echo `git stash`; | |
$stashed = true; | |
} | |
/* 3. ---- SOME BASIC ERROR CHECKS ---------------------------------------------------- */ | |
//lets roll | |
$branchType = $branchType[0]; | |
echo "Will deploy branch \"".$branchName."\", of type \"".$branchType."\"\n"; | |
echo "Pulling fresh branch list from origin... "; | |
echo `git pull`; //refresh list of branches | |
//now check if the desired branch that has to be merged exists at all | |
$existingBranches = getBranches(); | |
if(!in_array($branchName, $existingBranches)){ | |
errorMessage("Branch \"".$branchName."\" does NOT exist!"); | |
} | |
//we also defined a destination branch? check is also then | |
if(!empty($mergeIntoBranchName)){ | |
if(!in_array($mergeIntoBranchName, $existingBranches)){ | |
errorMessage("Destination Branch \"".$mergeIntoBranchName."\" does NOT exist!"); | |
} | |
//set special marker for a manual A->B merge | |
$branchType = 'manual'; | |
} | |
/* 4. ---- ACTUAL MERGING ------------------------------------------------------------- */ | |
//make sure we have the desired branch locally (needed for merge) | |
echo "Checking out branch \"{$branchName}\"\n"; | |
echo `git checkout {$branchName}`; | |
switch($branchType){ | |
case 'hotfix': { | |
if(!mergeBranch($branchName, 'master')){ | |
errorMessage("Merge Terminated manually"); | |
} | |
} | |
case 'bugfix': { | |
if($currentReleaseBranch = getCurrentReleaseBranch()){ | |
if(!mergeBranch($branchName, $currentReleaseBranch)){ | |
errorMessage("Merge Terminated manually"); | |
} | |
}else{ | |
echo "There is no current release branch, skipping\n"; | |
} | |
} | |
case 'feature': { | |
if(!mergeBranch($branchName, 'development')){ | |
errorMessage("Merge Terminated manually"); | |
} | |
break; | |
} | |
case 'manual': { //this is a special type denoting a merge into a user-defined branch | |
if(!mergeBranch($branchName, $mergeIntoBranchName)){ | |
errorMessage("Merge Terminated manually"); | |
} | |
break; | |
} | |
default: { | |
errorMessage("Unknown branch type \"".$branchType."\", possible types are \"hotfix\", \"bugfix\" or \"feature\""); | |
} | |
} | |
//no errors, great! remove remote branch, its been merged everywhere %) | |
$confirm = readline("\n\e[92mRemove branch from origin? Confirm with \"Y\", any other input to skip:\e[0m "); | |
if($confirm == 'Y'){ | |
echo "Removing branch from origin..."; | |
echo `git push origin --delete {$branchName}`; | |
echo "done!\n"; | |
} | |
//switch back to the original branch | |
if($currentBranch != 'development'){ | |
echo "Switching back to the initial branch\n"; | |
echo `git checkout {$currentBranch}`; | |
} | |
//anything stashed away before? | |
if($stashed){ | |
echo "Getting back stashed changes...\n"; | |
echo `git stash pop`; | |
} | |
echo "FIN!\n\n"; | |
###################### UTILITY HELPER FUNCTIONS BELOW ###################### | |
/** | |
* Utility function: Merge a source branch into the destination branch | |
* | |
* @param String $source | |
* @param String $destination | |
**/ | |
function mergeBranch($source, $destination){ | |
echo "\n+++++++++ \e[1mMerging ".$source." --> ".$destination."\e[0m +++++++++\n"; | |
echo "Checking out {$destination}\n"; | |
echo `git checkout {$destination}`; | |
echo `git pull`; | |
echo "Merging {$source}\n"; | |
echo `git merge {$source} `; | |
//now need the user to confirm this prior to pushing changes | |
$confirm = readline("\n\e[92mConfirm merge with \"Y\", any other input to terminate:\e[0m "); | |
if($confirm == 'Y'){ | |
echo `git push -u origin {$destination}`; | |
echo "\n\n"; | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Utility function: Echo error message and terminate script | |
* | |
* @param String $message | |
**/ | |
function errorMessage($message){ | |
echo "\n\e[31mERROR: ".$message.". Terminating\e[0m\n\n"; | |
exit; | |
} | |
/** | |
* Utility function: get a list of all known branches | |
* | |
* @return Array | |
**/ | |
function getBranches(){ | |
$branches = `git branch -a`; | |
$branches = explode("\n",$branches); | |
foreach($branches as &$branch){ | |
$branch = str_replace('remotes/origin/', '', trim($branch)); | |
} | |
return $branches; | |
} | |
/** | |
* Utility Function: get the current release branch from origin | |
* | |
* @return String | |
**/ | |
function getCurrentReleaseBranch(){ | |
$branches = `git branch -r --no-merged`; | |
$branches = explode("\n",$branches); | |
foreach($branches as $branch){ | |
$branch = trim($branch); | |
if(strstr($branch, 'origin/release/') !== false){ | |
return str_replace('origin/', '', $branch); | |
} | |
} | |
return false; | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the fix :)
btw, I have pushed V1.2 with more bugs fixed and some convenience options added!