Skip to content

Commit 546e0fd

Browse files
peffgitster
authored andcommitted
diff: handle relative paths in no-index
When diff-no-index is given a relative path to a file outside the repository, it aborts with error. However, if the file is given using an absolute path, the diff runs as expected. The two cases should be treated the same. Tests and commit message by Tim Henigan. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Tim Henigan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 785ee49 commit 546e0fd

File tree

4 files changed

+39
-22
lines changed

4 files changed

+39
-22
lines changed

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ extern const char *prefix_filename(const char *prefix, int len, const char *path
455455
extern int check_filename(const char *prefix, const char *name);
456456
extern void verify_filename(const char *prefix, const char *name);
457457
extern void verify_non_filename(const char *prefix, const char *name);
458+
extern int path_inside_repo(const char *prefix, const char *path);
458459

459460
#define INIT_DB_QUIET 0x0001
460461

diff-no-index.c

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -151,23 +151,6 @@ static int queue_diff(struct diff_options *o,
151151
}
152152
}
153153

154-
static int path_outside_repo(const char *path)
155-
{
156-
const char *work_tree;
157-
size_t len;
158-
159-
if (!is_absolute_path(path))
160-
return 0;
161-
work_tree = get_git_work_tree();
162-
if (!work_tree)
163-
return 1;
164-
len = strlen(work_tree);
165-
if (strncmp(path, work_tree, len) ||
166-
(path[len] != '\0' && path[len] != '/'))
167-
return 1;
168-
return 0;
169-
}
170-
171154
void diff_no_index(struct rev_info *revs,
172155
int argc, const char **argv,
173156
int nongit, const char *prefix)
@@ -197,8 +180,8 @@ void diff_no_index(struct rev_info *revs,
197180
* a colourful "diff" replacement.
198181
*/
199182
if ((argc != i + 2) ||
200-
(!path_outside_repo(argv[i]) &&
201-
!path_outside_repo(argv[i+1])))
183+
(path_inside_repo(prefix, argv[i]) &&
184+
path_inside_repo(prefix, argv[i+1])))
202185
return;
203186
}
204187
if (argc != i + 2)

setup.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
static int inside_git_dir = -1;
55
static int inside_work_tree = -1;
66

7-
char *prefix_path(const char *prefix, int len, const char *path)
7+
static char *prefix_path_gently(const char *prefix, int len, const char *path)
88
{
99
const char *orig = path;
1010
char *sanitized;
@@ -31,7 +31,8 @@ char *prefix_path(const char *prefix, int len, const char *path)
3131
if (strncmp(sanitized, work_tree, len) ||
3232
(len > root_len && sanitized[len] != '\0' && sanitized[len] != '/')) {
3333
error_out:
34-
die("'%s' is outside repository", orig);
34+
free(sanitized);
35+
return NULL;
3536
}
3637
if (sanitized[len] == '/')
3738
len++;
@@ -40,6 +41,25 @@ char *prefix_path(const char *prefix, int len, const char *path)
4041
return sanitized;
4142
}
4243

44+
char *prefix_path(const char *prefix, int len, const char *path)
45+
{
46+
char *r = prefix_path_gently(prefix, len, path);
47+
if (!r)
48+
die("'%s' is outside repository", path);
49+
return r;
50+
}
51+
52+
int path_inside_repo(const char *prefix, const char *path)
53+
{
54+
int len = prefix ? strlen(prefix) : 0;
55+
char *r = prefix_path_gently(prefix, len, path);
56+
if (r) {
57+
free(r);
58+
return 1;
59+
}
60+
return 0;
61+
}
62+
4363
int check_filename(const char *prefix, const char *arg)
4464
{
4565
const char *name;

t/t4053-diff-no-index.sh

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,25 @@ test_expect_success 'setup' '
88
mkdir a &&
99
mkdir b &&
1010
echo 1 >a/1 &&
11-
echo 2 >a/2
11+
echo 2 >a/2 &&
12+
git init repo &&
13+
echo 1 >repo/a &&
14+
mkdir -p non/git &&
15+
echo 1 >non/git/a &&
16+
echo 1 >non/git/b
1217
'
1318

1419
test_expect_success 'git diff --no-index directories' '
1520
git diff --no-index a b >cnt
1621
test $? = 1 && test_line_count = 14 cnt
1722
'
1823

24+
test_expect_success 'git diff --no-index relative path outside repo' '
25+
(
26+
cd repo &&
27+
test_expect_code 0 git diff --no-index a ../non/git/a &&
28+
test_expect_code 0 git diff --no-index ../non/git/a ../non/git/b
29+
)
30+
'
31+
1932
test_done

0 commit comments

Comments
 (0)