{"thread":{"id":"28380","subject":"[Survey] Signed push","startedAt":"2011-09-13T16:45:37Z","lastAt":"2011-09-29T06:44:04Z","messageCount":62,"participants":["Junio C Hamano","Guenter Roeck","Sam Vilain","Shawn Pearce","Linus Torvalds","Michael Haggerty","Matthieu Moy","Nguyen Thai Ngoc Duy","Johan Herland","Ted Ts'o","Andy Lutomirski","Andrew Lutomirski","Jonathan Nieder","Philip Oakley","Jeff King","Andrew Ardill","Michael J Gruber"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"175406","messageId":"7vaaa8xufi.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":null,"subject":"[Survey] Signed push","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-13T16:45:37Z","receivedAt":"2011-09-13T16:45:37Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"[administrivia] This message is also Cc'ed to the kernel mailing list in\norder to ask for opinions from members of one of the most important user\ncommunities of Git, but people may want to drop the kernel list when\nresponding to this message to reduce the noise level over there. Thanks.\n\nIn the light of what happened to k.org recently, we've been discussing\nthings Git can do to help raising confidence levels perceived by the\ngeneral public on integrity of the source trees, especially for the kernel\ncommunity. As the article by Jonathan Corbet on lwn.net nicely described,\nprojects managed with Git are already pretty resistant from tampering, and\nit is not my (nor anybody in the Git community's) intention to propose any\nmore unnecessary bureaucracy to the development process without merit.\n\nThere are two updates that may change the end user experience I would like\nto ask your opinions on, both as the Git designer (emeritus?) and as the\ntop kernel developer.\n\n\n1. Improved pull requests.\n\nCurrently a typical pull-request begins like this:\n\n    The following changes since commit f696543dad6c7ba27b0c4fab167a5687263a9ba0:\n\n      Flobar 2.4.3 (2011-09-13 12:34:56 +0900)\n\n    are available in the git repository at:\n      git://git.kernel.org/pub/flobar.git/ master\n\nwhich is followed by the shortlog and expected diffstat.  This tells you\nwhere the requester based his work on in excruciating detail, but does not\ntell you what you should expect to fetch, any more than \"whatever happened\nto be at the named branch when you happened to notice the request.\"\n\nWe have a tentative patch to add an extra line after the \"URL branch\" line\nthat is for your cut & paste that looks like:\n\n    are available in the git repository at:\n      git://git.kernel.org/pub/flobar.git/ master\n    for you to fetch changes up to 5738c9c21e53356ab5020912116e7f82fd2d428f\n\nI often see you respond to a pull request on the kernel mailing list with\n\"I see nothing new; forgot to push?\", and having this extra line may also\nhelp communication.\n\nWould it be just an added and useless noise that you nor your requesters\nwould not care much about?\n\nAn alternative that I am considering is to let the requester say this\ninstead:\n\n    are available in the git repository at:\n      git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f\n\nwithout adding the extra line.\n\nThat is, to allow fetching the history up to an explicitly named commit\nobject. This would only involve a change to fetch-pack at the receiving\nend; just match the commit object name given from the command line against\nthe ls-remote response and ask upload-pack to give the history leading to\nit. The released versions of Git already will happily oblige, as long as\nthe commit object named in the request message still sits at the tip of\nthe intended branch.\n\nDo you think it is worthwhile to pursue this alternative?\n\n\n2. Signed pushes.\n\nYou tag official releases and release candidates with your GPG key, and\neverybody who works within the kernel ecosystem trusts the history behind\nthe commits pointed by them, but there is no easy way to verify that\ncommits and merges between the last tagged commit and the tip of your\nbranch(es) are indeed from you, or if an intruder piled fake ones on top\nof your commits (until you try to push again and discover that the history\ndoes not fast-forward, that is).\n\nWe have been discussing an addition of \"git push -s\" to let people sign\ntheir pushes (instead of having to sign every commit or add signed\ntag). The implementation alternatives were being bikeshed but not of much\ninterest in this message, but the user experience would go like this:\n\n * You push out your work with \"git push -s\";\n\n * \"git push\" prepares a \"push certificate\" (it is meant to certify \"these\n   are the commits I place at the tips of these refs\"), which is a human\n   and machine readable text file in core, that may look like this:\n\n        Push-Certificate-Version: 0\n        Pusher: Junio C Hamano <gitster@pobox.com>\n        Update: 3793ac56b4c4f9bf0bddc306a0cec21118683728 refs/heads/master\n        Update: 12850bec0c24b529c9a9df6a95ad4bdeea39373e refs/heads/next\n\n   and asks you to GPG sign it. You only unlock your GPG key and the\n   command internally runs GPG, just like \"tag -s\".\n\n * When \"git push\" finishes, the receiving end has this record in its\n   refs/notes/signed-push notes tree, together with your previous pushes\n   (as this is not a shared repository, it will record only your pushes).\n   The notes annnotate the commits named on the \"Update:\" lines above.\n\n * People who want to verify commits that are not yet tagged near the tip\n   in their clone of your tree can fetch refs/notes/signed-push and run\n\n     $ git log --show-notes=signed-push --branches --not --tags\n\n   to see your push certificates as annotations on commits that are not\n   yet tagged. They can verify them using a tool (yet to be written) that\n   acts like \"git tag --verify\".\n\nIt is hoped that it would help downstream with warm and fuzzy assurances\nthat all commits including the ones that are not yet tagged are genuine\n(disclaimer: my employer is among the \"downstream\" that wants to have that\nwarm and fuzzy assurance) if we can see these push certificates published\nat your public repository.\n\nA few questions.\n\n * As a user, do you think \"signed push\" is a good idea, or is it merely\n   an unnecessary bureaucracy, having to sign all pushes?\n\n * As a user, do you think it is a good thing that you could also verify\n   the commits you receive from the Git-managed repositories of your\n   lieutenants using this mechanism, or you wouldn't bother, perhaps\n   because you are applying many patches sent via unsigned e-mail from\n   Andrew anyway?\n\n * If the answers to the above points are both \"yes\", do you think it\n   would make sense to also propagate the push certificates you obtain\n   from your lieutenants to your public repository when you make your\n   \"push -s\"? It will allow your downstream to follow the chain of trust\n   in one-go (if you are pulling from public places, they can fetch the\n   push certificates from your lieutenants themselves and merge them, so\n   this is merely a convenience feature) by simply fetching from the\n   refs/notes/signed-push notes tree from your public repository.  Do you\n   think it is a useful and worthwhile thing to do?\n"},{"id":"175433","messageId":"1315952896-17258-1-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"7vaaa8xufi.fsf@alter.siamese.dyndns.org","subject":"[PATCH v2 0/2] State commit name explicitly in request-pull messages","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-13T22:28:14Z","receivedAt":"2011-09-13T22:28:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Here is an alternative approach to the earlier \"request-pull\" patch.\n\nJunio C Hamano (2):\n  fetch: allow asking for an explicit commit object by name\n  request-pull: state exact commit object name\n\n git-request-pull.sh     |    2 +-\n remote.c                |   25 +++++++++++++++++++++++--\n t/t5150-request-pull.sh |   11 +++++++----\n 3 files changed, 31 insertions(+), 7 deletions(-)\n\n-- \n1.7.7.rc1.1.g1e5814\n"},{"id":"175431","messageId":"1315952896-17258-2-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"1315952896-17258-1-git-send-email-gitster@pobox.com","subject":"[PATCH v2 1/2] fetch: allow asking for an explicit commit object by name","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-13T22:28:15Z","receivedAt":"2011-09-13T22:28:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This teaches \"git fetch\" (hence \"git pull\") to accept an explicit commit\nobject name in the LHS of the refspec, as long as the named commit is at\nthe tip of an advertised ref. E.g.\n\n    $ git pull origin 5738c9c21e53356ab5020912116e7f82fd2d428f\n    $ git fetch origin 5738c9c21e53356ab5020912116e7f82fd2d428f:refs/remotes/origin\n\nwould behave exactly as if you asked\n\n    $ git pull origin refs/heads/master\n    $ git fetch origin refs/heads/master:refs/remotes/origin\n\nwhen the output from \"git ls-remote origin\" said the remote side has the\ncommit object whose name is 5738c9c21e53356ab5020912116e7f82fd2d428f at\nthe tip of refs/heads/master branch ref.\n\nThis does not allow asking for a random object that may or may not exist\nin the repository (this has been a longstanding security feature).\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n remote.c |   25 +++++++++++++++++++++++--\n 1 files changed, 23 insertions(+), 2 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex ca42a12..76c2943 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1387,6 +1387,25 @@ struct ref *get_remote_ref(const struct ref *remote_refs, const char *name)\n \treturn copy_ref(ref);\n }\n \n+/*\n+ * Allow fetching an explicitly-named commit from the command line,\n+ * but only if it exactly matches the commit at the tip of one of the\n+ * advertised refs.\n+ */\n+static struct ref *get_remote_commit(const struct ref *remote_refs, const char *hex)\n+{\n+\tconst struct ref *ref;\n+\tunsigned char sha1[20];\n+\n+\tif (get_sha1_hex(hex, sha1) || hex[40])\n+\t\treturn NULL;\n+\n+\tfor (ref = remote_refs; ref; ref = ref->next)\n+\t\tif (!strchr(ref->name, '^') && !hashcmp(sha1, ref->old_sha1))\n+\t\t\treturn copy_ref(ref);\n+\treturn NULL;\n+}\n+\n static struct ref *get_local_ref(const char *name)\n {\n \tif (!name || name[0] == '\\0')\n@@ -1416,8 +1435,10 @@ int get_fetch_map(const struct ref *remote_refs,\n \t\tconst char *name = refspec->src[0] ? refspec->src : \"HEAD\";\n \n \t\tref_map = get_remote_ref(remote_refs, name);\n-\t\tif (!missing_ok && !ref_map)\n-\t\t\tdie(\"Couldn't find remote ref %s\", name);\n+\t\tif (!ref_map)\n+\t\t\tref_map = get_remote_commit(remote_refs, name);\n+\t\tif (!ref_map && !missing_ok)\n+\t\t\tdie(\"Couldn't find remote ref that matches %s\", name);\n \t\tif (ref_map) {\n \t\t\tref_map->peer_ref = get_local_ref(refspec->dst);\n \t\t\tif (ref_map->peer_ref && refspec->force)\n-- \n1.7.7.rc1.1.g1e5814\n"},{"id":"175432","messageId":"1315952896-17258-3-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"1315952896-17258-1-git-send-email-gitster@pobox.com","subject":"[PATCH v2 2/2] request-pull: state exact commit object name","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-13T22:28:16Z","receivedAt":"2011-09-13T22:28:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"A typical pull-request begins like this:\n\n  The following changes since commit f696543dad6c7ba27b0c4fab167a5687263a9ba0:\n\n    Flobar 2.4.3 (2011-09-13 12:34:56 +0900)\n\n  are available in the git repository at:\n    git://git.kernel.org/pub/flobar.git/ master\n\nwhich is followed by the shortlog and expected diffstat. This tells you\nwhere the requester based his work on in excruciating detail, but does not\ntell you what you should expect to fetch, any more than \"whatever happened\nto be at the named branch when you happened to notice the request.\"\n\nUpdate the message slightly to say:\n\n    git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f ;# master\n\nso that the line still can be cut&pasted after \"git fetch\" (or \"git\npull\"), to form a command line that looks like:\n\n    $ git <repository> <full commit object name> ;# branch\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n git-request-pull.sh     |    2 +-\n t/t5150-request-pull.sh |   11 +++++++----\n 2 files changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/git-request-pull.sh b/git-request-pull.sh\nindex fc080cc..b5a2d0f 100755\n--- a/git-request-pull.sh\n+++ b/git-request-pull.sh\n@@ -70,7 +70,7 @@ git show -s --format='The following changes since commit %H:\n   %s (%ci)\n \n are available in the git repository at:' $baserev &&\n-echo \"  $url $branch\" &&\n+echo \"  $url $headrev ;# $branch\" &&\n echo &&\n \n git shortlog ^$baserev $headrev &&\ndiff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh\nindex 9cc0a42..e9d657e 100755\n--- a/t/t5150-request-pull.sh\n+++ b/t/t5150-request-pull.sh\n@@ -70,9 +70,10 @@ test_expect_success 'setup: two scripts for reading pull requests' '\n \t/ in the git repository at:$/!d\n \tn\n \t/^$/ n\n-\ts/^[ \t]*\\(.*\\) \\([^ ]*\\)/please pull\\\n+\ts/^[ \t]*\\(.*\\) \\([^ ]*\\) ;# \\([^ ]*\\)/please pull\\\n \t\\1\\\n-\t\\2/p\n+\t\\2\\\n+\t\\3/p\n \tq\n \tEOT\n \n@@ -145,6 +146,7 @@ test_expect_success 'pull request after push' '\n \t{\n \t\tread task &&\n \t\tread repository &&\n+\t\tread head &&\n \t\tread branch\n \t} <digest &&\n \t(\n@@ -153,6 +155,7 @@ test_expect_success 'pull request after push' '\n \t\tgit pull --ff-only \"$repository\" \"$branch\"\n \t) &&\n \ttest \"$branch\" = for-upstream &&\n+\ttest \"$head\" = \"$(GIT_DIR=downstream.git git rev-parse for-upstream)\" &&\n \ttest_cmp local/mnemonic.txt upstream-private/mnemonic.txt\n \n '\n@@ -170,10 +173,10 @@ test_expect_success 'request names an appropriate branch' '\n \t\tgit request-pull initial \"$downstream_url\" >../request\n \t) &&\n \tsed -nf read-request.sed <request >digest &&\n-\tcat digest &&\n \t{\n \t\tread task &&\n \t\tread repository &&\n+\t\tread head &&\n \t\tread branch\n \t} <digest &&\n \t{\n@@ -193,7 +196,7 @@ test_expect_success 'pull request format' '\n \t  SUBJECT (DATE)\n \n \tare available in the git repository at:\n-\t  URL BRANCH\n+\t  URL OBJECT_NAME ;# BRANCH\n \n \tSHORTLOG\n \n-- \n1.7.7.rc1.1.g1e5814\n"},{"id":"175439","messageId":"20110913232640.GA4189@ericsson.com","threadId":"28380","inReplyTo":"7vaaa8xufi.fsf@alter.siamese.dyndns.org","subject":"Re: [Survey] Signed push","fromName":"Guenter Roeck","fromEmail":"guenter.roeck@ericsson.com","sentAt":"2011-09-13T23:26:40Z","receivedAt":"2011-09-13T23:26:40Z","isPatch":false,"sender":{"key":"guenter.roeck@ericsson.com","avatar":null},"body":"On Tue, Sep 13, 2011 at 12:45:37PM -0400, Junio C Hamano wrote:\n[ ... ]\n\n> 1. Improved pull requests.\n> \nnoise for me\n\n[ ... ]\n\n> 2. Signed pushes.\n> \nExcellent idea, long since overdue.\n\nGuenter\n"},{"id":"175443","messageId":"7v1uvkvw68.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"20110913232640.GA4189@ericsson.com","subject":"Re: [Survey] Signed push","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-13T23:50:55Z","receivedAt":"2011-09-13T23:50:55Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Guenter Roeck <guenter.roeck@ericsson.com> writes:\n\n> On Tue, Sep 13, 2011 at 12:45:37PM -0400, Junio C Hamano wrote:\n> [ ... ]\n>\n>> 1. Improved pull requests.\n>> \n> noise for me\n\nAre you among the ones who respond to pull requests?\n"},{"id":"175444","messageId":"7vty8guh25.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"7v1uvkvw68.fsf@alter.siamese.dyndns.org","subject":"Re: [Survey] Signed push","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-14T00:02:42Z","receivedAt":"2011-09-14T00:02:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Guenter Roeck <guenter.roeck@ericsson.com> writes:\n>\n>> On Tue, Sep 13, 2011 at 12:45:37PM -0400, Junio C Hamano wrote:\n>> [ ... ]\n>>\n>>> 1. Improved pull requests.\n>>> \n>> noise for me\n>\n> Are you among the ones who respond to pull requests?\n\nSorry, this didn't come out quite the way I intended.\n\nAs I do not know every developer on earth, I would like to know in what\ncapacity you (figuratively---I mean everybody who gives his opinion on\nthis topic) fit in your ecosystem. Otherwise I cannot tell if many people\nwho receive pull requests find it noise but senders do not care, or many\npeople who send them find it noise but receivers do appreciate, etc.\n\nFor the purpose of commenting on \"pull requests\" topic, one can be (1)\na bystander, who does not request nor respond to pull requests, (2) who\ngets requests to pull, or (3) who sends requests to pull.\n\nThe same for \"signed pushes\". In this case, one can be (1) who pushes, (2)\nwho fetches and wants to verify what he gets, (3) both (e.g. Linus\nplaying role (3) while fetching from his lieutenants and then role (1)\nwhen pushing his integration results out).\n"},{"id":"175445","messageId":"4E6FF5D9.3080709@vilain.net","threadId":"28380","inReplyTo":"7vaaa8xufi.fsf@alter.siamese.dyndns.org","subject":"Re: [Survey] Signed push","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2011-09-14T00:31:21Z","receivedAt":"2011-09-14T00:31:21Z","isPatch":false,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"On 9/13/11 9:45 AM, Junio C Hamano wrote:\n>   * You push out your work with \"git push -s\";\n>\n>   * \"git push\" prepares a \"push certificate\" (it is meant to certify \"these\n>     are the commits I place at the tips of these refs\"), which is a human\n>     and machine readable text file in core, that may look like this:\n>\n>          Push-Certificate-Version: 0\n>          Pusher: Junio C Hamano<gitster@pobox.com>\n>          Update: 3793ac56b4c4f9bf0bddc306a0cec21118683728 refs/heads/master\n>          Update: 12850bec0c24b529c9a9df6a95ad4bdeea39373e refs/heads/next\n>\n>     and asks you to GPG sign it. You only unlock your GPG key and the\n>     command internally runs GPG, just like \"tag -s\".\n>\n>   * When \"git push\" finishes, the receiving end has this record in its\n>     refs/notes/signed-push notes tree, together with your previous pushes\n>     (as this is not a shared repository, it will record only your pushes).\n>     The notes annnotate the commits named on the \"Update:\" lines above.\n\nIf the push certificate also has the previous commit IDs for the changed \nrefs, then you actually have an audit log.  Otherwise, it does not \ncertify the commit range they pushed.\n\nThis is an important prerequisite for a fully distributed, peer to peer \ngit.  For this case it would also need something to distinguish which \nrepository is to be updated; such as a canonical repository URL (or list \nof URLs), or just a short project name.  A P2P protocol can then know \nprojects as (KEYID, projectname).\n\nSam\n"},{"id":"175446","messageId":"CAJo=hJt-n0Xn85g7-7eEgxZhsBu8wd843dvvbaJgdYSx3t4Xug@mail.gmail.com","threadId":"28380","inReplyTo":"4E6FF5D9.3080709@vilain.net","subject":"Re: [Survey] Signed push","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2011-09-14T00:39:13Z","receivedAt":"2011-09-14T00:39:13Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"On Tue, Sep 13, 2011 at 17:31, Sam Vilain <sam@vilain.net> wrote:\n> On 9/13/11 9:45 AM, Junio C Hamano wrote:\n>>\n>>  * \"git push\" prepares a \"push certificate\" (it is meant to certify \"these\n>>    are the commits I place at the tips of these refs\"), which is a human\n>>    and machine readable text file in core, that may look like this:\n>>\n>>         Push-Certificate-Version: 0\n>>         Pusher: Junio C Hamano<gitster@pobox.com>\n>>         Update: 3793ac56b4c4f9bf0bddc306a0cec21118683728 refs/heads/master\n>>         Update: 12850bec0c24b529c9a9df6a95ad4bdeea39373e refs/heads/next\n>\n> If the push certificate also has the previous commit IDs for the changed\n> refs, then you actually have an audit log.  Otherwise, it does not certify\n> the commit range they pushed.\n\nIs that necessary? The range they are certifying is that commit, and\nits entire ancestry. If the pusher doesn't trust his ancestry, why is\nhe working with it? Similar to an annotated tag. I make a signed\nannotated tag, I am asserting that revision and its ancestry is\nsomething I like as far as a project build goes. You don't need the\nold revision to realize I like this commit.\n\nIf you want to get into the game of, maybe I push a branch, then\nrewind it, and push something differently, and you want to be able to\nverify that the 2nd push is the \"right thing\" and the 1st push should\nbe ignored, you can already see that by looking at the timestamp of\nthe push certificates (/me assumes there is a timestamp in there). If\nyou can create multiple signed pushes by yourself, using your GPG key,\nwithin the same second, and they are conflicting... well, stop using\nautomated tools to create conflicting assertions as yourself. If you\nare creating signed pushes on systems with clock skew, learn how to\nconfigure NTP date.\n\n> This is an important prerequisite for a fully distributed, peer to peer git.\n>  For this case it would also need something to distinguish which repository\n> is to be updated; such as a canonical repository URL (or list of URLs), or\n> just a short project name.  A P2P protocol can then know projects as (KEYID,\n> projectname).\n\nWhy do we need a project name? Most Git based projects are uniquely\nidentified by the set of root commits they have. Why? Because most\nroot commits were created by different people, at different times,\nwith different commit messages, and different initial trees, resulting\nin a unique commit SHA-1 for that root commit. Projects with more than\none root commit also disambiguate themselves from other projects that\nmaybe contain one of those roots (e.g. git.git vs. gitk).\n\nIf you wanted to identify a project on a P2P network, I think you\nwould want to do it based off the root commits, not some random name\npeople came up with and might try to publish forgeries under.\n\n-- \nShawn.\n"},{"id":"175447","messageId":"4E6FFD52.7050907@vilain.net","threadId":"28380","inReplyTo":"CAJo=hJt-n0Xn85g7-7eEgxZhsBu8wd843dvvbaJgdYSx3t4Xug@mail.gmail.com","subject":"Re: [Survey] Signed push","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2011-09-14T01:03:14Z","receivedAt":"2011-09-14T01:03:14Z","isPatch":false,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"On 9/13/11 5:39 PM, Shawn Pearce wrote:\n> >  If the push certificate also has the previous commit IDs for the changed\n> >  refs, then you actually have an audit log.  Otherwise, it does not certify\n> >  the commit range they pushed.\n> Is that necessary? The range they are certifying is that commit, and\n> its entire ancestry. If the pusher doesn't trust his ancestry, why is\n> he working with it? Similar to an annotated tag. I make a signed\n> annotated tag, I am asserting that revision and its ancestry is\n> something I like as far as a project build goes. You don't need the\n> old revision to realize I like this commit.\n\nPerhaps because they didn't notice what happened.  Someone else pushed \nto the server without a signed push somehow, and then they pulled, \npushed ... and now as far as you know, those commits are certified like \nany other.  Having this extra information, not much information, will \nhelp figure out what happens in this sort of situation.\n\n>> This is an important prerequisite for a fully distributed, peer to peer git.\n>>   For this case it would also need something to distinguish which repository\n>> is to be updated; such as a canonical repository URL (or list of URLs), or\n>> just a short project name.  A P2P protocol can then know projects as (KEYID,\n>> projectname).\n> Why do we need a project name? Most Git based projects are uniquely\n> identified by the set of root commits they have. Why? Because most\n> root commits were created by different people, at different times,\n> with different commit messages, and different initial trees, resulting\n> in a unique commit SHA-1 for that root commit. Projects with more than\n> one root commit also disambiguate themselves from other projects that\n> maybe contain one of those roots (e.g. git.git vs. gitk).\n>\n> If you wanted to identify a project on a P2P network, I think you\n> would want to do it based off the root commits, not some random name\n> people came up with and might try to publish forgeries under.\n>\n\nYes, this is true, but it also makes it a lot harder to figure out if \ntwo projects are from the same real project, or whether they just shared \nsome history.  In general, git repositories are partitioned by URL or \nproject, and so this makes a soft case for a distributed system to \npartition itself by URL or project also.\n\nSam\n"},{"id":"175455","messageId":"CA+55aFy0b+eozmzbKD4RXcJ7e3WCpf7BV1n1qXHOeEwSHZKOXw@mail.gmail.com","threadId":"28380","inReplyTo":"CA+55aFxAQTR3sT7gekAD4qih8J+z-qwri7ZmNCPUd811xgci6w@mail.gmail.com","subject":"Fwd: [Survey] Signed push","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2011-09-14T07:06:37Z","receivedAt":"2011-09-14T07:06:37Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"Recovering lost emails. Or maybe you get duplicates. Sorry about that if so,\n\n                   Linus\n\n---------- Forwarded message ----------\nFrom: Linus Torvalds <torvalds@linux-foundation.org>\nDate: Tue, Sep 13, 2011 at 10:48 AM\nSubject: Re: [Survey] Signed push\nTo: Junio C Hamano <gitster@pobox.com>\nCc: git@vger.kernel.org, linux-kernel@vger.kernel.org\n\n\nOn Tue, Sep 13, 2011 at 9:45 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> We have a tentative patch to add an extra line after the \"URL branch\" line\n> that is for your cut & paste that looks like:\n>\n>    are available in the git repository at:\n>      git://git.kernel.org/pub/flobar.git/ master\n>    for you to fetch changes up to 5738c9c21e53356ab5020912116e7f82fd2d428f\n>\n> I often see you respond to a pull request on the kernel mailing list with\n> \"I see nothing new; forgot to push?\", and having this extra line may also\n> help communication.\n\nI think that would probably be a good idea, although I'd actually\nprefer you to be more verbose, and more human-friendly, and actually\ntalk about the commit in a readable way. Get rid of the *horrible*\nBRANCH-NOT-VERIFIED message (that actually messes up pull requests if\nmirroring is a bit delayed and throws away more important\ninformation), and instead just have a blurb afterwards saying\nsomething human-readable like\n\n Top commit 1f51b001cccf: \"Merge branches 'cns3xxx/fixes',\n 'omap/fixes' and 'davinci/fixes' into fixes\"\n\n and at *that* point you might have a \"UNVERIFIED\" notice for people\nto check if they forgot to push.\n\nSo I'd much prefer something like that over:\n\n> An alternative that I am considering is to let the requester say this\n> instead:\n>\n>    are available in the git repository at:\n>      git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f\n>\n> without adding the extra line.\n\nThe extra line in the pull request is cheap - it's not like we need to\nration them. The above format, in contrast, requires that the person\ndoing the *pull* have a recent enough git client, otherwise the merge\ncommit message will be just horrible.\n\nAnd even if you do have a new git client that turns the commit into a\nbranch name, that's ambigious. What if both 'master' and\n'experimental' have the same top commit, because experimental ended up\nbeing tested and was percolated to master? Which branch name would you\npick? And what if the branch was updated since, so *no* branch name\nmatches - does that mean that you'd disallow the pull entirely?\n\n> 2. Signed pushes.\n>\n> You tag official releases and release candidates with your GPG key, and\n> everybody who works within the kernel ecosystem trusts the history behind\n> the commits pointed by them, but there is no easy way to verify that\n> commits and merges between the last tagged commit and the tip of your\n> branch(es) are indeed from you, or if an intruder piled fake ones on top\n> of your commits (until you try to push again and discover that the history\n> does not fast-forward, that is).\n>\n> We have been discussing an addition of \"git push -s\" to let people sign\n> their pushes (instead of having to sign every commit or add signed\n> tag). The implementation alternatives were being bikeshed but not of much\n> interest in this message, but the user experience would go like this:\n\nAlso, if we're adding branch information, I'd say that a description\nof the branch is more important than a signature. Right now we lack\neven that.\n\nIt would be lovely if people could annotate their branches with\ndescriptions, so that when I pull a \"for-linus\" branch, if it has a\ndescription, the description of the branch makes it into the merge\nmessage. Our merge messages are often not very informative.\n\nI realize that cryptographic signature sound very important right now,\nbut in the end, *real* trust comes from people, not from signatures.\nRealistically, I checked a few signatures this time around due to the\nk.org issues, but at the same thing, the thing that made me trust most\nof it was just looking at commits and the email messages. The\nunconscious and non-cryptographic \"signature\" of a person acting like\nyou expect a person to act.\n\nTechnical measures can be subverted, and I think we should also think\nabout the social side. Every time somebody mentions a signature, I\nwant to also mention \"human readability\", because I think that matters\nas much, if not more.\n\nSo I'm not against signed pushes, but quite frankly, if you add some\nper-branch signature, I would argue against it unless that signature\nalso comes with information that allows us to do a better job of human\ncommunication too. Like a branch description.\n\nImagine, for example, than when you do a\n\n  git push -s ..\n\ngit would *require* you to actually write a message about what you are\npushing. And when somebody pulls it, and creates a merge commit, that\nexplanation would become part of the merge message. The \"signature\"\npart of the \"-s\" should be thought of as the *much* less interesting\npart - that's just a small detail that git can use to verify\nsomething, but it doesn't actually matter for the contents of the\npull. Not like the actual human-readable message would.\n\nNow *that* would be lovely. No?\n\n                       Linus\n"},{"id":"175464","messageId":"4E7085E6.3060509@alum.mit.edu","threadId":"28380","inReplyTo":"CA+55aFy0b+eozmzbKD4RXcJ7e3WCpf7BV1n1qXHOeEwSHZKOXw@mail.gmail.com","subject":"Re: Fwd: [Survey] Signed push","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-14T10:45:58Z","receivedAt":"2011-09-14T10:45:58Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/14/2011 09:06 AM, Linus Torvalds wrote:\n> So I'm not against signed pushes, but quite frankly, if you add some\n> per-branch signature, I would argue against it unless that signature\n> also comes with information that allows us to do a better job of human\n> communication too. Like a branch description.\n> \n> Imagine, for example, than when you do a\n> \n>   git push -s ..\n> \n> git would *require* you to actually write a message about what you are\n> pushing. And when somebody pulls it, and creates a merge commit, that\n> explanation would become part of the merge message. The \"signature\"\n> part of the \"-s\" should be thought of as the *much* less interesting\n> part - that's just a small detail that git can use to verify\n> something, but it doesn't actually matter for the contents of the\n> pull. Not like the actual human-readable message would.\n> \n> Now *that* would be lovely. No?\n\nInstead of \"like a branch description\", why not implement branch\ndescriptions directly?\n\nI wish that one could annotate a branch (e.g., at creation) and have the\nannotation follow the branch around.  This would be a useful place to\nrecord *why* you created the branch, your plans for it, etc.  The\nannotation should be modifiable, because often a branch evolves in\nunforeseen ways during its lifetime.  Anybody could read the annotation\nto get a quick idea of what kind of work is in progress.\n\nSuch a branch annotation could be used in pull requests, the cover\nletter of patch series emails, merge commit log messages, etc.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"175465","messageId":"vpqfwjzxu6i.fsf@bauges.imag.fr","threadId":"28380","inReplyTo":"4E7085E6.3060509@alum.mit.edu","subject":"Re: Fwd: [Survey] Signed push","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2011-09-14T11:03:17Z","receivedAt":"2011-09-14T11:03:17Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> I wish that one could annotate a branch (e.g., at creation) and have the\n> annotation follow the branch around.  This would be a useful place to\n> record *why* you created the branch, your plans for it, etc.  The\n> annotation should be modifiable, because often a branch evolves in\n> unforeseen ways during its lifetime.  Anybody could read the annotation\n> to get a quick idea of what kind of work is in progress.\n\nWould the notes mechanism be able to annotate ref names instead of\ncommit sha1?\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"175466","messageId":"CACsJy8DKbkryuFo0uHnPUvpkui7+Vm4bS_ki5F7mNx=5UoGGsA@mail.gmail.com","threadId":"28380","inReplyTo":"vpqfwjzxu6i.fsf@bauges.imag.fr","subject":"Re: Fwd: [Survey] Signed push","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-09-14T11:46:54Z","receivedAt":"2011-09-14T11:46:54Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Sep 14, 2011 at 9:03 PM, Matthieu Moy\n<Matthieu.Moy@grenoble-inp.fr> wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n>\n>> I wish that one could annotate a branch (e.g., at creation) and have the\n>> annotation follow the branch around.  This would be a useful place to\n>> record *why* you created the branch, your plans for it, etc.  The\n>> annotation should be modifiable, because often a branch evolves in\n>> unforeseen ways during its lifetime.  Anybody could read the annotation\n>> to get a quick idea of what kind of work is in progress.\n>\n> Would the notes mechanism be able to annotate ref names instead of\n> commit sha1?\n\nSpeaking from someone who has few experience with git-notes, no I\ndon't think current git-notes can do that. But similar mechanism can\nbe added, targeting ref instead of sha-1. But the question is, is\nbranch description local or public?\n\nBranch description sounds local to me. I just record a branch's\npurpose and status (the latter is more important to me). If it's\nlocal, we just need to extend ref format to store extra text in\naddition to SHA-1.\n\nIf it's public, perhaps if we have a good way to:\n - convert arbitrary text to a ref (maybe just converting spaces to hyphens)\n - specify a ref without writing the whole ref name (reminds me of\nshort sha-1 vs full sha-1)\n\nthen we could use branch name as branch description. The default merge\ncommit messages can be updated to convert back branch name (which is\nalso the branch description) to human-readable text.\n-- \nDuy\n"},{"id":"175468","messageId":"CACsJy8Dwu2U-7eEZU-VYmcrA7JwtvUkJS5SywXjZWoE1twchhQ@mail.gmail.com","threadId":"28380","inReplyTo":"7vaaa8xufi.fsf@alter.siamese.dyndns.org","subject":"Re: [Survey] Signed push","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-09-14T11:58:42Z","receivedAt":"2011-09-14T11:58:42Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Sep 14, 2011 at 2:45 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> 1. Improved pull requests.\n>\n> ...\n>\n> An alternative that I am considering is to let the requester say this\n> instead:\n>\n>    are available in the git repository at:\n>      git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f\n>\n> without adding the extra line.\n>\n> That is, to allow fetching the history up to an explicitly named commit\n> object. This would only involve a change to fetch-pack at the receiving\n> end; just match the commit object name given from the command line against\n> the ls-remote response and ask upload-pack to give the history leading to\n> it. The released versions of Git already will happily oblige, as long as\n> the commit object named in the request message still sits at the tip of\n> the intended branch.\n>\n> Do you think it is worthwhile to pursue this alternative?\n\nStupid question, if we agree to go with signed push, can we also sign\npull requests and verify them when we pull? I suppose most of the\ntime, pulling can be done automatically by extracting pull url from\nthe request. This would make pull/push both signed.\n\nBTW, there's a third way (rsync is obsolete) to carry changes away in\nhuman-unreadable way: bundles. Should we also sign the bundles too (I\nguess we could just do the same as in signed push).\n-- \nDuy\n"},{"id":"175469","messageId":"201109141428.53163.johanh@opera.com","threadId":"28380","inReplyTo":"vpqfwjzxu6i.fsf@bauges.imag.fr","subject":"Re: Fwd: [Survey] Signed push","fromName":"Johan Herland","fromEmail":"johanh@opera.com","sentAt":"2011-09-14T12:28:52Z","receivedAt":"2011-09-14T12:28:52Z","isPatch":false,"sender":{"key":"johanh@opera.com","avatar":null},"body":"On Wednesday 14. September 2011, Matthieu Moy wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n> > I wish that one could annotate a branch (e.g., at creation) and\n> > have the annotation follow the branch around.  This would be a\n> > useful place to record *why* you created the branch, your plans\n> > for it, etc.  The annotation should be modifiable, because often a\n> > branch evolves in unforeseen ways during its lifetime.  Anybody\n> > could read the annotation to get a quick idea of what kind of work\n> > is in progress.\n> \n> Would the notes mechanism be able to annotate ref names instead of\n> commit sha1?\n\nThis has been discussed on the list before, but I'm too lazy to dig up a \nreference, so:\n\nThe notes mechanism can in principle annotate anything that has a SHA1 \nsum. The notes tree is really only a key->value mapping using SHA1s as \nkeys and Git objects (typically blobs) as values.\n\nHOWEVER, \"git notes prune\" will assume that the SHA1 keys are supposed \nto identify existing git objects, and will delete any note whose SHA1 \nkey does not identify a reachable git object.\n\nHence, if you promise to never run \"git notes prune\" on \nrefs/notes/branch-descriptions, you could use that ref to store your \nbranch descriptions keyed by the SHA1 of your branch name.\n\nThe obvious deficiency with this scheme is that if your branch name is \ndifferent in some repos, the branch description will be lost in those \nrepos unless you rewrite the refs/notes/branch-descriptions notes tree \naccordingly.\n\n\n...Johan\n\n-- \nJohan Herland, <johanh@opera.com>\nCore Developer, Opera Software ASA\n"},{"id":"175470","messageId":"20110914125621.GE16815@dhcp-172-31-195-159.cam.corp.google.com","threadId":"28380","inReplyTo":"201109141428.53163.johanh@opera.com","subject":"Re: Fwd: [Survey] Signed push","fromName":"Ted Ts'o","fromEmail":"tytso@mit.edu","sentAt":"2011-09-14T12:56:21Z","receivedAt":"2011-09-14T12:56:21Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Wed, Sep 14, 2011 at 02:28:52PM +0200, Johan Herland wrote:\n> On Wednesday 14. September 2011, Matthieu Moy wrote:\n> > Michael Haggerty <mhagger@alum.mit.edu> writes:\n> > > I wish that one could annotate a branch (e.g., at creation) and\n> > > have the annotation follow the branch around.  This would be a\n> > > useful place to record *why* you created the branch, your plans\n> > > for it, etc.  The annotation should be modifiable, because often a\n> > > branch evolves in unforeseen ways during its lifetime.  Anybody\n> > > could read the annotation to get a quick idea of what kind of work\n> > > is in progress.\n> > \n> HOWEVER, \"git notes prune\" will assume that the SHA1 keys are supposed \n> to identify existing git objects, and will delete any note whose SHA1 \n> key does not identify a reachable git object.\n> \n> Hence, if you promise to never run \"git notes prune\" on \n> refs/notes/branch-descriptions, you could use that ref to store your \n> branch descriptions keyed by the SHA1 of your branch name.\n\nIt seems like notes is the wrong place to encode this.  If people\nreally want this, what if there was a convention where there could be\na separate branch head: ref/heads/META\n\nwhich contained a directory structure like this:\n\n<e-mail>/key\t\t\t# The developer's GPG key\n<e-mail>/<tree>/URL\t\t# URL of developer's tree named <tree>\n<e-mail>/<tree>/description\t# Descrition of <tree>\n<e-mail>/<tree>/branch/<branch-name>\t# A description of that branch\n\netc.\n\nSince it's a separate branch head, the contents can be pushed around\nand merged very easily, and there's no danger of the information\ngetting lost via a garbage collection or prune operation.\n\nIf there was an association between a local branch and <e-mail>/<tree>\nthat it was tracking, then either a modified git core or porcelein\ncommand could get the information from the META tree.  It would also\nmake it easy to fetch a developer's GPG key without having to go to\noutside GPG key servers, which is a minor benefit (although maybe\nthat's not worth it).\n\n\t     \t   \t   \t      \t - Ted\n"},{"id":"175475","messageId":"CA+55aFw08zEeWovDPRGCM2f-xCuamJogFzigka4=mfcpJbZpsA@mail.gmail.com","threadId":"28380","inReplyTo":"4E7085E6.3060509@alum.mit.edu","subject":"Re: Fwd: [Survey] Signed push","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2011-09-14T15:25:15Z","receivedAt":"2011-09-14T15:25:15Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"On Wed, Sep 14, 2011 at 3:45 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n>\n> Instead of \"like a branch description\", why not implement branch\n> descriptions directly?\n\nMostly because of just human interface issues.\n\nWe already have a \"repository description\", and it's quite commonly\nnever even filled in. For branches, that would be doubly true, because\na lot of branches are throw-away.\n\nSo I think it would work if we made it part of of something like \"git\npush -s\" - because that's when it starts mattering to others.\n\n> I wish that one could annotate a branch (e.g., at creation) and have the\n> annotation follow the branch around.  This would be a useful place to\n> record *why* you created the branch, your plans for it, etc.  The\n> annotation should be modifiable, because often a branch evolves in\n> unforeseen ways during its lifetime.  Anybody could read the annotation\n> to get a quick idea of what kind of work is in progress.\n\nI wouldn't be against that as a concept, I just think you'd be a small\nsmall minority, and most branches would never get annotated.\n\nBut I don't really care deeply how it actually works - my main issue\nis that git makes it way too easy to have bad merge messages. I think\npart of that is an even simpler idiocy: we never even fire up the\neditor by default for a \"git merge\", but we do for a \"git commit\".\nThat was a design mistake, and it means that if you want to actually\nadd a note to a merge, you have to do extra work. So people don't.\n\nNow people do \"git merge\" in scripts etc, so we can't fix it ;-(\n\n                    Linus\n"},{"id":"175476","messageId":"CA+55aFyGRM132OzoJR7wZ8wETvxrFWSmSMjMJnVOKP+6vys-Sw@mail.gmail.com","threadId":"28380","inReplyTo":"vpqfwjzxu6i.fsf@bauges.imag.fr","subject":"Re: Fwd: [Survey] Signed push","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2011-09-14T15:27:35Z","receivedAt":"2011-09-14T15:27:35Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"On Wed, Sep 14, 2011 at 4:03 AM, Matthieu Moy\n<Matthieu.Moy@grenoble-inp.fr> wrote:\n>\n> Would the notes mechanism be able to annotate ref names instead of\n> commit sha1?\n\nThat would be a horrible, horrible notion.\n\nIt's quite common to have multiple branches with the same SHA1. It\nmight be in the \"experimental-development\" branch, but it got through\ntesting with flying colors and deemed to be stable, so it got upgraded\nto the \"for-linus\" branch, and there hasn't been any other development\nsince. So now both \"for-linus\" and \"experimental-development\" are the\nsame commit, but they are very much not the same branch!\n\nSo no, don't confuse branch *contents* with branch *descriptions*.\n\n                          Linus\n"},{"id":"175477","messageId":"vpqhb4f5dwe.fsf@bauges.imag.fr","threadId":"28380","inReplyTo":"CA+55aFyGRM132OzoJR7wZ8wETvxrFWSmSMjMJnVOKP+6vys-Sw@mail.gmail.com","subject":"Re: Fwd: [Survey] Signed push","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2011-09-14T15:42:25Z","receivedAt":"2011-09-14T15:42:25Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> On Wed, Sep 14, 2011 at 4:03 AM, Matthieu Moy\n> <Matthieu.Moy@grenoble-inp.fr> wrote:\n>>\n>> Would the notes mechanism be able to annotate ref names instead of\n>> commit sha1?\n>\n> That would be a horrible, horrible notion.\n>\n> It's quite common to have multiple branches with the same SHA1. \n\nThat's why my question was about annotating ref _names_, yes. As Johan\nHerland pointed out, this would be possible in theory, but not really in\npractice.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"175479","messageId":"201109141814.04752.johan@herland.net","threadId":"28380","inReplyTo":"CA+55aFyGRM132OzoJR7wZ8wETvxrFWSmSMjMJnVOKP+6vys-Sw@mail.gmail.com","subject":"Re: Fwd: [Survey] Signed push","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2011-09-14T16:14:04Z","receivedAt":"2011-09-14T16:14:04Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Wednesday 14. September 2011, Linus Torvalds wrote:\n> On Wed, Sep 14, 2011 at 4:03 AM, Matthieu Moy\n> \n> <Matthieu.Moy@grenoble-inp.fr> wrote:\n> > Would the notes mechanism be able to annotate ref names instead of\n> > commit sha1?\n> \n> That would be a horrible, horrible notion.\n> \n> It's quite common to have multiple branches with the same SHA1. It\n> might be in the \"experimental-development\" branch, but it got through\n> testing with flying colors and deemed to be stable, so it got\n> upgraded to the \"for-linus\" branch, and there hasn't been any other\n> development since. So now both \"for-linus\" and\n> \"experimental-development\" are the same commit, but they are very\n> much not the same branch!\n> \n> So no, don't confuse branch *contents* with branch *descriptions*.\n\nI don't think the suggestion was about annotating the branch tip as a \nway of describing the branch. Rather, you create a _new_ SHA1 that \nidentifies the branch (e.g. SHA1(branch_name) ), and then annotate \n_that_ SHA1. As I said, that _can_ be done with the notes \ninfrastructure, but - as Ted noted - there might be better solutions to \nstoring branch descriptions.\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"175481","messageId":"7vobynui8a.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"CA+55aFy0b+eozmzbKD4RXcJ7e3WCpf7BV1n1qXHOeEwSHZKOXw@mail.gmail.com","subject":"Re: Fwd: [Survey] Signed push","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-14T17:49:41Z","receivedAt":"2011-09-14T17:49:41Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> I think that would probably be a good idea, although I'd actually\n> prefer you to be more verbose, and more human-friendly, and actually\n> talk about the commit in a readable way. Get rid of the *horrible*\n> BRANCH-NOT-VERIFIED message (that actually messes up pull requests if\n> mirroring is a bit delayed and throws away more important\n> information), and instead just have a blurb afterwards saying\n> something human-readable like\n>\n>  Top commit 1f51b001cccf: \"Merge branches 'cns3xxx/fixes',\n>  'omap/fixes' and 'davinci/fixes' into fixes\"\n>\n>  and at *that* point you might have a \"UNVERIFIED\" notice for people\n> to check if they forgot to push.\n\nThat UNVERIFIED thing was neither my favorite nor my idea, and I'd happily\nrip it out in any second ;-)\n\n>> An alternative that I am considering is to let the requester say this\n>> instead:\n>>\n>>    are available in the git repository at:\n>>      git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f\n>>\n>> without adding the extra line.\n>\n> The extra line in the pull request is cheap - it's not like we need to\n> ration them. The above format, in contrast, requires that the person\n> doing the *pull* have a recent enough git client, otherwise the merge\n> commit message will be just horrible.\n\nIn a re-roll patch I've added \";# branch-name\" at the end of that line for\npeople with older git, but existing git wouldn't allow you to fetch anything\nbut refs so you won't risk getting \"just horrible\" merge message ;-)\n\n> ... And what if the branch was updated since, so *no* branch name\n> matches - does that mean that you'd disallow the pull entirely?\n\nYou are right about ambiguities, but when the specified commit does not\nmatch the branch, it was indeed my intention to claim it is a _feature_ \nthat pull fails, as you would be getting something different from what you\nthought was promised by the requester with bait-and-switch.\n\n> Also, if we're adding branch information, I'd say that a description\n> of the branch is more important than a signature. Right now we lack\n> even that.\n\nI do not particularly want to go into that tangent, and I do agree with\nyour later message in this thread that it may make sense to tie the\npublishing (and possibly recording) of the description of the branch to\n\"push -s\"; people simply do not have reason to name throw-away branches.\n\n> It would be lovely if people could annotate their branches with\n> descriptions, so that when I pull a \"for-linus\" branch, if it has a\n> description, the description of the branch makes it into the merge\n> message.\n\nI'm wondering if this could be something we can share between the push\ncertificate \"Into this repository, I pushed this commit to that branch,\nwhose pupose is...\" and pull request \"...so please pull it to merge into\nyour history.\" There are three possibile orders of things a lieutenant or\na contributor may want to do after perfecting his tree locally:\n\n (1) Write pull-request, and then \"push -s\".\n\n (2) \"push -s\", and then write pull-request.\n\n (3) \"push -s\" auto-mailing a pull-request.\n\n> I realize that cryptographic signature sound very important right now,\n> but in the end, *real* trust comes from people, not from signatures.\n> ...\n> Technical measures can be subverted, and I think we should also think\n> about the social side. Every time somebody mentions a signature, I\n> want to also mention \"human readability\", because I think that matters\n> as much, if not more.\n\nI obviously agree 100%, but that is an argument against trusting only\ntechnical measures---right now, we do not have a good technical measure to\nvalidate latest commits not yet contained in any tagged releases.\n\nA piece of e-mail to the kernel list from you that says \"I pushed it out\nand the tip is this SHA-1\", if it is written in good English with a bit of\nyour usual humor sprinkled in, would in practice be just as good as GPG \nfor the kernel list regulars who can recognize your style and serve as\nthat \"technical measure\" (by the way \"What's cooking\" does have the tips\nof master and next branches for this exact reason).\n\n> Imagine, for example, than when you do a\n>\n>   git push -s ..\n>\n> git would *require* you to actually write a message about what you are\n> pushing.\n\nYeah, we could go in that direction.\n"},{"id":"175482","messageId":"7vk49bui4f.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"CA+55aFw08zEeWovDPRGCM2f-xCuamJogFzigka4=mfcpJbZpsA@mail.gmail.com","subject":"Re: Fwd: [Survey] Signed push","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-14T17:52:00Z","receivedAt":"2011-09-14T17:52:00Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> Now people do \"git merge\" in scripts etc, so we can't fix it ;-(\n\nYes you can, by teaching \"git merge -e\" to open an editor ;-).\n\nIn the meantime, \"commit --amend\" is your friend.\n"},{"id":"175490","messageId":"CA+55aFyUxmPWdG1j-0t9h9g9=1MmLt7w8fdmz+dZjS=1aDgWiA@mail.gmail.com","threadId":"28380","inReplyTo":"7vk49bui4f.fsf@alter.siamese.dyndns.org","subject":"Re: Fwd: [Survey] Signed push","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2011-09-14T18:36:39Z","receivedAt":"2011-09-14T18:36:39Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"On Wed, Sep 14, 2011 at 10:52 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Linus Torvalds <torvalds@linux-foundation.org> writes:\n>\n>> Now people do \"git merge\" in scripts etc, so we can't fix it ;-(\n>\n> Yes you can, by teaching \"git merge -e\" to open an editor ;-).\n>\n> In the meantime, \"commit --amend\" is your friend.\n\nThe problem with both of those are human: because it's extra work,\nit's not going to get done.\n\nIn contrast, if it's extra work to *avoid* editing the merge message,\npeople probably would see the editor pop up, and start adding a few\nsmall notes.\n\nThat's why \"default behavior\" matters so much. It's not that it's not\n*possible* to edit a merge message, it's that nobody ever does!\n\n                        Linus\n"},{"id":"175507","messageId":"4E7101F3.1090204@mit.edu","threadId":"28380","inReplyTo":"7vaaa8xufi.fsf@alter.siamese.dyndns.org","subject":"Re: [Survey] Signed push","fromName":"Andy Lutomirski","fromEmail":"luto@mit.edu","sentAt":"2011-09-14T19:35:15Z","receivedAt":"2011-09-14T19:35:15Z","isPatch":false,"sender":{"key":"luto@mit.edu","avatar":null},"body":"On 09/13/2011 09:45 AM, Junio C Hamano wrote:\n> \n> An alternative that I am considering is to let the requester say this\n> instead:\n> \n>     are available in the git repository at:\n>       git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f\n> \n> without adding the extra line.\n> \n> That is, to allow fetching the history up to an explicitly named commit\n> object. This would only involve a change to fetch-pack at the receiving\n> end; just match the commit object name given from the command line against\n> the ls-remote response and ask upload-pack to give the history leading to\n> it. The released versions of Git already will happily oblige, as long as\n> the commit object named in the request message still sits at the tip of\n> the intended branch.\n\nI would love this feature on the pull/fetch interface, but for a\ncompletely different reason.  Sometimes I want to pull a particular\nobject (usually a commit, but sometimes just a tree or blob) from\n*myself*, and having to stick it on a branch is annoying.\n\nOne use-case is when applying a patch in git's extended format.  If I\nknow where it came from, I ought to be able to pull the blobs it depends\non to enable three-way merge.  I think that this is essentially\nimpossible remotely right now.\n\nOf course, merging with the result of the pull will result in terrible\nautomatically-generated messages, but it's easy to fix that up manually.\n\nThis is one thing that I think Mercurial handles better than git.  (And\napologies for the noise if I've missed a way to do this with current\ngit.  I've looked, but maybe I missed some magic way to do this.)\n\n--Andy\n"},{"id":"175510","messageId":"7vwrdasvr7.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"4E7101F3.1090204@mit.edu","subject":"Re: [Survey] Signed push","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-14T20:40:28Z","receivedAt":"2011-09-14T20:40:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andy Lutomirski <luto@MIT.EDU> writes:\n\n>> An alternative that I am considering is to let the requester say this\n>> instead:\n>> \n>>     are available in the git repository at:\n>>       git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f\n>> \n>> without adding the extra line.\n>> \n>> That is, to allow fetching the history up to an explicitly named commit\n>> object. This would only involve a change to fetch-pack at the receiving\n>> end; just match the commit object name given from the command line against\n>> the ls-remote response and ask upload-pack to give the history leading to\n>> it....\n>\n> I would love this feature on the pull/fetch interface, but for a\n> completely different reason.  Sometimes I want to pull a particular\n> object (usually a commit, but sometimes just a tree or blob) from\n> *myself*, and having to stick it on a branch is annoying.\n\nI am afraind that it is not going to happen; see\n\n    http://article.gmane.org/gmane.comp.version-control.git/181317\n\nfor a rationale.\n"},{"id":"175511","messageId":"CAObL_7Er5mMuNaNgLDptBHw-zrqEeHHqXkC+TNf9G81_+NmFKw@mail.gmail.com","threadId":"28380","inReplyTo":"7vwrdasvr7.fsf@alter.siamese.dyndns.org","subject":"Re: [Survey] Signed push","fromName":"Andrew Lutomirski","fromEmail":"luto@mit.edu","sentAt":"2011-09-14T20:49:31Z","receivedAt":"2011-09-14T20:49:31Z","isPatch":false,"sender":{"key":"luto@mit.edu","avatar":null},"body":"On Wed, Sep 14, 2011 at 1:40 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Andy Lutomirski <luto@MIT.EDU> writes:\n>\n>>> An alternative that I am considering is to let the requester say this\n>>> instead:\n>>>\n>>>     are available in the git repository at:\n>>>       git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f\n>>>\n>>> without adding the extra line.\n>>>\n>>> That is, to allow fetching the history up to an explicitly named commit\n>>> object. This would only involve a change to fetch-pack at the receiving\n>>> end; just match the commit object name given from the command line against\n>>> the ls-remote response and ask upload-pack to give the history leading to\n>>> it....\n>>\n>> I would love this feature on the pull/fetch interface, but for a\n>> completely different reason.  Sometimes I want to pull a particular\n>> object (usually a commit, but sometimes just a tree or blob) from\n>> *myself*, and having to stick it on a branch is annoying.\n>\n> I am afraind that it is not going to happen; see\n>\n>    http://article.gmane.org/gmane.comp.version-control.git/181317\n>\n> for a rationale.\n>\n\nDo you mean that it's a security feature?  What if a .git/config\noption existed to allow this use?  Or even a git upload-pack option\nthat turned it *on* and was stripped by git-shell?\n\n--Andy\n"},{"id":"175512","messageId":"4E711420.9080409@vilain.net","threadId":"28380","inReplyTo":"7vobynui8a.fsf@alter.siamese.dyndns.org","subject":"Re: Fwd: [Survey] Signed push","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2011-09-14T20:52:48Z","receivedAt":"2011-09-14T20:52:48Z","isPatch":false,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"[re-send as text-only.  sorry, new system]\n\nOn 9/14/11 10:49 AM, Junio C Hamano wrote:\n>> The extra line in the pull request is cheap - it's not like we need to\n>> >  ration them. The above format, in contrast, requires that the person\n>> >  doing the*pull*  have a recent enough git client, otherwise the merge\n>> >  commit message will be just horrible.\n> In a re-roll patch I've added \";# branch-name\" at the end of that line for\n> people with older git, but existing git wouldn't allow you to fetch anything\n> but refs so you won't risk getting \"just horrible\" merge message;-)\n>\n\nIf the system is watertight enough, then you could have verified pushes \nONLY under some new refspace, like:\n\nrefs/forks/forkid/branch\n\n\"forkid\" is set up when you choose to \"follow\" someone's pushes.  ie, \nyou say something like:\n\ngit fork follow linustorvalds@osdl.org \n<http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0x17762C4676E21CBB>\n\n\"torvalds@osdl.org\" here representing a PGP key ID search string.  It \ncould be instead, \"0x17762c4676e21cbb\"\n\nAnd then the \"refs/forks/linus/xxx\" space gets populated as signed \npushes are seen on the network (perhaps when fetching from a pull \nrequest, or perhaps via a service).  A configuration option can be set \nto warn if you are not merging a signed branch.  If the new \"pull \nrequest/push\" object is a distinct object type or tag object, then it \ncould be the destination of the 'refs/forks/...' ref, and the branch \ndesription and hence the default merge message be retrieved from that.\n\nSam\n"},{"id":"175514","messageId":"20110914210512.GA20294@elie","threadId":"28380","inReplyTo":"CACsJy8Dwu2U-7eEZU-VYmcrA7JwtvUkJS5SywXjZWoE1twchhQ@mail.gmail.com","subject":"Re: [Survey] Signed push","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-09-14T21:05:12Z","receivedAt":"2011-09-14T21:05:12Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Nguyen Thai Ngoc Duy wrote:\n> On Wed, Sep 14, 2011 at 2:45 AM, Junio C Hamano <gitster@pobox.com> wrote:\n\n>> An alternative that I am considering is to let the requester say this\n>> instead:\n>>\n>>    are available in the git repository at:\n>>      git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f\n[...]\n> Stupid question, if we agree to go with signed push, can we also sign\n> pull requests and verify them when we pull? I suppose most of the\n> time, pulling can be done automatically by extracting pull url from\n> the request. This would make pull/push both signed.\n>\n> BTW, there's a third way (rsync is obsolete) to carry changes away in\n> human-unreadable way: bundles. Should we also sign the bundles too (I\n> guess we could just do the same as in signed push).\n\nIf I understand you correctly, then ordinary PGP email signing[1]\nshould work for that already.  In your first example, the receiver can\nmake sure whatever process grabs a pull request verifies it, and in\nthe second example, the receiver checks the signature on her email\nbefore saving a bundle and passing it to \"git fetch\".\n\n[1] http://www.phildev.net/pgp/gpgmua.html\n"},{"id":"175518","messageId":"CACsJy8BEES2j8K1v23RQQS=R1vRm1SVizBGFzq0wsDcMvC6Fjw@mail.gmail.com","threadId":"28380","inReplyTo":"20110914210512.GA20294@elie","subject":"Re: [Survey] Signed push","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-09-14T22:42:40Z","receivedAt":"2011-09-14T22:42:40Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Sep 15, 2011 at 7:05 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Nguyen Thai Ngoc Duy wrote:\n>> On Wed, Sep 14, 2011 at 2:45 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n>>> An alternative that I am considering is to let the requester say this\n>>> instead:\n>>>\n>>>    are available in the git repository at:\n>>>      git://git.kernel.org/pub/flobar.git/ 5738c9c21e53356ab5020912116e7f82fd2d428f\n> [...]\n>> Stupid question, if we agree to go with signed push, can we also sign\n>> pull requests and verify them when we pull? I suppose most of the\n>> time, pulling can be done automatically by extracting pull url from\n>> the request. This would make pull/push both signed.\n>>\n>> BTW, there's a third way (rsync is obsolete) to carry changes away in\n>> human-unreadable way: bundles. Should we also sign the bundles too (I\n>> guess we could just do the same as in signed push).\n>\n> If I understand you correctly, then ordinary PGP email signing[1]\n> should work for that already.  In your first example, the receiver can\n> make sure whatever process grabs a pull request verifies it, and in\n> the second example, the receiver checks the signature on her email\n> before saving a bundle and passing it to \"git fetch\".\n\nYes, I think we can do that already. It's just more convenient to\nteach \"git fetch/pull\" to take pull requests and automatically verify\nthem. Some repositories may also want to enforce signing and we can do\nthat by setting config file and fetch/pull refuses if pull requests\nare not signed. We can also store the sign as git notes, just like in\ngit-push (extra work if it has to be done manually).\n\n> [1] http://www.phildev.net/pgp/gpgmua.html\n-- \nDuy\n"},{"id":"175524","messageId":"E9E05FA85D0F4461BAE9ECAFE25CD84E@PhilipOakley","threadId":"28380","inReplyTo":"201109141814.04752.johan@herland.net","subject":"Re: Fwd: [Survey] Signed push","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":"2011-09-14T22:51:27Z","receivedAt":"2011-09-14T22:51:27Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Johan Herland\" <johan@herland.net>\n.\n> _that_ SHA1. As I said, that _can_ be done with the notes\n> infrastructure, but - as Ted noted - there might be better solutions to\n> storing branch descriptions.\n>\nIs one option to store the branch description (if any) on line two of the \n<branch name> file in .git\\refs\\heads.\nThat is, from byte 42 onward, after the 40 byte sha1 and its LF.\nOlder systems would simply overwrite it, while newer systems would be able \nto read it. The fixed format of the first 41 chars alllows sensible checks \nin the various places it is used.\n\nPhilip Oakley \n"},{"id":"175525","messageId":"CA+55aFxFnAjpSAd+uB25BuZXBJGvN59qNMmF3fzvky8XK_DP0A@mail.gmail.com","threadId":"28380","inReplyTo":"E9E05FA85D0F4461BAE9ECAFE25CD84E@PhilipOakley","subject":"Re: Fwd: [Survey] Signed push","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2011-09-14T23:30:10Z","receivedAt":"2011-09-14T23:30:10Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"On Wed, Sep 14, 2011 at 3:51 PM, Philip Oakley <philipoakley@iee.org> wrote:\n>\n> Is one option to store the branch description (if any) on line two of the\n> <branch name> file in .git\\refs\\heads.\n\nOr even on line one.\n\nWe already basically do that for the magic FETCH_HEAD branch, and use\nit to populate the merge commit. Extending that kind of thing to all\nbranches might be a nice idea.\n\nOf course, then the question becomes \"what about packed refs\"? Do you\njust leave the unpacked ref in place for those?\n\n                          Linus\n"},{"id":"175527","messageId":"7v8vpqsn7y.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"CA+55aFxFnAjpSAd+uB25BuZXBJGvN59qNMmF3fzvky8XK_DP0A@mail.gmail.com","subject":"Re: Fwd: [Survey] Signed push","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-14T23:44:49Z","receivedAt":"2011-09-14T23:44:49Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> On Wed, Sep 14, 2011 at 3:51 PM, Philip Oakley <philipoakley@iee.org> wrote:\n>>\n>> Is one option to store the branch description (if any) on line two of the\n>> <branch name> file in .git\\refs\\heads.\n>\n> Or even on line one.\n>\n> We already basically do that for the magic FETCH_HEAD branch, and use\n> it to populate the merge commit. Extending that kind of thing to all\n> branches might be a nice idea.\n>\n> Of course, then the question becomes \"what about packed refs\"? Do you\n> just leave the unpacked ref in place for those?\n\nSeriously, storage format is not an issue at all and you know it.  The\nsemantics is.\n\nWhat commands use the description and for what purpose, how it is updated\nwhen the branch is repurposed, how it is propagated to other repositories,\nif there is a situation where two descriptions need to be merged, and if\nso how that merge happens, etc., etc.\n\nWe could store it in unused part of loose refs. We could add [branch\n\"master\"] description = ...  in the .git/config. The latter would even be\neasier for humans to edit by hand.\n\nIf we want to use the description when merging locally, for example,\nfmt-merge-msg needs to be taught to read it, which would mean we would\nneed an internal API \"read_branch_description()\", regardless of what\nstorage format we choose to use. If we want to use it for \"git pull\", then\nthe transport layer needs to become aware of it.\n"},{"id":"175594","messageId":"20110915175050.GA20495@sigill.intra.peff.net","threadId":"28380","inReplyTo":"CACsJy8BEES2j8K1v23RQQS=R1vRm1SVizBGFzq0wsDcMvC6Fjw@mail.gmail.com","subject":"Re: [Survey] Signed push","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-15T17:50:50Z","receivedAt":"2011-09-15T17:50:50Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Sep 15, 2011 at 08:42:40AM +1000, Nguyen Thai Ngoc Duy wrote:\n\n> Yes, I think we can do that already. It's just more convenient to\n> teach \"git fetch/pull\" to take pull requests and automatically verify\n> them. Some repositories may also want to enforce signing and we can do\n> that by setting config file and fetch/pull refuses if pull requests\n> are not signed. We can also store the sign as git notes, just like in\n> git-push (extra work if it has to be done manually).\n\nIsn't there a human element in the verification? I.e., I see a pull\nrequest, and we can computationally verify that it is signed by some\nkey. Now assuming GPG's web of trust works, that binds that key to an\nemail address and a real name. But how is that bound to the repository\nyou are actually fetching from (or more appropriately, that the commits\nmentioned are appropriate to be pulled)?\n\nThat is a policy that the human must decide upon seeing \"Oh, a pull\nrequest from developer X; I should pull that into my local branch Y\",\nand which they do implicitly when they manually run the pull command\nmentioned in the email.\n\nAnother way to think of it is that verifying the identity of the sender\n(which GPG does) is only one step. You also need an ACL saying that the\nsender is worth pulling from.\n\nSo either:\n\n  1. The human is still in the loop, in which case having git-pull\n     verify the sender's identity hasn't really done anything (because\n     probably their MUA already told them it was really from the\n     purported sender, and then they made the ACL decision in their head\n     before deciding to pull from you).\n\n  2. The human is not in the loop, and nothing is checking that ACL.\n\n-Peff\n"},{"id":"175655","messageId":"7viposfgvd.fsf_-_@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"7vobynui8a.fsf@alter.siamese.dyndns.org","subject":"[PATCH v3] request-pull: state what commit to expect","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-16T19:04:54Z","receivedAt":"2011-09-16T19:04:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Linus Torvalds <torvalds@linux-foundation.org> writes:\n>\n>> I think that would probably be a good idea, although I'd actually\n>> prefer you to be more verbose, and more human-friendly, and actually\n>> talk about the commit in a readable way. Get rid of the *horrible*\n>> BRANCH-NOT-VERIFIED message...\n>>\n>>  Top commit 1f51b001cccf: \"Merge branches 'cns3xxx/fixes',\n>>  'omap/fixes' and 'davinci/fixes' into fixes\"\n>>\n>>  and at *that* point you might have a \"UNVERIFIED\" notice for people\n>> to check if they forgot to push.\n>\n> That UNVERIFIED thing was neither my favorite nor my idea, and I'd happily\n> rip it out in any second ;-)\n\nSo this is the third round.\n\n-- >8 --\nThe message gives a detailed explanation of the commit the requester based\nthe changes on, but lacks information that is necessary for the person who\nperforms a fetch & merge in order to verify that the correct branch was\nfetched when responding to the pull request.\n\nAdd a few more lines to describe the commit at the tip expected to be\nfetched to the same level of detail as the base commit.\n\nAlso update the warning message slightly when the script notices that the\ncommit may not have been pushed.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\nA UI wart that we cannot fix without breaking backward compatibility is\nthat the \"end\" parameter (which defaults to HEAD and is assigned to $head\nvariable in the script) the requestor uses from the command line names a\ncommit (often the name of a local branch), but for the purpose of telling\nwhich ref to pull from the public repository, that is a _wrong_ thing to\ngive to the recipient.\n\nBecause the act of generating a request-pull message and the act of\npushing to the public repository are not linked in any way, the script\ndoes not know _how_ the requestor caused (or intends to cause) the commit\nto sit at the tip of which branch. There is no guarantee that a lazy \"git\npush\" that relies on the configured refspec will be (or have been) used,\nso even parsing the output from \"git push -n --porcelain -v $there\" would\nnot tell the script which branch the commit to be pulled is to be pushed\nout to, or if the branch is consistent with the request message.\n\nThe use of \"git ls-remote\" in the script and picking one of the refs that\nmatches the commit object at random from its output is unsatisfactory, but\nthat is unfortunately the best this script could do without correcting the\ndesign mistake and redefining what the \"end\" parameter means.\n\nIf we can break the backward compatibility and redefine that the \"end\"\nparameter now means the name of the branch at the public repository, it\nwould make the operation a lot more robust.  We could then:\n\n - $branch is what is given by the end user (it is an error not to give\n   the \"end\" parameter);\n - run \"git ls-remote $url $head\" to find $headrev;\n - generate the message and shortlog using the information obtained from\n   $url; and\n - get rid of \"did you forget to push\" message.\n\nWe could allow adding yet another argument which names a commit object\nlocally, and make sure if the $headrev observed by ls-remote does not\nmatch it.\n\n---\n git-request-pull.sh     |   34 +++++++++++++++++++---------------\n t/t5150-request-pull.sh |    6 ++++++\n 2 files changed, 25 insertions(+), 15 deletions(-)\n\ndiff --git a/git-request-pull.sh b/git-request-pull.sh\nindex afb75e8..438e7eb 100755\n--- a/git-request-pull.sh\n+++ b/git-request-pull.sh\n@@ -35,7 +35,7 @@ do\n \tshift\n done\n \n-base=$1 url=$2 head=${3-HEAD}\n+base=$1 url=$2 head=${3-HEAD} status=0\n \n test -n \"$base\" && test -n \"$url\" || usage\n baserev=$(git rev-parse --verify \"$base\"^0) &&\n@@ -51,25 +51,29 @@ find_matching_branch=\"/^$headrev\t\"'refs\\/heads\\//{\n }'\n branch=$(git ls-remote \"$url\" | sed -n -e \"$find_matching_branch\")\n url=$(git ls-remote --get-url \"$url\")\n-if test -z \"$branch\"\n-then\n-\techo \"warn: No branch of $url is at:\" >&2\n-\tgit log --max-count=1 --pretty='tformat:warn:   %h: %s' $headrev >&2\n-\techo \"warn: Are you sure you pushed $head there?\" >&2\n-\techo >&2\n-\techo >&2\n-\tbranch=..BRANCH.NOT.VERIFIED..\n-\tstatus=1\n-fi\n \n git show -s --format='The following changes since commit %H:\n \n   %s (%ci)\n \n-are available in the git repository at:' $baserev &&\n-echo \"  $url $branch\" &&\n-echo &&\n+are available in the git repository at:\n+' $baserev &&\n+echo \"  $url${branch+ $branch}\" &&\n+git show -s --format='\n+for you to fetch changes up to %H:\n+\n+  %s (%ci)\n+\n+----------------------------------------------------------------' $headrev &&\n \n git shortlog ^$baserev $headrev &&\n-git diff -M --stat --summary $patch $merge_base..$headrev || exit\n+git diff -M --stat --summary $patch $merge_base..$headrev || status=1\n+\n+if test -z \"$branch\"\n+then\n+\techo \"warn: No branch of $url is at:\" >&2\n+\tgit show -s --format='warn:   %h: %s' $headrev >&2\n+\techo \"warn: Are you sure you pushed '$head' there?\" >&2\n+\tstatus=1\n+fi\n exit $status\ndiff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh\nindex 9cc0a42..5bd1682 100755\n--- a/t/t5150-request-pull.sh\n+++ b/t/t5150-request-pull.sh\n@@ -193,8 +193,14 @@ test_expect_success 'pull request format' '\n \t  SUBJECT (DATE)\n \n \tare available in the git repository at:\n+\n \t  URL BRANCH\n \n+\tfor you to fetch changes up to OBJECT_NAME:\n+\n+\t  SUBJECT (DATE)\n+\n+\t----------------------------------------------------------------\n \tSHORTLOG\n \n \tDIFFSTAT\n-- \n1.7.7.rc1.3.g559357\n"},{"id":"175905","messageId":"7vy5xi4y3m.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"7viposfgvd.fsf_-_@alter.siamese.dyndns.org","subject":"Re: [PATCH v3] request-pull: state what commit to expect","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-20T23:01:49Z","receivedAt":"2011-09-20T23:01:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Here are three patches on top of the latest round of request-pull update.\nThe first two are to add a new option to \"git branch\" command so that a\ndescriptive text that explains what the purpose of the branch is, for use\nby other commands. And the last one builds on top of the patch this\nmessage is a response to, to use that information.\n\nAnd here is the first one, just an unrelated doc clean-up.\n\n-- >8 --\nSubject: [PATCH 1/3] branch doc: minor formatting fix\n\nWe tend to use typewriter font when writing command flags that are\nmeant to be typed literally by the user.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-branch.txt |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 507b8d0..79424a5 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -54,7 +54,7 @@ With a `-d` or `-D` option, `<branchname>` will be deleted.  You may\n specify more than one branch for deletion.  If the branch currently\n has a reflog then the reflog will also be deleted.\n \n-Use -r together with -d to delete remote-tracking branches. Note, that it\n+Use `-r` together with `-d` to delete remote-tracking branches. Note, that it\n only makes sense to delete remote-tracking branches if they no longer exist\n in the remote repository or if 'git fetch' was configured not to fetch\n them again. See also the 'prune' subcommand of linkgit:git-remote[1] for a\n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"175906","messageId":"7vty864y24.fsf_-_@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"7vy5xi4y3m.fsf@alter.siamese.dyndns.org","subject":"[PATCH 2/3] branch: teach --edit-description option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-20T23:02:43Z","receivedAt":"2011-09-20T23:02:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Using branch.$name.description as the configuration key, give users a\nplace to write about what the purpose of the branch is and things like\nthat, so that various subsystems, e.g. \"push -s\", \"request-pull\", and\n\"format-patch --cover-letter\", can later be taught to use this\ninformation.\n\nThe \"-m\" option similar to \"commit/tag\" is deliberately omitted, as the\nwhole point of branch description is about giving descriptive information\n(the name of the branch itself is a better place for information that fits\non a single-line).\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-branch.txt |    5 +++\n builtin/branch.c             |   68 ++++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 71 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 79424a5..12bdffc 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -14,6 +14,7 @@ SYNOPSIS\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n 'git branch' (-d | -D) [-r] <branchname>...\n+'git branch' --edit-description [<branchname>]\n \n DESCRIPTION\n -----------\n@@ -144,6 +145,10 @@ start-point is either a local or remote-tracking branch.\n \tlike '--track' would when creating the branch, except that where\n \tbranch points to is not changed.\n \n+--edit-description::\n+\tOpen an editor and edit the text to explain what the branch is\n+\tfor, to be used by various other commands (e.g. `request-pull`).\n+\n --contains <commit>::\n \tOnly list branches which contain the specified commit.\n \ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex f49596f..94319c4 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -606,11 +606,61 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int\n \treturn 0;\n }\n \n+struct branch_desc_cb {\n+\tconst char *config_name;\n+\tconst char *value;\n+};\n+\n+static int read_branch_desc(const char *var, const char *value, void *cb)\n+{\n+\tstruct branch_desc_cb *desc = cb;\n+\tif (strcmp(desc->config_name, var))\n+\t\treturn 0;\n+\tfree((char *)desc->value);\n+\treturn git_config_string(&desc->value, var, value);\n+}\n+\n+static const char edit_description[] = \"BRANCH_DESCRIPTION\";\n+\n+static int edit_branch_description(const char *branch_name)\n+{\n+\tstruct branch_desc_cb cb;\n+\tstruct strbuf name = STRBUF_INIT;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tFILE *fp;\n+\n+\tstrbuf_addf(&name, \"branch.%s.description\", branch_name);\n+\tcb.config_name = name.buf;\n+\tcb.value = NULL;\n+\tgit_config(read_branch_desc, &cb);\n+\n+\tif (cb.value)\n+\t\tstrbuf_addstr(&buf, cb.value);\n+\tif (!buf.len || buf.buf[buf.len-1] != '\\n')\n+\t\tstrbuf_addch(&buf, '\\n');\n+\tstrbuf_addf(&buf,\n+\t\t    \"# Please edit the description for the branch\\n\"\n+\t\t    \"#   %s\\n\"\n+\t\t    \"# Lines starting with '#' will be stripped.\\n\",\n+\t\t    branch_name);\n+\tfp = fopen(git_path(edit_description), \"w\");\n+\tif (fwrite(buf.buf, 1, buf.len, fp) < buf.len) {\n+\t\tstrbuf_release(&buf);\n+\t\treturn error(_(\"could not write branch description template: %s\\n\"),\n+\t\t\t     strerror(errno));\n+\t}\n+\tstrbuf_reset(&buf);\n+\tif (launch_editor(git_path(edit_description), &buf, NULL))\n+\t\treturn -1;\n+\tstripspace(&buf, 1);\n+\treturn git_config_set(name.buf, buf.buf);\n+}\n+\n int cmd_branch(int argc, const char **argv, const char *prefix)\n {\n \tint delete = 0, rename = 0, force_create = 0;\n \tint verbose = 0, abbrev = -1, detached = 0;\n-\tint reflog = 0;\n+\tint reflog = 0, edit_description = 0;\n \tenum branch_track track;\n \tint kinds = REF_LOCAL_BRANCH;\n \tstruct commit_list *with_commit = NULL;\n@@ -648,6 +698,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT('m', NULL, &rename, \"move/rename a branch and its reflog\", 1),\n \t\tOPT_BIT('M', NULL, &rename, \"move/rename a branch, even if target exists\", 2),\n \t\tOPT_BOOLEAN('l', NULL, &reflog, \"create the branch's reflog\"),\n+\t\tOPT_BOOLEAN(0, \"edit-description\", &edit_description,\n+\t\t\t    \"edit the description for the branch\"),\n \t\tOPT__FORCE(&force_create, \"force creation (when already exists)\"),\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"no-merged\", &merge_filter_ref,\n@@ -694,7 +746,19 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n-\telse if (argc == 0)\n+\telse if (edit_description) {\n+\t\tconst char *branch_name;\n+\t\tif (detached)\n+\t\t\tdie(\"Cannot give description to detached HEAD\");\n+\t\tif (!argc)\n+\t\t\tbranch_name = head;\n+\t\telse if (argc == 1)\n+\t\t\tbranch_name = argv[0];\n+\t\telse\n+\t\t\tusage_with_options(builtin_branch_usage, options);\n+\t\tif (edit_branch_description(branch_name))\n+\t\t\treturn 1;\n+\t} else if (argc == 0)\n \t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"175907","messageId":"7vpqiu4y1j.fsf_-_@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"7vy5xi4y3m.fsf@alter.siamese.dyndns.org","subject":"[PATCH] request-pull: use the branch description","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-20T23:03:04Z","receivedAt":"2011-09-20T23:03:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Now we have branch descriptions stored in the repository, we can\nuse it when preparing the request-pull message.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n git-request-pull.sh |   20 +++++++++++++++++++-\n 1 files changed, 19 insertions(+), 1 deletions(-)\n\ndiff --git a/git-request-pull.sh b/git-request-pull.sh\nindex 438e7eb..626cf25 100755\n--- a/git-request-pull.sh\n+++ b/git-request-pull.sh\n@@ -35,7 +35,18 @@ do\n \tshift\n done\n \n-base=$1 url=$2 head=${3-HEAD} status=0\n+base=$1 url=$2 head=${3-HEAD} status=0 branch_name=\n+\n+headref=$(git symbolic-ref -q \"$head\")\n+if git show-ref -q --verify \"$headref\"\n+then\n+\tbranch_name=${headref#refs/heads/}\n+\tif test \"z$branch_name\" = \"z$headref\" ||\n+\t\t! git config \"branch.$branch_name.description\" >/dev/null\n+\tthen\n+\t\tbranch_name=\n+\tfi\n+fi\n \n test -n \"$base\" && test -n \"$url\" || usage\n baserev=$(git rev-parse --verify \"$base\"^0) &&\n@@ -66,6 +77,13 @@ for you to fetch changes up to %H:\n \n ----------------------------------------------------------------' $headrev &&\n \n+if test -n \"$branch_name\"\n+then\n+\techo \"(from the branch description for $branch local branch)\"\n+\techo\n+\tgit config \"branch.$branch_name.description\"\n+\techo \"----------------------------------------------------------------\"\n+fi &&\n git shortlog ^$baserev $headrev &&\n git diff -M --stat --summary $patch $merge_base..$headrev || status=1\n \n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"175909","messageId":"CAH5451nai988=jB8cgFcUaQZWWUyALC-tOSV_jdLX0r_2UfbPw@mail.gmail.com","threadId":"28380","inReplyTo":"7vty864y24.fsf_-_@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/3] branch: teach --edit-description option","fromName":"Andrew Ardill","fromEmail":"andrew.ardill@gmail.com","sentAt":"2011-09-21T00:15:20Z","receivedAt":"2011-09-21T00:15:20Z","isPatch":true,"sender":{"key":"andrew.ardill@gmail.com","avatar":"https://gravatar.com/avatar/da14cb7c091dd44dc6c63a4d3361b149acaf25226dc78eb4131a17b93d9b0993?d=mp&s=160"},"body":"On 21 September 2011 09:02, Junio C Hamano <gitster@pobox.com> wrote:\n> Using branch.$name.description as the configuration key, give users a\n> place to write about what the purpose of the branch is and things like\n> that, so that various subsystems, e.g. \"push -s\", \"request-pull\", and\n> \"format-patch --cover-letter\", can later be taught to use this\n> information.\n>\n> The \"-m\" option similar to \"commit/tag\" is deliberately omitted, as the\n> whole point of branch description is about giving descriptive information\n> (the name of the branch itself is a better place for information that fits\n> on a single-line).\n\nI understand your reasoning here, however is there a way to allow\nsetting the branch description in, for example, a script?\n\nAdditionally I can imagine it would be useful to be able to set the\nbranch description from another tool, what is the recommended way of\ndoing that? Should tools modify the config directly??\n\nRegards,\nAndrew\n"},{"id":"175914","messageId":"7v7h524nrx.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"CAH5451nai988=jB8cgFcUaQZWWUyALC-tOSV_jdLX0r_2UfbPw@mail.gmail.com","subject":"Re: [PATCH 2/3] branch: teach --edit-description option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-21T02:44:50Z","receivedAt":"2011-09-21T02:44:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andrew Ardill <andrew.ardill@gmail.com> writes:\n\n> I understand your reasoning here, however is there a way to allow\n> setting the branch description in, for example, a script?\n\nAs you read in the patch, especially the documentation part, there is not\na way to do that.\n\nI am not interested because it does not directly help my cause of helping\nthe human communication between the kernel developers who may want to\nperform a signed push to their public repository and send their pull\nrequests with the same message to Linus.\n\nThat does _not_ mean I will _reject_ a patch to add such a feature. It\njust means writing such a patch myself or reviewing and accepting such a\npatch is not very high in my prioritized list at this point in the\nevolution of the series. Teaching the use of the information to other\ncommands such as \"format-patch --cover-letter\" would have much higher\nprecedence.\n\n> Additionally I can imagine it would be useful to be able to set the\n> branch description from another tool, what is the recommended way of\n> doing that? Should tools modify the config directly??\n\nAn obvious answer: \"do whatever you want\". The only rule that the programs\nthat need to follow is that branch.$name.description has the string to use\nto obtain the explanation text.\n\nHow they achieve that (perhaps by running \"git config\") is of secondary\nimportance.\n"},{"id":"176021","messageId":"1316729362-7714-1-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"7vy5xi4y3m.fsf@alter.siamese.dyndns.org","subject":"[PATCH 0/6] A handful of \"branch description\" patches","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-22T22:09:16Z","receivedAt":"2011-09-22T22:09:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Here are a few patches that I have queued in 'pu', redoing some of the\npatches I already sent out to the list, around \"branch description\".\n\nThe original motivation was to make the push/pull workflow appear more\nrobust by allowing human-to-human communication to leave audit trail that\ncan be verified when it becomes necessary. Namely:\n\n * request-pull message carries the SHA-1 of what is expected to be\n   merged; and\n\n * \"signed push\" leaves the SHA-1 of what was pushed to the remote,\n   cryptographically signed.\n\nLinus's reaction, as I understood him, was \"if we are spending efforts to\nadd more information, the end result should be more informative to humans\nnot just to machines\", and I agree.  An example of piece of information we\noften talk about is branch description---what a particular branch is meant\nto achieve. Both request-pull messages and declarations of what was pushed\nare good places to record that piece of information.\n\nSo here is a partially re-rolled series to get us closer.\n\n * The logic to read from an existing branch description was in\n   builtin/branch.c in the original series, but the first patch separates\n   it out into branch.c as a helper function;\n\n * The second one is a digression; the branch description describes what\n   the topic aims to achieve, so it was natural to use it to prime the\n   cover letter while preparing a patch series with format-patch;\n\n * The third one that adds \"branch --edit-description\" is basically\n   unchanged modulo small leakfix from the original round;\n\n * And the remainder of the series for request-pull is the same as the\n   last round.\n\nThe second patch uses facility introduced in bk/ancestry-path topic, so\nit would be the easiest to apply the series on top of a merge of c05b988\nto 'master'.\n\nI haven't updated the \"signed push\" patch to use this information yet.\n\n\nJunio C Hamano (6):\n  branch: add read_branch_desc() helper function\n  format-patch: use branch description in cover letter\n  branch: teach --edit-description option\n  request-pull: modernize style\n  request-pull: state what commit to expect\n  request-pull: use the branch description\n\n Documentation/git-branch.txt |    5 +++\n branch.c                     |   31 ++++++++++++++++++\n branch.h                     |    5 +++\n builtin/branch.c             |   56 +++++++++++++++++++++++++++++++-\n builtin/log.c                |   71 +++++++++++++++++++++++++++++++++++++++--\n git-request-pull.sh          |   73 ++++++++++++++++++++++++++---------------\n t/t5150-request-pull.sh      |    6 +++\n 7 files changed, 215 insertions(+), 32 deletions(-)\n\n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"176022","messageId":"1316729362-7714-2-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"1316729362-7714-1-git-send-email-gitster@pobox.com","subject":"[PATCH 1/6] branch: add read_branch_desc() helper function","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-22T22:09:17Z","receivedAt":"2011-09-22T22:09:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This will be used by various callers that make use of the branch\ndescription throughout the system, so that if we need to update\nthe implementation the callers do not have to be modified.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n branch.c |   31 +++++++++++++++++++++++++++++++\n branch.h |    5 +++++\n 2 files changed, 36 insertions(+), 0 deletions(-)\n\ndiff --git a/branch.c b/branch.c\nindex fecedd3..88da275 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -135,6 +135,37 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,\n \treturn 0;\n }\n \n+struct branch_desc_cb {\n+\tconst char *config_name;\n+\tconst char *value;\n+};\n+\n+static int read_branch_desc_cb(const char *var, const char *value, void *cb)\n+{\n+\tstruct branch_desc_cb *desc = cb;\n+\tif (strcmp(desc->config_name, var))\n+\t\treturn 0;\n+\tfree((char *)desc->value);\n+\treturn git_config_string(&desc->value, var, value);\n+}\n+\n+int read_branch_desc(struct strbuf *buf, const char *branch_name)\n+{\n+\tstruct branch_desc_cb cb;\n+\tstruct strbuf name = STRBUF_INIT;\n+\tstrbuf_addf(&name, \"branch.%s.description\", branch_name);\n+\tcb.config_name = name.buf;\n+\tcb.value = NULL;\n+\tif (git_config(read_branch_desc_cb, &cb)) {\n+\t\tstrbuf_release(&name);\n+\t\treturn -1;\n+\t}\n+\tif (cb.value)\n+\t\tstrbuf_addstr(buf, cb.value);\n+\tstrbuf_release(&name);\n+\treturn 0;\n+}\n+\n int validate_new_branchname(const char *name, struct strbuf *ref,\n \t\t\t    int force, int attr_only)\n {\ndiff --git a/branch.h b/branch.h\nindex 1285158..1493f73 100644\n--- a/branch.h\n+++ b/branch.h\n@@ -46,4 +46,9 @@ void remove_branch_state(void);\n #define BRANCH_CONFIG_VERBOSE 01\n extern void install_branch_config(int flag, const char *local, const char *origin, const char *remote);\n \n+/*\n+ * Read branch description\n+ */\n+extern int read_branch_desc(struct strbuf *, const char *branch_name);\n+\n #endif\n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"176025","messageId":"1316729362-7714-3-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"1316729362-7714-1-git-send-email-gitster@pobox.com","subject":"[PATCH 2/6] format-patch: use branch description in cover letter","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-22T22:09:18Z","receivedAt":"2011-09-22T22:09:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Use the description for the branch when preparing the cover letter\nwhen available.\n\nWhile at it, mark a loosely written codepath that would do a random and\nuseless thing given an unusual input (e.g. \"^master HEAD HEAD^\"), which\nwe may want to fix someday.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n branch.c      |    2 +-\n builtin/log.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--\n 2 files changed, 69 insertions(+), 4 deletions(-)\n\ndiff --git a/branch.c b/branch.c\nindex 88da275..50088a4 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -156,7 +156,7 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name)\n \tstrbuf_addf(&name, \"branch.%s.description\", branch_name);\n \tcb.config_name = name.buf;\n \tcb.value = NULL;\n-\tif (git_config(read_branch_desc_cb, &cb)) {\n+\tif (git_config(read_branch_desc_cb, &cb) < 0) {\n \t\tstrbuf_release(&name);\n \t\treturn -1;\n \t}\ndiff --git a/builtin/log.c b/builtin/log.c\nindex f5d4930..e80a925 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -19,6 +19,7 @@\n #include \"remote.h\"\n #include \"string-list.h\"\n #include \"parse-options.h\"\n+#include \"branch.h\"\n \n /* Set a default date-time format for git log (\"log.date\" config variable) */\n static const char *default_date_mode = NULL;\n@@ -746,10 +747,24 @@ static void print_signature(void)\n \t\tprintf(\"-- \\n%s\\n\\n\", signature);\n }\n \n+static void add_branch_description(struct strbuf *buf, const char *branch_name)\n+{\n+\tstruct strbuf desc = STRBUF_INIT;\n+\tif (!branch_name || !*branch_name)\n+\t\treturn;\n+\tread_branch_desc(&desc, branch_name);\n+\tif (desc.len) {\n+\t\tstrbuf_addch(buf, '\\n');\n+\t\tstrbuf_add(buf, desc.buf, desc.len);\n+\t\tstrbuf_addch(buf, '\\n');\n+\t}\n+}\n+\n static void make_cover_letter(struct rev_info *rev, int use_stdout,\n \t\t\t      int numbered, int numbered_files,\n \t\t\t      struct commit *origin,\n \t\t\t      int nr, struct commit **list, struct commit *head,\n+\t\t\t      const char *branch_name,\n \t\t\t      int quiet)\n {\n \tconst char *committer;\n@@ -807,6 +822,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n \tpp_user_info(&pp, NULL, &sb, committer, encoding);\n \tpp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);\n \tpp_remainder(&pp, &msg, &sb, 0);\n+\tadd_branch_description(&sb, branch_name);\n \tprintf(\"%s\\n\", sb.buf);\n \n \tstrbuf_release(&sb);\n@@ -1006,6 +1022,35 @@ static int cc_callback(const struct option *opt, const char *arg, int unset)\n \treturn 0;\n }\n \n+static char *find_branch_name(struct rev_info *rev)\n+{\n+\tint i, positive = -1;\n+\tunsigned char branch_sha1[20];\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tconst char *branch;\n+\n+\tfor (i = 0; i < rev->cmdline.nr; i++) {\n+\t\tif (rev->cmdline.rev[i].flags & UNINTERESTING)\n+\t\t\tcontinue;\n+\t\tif (positive < 0)\n+\t\t\tpositive = i;\n+\t\telse\n+\t\t\treturn NULL;\n+\t}\n+\tif (positive < 0)\n+\t\treturn NULL;\n+\tstrbuf_addf(&buf, \"refs/heads/%s\", rev->cmdline.rev[positive].name);\n+\tbranch = resolve_ref(buf.buf, branch_sha1, 1, 0);\n+\tif (!branch ||\n+\t    prefixcmp(branch, \"refs/heads/\") ||\n+\t    hashcmp(rev->cmdline.rev[positive].item->sha1, branch_sha1))\n+\t\tbranch = NULL;\n+\tstrbuf_release(&buf);\n+\tif (branch)\n+\t\treturn xstrdup(rev->cmdline.rev[positive].name);\n+\treturn NULL;\n+}\n+\n int cmd_format_patch(int argc, const char **argv, const char *prefix)\n {\n \tstruct commit *commit;\n@@ -1027,6 +1072,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \tstruct strbuf buf = STRBUF_INIT;\n \tint use_patch_format = 0;\n \tint quiet = 0;\n+\tchar *branch_name = NULL;\n \tconst struct option builtin_format_patch_options[] = {\n \t\t{ OPTION_CALLBACK, 'n', \"numbered\", &numbered, NULL,\n \t\t\t    \"use [PATCH n/m] even with a single patch\",\n@@ -1217,8 +1263,16 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\t\t * origin\" that prepares what the origin side still\n \t\t\t * does not have.\n \t\t\t */\n+\t\t\tunsigned char sha1[20];\n+\t\t\tconst char *ref;\n+\n \t\t\trev.pending.objects[0].item->flags |= UNINTERESTING;\n \t\t\tadd_head_to_pending(&rev);\n+\t\t\tref = resolve_ref(\"HEAD\", sha1, 1, NULL);\n+\t\t\tif (ref && !prefixcmp(ref, \"refs/heads/\"))\n+\t\t\t\tbranch_name = xstrdup(ref + strlen(\"refs/heads/\"));\n+\t\t\telse\n+\t\t\t\tbranch_name = xstrdup(\"\"); /* no branch */\n \t\t}\n \t\t/*\n \t\t * Otherwise, it is \"format-patch -22 HEAD\", and/or\n@@ -1234,16 +1288,26 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \trev.show_root_diff = 1;\n \n \tif (cover_letter) {\n-\t\t/* remember the range */\n+\t\t/*\n+\t\t * NEEDSWORK:randomly pick one positive commit to show\n+\t\t * diffstat; this is often the tip and the command\n+\t\t * happens to do the right thing in most cases, but a\n+\t\t * complex command like \"--cover-letter a b c ^bottom\"\n+\t\t * picks \"c\" and shows diffstat between bottom..c\n+\t\t * which may not match what the series represents at\n+\t\t * all and totally broken.\n+\t\t */\n \t\tint i;\n \t\tfor (i = 0; i < rev.pending.nr; i++) {\n \t\t\tstruct object *o = rev.pending.objects[i].item;\n \t\t\tif (!(o->flags & UNINTERESTING))\n \t\t\t\thead = (struct commit *)o;\n \t\t}\n-\t\t/* We can't generate a cover letter without any patches */\n+\t\t/* There is nothing to show; it is not an error, though. */\n \t\tif (!head)\n \t\t\treturn 0;\n+\t\tif (!branch_name)\n+\t\t\tbranch_name = find_branch_name(&rev);\n \t}\n \n \tif (ignore_if_in_upstream) {\n@@ -1294,7 +1358,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\tif (thread)\n \t\t\tgen_message_id(&rev, \"cover\");\n \t\tmake_cover_letter(&rev, use_stdout, numbered, numbered_files,\n-\t\t\t\t  origin, nr, list, head, quiet);\n+\t\t\t\t  origin, nr, list, head, branch_name, quiet);\n \t\ttotal++;\n \t\tstart_number--;\n \t}\n@@ -1366,6 +1430,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\t\tfclose(stdout);\n \t}\n \tfree(list);\n+\tfree(branch_name);\n \tstring_list_clear(&extra_to, 0);\n \tstring_list_clear(&extra_cc, 0);\n \tstring_list_clear(&extra_hdr, 0);\n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"176024","messageId":"1316729362-7714-4-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"1316729362-7714-1-git-send-email-gitster@pobox.com","subject":"[PATCH 3/6] branch: teach --edit-description option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-22T22:09:19Z","receivedAt":"2011-09-22T22:09:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Using branch.$name.description as the configuration key, give users a\nplace to write about what the purpose of the branch is and things like\nthat, so that various subsystems, e.g. \"push -s\", \"request-pull\", and\n\"format-patch --cover-letter\", can later be taught to use this\ninformation.\n\nThe \"-m\" option similar to \"commit/tag\" is deliberately omitted, as the\nwhole point of branch description is about giving descriptive information\n(the name of the branch itself is a better place for information that fits\non a single-line).\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-branch.txt |    5 +++\n builtin/branch.c             |   56 ++++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 59 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 507b8d0..8871a4e 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -14,6 +14,7 @@ SYNOPSIS\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n 'git branch' (-d | -D) [-r] <branchname>...\n+'git branch' --edit-description [<branchname>]\n \n DESCRIPTION\n -----------\n@@ -144,6 +145,10 @@ start-point is either a local or remote-tracking branch.\n \tlike '--track' would when creating the branch, except that where\n \tbranch points to is not changed.\n \n+--edit-description::\n+\tOpen an editor and edit the text to explain what the branch is\n+\tfor, to be used by various other commands (e.g. `request-pull`).\n+\n --contains <commit>::\n \tOnly list branches which contain the specified commit.\n \ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex f49596f..fffa319 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -606,11 +606,49 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int\n \treturn 0;\n }\n \n+static const char edit_description[] = \"BRANCH_DESCRIPTION\";\n+\n+static int edit_branch_description(const char *branch_name)\n+{\n+\tFILE *fp;\n+\tint status;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tstruct strbuf name = STRBUF_INIT;\n+\n+\tread_branch_desc(&buf, branch_name);\n+\tif (!buf.len || buf.buf[buf.len-1] != '\\n')\n+\t\tstrbuf_addch(&buf, '\\n');\n+\tstrbuf_addf(&buf,\n+\t\t    \"# Please edit the description for the branch\\n\"\n+\t\t    \"#   %s\\n\"\n+\t\t    \"# Lines starting with '#' will be stripped.\\n\",\n+\t\t    branch_name);\n+\tfp = fopen(git_path(edit_description), \"w\");\n+\tif ((fwrite(buf.buf, 1, buf.len, fp) < buf.len) || fclose(fp)) {\n+\t\tstrbuf_release(&buf);\n+\t\treturn error(_(\"could not write branch description template: %s\\n\"),\n+\t\t\t     strerror(errno));\n+\t}\n+\tstrbuf_reset(&buf);\n+\tif (launch_editor(git_path(edit_description), &buf, NULL)) {\n+\t\tstrbuf_release(&buf);\n+\t\treturn -1;\n+\t}\n+\tstripspace(&buf, 1);\n+\n+\tstrbuf_addf(&name, \"branch.%s.description\", branch_name);\n+\tstatus = git_config_set(name.buf, buf.buf);\n+\tstrbuf_release(&name);\n+\tstrbuf_release(&buf);\n+\n+\treturn status;\n+}\n+\n int cmd_branch(int argc, const char **argv, const char *prefix)\n {\n \tint delete = 0, rename = 0, force_create = 0;\n \tint verbose = 0, abbrev = -1, detached = 0;\n-\tint reflog = 0;\n+\tint reflog = 0, edit_description = 0;\n \tenum branch_track track;\n \tint kinds = REF_LOCAL_BRANCH;\n \tstruct commit_list *with_commit = NULL;\n@@ -648,6 +686,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT('m', NULL, &rename, \"move/rename a branch and its reflog\", 1),\n \t\tOPT_BIT('M', NULL, &rename, \"move/rename a branch, even if target exists\", 2),\n \t\tOPT_BOOLEAN('l', NULL, &reflog, \"create the branch's reflog\"),\n+\t\tOPT_BOOLEAN(0, \"edit-description\", &edit_description,\n+\t\t\t    \"edit the description for the branch\"),\n \t\tOPT__FORCE(&force_create, \"force creation (when already exists)\"),\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"no-merged\", &merge_filter_ref,\n@@ -694,7 +734,19 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n-\telse if (argc == 0)\n+\telse if (edit_description) {\n+\t\tconst char *branch_name;\n+\t\tif (detached)\n+\t\t\tdie(\"Cannot give description to detached HEAD\");\n+\t\tif (!argc)\n+\t\t\tbranch_name = head;\n+\t\telse if (argc == 1)\n+\t\t\tbranch_name = argv[0];\n+\t\telse\n+\t\t\tusage_with_options(builtin_branch_usage, options);\n+\t\tif (edit_branch_description(branch_name))\n+\t\t\treturn 1;\n+\t} else if (argc == 0)\n \t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"176026","messageId":"1316729362-7714-5-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"1316729362-7714-1-git-send-email-gitster@pobox.com","subject":"[PATCH 4/6] request-pull: modernize style","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-22T22:09:20Z","receivedAt":"2011-09-22T22:09:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Make it a bit more conforming to Documentation/Codingstyle\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n git-request-pull.sh |   29 +++++++++++++----------------\n 1 files changed, 13 insertions(+), 16 deletions(-)\n\ndiff --git a/git-request-pull.sh b/git-request-pull.sh\nindex fc080cc..afb75e8 100755\n--- a/git-request-pull.sh\n+++ b/git-request-pull.sh\n@@ -35,27 +35,24 @@ do\n \tshift\n done\n \n-base=$1\n-url=$2\n-head=${3-HEAD}\n+base=$1 url=$2 head=${3-HEAD}\n \n-[ \"$base\" ] || usage\n-[ \"$url\" ] || usage\n+test -n \"$base\" && test -n \"$url\" || usage\n+baserev=$(git rev-parse --verify \"$base\"^0) &&\n+headrev=$(git rev-parse --verify \"$head\"^0) || exit\n \n-baserev=`git rev-parse --verify \"$base\"^0` &&\n-headrev=`git rev-parse --verify \"$head\"^0` || exit\n-\n-merge_base=`git merge-base $baserev $headrev` ||\n+merge_base=$(git merge-base $baserev $headrev) ||\n die \"fatal: No commits in common between $base and $head\"\n \n-branch=$(git ls-remote \"$url\" \\\n-\t| sed -n -e \"/^$headrev\trefs.heads./{\n-\t\ts/^.*\trefs.heads.//\n-\t\tp\n-\t\tq\n-\t}\")\n+find_matching_branch=\"/^$headrev\t\"'refs\\/heads\\//{\n+\ts/^.*\trefs\\/heads\\///\n+\tp\n+\tq\n+}'\n+branch=$(git ls-remote \"$url\" | sed -n -e \"$find_matching_branch\")\n url=$(git ls-remote --get-url \"$url\")\n-if [ -z \"$branch\" ]; then\n+if test -z \"$branch\"\n+then\n \techo \"warn: No branch of $url is at:\" >&2\n \tgit log --max-count=1 --pretty='tformat:warn:   %h: %s' $headrev >&2\n \techo \"warn: Are you sure you pushed $head there?\" >&2\n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"176027","messageId":"1316729362-7714-6-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"1316729362-7714-1-git-send-email-gitster@pobox.com","subject":"[PATCH 5/6] request-pull: state what commit to expect","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-22T22:09:21Z","receivedAt":"2011-09-22T22:09:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The message gives a detailed explanation of the commit the requester based\nthe changes on, but lacks information that is necessary for the person who\nperforms a fetch & merge in order to verify that the correct branch was\nfetched when responding to the pull request.\n\nAdd a few more lines to describe the commit at the tip expected to be\nfetched to the same level of detail as the base commit.\n\nAlso update the warning message slightly when the script notices that the\ncommit may not have been pushed.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n git-request-pull.sh     |   34 +++++++++++++++++++---------------\n t/t5150-request-pull.sh |    6 ++++++\n 2 files changed, 25 insertions(+), 15 deletions(-)\n\ndiff --git a/git-request-pull.sh b/git-request-pull.sh\nindex afb75e8..438e7eb 100755\n--- a/git-request-pull.sh\n+++ b/git-request-pull.sh\n@@ -35,7 +35,7 @@ do\n \tshift\n done\n \n-base=$1 url=$2 head=${3-HEAD}\n+base=$1 url=$2 head=${3-HEAD} status=0\n \n test -n \"$base\" && test -n \"$url\" || usage\n baserev=$(git rev-parse --verify \"$base\"^0) &&\n@@ -51,25 +51,29 @@ find_matching_branch=\"/^$headrev\t\"'refs\\/heads\\//{\n }'\n branch=$(git ls-remote \"$url\" | sed -n -e \"$find_matching_branch\")\n url=$(git ls-remote --get-url \"$url\")\n-if test -z \"$branch\"\n-then\n-\techo \"warn: No branch of $url is at:\" >&2\n-\tgit log --max-count=1 --pretty='tformat:warn:   %h: %s' $headrev >&2\n-\techo \"warn: Are you sure you pushed $head there?\" >&2\n-\techo >&2\n-\techo >&2\n-\tbranch=..BRANCH.NOT.VERIFIED..\n-\tstatus=1\n-fi\n \n git show -s --format='The following changes since commit %H:\n \n   %s (%ci)\n \n-are available in the git repository at:' $baserev &&\n-echo \"  $url $branch\" &&\n-echo &&\n+are available in the git repository at:\n+' $baserev &&\n+echo \"  $url${branch+ $branch}\" &&\n+git show -s --format='\n+for you to fetch changes up to %H:\n+\n+  %s (%ci)\n+\n+----------------------------------------------------------------' $headrev &&\n \n git shortlog ^$baserev $headrev &&\n-git diff -M --stat --summary $patch $merge_base..$headrev || exit\n+git diff -M --stat --summary $patch $merge_base..$headrev || status=1\n+\n+if test -z \"$branch\"\n+then\n+\techo \"warn: No branch of $url is at:\" >&2\n+\tgit show -s --format='warn:   %h: %s' $headrev >&2\n+\techo \"warn: Are you sure you pushed '$head' there?\" >&2\n+\tstatus=1\n+fi\n exit $status\ndiff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh\nindex 9cc0a42..5bd1682 100755\n--- a/t/t5150-request-pull.sh\n+++ b/t/t5150-request-pull.sh\n@@ -193,8 +193,14 @@ test_expect_success 'pull request format' '\n \t  SUBJECT (DATE)\n \n \tare available in the git repository at:\n+\n \t  URL BRANCH\n \n+\tfor you to fetch changes up to OBJECT_NAME:\n+\n+\t  SUBJECT (DATE)\n+\n+\t----------------------------------------------------------------\n \tSHORTLOG\n \n \tDIFFSTAT\n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"176023","messageId":"1316729362-7714-7-git-send-email-gitster@pobox.com","threadId":"28380","inReplyTo":"1316729362-7714-1-git-send-email-gitster@pobox.com","subject":"[PATCH 6/6] request-pull: use the branch description","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-22T22:09:22Z","receivedAt":"2011-09-22T22:09:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Now we have branch descriptions stored in the repository, we can\nuse it when preparing the request-pull message.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n git-request-pull.sh |   20 +++++++++++++++++++-\n 1 files changed, 19 insertions(+), 1 deletions(-)\n\ndiff --git a/git-request-pull.sh b/git-request-pull.sh\nindex 438e7eb..626cf25 100755\n--- a/git-request-pull.sh\n+++ b/git-request-pull.sh\n@@ -35,7 +35,18 @@ do\n \tshift\n done\n \n-base=$1 url=$2 head=${3-HEAD} status=0\n+base=$1 url=$2 head=${3-HEAD} status=0 branch_name=\n+\n+headref=$(git symbolic-ref -q \"$head\")\n+if git show-ref -q --verify \"$headref\"\n+then\n+\tbranch_name=${headref#refs/heads/}\n+\tif test \"z$branch_name\" = \"z$headref\" ||\n+\t\t! git config \"branch.$branch_name.description\" >/dev/null\n+\tthen\n+\t\tbranch_name=\n+\tfi\n+fi\n \n test -n \"$base\" && test -n \"$url\" || usage\n baserev=$(git rev-parse --verify \"$base\"^0) &&\n@@ -66,6 +77,13 @@ for you to fetch changes up to %H:\n \n ----------------------------------------------------------------' $headrev &&\n \n+if test -n \"$branch_name\"\n+then\n+\techo \"(from the branch description for $branch local branch)\"\n+\techo\n+\tgit config \"branch.$branch_name.description\"\n+\techo \"----------------------------------------------------------------\"\n+fi &&\n git shortlog ^$baserev $headrev &&\n git diff -M --stat --summary $patch $merge_base..$headrev || status=1\n \n-- \n1.7.7.rc2.4.g5ec82\n"},{"id":"176052","messageId":"4E7C49CF.60508@drmicha.warpmail.net","threadId":"28380","inReplyTo":"1316729362-7714-1-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 0/6] A handful of \"branch description\" patches","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-23T08:56:47Z","receivedAt":"2011-09-23T08:56:47Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 23.09.2011 00:09:\n> Here are a few patches that I have queued in 'pu', redoing some of the\n> patches I already sent out to the list, around \"branch description\".\n> \n> The original motivation was to make the push/pull workflow appear more\n> robust by allowing human-to-human communication to leave audit trail that\n> can be verified when it becomes necessary. Namely:\n> \n>  * request-pull message carries the SHA-1 of what is expected to be\n>    merged; and\n> \n>  * \"signed push\" leaves the SHA-1 of what was pushed to the remote,\n>    cryptographically signed.\n> \n> Linus's reaction, as I understood him, was \"if we are spending efforts to\n> add more information, the end result should be more informative to humans\n> not just to machines\", and I agree.  An example of piece of information we\n> often talk about is branch description---what a particular branch is meant\n> to achieve. Both request-pull messages and declarations of what was pushed\n> are good places to record that piece of information.\n> \n> So here is a partially re-rolled series to get us closer.\n> \n>  * The logic to read from an existing branch description was in\n>    builtin/branch.c in the original series, but the first patch separates\n>    it out into branch.c as a helper function;\n> \n>  * The second one is a digression; the branch description describes what\n>    the topic aims to achieve, so it was natural to use it to prime the\n>    cover letter while preparing a patch series with format-patch;\n> \n>  * The third one that adds \"branch --edit-description\" is basically\n>    unchanged modulo small leakfix from the original round;\n> \n>  * And the remainder of the series for request-pull is the same as the\n>    last round.\n\nI'm afraid I've missed the first installment of the series, or rather the fact that it was about more than just signed pushes. I've been working at (and with) branch and tag annotations for quite a while now and should have probably pushed the WIP rather than just dropping the occasional note. So I'll describe briefly what I have (the branches are in any of my repos[1]), which is notes based:\n\n  mjg/vob/branch-notes [mjg/vob/virtual-objects: ahead 4]\n    Annotations for branches and tags\n    \n    Show notes for branches and tags when \"branch\" resp. \"tag\" is called with \"--notes\".\n    The \"--notes\" argument can take on all usual forms.\n\n  mjg/vob/format-patch-branch-note [mjg/vob/refrev-hash: ahead 1]\n    Cover letter from notes\n    \n    Fill in the cover letter from a note to ref:HEAD if --notes is given.\n    TODO: The current branch may not be the one the format-patch arguments refer to.\n\n  mjg/vob/refrev-hash [mjg/vob/virtual-objects: ahead 2]\n    Pseudo revs for refnames\n    \n    Introduce \"ref:foo\" to denote the (virtual) refname object for the ref named\n    \"foo\". This is handy for now (editing branch and tag notes) but should\n    become obsoleted by a better ui, such as \"git branch --edit foo\" or\n    \"git notes --refname edit foo\".\n    \n    Introduce \"ref:\" as a shortcut to \"ref:HEAD\" which is the refname object\n    for the current branch.\n\n  mjg/vob/refrev-pretend [mjg/vob/virtual-objects: ahead 1]\n    Pseudo revs for refnames\n    \n    An alternative implementation using pretend_sha1...\n    Currently unused.\n\n  mjg/vob/virtual-objects [origin/next: ahead 2, behind 10]\n    Virtual refname objects\n    \n    For each existing refname, introduce virtual objects corresponding to a blob\n    with the refname as the content. \"virtual\" refers to the fact that these\n    objects are not written out but exist for all other purposes, such as\n    attaching notes and keeping them from being pruned.\n\n  mjg/vob/virtual-refs-for-rnos\n    Virtual refs for refname objects\n    \n    For each ref, pretend that the corresponding refname object is referenced\n    to keep it from being pruned. This still requires branch note code to\n    write out these objects.\n    (Unused earlier approach.)\n\n  mjg/vob/virtual-refs-pretend-all\n    Virtual refs for refname objects\n    \n    For each ref, pretend that the corresponding refname object is referenced\n    to keep it from being pruned. This still requires branch note code to\n    write out these objects.\n    (Unused earlier approach using pretend_sha1....)\n\n\nYes, the above is (with added newlines and removed top commit info) the output of 'git branch -vv --notes --list mjg/vob\\*' :)\n\nOpen questions:\n* Should the refname object for ref \"foo\" really be identical to a blob with content \"foo\"? Or content \"ref: foo? Or...?\n* Should ref (branch and tag) annotations use the same default notes tree as commit notes?\n* How best to view annotations on remote branches? This is connected with open questions about notes sharing and the ref namespace structure.\n\nI do think that config based descriptions are a quick solution, but a very non-distributed, non-versioned approach when compared to the notes approach.\n\nMichael\n\n[1]\ngit://github.com/gitigit/git.git\ngit://gitorious.org/~mjg/git/mjg.git\ngit://repo.or.cz/git/mjg.git\n"},{"id":"176053","messageId":"4E7C4ABF.1020804@drmicha.warpmail.net","threadId":"28380","inReplyTo":"1316729362-7714-4-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 3/6] branch: teach --edit-description option","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-23T09:00:47Z","receivedAt":"2011-09-23T09:00:47Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 23.09.2011 00:09:\n> Using branch.$name.description as the configuration key, give users a\n> place to write about what the purpose of the branch is and things like\n> that, so that various subsystems, e.g. \"push -s\", \"request-pull\", and\n> \"format-patch --cover-letter\", can later be taught to use this\n> information.\n> \n> The \"-m\" option similar to \"commit/tag\" is deliberately omitted, as the\n> whole point of branch description is about giving descriptive information\n> (the name of the branch itself is a better place for information that fits\n> on a single-line).\n\nI don't think that is the only reason why we should not make \"git branch\n-m foo bar\" set the description \"foo\" for branch \"bar\"...\n\nGranted, your argument applies to \"--set-description\" (\"-m\"-like) also.\n\nMichael\n\n> \n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  Documentation/git-branch.txt |    5 +++\n>  builtin/branch.c             |   56 ++++++++++++++++++++++++++++++++++++++++-\n>  2 files changed, 59 insertions(+), 2 deletions(-)\n> \n> diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\n> index 507b8d0..8871a4e 100644\n> --- a/Documentation/git-branch.txt\n> +++ b/Documentation/git-branch.txt\n> @@ -14,6 +14,7 @@ SYNOPSIS\n>  'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n>  'git branch' (-m | -M) [<oldbranch>] <newbranch>\n\n;)\n\n>  'git branch' (-d | -D) [-r] <branchname>...\n> +'git branch' --edit-description [<branchname>]\n"},{"id":"176051","messageId":"20110923094721.GA8397@duynguyen-vnpc","threadId":"28380","inReplyTo":"1316729362-7714-4-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 3/6] branch: teach --edit-description option","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-09-23T09:47:21Z","receivedAt":"2011-09-23T09:47:21Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Sep 22, 2011 at 03:09:19PM -0700, Junio C Hamano wrote:\n> +\tif (launch_editor(git_path(edit_description), &buf, NULL)) {\n> +\t\tstrbuf_release(&buf);\n> +\t\treturn -1;\n> +\t}\n> +\tstripspace(&buf, 1);\n> +\n> +\tstrbuf_addf(&name, \"branch.%s.description\", branch_name);\n> +\tstatus = git_config_set(name.buf, buf.buf);\n\nI suppose a Windows editor mave save the description with \\r\\n\nending. Perhaps a patch like this to avoid messing up config file?\n\n--8<--\nSubject: [PATCH] config: quote \\r in value\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n config.c |    6 ++++++\n 1 files changed, 6 insertions(+), 0 deletions(-)\n\ndiff --git a/config.c b/config.c\nindex 4183f80..2e238ac 100644\n--- a/config.c\n+++ b/config.c\n@@ -165,6 +165,9 @@ static char *parse_value(void)\n \t\t\tcase 'b':\n \t\t\t\tc = '\\b';\n \t\t\t\tbreak;\n+\t\t\tcase 'r':\n+\t\t\t\tc = '\\r';\n+\t\t\t\tbreak;\n \t\t\tcase 'n':\n \t\t\t\tc = '\\n';\n \t\t\t\tbreak;\n@@ -1048,6 +1051,9 @@ static int store_write_pair(int fd, const char *key, const char *value)\n \n \tfor (i = 0; value[i]; i++)\n \t\tswitch (value[i]) {\n+\t\tcase '\\r':\n+\t\t\tstrbuf_addstr(&sb, \"\\\\r\");\n+\t\t\tbreak;\n \t\tcase '\\n':\n \t\t\tstrbuf_addstr(&sb, \"\\\\n\");\n \t\t\tbreak;\n-- \n1.7.3.1.256.g2539c.dirty\n--8<--\n"},{"id":"176089","messageId":"7v62kjulkf.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"20110923094721.GA8397@duynguyen-vnpc","subject":"Re: [PATCH 3/6] branch: teach --edit-description option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-23T19:04:48Z","receivedAt":"2011-09-23T19:04:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> On Thu, Sep 22, 2011 at 03:09:19PM -0700, Junio C Hamano wrote:\n>> +\tif (launch_editor(git_path(edit_description), &buf, NULL)) {\n>> +\t\tstrbuf_release(&buf);\n>> +\t\treturn -1;\n>> +\t}\n>> +\tstripspace(&buf, 1);\n>> +\n>> +\tstrbuf_addf(&name, \"branch.%s.description\", branch_name);\n>> +\tstatus = git_config_set(name.buf, buf.buf);\n>\n> I suppose a Windows editor mave save the description with \\r\\n\n> ending. Perhaps a patch like this to avoid messing up config file?\n\nDoesn't stripspace() cleanse that already?\n"},{"id":"176097","messageId":"20110923201824.GA27999@sigill.intra.peff.net","threadId":"28380","inReplyTo":"4E7C49CF.60508@drmicha.warpmail.net","subject":"Re: [PATCH 0/6] A handful of \"branch description\" patches","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-23T20:18:24Z","receivedAt":"2011-09-23T20:18:24Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Sep 23, 2011 at 10:56:47AM +0200, Michael J Gruber wrote:\n\n>   mjg/vob/refrev-pretend [mjg/vob/virtual-objects: ahead 1]\n>     Pseudo revs for refnames\n>     \n>     An alternative implementation using pretend_sha1...\n>     Currently unused.\n> \n>   mjg/vob/virtual-objects [origin/next: ahead 2, behind 10]\n>     Virtual refname objects\n>     \n>     For each existing refname, introduce virtual objects corresponding to a blob\n>     with the refname as the content. \"virtual\" refers to the fact that these\n>     objects are not written out but exist for all other purposes, such as\n>     attaching notes and keeping them from being pruned.\n\nEww. :)\n\nThis seems like a clever solution to making git-notes store a ref as a\nkey instead of an arbitrary sha1. But I wonder if the end result is\nreally waht the user wants. The resulting notes tree is good for doing\nlookups, but the entries are completely obfuscated. So I can't easily do\nsomething like \"list all of the refs which have descriptions\". I can\nonly list the _hashes_ of the refs which have descriptions. And if I am\nlucky, I can hash the refs I have and correlate them. But unknown ones\nwill simply be a mystery.\n\nWouldn't it be much more friendly to have a separate tree of refnames\nthat stores:\n\n  refs/heads/foo -> (some blob with the \"foo\" description)\n  refs/heads/bar -> (some blob with the \"bar\" description)\n\nYeah, you have to build another git-notes-like interface around it. But\nthe data structure is pleasant and flexible. You could even \"git\ncheckout\" the whole tree and edit the notes with your editor, without\nhaving to deal with some obfuscated name.\n\n-Peff\n"},{"id":"176098","messageId":"7vk48zt211.fsf@alter.siamese.dyndns.org","threadId":"28380","inReplyTo":"20110923201824.GA27999@sigill.intra.peff.net","subject":"Re: [PATCH 0/6] A handful of \"branch description\" patches","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-23T20:52:10Z","receivedAt":"2011-09-23T20:52:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Eww. :)\n>\n> This seems like a clever solution to making git-notes store a ref as a\n> key instead of an arbitrary sha1. But I wonder if the end result is\n> really waht the user wants.\n\nA more fundamental issue I have with this is that names of the refs are\nlocal by nature (what I call \"master\" branch is not \"master\" to you, but\nrather it is \"origin/master\" or \"jch/master\") while notes is meant to be\nthe mechanism to share. The following shares the same issue, but at least\nit does not abuse \"notes\", so in that sense it may be cleaner at the\ndesign level...\n\n> Wouldn't it be much more friendly to have a separate tree of refnames\n> that stores:\n>\n>   refs/heads/foo -> (some blob with the \"foo\" description)\n>   refs/heads/bar -> (some blob with the \"bar\" description)\n>\n> Yeah, you have to build another git-notes-like interface around it. But\n> the data structure is pleasant and flexible. You could even \"git\n> checkout\" the whole tree and edit the notes with your editor, without\n> having to deal with some obfuscated name.\n"},{"id":"176099","messageId":"20110923205319.GA28802@sigill.intra.peff.net","threadId":"28380","inReplyTo":"7vk48zt211.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 0/6] A handful of \"branch description\" patches","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-23T20:53:19Z","receivedAt":"2011-09-23T20:53:19Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Sep 23, 2011 at 01:52:10PM -0700, Junio C Hamano wrote:\n\n> A more fundamental issue I have with this is that names of the refs are\n> local by nature (what I call \"master\" branch is not \"master\" to you, but\n> rather it is \"origin/master\" or \"jch/master\") while notes is meant to be\n> the mechanism to share. The following shares the same issue, but at least\n> it does not abuse \"notes\", so in that sense it may be cleaner at the\n> design level...\n\nGood point. For that reason, your config-based solution perhaps makes\nmore sense.\n\n-Peff\n"},{"id":"176125","messageId":"4E7DEC4A.3050900@drmicha.warpmail.net","threadId":"28380","inReplyTo":"20110923201824.GA27999@sigill.intra.peff.net","subject":"Re: [PATCH 0/6] A handful of \"branch description\" patches","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-24T14:42:18Z","receivedAt":"2011-09-24T14:42:18Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 23.09.2011 22:18:\n> On Fri, Sep 23, 2011 at 10:56:47AM +0200, Michael J Gruber wrote:\n> \n>>   mjg/vob/refrev-pretend [mjg/vob/virtual-objects: ahead 1]\n>>     Pseudo revs for refnames\n>>     \n>>     An alternative implementation using pretend_sha1...\n>>     Currently unused.\n>>\n>>   mjg/vob/virtual-objects [origin/next: ahead 2, behind 10]\n>>     Virtual refname objects\n>>     \n>>     For each existing refname, introduce virtual objects corresponding to a blob\n>>     with the refname as the content. \"virtual\" refers to the fact that these\n>>     objects are not written out but exist for all other purposes, such as\n>>     attaching notes and keeping them from being pruned.\n> \n> Eww. :)\n> \n> This seems like a clever solution to making git-notes store a ref as a\n> key instead of an arbitrary sha1. But I wonder if the end result is\n> really waht the user wants. The resulting notes tree is good for doing\n> lookups, but the entries are completely obfuscated. So I can't easily do\n> something like \"list all of the refs which have descriptions\". I can\n> only list the _hashes_ of the refs which have descriptions. And if I am\n> lucky, I can hash the refs I have and correlate them. But unknown ones\n> will simply be a mystery.\n\n[mjg@localhost git]$ git rev-parse ref:mjg/vob/virtual-objects\n3f8aa9bb80fe241306aafd3d76af50739ba88268\n[mjg@localhost git]$ git show 3f8aa9bb80fe241306aafd3d76af50739ba88268\nrefs/heads/mjg/vob/virtual-objects\n\n:)\n\nThe only problem is with notes for non-existing refs. [You only have to\ninvoke the inverse mapping to sha1, of course... Uhm.]\n\n> Wouldn't it be much more friendly to have a separate tree of refnames\n> that stores:\n> \n>   refs/heads/foo -> (some blob with the \"foo\" description)\n>   refs/heads/bar -> (some blob with the \"bar\" description)\n\nGiven the above, I don't think it's more friendly.\n\nIn fact, in my first attempt, I wrote out the blobs, and referenced them\njust like above from a different subtree within the notes tree, in order\nto keep them from being pruned. So the virtual approach is pretty\nequivalent, though leaner.\n\n> Yeah, you have to build another git-notes-like interface around it. But\n> the data structure is pleasant and flexible. You could even \"git\n> checkout\" the whole tree and edit the notes with your editor, without\n> having to deal with some obfuscated name.\n\nWell, \"git branch --edit-description\" and such should be the way to edit\nthem, shouldn't it?\n\nI really think the only issue is remote refnames. As Junio points out,\nthey are local by nature. OTOH, you typically use a non-renaming refspec\nwhich puts them under refs/remotes/foo/bar with \"bar\" being the same\nname as the local one on the remote, foo something you have chosen. So,\nteaching the code that the note for\n\nrefs/remotes/foo/bar\n\nis in the notes tree\n\nrefs/remotes/foo/notes/commits (or .../refames, or whatever we do with\nthe namespaces)\n\nas a note attached to sha1(\"refs/bar\")\n\nis really a non-issue. It's not done yet, in part because of the\npossible namespace restructuring.\n\nMichael\n"},{"id":"176156","messageId":"CACsJy8BdLKdT-CiBBD1FmnSo3ZBcRQmMst7FN2fmDrgvzqbyng@mail.gmail.com","threadId":"28380","inReplyTo":"7v62kjulkf.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 3/6] branch: teach --edit-description option","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-09-25T05:21:17Z","receivedAt":"2011-09-25T05:21:17Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Sep 24, 2011 at 5:04 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> On Thu, Sep 22, 2011 at 03:09:19PM -0700, Junio C Hamano wrote:\n>>> +    if (launch_editor(git_path(edit_description), &buf, NULL)) {\n>>> +            strbuf_release(&buf);\n>>> +            return -1;\n>>> +    }\n>>> +    stripspace(&buf, 1);\n>>> +\n>>> +    strbuf_addf(&name, \"branch.%s.description\", branch_name);\n>>> +    status = git_config_set(name.buf, buf.buf);\n>>\n>> I suppose a Windows editor mave save the description with \\r\\n\n>> ending. Perhaps a patch like this to avoid messing up config file?\n>\n> Doesn't stripspace() cleanse that already?\n>\n\nYes, isspace() indeed treats \\r as a space and stripspace() does the\nright thing.\n-- \nDuy\n"},{"id":"176362","messageId":"20110927215843.GE5176@sigill.intra.peff.net","threadId":"28380","inReplyTo":"4E7DEC4A.3050900@drmicha.warpmail.net","subject":"Re: [PATCH 0/6] A handful of \"branch description\" patches","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-27T21:58:43Z","receivedAt":"2011-09-27T21:58:43Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Sep 24, 2011 at 04:42:18PM +0200, Michael J Gruber wrote:\n\n> > This seems like a clever solution to making git-notes store a ref as a\n> > key instead of an arbitrary sha1. But I wonder if the end result is\n> > really waht the user wants. The resulting notes tree is good for doing\n> > lookups, but the entries are completely obfuscated. So I can't easily do\n> > something like \"list all of the refs which have descriptions\". I can\n> > only list the _hashes_ of the refs which have descriptions. And if I am\n> > lucky, I can hash the refs I have and correlate them. But unknown ones\n> > will simply be a mystery.\n> \n> [mjg@localhost git]$ git rev-parse ref:mjg/vob/virtual-objects\n> 3f8aa9bb80fe241306aafd3d76af50739ba88268\n> [mjg@localhost git]$ git show 3f8aa9bb80fe241306aafd3d76af50739ba88268\n> refs/heads/mjg/vob/virtual-objects\n\nSure, but what about:\n\n  git notes list\n\nwhich is just filled with meaningless nonsense.\n\n> > Wouldn't it be much more friendly to have a separate tree of refnames\n> > that stores:\n> > \n> >   refs/heads/foo -> (some blob with the \"foo\" description)\n> >   refs/heads/bar -> (some blob with the \"bar\" description)\n> \n> Given the above, I don't think it's more friendly.\n> \n> In fact, in my first attempt, I wrote out the blobs, and referenced them\n> just like above from a different subtree within the notes tree, in order\n> to keep them from being pruned. So the virtual approach is pretty\n> equivalent, though leaner.\n\nHmm. So your mapping of $ref to $desc is:\n\n  sha1($ref) -> sha1(blob($desc))\n\n>From what you wrote there, I think maybe you think I meant to store:\n\n  sha1(blob($ref)) -> sha1(blob($desc))\n\nBut what I meant was actually:\n\n  $ref -> sha1(blob($desc))\n\nI.e., not to use \"notes\" at all, but rather a tree that mirrors the\nrefs/ hierarchy in its names.\n\n> > Yeah, you have to build another git-notes-like interface around it. But\n> > the data structure is pleasant and flexible. You could even \"git\n> > checkout\" the whole tree and edit the notes with your editor, without\n> > having to deal with some obfuscated name.\n> \n> Well, \"git branch --edit-description\" and such should be the way to edit\n> them, shouldn't it?\n\nIt's one way. I assume that if we store things in a reasonable,\nreadable state, then people like that because they can hack on the data\nstructure using more flexible tools.\n\n> I really think the only issue is remote refnames. As Junio points out,\n> they are local by nature. OTOH, you typically use a non-renaming refspec\n> which puts them under refs/remotes/foo/bar with \"bar\" being the same\n> name as the local one on the remote, foo something you have chosen. So,\n> teaching the code that the note for\n\nIf they are local by nature, is it worth putting them into a notes tree\nat all? That provides versioning and backup. But I wonder if it is worth\nthe hassle, when one could just put them in the config.\n\n-Peff\n"},{"id":"176384","messageId":"4E82A13B.2080509@alum.mit.edu","threadId":"28380","inReplyTo":"20110927215843.GE5176@sigill.intra.peff.net","subject":"Annotated branch ≈ annotated tag?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-28T04:23:23Z","receivedAt":"2011-09-28T04:23:23Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/27/2011 11:58 PM, Jeff King wrote:\n> On Sat, Sep 24, 2011 at 04:42:18PM +0200, Michael J Gruber wrote:\n>> I really think the only issue is remote refnames. As Junio points out,\n>> they are local by nature. OTOH, you typically use a non-renaming refspec\n>> which puts them under refs/remotes/foo/bar with \"bar\" being the same\n>> name as the local one on the remote, foo something you have chosen. So,\n>> teaching the code that the note for\n> \n> If they are local by nature, is it worth putting them into a notes tree\n> at all? That provides versioning and backup. But I wonder if it is worth\n> the hassle, when one could just put them in the config.\n\nI don't think that branch descriptions should be local-only.  They would\nbe a good way to share information with others about work in progress.\n\nIt seems to me that an annotated branch is very much like an (unsigned)\nannotated tag, except that it is movable and disposable like a normal\nbranch.  What would be the ramifications of using an annotated-tag-like\nobject to record metainformation about a branch?  (Let's just call it an\n\"annotation object\" for this discussion.)\n\n* The branch would point not at a commit but at an annotation object\nthat points at a commit.\n\n* Obviously, a new annotation object would have to be written every time\nthe branch is updated.\n\n  * Presumably, by default, the old description would be copied from the\nold annotation object to the new one; the committer would be set to\nthose of the user doing the update.\n\n  * The old annotation object would become unreachable after every\nbranch update, though locally it would still be reachable via the\nbranch's reflog [1].\n\n* Creating a new branch from an annotated branch should perhaps open an\neditor to allow the user to set a new comment.  If the user deletes the\nwhole comment in the editor, then an unannotated branch is created\ninstead of an annotated branch.\n\n* We would need rules for merging annotation objects:\n\n  * There is no such thing as a fast-forward merge to an annotated\nbranch, because the merged-from branch, even if annotated, can never\nhave the merged-to annotation object in its history.  So proceed to the\nfollowing rules.\n\n  * If both branches are unannotated, then the result should be an\nunannotated branch (like today).\n\n  * If both branches have the same comment, the comment should be\ncarried over to the result without prompting.\n\n  * If the merge-to branch is annotated and the merge-from branch is\nnot, keep the merge-to branch's annotation.\n\n  * If the merge-to branch is unannotated and the merge-from branch is\nannotated, the result should be a conflict.  This cannot be resolved\nautomatically because there are two likely scenarios:\n\n    * A remote branch is being merged into a remote-tracking branch.  In\nthis case somebody upstream probably added a comment to the branch, and\none would like to preserve this comment in a local annotated branch.\n\n    * A feature branch is being merged back to mainline.  In such a case\none would *not* like to carry over the branch annotation (which\npresumably describes the feature that was developed on the branch),\nthough it would often be convenient to integrate the merged-from branch\nannotation into the log message of the merge commit.\n\n    I'm not sure how to let the user distinguish between the two cases\nabove, but it probably involves $EDITOR.\n\n  * If the merge-to branch and the merge-from branch have conflicting\nannotations, there are two possibilities much like in the previous case.\n\n* Annotated tag objects include the name of the tag that is being\nannotated.  Annotated branch objects should *not* include this\ninformation, because it does not carry across from one repo to another\nwhen branches are renamed.  (Perhaps the presence/absence of the tag\nname could be what distinguishes an (unmovable) annotated tag object\nfrom a (movable) annotated branch object.)\n\nIt would even be possible to allow signatures in the annotated objects;\nthese could play the role of push certificates.  Whenever a signed\nannotated branch is updated, the signature would go away (it would\nprobably be too cumbersome to prompt the user to generate it a new\nsignature for every branch update).  It should be easy to add a\nsignature to an existing annotated or unannotated branch (writing a new\nannotation object, of course).\n\nISTM that the semantics would be very close to what is desired, and\nwould satisfy a few needs: a place to describe work-in-progress in a\nsharable way, branch descriptions that can be used for constructing pull\nrequests and merge commit messages, and (optionally) a way to implement\nsigned pushes.  It would surely be a lot of work to implement, but being\nbased on annotated tags would mean that a lot of code, documentation,\nand training would be common to the two concepts.\n\nMichael\n\n[1] If the retention of annotation history were considered a\nrequirement, the annotation object could record as a \"parent\" the object\nname of the annotation object that it is succeeding.  But I don't think\nthat this is a good idea; it would make branches too heavyweight and\nevery branch update would be recorded permanently, both of which are\ncontrary to the git philosophy.\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"176386","messageId":"CAH5451nT2Z6mBPkK4B2EgJAoMpf32bcc=7UqhTDnsw4-_hJwJw@mail.gmail.com","threadId":"28380","inReplyTo":"4E82A13B.2080509@alum.mit.edu","subject":"Re: Annotated branch ≈ annotated tag?","fromName":"Andrew Ardill","fromEmail":"andrew.ardill@gmail.com","sentAt":"2011-09-28T07:12:13Z","receivedAt":"2011-09-28T07:12:13Z","isPatch":false,"sender":{"key":"andrew.ardill@gmail.com","avatar":"https://gravatar.com/avatar/da14cb7c091dd44dc6c63a4d3361b149acaf25226dc78eb4131a17b93d9b0993?d=mp&s=160"},"body":"On 28 September 2011 14:23, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n[snip]\n>\n> [1] If the retention of annotation history were considered a\n> requirement, the annotation object could record as a \"parent\" the object\n> name of the annotation object that it is succeeding.  But I don't think\n> that this is a good idea; it would make branches too heavyweight and\n> every branch update would be recorded permanently, both of which are\n> contrary to the git philosophy.\n\nIf this was required, a better way would be to update the parent object only\nif the description changed. You would then have a nice little DAG that\nrecords changes to the description and could be used in 3-way merges etc.\nYou would of course get lots of 'dead' annotation objects pointing to the\nprevious change, however that shouldn't be too much of an issue.\n\nAt this point, however, I ask how is an annotation object any different to\nplacing an annotation file in our repository. Perhaps there is no difference,\nexcept that one is a convention and the other is provided.\n\nRegards,\nAndrew\n"},{"id":"176391","messageId":"4E82D52B.9020709@alum.mit.edu","threadId":"28380","inReplyTo":"CAH5451nT2Z6mBPkK4B2EgJAoMpf32bcc=7UqhTDnsw4-_hJwJw@mail.gmail.com","subject":"Re: Annotated branch ≈ annotated tag?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-28T08:04:59Z","receivedAt":"2011-09-28T08:04:59Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/28/2011 09:12 AM, Andrew Ardill wrote:\n> On 28 September 2011 14:23, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> [snip]\n>>\n>> [1] If the retention of annotation history were considered a\n>> requirement, the annotation object could record as a \"parent\" the object\n>> name of the annotation object that it is succeeding.  But I don't think\n>> that this is a good idea; it would make branches too heavyweight and\n>> every branch update would be recorded permanently, both of which are\n>> contrary to the git philosophy.\n> \n> If this was required, a better way would be to update the parent object only\n> if the description changed. You would then have a nice little DAG that\n> records changes to the description and could be used in 3-way merges etc.\n> You would of course get lots of 'dead' annotation objects pointing to the\n> previous change, however that shouldn't be too much of an issue.\n> \n> At this point, however, I ask how is an annotation object any different to\n> placing an annotation file in our repository. Perhaps there is no difference,\n> except that one is a convention and the other is provided.\n\nYes, if history is being preserved, then the annotation objects would\nnot be much different than storing a file in the repository.  But even\nthen, there are differences:\n\n- A branch annotation would be separate from the source code and not\nappear in the working tree, which seems more appropriate for metadata.\n\n- git and other tools would know where to find the annotation instead of\nhaving to configure whether a particular project uses annotations and if\nso where to find them.  This would make it easier to use the annotations\nin git workflow like the generation of pull requests.\n\n- The merge rules for annotations would be different than those for\nother files.\n\nBut I believe that branch annotation history should *not* be retained,\nso storing the annotations in the source tree is not even an option\n(except perhaps in another artificial branch used only for annotations).\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"176394","messageId":"4E82E1A8.5080305@drmicha.warpmail.net","threadId":"28380","inReplyTo":"4E82D52B.9020709@alum.mit.edu","subject":"Branch annotations [Re: Annotated branch ≈ annotated tag?]","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-28T08:58:16Z","receivedAt":"2011-09-28T08:58:16Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"I'm not tied to a particular implementation (not even mine), but we\nshould think through the concept before baking something in. That was my\nimpetus for throwing in a (half-baked) notes based solution before a\nconfig based is baked^Wset in stone ;)\n\nFor me, commit annotations as currently implemented (notes) have the\nfollowing positives:\n\n* easy ui (add/edit/copy)\n* easy scripting (-F/-m)\n* can be shared *if I want* (by pushing refspec; note that share=backup\nas well as share=publish, depending on where I push to); ui could be\nsomewhat better\n* multiple sources possible\n* is versioned (ui could be better, e.g. git notes log)\n\nFor branch annotations, I would want to have all of the above. Depending\non the use case, I want to treat branch annotations as purely local (but\nmay still want to push them to backup) or share and publish them. I\nmight be interested in their history or not, etc. In addition, we would\nwant to have the obvious:\n* git branch -m moves annotation\n* git branch --list --younameit shows annotation\n* etc.\n\nIf we agree that we want the above properties (and that is a big if)\nthen using notes seem very natural. [Having to rewrite an annotated tag\nobject at each branch head change appears unnatural.] They should\nprobably live in a separate default tree (one per remote for remote\nbranches), and the actual mechanics (virtual objects, real objects,\ntextconvcache like...) is not dictated by those requirements.\n\nNote though that we might be interested in annotating more general names\nthan just refnames, e.g. paths, or names like \"description\". Since tags\nshould be immutable, adding notes to a tag seems not much different from\nannotating the referenced commit, but it is different in concept and\ncould be treated differently (as tag notes would be in a separate tree\nfrom the commit notes tree).\n\nSo, if we want to keep that path open (annotate more general names), a\nmapping from names to notes becomes mandatory. Again, that does not\ndictate a specific implementation.\n\nMichael\n"},{"id":"176475","messageId":"20110929064404.GA14022@sigill.intra.peff.net","threadId":"28380","inReplyTo":"4E82A13B.2080509@alum.mit.edu","subject":"Re: Annotated branch ≈ annotated tag?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-29T06:44:04Z","receivedAt":"2011-09-29T06:44:04Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Sep 28, 2011 at 06:23:23AM +0200, Michael Haggerty wrote:\n\n> It seems to me that an annotated branch is very much like an (unsigned)\n> annotated tag, except that it is movable and disposable like a normal\n> branch.  What would be the ramifications of using an annotated-tag-like\n> object to record metainformation about a branch?  (Let's just call it an\n> \"annotation object\" for this discussion.)\n> \n> * The branch would point not at a commit but at an annotation object\n> that points at a commit.\n> \n> * Obviously, a new annotation object would have to be written every time\n> the branch is updated.\n\nLeaving aside for a moment whether this is a good system or not, I think\nit's infeasible at this point simply because it is so far from what\ncurrent git does, and in such a visible way.\n\nConsider the interactions between this system and older versions of git.\nWon't all of the older clients see this annotation cruft at the tip of\neach branch? How will they react? It would no longer be correct to make\ncommits with \"git commit-tree $tree `git rev-parse HEAD`\", would it?\n\n-Peff\n"}]}