Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do a non-fast-forward git merge to a branch that isn't checked out?

Tags:

git

I'm on branch a. I want to merge branch b into branch c. The merge is not a fast-forward, but it also doesn't require manual resolution. (i.e., it's not the simplest case, but it's also not the most difficult one, so it's a merge that Git is able to do on its own without needing a human.)

Is there a way for me to do this merge from b to c without having to check out any branch? How?

UPDATE: If you know of an alternative Git implementation that can do it, that would be a valid solution as well. But writing a script that would do the checkouts programmatically would not be a good solution, because it would still require me to have a clean working directory.

like image 502
Ram Rachum Avatar asked May 17 '12 14:05

Ram Rachum


1 Answers

If the merge doesn't involve files touched on both branches then I think you want git read-tree and git write-tree with a sideband GIT_INDEX_FILE. This should do it:

#!/bin/sh
export GIT_INDEX_FILE=.git/aux-merge-index
trap 'rm -f '"'$GIT_INDEX_FILE'" 0 1 2 3 15
set -e
git read-tree -im `git merge-base $2 $1` $2 $1
git write-tree \
| xargs -i@ git commit-tree @ -p $2 -p $1 -m "Merge $1 into $2" \
| xargs git update-ref -m"Merge $1 into $2" refs/heads/$2

You could also use git mktree </dev/null instead of the merge-base to treat b and c as entirely unrelated branches and make the resulting merge combine the files in each rather than treating files missing in either as deletions.

You say your merge isn't a fast-forward, so you're going to need to read the read-tree docs to make the sequence above do exactly what you want. --aggressive looks like it might be right, it depends on what the actual differences between your branches are.

edit added the empty-tree base to handle unrelated trees edit 2 hoisting some payload I said or left implicit in a comment

like image 150
jthill Avatar answered Nov 01 '22 08:11

jthill