Skip to content

Instantly share code, notes, and snippets.

@phpfunk
Last active May 2, 2017 18:42
Show Gist options
  • Save phpfunk/6089284 to your computer and use it in GitHub Desktop.
Save phpfunk/6089284 to your computer and use it in GitHub Desktop.
A command line PHP script to merge a git branch into multiple other git branches.
### Alias
alias gam='php /path/to/auto-merge.php'
#!/usr/bin/php
<?php
// Normalize data in all branches
$all_branches = explode(PHP_EOL, shell_exec('git branch'));
foreach ($all_branches as $k => $branch) {
$all_branches[$k] = trim(str_replace('*', '', $branch));
}
// Look for user submitted variables
// 1 = comma delimited list of branches to merge into (default is all branches other than production or master)
// 2 = branch to use to merge from (default will be master or production)
$local = (isset($argv[1]) && ! empty($argv[1])) ? explode(',', $argv[1]) : $all_branches;
$master = (isset($argv[2]) && ! empty($argv[2])) ? trim($argv[2]) : 'master';
// Set some other vars
$branches = array();
$conflict = false;
$remotes = explode(PHP_EOL, shell_exec('git remote'));
$remote = (isset($remotes[0]) && ! empty($remotes[0])) ? trim($remotes[0]) : null;
$remote = (empty($remote)) ? 'origin' : $remote;
// Loop thru branches to make final list to merge into
// Also find the master branch if not already submitted by the user
foreach ($local as $branch) {
if (($branch == 'production' || $branch == 'master') && (! isset($argv[2]) || empty($argv[2]))) {
$master = $branch;
}
elseif (! empty($branch)) {
array_push($branches, $branch);
}
}
// Figure if master branch used for merging even exists
if (! in_array($master, $all_branches)) {
print 'Fatal: The branch `' . $master . '` to be used for merging from does not exist.' . PHP_EOL;
exit(0);
}
// Check to make sure there is more than master branch
$self_merge = (count($branches) == 1 && $branches[0] == $master) ? true : false;
// If there are branches to merge into, make it happen
if (! empty($branches) && $self_merge === false) {
print 'Starting to auto-merge of `' . $master . '` into all other local branches...' . PHP_EOL;
foreach ($branches as $branch) {
// check to see if the branch we are checking out even exists
// If not, skip it
if (! in_array($branch, $all_branches)) {
print 'Notice: `' . $branch . '` does not exist, skipping merge for this branch.' . PHP_EOL;
}
elseif ($branch == $master) {
// Gracefully skip
// Can happen when merging into all branches
// while submitting your own master branch other than production or master
}
else {
print shell_exec('git checkout ' . $branch);
$output = shell_exec('git merge --no-ff ' . $master);
print $output;
if (strstr($output, 'CONFLICT')) {
$conflict = true;
print 'There were errors merging `' . $master . '` into `' . $branch . '`. Please fix these conflicts in `' . $branch . '` and update your other local branches if you care to.' . PHP_EOL;
exit(0);
}
else {
print shell_exec('git push ' . $remote . ' ' . $branch);
}
}
}
print 'Auto-merge complete...' . PHP_EOL;
}
else {
print 'Notice: Can\'t merge `' . $master . '` into itself silly.' . PHP_EOL;
}

Examples below will use the following branches:

  • master
  • staging
  • 123-new-docs
  • 127-bug-fix

The script will provide the output from git and also from the script. Any conflicts found will halt the script until you fix them.

Arguments

This command can accept two arguments:

  • comma-delimited list of branches to merge into (defaults to all branches other than master or production)
  • branch to merge from (defaults to production or master)

Default

Finds master branch (named production or master) and all other local branches. Merges master into other locals and pushes.

Example

$ gam

Starting to auto-merge of `master` into all other local branches...
Switched to branch '123-new-docs'
Already up-to-date.
Everything up-to-date
Switched to branch '127-bug-fix'
Already up-to-date.
Everything up-to-date
Switched to branch 'staging'
Already up-to-date.
Everything up-to-date
Auto-merge complete...

Selective Merge

This will merge the master branch found only into the branches you specify.

Example

As you will see if skips the staging branch this time.

$ gam "123-new-docs,127-bug-fix"

Starting to auto-merge of `master` into all other local branches...
Switched to branch '123-new-docs'
Already up-to-date.
Everything up-to-date
Switched to branch '127-bug-fix'
Already up-to-date.
Everything up-to-date
Auto-merge complete...

Merge from Custom Branch

This will merge a different branch (that you specify) into all other branches. You can use this if you want to merge a branch other than master or production.

Example

As you will see it uses 127-bug-fix to merge from this time.

$ gam "" "127-bug-fix"

Starting to auto-merge of `127-bug-fix` into all other local branches...
Switched to branch '123-new-docs'
Already up-to-date.
Everything up-to-date
Switched to branch 'master'
Already up-to-date.
Everything up-to-date
Switched to branch 'staging'
Already up-to-date.
Everything up-to-date
Auto-merge complete...

Selective Merge from Custom Branch

This will merge a custom branch into only the other branches you specify.

Example

As you will see it skips merging 127-bug-fix into the master branch.

$ gam "123-new-docs,staging" "127-bug-fix"

Starting to auto-merge of `127-bug-fix` into all other local branches...
Switched to branch '123-new-docs'
Already up-to-date.
Everything up-to-date
Switched to branch 'staging'
Already up-to-date.
Everything up-to-date
Auto-merge complete...

Errors

If the master branch to be used does not exist in your local branches the script will exit.

Example

$ gam "" "fail-branch"
Fatal: The branch `fail-branch` to be used for merging from does not exist.

Notices

A notice will display to terminal but not stop the process from running. These happen when trying to merge into a branch that does not exist or if trying to merge into master from master (only one branch in repo).

Example

$ gam "154-does-not-exist,staging"

Starting to auto-merge of `master` into all other local branches...
Notice: `154-does-not-exist` does not exist, skipping merge for this branch.
Already on 'staging'
Already up-to-date.
Everything up-to-date
Auto-merge complete...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment