Web lists-archives.com

Re: What's cooking in git.git (Jul 2017, #03; Mon, 10)

Jeff King <peff@xxxxxxxx> 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".


> 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


 (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 ;-)