Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git apply --3way: don't abort if some hunks fail

Tags:

git

Situation

I have a file called testing.txt committed in the repo, with the following contents:

First line

I'm attempting to apply this patch, which modifies two files, testing.txt and nonexistent.txt:

diff --git a/testing.txt b/testing.txt
index 5e867b1..e5c47f2 100644
--- a/testing.txt
+++ b/testing.txt
@@ -1 +1,2 @@
 Non-matching first line
+Second line from patch
diff --git a/nonexistent.txt b/nonexistent.txt
index 9649cde..8aab0eb 100644
--- a/nonexistent.txt
+++ b/nonexistent.txt
@@ -1 +1,2 @@
 First line
+Second line from patch

using this command:

git apply --verbose --3way patch.txt

During the execution of the command, the testing.txt hunk is successfully applied with a fallback three-way merge:

Checking patch testing.txt...
error: while searching for:
Non-matching first line

error: patch failed: testing.txt:1
Falling back to three-way merge...
Applied patch to 'testing.txt' with conflicts.

and (as expected) the nonexistent.txt hunk fails (because that file doesn't exist):

Checking patch nonexistent.txt...
error: nonexistent.txt: does not exist in index

Problem

The entire apply command is aborted because the nonexistent.txt hunk fails.

The three-way merge for the testing.txt hunk is discarded, even though it was successful.

This is stated in the docs:

For atomicity, git apply by default fails the whole patch and does not touch the working tree when some of the hunks do not apply.

Question

I want the successful testing.txt hunk to be applied to the file, not discarded. How can I do this?

In other words, how can I change the nonexistent.txt fatal error to a non-fatal warning, so that the apply command doesn't abort?

(With this simple example, I could just remove the nonexistent.txt hunk from the patch file, but this isn't practical for a large patch where hundreds of hunks might need to be removed.)

What I've tried

I've looked through the docs, but I can't find an option to do this.

The --reject option "makes it apply the parts of the patch that are applicable, and leave the rejected hunks in corresponding *.rej files", but it's incompatible with the --3way option.

I've also tried -C0 and --unidiff-zero (ignore all context).

like image 396
TachyonVortex Avatar asked Sep 28 '22 06:09

TachyonVortex


1 Answers

This worked for me:

git apply --verbose --3way --exclude=nonexistent.txt patch.txt
like image 141
orgads Avatar answered Oct 31 '22 14:10

orgads