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.