Browse Source

Cleanup double stat update of symlinks in DirCacheCheckout

When writing a symlink the stat data should only be written once
into the DirCacheEntry, based on the symlink itself and not the
possibly resolved destination observed by java.io.File.

Refactor the code to handle symlinks and early return.  This
removes the risk the blob stat info update is used against a
newly checked out symlink.

Hoist the file length stat update immediately after writing
the file, before a rename. This eliminates any race caused by another
process updating the file length after the rename and having it to
fall into the racily clean path.

Change-Id: I978ad9719c018ce1cf26947efbabaa8b9dff2217
stable-3.6
Shawn Pearce 10 years ago committed by Shawn Pearce
parent
commit
a606dc363d
  1. 20
      org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java

20
org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java vendored

@ -1233,20 +1233,23 @@ public class DirCacheCheckout {
fs.createSymLink(f, target);
entry.setLength(bytes.length);
entry.setLastModified(fs.lastModified(f));
} else {
return;
}
File tmpFile = File.createTempFile(
"._" + f.getName(), null, parentDir); //$NON-NLS-1$
FileOutputStream rawChannel = new FileOutputStream(tmpFile);
OutputStream channel;
OutputStream channel = new FileOutputStream(tmpFile);
if (opt.getAutoCRLF() == AutoCRLF.TRUE)
channel = new AutoCRLFOutputStream(rawChannel);
else
channel = rawChannel;
channel = new AutoCRLFOutputStream(channel);
try {
ol.copyTo(channel);
} finally {
channel.close();
}
entry.setLength(opt.getAutoCRLF() == AutoCRLF.TRUE
? f.length() // AutoCRLF wants on-disk-size
: (int) ol.getSize());
if (opt.isFileMode() && fs.supportsExecute()) {
if (FileMode.EXECUTABLE_FILE.equals(entry.getRawMode())) {
if (!fs.canExecute(tmpFile))
@ -1263,12 +1266,7 @@ public class DirCacheCheckout {
JGitText.get().renameFileFailed, tmpFile.getPath(),
f.getPath()));
}
}
entry.setLastModified(f.lastModified());
if (opt.getAutoCRLF() != AutoCRLF.FALSE)
entry.setLength(f.length()); // AutoCRLF wants on-disk-size
else
entry.setLength((int) ol.getSize());
}
private static void checkValidPath(CanonicalTreeParser t)

Loading…
Cancel
Save