diff --git a/org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FS_POSIX_Java7.java b/org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FS_POSIX_Java7.java index e8307fc2b..0879e8021 100644 --- a/org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FS_POSIX_Java7.java +++ b/org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FS_POSIX_Java7.java @@ -156,4 +156,20 @@ public class FS_POSIX_Java7 extends FS_POSIX { public Attributes getAttributes(File path) { return FileUtil.getFileAttributesPosix(this, path); } + + /** + * @since 3.3 + */ + @Override + public File normalize(File file) { + return FileUtil.normalize(file); + } + + /** + * @since 3.3 + */ + @Override + public String normalize(String name) { + return FileUtil.normalize(name); + } } diff --git a/org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FileUtil.java b/org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FileUtil.java index 78dc2c393..c958494d0 100644 --- a/org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FileUtil.java +++ b/org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FileUtil.java @@ -222,4 +222,24 @@ class FileUtil { } } + public static File normalize(File file) { + if (SystemReader.getInstance().isMacOS()) { + // TODO: Would it be faster to check with isNormalized first + // assuming normalized paths are much more common + String normalized = Normalizer.normalize(file.getPath(), + Normalizer.Form.NFC); + return new File(normalized); + } + return file; + } + + public static String normalize(String name) { + if (SystemReader.getInstance().isMacOS()) { + if (name == null) + return null; + return Normalizer.normalize(name, Normalizer.Form.NFC); + } + return name; + } + } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java index 8dc8276b3..8d2cb1d8c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java @@ -163,8 +163,9 @@ public class FileTreeIterator extends WorkingTreeIterator { * @param fs * file system */ - public FileEntry(final File f, FS fs) { + public FileEntry(File f, FS fs) { this.fs = fs; + f = fs.normalize(f); attributes = fs.getAttributes(f); if (attributes.isSymbolicLink()) mode = FileMode.SYMLINK; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index b57176b48..633865ed4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -921,8 +921,8 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { return false; } else { if (mode == FileMode.SYMLINK.getBits()) - return !new File(readContentAsString(current())) - .equals(new File(readContentAsString(entry))); + return !new File(readContentAsNormalizedString(current())) + .equals(new File((readContentAsNormalizedString(entry)))); // Content differs: that's a real change, perhaps if (reader == null) // deprecated use, do no further checks return true; @@ -971,19 +971,19 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { } } - private String readContentAsString(DirCacheEntry entry) + private String readContentAsNormalizedString(DirCacheEntry entry) throws MissingObjectException, IOException { ObjectLoader open = repository.open(entry.getObjectId()); byte[] cachedBytes = open.getCachedBytes(); - return RawParseUtils.decode(cachedBytes); + return FS.detect().normalize(RawParseUtils.decode(cachedBytes)); } - private static String readContentAsString(Entry entry) throws IOException { + private static String readContentAsNormalizedString(Entry entry) throws IOException { long length = entry.getLength(); byte[] content = new byte[(int) length]; InputStream is = entry.openInputStream(); IO.readFully(is, content, 0, (int) length); - return RawParseUtils.decode(content); + return FS.detect().normalize(RawParseUtils.decode(content)); } private long computeLength(InputStream in) throws IOException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index 9e964fc36..dcece6289 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -780,4 +780,26 @@ public abstract class FS { return new Attributes(this, path, exists, isDirectory, canExecute, isSymlink, isFile, createTime, lastModified, -1); } + + /** + * Normalize the unicode path to composed form. + * + * @param file + * @return NFC-format File + * @since 3.3 + */ + public File normalize(File file) { + return file; + } + + /** + * Normalize the unicode path to composed form. + * + * @param name + * @return NFC-format string + * @since 3.3 + */ + public String normalize(String name) { + return name; + } }