Jeff King <p...@peff.net> writes: > I do think Dscho is on to something with the "see if it was ever in our > reflog" idea.
Yes, I found the idea was interesting when I responded with the "thinking aloud", and I still do think it has some uses elsewhere, even if not in "pull --rebase" workflow. > What you really want as a default for force-with-lease is > some way to say "I want to change that ref from X to Y, but only for > values of X that I know Y has already considered and incorporated". Correct. > But imagine force-with-lease rule were more like: when pushing > branch "foo" to remote branch "bar", allow only if the current value of > "bar" is an ancestor of some entry in the reflog of "foo". Would that cover the case that originally motivated the "with lease" thing? Let's see. BC "foo" / o---A---B---C "bar" You are pushing back to "bar" that still has C (or it may have acquired D) from "foo" that is now at BC. It is likely that you started to prepare the "A---BC" history from "A---B---C" history, in which case your current branch "foo" that is being pushed out would have had C at its tip some time in the past. So seeing that the tip of the remote is still C, which is in the reflog of "foo", we can happily push it out. If the tip of the remote "bar" is now D because somebody updated it, you did not consider it while preparing your BC, and we want to fail the push---because D does not appear in the reflog of "foo", that is achieved. > That degrades to the usual fast-forward rule if you just check the ref > tip. And when checking the reflog entries, it shows that at some point > you had your local branch set to something that covered all of the > destination, but then later rewound or rewrote history. We don't have to > care what that operation was. "rebase" is a likely one, but "git reset > --hard HEAD^ && git push" would fall out naturally from the same rule. > > It's not quite as safe as a true force-with-lease with a value would be. All correct. I wonder if this could be a replacement for the current "the user did not even specify what the expected current value is, so we pretend as if the tip of the remote-tracking branch was given" kludge. Instead, git push --force-with-lease origin master git push --force-with-lease origin topic:master git push --force-with-lease origin HEAD:master could (1) first learn where 'refs/heads/master' over there is at. Call it X (it may be C or D in the earlier example). (2) locate from which ref the commit we are pushing out is taken; in the above examples, they are our refs/heads/master, refs/heads/topic, and HEAD, respectively. Call it R. (3) see if the reflog of R has X. If so do a --force push; otherwise fail. With such an update, I suspect that it would become a lot safer than relying on the stability of the remote tracking branch, which is what the current code does. As you said, this is not as safe as a true "the user knows and tells what commit was considered" force-with-lease, but can be a lot safer and can become a replacement for the current "the user does not tell and allows us to DWIM". A good thing is that the DWIM is advertised like so: ... are still experimental and their semantics may change so we are free to change it to any better version. And I think Dscho's idea could be that better one. I am still somewhat reserved because in the above, I only illustrated a case that would work better than the current one, without trying hard to poke a hole at the reasoning and to come up with cases that would work worse. But I agree that this is on to something good ;-)