Skip to content

Commit 7c3f847

Browse files
committed
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 <[email protected]> Helped-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]> Signed-off-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 08f9c32 commit 7c3f847

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

sha1_name.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,10 @@ void strbuf_branchname(struct strbuf *sb, const char *name, unsigned allowed)
13211321

13221322
int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
13231323
{
1324-
strbuf_branchname(sb, name, INTERPRET_BRANCH_LOCAL);
1324+
if (startup_info->have_repository)
1325+
strbuf_branchname(sb, name, INTERPRET_BRANCH_LOCAL);
1326+
else
1327+
strbuf_addstr(sb, name);
13251328
if (name[0] == '-')
13261329
return -1;
13271330
strbuf_splice(sb, 0, 0, "refs/heads/", 11);

t/t1402-check-ref-format.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ test_expect_success "check-ref-format --branch @{-1}" '
144144
refname2=$(git check-ref-format --branch @{-2}) &&
145145
test "$refname2" = master'
146146

147+
test_expect_success 'check-ref-format --branch -naster' '
148+
test_must_fail git check-ref-format --branch -naster >actual &&
149+
test_must_be_empty actual
150+
'
151+
147152
test_expect_success 'check-ref-format --branch from subdir' '
148153
mkdir subdir &&
149154
@@ -161,6 +166,17 @@ test_expect_success 'check-ref-format --branch from subdir' '
161166
test "$refname" = "$sha1"
162167
'
163168

169+
test_expect_success 'check-ref-format --branch @{-1} from non-repo' '
170+
nongit test_must_fail git check-ref-format --branch @{-1} >actual &&
171+
test_must_be_empty actual
172+
'
173+
174+
test_expect_success 'check-ref-format --branch master from non-repo' '
175+
echo master >expect &&
176+
nongit git check-ref-format --branch master >actual &&
177+
test_cmp expect actual
178+
'
179+
164180
valid_ref_normalized() {
165181
prereq=
166182
case $1 in

0 commit comments

Comments
 (0)