<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/builtin/push.c, branch v2.2.0</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/git/git.git/
</subtitle>
<id>https://git.shady.money/git/atom?h=v2.2.0</id>
<link rel='self' href='https://git.shady.money/git/atom?h=v2.2.0'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/'/>
<updated>2014-10-24T17:50:05Z</updated>
<entry>
<title>push: heed user.signingkey for signed pushes</title>
<updated>2014-10-24T17:50:05Z</updated>
<author>
<name>Michael J Gruber</name>
<email>git@drmicha.warpmail.net</email>
</author>
<published>2014-10-22T14:57:49Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=b9459019bbb7b864cf59fa307953834996ab4dbe'/>
<id>urn:sha1:b9459019bbb7b864cf59fa307953834996ab4dbe</id>
<content type='text'>
push --signed promises to take user.signingkey as the signing key but
fails to read the config.

Make it do so.

Signed-off-by: Michael J Gruber &lt;git@drmicha.warpmail.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>push: the beginning of "git push --signed"</title>
<updated>2014-09-15T20:23:20Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2014-09-12T18:17:07Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=a85b377d0419a9dfaca8af2320cc33b051cbed04'/>
<id>urn:sha1:a85b377d0419a9dfaca8af2320cc33b051cbed04</id>
<content type='text'>
While signed tags and commits assert that the objects thusly signed
came from you, who signed these objects, there is not a good way to
assert that you wanted to have a particular object at the tip of a
particular branch.  My signing v2.0.1 tag only means I want to call
the version v2.0.1, and it does not mean I want to push it out to my
'master' branch---it is likely that I only want it in 'maint', so
the signature on the object alone is insufficient.

The only assurance to you that 'maint' points at what I wanted to
place there comes from your trust on the hosting site and my
authentication with it, which cannot easily audited later.

Introduce a mechanism that allows you to sign a "push certificate"
(for the lack of better name) every time you push, asserting that
what object you are pushing to update which ref that used to point
at what other object.  Think of it as a cryptographic protection for
ref updates, similar to signed tags/commits but working on an
orthogonal axis.

The basic flow based on this mechanism goes like this:

 1. You push out your work with "git push --signed".

 2. The sending side learns where the remote refs are as usual,
    together with what protocol extension the receiving end
    supports.  If the receiving end does not advertise the protocol
    extension "push-cert", an attempt to "git push --signed" fails.

    Otherwise, a text file, that looks like the following, is
    prepared in core:

	certificate version 0.1
	pusher Junio C Hamano &lt;gitster@pobox.com&gt; 1315427886 -0700

	7339ca65... 21580ecb... refs/heads/master
	3793ac56... 12850bec... refs/heads/next

    The file begins with a few header lines, which may grow as we
    gain more experience.  The 'pusher' header records the name of
    the signer (the value of user.signingkey configuration variable,
    falling back to GIT_COMMITTER_{NAME|EMAIL}) and the time of the
    certificate generation.  After the header, a blank line follows,
    followed by a copy of the protocol message lines.

    Each line shows the old and the new object name at the tip of
    the ref this push tries to update, in the way identical to how
    the underlying "git push" protocol exchange tells the ref
    updates to the receiving end (by recording the "old" object
    name, the push certificate also protects against replaying).  It
    is expected that new command packet types other than the
    old-new-refname kind will be included in push certificate in the
    same way as would appear in the plain vanilla command packets in
    unsigned pushes.

    The user then is asked to sign this push certificate using GPG,
    formatted in a way similar to how signed tag objects are signed,
    and the result is sent to the other side (i.e. receive-pack).

    In the protocol exchange, this step comes immediately before the
    sender tells what the result of the push should be, which in
    turn comes before it sends the pack data.

 3. When the receiving end sees a push certificate, the certificate
    is written out as a blob.  The pre-receive hook can learn about
    the certificate by checking GIT_PUSH_CERT environment variable,
    which, if present, tells the object name of this blob, and make
    the decision to allow or reject this push.  Additionally, the
    post-receive hook can also look at the certificate, which may be
    a good place to log all the received certificates for later
    audits.

