* [PATCH 1/4] Add tests for git check-ref-format
2009-10-12 5:25 ` [PATCH/RFC 0/4] plumbing to help fix git-gui Jonathan Nieder
@ 2009-10-12 5:27 ` Jonathan Nieder
2009-10-12 5:28 ` [PATCH 2/4] Documentation: describe check-ref-format --branch Jonathan Nieder
` (3 subsequent siblings)
4 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2009-10-12 5:27 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jens Lehmann, git, Shawn O. Pearce
The "git check-ref-format" command is a basic command various
porcelains rely on. Test its functionality to make sure it does
not unintentionally change.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
t/t1402-check-ref-format.sh | 44 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)
create mode 100644 t/t1402-check-ref-format.sh
diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
new file mode 100644
index 0000000..382bc6e
--- /dev/null
+++ b/t/t1402-check-ref-format.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+test_description='Test git check-ref-format'
+
+. ./test-lib.sh
+
+valid_ref() {
+ test_expect_success "ref name '$1' is valid" \
+ "git check-ref-format '$1'"
+}
+invalid_ref() {
+ test_expect_success "ref name '$1' is not valid" \
+ "test_must_fail git check-ref-format '$1'"
+}
+
+valid_ref 'heads/foo'
+invalid_ref 'foo'
+valid_ref 'foo/bar/baz'
+valid_ref 'refs///heads/foo'
+invalid_ref 'heads/foo/'
+invalid_ref './foo'
+invalid_ref '.refs/foo'
+invalid_ref 'heads/foo..bar'
+invalid_ref 'heads/foo?bar'
+valid_ref 'foo./bar'
+invalid_ref 'heads/foo.lock'
+valid_ref 'heads/foo@bar'
+invalid_ref 'heads/v@{ation'
+invalid_ref 'heads/foo\bar'
+
+test_expect_success "check-ref-format --branch @{-1}" '
+ T=$(git write-tree) &&
+ sha1=$(echo A | git commit-tree $T) &&
+ git update-ref refs/heads/master $sha1 &&
+ git update-ref refs/remotes/origin/master $sha1
+ git checkout master &&
+ git checkout origin/master &&
+ git checkout master &&
+ refname=$(git check-ref-format --branch @{-1}) &&
+ test "$refname" = "$sha1" &&
+ refname2=$(git check-ref-format --branch @{-2}) &&
+ test "$refname2" = master'
+
+test_done
--
1.6.5.rc1.199.g596ec
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/4] Documentation: describe check-ref-format --branch
2009-10-12 5:25 ` [PATCH/RFC 0/4] plumbing to help fix git-gui Jonathan Nieder
2009-10-12 5:27 ` [PATCH 1/4] Add tests for git check-ref-format Jonathan Nieder
@ 2009-10-12 5:28 ` Jonathan Nieder
2009-10-12 5:31 ` [PATCH/RFC 3/4] git check-ref-format --print Jonathan Nieder
` (2 subsequent siblings)
4 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2009-10-12 5:28 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jens Lehmann, git, Shawn O. Pearce
Unless one already knew, it was not obvious what sort of shorthand
"git check-ref-format --branch" expands. Explain it.
The --branch argument is not optional.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Documentation/git-check-ref-format.txt | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt
index 0b7982e..e9b3b40 100644
--- a/Documentation/git-check-ref-format.txt
+++ b/Documentation/git-check-ref-format.txt
@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git check-ref-format' <refname>
-'git check-ref-format' [--branch] <branchname-shorthand>
+'git check-ref-format' --branch <branchname-shorthand>
DESCRIPTION
-----------
@@ -63,8 +63,11 @@ reference name expressions (see linkgit:git-rev-parse[1]):
. at-open-brace `@{` is used as a notation to access a reflog entry.
-With the `--branch` option, it expands a branch name shorthand and
-prints the name of the branch the shorthand refers to.
+With the `--branch` option, it expands the ``previous branch syntax''
+`@{-n}`. For example, `@{-1}` is a way to refer the last branch you
+were on. This option should be used by porcelains to accept this
+syntax anywhere a branch name is expected, so they can act as if you
+typed the branch name.
EXAMPLE
-------
--
1.6.5.rc1.199.g596ec
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH/RFC 3/4] git check-ref-format --print
2009-10-12 5:25 ` [PATCH/RFC 0/4] plumbing to help fix git-gui Jonathan Nieder
2009-10-12 5:27 ` [PATCH 1/4] Add tests for git check-ref-format Jonathan Nieder
2009-10-12 5:28 ` [PATCH 2/4] Documentation: describe check-ref-format --branch Jonathan Nieder
@ 2009-10-12 5:31 ` Jonathan Nieder
2009-10-12 14:39 ` Shawn O. Pearce
2009-10-12 23:36 ` Junio C Hamano
2009-10-12 5:33 ` [PATCH/RFC 4/4] check-ref-format: simplify --print implementation Jonathan Nieder
2009-10-12 5:45 ` [PATCH/RFC 0/4] plumbing to help fix git-gui Jonathan Nieder
4 siblings, 2 replies; 17+ messages in thread
From: Jonathan Nieder @ 2009-10-12 5:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jens Lehmann, git, Shawn O. Pearce
Tolerating empty path components in ref names means each ref does
not have a unique name. This creates difficulty for porcelains
that want to see if two branches are equal. Add a helper associating
to each ref a canonical name.
If a user asks a porcelain to create a ref "refs/heads//master",
the porcelain can run "git check-ref-format --print refs/heads//master"
and only deal with "refs/heads/master" from then on.
In the future, it would be very nice if this command could be
modified to transform Unicode ref names to some appropriate
normalization form, to make Unicode ref names usable in Mac OS X,
too, and less confusing everywhere.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Documentation/git-check-ref-format.txt | 25 +++++++++++++++++++------
builtin-check-ref-format.c | 10 ++++++++++
t/t1402-check-ref-format.sh | 17 +++++++++++++++++
3 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt
index e9b3b40..0aeef24 100644
--- a/Documentation/git-check-ref-format.txt
+++ b/Documentation/git-check-ref-format.txt
@@ -9,6 +9,7 @@ SYNOPSIS
--------
[verse]
'git check-ref-format' <refname>
+'git check-ref-format' --print <refname>
'git check-ref-format' --branch <branchname-shorthand>
DESCRIPTION
@@ -63,19 +64,31 @@ reference name expressions (see linkgit:git-rev-parse[1]):
. at-open-brace `@{` is used as a notation to access a reflog entry.
+With the `--print` option, if 'refname' is acceptable, it prints the
+canonicalized name of a hypothetical reference with that name. That is,
+it prints 'refname' with any extra `/` characters removed.
+
With the `--branch` option, it expands the ``previous branch syntax''
`@{-n}`. For example, `@{-1}` is a way to refer the last branch you
were on. This option should be used by porcelains to accept this
syntax anywhere a branch name is expected, so they can act as if you
typed the branch name.
-EXAMPLE
--------
-
-git check-ref-format --branch @{-1}::
-
-Print the name of the previous branch.
+EXAMPLES
+--------
+* Print the name of the previous branch:
++
+------------
+$ git check-ref-format --branch @{-1}
+------------
+
+* Determine the reference name to use for a new branch:
++
+------------
+$ ref=$(git check-ref-format --print "refs/heads/$newbranch") ||
+die "we do not like '$newbranch' as a branch name."
+------------
GIT
---
diff --git a/builtin-check-ref-format.c b/builtin-check-ref-format.c
index f9381e0..b97b61a 100644
--- a/builtin-check-ref-format.c
+++ b/builtin-check-ref-format.c
@@ -17,6 +17,16 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
printf("%s\n", sb.buf + 11);
exit(0);
}
+ if (argc == 3 && !strcmp(argv[1], "--print")) {
+ char *refname = xmalloc(strlen(argv[2]) + 1);
+
+ if (check_ref_format(argv[2]))
+ exit(1);
+ if (normalize_path_copy(refname, argv[2]))
+ die("Could not normalize ref name '%s'", argv[2]);
+ printf("%s\n", refname);
+ exit(0);
+ }
if (argc != 2)
usage("git check-ref-format refname");
return !!check_ref_format(argv[1]);
diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
index 382bc6e..eb45afb 100644
--- a/t/t1402-check-ref-format.sh
+++ b/t/t1402-check-ref-format.sh
@@ -41,4 +41,21 @@ test_expect_success "check-ref-format --branch @{-1}" '
refname2=$(git check-ref-format --branch @{-2}) &&
test "$refname2" = master'
+valid_ref_normalized() {
+ test_expect_success "ref name '$1' simplifies to '$2'" "
+ refname=\$(git check-ref-format --print '$1') &&
+ test \"\$refname\" = '$2'"
+}
+invalid_ref_normalized() {
+ test_expect_success "check-ref-format --print rejects '$1'" "
+ test_must_fail git check-ref-format --print '$1'"
+}
+
+valid_ref_normalized 'heads/foo' 'heads/foo'
+valid_ref_normalized 'refs///heads/foo' 'refs/heads/foo'
+invalid_ref_normalized 'foo'
+invalid_ref_normalized 'heads/foo/../bar'
+invalid_ref_normalized 'heads/./foo'
+invalid_ref_normalized 'heads\foo'
+
test_done
--
1.6.5.rc1.199.g596ec
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH/RFC 3/4] git check-ref-format --print
2009-10-12 5:31 ` [PATCH/RFC 3/4] git check-ref-format --print Jonathan Nieder
@ 2009-10-12 14:39 ` Shawn O. Pearce
2009-10-12 21:06 ` Junio C Hamano
2009-10-12 23:36 ` Junio C Hamano
1 sibling, 1 reply; 17+ messages in thread
From: Shawn O. Pearce @ 2009-10-12 14:39 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Jens Lehmann, git
Jonathan Nieder <jrnieder@gmail.com> wrote:
> +valid_ref_normalized 'heads/foo' 'heads/foo'
> +valid_ref_normalized 'refs///heads/foo' 'refs/heads/foo'
> +invalid_ref_normalized 'foo'
> +invalid_ref_normalized 'heads/foo/../bar'
> +invalid_ref_normalized 'heads/./foo'
> +invalid_ref_normalized 'heads\foo'
What about '/refs/heads/foo'? Shouldn't that drop the leading /?
I actually had someone enter that into Gerrit Code Review once,
exposing a bug I have yet to fix that permits that as a valid
branch name. *sigh*
FWIW, I think this is heading in the right direction. Rather
than teaching the UIs how clean up a name, give us a tool to
do the normalization and validation, and let us call it when
we get user input.
--
Shawn.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH/RFC 3/4] git check-ref-format --print
2009-10-12 14:39 ` Shawn O. Pearce
@ 2009-10-12 21:06 ` Junio C Hamano
2009-10-12 23:26 ` Shawn O. Pearce
0 siblings, 1 reply; 17+ messages in thread
From: Junio C Hamano @ 2009-10-12 21:06 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Jonathan Nieder, Junio C Hamano, Jens Lehmann, git
"Shawn O. Pearce" <spearce@spearce.org> writes:
> Jonathan Nieder <jrnieder@gmail.com> wrote:
>> +valid_ref_normalized 'heads/foo' 'heads/foo'
>> +valid_ref_normalized 'refs///heads/foo' 'refs/heads/foo'
>> +invalid_ref_normalized 'foo'
>> +invalid_ref_normalized 'heads/foo/../bar'
>> +invalid_ref_normalized 'heads/./foo'
>> +invalid_ref_normalized 'heads\foo'
>
> What about '/refs/heads/foo'? Shouldn't that drop the leading /?
>
> I actually had someone enter that into Gerrit Code Review once,
> exposing a bug I have yet to fix that permits that as a valid
> branch name. *sigh*
>
> FWIW, I think this is heading in the right direction. Rather
> than teaching the UIs how clean up a name, give us a tool to
> do the normalization and validation, and let us call it when
> we get user input.
I understand that you prefer the latter between "there is no tool; the
caller is responsibile to make sure it feeds us canonical representation"
and "there is a tool that makes a slightly malformed string into canonical
form for the callers to use before calling us." And that would be my
preference between these two as well.
But that is based on the current behaviour of accepting slightly malformed
and silently making it canonical. If we throw a third alternative,
Jonathan's original patch, that did "we reject malformed string", in the
mix, what would be your preference?
I moderately favour the "tool to canonicalize is given, and it would be a
bug for the caller not to use it" approach this series takes primarily
because that approach won't break scripts that do something like this to
make a new branch, optionally grouped by the owner (e.g. 'sp/smart-http'
or 'next'):
owner=$1 topic=$2
branch=$owner/$topic
git branch "$branch"
This currently works as expected as long as it does not later try to
compare for-each-ref output with "refs/heads/$branch" and expects a match.
With the third approach, the optional username grouping becomes mandatory
for such a script, as 'git branch' will error out. To keep the grouping
still optinal, such a script needs to be written perhaps like:
if test -z "$2"
then
branch="$1"
else
branch="$1/$2"
fi
and that would be a hassle for the scripters, but this _could_ be a kind
of backward incompatible tightening we might want to consider for 1.7.0,
as somebody suggested earlier.
But now I have spelled this out, I do not see much upside for rejecting,
and more importantly, I think it would be an independent issue. We can
reject or just keep normalizing silently, and a tool to show the
normalized name would be useful and necessary regardless of that.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH/RFC 3/4] git check-ref-format --print
2009-10-12 21:06 ` Junio C Hamano
@ 2009-10-12 23:26 ` Shawn O. Pearce
0 siblings, 0 replies; 17+ messages in thread
From: Shawn O. Pearce @ 2009-10-12 23:26 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jonathan Nieder, Jens Lehmann, git
Junio C Hamano <gitster@pobox.com> wrote:
> I understand that you prefer the latter between "there is no tool; the
> caller is responsibile to make sure it feeds us canonical representation"
> and "there is a tool that makes a slightly malformed string into canonical
> form for the callers to use before calling us." And that would be my
> preference between these two as well.
...
> But now I have spelled this out, I do not see much upside for rejecting,
> and more importantly, I think it would be an independent issue. We can
> reject or just keep normalizing silently, and a tool to show the
> normalized name would be useful and necessary regardless of that.
I agree with the last paragraph here, we shouldn't reject, but
instead keep the current state but encourage tools to use the new
canonical print tool to clean up a name if they want to hang onto the
string the user entered and it needs to exactly match for-each-ref
sort of output.
--
Shawn.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH/RFC 3/4] git check-ref-format --print
2009-10-12 5:31 ` [PATCH/RFC 3/4] git check-ref-format --print Jonathan Nieder
2009-10-12 14:39 ` Shawn O. Pearce
@ 2009-10-12 23:36 ` Junio C Hamano
2009-10-13 4:49 ` Jonathan Nieder
1 sibling, 1 reply; 17+ messages in thread
From: Junio C Hamano @ 2009-10-12 23:36 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Jens Lehmann, git, Shawn O. Pearce
Jonathan Nieder <jrnieder@gmail.com> writes:
> In the future, it would be very nice if this command could be
> modified to transform Unicode ref names to some appropriate
> normalization form, to make Unicode ref names usable in Mac OS X,
> too, and less confusing everywhere.
I do not disagree with a desire to help fixing the unicode insanity on
that platform, but I suspect that check-ref-format is a wrong place to
tackle the issue. You would need a similar filter for outputs from the
likes of ls-files and "diff --name-only", iow, anything that deal with
pathnames, no?
It would have be something like "check-ref-format --print | iconv ..."
pipeline (conceptually, if not forcing the pipeline to the end users, that
is).
Also are people happy with "--print"? I was waiting for others to reword
it to "--normalize" or something like that. In your documentation you
explain it to "canonicalize", and in your tests you name the output
"normalized". I am fine with either wording, but would like to see us
using only one, not both.
Thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH/RFC 3/4] git check-ref-format --print
2009-10-12 23:36 ` Junio C Hamano
@ 2009-10-13 4:49 ` Jonathan Nieder
0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2009-10-13 4:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jens Lehmann, git, Shawn O. Pearce
Junio C Hamano wrote:
> I do not disagree with a desire to help fixing the unicode insanity on
> that platform, but I suspect that check-ref-format is a wrong place to
> tackle the issue. You would need a similar filter for outputs from the
> likes of ls-files and "diff --name-only", iow, anything that deal with
> pathnames, no?
>
> It would have be something like "check-ref-format --print | iconv ..."
> pipeline (conceptually, if not forcing the pipeline to the end users, that
> is).
GNU iconv does not write the various Unicode normalization forms, so it
would have to be something like "check-ref-format --print | charlint ..."
instead. Regardless of the filesystem, it seems reasonable to consider é
(U+00e9) and é (U+0065 + U+0301) the same character when it appears in a
ref name, and one way to achieve this would be to pick one normalization
form and stick to it. This does not seem so different from stripping out
empty path components.
As a side effect, that would deal with OS X’s strange handling of unicode
filenames for .git/refs/*. Now that I think about it, if fighting OS X
were the only problem that needed to be solved, I don’t think I’d like
this solution so much. The analogous solution to the also unsolved issue
of case insensitive filesystems is to force all ref names to lowercase.
Do we want to do that? (The case insensitivity issue might not be as bad,
since the relevant filesystems will at least _preserve_ the case of
filenames in .git/refs. Should we copy them and smudge new ref names to
match known ones that differ only in case? Just thinking about the
problem makes me cringe.)
Coping with the unicode filename craziness in the working tree is a
separate issue, though probably a more important one. I think Linus set
up a framework for solving it in
<http://thread.gmane.org/gmane.comp.version-control.git/77827>.
Regards,
Jonathan
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH/RFC 4/4] check-ref-format: simplify --print implementation
2009-10-12 5:25 ` [PATCH/RFC 0/4] plumbing to help fix git-gui Jonathan Nieder
` (2 preceding siblings ...)
2009-10-12 5:31 ` [PATCH/RFC 3/4] git check-ref-format --print Jonathan Nieder
@ 2009-10-12 5:33 ` Jonathan Nieder
2009-10-12 5:45 ` [PATCH/RFC 0/4] plumbing to help fix git-gui Jonathan Nieder
4 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2009-10-12 5:33 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jens Lehmann, git, Shawn O. Pearce
normalize_path_copy() is a complicated function, but most of its
functionality will never apply to a ref name that has been checked
with check_ref_format().
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
builtin-check-ref-format.c | 25 +++++++++++++++++++++++--
1 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/builtin-check-ref-format.c b/builtin-check-ref-format.c
index b97b61a..e439136 100644
--- a/builtin-check-ref-format.c
+++ b/builtin-check-ref-format.c
@@ -7,6 +7,28 @@
#include "builtin.h"
#include "strbuf.h"
+/*
+ * Replace each run of adjacent slashes in src with a single slash,
+ * and write the result to dst.
+ *
+ * This function is similar to normalize_path_copy(), but stripped down
+ * to meet check_ref_format's simpler needs.
+ */
+static void collapse_slashes(char *dst, const char *src)
+{
+ char ch;
+ char prev = '\0';
+
+ while (ch = *src++) {
+ if (prev == '/' && ch == prev)
+ continue;
+
+ *dst++ = ch;
+ prev = ch;
+ }
+ *dst = '\0';
+}
+
int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
{
if (argc == 3 && !strcmp(argv[1], "--branch")) {
@@ -22,8 +44,7 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
if (check_ref_format(argv[2]))
exit(1);
- if (normalize_path_copy(refname, argv[2]))
- die("Could not normalize ref name '%s'", argv[2]);
+ collapse_slashes(refname, argv[2]);
printf("%s\n", refname);
exit(0);
}
--
1.6.5.rc1.199.g596ec
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH/RFC 0/4] plumbing to help fix git-gui
2009-10-12 5:25 ` [PATCH/RFC 0/4] plumbing to help fix git-gui Jonathan Nieder
` (3 preceding siblings ...)
2009-10-12 5:33 ` [PATCH/RFC 4/4] check-ref-format: simplify --print implementation Jonathan Nieder
@ 2009-10-12 5:45 ` Jonathan Nieder
4 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2009-10-12 5:45 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jens Lehmann, git, Shawn O. Pearce
Jonathan Nieder wrote:
> Junio C Hamano wrote:
>> Perhaps an interface to give a cleaned-up version, e.g.
>>
>> $ git check-ref-format --print refs/heads//foo/bar
>> refs/heads/foo/bar
>>
>> is what you want in order to fix git-gui? I dunno.
>
> The following packages do exactly that.
s/packages/patches/
I better sleep...
Sorry for the confusion,
Jonathan
^ permalink raw reply [flat|nested] 17+ messages in thread