Thread (1 message) 1 message, 1 author, 2016-06-15

Default expectation of --lockref

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:58:10

I think the use of "reverse tracking" is way overrated.  It is
probably the only default value that we could use, if the user is
too lazy not to specify it, but I do not think it is particularly a
sensible or safe default.

The following does not discuss "should --lockref automatically
disable the 'must fast-forward' check?".  The problem highlighted is
the same, regardless of the answer to that question.

After rebasing beyond what is already published, you try the
"lockref" push, e.g. (we assume you work on master and push back to
update master at your origin):

      $ git fetch
      $ git rebase -i @{u}~4 ;# rebase beyond what is there
      $ git push ;# of course this will not fast-forward
      $ git push --lockref

If somebody else pushed while you are working on the rebase, the
last step (one of the above push) will fail due to stale
expectation.  What now?

The user would want to keep the updated tip, so the first thing that
happens will always be

      $ git fetch
      $ git log ..@{u} ;# what will we be losing?

The right thing to do at this point is to rebase your 'master' again
on top of @{u}

      $ git rebase -i @{u}

before attempting to push back again.  If you do that, then you can
do another "lockref" push.

But the thing is, a novice who does not know what he is doing will
likely to do this:

      $ git push --lockref

      ... rejected due to stale expectation
      $ git fetch

You just have updated the lockref base, so if you did, without doing
anything else, 

      $ git push --lockref

then you will lose the updated contents.
We _might_ be able to use the reflog on refs/remotes/origin/master
to come up with a better default expectation.

We are pushing an updated master, and the commit at the tip of the
branch has a committer timestamp.  refs/remotes/origin/master should
at least have two reflog entries for it at this point.  The latest
one is our latest "git fetch" after the previous lockref push failed
(and we see somebody else updated the master at the origin).  One
before is the one we based our judgement that the rebased result can
replace it.  They both have timestamps for reflog updates.

So we _could_ use refs/remotes/origin/master@{$timestamp} where
the $timestamp is the committer timestamp of the tip of 'master'
we are pushing to replace the 'master' branch at 'origin'.

I do not particularly like this approach, though.  I do not
particulary like the "look at the tracking branch of what we are
updating" in the first place myself, because it requires you to have
such a tracking branch, but now with this, we will also require you
to have a reflog on such a tracking branch, too, which is even
worse.  And it is making it too complex and obscure, even though I
think the semantics would make sense.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help