git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Johan Herland <johan@herland.net>
Cc: git@vger.kernel.org
Subject: Re: [RFD] Making "git push [--force/--delete]" safer?
Date: Wed, 03 Jul 2013 12:48:39 -0700	[thread overview]
Message-ID: <7vvc4re86g.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <CALKQrge_REZKfds0T-owJOn2BvfLmHpk7yQeSog=yvofE_zKJQ@mail.gmail.com> (Johan Herland's message of "Wed, 3 Jul 2013 12:00:01 +0200")

Johan Herland <johan@herland.net> writes:

>> 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.
>
> I agree that neither --expect nor --validate are very good. I also
> don't like --lockref, mostly because there is no locking involved, and

Yes and no.

This is not compare-and-swap but is "store-conditional" step in
ll/sc.  It is letting other people's activities to break your lock
to prevent you from making an undesirable update.  So in that sense,
this mechanism is very much a lock.

> Some other suggestions:
>
> a) --update-if. I think this reads quite nicely in the fully specified
> variant: --update-if=theirRefName:expectedValue, but it becomes more
> cryptic when defaults are assumed (i.e. --update-if without any
> arguments).

This name is in line with the "store conditional" aspect of the
operation, but it, together with your --precond and --pre-verify,
share the same problem as your --validate.  This is only to check
one specific precondition "The remote ref being updated must point
at this object", but all the names you suggested are too broad.

If we were to go in the direction (3) I suggested in the original
message to let you specify an arbitrary script that reads the list
of proposed updates and decide to allow them, --update-if=script.sh
would be the ideal name for that option to specify the script to be
run, though. That mechanism is broad enough to deserve such a broad
name, if we were to go in that direction.

> b) --precond. This makes it clear that we're specifying a precondition
> on the push. Again, I think the fully specified version reads nicely,
> but it might seem a little cryptic when no arguments are given.

See above.

> c) --pre-verify, --pre-check are merely variations on (b), other
> variations include --pre-verify-ref or --pre-check-ref, making things
> more explicit at the cost of option name length.

See above.

> So, how do we deal with the various corner cases?

I thought I spelled out everything, but apparently I didn't.  Here
is what I had in mind.

 (1) A bare "--lockref" exists on the command line.  E.g.

     $ git push --lockref [remote [refspec]...] ;# nothing else about lockref

     This will apply to updates of _all_ refs to be updated (e.g.
     with "remote.origin.push = +refs/heads/pu:refs/heads/pu", the
     update of 'pu' at the origin will be rejected if 'pu' fails to
     pass the test) with this push.  We make sure

     - we have remote-tracking branch for the updated ref; if we do
       not have any, we *fail* the update.

     - the value of that remote-tracking branch is the same as what
       the remote advertises to "git push"; if they do not match, we
       *fail* the update.  This includes the case where there is no
       such ref at the remote (may have deleted while we are looking
       the other way).

 (2) Remote ref specified on one of the --lockref option(s).  E.g.

     $ git push --lockref=theirRef[:value] [remote [refspec]...]

     This will apply to updates of _only_ the refs given.  refs not
     covered by --lockref will follow the usual rule (i.e. with
     --force, anything goes, without --force, only fast-forward is
     allowed).  If ":value" is given, we will use it, otherwise we
     will try to find the remote tracking branch for the updated
     ref, just like a non-specific case as above.

     A --lockref=theirRef[:value] that specifies theirRef that is
     not being pushed will be _ignored_ and not checked, so that you
     could say

	[alias]
        	safepush = push --lockref=next
	[remote "origin"]
        	push = refs/heads/maint:refs/heads/maint
        	push = refs/heads/master:refs/heads/master
        	push = refs/heads/next:refs/heads/next
        	push = +refs/heads/pu:refs/heads/pu

     and then do

	$ git safepush origin +next

     after a major version bump to rewind 'next' but still do so
     with safety, while still allowing you to say

	$ git safepush origin maint

     to push out 'maint' without having to worry about --lockref=next
     getting in the way.

 (3) Mixing --lockref and --lockref=theirRef[:value].

     Apply (2) for refs we do have remote ref specified on
     --lockref, and apply (1) for other refs we are going to update.

In any case, this check happens after we learn the current value of
remote refs but before we propose what the updated values would be,
so we can afford to fail the entire push atomically.  We could only
fail the ones that do not pass the check and let others go, but I do
not think it is a good idea.

