Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git: fast-forward merge without touching the working tree

Tags:

git

merge

A common thing I do in git (especially when working allone on a project) is merging the current topic branch into the master branch with a fast-forward merge. What bothers me a bit is that I have to first checkout the master branch, which changes all changed files in the working tree back to their original state, and then merge the topic branch which sets the files to the new state again.

This causes my IDE to recompile all changed files since it sees that they have been touched, which is actually unnecessary, because the files' contents are the same as before as the same commit is checked out as before.

Is there some git magic to achieve the same result without git touching the working tree?

like image 972
jederik Avatar asked Sep 11 '25 15:09

jederik


1 Answers

There is a sneaky trick for this using git push.

Note that when you git push origin foo:foo, this calls up a second Git at your remote named origin, delivers to that Git any necessary commits and other Git objects, then asks the other Git: Please set your branch or tag foo to the same commit as mine. The other Git either says Yes, that's fine, I did it or No, that's not a fast-forward operation, I cannot do that without losing commits.1

This means that git push has within it the logic needed to detect whether something is a fast-forward operation. If only you could push your branch xyz to your own Git's branch master ... and in fact, you can!

git push . xyz:master

tells your Git to call itself—the remote . means "me, myself". Next, you send the other Git any commits you have that they don't. Since they are you, that's nothing at all, and goes really fast. :-) Last, it asks that they (i.e., you) set their (i.e., your) master to match your xyz, but only if that's a fast-forward operation on their (i.e., your) master.

All of this happens without changing anything else about your own Git repository. It's essentially a simple (although sneaky) way of testing: "is moving some branch name a fast-forward operation? if so, do it, if not, don't."


1This assumes there are no prohibited updates via pre-receive and update hooks. Such hooks could also reject a push, for some reason other than non-fast-forward.

like image 189
torek Avatar answered Sep 13 '25 04:09

torek