Skip to content

Commit 34d6070

Browse files
jerry-skydiogitster
authored andcommitted
git-apply: skip threeway in add / rename cases
Certain invocations of "git apply --3way" will attempt threeway and fail due to missing objects, even though git is able to fall back on apply_fragments and apply the patch successfully with a return value of 0. To fix, return early from try_threeway() in the following cases: - When the patch is a rename and no lines have changed. In this case, "git diff" doesn't record the blob info, so 3way is neither possible nor necessary. - When the patch is an addition and there is no add/add conflict, i.e. direct_to_threeway is false. In this case, threeway will fail since the preimage is not in cache, but isn't necessary anyway since there is no conflict. This fixes a few unecessary error messages when applying these kinds of patches with --3way. It also fixes a reported issue where applying a concatenation of several git produced patches will fail when those patches involve a deletion followed by creation of the same file. Add a test for this case too. (test provided by <[email protected]>) Signed-off-by: Jerry Zhang <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e9d7761 commit 34d6070

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

apply.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3582,7 +3582,9 @@ static int try_threeway(struct apply_state *state,
35823582

35833583
/* No point falling back to 3-way merge in these cases */
35843584
if (patch->is_delete ||
3585-
S_ISGITLINK(patch->old_mode) || S_ISGITLINK(patch->new_mode))
3585+
S_ISGITLINK(patch->old_mode) || S_ISGITLINK(patch->new_mode) ||
3586+
(patch->is_new && !patch->direct_to_threeway) ||
3587+
(patch->is_rename && !patch->lines_added && !patch->lines_deleted))
35863588
return -1;
35873589

35883590
/* Preimage the patch was prepared for */

t/t4108-apply-threeway.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,4 +275,22 @@ test_expect_success 'apply full-index patch with 3way' '
275275
git apply --3way --index bin.diff
276276
'
277277

278+
test_expect_success 'apply delete then new patch with 3way' '
279+
git reset --hard main &&
280+
test_write_lines 2 > delnew &&
281+
git add delnew &&
282+
git diff --cached >> new.patch &&
283+
git reset --hard &&
284+
test_write_lines 1 > delnew &&
285+
git add delnew &&
286+
git commit -m "delnew" &&
287+
rm delnew &&
288+
git diff >> delete-then-new.patch &&
289+
cat new.patch >> delete-then-new.patch &&
290+
291+
git checkout -- . &&
292+
# Apply must succeed.
293+
git apply --3way delete-then-new.patch
294+
'
295+
278296
test_done

0 commit comments

Comments
 (0)