So in short, I think I agree with you on the semantics.

  parent reply	other threads:[~2013-07-03 19:48 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-02 20:57 [RFD] Making "git push [--force/--delete]" safer? Junio C Hamano
2013-07-02 22:55 ` Johan Herland
2013-07-03  6:34   ` Johan Herland
2013-07-03  8:49     ` Junio C Hamano
2013-07-03 10:00       ` Johan Herland
2013-07-03 10:06         ` Jonathan del Strother
2013-07-03 10:11           ` Johan Herland
2013-07-03 10:50             ` Michael Haggerty
2013-07-03 12:06               ` Johannes Sixt
2013-07-03 19:53                 ` Junio C Hamano
2013-07-04  5:37                   ` Johannes Sixt
2013-07-04  5:46                     ` Junio C Hamano
2013-07-03 19:50           ` Junio C Hamano
2013-07-03 20:18             ` Junio C Hamano
2013-07-03 19:48         ` Junio C Hamano [this message]
2013-07-09 19:53 ` [PATCH 0/7] safer "push --force" with compare-and-swap Junio C Hamano
2013-07-09 19:53   ` [PATCH 1/7] cache.h: move remote/connect API out of it Junio C Hamano
2013-07-09 19:53   ` [PATCH 2/7] builtin/push.c: use OPT_BOOL, not OPT_BOOLEAN Junio C Hamano
2013-07-09 19:53   ` [PATCH 3/7] push: beginning of compare-and-swap "force/delete safety" Junio C Hamano
2013-07-09 19:53   ` [PATCH 4/7] remote.c: add command line option parser for --lockref Junio C Hamano
2013-07-16 22:13     ` John Keeping
2013-07-17 17:06       ` Junio C Hamano
2013-07-17 17:09       ` Junio C Hamano
2013-07-09 19:53   ` [PATCH 5/7] push --lockref: implement logic to populate old_sha1_expect[] Junio C Hamano
2013-07-09 19:53   ` [PATCH 6/7] t5533: test "push --lockref" Junio C Hamano
2013-07-09 19:53   ` [PATCH 7/7] push: document --lockref Junio C Hamano
2013-07-09 20:17     ` Aaron Schrab
2013-07-09 20:39       ` Junio C Hamano
2013-07-09 20:24     ` Johannes Sixt
2013-07-09 20:37       ` Junio C Hamano
2013-07-09 20:55         ` Johannes Sixt
2013-07-09 22:09           ` Junio C Hamano
2013-07-09 23:08             ` Junio C Hamano
2013-07-11 21:10               ` Johannes Sixt
2013-07-11 21:57                 ` Junio C Hamano
2013-07-11 22:14                 ` Junio C Hamano
2013-07-12 17:21                   ` Johannes Sixt
2013-07-12 17:40                     ` Junio C Hamano
2013-07-12 20:00                       ` Johannes Sixt
2013-07-12 21:19                         ` Junio C Hamano
2013-07-13  6:52                           ` Johannes Sixt
2013-07-13 18:14                             ` Junio C Hamano
2013-07-13 20:08                               ` Junio C Hamano
2013-07-13 21:11                                 ` Johannes Sixt
2013-07-14 14:28                                 ` John Keeping
2013-07-13 20:17                               ` Johannes Sixt
2013-07-14 19:17                                 ` Junio C Hamano
2013-07-14 20:21                                   ` Johannes Sixt
2013-07-14 20:34                                     ` Jonathan Nieder
2013-07-14 20:49                                       ` Jonathan Nieder
2013-07-14 20:59                                       ` Johannes Sixt
2013-07-14 21:28                                         ` Jonathan Nieder
2013-07-15  4:10                                           ` Junio C Hamano
2013-07-15  4:44                                             ` Jonathan Nieder
2013-07-15 15:37                                               ` Junio C Hamano
2013-07-15 20:30                                         ` Johannes Sixt
2013-07-15  3:50                                     ` Junio C Hamano
2013-07-15 15:47                                       ` Default expectation of --lockref Junio C Hamano
2013-07-15 20:27                                       ` [PATCH 7/7] push: document --lockref Johannes Sixt
2013-07-09 21:37         ` Marc Branchaud
2013-07-09 20:27     ` Michael Haggerty
2013-07-09 20:42       ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vvc4re86g.fsf@alter.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=johan@herland.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).