aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Thun2010-12-14 05:31:41 (EST)
committerPhilipp Thun2010-12-14 05:31:41 (EST)
commitbab053afddbbc26203da54af2dface6ed657f116 (patch)
treedd78fc781524a320a327416f78b1148139cb25a9
parentc6ca443b61372d73a7f1438c995713bad39b5277 (diff)
downloadjgit-bab053afddbbc26203da54af2dface6ed657f116.zip
jgit-bab053afddbbc26203da54af2dface6ed657f116.tar.gz
jgit-bab053afddbbc26203da54af2dface6ed657f116.tar.bz2
Do not rely on filemode differences in case of symbolic linksrefs/changes/09/2109/2
When checking whether a file in the working tree has been modified - WorkingTreeIterator.isModified() - we should not trust the filemode in case of symbolic links, but check the timestamp and also the content, if requested. Without this fix symlinks will always be shown in EGit as modified files on Windows systems. Change-Id: I367c807df5a7e85e828ddacff7fee7901441f187 Signed-off-by: Philipp Thun <philipp.thun@sap.com>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java21
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java22
2 files changed, 34 insertions, 9 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java
index 22eeb8e..67fae27 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java
@@ -46,6 +46,9 @@ package org.eclipse.jgit.treewalk;
import java.io.File;
import java.security.MessageDigest;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.dircache.DirCacheCheckout;
+import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
@@ -175,6 +178,24 @@ public class FileTreeIteratorTest extends RepositoryTestCase {
assertEquals(expect, top.getEntryObjectId());
}
+ public void testIsModifiedSymlink() throws Exception {
+ File f = writeTrashFile("symlink", "content");
+ Git git = new Git(db);
+ git.add().addFilepattern("symlink").call();
+ git.commit().setMessage("commit").call();
+
+ // Modify previously committed DirCacheEntry and write it back to disk
+ DirCacheEntry dce = db.readDirCache().getEntry("symlink");
+ dce.setFileMode(FileMode.SYMLINK);
+ DirCacheCheckout.checkoutEntry(db, f, dce);
+
+ FileTreeIterator fti = new FileTreeIterator(trash, db.getFS(), db
+ .getConfig().get(WorkingTreeOptions.KEY));
+ while (!fti.getEntryPathString().equals("symlink"))
+ fti.next(1);
+ assertFalse(fti.isModified(dce, false));
+ }
+
private static String nameOf(final AbstractTreeIterator i) {
return RawParseUtils.decode(Constants.CHARSET, i.path, 0, i.pathLen);
}
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 6365c11..69d9b22 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -556,15 +556,19 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
// bitwise presentation of modeDiff we'll have a '1' when the two modes
// differ at this position.
int modeDiff = getEntryRawMode() ^ entry.getRawMode();
- // Ignore the executable file bits if checkFilemode tells me to do so.
- // Ignoring is done by setting the bits representing a EXECUTABLE_FILE
- // to '0' in modeDiff
- if (!state.options.isFileMode())
- modeDiff &= ~FileMode.EXECUTABLE_FILE.getBits();
- if (modeDiff != 0)
- // Report a modification if the modes still (after potentially
- // ignoring EXECUTABLE_FILE bits) differ
- return true;
+
+ // Do not rely on filemode differences in case of symbolic links
+ if (modeDiff != 0 && !FileMode.SYMLINK.equals(entry.getRawMode())) {
+ // Ignore the executable file bits if WorkingTreeOptions tell me to
+ // do so. Ignoring is done by setting the bits representing a
+ // EXECUTABLE_FILE to '0' in modeDiff
+ if (!state.options.isFileMode())
+ modeDiff &= ~FileMode.EXECUTABLE_FILE.getBits();
+ if (modeDiff != 0)
+ // Report a modification if the modes still (after potentially
+ // ignoring EXECUTABLE_FILE bits) differ
+ return true;
+ }
// Git under windows only stores seconds so we round the timestamp
// Java gives us if it looks like the timestamp in index is seconds