Subject: Re: [PATCH 7/7] push: document --lockref

From: Johannes Sixt <[email-masked]>
Date: Sat, 13 Jul 2013 08:52:42 +0200

Am 12.07.2013 23:19, schrieb Junio C Hamano:
> Johannes Sixt <[email-masked]> writes:
> 
>> We have three independent options that the user can choose in any
>> combination:
>>
>>  o --force given or not;
>>
>>  o --lockref semantics enabled or not;
>>
>>  o refspec with or without +;
>>
>> and these two orthogonal preconditions of the push
>>
>>  o push is fast-forward or it is not ("ff", "noff");
>>
>>  o the branch at the remote is at the expected rev or it is not
>>    ("match", "mismatch").
>>
>> Here is a table with the expected outcome. "ok" means that the push is
>> allowed(*), "fail" means that the push is denied. (Four more lines with
>> --force are omitted because they have "ok" in all spots.)
>>
>>                        ff   noff     ff      noff
>>                       match match mismatch mismatch
>>
>> --lockref +refspec     ok    ok    denied   denied
>> --lockref  refspec     ok  denied  denied   denied
> 
> I am confused with these.  The latter is the most typical:
> 
> 	git fetch
>         git checkout topic
>         git rebase topic
> 	git push --lockref topic
> 
> where we know it is "noff" already, and we just want to make sure
> that nobody mucked with our remote while we are rebasing.

Today (without --lockref), the above sequence would fail to push.
(Because there is no + and no --force.)

> If nobody updated the remote, why should this push be denied?  And in
> order to make it succeed, you need to force with +refspec or --force,
> but that would bypass match/mismatch safety, which makes the whole
> "make sure the other end is unchanged" safety meaningless, no?

I am suggesting that +refspec would *not* override the match/mismatch
safety, but --force would.

> 
>>           +refspec     ok    ok      ok       ok
> 
> This is traditional --force.
> 
>>            refspec     ok  denied    ok     denied
> 
> We are not asking for --lockref, so match/mismatch does not affect
> the outcome.

I think you are worried that a deviation from the principle that
+refspec == --force hurts current users. But I am arguing that this is
not the case because "current" users do not use --lockref. As you have
seen from the table, without --lockref there is *no change* in behavior.

I still have not seen an example where +refspec != --force would have
unexpected consequences. (The inequality is merely that +refspec fails
on mismatch when --lockref was also given while --force does not.)

>> Notice that without --lockref semantics enabled, +refspec and refspec
>> keep the current behavior.
> 
> But I do not think the above table with --lockref makes much sense.
> 
> Let's look at noff/match case.  That is the only interesting one.
> 
> This should fail:
> 
> 	git push topic
> 
> due to no-ff.

Yes.

> Your table above makes this fail:
> 
>         git push --lockref topic
> 
> and the user has to force it,

Of course.

> like this?
> 
> 	git push --lockref --force topic ;# or alternatively
>         git push --lockref +topic
> 
> Why is it even necessary?

Because it is no-ff. How do you achieve the push today (without
--lockref)? You use one of these two options. It does not change with
--lockref.

> If you make
> 
> 	git push --lockref topic
> 
> succeed in noff/match case, everything makes more sense to me.

Not to me, obviously ;)

> The --lockref option is merely a weaker form of --force but still a
> way to override the noff check.

No; --lockref only adds the check that the destination is at the
expected revision, but does *NOT* override the no-ff check. Why should
it? (This is not a rethoric question.)

(I think I said differently in an earlier messages, but back then things
were still blurry. The table in my previous message is what I mean.)

>  If the user wants to keep noff
> check, the user can simply choose not to use the option.

No. If the user wants to keep the no-ff check, she does not use the + in
the refspec and does not use --force. (Just like today.)

> Of course, that form should fail if "mismatch".  And then you can
> force it,
> 
> 	git push --force [--lockref] topic
> 
> As "--force" is "anything goes", it does not matter if you give the
> other option on the command line.

... or the + in the refsepc.

-- Hannes