{"thread":{"id":"28207","subject":"Buggy handling of non-canonical ref names","startedAt":"2011-08-24T15:49:04Z","lastAt":"2011-08-25T21:57:46Z","messageCount":10,"participants":["Michael Haggerty","Junio C Hamano","Carlos Martín Nieto"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"174163","messageId":"4E551D70.9080509@alum.mit.edu","threadId":"28207","inReplyTo":null,"subject":"Buggy handling of non-canonical ref names","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-24T15:49:04Z","receivedAt":"2011-08-24T15:49:04Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"git has inconsistencies (I would say bugs) in how it handles reference\nnames that are in non-canonical format (e.g., \"/foo/bar\", \"foo///bar\",\netc).  Some commands work with reference names that are in non-canonical\nform, whereas others do not.  Sometimes the behavior depends on whether\nthe reference is loose or packed.\n\nFor example \"git branch\" and \"git update-ref\" seem to swallow them OK:\n\n    $ git update-ref /foo/bar HEAD\n    $ cat .git/foo/bar\n    ef6cf90ba11dd6205f8b974692d795ea0b1c0bdd\n    $ git branch /bar/baz\n    $ git for-each-ref | grep baz\n    ef6cf90ba11dd6205f8b974692d795ea0b1c0bdd commit refs/heads/bar/baz\n\nBut other commands do not:\n\n    $ git rev-parse /foo/bar --\n    /foo/bar\n    fatal: ambiguous argument '/foo/bar': unknown revision or path not\nin the working tree.\n    Use '--' to separate paths from revisions\n    $ git rev-parse foo///bar --\n    foo///bar\n    fatal: ambiguous argument 'foo///bar': unknown revision or path not\nin the working tree.\n    Use '--' to separate paths from revisions\n    $ git rev-parse foo/bar --\n    ef6cf90ba11dd6205f8b974692d795ea0b1c0bdd\n    --\n\nIt seems like most of the canonicalization of reference names is via\npath canonicalization using the likes of git_snpath() and git_path(),\nwith the exception of \"git check-ref-format --print\", which does the\nwork using its own code.  But packed references are not transformed into\npaths, so they don't handle canonicalization at all.  For example, in\nthe following case, there is a difference between how packed and\nunpacked references are handled:\n\n    $ git update-ref refs/heads/foo/bar HEAD\n    $ git update-ref -d refs/heads/foo///bar HEAD\n    [Reference was really deleted]\n    $ git update-ref refs/heads/foo/bar HEAD\n    $ git pack-refs --all\n    $ git update-ref -d refs/heads/foo///bar HEAD\n    error: unable to resolve reference refs/heads/foo///bar: No such\nfile or directory\n    $ git for-each-ref | grep foo\n    ffae1b1dc75896bd89ff3cbe7037f40474e57e2a commit refs/heads/foo/bar\n    [Reference was not deleted]\n\nWhat is the policy about reference names and their canonicalization?  In\nwhat situations should one be able to use non-canonical refnames, and in\nwhat situations should it be forbidden?\n\nGiven that refnames are closely associated with filesystem paths, it is\nimportant that every code path either canonicalize or reject\nnon-canonical refnames (i.e., failure to do so could be a security\nproblem).  In the absence of clear rules, it will be very difficult to\nensure that this is being done consistently.\n\nI also noticed that check_ref_format() accepts ref names that start with\na \"/\", but that the leading slash is *not* stripped off as part of the\ncanonicalization:\n\n    $ git check-ref-format /foo/bar ; echo $?\n    0\n    $ git check-ref-format --print /foo/bar\n    /foo/bar\n\nHowever, creating a reference with such a name is equivalent to creating\na reference without the leading slash:\n\n    $ git update-ref /foo/bar HEAD\n    $ cat .git/foo/bar\n    ef6cf90ba11dd6205f8b974692d795ea0b1c0bdd\n    $ git branch /bar/baz\n    $ git for-each-ref | grep baz\n    ef6cf90ba11dd6205f8b974692d795ea0b1c0bdd commit refs/heads/bar/baz\n\nTherefore, it seems to belong in the equivalence class of \"foo/bar\".\n\nThe test suite for \"git check-ref-format\" says nothing about how leading\nslashes should be handled.\n\nEither leading slashes should not be allowed in ref names at all or they\nshould be canonicalized away.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"174174","messageId":"7vaaayps9z.fsf@alter.siamese.dyndns.org","threadId":"28207","inReplyTo":"4E551D70.9080509@alum.mit.edu","subject":"Re: Buggy handling of non-canonical ref names","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-24T18:40:24Z","receivedAt":"2011-08-24T18:40:24Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> What is the policy about reference names and their canonicalization?\n\nThe overall policy has been that we care about well-formed input, and\neverything else is \"undefined\", even though as you found out some of them\ntry to work sensibly.\n\n>     $ git check-ref-format /foo/bar ; echo $?\n>     0\n>\n>     $ git check-ref-format --print /foo/bar\n>     /foo/bar\n\nI think these are bogus. Patches welcome.\n\n> However, creating a reference with such a name is equivalent to creating\n> a reference without the leading slash:\n>\n>     $ git update-ref /foo/bar HEAD\n>     $ cat .git/foo/bar\n>     ef6cf90ba11dd6205f8b974692d795ea0b1c0bdd\n>     $ git branch /bar/baz\n>     $ git for-each-ref | grep baz\n>     ef6cf90ba11dd6205f8b974692d795ea0b1c0bdd commit refs/heads/bar/baz\n\nThese are just examples of \"undefined being nice to the user as a bonus\".\n"},{"id":"174195","messageId":"1314221553.4325.13.camel@centaur.lab.cmartin.tk","threadId":"28207","inReplyTo":"7vaaayps9z.fsf@alter.siamese.dyndns.org","subject":"Re: Buggy handling of non-canonical ref names","fromName":"Carlos Martín Nieto","fromEmail":"cmn@elego.de","sentAt":"2011-08-24T21:32:17Z","receivedAt":"2011-08-24T21:32:17Z","isPatch":false,"sender":{"key":"cmn@elego.de","avatar":"https://avatars.githubusercontent.com/u/335443?v=4"},"body":"On Wed, 2011-08-24 at 11:40 -0700, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n> \n> > What is the policy about reference names and their canonicalization?\n> \n> The overall policy has been that we care about well-formed input, and\n> everything else is \"undefined\", even though as you found out some of them\n> try to work sensibly.\n> \n> >     $ git check-ref-format /foo/bar ; echo $?\n> >     0\n> >\n> >     $ git check-ref-format --print /foo/bar\n> >     /foo/bar\n> \n> I think these are bogus. Patches welcome.\n> \n\nThe rules in the manpage don't forbit it, as we assume that $GIT_DIR/ is\ngoing to be put in front. This makes /foo/bar mean the same as foo/bar\n(both become would cause git to look at $GIT_DIR/foo/bar), but I agree\nthat it can be quite confusing.\n\n> > However, creating a reference with such a name is equivalent to creating\n> > a reference without the leading slash:\n> >\n> >     $ git update-ref /foo/bar HEAD\n> >     $ cat .git/foo/bar\n> >     ef6cf90ba11dd6205f8b974692d795ea0b1c0bdd\n> >     $ git branch /bar/baz\n> >     $ git for-each-ref | grep baz\n> >     ef6cf90ba11dd6205f8b974692d795ea0b1c0bdd commit refs/heads/bar/baz\n> \n> These are just examples of \"undefined being nice to the user as a bonus\".\n\nOr not, the user might have expected `git branch /bar/baz` to create a\nreference in $GIT_DIR/bar/baz with the SHA of the current branch (yes,\nit's probably unlikely, but this is what one might think when giving\nreferences as absolute paths).\n\n\nBe as it may, allowing /foo/bar is not a good thing, how about this\npatch? It doesn't modify the manpage, as I wasn't sure whether this\nshould become an explicit rule.\n\n-- >8 --\nSubject: [PATCH] Don't allow reference names to start with '/'\n\nBeing able to name references using absolute filenames is confusing\nat best and might give people wrong ideas.\n\nSigned-off-by: Carlos Martín Nieto <cmn@elego.de>\n---\n refs.c |    4 ++++\n 1 files changed, 4 insertions(+), 0 deletions(-)\n\ndiff --git a/refs.c b/refs.c\nindex 6f313a9..ab549e4 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -879,6 +879,10 @@ int check_ref_format(const char *ref)\n \tint ret = CHECK_REF_FORMAT_OK;\n \tconst char *cp = ref;\n \n+\t/* we don't want refs expressed as absolute paths */\n+\tif (*cp == '/')\n+\t\treturn CHECK_REF_FORMAT_ERROR;\n+\n \tlevel = 0;\n \twhile (1) {\n \t\twhile ((ch = *cp++) == '/')\n-- \n1.7.5.2.354.g349bf\n\n\n"},{"id":"174197","messageId":"7vaaayo369.fsf@alter.siamese.dyndns.org","threadId":"28207","inReplyTo":"7vaaayps9z.fsf@alter.siamese.dyndns.org","subject":"Re: Buggy handling of non-canonical ref names","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-24T22:27:58Z","receivedAt":"2011-08-24T22:27:58Z","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> Michael Haggerty <mhagger@alum.mit.edu> writes:\n>\n>> What is the policy about reference names and their canonicalization?\n>\n> The overall policy has been that we care about well-formed input, and\n> everything else is \"undefined\", even though as you found out some of them\n> try to work sensibly.\n>\n>>     $ git check-ref-format /foo/bar ; echo $?\n>>     0\n>>\n>>     $ git check-ref-format --print /foo/bar\n>>     /foo/bar\n>\n> I think these are bogus. Patches welcome.\n\nI actually think the former is correct and the latter should strip the\nleading slash. Essentially what \"check-ref-format\" (and the underlying\ncheck_ref_format() function) validates is if the given user string can be\nused under $GIT_DIR/refs/ to name a ref, and $GIT_DIR/refs//foo/bar is\n(because we \"tolerate duplicated slashes\" cf. comment in the function) the\nsame as $GIT_DIR/refs/foo/bar and is allowed.\n\nI do not know what the original motivation behind --print was, but it\nseems to want to show it canonicalized, so it should strip the leading\nslash as well.\n\nI think what is missing is a unified way to canonicalize the refnames\n(which led to the inconsistencies you observed), and I strongly suspect\nthat check_ref_format() should learn to return the canonicalized format\n(if asked by the caller) and the caller should use the canonicalized\nversion after feeding end-user input to it.\n\nThen the plumbing \"check-ref-format --print\" can use it just like any\nother caller that should be (or already are) using check_ref_format()\nto validate the end-user input.\n\nYes, such a change will update the overall policy I stated earlier and\nnarrow the scope of \"undefined\" down a bit, by uniformly codifying that\nleading and duplicate slashes are removed to be nice to the user.\n"},{"id":"174213","messageId":"4E55FFAA.9030904@alum.mit.edu","threadId":"28207","inReplyTo":"7vaaayo369.fsf@alter.siamese.dyndns.org","subject":"Re: Buggy handling of non-canonical ref names","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-25T07:54:18Z","receivedAt":"2011-08-25T07:54:18Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 08/25/2011 12:27 AM, Junio C Hamano wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>> Michael Haggerty <mhagger@alum.mit.edu> writes:\n>>> What is the policy about reference names and their canonicalization?\n>>\n>> The overall policy has been that we care about well-formed input, and\n>> everything else is \"undefined\", even though as you found out some of them\n>> try to work sensibly.\n>>\n>>>     $ git check-ref-format /foo/bar ; echo $?\n>>>     0\n>>>\n>>>     $ git check-ref-format --print /foo/bar\n>>>     /foo/bar\n>>\n>> I think these are bogus. Patches welcome.\n> \n> I actually think the former is correct and the latter should strip the\n> leading slash. Essentially what \"check-ref-format\" (and the underlying\n> check_ref_format() function) validates is if the given user string can be\n> used under $GIT_DIR/refs/ to name a ref, and $GIT_DIR/refs//foo/bar is\n> (because we \"tolerate duplicated slashes\" cf. comment in the function) the\n> same as $GIT_DIR/refs/foo/bar and is allowed.\n\nI can live with either way, but I should point out that such an extra\nslash can be problematic when used naively in conjunction with Python's\nstandard glue-together-pathname function, os.path.join() [1]:\n\n    $ python\n    >>> import os\n    >>> os.path.join('.git', '/foo/bar')\n    '/foo/bar'\n    >>>\n\nMaybe there are other examples of libraries with these semantics.\n\n> I think what is missing is a unified way to canonicalize the refnames\n> (which led to the inconsistencies you observed), and I strongly suspect\n> that check_ref_format() should learn to return the canonicalized format\n> (if asked by the caller) and the caller should use the canonicalized\n> version after feeding end-user input to it.\n> \n> Then the plumbing \"check-ref-format --print\" can use it just like any\n> other caller that should be (or already are) using check_ref_format()\n> to validate the end-user input.\n\nIndeed, regardless of the policy about leading slashes, this is a good\nplan.  I will try to find time to work on it.\n\n> Yes, such a change will update the overall policy I stated earlier and\n> narrow the scope of \"undefined\" down a bit, by uniformly codifying that\n> leading and duplicate slashes are removed to be nice to the user.\n\nMichael\n\n[1] http://docs.python.org/library/os.path.html#os.path.join\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"174215","messageId":"1314259695-30801-1-git-send-email-mhagger@alum.mit.edu","threadId":"28207","inReplyTo":"4E55FFAA.9030904@alum.mit.edu","subject":"[PATCH] Do not allow refnames to start with a slash","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-25T08:08:15Z","receivedAt":"2011-08-25T08:08:15Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Previously, refnames with leading slashes were handled inconsistently.\nSo forbid them altogether.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\nThis patch chooses the alternative of forbidding leading slashes,\nbecause I feel that it is the safer option.  It is like Carlos's patch\nbut with documentation changes, test-suite additions, and an\ncorresponding change to git.py.  If anybody knows of other\nimplementations of the ref format checking code, please let me know.\n\nThis patch applies to either master or maint.  Since it restricts the\nDWIM behavior in some cases, master is probably the better choice.\n\n Documentation/git-check-ref-format.txt |    7 ++++---\n git_remote_helpers/git/git.py          |    3 ++-\n refs.c                                 |    3 +++\n t/t1402-check-ref-format.sh            |    4 ++++\n 4 files changed, 13 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt\nindex c9fdf84..238b185 100644\n--- a/Documentation/git-check-ref-format.txt\n+++ b/Documentation/git-check-ref-format.txt\n@@ -34,15 +34,16 @@ git imposes the following rules on how references are named:\n   category like `heads/`, `tags/` etc. but the actual names are not\n   restricted.\n \n-. They cannot have two consecutive dots `..` anywhere.\n+. They must not start or end with slash `/`.\n+\n+. They cannot have two consecutive dots `..` anywhere or end with a\n+  dot `.`.\n \n . They cannot have ASCII control characters (i.e. bytes whose\n   values are lower than \\040, or \\177 `DEL`), space, tilde `~`,\n   caret `{caret}`, colon `:`, question-mark `?`, asterisk `*`,\n   or open bracket `[` anywhere.\n \n-. They cannot end with a slash `/` nor a dot `.`.\n-\n . They cannot end with the sequence `.lock`.\n \n . They cannot contain a sequence `@{`.\ndiff --git a/git_remote_helpers/git/git.py b/git_remote_helpers/git/git.py\nindex a383e6c..6df53aa 100644\n--- a/git_remote_helpers/git/git.py\n+++ b/git_remote_helpers/git/git.py\n@@ -55,7 +55,8 @@ def valid_git_ref (ref_name):\n     # command.  The rules were derived from the git check-ref-format(1)\n     # manual page.  This code should be replaced by a call to\n     # check_ref_format() in the git library, when such is available.\n-    if ref_name.endswith('/') or \\\n+    if ref_name.startswith('/') or \\\n+       ref_name.endswith('/') or \\\n        ref_name.startswith('.') or \\\n        ref_name.count('/.') or \\\n        ref_name.count('..') or \\\ndiff --git a/refs.c b/refs.c\nindex 6f313a9..84c5af3 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -880,6 +880,9 @@ int check_ref_format(const char *ref)\n \tconst char *cp = ref;\n \n \tlevel = 0;\n+\tif (*cp == '/')\n+\t\t/* no leading slashes */\n+\t\treturn CHECK_REF_FORMAT_ERROR;\n \twhile (1) {\n \t\twhile ((ch = *cp++) == '/')\n \t\t\t; /* tolerate duplicated slashes */\ndiff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh\nindex 1b0f82f..b05ca26 100755\n--- a/t/t1402-check-ref-format.sh\n+++ b/t/t1402-check-ref-format.sh\n@@ -18,6 +18,10 @@ invalid_ref 'foo'\n valid_ref 'foo/bar/baz'\n valid_ref 'refs///heads/foo'\n invalid_ref 'heads/foo/'\n+invalid_ref '/foo'\n+invalid_ref 'foo/'\n+invalid_ref '/foo/bar'\n+invalid_ref 'foo/bar/'\n invalid_ref './foo'\n invalid_ref '.refs/foo'\n invalid_ref 'heads/foo..bar'\n-- \n1.7.6.8.gd2879\n"},{"id":"174244","messageId":"7v39gpmk3x.fsf@alter.siamese.dyndns.org","threadId":"28207","inReplyTo":"1314259695-30801-1-git-send-email-mhagger@alum.mit.edu","subject":"Re: [PATCH] Do not allow refnames to start with a slash","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-25T18:17:22Z","receivedAt":"2011-08-25T18:17:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh\n> index 1b0f82f..b05ca26 100755\n> --- a/t/t1402-check-ref-format.sh\n> +++ b/t/t1402-check-ref-format.sh\n> @@ -18,6 +18,10 @@ invalid_ref 'foo'\n>  valid_ref 'foo/bar/baz'\n>  valid_ref 'refs///heads/foo'\n>  invalid_ref 'heads/foo/'\n\n> +invalid_ref '/foo'\n> +invalid_ref '/foo/bar'\n\nAs refs///heads/foo is defined to be valid_ref, I am moderately against\nthis change, which can break existing scripts.\n\n> +invalid_ref 'foo/'\n> +invalid_ref 'foo/bar/'\n\nWe already check trailing slash in existing checks, so I do not see a\npoint in these two additional lines.\n\n>  invalid_ref './foo'\n>  invalid_ref '.refs/foo'\n>  invalid_ref 'heads/foo..bar'\n\nI was about to write \"other than that the patch looks good\", but then\nrealized there is nothing remaining after rejecting the new \"now slash\ncannot come at the beginning\".\n"},{"id":"174253","messageId":"1314299964-21866-1-git-send-email-mhagger@alum.mit.edu","threadId":"28207","inReplyTo":"7v39gpmk3x.fsf@alter.siamese.dyndns.org","subject":"[PATCH] check-ref-format --print: Normalize refnames that start with slashes","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-25T19:19:24Z","receivedAt":"2011-08-25T19:19:24Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"And add tests that such refnames are accepted and normalized\ncorrectly.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n\nI didn't convince Junio that it is preferable to reject refnames that\nstart with slashes, so go the other way instead.\n\nThis patch should be applied to maint, as it fixes a bug.  The\nnormalization should probably be moved to refs.[ch] as mentioned on\nthe mailing list, but that can be done separately, on master.\n\n builtin/check-ref-format.c  |    6 ++++--\n t/t1402-check-ref-format.sh |    7 +++++++\n 2 files changed, 11 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c\nindex ae3f281..7118021 100644\n--- a/builtin/check-ref-format.c\n+++ b/builtin/check-ref-format.c\n@@ -12,8 +12,8 @@ static const char builtin_check_ref_format_usage[] =\n \"   or: git check-ref-format --branch <branchname-shorthand>\";\n \n /*\n- * Replace each run of adjacent slashes in src with a single slash,\n- * and write the result to dst.\n+ * Remove leading slashes and replace each run of adjacent slashes in\n+ * src with a single slash, and write the result to dst.\n  *\n  * This function is similar to normalize_path_copy(), but stripped down\n  * to meet check_ref_format's simpler needs.\n@@ -23,6 +23,8 @@ static void collapse_slashes(char *dst, const char *src)\n \tchar ch;\n \tchar prev = '\\0';\n \n+\twhile (*src == '/')\n+\t\tsrc++;\n \twhile ((ch = *src++) != '\\0') {\n \t\tif (prev == '/' && ch == prev)\n \t\t\tcontinue;\ndiff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh\nindex 1b0f82f..e6fafb2 100755\n--- a/t/t1402-check-ref-format.sh\n+++ b/t/t1402-check-ref-format.sh\n@@ -18,6 +18,9 @@ invalid_ref 'foo'\n valid_ref 'foo/bar/baz'\n valid_ref 'refs///heads/foo'\n invalid_ref 'heads/foo/'\n+valid_ref '/heads/foo'\n+valid_ref '///heads/foo'\n+invalid_ref '/foo'\n invalid_ref './foo'\n invalid_ref '.refs/foo'\n invalid_ref 'heads/foo..bar'\n@@ -28,6 +31,7 @@ valid_ref 'heads/foo@bar'\n invalid_ref 'heads/v@{ation'\n invalid_ref 'heads/foo\\bar'\n \n+\n test_expect_success \"check-ref-format --branch @{-1}\" '\n \tT=$(git write-tree) &&\n \tsha1=$(echo A | git commit-tree $T) &&\n@@ -70,7 +74,10 @@ invalid_ref_normalized() {\n \n valid_ref_normalized 'heads/foo' 'heads/foo'\n valid_ref_normalized 'refs///heads/foo' 'refs/heads/foo'\n+valid_ref_normalized '/heads/foo' 'heads/foo'\n+valid_ref_normalized '///heads/foo' 'heads/foo'\n invalid_ref_normalized 'foo'\n+invalid_ref_normalized '/foo'\n invalid_ref_normalized 'heads/foo/../bar'\n invalid_ref_normalized 'heads/./foo'\n invalid_ref_normalized 'heads\\foo'\n-- \n1.7.6.8.gd2879\n"},{"id":"174263","messageId":"7v39gpjk8m.fsf@alter.siamese.dyndns.org","threadId":"28207","inReplyTo":"1314299964-21866-1-git-send-email-mhagger@alum.mit.edu","subject":"Re: [PATCH] check-ref-format --print: Normalize refnames that start with slashes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-25T20:42:49Z","receivedAt":"2011-08-25T20:42:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> And add tests that such refnames are accepted and normalized\n> correctly.\n\nThanks. I think this is a bit simpler, though...\n\n builtin/check-ref-format.c  |    4 +---\n t/t1402-check-ref-format.sh |    1 -\n 2 files changed, 1 insertions(+), 4 deletions(-)\n\ndiff --git b/builtin/check-ref-format.c a/builtin/check-ref-format.c\nindex 7118021..0723cf2 100644\n--- b/builtin/check-ref-format.c\n+++ a/builtin/check-ref-format.c\n@@ -21,10 +21,8 @@ static const char builtin_check_ref_format_usage[] =\n static void collapse_slashes(char *dst, const char *src)\n {\n \tchar ch;\n-\tchar prev = '\\0';\n+\tchar prev = '/';\n \n-\twhile (*src == '/')\n-\t\tsrc++;\n \twhile ((ch = *src++) != '\\0') {\n \t\tif (prev == '/' && ch == prev)\n \t\t\tcontinue;\ndiff --git b/t/t1402-check-ref-format.sh a/t/t1402-check-ref-format.sh\nindex e6fafb2..7563043 100755\n--- b/t/t1402-check-ref-format.sh\n+++ a/t/t1402-check-ref-format.sh\n@@ -31,7 +31,6 @@ valid_ref 'heads/foo@bar'\n invalid_ref 'heads/v@{ation'\n invalid_ref 'heads/foo\\bar'\n \n-\n test_expect_success \"check-ref-format --branch @{-1}\" '\n \tT=$(git write-tree) &&\n \tsha1=$(echo A | git commit-tree $T) &&\n"},{"id":"174276","messageId":"4E56C55A.6090909@alum.mit.edu","threadId":"28207","inReplyTo":"7v39gpjk8m.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] check-ref-format --print: Normalize refnames that start with slashes","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-25T21:57:46Z","receivedAt":"2011-08-25T21:57:46Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 08/25/2011 10:42 PM, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n> \n>> And add tests that such refnames are accepted and normalized\n>> correctly.\n> \n> Thanks. I think this is a bit simpler, though [...]\n\nIndeed.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"}]}