Jeff King <peff@xxxxxxxx> writes: > [1] Another sticking point is that this really does need to be in the > reflog of the ref we are pushing (and not, e.g., HEAD). But one does > not always push from a ref. I suspect that's OK in practice, though. > If you are doing "git push --force-with-lease HEAD~2:master", it is > probably OK for us to error out with "uh, lease from what?". I actually expect this to bite me personally, as I often do not rewind the actual "topic" ref that is my target of rewriting, because I am a chicken---I detach the HEAD and build a history there to see if I can come up with a better history, compare the result with what is on the "topic" (which is not touched at all during the rewriting), and after all is done, do a "checkout -B topic". The "remote tip must appear in the local reflog" rule will never be satisfied. >> 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. > > Yes, that is exactly what I was thinking of (and why I said that even > though this really isn't force-with-lease in a strict sense, it slots > into the same level of safety, so it might be worth using the name). > >> 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. > > Yes, more or less. A few thoughts: > > - that step 2 is where the "wait, that isn't even a ref" error above > would come in > > - I suspect in the third example we probably ought to be using the > reflog of the branch that HEAD points to. You would not want: > > $ git checkout advanced-branch $ git checkout older-branch $ git > push --force-with-lease origin HEAD:older-branch > > to consider that commits in advanced-branch are part of the lease. The third one was meant to be rewriting on detached HEAD, not having any underlying branch. > - For step 3, I'm not sure if we you mean to look for exactly X, or > if it would be OK to have any commit whose ancestor is X. I think > you'd need the latter to accommodate a non-fast-forward "git pull" > (or fetch+merge) where the local ref is never set precisely to the > upstream commit. But the result in that case is a descendant of upstream you just merged, so you do not even want to use any form of forcing---you would rather want to rely on the usual "push must fast-forward" mechanism, no?