Merge "Use relative paths for attribute rule matching"
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java
index ca456b3..50d020c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java
@@ -254,6 +254,33 @@
endWalk();
}
+ @Test
+ public void testRelativePaths() throws Exception {
+ setupRepo("sub/ global", "sub/** init",
+ "sub/** top_sub\n*.txt top",
+ "sub/** subsub\nsub/ subsub2\n*.txt foo");
+ // The last two sub/** and sub/ rules are in sub/.gitattributes. They
+ // must not apply to any of the files here. They would match for a
+ // further subdirectory sub/sub.
+ walk = beginWalk();
+ assertIteration(F, ".gitattributes");
+ assertIteration(D, "sub", attrs("global"));
+ assertIteration(F, "sub/.gitattributes", attrs("init top_sub global"));
+ assertIteration(F, "sub/a.txt", attrs("init foo top top_sub global"));
+ endWalk();
+ // All right, let's see that they *do* apply in sub/sub:
+ writeTrashFile("sub/sub/b.txt", "b");
+ walk = beginWalk();
+ assertIteration(F, ".gitattributes");
+ assertIteration(D, "sub", attrs("global"));
+ assertIteration(F, "sub/.gitattributes", attrs("init top_sub global"));
+ assertIteration(F, "sub/a.txt", attrs("init foo top top_sub global"));
+ assertIteration(D, "sub/sub", attrs("init subsub2 top_sub global"));
+ assertIteration(F, "sub/sub/b.txt",
+ attrs("init foo subsub2 subsub top top_sub global"));
+ endWalk();
+ }
+
private static Collection<Attribute> attrs(String s) {
return new AttributesRule("*", s).getAttributes();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java
index 3bf4179..8d928e3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java
@@ -144,7 +144,8 @@
mergeInfoAttributes(entryPath, isDirectory, attributes);
// Gets the attributes located on the current entry path
- mergePerDirectoryEntryAttributes(entryPath, isDirectory,
+ mergePerDirectoryEntryAttributes(entryPath, entryPath.lastIndexOf('/'),
+ isDirectory,
treeWalk.getTree(WorkingTreeIterator.class),
treeWalk.getTree(DirCacheIterator.class),
treeWalk.getTree(CanonicalTreeParser.class),
@@ -206,6 +207,8 @@
* the path to test. The path must be relative to this attribute
* node's own repository path, and in repository path format
* (uses '/' and not '\').
+ * @param nameRoot
+ * index of the '/' preceeding the current level, or -1 if none
* @param isDirectory
* true if the target item is a directory.
* @param workingTreeIterator
@@ -217,7 +220,7 @@
* @throws IOException
*/
private void mergePerDirectoryEntryAttributes(String entryPath,
- boolean isDirectory,
+ int nameRoot, boolean isDirectory,
@Nullable WorkingTreeIterator workingTreeIterator,
@Nullable DirCacheIterator dirCacheIterator,
@Nullable CanonicalTreeParser otherTree, Attributes result)
@@ -228,9 +231,12 @@
AttributesNode attributesNode = attributesNode(
treeWalk, workingTreeIterator, dirCacheIterator, otherTree);
if (attributesNode != null) {
- mergeAttributes(attributesNode, entryPath, isDirectory, result);
+ mergeAttributes(attributesNode,
+ entryPath.substring(nameRoot + 1), isDirectory,
+ result);
}
- mergePerDirectoryEntryAttributes(entryPath, isDirectory,
+ mergePerDirectoryEntryAttributes(entryPath,
+ entryPath.lastIndexOf('/', nameRoot - 1), isDirectory,
parentOf(workingTreeIterator), parentOf(dirCacheIterator),
parentOf(otherTree), result);
}