2009-10-12 07:27:04 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='Test git check-ref-format'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
valid_ref() {
|
2011-10-13 10:06:20 +02:00
|
|
|
prereq=
|
|
|
|
case $1 in
|
2014-07-22 00:09:27 +02:00
|
|
|
[A-Z!]*)
|
2011-10-13 10:06:20 +02:00
|
|
|
prereq=$1
|
|
|
|
shift
|
|
|
|
esac
|
2013-01-08 21:23:01 +01:00
|
|
|
desc="ref name '$1' is valid${2:+ with options $2}"
|
|
|
|
test_expect_success $prereq "$desc" "
|
2011-10-13 10:06:20 +02:00
|
|
|
git check-ref-format $2 '$1'
|
|
|
|
"
|
2009-10-12 07:27:04 +02:00
|
|
|
}
|
|
|
|
invalid_ref() {
|
2011-10-13 10:06:20 +02:00
|
|
|
prereq=
|
|
|
|
case $1 in
|
2014-07-22 00:09:27 +02:00
|
|
|
[A-Z!]*)
|
2011-10-13 10:06:20 +02:00
|
|
|
prereq=$1
|
|
|
|
shift
|
|
|
|
esac
|
2013-01-08 21:23:01 +01:00
|
|
|
desc="ref name '$1' is invalid${2:+ with options $2}"
|
|
|
|
test_expect_success $prereq "$desc" "
|
2011-10-13 10:06:20 +02:00
|
|
|
test_must_fail git check-ref-format $2 '$1'
|
|
|
|
"
|
2009-10-12 07:27:04 +02:00
|
|
|
}
|
|
|
|
|
2011-09-15 23:10:22 +02:00
|
|
|
invalid_ref ''
|
2014-07-22 00:09:27 +02:00
|
|
|
invalid_ref !MINGW '/'
|
|
|
|
invalid_ref !MINGW '/' --allow-onelevel
|
|
|
|
invalid_ref !MINGW '/' --normalize
|
|
|
|
invalid_ref !MINGW '/' '--allow-onelevel --normalize'
|
2009-10-12 07:27:04 +02:00
|
|
|
valid_ref 'foo/bar/baz'
|
2011-09-15 23:10:30 +02:00
|
|
|
valid_ref 'foo/bar/baz' --normalize
|
|
|
|
invalid_ref 'refs///heads/foo'
|
|
|
|
valid_ref 'refs///heads/foo' --normalize
|
2009-10-12 07:27:04 +02:00
|
|
|
invalid_ref 'heads/foo/'
|
2014-07-22 00:09:27 +02:00
|
|
|
invalid_ref !MINGW '/heads/foo'
|
|
|
|
valid_ref !MINGW '/heads/foo' --normalize
|
2011-09-15 23:10:30 +02:00
|
|
|
invalid_ref '///heads/foo'
|
|
|
|
valid_ref '///heads/foo' --normalize
|
2009-10-12 07:27:04 +02:00
|
|
|
invalid_ref './foo'
|
2011-09-15 23:10:23 +02:00
|
|
|
invalid_ref './foo/bar'
|
|
|
|
invalid_ref 'foo/./bar'
|
|
|
|
invalid_ref 'foo/bar/.'
|
2009-10-12 07:27:04 +02:00
|
|
|
invalid_ref '.refs/foo'
|
2014-07-28 17:48:11 +02:00
|
|
|
invalid_ref 'refs/heads/foo.'
|
2009-10-12 07:27:04 +02:00
|
|
|
invalid_ref 'heads/foo..bar'
|
|
|
|
invalid_ref 'heads/foo?bar'
|
|
|
|
valid_ref 'foo./bar'
|
|
|
|
invalid_ref 'heads/foo.lock'
|
2011-09-15 23:10:22 +02:00
|
|
|
invalid_ref 'heads///foo.lock'
|
2011-09-15 23:10:27 +02:00
|
|
|
invalid_ref 'foo.lock/bar'
|
|
|
|
invalid_ref 'foo.lock///bar'
|
2009-10-12 07:27:04 +02:00
|
|
|
valid_ref 'heads/foo@bar'
|
|
|
|
invalid_ref 'heads/v@{ation'
|
|
|
|
invalid_ref 'heads/foo\bar'
|
2011-08-27 06:12:44 +02:00
|
|
|
invalid_ref "$(printf 'heads/foo\t')"
|
|
|
|
invalid_ref "$(printf 'heads/foo\177')"
|
|
|
|
valid_ref "$(printf 'heads/fu\303\237')"
|
2015-07-22 23:05:33 +02:00
|
|
|
valid_ref 'heads/*foo/bar' --refspec-pattern
|
|
|
|
valid_ref 'heads/foo*/bar' --refspec-pattern
|
|
|
|
valid_ref 'heads/f*o/bar' --refspec-pattern
|
|
|
|
invalid_ref 'heads/f*o*/bar' --refspec-pattern
|
|
|
|
invalid_ref 'heads/foo*/bar*' --refspec-pattern
|
2011-09-15 23:10:23 +02:00
|
|
|
|
|
|
|
ref='foo'
|
|
|
|
invalid_ref "$ref"
|
|
|
|
valid_ref "$ref" --allow-onelevel
|
|
|
|
invalid_ref "$ref" --refspec-pattern
|
|
|
|
valid_ref "$ref" '--refspec-pattern --allow-onelevel'
|
2011-09-15 23:10:30 +02:00
|
|
|
invalid_ref "$ref" --normalize
|
|
|
|
valid_ref "$ref" '--allow-onelevel --normalize'
|
2011-09-15 23:10:23 +02:00
|
|
|
|
|
|
|
ref='foo/bar'
|
|
|
|
valid_ref "$ref"
|
|
|
|
valid_ref "$ref" --allow-onelevel
|
|
|
|
valid_ref "$ref" --refspec-pattern
|
|
|
|
valid_ref "$ref" '--refspec-pattern --allow-onelevel'
|
2011-09-15 23:10:30 +02:00
|
|
|
valid_ref "$ref" --normalize
|
2011-09-15 23:10:23 +02:00
|
|
|
|
|
|
|
ref='foo/*'
|
|
|
|
invalid_ref "$ref"
|
|
|
|
invalid_ref "$ref" --allow-onelevel
|
|
|
|
valid_ref "$ref" --refspec-pattern
|
|
|
|
valid_ref "$ref" '--refspec-pattern --allow-onelevel'
|
|
|
|
|
|
|
|
ref='*/foo'
|
|
|
|
invalid_ref "$ref"
|
|
|
|
invalid_ref "$ref" --allow-onelevel
|
|
|
|
valid_ref "$ref" --refspec-pattern
|
|
|
|
valid_ref "$ref" '--refspec-pattern --allow-onelevel'
|
2011-09-15 23:10:30 +02:00
|
|
|
invalid_ref "$ref" --normalize
|
|
|
|
valid_ref "$ref" '--refspec-pattern --normalize'
|
2011-09-15 23:10:23 +02:00
|
|
|
|
|
|
|
ref='foo/*/bar'
|
|
|
|
invalid_ref "$ref"
|
|
|
|
invalid_ref "$ref" --allow-onelevel
|
|
|
|
valid_ref "$ref" --refspec-pattern
|
|
|
|
valid_ref "$ref" '--refspec-pattern --allow-onelevel'
|
|
|
|
|
|
|
|
ref='*'
|
|
|
|
invalid_ref "$ref"
|
2011-09-15 23:10:25 +02:00
|
|
|
invalid_ref "$ref" --allow-onelevel
|
2011-09-15 23:10:23 +02:00
|
|
|
invalid_ref "$ref" --refspec-pattern
|
|
|
|
valid_ref "$ref" '--refspec-pattern --allow-onelevel'
|
|
|
|
|
|
|
|
ref='foo/*/*'
|
|
|
|
invalid_ref "$ref" --refspec-pattern
|
|
|
|
invalid_ref "$ref" '--refspec-pattern --allow-onelevel'
|
|
|
|
|
|
|
|
ref='*/foo/*'
|
|
|
|
invalid_ref "$ref" --refspec-pattern
|
|
|
|
invalid_ref "$ref" '--refspec-pattern --allow-onelevel'
|
|
|
|
|
|
|
|
ref='*/*/foo'
|
|
|
|
invalid_ref "$ref" --refspec-pattern
|
|
|
|
invalid_ref "$ref" '--refspec-pattern --allow-onelevel'
|
|
|
|
|
|
|
|
ref='/foo'
|
2014-07-22 00:09:27 +02:00
|
|
|
invalid_ref !MINGW "$ref"
|
|
|
|
invalid_ref !MINGW "$ref" --allow-onelevel
|
|
|
|
invalid_ref !MINGW "$ref" --refspec-pattern
|
|
|
|
invalid_ref !MINGW "$ref" '--refspec-pattern --allow-onelevel'
|
|
|
|
invalid_ref !MINGW "$ref" --normalize
|
|
|
|
valid_ref !MINGW "$ref" '--allow-onelevel --normalize'
|
|
|
|
invalid_ref !MINGW "$ref" '--refspec-pattern --normalize'
|
|
|
|
valid_ref !MINGW "$ref" '--refspec-pattern --allow-onelevel --normalize'
|
2009-10-12 07:27:04 +02:00
|
|
|
|
|
|
|
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 &&
|
2010-10-31 02:46:54 +01:00
|
|
|
git update-ref refs/remotes/origin/master $sha1 &&
|
2009-10-12 07:27:04 +02:00
|
|
|
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'
|
|
|
|
|
check-ref-format --branch: do not expand @{...} outside repository
Running "git check-ref-format --branch @{-1}" from outside any
repository produces
$ git check-ref-format --branch @{-1}
BUG: environment.c:182: git environment hasn't been setup
This is because the expansion of @{-1} must come from the HEAD reflog,
which involves opening the repository. @{u} and @{push} (which are
more unusual because they typically would not expand to a local
branch) trigger the same assertion.
This has been broken since day one. Before v2.13.0-rc0~48^2
(setup_git_env: avoid blind fall-back to ".git", 2016-10-02), the
breakage was more subtle: Git would read reflogs from ".git" within
the current directory even if it was not a valid repository. Usually
that is harmless because Git is not being run from the root directory
of an invalid repository, but in edge cases such accesses can be
confusing or harmful. Since v2.13.0, the problem is easier to
diagnose because Git aborts with a BUG message.
Erroring out is the right behavior: when asked to interpret a branch
name like "@{-1}", there is no reasonable answer in this context.
But we should print a message saying so instead of an assertion failure.
We do not forbid "check-ref-format --branch" from outside a repository
altogether because it is ok for a script to pre-process branch
arguments without @{...} in such a context. For example, with
pre-2.13 Git, a script that does
branch='master'; # default value
parse_options
branch=$(git check-ref-format --branch "$branch")
to normalize an optional branch name provided by the user would work
both inside a repository (where the user could provide '@{-1}') and
outside (where '@{-1}' should not be accepted).
So disable the "expand @{...}" half of the feature when run outside a
repository, but keep the check of the syntax of a proposed branch
name. This way, when run from outside a repository, "git
check-ref-format --branch @{-1}" will gracefully fail:
$ git check-ref-format --branch @{-1}
fatal: '@{-1}' is not a valid branch name
and "git check-ref-format --branch master" will succeed as before:
$ git check-ref-format --branch master
master
restoring the usual pre-2.13 behavior.
[jn: split out from a larger patch; moved conditional to
strbuf_check_branch_ref instead of its caller; fleshed out commit
message; some style tweaks in tests]
Reported-by: Marko Kungla <marko.kungla@gmail.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-10-17 09:08:08 +02:00
|
|
|
test_expect_success 'check-ref-format --branch -naster' '
|
|
|
|
test_must_fail git check-ref-format --branch -naster >actual &&
|
|
|
|
test_must_be_empty actual
|
|
|
|
'
|
|
|
|
|
2010-08-06 05:39:22 +02:00
|
|
|
test_expect_success 'check-ref-format --branch from subdir' '
|
|
|
|
mkdir subdir &&
|
|
|
|
|
|
|
|
T=$(git write-tree) &&
|
|
|
|
sha1=$(echo A | git commit-tree $T) &&
|
|
|
|
git update-ref refs/heads/master $sha1 &&
|
2010-10-31 02:46:54 +01:00
|
|
|
git update-ref refs/remotes/origin/master $sha1 &&
|
2010-08-06 05:39:22 +02:00
|
|
|
git checkout master &&
|
|
|
|
git checkout origin/master &&
|
|
|
|
git checkout master &&
|
|
|
|
refname=$(
|
|
|
|
cd subdir &&
|
|
|
|
git check-ref-format --branch @{-1}
|
|
|
|
) &&
|
|
|
|
test "$refname" = "$sha1"
|
|
|
|
'
|
|
|
|
|
check-ref-format --branch: do not expand @{...} outside repository
Running "git check-ref-format --branch @{-1}" from outside any
repository produces
$ git check-ref-format --branch @{-1}
BUG: environment.c:182: git environment hasn't been setup
This is because the expansion of @{-1} must come from the HEAD reflog,
which involves opening the repository. @{u} and @{push} (which are
more unusual because they typically would not expand to a local
branch) trigger the same assertion.
This has been broken since day one. Before v2.13.0-rc0~48^2
(setup_git_env: avoid blind fall-back to ".git", 2016-10-02), the
breakage was more subtle: Git would read reflogs from ".git" within
the current directory even if it was not a valid repository. Usually
that is harmless because Git is not being run from the root directory
of an invalid repository, but in edge cases such accesses can be
confusing or harmful. Since v2.13.0, the problem is easier to
diagnose because Git aborts with a BUG message.
Erroring out is the right behavior: when asked to interpret a branch
name like "@{-1}", there is no reasonable answer in this context.
But we should print a message saying so instead of an assertion failure.
We do not forbid "check-ref-format --branch" from outside a repository
altogether because it is ok for a script to pre-process branch
arguments without @{...} in such a context. For example, with
pre-2.13 Git, a script that does
branch='master'; # default value
parse_options
branch=$(git check-ref-format --branch "$branch")
to normalize an optional branch name provided by the user would work
both inside a repository (where the user could provide '@{-1}') and
outside (where '@{-1}' should not be accepted).
So disable the "expand @{...}" half of the feature when run outside a
repository, but keep the check of the syntax of a proposed branch
name. This way, when run from outside a repository, "git
check-ref-format --branch @{-1}" will gracefully fail:
$ git check-ref-format --branch @{-1}
fatal: '@{-1}' is not a valid branch name
and "git check-ref-format --branch master" will succeed as before:
$ git check-ref-format --branch master
master
restoring the usual pre-2.13 behavior.
[jn: split out from a larger patch; moved conditional to
strbuf_check_branch_ref instead of its caller; fleshed out commit
message; some style tweaks in tests]
Reported-by: Marko Kungla <marko.kungla@gmail.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-10-17 09:08:08 +02:00
|
|
|
test_expect_success 'check-ref-format --branch @{-1} from non-repo' '
|
|
|
|
nongit test_must_fail git check-ref-format --branch @{-1} >actual &&
|
|
|
|
test_must_be_empty actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check-ref-format --branch master from non-repo' '
|
|
|
|
echo master >expect &&
|
|
|
|
nongit git check-ref-format --branch master >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2009-10-13 01:39:43 +02:00
|
|
|
valid_ref_normalized() {
|
2011-10-13 10:06:20 +02:00
|
|
|
prereq=
|
|
|
|
case $1 in
|
2014-07-22 00:09:27 +02:00
|
|
|
[A-Z!]*)
|
2011-10-13 10:06:20 +02:00
|
|
|
prereq=$1
|
|
|
|
shift
|
|
|
|
esac
|
|
|
|
test_expect_success $prereq "ref name '$1' simplifies to '$2'" "
|
2011-09-15 23:10:30 +02:00
|
|
|
refname=\$(git check-ref-format --normalize '$1') &&
|
2011-10-13 10:06:20 +02:00
|
|
|
test \"\$refname\" = '$2'
|
|
|
|
"
|
2009-10-13 01:39:43 +02:00
|
|
|
}
|
|
|
|
invalid_ref_normalized() {
|
2011-10-13 10:06:20 +02:00
|
|
|
prereq=
|
|
|
|
case $1 in
|
2014-07-22 00:09:27 +02:00
|
|
|
[A-Z!]*)
|
2011-10-13 10:06:20 +02:00
|
|
|
prereq=$1
|
|
|
|
shift
|
|
|
|
esac
|
|
|
|
test_expect_success $prereq "check-ref-format --normalize rejects '$1'" "
|
|
|
|
test_must_fail git check-ref-format --normalize '$1'
|
|
|
|
"
|
2009-10-13 01:39:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
valid_ref_normalized 'heads/foo' 'heads/foo'
|
|
|
|
valid_ref_normalized 'refs///heads/foo' 'refs/heads/foo'
|
2014-07-22 00:09:27 +02:00
|
|
|
valid_ref_normalized !MINGW '/heads/foo' 'heads/foo'
|
check-ref-format --print: Normalize refnames that start with slashes
When asked if "refs///heads/master" is valid, check-ref-format says "Yes,
it is well formed", and when asked to print canonical form, it shows
"refs/heads/master". This is so that it can be tucked after "$GIT_DIR/"
to form a valid pathname for a loose ref, and we normalize a pathname like
"$GIT_DIR/refs///heads/master" to de-dup the slashes in it.
Similarly, when asked if "/refs/heads/master" is valid, check-ref-format
says "Yes, it is Ok", but the leading slash is not removed when printing,
leading to "$GIT_DIR//refs/heads/master".
Fix it to make sure such leading slashes are removed. Add tests that such
refnames are accepted and normalized correctly.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-25 21:19:24 +02:00
|
|
|
valid_ref_normalized '///heads/foo' 'heads/foo'
|
2009-10-13 01:39:43 +02:00
|
|
|
invalid_ref_normalized 'foo'
|
2014-07-22 00:09:27 +02:00
|
|
|
invalid_ref_normalized !MINGW '/foo'
|
2009-10-13 01:39:43 +02:00
|
|
|
invalid_ref_normalized 'heads/foo/../bar'
|
|
|
|
invalid_ref_normalized 'heads/./foo'
|
|
|
|
invalid_ref_normalized 'heads\foo'
|
2011-09-15 23:10:22 +02:00
|
|
|
invalid_ref_normalized 'heads/foo.lock'
|
|
|
|
invalid_ref_normalized 'heads///foo.lock'
|
2011-09-15 23:10:27 +02:00
|
|
|
invalid_ref_normalized 'foo.lock/bar'
|
|
|
|
invalid_ref_normalized 'foo.lock///bar'
|
2009-10-13 01:39:43 +02:00
|
|
|
|
2009-10-12 07:27:04 +02:00
|
|
|
test_done
|