Because a push certificate carry the same information as the usual
command packets in the protocol exchange, we can omit the latter
when a push certificate is in use and reduce the protocol overhead.
This however is not included in this patch to make it easier to
review (in other words, the series at this step should never be
released without the remainder of the series, as it implements an
interim protocol that will be incompatible with the final one).
As such, the documentation update for the protocol is left out of
this step.

Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>refactor skip_prefix to return a boolean</title>
<updated>2014-06-20T17:44:43Z</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2014-06-18T19:44:19Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=cf4fff579e02d8585d59f6c8739534b7b0d617dd'/>
<id>urn:sha1:cf4fff579e02d8585d59f6c8739534b7b0d617dd</id>
<content type='text'>
The skip_prefix() function returns a pointer to the content
past the prefix, or NULL if the prefix was not found. While
this is nice and simple, in practice it makes it hard to use
for two reasons:

  1. When you want to conditionally skip or keep the string
     as-is, you have to introduce a temporary variable.
     For example:

       tmp = skip_prefix(buf, "foo");
       if (tmp)
	       buf = tmp;

  2. It is verbose to check the outcome in a conditional, as
     you need extra parentheses to silence compiler
     warnings. For example:

       if ((cp = skip_prefix(buf, "foo"))
	       /* do something with cp */

Both of these make it harder to use for long if-chains, and
we tend to use starts_with() instead. However, the first line
of "do something" is often to then skip forward in buf past
the prefix, either using a magic constant or with an extra
strlen(3) (which is generally computed at compile time, but
means we are repeating ourselves).

This patch refactors skip_prefix() to return a simple boolean,
and to provide the pointer value as an out-parameter. If the
prefix is not found, the out-parameter is untouched. This
lets you write:

  if (skip_prefix(arg, "foo ", &amp;arg))
	  do_foo(arg);
  else if (skip_prefix(arg, "bar ", &amp;arg))
	  do_bar(arg);

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'cc/starts-n-ends-with-endgame'</title>
<updated>2014-03-07T23:18:28Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2014-03-07T23:18:17Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=e3f118594683b075d70fb479a81613f614a7b1f1'/>
<id>urn:sha1:e3f118594683b075d70fb479a81613f614a7b1f1</id>
<content type='text'>
prefixcmp/suffixcmp are gone.
</content>
</entry>
<entry>
<title>Merge branch 'gj/push-more-verbose-advice'</title>
<updated>2014-03-07T23:17:20Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2014-03-07T23:17:20Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=289ca27deefab9b145a156a30571d9d25a9ad17c'/>
<id>urn:sha1:289ca27deefab9b145a156a30571d9d25a9ad17c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Merge branch 'jc/push-2.0-default-to-simple'</title>
<updated>2014-03-07T23:13:15Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2014-03-07T23:13:15Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=009055f3ecd8d9b4eb140429cb5ce5d2088174c7'/>
<id>urn:sha1:009055f3ecd8d9b4eb140429cb5ce5d2088174c7</id>
<content type='text'>
Finally update the "git push" default behaviour to "simple".
</content>
</entry>
<entry>
<title>Merge branch 'jc/push-refmap'</title>
<updated>2013-12-27T22:57:50Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2013-12-27T22:57:50Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=7cdebd8a2039cb3ec717b880709ea6dfd824e3c4'/>
<id>urn:sha1:7cdebd8a2039cb3ec717b880709ea6dfd824e3c4</id>
<content type='text'>
Make "git push origin master" update the same ref that would be
updated by our 'master' when "git push origin" (no refspecs) is run
while the 'master' branch is checked out, which makes "git push"
more symmetric to "git fetch" and more usable for the triangular
workflow.

* jc/push-refmap:
  push: also use "upstream" mapping when pushing a single ref
  push: use remote.$name.push as a refmap
  builtin/push.c: use strbuf instead of manual allocation
</content>
</entry>
<entry>
<title>push: also use "upstream" mapping when pushing a single ref</title>
<updated>2013-12-04T23:12:34Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2013-12-04T00:23:35Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=fc9261ca611080b1dae76b86b3bf5f36d592042f'/>
<id>urn:sha1:fc9261ca611080b1dae76b86b3bf5f36d592042f</id>
<content type='text'>
When the user is using the 'upstream' mode, these commands:

    $ git push
    $ git push origin

would find the 'upstream' branch for the current branch, and then
push the current branch to update it.  However, pushing a single
branch explicitly, i.e.

    $ git push origin $(git symbolic-ref --short HEAD)

would not go through the same ref mapping process, and ends up
updating the branch at 'origin' of the same name, which may not
necessarily be the upstream of the branch being pushed.

In the spirit similar to the previous one, map a colon-less refspec
using the upstream mapping logic.

Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>push: use remote.$name.push as a refmap</title>
<updated>2013-12-04T23:11:08Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2013-12-03T23:41:15Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=ca02465b41311fe7634acb9bb5b5c61975ef5f38'/>
<id>urn:sha1:ca02465b41311fe7634acb9bb5b5c61975ef5f38</id>
<content type='text'>
Since f2690487 (fetch: opportunistically update tracking refs,
2013-05-11), we stopped taking a non-storing refspec given on the
command line of "git fetch" literally, and instead started mapping
it via remote.$name.fetch refspecs.  This allows

    $ git fetch origin master

from the 'origin' repository, which is configured with

    [remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*

to update refs/remotes/origin/master with the result, as if the
command line were

    $ git fetch origin +master:refs/remotes/origin/master

to reduce surprises and improve usability.  Before that change, a
refspec on the command line without a colon was only to fetch the
history and leave the result in FETCH_HEAD, without updating the
remote-tracking branches.

When you are simulating a fetch from you by your mothership with a
push by you into your mothership, instead of having:

    [remote "satellite"]
        fetch = +refs/heads/*:refs/remotes/satellite/*

on the mothership repository and running:

    mothership$ git fetch satellite

you would have:

    [remote "mothership"]
        push = +refs/heads/*:refs/remotes/satellite/*

on your satellite machine, and run:

    satellite$ git push mothership

Because we so far did not make the corresponding change to the push
side, this command:

    satellite$ git push mothership master

does _not_ allow you on the satellite to only push 'master' out but
still to the usual destination (i.e. refs/remotes/satellite/master).

Implement the logic to map an unqualified refspec given on the
command line via the remote.$name.push refspec.  This will bring a
bit more symmetry between "fetch" and "push".

Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>builtin/push.c: use strbuf instead of manual allocation</title>
<updated>2013-12-03T22:47:18Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2013-12-03T22:33:10Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=50d829c11a3c82a8b23f2e165ab6944dfd9bbb36'/>
<id>urn:sha1:50d829c11a3c82a8b23f2e165ab6944dfd9bbb36</id>
<content type='text'>
The command line arguments given to "git push" are massaged into
a list of refspecs in set_refspecs() function. This was implemented
using xmalloc, strcpy and friends, but it is much easier to read if
done using strbuf.

Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
</feed>
