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

'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
This commit is contained in:
Junio C Hamano committed 2026-10-03 21:45:55 -07:00
commit f85fa0c567
2 files changed
+36 -1

No files matched your search

+9 -1
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);
+27
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