git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Stefan Beller <sbeller@google.com>
To: Brandon Williams <bmwill@google.com>
Cc: git <git@vger.kernel.org>
Subject: Re: [RFC] push: add documentation on push v2
Date: Tue, 17 Jul 2018 16:25:35 -0700	[thread overview]
Message-ID: <CAGZ79kZEpNLkXuEQEiMB_nc-MOOp-KOziHyONmr4SiajA5+F2g@mail.gmail.com> (raw)
In-Reply-To: <20180717210915.139521-1-bmwill@google.com>

On Tue, Jul 17, 2018 at 2:09 PM Brandon Williams <bmwill@google.com> wrote:
>
> Signed-off-by: Brandon Williams <bmwill@google.com>
> ---
>
> Since introducing protocol v2 and enabling fetch I've been thinking
> about what its inverse 'push' would look like.  After talking with a
> number of people I have a longish list of things that could be done to
> improve push and I think I've been able to distill the core features we
> want in push v2.

It would be nice to know which things you want to improve.

>  Thankfully (due to the capability system) most of the
> other features/improvements can be added later with ease.
>
> What I've got now is a rough design for a more flexible push, more
> flexible because it allows for the server to do what it wants with the
> refs that are pushed and has the ability to communicate back what was
> done to the client.  The main motivation for this is to work around
> issues when working with Gerrit and other code-review systems where you
> need to have Change-Ids in the commit messages (now the server can just
> insert them for you and send back new commits) and you need to push to
> magic refs to get around various limitations (now a Gerrit server should
> be able to communicate that pushing to 'master' doesn't update master
> but instead creates a refs/changes/<id> ref).

Well Gerrit is our main motivation, but this allows for other workflows as well.
For example Facebook uses hg internally and they have a
"rebase-on-the-server-after-push" workflow IIRC as pushing to a single repo
brings up quite some contention. The protocol outlined below would allow
for such a workflow as well? (This might be an easier sell to the Git
community as most are not quite familiar with Gerrit)

> Before actually moving to write any code I'm hoping to get some feedback
> on if we think this is an acceptable base design for push (other
> features like atomic-push, signed-push, etc can be added as
> capabilities), so any comments are appreciated.
>
>  Documentation/technical/protocol-v2.txt | 76 +++++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
>
> diff --git a/Documentation/technical/protocol-v2.txt b/Documentation/technical/protocol-v2.txt
> index 49bda76d23..16c1ce60dd 100644
> --- a/Documentation/technical/protocol-v2.txt
> +++ b/Documentation/technical/protocol-v2.txt
> @@ -403,6 +403,82 @@ header.
>                 2 - progress messages
>                 3 - fatal error message just before stream aborts
>
> + push
> +~~~~~~
> +
> +`push` is the command used to push ref-updates and a packfile to a remote
> +server in v2.
> +
> +Additional features not supported in the base command will be advertised
> +as the value of the command in the capability advertisement in the form
> +of a space separated list of features: "<command>=<feature 1> <feature 2>"
> +
> +The format of a push request is as follows:
> +
> +    request = *section
> +    section = (ref-updates | packfile)

This reads as if a request consists of sections, which
each can be a "ref-updates" or a packfile, no order given,
such that multiple ref-update sections mixed with packfiles
are possible.

I would assume we'd only want to allow for ref-updates
followed by the packfile.

Given the example above for "rebase-on-push" though
it is better to first send the packfile (as that is assumed to
take longer) and then send the ref updates, such that the
rebasing could be faster and has no bottleneck.

> +              (delim-pkt | flush-pkt)



> +
> +    ref-updates = PKT-LINE("ref-updates" LF)
> +                 *PKT-Line(update/force-update LF)
> +
> +    update = txn_id SP action SP refname SP old_oid SP new_oid
> +    force-update = txn_id SP "force" SP action SP refname SP new_oid

So we insert "force" after the transaction id if we want to force it.
When adding the atomic capability later we could imagine another insert here

  1 atomic create refs/heads/new-ref <0-hash> <hash>
  1 atomic delete refs/heads/old-ref <hash> <0-hash>

which would look like a "rename" that we could also add instead.
The transaction numbers are an interesting concept, how do you
envision them to be used? In the example I put them both in the same
transaction to demonstrate the "atomic-ness", but one could also
imagine different transactions numbers per ref (i.e. exactly one
ref per txn_id) to have a better understanding of what the server did
to each individual ref.

