summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.test
diff options
context:
space:
mode:
authorPatrick Hiesel <hiesel@google.com>2023-03-10 16:50:37 +0100
committerPatrick Hiesel <hiesel@google.com>2024-05-14 18:52:47 +0200
commit6e9a170364efc727f4368cf5304115c7b278a649 (patch)
tree15d27c0e3b1fbd2a882a10b3a5fcbd803e0a503d /org.eclipse.jgit.test
parent5c0c18f5665fe8d3c3fae0176e231deb6c2480a7 (diff)
downloadjgit-6e9a170364efc727f4368cf5304115c7b278a649.tar.gz
jgit-6e9a170364efc727f4368cf5304115c7b278a649.zip
Allow applying a patch with conflicts
In some settings, we want to let users apply a patch that does not cleanly apply and add conflict markers. In Gerrit, this is useful when cherry picking (via Git patches) from one host to another. This commit takes a simple approach: If a hunk doesn't apply, go to the pre-image line, treat all lines in pre-image length as left side of the conflict and all context and newly added lines as right side of the conflict. Change-Id: I01411d7a32b3f3207097b26231909aae6b835650
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r--org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds.patch10
-rw-r--r--org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds_PostImage15
-rw-r--r--org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds_PreImage8
-rw-r--r--org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict.patch10
-rw-r--r--org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict_PostImage15
-rw-r--r--org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict_PreImage8
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchApplierTest.java55
7 files changed, 119 insertions, 2 deletions
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds.patch
new file mode 100644
index 0000000000..6e7448b95c
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds.patch
@@ -0,0 +1,10 @@
+diff --git a/ConflictOutOfBounds b/ConflictOutOfBounds
+index 0000000..de98044
+--- a/ConflictOutOfBounds
++++ b/ConflictOutOfBounds
+@@ -25,4 +25,4 @@
+ line3
+-lineA
++lineB
+ line5
+ line6
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds_PostImage
new file mode 100644
index 0000000000..4e5d5b2d88
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds_PostImage
@@ -0,0 +1,15 @@
+line1
+line2
+line3
+line4
+line5
+line6
+line7
+line8
+<<<<<<< HEAD
+=======
+line3
+lineB
+line5
+line6
+>>>>>>> PATCH
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds_PreImage
new file mode 100644
index 0000000000..f62562a216
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ConflictOutOfBounds_PreImage
@@ -0,0 +1,8 @@
+line1
+line2
+line3
+line4
+line5
+line6
+line7
+line8
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict.patch
new file mode 100644
index 0000000000..a99e636382
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict.patch
@@ -0,0 +1,10 @@
+diff --git a/allowconflict b/allowconflict
+index 0000000..de98044
+--- a/allowconflict
++++ b/allowconflict
+@@ -3,4 +3,4 @@
+ line3
+-lineA
++lineB
+ line5
+ line6
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict_PostImage
new file mode 100644
index 0000000000..a963b40dfe
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict_PostImage
@@ -0,0 +1,15 @@
+line1
+line2
+<<<<<<< HEAD
+line3
+line4
+line5
+line6
+=======
+line3
+lineB
+line5
+line6
+>>>>>>> PATCH
+line7
+line8
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict_PreImage
new file mode 100644
index 0000000000..f62562a216
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/allowconflict_PreImage
@@ -0,0 +1,8 @@
+line1
+line2
+line3
+line4
+line5
+line6
+line7
+line8
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchApplierTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchApplierTest.java
index 2aac15bbb6..e4b0ffbc21 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchApplierTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchApplierTest.java
@@ -27,6 +27,7 @@ import java.nio.file.Files;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.PatchFormatException;
import org.eclipse.jgit.attributes.FilterCommand;
import org.eclipse.jgit.attributes.FilterCommandFactory;
import org.eclipse.jgit.attributes.FilterCommandRegistry;
@@ -48,8 +49,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
-@Suite.SuiteClasses({
- PatchApplierTest.WithWorktree. class, //
+@Suite.SuiteClasses({ PatchApplierTest.WithWorktree.class, //
PatchApplierTest.InCore.class, //
})
public class PatchApplierTest {
@@ -128,6 +128,20 @@ public class PatchApplierTest {
}
}
+ protected Result applyPatchAllowConflicts() throws IOException {
+ InputStream patchStream = getTestResource(name + ".patch");
+ Patch patch = new Patch();
+ patch.parse(patchStream);
+ if (inCore) {
+ try (ObjectInserter oi = db.newObjectInserter()) {
+ return new PatchApplier(db, baseTip, oi).allowConflicts()
+ .applyPatch(patch);
+ }
+ }
+ return new PatchApplier(db).allowConflicts()
+ .applyPatch(patch);
+ }
+
protected static InputStream getTestResource(String patchFile) {
return PatchApplierTest.class.getClassLoader()
.getResourceAsStream("org/eclipse/jgit/diff/" + patchFile);
@@ -169,6 +183,13 @@ public class PatchApplierTest {
verifyContent(result, aName, exists);
}
+ void verifyChange(Result result, String aName, boolean exists,
+ int numConflicts) throws Exception {
+ assertEquals(numConflicts, result.getErrors().size());
+ assertEquals(1, result.getPaths().size());
+ verifyContent(result, aName, exists);
+ }
+
protected byte[] readBlob(ObjectId treeish, String path)
throws Exception {
try (TestRepository<?> tr = new TestRepository<>(db);
@@ -346,6 +367,36 @@ public class PatchApplierTest {
}
@Test
+ public void testConflictMarkers() throws Exception {
+ init("allowconflict", true, true);
+
+ Result result = applyPatchAllowConflicts();
+
+ assertEquals(result.getErrors().size(), 1);
+ PatchApplier.Result.Error error = result.getErrors().get(0);
+ error.hh = null; // We don't assert the hunk header as it is a
+ // complex object with lots of internal state.
+ assertEquals(error, new PatchApplier.Result.Error(
+ "cannot apply hunk", "allowconflict", null));
+ verifyChange(result, "allowconflict", true, 1);
+ }
+
+ @Test
+ public void testConflictMarkersOutOfBounds() throws Exception {
+ init("ConflictOutOfBounds", true, true);
+
+ Result result = applyPatchAllowConflicts();
+
+ assertEquals(result.getErrors().size(), 1);
+ PatchApplier.Result.Error error = result.getErrors().get(0);
+ error.hh = null; // We don't assert the hunk header as it is a
+ // complex object with lots of internal state.
+ assertEquals(error, new PatchApplier.Result.Error(
+ "cannot apply hunk", "ConflictOutOfBounds", null));
+ verifyChange(result, "ConflictOutOfBounds", true, 1);
+ }
+
+ @Test
public void testShiftUp() throws Exception {
init("ShiftUp");