diff-lib: ignore paths that are outside $cwd if --relative asked
For diff family commands, we can tell them to exclude changes outside of some directories if --relative is requested. In diff_unmerge(), NULL will be returned if the requested path is outside of the interesting directories, thus we'll run into NULL pointer dereference in run_diff_files when trying to dereference its return value. Checking for return value of diff_unmerge before dereferencing is not sufficient, though. Since, diff engine will try to work on such pathspec later. Let's not run diff on those unintesting entries, instead. As a side effect, by skipping like that, we can save some CPU cycles. Reported-by: Thomas De Zeeuw <thomas@slight.dev> Tested-by: Carlo Arenas <carenas@gmail.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
94f6e3e283
commit
8174627b3d
@ -116,6 +116,10 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
|
||||
if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
|
||||
continue;
|
||||
|
||||
if (revs->diffopt.prefix &&
|
||||
strncmp(ce->name, revs->diffopt.prefix, revs->diffopt.prefix_length))
|
||||
continue;
|
||||
|
||||
if (ce_stage(ce)) {
|
||||
struct combine_diff_path *dpath;
|
||||
struct diff_filepair *pair;
|
||||
|
@ -162,4 +162,57 @@ check_diff_relative_option subdir file2 true --no-relative --relative
|
||||
check_diff_relative_option . file2 false --no-relative --relative=subdir
|
||||
check_diff_relative_option . file2 true --no-relative --relative=subdir
|
||||
|
||||
test_expect_success 'setup diff --relative unmerged' '
|
||||
test_commit zero file0 &&
|
||||
test_commit base subdir/file0 &&
|
||||
git switch -c br1 &&
|
||||
test_commit one file0 &&
|
||||
test_commit sub1 subdir/file0 &&
|
||||
git switch -c br2 base &&
|
||||
test_commit two file0 &&
|
||||
git switch -c br3 &&
|
||||
test_commit sub3 subdir/file0
|
||||
'
|
||||
|
||||
test_expect_success 'diff --relative without change in subdir' '
|
||||
git switch br2 &&
|
||||
test_when_finished "git merge --abort" &&
|
||||
test_must_fail git merge one &&
|
||||
git -C subdir diff --relative >out &&
|
||||
test_must_be_empty out &&
|
||||
git -C subdir diff --relative --name-only >out &&
|
||||
test_must_be_empty out
|
||||
'
|
||||
|
||||
test_expect_success 'diff --relative --name-only with change in subdir' '
|
||||
git switch br3 &&
|
||||
test_when_finished "git merge --abort" &&
|
||||
test_must_fail git merge sub1 &&
|
||||
test_write_lines file0 file0 >expected &&
|
||||
git -C subdir diff --relative --name-only >out &&
|
||||
test_cmp expected out
|
||||
'
|
||||
|
||||
test_expect_failure 'diff --relative with change in subdir' '
|
||||
git switch br3 &&
|
||||
br1_blob=$(git rev-parse --short --verify br1:subdir/file0) &&
|
||||
br3_blob=$(git rev-parse --short --verify br3:subdir/file0) &&
|
||||
test_when_finished "git merge --abort" &&
|
||||
test_must_fail git merge br1 &&
|
||||
cat >expected <<-EOF &&
|
||||
diff --cc file0
|
||||
index $br3_blob,$br1_blob..0000000
|
||||
--- a/file0
|
||||
+++ b/file0
|
||||
@@@ -1,1 -1,1 +1,5 @@@
|
||||
++<<<<<<< HEAD
|
||||
+sub3
|
||||
++=======
|
||||
+ sub1
|
||||
++>>>>>>> br1
|
||||
EOF
|
||||
git -C subdir diff --relative >out &&
|
||||
test_cmp expected out
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user