Merge "Do not rely on filemode differences in case of symbolic links"

This commit is contained in:
Shawn Pearce 2010-12-15 18:55:59 -05:00 committed by Code Review
commit c19093bbad
2 changed files with 34 additions and 9 deletions

View File

@ -46,6 +46,9 @@
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 void testComputeFileObjectId() throws Exception {
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);
}

View File

@ -556,15 +556,19 @@ public boolean isModified(DirCacheEntry entry, boolean forceContentCheck) {
// 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