I have the following scenario:
* ab82147 (HEAD, topic) changes
* 8993636 changes
* 82f4426 changes
* 18be5a3 (master) first
I’d like to merge (non fast-forward) topic into master. This requires me to:
git checkout mastergit merge --no-ff topic
But checking out master, and then merging topic into it causes git to change my working directory (although the final result is identical to the one before checking out master), and the problem I have with that is due to the size of our project, it takes about 30 minutes to build it (with IncrediBuild) although nothing really changed and it’s simply unbearable.
So what I would like to get is the following:
* 9075cf4 (HEAD, master) Merge branch 'topic'
|\
| * ab82147 (topic) changes
| * 8993636 changes
| * 82f4426 changes
|/
* 18be5a3 first
Without really touching the working directory (or at least cheating git somehow).
Interesting! I don’t think there’s a built-in way to do this, but you should be able to fudge it using the plumbing:
The interesting bit is that
newcommit=line; it uses commit-tree to directly create the merge commit. The first argument is the tree to use; that’s the tree HEAD, the branch whose contents you want to keep. The commit message is supplied on stdin, and the rest of the arguments name the parents the new commit should have. The commit’s SHA1 is printed to stdout, so assuming the commit succeeded, you capture that, then merge that commit (that’ll be a fast-forward). If you’re obsessive, you could make sure that commit-tree succeeded – but that should be pretty much guaranteed.Limitations:
--no-ff, git will actually force itself to use the default (recursive) strategy, but to write that in the reflog would be a lie.And yes, I tested this on a toy repo, and it appears to work properly! (Though I didn’t try hard to break it.)