prefix_path: show gitdir if worktree unavailable
If there is no worktree at present, we can still hint the user about Git's current directory by showing them the absolute path to the Git directory. Even though the Git directory doesn't make it as easy to locate the worktree in question, it can still help a user figure out what's going on while developing a script. This fixes a segmentation fault introduced in e0020b2f ("prefix_path: show gitdir when arg is outside repo", 2020-02-14). Signed-off-by: Emily Shaffer <emilyshaffer@google.com> [jc: added minimum tests, with help from Szeder Gábor] Signed-off-by: Junio C Hamano <gitster@pobox.com>
Emily Shaffer committed
Mar 2, 2020 at 20:05 UTC
5c20398699165a91af2d81ea2d20385bc8dd3627
3 files changed
+50
-4
pathspec.c
+6
-2
@@ -438,9 +438,13 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
438
} else {
439
match = prefix_path_gently(prefix, prefixlen,
440
&prefixlen, copyfrom);
441
- if (!match)
441
+ if (!match) {
442
+ const char *hint_path = get_git_work_tree();
443
+ if (!hint_path)
444
+ hint_path = get_git_dir();
445
die(_("%s: '%s' is outside repository at '%s'"), elt,
443
- copyfrom, absolute_path(get_git_work_tree()));
446
+ copyfrom, absolute_path(hint_path));
447
+ }
448
}
449
450
item->match = match;
setup.c
+6
-2
@@ -120,9 +120,13 @@ char *prefix_path_gently(const char *prefix, int len,
120
char *prefix_path(const char *prefix, int len, const char *path)
121
{
122
char *r = prefix_path_gently(prefix, len, NULL, path);
123
- if (!r)
123
+ if (!r) {
124
+ const char *hint_path = get_git_work_tree();
125
+ if (!hint_path)
126
+ hint_path = get_git_dir();
127
die(_("'%s' is outside repository at '%s'"), path,
125
- absolute_path(get_git_work_tree()));
128
+ absolute_path(hint_path));
129
+ }
130
return r;
131
}
132
t/t6136-pathspec-in-bare.sh
new
+38
@@ -0,0 +1,38 @@
1
+#!/bin/sh
2
+
3
+test_description='diagnosing out-of-scope pathspec'
4
+
5
+. ./test-lib.sh
6
+
7
+test_expect_success 'setup a bare and non-bare repository' '
8
+ test_commit file1 &&
9
+ git clone --bare . bare
10
+'
11
+
12
+test_expect_success 'log and ls-files in a bare repository' '
13
+ (
14
+ cd bare &&
15
+ test_must_fail git log -- .. >out 2>err &&
16
+ test_must_be_empty out &&
17
+ test_i18ngrep "outside repository" err &&
18
+
19
+ test_must_fail git ls-files -- .. >out 2>err &&
20
+ test_must_be_empty out &&
21
+ test_i18ngrep "outside repository" err
22
+ )
23
+'
24
+
25
+test_expect_success 'log and ls-files in .git directory' '
26
+ (
27
+ cd .git &&
28
+ test_must_fail git log -- .. >out 2>err &&
29
+ test_must_be_empty out &&
30
+ test_i18ngrep "outside repository" err &&
31
+
32
+ test_must_fail git ls-files -- .. >out 2>err &&
33
+ test_must_be_empty out &&
34
+ test_i18ngrep "outside repository" err
35
+ )
36
+'
37
+
38
+test_done