> +    action = ("create" | "delete" | "update")
> +    txn_id = 1*DIGIT
> +
> +    packfile = PKT-LINE("packfile" LF)
> +              *PKT-LINE(*%x00-ff)
> +
> +    ref-updates section
> +       * Transaction id's allow for mapping what was requested to what the
> +         server actually did with the ref-update.

this would imply the client ought to have at most one ref per transaction id.
Is the client allowed to put multiple refs per id?

Are new capabilities attached to ref updates or transactions?
Unlike the example above, stating "atomic" on each line, you could just
say "transaction 1 should be atomic" in another line, that would address
all refs in that transaction.

> +       * Normal ref-updates require that the old value of a ref is supplied so
> +         that the server can verify that the reference that is being updated
> +         hasn't changed while the request was being processed.

create/delete assume <00..00> for either old or new ? (We could also
omit the second hash for create delete, which is more appealing to me)

> +       * Forced ref-updates only include the new value of a ref as we don't
> +         care what the old value was.

How are you implementing force-with-lease then?

> +    packfile section
> +       * A packfile MAY not be included if only delete commands are used or if
> +         an update only incorperates objects the server already has

Or rather: "An empty pack SHALL be omitted" ?

> +The server will receive the packfile, unpack it, then validate each ref-update,
> +and it will run any update hooks to make sure that the update is acceptable.
> +If all of that is fine, the server will then update the references.
> +
> +The format of a push response is as follows:
> +
> +    response = *section
> +    section = (unpack-error | ref-update-status | packfile)

As above, I assume they ought to go in the order as written,
or would it make sense to allow for any order?

> +             (delim-pkt | flush-pkt)
> +
> +    unpack-error = PKT-LINE("ERR" SP error-msg LF)
> +
> +    ref-update-status = *(update-result | update-error)
> +    update-result = *PKT-LINE(txn_id SP result LF)
> +    result = ("created" | "deleted" | "updated") SP refname SP old_oid SP new_oid
> +    update-error = PKT-LINE(txn_id SP "error" SP error-msg LF)

Can we unify "ERR" and "error" ?

> +    packfile = PKT-LINE("packfile" LF)
> +              *PKT-LINE(*%x00-ff)
> +
> +    ref-update-status section
> +       * This section is always included unless there was an error unpacking
> +         the packfile sent in the request.
> +       * The server is given the freedom to do what it wants with the
> +         ref-updates provided in the reqeust.  This means that an update sent
> +         from the server may result in the creation of a ref or rebasing the
> +         update on the server.
> +       * If a server creates any new objects due to a ref-update, a packfile
> +         MUST be sent back in the response.
> +
> +    packfile section
> +       * This section is included if the server decided to do something with
> +         the ref-updates that involved creating new objects.
> +
>   server-option
>  ~~~~~~~~~~~~~~~
>
> --
> 2.18.0.203.gfac676dfb9-goog
>

  reply	other threads:[~2018-07-17 23:25 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-17 21:09 [RFC] push: add documentation on push v2 Brandon Williams
2018-07-17 23:25 ` Stefan Beller [this message]
2018-07-18 13:31   ` Derrick Stolee
2018-07-18 16:56     ` Stefan Beller
2018-07-18 17:15       ` Brandon Williams
2018-07-20 13:12         ` Jeff Hostetler
2018-07-24 19:00           ` Brandon Williams
2018-07-18 17:11     ` Brandon Williams
2018-07-18 17:19       ` Duy Nguyen
2018-07-18 17:46         ` Brandon Williams
2018-07-18 17:57           ` Duy Nguyen
2018-07-18 17:08   ` Brandon Williams
2018-07-18 18:07     ` Stefan Beller
2018-07-18 18:17       ` Duy Nguyen
2018-07-18 18:21       ` Brandon Williams
2018-07-24 19:28 ` Brandon Williams
2018-07-25 15:15   ` Duy Nguyen
2018-07-25 17:46     ` Brandon Williams
2018-08-02 15:17       ` Duy Nguyen

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=CAGZ79kZEpNLkXuEQEiMB_nc-MOOp-KOziHyONmr4SiajA5+F2g@mail.gmail.com \
    --to=sbeller@google.com \
    --cc=bmwill@google.com \
    --cc=git@vger.kernel.org \
    /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).