[EGIT PATCH 2/4] Use the Git sort order.
Show changes to 17 files +160 −115
org.spearce.egit.core/src/org/spearce/egit/core/GitBlobStorage.java, org.spearce.egit.core/src/org/spearce/egit/core/GitMoveDeleteHook.java, org.spearce.egit.core/src/org/spearce/egit/core/GitStorage.java, org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileHistory.java, org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileRevision.java, org.spearce.egit.core/src/org/spearce/egit/core/op/TrackOperation.java, org.spearce.egit.core/src/org/spearce/egit/core/op/UntrackOperation.java, org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java, org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryMapping.java, org.spearce.jgit/org.spearce.jgit--All-Tests.launch, org.spearce.jgit/src/org/spearce/jgit/lib/MergedTree.java, org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java, org.spearce.jgit/src/org/spearce/jgit/lib/SubtreeSorter.java, org.spearce.jgit/src/org/spearce/jgit/lib/Tree.java, org.spearce.jgit/src/org/spearce/jgit/lib/TreeEntry.java, org.spearce.jgit/tst/org/spearce/jgit/lib/T0002_Tree.java, org.spearce.jgit/tst/org/spearce/jgit/lib/T0006_DeepSpeedTest.java
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/GitBlobStorage.java b/org.spearce.egit.core/src/org/spearce/egit/core/GitBlobStorage.java
index c947e2b..3ab2184 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/GitBlobStorage.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/GitBlobStorage.java
@@ -59,7 +59,7 @@ public class GitBlobStorage implements IStorage {
else
prefix = "";
String name = prefix + resource.getProjectRelativePath().toString();
- entry = tree.findMember(name);
+ entry = tree.findBlobMember(name);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/GitMoveDeleteHook.java b/org.spearce.egit.core/src/org/spearce/egit/core/GitMoveDeleteHook.java
index e09ac76..389fc76 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/GitMoveDeleteHook.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/GitMoveDeleteHook.java
@@ -122,7 +122,7 @@ class GitMoveDeleteHook implements IMoveDeleteHook {
if (s != null && m != null && m.getCacheTree() != null) {
try {
- final TreeEntry e = m.getCacheTree().findMember(s);
+ final TreeEntry e = m.getCacheTree().findTreeMember(s);
if (e != null) {
e.delete();
m.recomputeMerge();
@@ -182,7 +182,10 @@ class GitMoveDeleteHook implements IMoveDeleteHook {
}
try {
- srcEnt = srcMap.getCacheTree().findMember(srcPath);
+ if (src.getType() == IResource.FILE)
+ srcEnt = srcMap.getCacheTree().findBlobMember(srcPath);
+ else
+ srcEnt = srcMap.getCacheTree().findTreeMember(srcPath);
if (srcEnt == null) {
return FINISH_FOR_ME;
}
@@ -199,7 +202,11 @@ class GitMoveDeleteHook implements IMoveDeleteHook {
if (dstPath == null) {
dstTree = dstMap.getCacheTree();
} else {
- final TreeEntry e = dstMap.getCacheTree().findMember(dstPath);
+ final TreeEntry e;
+ if (src.getType() == IResource.FILE)
+ e = dstMap.getCacheTree().findBlobMember(dstPath);
+ else
+ e = dstMap.getCacheTree().findTreeMember(dstPath);
if (e == null) {
dstTree = dstMap.getCacheTree().addTree(dstPath);
} else if (e instanceof Tree) {
@@ -216,7 +223,9 @@ class GitMoveDeleteHook implements IMoveDeleteHook {
// What? Something already exists at the destination? Assume
// Eclipse meant for us to replace the item.
//
- final TreeEntry existing = dstTree.findMember(dstName);
+ TreeEntry existing = dstTree.findTreeMember(dstName);
+ if (existing == null)
+ dstTree.findBlobMember(dstName);
if (existing != null) {
existing.delete();
}
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/GitStorage.java b/org.spearce.egit.core/src/org/spearce/egit/core/GitStorage.java
index ce4ff71..edef5db 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/GitStorage.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/GitStorage.java
@@ -62,7 +62,10 @@ public class GitStorage implements IStorage {
else
prefix = "";
String name = prefix + resource.getProjectRelativePath().toString();
- entry = tree.findMember(name);
+ if (resource.getType() == IResource.FILE)
+ entry = tree.findBlobMember(name);
+ else
+ entry = tree.findTreeMember(name);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileHistory.java b/org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileHistory.java
index 51109fb..0569862 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileHistory.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileHistory.java
@@ -147,7 +147,11 @@ public class GitFileHistory extends FileHistory implements IAdaptable {
ObjectId[] currentResourceHash = new ObjectId[lastResourceHash.length];
Tree t = current.getTree();
for (int i = 0; i < currentResourceHash.length; ++i) {
- TreeEntry m = t.findMember(relativeResourceName[i]);
+ TreeEntry m;
+ if (i == relativeResourceName.length-1 && resource.getType() == IResource.FILE)
+ m = t.findBlobMember(relativeResourceName[i]);
+ else
+ m = t.findTreeMember(relativeResourceName[i]);
if (m != null) {
ObjectId id = m.getId();
currentResourceHash[i] = id;
@@ -251,7 +255,10 @@ public class GitFileHistory extends FileHistory implements IAdaptable {
}
TreeEntry currentEntry = current.getTree();
for (int i=0; i < relativeResourceName.length && currentEntry != null; ++i) {
- ((Tree)currentEntry).findMember(relativeResourceName[i]);
+ if (i == relativeResourceName.length-1 && resource.getType() == IResource.FILE)
+ ((Tree)currentEntry).findBlobMember(relativeResourceName[i]);
+ else
+ ((Tree)currentEntry).findTreeMember(relativeResourceName[i]);
}
if (currentEntry != null)
revisions = new IFileRevision[] { new GitFileRevision(current, resource,
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileRevision.java b/org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileRevision.java
index def142f..63d8486 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileRevision.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/internal/mapping/GitFileRevision.java
@@ -156,7 +156,10 @@ public class GitFileRevision extends FileRevision {
else {
prefix = prefix + "/";
String name = prefix + relPath;
- return tree.findMember(name);
+ if (resource.getType() == IResource.FILE)
+ return tree.findBlobMember(name);
+ else
+ return tree.findTreeMember(name);
}
} else
return tree;
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/op/TrackOperation.java b/org.spearce.egit.core/src/org/spearce/egit/core/op/TrackOperation.java
index 2f4488d..df3dba7 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/op/TrackOperation.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/op/TrackOperation.java
@@ -137,12 +137,14 @@ public class TrackOperation implements IWorkspaceRunnable {
// Uh, what? Why are we adding a phantom resource? Just say no!
//
} else if (toAdd instanceof IFile) {
- if (!t.exists(path)) {
- t.addFile(path);
+ if (!t.existsTree(path)) {
+ if (!t.existsBlob(path)) {
+ t.addFile(path);
+ }
}
} else if (toAdd instanceof IContainer) {
final IResource[] m = ((IContainer) toAdd).members();
- final TreeEntry e = t.findMember(path);
+ final TreeEntry e = t.findTreeMember(path);
final Tree c;
c = e instanceof Tree ? (Tree) e : e == null ? t.addTree(path)
: null;
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/op/UntrackOperation.java b/org.spearce.egit.core/src/org/spearce/egit/core/op/UntrackOperation.java
index 1a81192..d477644 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/op/UntrackOperation.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/op/UntrackOperation.java
@@ -120,7 +120,11 @@ public class UntrackOperation implements IWorkspaceRunnable {
try {
final Tree t = m.getCacheTree();
- final TreeEntry e = t.findMember(s);
+ final TreeEntry e;
+ if (torm.getType() == IResource.FILE)
+ e = t.findBlobMember(s);
+ else
+ e = t.findTreeMember(s);
if (e != null) {
e.delete();
tomerge.put(m, m);
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java b/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java
index 10cc3a0..0c4683e 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java
@@ -296,7 +296,10 @@ public class GitProjectData {
if (s != null && m != null && m.getActiveDiff() != null) {
try {
- return m.getActiveDiff().findMember(s);
+ if (r.getType() == IResource.FILE)
+ return m.getActiveDiff().findBlobMember(s);
+ else
+ return m.getActiveDiff().findTreeMember(s);
} catch (IOException ioe) {
throw Activator.error(
CoreText.GitProjectData_lazyResolveFailed, ioe);
@@ -416,7 +419,10 @@ public class GitProjectData {
try {
synchronized (cacheTree) {
final TreeEntry e;
- e = cacheTree.findMember(s);
+ if (r.getType() == IResource.FILE)
+ e = cacheTree.findBlobMember(s);
+ else
+ e = cacheTree.findTreeMember(s);
if (e instanceof FileTreeEntry) {
trace("modified " + r + " -> "
+ e.getFullName());
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryMapping.java b/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryMapping.java
index df10665..6b9beed 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryMapping.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryMapping.java
@@ -210,7 +210,7 @@ public class RepositoryMapping {
Tree head = getRepository().mapTree(Constants.HEAD);
if (head != null) {
if (getSubset() != null) {
- final TreeEntry e = head.findMember(getSubset());
+ final TreeEntry e = head.findTreeMember(getSubset());
e.detachParent();
head = e instanceof Tree ? (Tree) e : null;
}
diff --git a/org.spearce.jgit/org.spearce.jgit--All-Tests.launch b/org.spearce.jgit/org.spearce.jgit--All-Tests.launch
index bdbfdea..0ff3d23 100644
--- a/org.spearce.jgit/org.spearce.jgit--All-Tests.launch
+++ b/org.spearce.jgit/org.spearce.jgit--All-Tests.launch
@@ -3,11 +3,17 @@
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.spearce.jgit"/>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/org.spearce.jgit"/>
+</listAttribute>
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.spearce.jgit"/>
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/MergedTree.java b/org.spearce.jgit/src/org/spearce/jgit/lib/MergedTree.java
index e5b2967..165adc3 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/MergedTree.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/MergedTree.java
@@ -53,7 +53,7 @@ public class MergedTree {
}
private static final int binarySearch(final TreeEntry[] entries,
- final int width, final byte[] nameUTF8, final int nameStart,
+ final int width, final byte[] nameUTF8, final byte nameUTF8last, final int nameStart,
final int nameEnd) {
if (entries.length == 0)
return -1;
@@ -66,7 +66,7 @@ public class MergedTree {
while (entries[ix] == null)
ix++;
cmp = Tree.compareNames(entries[ix].getNameUTF8(), nameUTF8,
- nameStart, nameEnd);
+ nameStart, nameEnd, TreeEntry.lastChar(entries[ix]), nameUTF8last);
if (cmp < 0)
low = mid + 1;
else if (cmp == 0)
@@ -95,11 +95,11 @@ public class MergedTree {
return isModified(sources);
}
- public TreeEntry[] findMember(final String s) throws IOException {
- return findMember(s.getBytes(Constants.CHARACTER_ENCODING), 0);
+ public TreeEntry[] findMember(final String s, final byte slast) throws IOException {
+ return findMember(s.getBytes(Constants.CHARACTER_ENCODING), slast, 0);
}
- public TreeEntry[] findMember(final byte[] s, final int offset)
+ public TreeEntry[] findMember(final byte[] s, final byte slast, final int offset)
throws IOException {
final int srcCnt = sources.length;
int slash;
@@ -108,7 +108,8 @@ public class MergedTree {
for (slash = offset; slash < s.length && s[slash] != '/'; slash++) {
// search for path component terminator
}
- p = binarySearch(merged, srcCnt, s, offset, slash);
+ byte xlast = slash<s.length ? (byte)'/' : slast;
+ p = binarySearch(merged, srcCnt, s, xlast, offset, slash);
if (p < 0)
return null;
@@ -127,7 +128,15 @@ public class MergedTree {
subs[j] = merged[k] instanceof Tree ? (Tree) merged[k] : null;
subtrees[p] = new MergedTree(subs);
}
- return subtrees[p].findMember(s, slash + 1);
+ return subtrees[p].findMember(s, slast, slash + 1);
+ }
+
+ public TreeEntry[] findBlobMember(String s) throws IOException {
+ return findMember(s,(byte)0);
+ }
+
+ public TreeEntry[] findTreeMember(String s) throws IOException {
+ return findMember(s,(byte)'/');
}
private void matchByName() throws IOException {
@@ -160,6 +169,7 @@ public class MergedTree {
newMerged = new TreeEntry[pos * srcCnt];
for (pos = 0, treeId = 0; done < srcCnt; pos += srcCnt, treeId++) {
byte[] minName = null;
+ int minNameLast = 0;
if ((pos + srcCnt) >= newMerged.length) {
final TreeEntry[] t = new TreeEntry[newMerged.length * 2];
@@ -176,10 +186,11 @@ public class MergedTree {
final TreeEntry thisEntry = ents[ti];
final int cmp = minName == null ? -1 : Tree.compareNames(
- thisEntry.getNameUTF8(), minName);
+ thisEntry.getNameUTF8(), minName, TreeEntry.lastChar(thisEntry), minNameLast);
if (cmp < 0) {
minName = thisEntry.getNameUTF8();
+ minNameLast = TreeEntry.lastChar(thisEntry);
for (int j = srcId - 1; j >= 0; j--) {
if (newMerged[pos + j] != null) {
newMerged[pos + j] = null;
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java
index 5722eec..f9f2bde 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java
@@ -25,7 +25,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.security.MessageDigest;
-import java.util.Arrays;
import java.util.Iterator;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
@@ -82,12 +81,6 @@ public class ObjectWriter {
public ObjectId writeTree(final Tree t) throws IOException {
final ByteArrayOutputStream o = new ByteArrayOutputStream();
final TreeEntry[] items = t.members();
- for (int k = items.length - 1; k >= 0; k--) {
- if (items[k] instanceof Tree) {
- Arrays.sort(items, SubtreeSorter.INSTANCE);
- break;
- }
- }
for (int k = 0; k < items.length; k++) {
final TreeEntry e = items[k];
final ObjectId id = e.getId();
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/SubtreeSorter.java b/org.spearce.jgit/src/org/spearce/jgit/lib/SubtreeSorter.java
deleted file mode 100644
index 2557525..0000000
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/SubtreeSorter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.spearce.jgit.lib;
-
-import java.util.Comparator;
-
-public class SubtreeSorter implements Comparator {
- public static final SubtreeSorter INSTANCE = new SubtreeSorter();
-
- public int compare(final Object o1, final Object o2) {
- final TreeEntry a = (TreeEntry) o1;
- final TreeEntry b = (TreeEntry) o2;
- final byte[] aName = a.getNameUTF8();
- final byte[] bName = b.getNameUTF8();
-
- for (int k = 0; k < aName.length && k < bName.length; k++) {
- if (aName[k] < bName[k])
- return -1;
- else if (aName[k] > bName[k])
- return 1;
- }
-
- if (aName.length < bName.length) {
- if (a instanceof Tree && '/' > bName[aName.length])
- return 1;
- return -1;
- } else if (aName.length == bName.length) {
- if (a instanceof Tree && b instanceof Tree)
- return 0;
- else if (a instanceof Tree)
- return 1;
- else if (b instanceof Tree)
- return -1;
- else
- return 0;
- } else {
- if (b instanceof Tree && aName[bName.length] < '/')
- return -1;
- return 1;
- }
- }
-}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Tree.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Tree.java
index 65ed400..73a5e2c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Tree.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Tree.java
@@ -17,7 +17,6 @@
package org.spearce.jgit.lib;
import java.io.IOException;
-import java.util.Arrays;
import org.spearce.jgit.errors.CorruptObjectException;
import org.spearce.jgit.errors.EntryExistsException;
@@ -26,13 +25,14 @@ import org.spearce.jgit.errors.MissingObjectException;
public class Tree extends TreeEntry implements Treeish {
public static final TreeEntry[] EMPTY_TREE = {};
- public static final int compareNames(final byte[] a, final byte[] b) {
- return compareNames(a, b, 0, b.length);
+ public static final int compareNames(final byte[] a, final byte[] b, final int lasta,final int lastb) {
+ return compareNames(a, b, 0, b.length, lasta, lastb);
}
public static final int compareNames(final byte[] a, final byte[] nameUTF8,
- final int nameStart, final int nameEnd) {
- for (int j = 0, k = nameStart; j < a.length && k < nameEnd; j++, k++) {
+ final int nameStart, final int nameEnd, final int lasta, int lastb) {
+ int j,k;
+ for (j = 0, k = nameStart; j < a.length && k < nameEnd; j++, k++) {
final int aj = a[j] & 0xff;
final int bk = nameUTF8[k] & 0xff;
if (aj < bk)
@@ -40,6 +40,28 @@ public class Tree extends TreeEntry implements Treeish {
else if (aj > bk)
return 1;
}
+ if (j < a.length) {
+ int aj = a[j]&0xff;
+ if (aj < lastb)
+ return -1;
+ else if (aj > lastb)
+ return 1;
+ else
+ return 0;
+ }
+ if (k < nameEnd) {
+ int bk = nameUTF8[k] & 0xff;
+ if (lasta < bk)
+ return -1;
+ else if (lasta > bk)
+ return 1;
+ else
+ return 0;
+ }
+ if (lasta < lastb)
+ return -1;
+ else if (lasta > lastb)
+ return 1;
final int namelength = nameEnd - nameStart;
if (a.length == namelength)
@@ -60,7 +82,7 @@ public class Tree extends TreeEntry implements Treeish {
}
private static final int binarySearch(final TreeEntry[] entries,
- final byte[] nameUTF8, final int nameStart, final int nameEnd) {
+ final byte[] nameUTF8, final int nameUTF8last, final int nameStart, final int nameEnd) {
if (entries.length == 0)
return -1;
int high = entries.length;
@@ -68,7 +90,7 @@ public class Tree extends TreeEntry implements Treeish {
do {
final int mid = (low + high) / 2;
final int cmp = compareNames(entries[mid].getNameUTF8(), nameUTF8,
- nameStart, nameEnd);
+ nameStart, nameEnd, TreeEntry.lastChar(entries[mid]), nameUTF8last);
if (cmp < 0)
low = mid + 1;
else if (cmp == 0)
@@ -151,7 +173,8 @@ public class Tree extends TreeEntry implements Treeish {
}
ensureLoaded();
- p = binarySearch(contents, s, offset, slash);
+ byte xlast = slash<s.length ? (byte)'/' : 0;
+ p = binarySearch(contents, s, xlast, offset, slash);
if (p >= 0 && slash < s.length && contents[p] instanceof Tree)
return ((Tree) contents[p]).addFile(s, slash + 1);
@@ -184,7 +207,7 @@ public class Tree extends TreeEntry implements Treeish {
}
ensureLoaded();
- p = binarySearch(contents, s, offset, slash);
+ p = binarySearch(contents, s, (byte)'/', offset, slash);
if (p >= 0 && slash < s.length && contents[p] instanceof Tree)
return ((Tree) contents[p]).addTree(s, slash + 1);
@@ -202,7 +225,7 @@ public class Tree extends TreeEntry implements Treeish {
final int p;
ensureLoaded();
- p = binarySearch(contents, e.getNameUTF8(), 0, e.getNameUTF8().length);
+ p = binarySearch(contents, e.getNameUTF8(), TreeEntry.lastChar(e), 0, e.getNameUTF8().length);
if (p < 0) {
e.attachParent(this);
insertEntry(p, e);
@@ -227,7 +250,7 @@ public class Tree extends TreeEntry implements Treeish {
void removeEntry(final TreeEntry e) {
final TreeEntry[] c = contents;
- final int p = binarySearch(c, e.getNameUTF8(), 0,
+ final int p = binarySearch(c, e.getNameUTF8(), TreeEntry.lastChar(e), 0,
e.getNameUTF8().length);
if (p >= 0) {
final TreeEntry[] n = new TreeEntry[c.length - 1];
@@ -257,15 +280,23 @@ public class Tree extends TreeEntry implements Treeish {
return c;
}
- public boolean exists(final String s) throws IOException {
- return findMember(s) != null;
+ public boolean exists(final String s, byte slast) throws IOException {
+ return findMember(s, slast) != null;
}
- public TreeEntry findMember(final String s) throws IOException {
- return findMember(s.getBytes(Constants.CHARACTER_ENCODING), 0);
+ public boolean existsTree(String path) throws IOException {
+ return exists(path,(byte)'/');
}
- public TreeEntry findMember(final byte[] s, final int offset)
+ public boolean existsBlob(String path) throws IOException {
+ return exists(path,(byte)0);
+ }
+
+ public TreeEntry findMember(final String s, byte slast) throws IOException {
+ return findMember(s.getBytes(Constants.CHARACTER_ENCODING), slast, 0);
+ }
+
+ public TreeEntry findMember(final byte[] s, final byte slast, final int offset)
throws IOException {
int slash;
int p;
@@ -275,17 +306,26 @@ public class Tree extends TreeEntry implements Treeish {
}
ensureLoaded();
- p = binarySearch(contents, s, offset, slash);
+ byte xlast = slash<s.length ? (byte)'/' : slast;
+ p = binarySearch(contents, s, xlast, offset, slash);
if (p >= 0) {
final TreeEntry r = contents[p];
if (slash < s.length)
- return r instanceof Tree ? ((Tree) r).findMember(s, slash + 1)
+ return r instanceof Tree ? ((Tree) r).findMember(s, slast, slash + 1)
: null;
return r;
}
return null;
}
+ public TreeEntry findBlobMember(String s) throws IOException {
+ return findMember(s,(byte)0);
+ }
+
+ public TreeEntry findTreeMember(String s) throws IOException {
+ return findMember(s,(byte)'/');
+ }
+
public void accept(final TreeVisitor tv, final int flags)
throws IOException {
final TreeEntry[] c;
@@ -326,7 +366,6 @@ public class Tree extends TreeEntry implements Treeish {
int rawPtr = 0;
TreeEntry[] temp = new TreeEntry[64];
int nextIndex = 0;
- boolean resort = false;
while (rawPtr < raw.length) {
int c = raw[rawPtr++] & 0xff;
@@ -362,7 +401,6 @@ public class Tree extends TreeEntry implements Treeish {
ent = new FileTreeEntry(this, id, name, true);
else if (FileMode.TREE.equals(mode)) {
ent = new Tree(this, id, name);
- resort = true;
} else if (FileMode.SYMLINK.equals(mode))
ent = new SymlinkTreeEntry(this, id, name);
else
@@ -388,12 +426,6 @@ public class Tree extends TreeEntry implements Treeish {
contents = n;
}
- // Resort contents using our internal sorting order. Git sorts
- // subtrees as though their names end in '/' but that's not how
- // we sort them in memory. Its all the fault of the index...
- //
- if (resort)
- Arrays.sort(contents);
}
public String toString() {
@@ -403,4 +435,5 @@ public class Tree extends TreeEntry implements Treeish {
r.append(getFullName());
return r.toString();
}
+
}
\ No newline at end of file
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/TreeEntry.java b/org.spearce.jgit/src/org/spearce/jgit/lib/TreeEntry.java
index 084a9f3..1219846 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/TreeEntry.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/TreeEntry.java
@@ -126,10 +126,17 @@ public abstract class TreeEntry implements Comparable {
if (this == o)
return 0;
if (o instanceof TreeEntry)
- return Tree.compareNames(nameUTF8, ((TreeEntry) o).nameUTF8);
+ return Tree.compareNames(nameUTF8, ((TreeEntry) o).nameUTF8, lastChar(this), lastChar((TreeEntry)o));
return -1;
}
+ final public static int lastChar(TreeEntry treeEntry) {
+ if (treeEntry instanceof FileTreeEntry)
+ return '\0';
+ else
+ return '/';
+ }
+
public void accept(final TreeVisitor tv) throws IOException {
accept(tv, 0);
}
diff --git a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0002_Tree.java b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0002_Tree.java
index e757ef8..62df113 100644
--- a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0002_Tree.java
+++ b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0002_Tree.java
@@ -38,7 +38,8 @@ public class T0002_Tree extends RepositoryTestCase {
assertTrue("no id", t.getId() == null);
assertTrue("tree is self", t.getTree() == t);
assertTrue("database is r", t.getRepository() == db);
- assertTrue("no foo child", t.findMember("foo") == null);
+ assertTrue("no foo child", t.findTreeMember("foo") == null);
+ assertTrue("no foo child", t.findBlobMember("foo") == null);
}
public void test002_addFile() throws IOException {
@@ -57,7 +58,7 @@ public class T0002_Tree extends RepositoryTestCase {
assertTrue("no id", f.getId() == null);
assertTrue("is modified", t.isModified());
assertTrue("has no id", t.getId() == null);
- assertTrue("found bob", t.findMember(f.getName()) == f);
+ assertTrue("found bob", t.findBlobMember(f.getName()) == f);
final TreeEntry[] i = t.members();
assertTrue("iterator is not empty", i != null && i.length > 0);
@@ -87,7 +88,7 @@ public class T0002_Tree extends RepositoryTestCase {
assertTrue("tree is self", f.getTree() == f);
assertTrue("parent is modified", t.isModified());
assertTrue("parent has no id", t.getId() == null);
- assertTrue("found bob child", t.findMember(f.getName()) == f);
+ assertTrue("found bob child", t.findTreeMember(f.getName()) == f);
final TreeEntry[] i = t.members();
assertTrue("iterator is not empty", i.length > 0);
@@ -145,14 +146,14 @@ public class T0002_Tree extends RepositoryTestCase {
assertTrue("t not modified.", !t.isModified());
assertEquals("full path of h ok", "f/g/h", h.getFullName());
- assertTrue("Can find h", t.findMember(h.getFullName()) == h);
- assertTrue("Can't find f/z", t.findMember("f/z") == null);
- assertTrue("Can't find y/z", t.findMember("y/z") == null);
+ assertTrue("Can find h", t.findTreeMember(h.getFullName()) == h);
+ assertTrue("Can't find f/z", t.findBlobMember("f/z") == null);
+ assertTrue("Can't find y/z", t.findBlobMember("y/z") == null);
final FileTreeEntry i = h.addFile("i");
assertNotNull(i);
assertEquals("full path of i ok", "f/g/h/i", i.getFullName());
- assertTrue("Can find i", t.findMember(i.getFullName()) == i);
+ assertTrue("Can find i", t.findBlobMember(i.getFullName()) == i);
assertTrue("h modified", h.isModified());
assertTrue("g modified", g.isModified());
assertTrue("f modified", f.isModified());
@@ -190,17 +191,17 @@ public class T0002_Tree extends RepositoryTestCase {
public void test008_SubtreeInternalSorting() throws IOException {
final Tree t = new Tree(db);
- final FileTreeEntry e0 = t.addFile("a-");
- final FileTreeEntry e1 = t.addFile("a-b");
- final Tree e2 = t.addTree("a");
- final FileTreeEntry e3 = t.addFile("a=");
- final FileTreeEntry e4 = t.addFile("a=b");
+ final FileTreeEntry e0 = t.addFile("a-b");
+ final FileTreeEntry e1 = t.addFile("a-");
+ final FileTreeEntry e2 = t.addFile("a=b");
+ final Tree e3 = t.addTree("a");
+ final FileTreeEntry e4 = t.addFile("a=");
final TreeEntry[] ents = t.members();
- assertSame(e2, ents[0]);
+ assertSame(e1, ents[0]);
assertSame(e0, ents[1]);
- assertSame(e1, ents[2]);
- assertSame(e3, ents[3]);
- assertSame(e4, ents[4]);
+ assertSame(e3, ents[2]);
+ assertSame(e4, ents[3]);
+ assertSame(e2, ents[4]);
}
}
diff --git a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0006_DeepSpeedTest.java b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0006_DeepSpeedTest.java
index 2ae9d42..b4ae4b8 100644
--- a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0006_DeepSpeedTest.java
+++ b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0006_DeepSpeedTest.java
@@ -39,7 +39,7 @@ public class T0006_DeepSpeedTest extends SpeedTestBase {
if (parent.size() > 0) {
ObjectId parentId = (ObjectId) parent.get(0);
commit = db.mapCommit(parentId);
- TreeEntry m = commit.getTree().findMember("net/netfilter/nf_queue.c");
+ TreeEntry m = commit.getTree().findBlobMember("net/netfilter/nf_queue.c");
if (m != null)
commit.getCommitId().toString();
++n;