Merge branch 'jk/pull-null-merge-head' into jch

'git pull' has been taught to fail more gracefully instead of
segfaulting when lookup_commit_reference() fails on unparseable
objects.

* jk/pull-null-merge-head:
  pull: avoid segfault when commit lookup fails
Junio C Hamano 2026-09-22 10:36:36 -07:00
commit b695eb8e6a
2 changed files with 36 additions and 1 deletions

View File

@ -800,8 +800,12 @@ static int get_can_ff(struct object_id *orig_head,

orig_merge_head = &merge_heads->oid[0];
head = lookup_commit_reference(the_repository, orig_head);
commit_list_insert(head, &list);
if (!head)
return 0;
merge_head = lookup_commit_reference(the_repository, orig_merge_head);
if (!merge_head)
return 0;
commit_list_insert(head, &list);
ret = repo_is_descendant_of(the_repository, merge_head, list);
commit_list_free(list);
if (ret < 0)
@ -820,12 +824,16 @@ static int already_up_to_date(struct object_id *orig_head,
struct commit *ours;

ours = lookup_commit_reference(the_repository, orig_head);
if (!ours)
return 0;
for (size_t i = 0; i < merge_heads->nr; i++) {
struct commit_list *list = NULL;
struct commit *theirs;
int ok;

theirs = lookup_commit_reference(the_repository, &merge_heads->oid[i]);
if (!theirs)
return 0;
commit_list_insert(theirs, &list);
ok = repo_is_descendant_of(the_repository, ours, list);
commit_list_free(list);

View File

@ -888,4 +888,31 @@ test_expect_success 'git pull --rebase against local branch' '
test_cmp expect file2
'

test_expect_success 'pull does not crash when a merge head does not resolve' '
test_when_finished "rm -rf up dn" &&
git init up &&
(
cd up &&
test_commit base &&
git switch -c sideA &&
test_commit a &&
git switch -c sideB base &&
test_commit b
) &&
git clone up dn &&
(
cd dn &&
git commit-graph write --reachable &&
oid=$(git rev-parse refs/remotes/origin/sideA) &&
obj=.git/objects/$(test_oid_to_path "$oid") &&

# Corrupt the object instead of removing it: a missing
# object that is still in the commit-graph is caught by
# fetch before pull ever reaches the fast-forward check.
rm -f "$obj" &&
echo garbage >"$obj" &&
test_must_fail git pull --no-rebase origin sideA sideB
)
'

test_done