Re: [RFD] Making "git push [--force/--delete]" safer?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Johan Herland <johan@xxxxxxxxxxx> writes:

> Overnight, it occured to me that --force-if-expected could be
> simplified by leveraging the existing --force option; for the above
> two examples, respectively:
>
>   $ git push --force --expect
>   # validate foo @ origin == @{upstream} before pushing
>
> and
>
>   $ git push --force --expect=refs/original/foo my_remote HEAD:foo
>   # validate foo @ my_remote == refs/original/foo before pushing

First, on the name.

I do not think either "--validate" or "--expect" is particularly a
good one.  The former lets this feature squat on a good name that
covers a much broader spectrum, forbidding people from adding other
kinds of validation later.  "--expect" is slightly less bad in that
sense; saying "we expect this" does imply "otherwise it is an
unexpected situation and we would fail", but the name still does not
feel ideal.

What is the essense of compare-and-swap?  Perhaps we can find a good
word by thinking that question through.  

To me, it is a way to implement a "lock" on the remote ref without
actually taking a lock (which would leave us open for a stale lock),
and this "lock"-ness is what we want in order to guarantee safety.

So we could perhaps call it "--lockref"?

I'll leave the name open but tentatively use this name in the
following, primarily to see how well it sits on the command line
examples.

Then on the semantics/substance.

I had quite a similar thought as you had while reading your initial
response.  In the most generic form, we would want to be able to
pass necessary information fully via the option, i.e.

	--lockref=theirRefName:expectedValue

but when the option is spelled without details, we could fill in the
default values by making a reasonable guess of what the user could
have meant.  If we only have --lockref without refname nor value,
then we will enable the safety for _all_ refs that we are going to
update during this push.  If we have --lockref=theirRefName without
the expected value for that ref, we will enable the safety only for
the ref (you can give more than one --lockref=theirRefName), and
guess what value we should expect.  If we have a fully specified
option, we do not have to guess the value.

And for the expected value, when we have a tracking branch for the
branch at the remote we are trying to update, its value is a very
good guess of what the user meant.

Note, however, that this is very different from @{upstream}.

You could be pushing a branch "frotz", that is configured to
integrate with "master" taken from "origin", but

 (1) to a branch different from "master" of "origin", e.g.

	$ git push --lockref origin frotz:nitfol
	$ git push --lockref origin :nitfol	;# deleting

 (2) even to a branch of a remote that is different from "origin",
     e.g.

	$ git push --lockref xyzzy frotz:nitfol
	$ git push --lockref xyzzy :nitfol	;# deleting

Even in these case, if you have a remote tracking branch for the
destination (i.e. you have refs/remotes/origin/nitfol in case (1) or
refs/remotes/xyzzy/nitfol in case (2) to be updated by fetching from
origin or xyzzy), we can and should use that value as the default.

There is no room for frotz@{upstream} (or @{upstream} of the current
branch) to get in the picture.

Except when you happen to be pushing with "push.default = upstream",
that is.  But that is a natural consequence of the more generic
check with "our remote tracking branch of the branch we are updating
at the remote" rule.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]