Merge branch 'jn/show-normalized-refs'

* jn/show-normalized-refs:
  check-ref-format: simplify --print implementation
  git check-ref-format --print
  Add tests for git check-ref-format

Conflicts:
	Documentation/git-check-ref-format.txt
This commit is contained in:
Junio C Hamano
2009-10-30 20:07:33 -07:00
3 changed files with 110 additions and 5 deletions

View File

@ -9,6 +9,7 @@ SYNOPSIS
-------- --------
[verse] [verse]
'git check-ref-format' <refname> 'git check-ref-format' <refname>
'git check-ref-format' --print <refname>
'git check-ref-format' --branch <branchname-shorthand> 'git check-ref-format' --branch <branchname-shorthand>
DESCRIPTION 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. . 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'' With the `--branch` option, it expands the ``previous branch syntax''
`@{-n}`. For example, `@{-1}` is a way to refer the last branch you `@{-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 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 syntax anywhere a branch name is expected, so they can act as if you
typed the branch name. typed the branch name.
EXAMPLE EXAMPLES
------- --------
git check-ref-format --branch @{-1}:: * Print the name of the previous branch:
+
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 GIT
--- ---

View File

@ -7,6 +7,28 @@
#include "builtin.h" #include "builtin.h"
#include "strbuf.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++) != '\0') {
if (prev == '/' && ch == prev)
continue;
*dst++ = ch;
prev = ch;
}
*dst = '\0';
}
int cmd_check_ref_format(int argc, const char **argv, const char *prefix) int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
{ {
if (argc == 3 && !strcmp(argv[1], "--branch")) { if (argc == 3 && !strcmp(argv[1], "--branch")) {
@ -17,6 +39,15 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
printf("%s\n", sb.buf + 11); printf("%s\n", sb.buf + 11);
exit(0); exit(0);
} }
if (argc == 3 && !strcmp(argv[1], "--print")) {
char *refname = xmalloc(strlen(argv[2]) + 1);
if (check_ref_format(argv[2]))
exit(1);
collapse_slashes(refname, argv[2]);
printf("%s\n", refname);
exit(0);
}
if (argc != 2) if (argc != 2)
usage("git check-ref-format refname"); usage("git check-ref-format refname");
return !!check_ref_format(argv[1]); return !!check_ref_format(argv[1]);

View File

@ -0,0 +1,61 @@
#!/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'
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