[EGIT PATCH 2/2] Resort entries in "normal" order before looking for conflicts
From: Robin Rosenberg <hidden>
Date: 2016-06-15 22:44:10
Subsystem:
the rest · Maintainer:
Linus Torvalds
When checking out another branch we get a problem if our version contains
a tree name that is longer, but has another tree as a prefix.
Our tree
a/a
a.a/b
Other tree
a/a
The conflict comes from names not being compared properly in git
order.
Directory/File conflicts are not easy to handle. This solution
is cheating, but solved a real user's problem.
This commit adds test cases for the particular problem plus one
similar test that didn't fail before either.
Signed-off-by: Robin Rosenberg <redacted>
---
.../tst/org/spearce/jgit/lib/ReadTreeTest.java | 16 ++++++++-
.../src/org/spearce/jgit/lib/IndexTreeWalker.java | 35 ++++++++++++--------
2 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/ReadTreeTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/ReadTreeTest.java
index 7ac48c9..6faedc7 100644
--- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/ReadTreeTest.java
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/ReadTreeTest.java@@ -477,7 +477,21 @@ public class ReadTreeTest extends RepositoryTestCase { assertNoConflicts(); } - + + public void testCloseNameConflictsX0() throws IOException { + setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "b.b/b.b","b.b/b.bs"), mkmap("a/a", "a/a-c") ); + checkout(); + go(); + assertNoConflicts(); + } + + public void testCloseNameConflicts1() throws IOException { + setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "a.a/a.a","a.a/a.a"), mkmap("a/a", "a/a-c") ); + checkout(); + go(); + assertNoConflicts(); + } + private void checkout() throws IOException { readTree = new WorkDirCheckout(db, trash, head, index, merge); readTree.checkout();
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/IndexTreeWalker.java b/org.spearce.jgit/src/org/spearce/jgit/lib/IndexTreeWalker.java
index 93d5bb2..bc2fb23 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/IndexTreeWalker.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/IndexTreeWalker.java@@ -19,6 +19,8 @@ package org.spearce.jgit.lib; import java.io.File; import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; import org.spearce.jgit.lib.GitIndex.Entry;
@@ -85,9 +87,28 @@ public class IndexTreeWalker { walk(mainTree, newTree, "/"); } + static Comparator<TreeEntry> treeEntryPlainComparator() { + return new Comparator<TreeEntry>() { + public int compare(TreeEntry o1, TreeEntry o2) { + return o1.getName().compareTo(o2.getName()); + } + }; + } + + static Comparator<Entry> indexEntryPlainComparator() { + return new Comparator<Entry>() { + public int compare(Entry o1, Entry o2) { + return o1.getName().compareTo(o2.getName()); + } + }; + } + private void walk(Tree tree, Tree auxTree, String curDir) throws IOException { TreeEntry[] treeMembers = tree == null ? new TreeEntry[0] : tree.members(); TreeEntry[] auxTreeMembers = auxTree == null ? new TreeEntry[0] : auxTree.members(); + Arrays.sort(treeMembers, treeEntryPlainComparator()); + Arrays.sort(auxTreeMembers, treeEntryPlainComparator()); + Arrays.sort(indexMembers, indexEntryPlainComparator()); int treeCounter = 0; int auxTreeCounter = 0;
@@ -308,18 +329,4 @@ public class IndexTreeWalker { } return t1.getName().compareTo(t2.getName()); } - - static int compare(byte[] name1, byte[] name2) { - for (int i = 0; i < name1.length && i < name2.length; i++) { - if (name1[i] < name2[i]) - return -1; - if (name1[i] > name2[i]) - return 1; - } - if (name1.length < name2.length) - return -1; - if (name2.length < name1.length) - return 1; - return 0; - } }
--
1.5.4.rc4.25.g81cc