Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion builtin/pull.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand Down
26 changes: 26 additions & 0 deletions t/t5520-pull.sh
Original file line number Diff line number Diff line change
Expand Up @@ -888,4 +888,30 @@ 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 -c fetch.unpackLimit=1000 fetch origin \
"+refs/heads/*:refs/remotes/origin/*" &&
git commit-graph write --reachable &&
oid=$(git rev-parse refs/remotes/origin/sideA) &&
obj=.git/objects/$(test_oid_to_path "$oid") &&
test -f "$obj" &&
chmod u+w "$obj" &&
>"$obj" &&
test_must_fail git pull --no-rebase origin sideA sideB
)
'

test_done
Loading