Skip to content

Commit

Permalink
diff: handle relative paths in no-index
Browse files Browse the repository at this point in the history
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 <peff@peff.net>
Signed-off-by: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Jun 22, 2012
1 parent 785ee49 commit 546e0fd
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 22 deletions.
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ extern const char *prefix_filename(const char *prefix, int len, const char *path
extern int check_filename(const char *prefix, const char *name);
extern void verify_filename(const char *prefix, const char *name);
extern void verify_non_filename(const char *prefix, const char *name);
extern int path_inside_repo(const char *prefix, const char *path);

#define INIT_DB_QUIET 0x0001

Expand Down
21 changes: 2 additions & 19 deletions diff-no-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,23 +151,6 @@ static int queue_diff(struct diff_options *o,
}
}

static int path_outside_repo(const char *path)
{
const char *work_tree;
size_t len;

if (!is_absolute_path(path))
return 0;
work_tree = get_git_work_tree();
if (!work_tree)
return 1;
len = strlen(work_tree);
if (strncmp(path, work_tree, len) ||
(path[len] != '\0' && path[len] != '/'))
return 1;
return 0;
}

void diff_no_index(struct rev_info *revs,
int argc, const char **argv,
int nongit, const char *prefix)
Expand Down Expand Up @@ -197,8 +180,8 @@ void diff_no_index(struct rev_info *revs,
* a colourful "diff" replacement.
*/
if ((argc != i + 2) ||
(!path_outside_repo(argv[i]) &&
!path_outside_repo(argv[i+1])))
(path_inside_repo(prefix, argv[i]) &&
path_inside_repo(prefix, argv[i+1])))
return;
}
if (argc != i + 2)
Expand Down
24 changes: 22 additions & 2 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
static int inside_git_dir = -1;
static int inside_work_tree = -1;

char *prefix_path(const char *prefix, int len, const char *path)
static char *prefix_path_gently(const char *prefix, int len, const char *path)
{
const char *orig = path;
char *sanitized;
Expand All @@ -31,7 +31,8 @@ char *prefix_path(const char *prefix, int len, const char *path)
if (strncmp(sanitized, work_tree, len) ||
(len > root_len && sanitized[len] != '\0' && sanitized[len] != '/')) {
error_out:
die("'%s' is outside repository", orig);
free(sanitized);
return NULL;
}
if (sanitized[len] == '/')
len++;
Expand All @@ -40,6 +41,25 @@ char *prefix_path(const char *prefix, int len, const char *path)
return sanitized;
}

char *prefix_path(const char *prefix, int len, const char *path)
{
char *r = prefix_path_gently(prefix, len, path);
if (!r)
die("'%s' is outside repository", path);
return r;
}

int path_inside_repo(const char *prefix, const char *path)
{
int len = prefix ? strlen(prefix) : 0;
char *r = prefix_path_gently(prefix, len, path);
if (r) {
free(r);
return 1;
}
return 0;
}

int check_filename(const char *prefix, const char *arg)
{
const char *name;
Expand Down
15 changes: 14 additions & 1 deletion t/t4053-diff-no-index.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,25 @@ test_expect_success 'setup' '
mkdir a &&
mkdir b &&
echo 1 >a/1 &&
echo 2 >a/2
echo 2 >a/2 &&
git init repo &&
echo 1 >repo/a &&
mkdir -p non/git &&
echo 1 >non/git/a &&
echo 1 >non/git/b
'

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

test_expect_success 'git diff --no-index relative path outside repo' '
(
cd repo &&
test_expect_code 0 git diff --no-index a ../non/git/a &&
test_expect_code 0 git diff --no-index ../non/git/a ../non/git/b
)
'

test_done

0 comments on commit 546e0fd

Please sign in to comment.