From 38eedc634bc5d30e8a7a2356d9eb3ae95d9b1d75 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 12 Oct 2009 16:39:43 -0700 Subject: [PATCH] git check-ref-format --print 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. Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- 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 0b7982ea7..211ae1c3f 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' +'git check-ref-format' --print 'git check-ref-format' [--branch] DESCRIPTION @@ -63,16 +64,28 @@ 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 a branch name shorthand and prints the name of the branch the shorthand refers to. -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 f9381e07e..b97b61a0a 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 382bc6e82..eb45afb01 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 -- 2.26.2