Merge branch 'jk/diff-relative-cached-unmerged' into jch

'git diff --relative' running with '--cached' has been corrected to
avoid a segfault when encountering unmerged paths outside the
prefix.

* jk/diff-relative-cached-unmerged:
  diff-lib: add idx/tree sanity check to oneway_diff
  diff: ignore unmerged paths outside prefix with --relative --cached
This commit is contained in:
Junio C Hamano
2026-08-03 09:31:37 -07:00
2 changed files with 20 additions and 1 deletions

View File

@@ -467,7 +467,7 @@ static void do_oneway_diff(struct unpack_trees_options *o,
if (cached && idx && ce_stage(idx)) {
struct diff_filepair *pair;
pair = diff_unmerge(&revs->diffopt, idx->name);
if (tree)
if (pair && tree)
fill_filespec(pair->one, &tree->oid, 1,
tree->ce_mode);
return;
@@ -530,6 +530,16 @@ static int oneway_diff(const struct cache_entry * const *src,
if (tree == o->df_conflict_entry)
tree = NULL;
/*
* We should only see a NULL idx when the entry was present in the tree
* but deleted in the idx. In which case it should be impossible
* that a NULL tree was passed in (there would have been no entry at
* all) or that we got a df conflict above (you need a directory and a
* file to get such a conflict, which implies both sides are present).
*/
if (!idx && !tree)
BUG("oneway_diff with neither idx nor tree");
if (ce_path_match(revs->diffopt.repo->index,
idx ? idx : tree,
&revs->prune_data, NULL)) {

View File

@@ -245,4 +245,13 @@ test_expect_failure 'diff --relative with change in subdir' '
test_cmp expected out
'
test_expect_success 'diff --relative --cached with change in subdir' '
git switch br3 &&
test_when_finished "git merge --abort" &&
test_must_fail git merge sub1 &&
echo file0 >expected &&
git -C subdir diff --relative --name-only --cached >out &&
test_cmp expected out
'
test_done