Delete non empty directories before checkout a path
If the checkout path is currently a non-empty directory (and was a link or a regular file before), this directory will be removed before performing checkout, but only if the checkout path is specified. Bug: 474973 Change-Id: Ifc6c61592d9b54d26c66367163acdebea369145c Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
This commit is contained in:
parent
227b78f087
commit
a406ebf401
|
@ -55,6 +55,7 @@
|
|||
import java.lang.reflect.Method;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.util.FileUtils;
|
||||
|
@ -240,4 +241,10 @@ public static void deleteTrashFile(final Repository db,
|
|||
FileUtils.delete(path);
|
||||
}
|
||||
|
||||
public static Path writeLink(Repository db, String link,
|
||||
String target) throws Exception {
|
||||
return FileUtils.createSymLink(new File(db.getWorkTree(), link),
|
||||
target);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
|
@ -107,6 +108,11 @@ protected File writeTrashFile(final String name, final String data)
|
|||
return JGitTestUtil.writeTrashFile(db, name, data);
|
||||
}
|
||||
|
||||
protected Path writeLink(final String link, final String target)
|
||||
throws Exception {
|
||||
return JGitTestUtil.writeLink(db, link, target);
|
||||
}
|
||||
|
||||
protected File writeTrashFile(final String subdir, final String name,
|
||||
final String data)
|
||||
throws IOException {
|
||||
|
|
|
@ -923,6 +923,299 @@ public void testCheckoutOutChanges() throws IOException {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckoutChangeLinkToEmptyDir() throws Exception {
|
||||
String fname = "was_file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
|
||||
// Add a link to file
|
||||
String linkName = "link";
|
||||
File link = writeLink(linkName, fname).toFile();
|
||||
git.add().addFilepattern(linkName).call();
|
||||
git.commit().setMessage("Added file and link").call();
|
||||
|
||||
assertWorkDir(mkmap(linkName, "a", fname, "a"));
|
||||
|
||||
// replace link with empty directory
|
||||
FileUtils.delete(link);
|
||||
FileUtils.mkdir(link);
|
||||
assertTrue("Link must be a directory now", link.isDirectory());
|
||||
|
||||
// modify file
|
||||
writeTrashFile(fname, "b");
|
||||
assertWorkDir(mkmap(fname, "b", linkName, "/"));
|
||||
|
||||
// revert both paths to HEAD state
|
||||
git.checkout().setStartPoint(Constants.HEAD)
|
||||
.addPath(fname).addPath(linkName).call();
|
||||
|
||||
assertWorkDir(mkmap(fname, "a", linkName, "a"));
|
||||
|
||||
Status st = git.status().call();
|
||||
assertTrue(st.isClean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckoutChangeLinkToEmptyDirs() throws Exception {
|
||||
String fname = "was_file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
|
||||
// Add a link to file
|
||||
String linkName = "link";
|
||||
File link = writeLink(linkName, fname).toFile();
|
||||
git.add().addFilepattern(linkName).call();
|
||||
git.commit().setMessage("Added file and link").call();
|
||||
|
||||
assertWorkDir(mkmap(linkName, "a", fname, "a"));
|
||||
|
||||
// replace link with directory containing only directories, no files
|
||||
FileUtils.delete(link);
|
||||
FileUtils.mkdirs(new File(link, "dummyDir"));
|
||||
assertTrue("Link must be a directory now", link.isDirectory());
|
||||
|
||||
assertFalse("Must not delete non empty directory", link.delete());
|
||||
|
||||
// modify file
|
||||
writeTrashFile(fname, "b");
|
||||
assertWorkDir(mkmap(fname, "b", linkName + "/dummyDir", "/"));
|
||||
|
||||
// revert both paths to HEAD state
|
||||
git.checkout().setStartPoint(Constants.HEAD)
|
||||
.addPath(fname).addPath(linkName).call();
|
||||
|
||||
assertWorkDir(mkmap(fname, "a", linkName, "a"));
|
||||
|
||||
Status st = git.status().call();
|
||||
assertTrue(st.isClean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckoutChangeLinkToNonEmptyDirs() throws Exception {
|
||||
String fname = "file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
|
||||
// Add a link to file
|
||||
String linkName = "link";
|
||||
File link = writeLink(linkName, fname).toFile();
|
||||
git.add().addFilepattern(linkName).call();
|
||||
git.commit().setMessage("Added file and link").call();
|
||||
|
||||
assertWorkDir(mkmap(linkName, "a", fname, "a"));
|
||||
|
||||
// replace link with directory containing only directories, no files
|
||||
FileUtils.delete(link);
|
||||
|
||||
// create but do not add a file in the new directory to the index
|
||||
writeTrashFile(linkName + "/dir1", "file1", "c");
|
||||
|
||||
// create but do not add a file in the new directory to the index
|
||||
writeTrashFile(linkName + "/dir2", "file2", "d");
|
||||
|
||||
assertTrue("File must be a directory now", link.isDirectory());
|
||||
assertFalse("Must not delete non empty directory", link.delete());
|
||||
|
||||
// 2 extra files are created
|
||||
assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c",
|
||||
linkName + "/dir2/file2", "d"));
|
||||
|
||||
// revert path to HEAD state
|
||||
git.checkout().setStartPoint(Constants.HEAD).addPath(linkName).call();
|
||||
|
||||
// expect only the one added to the index
|
||||
assertWorkDir(mkmap(linkName, "a", fname, "a"));
|
||||
|
||||
Status st = git.status().call();
|
||||
assertTrue(st.isClean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckoutChangeLinkToNonEmptyDirsAndNewIndexEntry()
|
||||
throws Exception {
|
||||
String fname = "file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
|
||||
// Add a link to file
|
||||
String linkName = "link";
|
||||
File link = writeLink(linkName, fname).toFile();
|
||||
git.add().addFilepattern(linkName).call();
|
||||
git.commit().setMessage("Added file and link").call();
|
||||
|
||||
assertWorkDir(mkmap(linkName, "a", fname, "a"));
|
||||
|
||||
// replace link with directory containing only directories, no files
|
||||
FileUtils.delete(link);
|
||||
|
||||
// create and add a file in the new directory to the index
|
||||
writeTrashFile(linkName + "/dir1", "file1", "c");
|
||||
git.add().addFilepattern(linkName + "/dir1/file1").call();
|
||||
|
||||
// create but do not add a file in the new directory to the index
|
||||
writeTrashFile(linkName + "/dir2", "file2", "d");
|
||||
|
||||
assertTrue("File must be a directory now", link.isDirectory());
|
||||
assertFalse("Must not delete non empty directory", link.delete());
|
||||
|
||||
// 2 extra files are created
|
||||
assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c",
|
||||
linkName + "/dir2/file2", "d"));
|
||||
|
||||
// revert path to HEAD state
|
||||
git.checkout().setStartPoint(Constants.HEAD).addPath(linkName).call();
|
||||
|
||||
// original file and link
|
||||
assertWorkDir(mkmap(linkName, "a", fname, "a"));
|
||||
|
||||
Status st = git.status().call();
|
||||
assertFalse(st.isClean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckoutChangeFileToEmptyDir() throws Exception {
|
||||
String fname = "was_file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
File file = writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
git.commit().setMessage("Added file").call();
|
||||
|
||||
// replace file with empty directory
|
||||
FileUtils.delete(file);
|
||||
FileUtils.mkdir(file);
|
||||
assertTrue("File must be a directory now", file.isDirectory());
|
||||
|
||||
assertWorkDir(mkmap(fname, "/"));
|
||||
|
||||
// revert path to HEAD state
|
||||
git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call();
|
||||
|
||||
assertWorkDir(mkmap(fname, "a"));
|
||||
|
||||
Status st = git.status().call();
|
||||
assertTrue(st.isClean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckoutChangeFileToEmptyDirs() throws Exception {
|
||||
String fname = "was_file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
File file = writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
git.commit().setMessage("Added file").call();
|
||||
|
||||
// replace file with directory containing only directories, no files
|
||||
FileUtils.delete(file);
|
||||
FileUtils.mkdirs(new File(file, "dummyDir"));
|
||||
assertTrue("File must be a directory now", file.isDirectory());
|
||||
assertFalse("Must not delete non empty directory", file.delete());
|
||||
|
||||
assertWorkDir(mkmap(fname + "/dummyDir", "/"));
|
||||
|
||||
// revert path to HEAD state
|
||||
git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call();
|
||||
|
||||
assertWorkDir(mkmap(fname, "a"));
|
||||
|
||||
Status st = git.status().call();
|
||||
assertTrue(st.isClean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckoutChangeFileToNonEmptyDirs() throws Exception {
|
||||
String fname = "was_file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
File file = writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
git.commit().setMessage("Added file").call();
|
||||
|
||||
assertWorkDir(mkmap(fname, "a"));
|
||||
|
||||
// replace file with directory containing only directories, no files
|
||||
FileUtils.delete(file);
|
||||
|
||||
// create but do not add a file in the new directory to the index
|
||||
writeTrashFile(fname + "/dir1", "file1", "c");
|
||||
|
||||
// create but do not add a file in the new directory to the index
|
||||
writeTrashFile(fname + "/dir2", "file2", "d");
|
||||
|
||||
assertTrue("File must be a directory now", file.isDirectory());
|
||||
assertFalse("Must not delete non empty directory", file.delete());
|
||||
|
||||
// 2 extra files are created
|
||||
assertWorkDir(
|
||||
mkmap(fname + "/dir1/file1", "c", fname + "/dir2/file2", "d"));
|
||||
|
||||
// revert path to HEAD state
|
||||
git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call();
|
||||
|
||||
// expect only the one added to the index
|
||||
assertWorkDir(mkmap(fname, "a"));
|
||||
|
||||
Status st = git.status().call();
|
||||
assertTrue(st.isClean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckoutChangeFileToNonEmptyDirsAndNewIndexEntry()
|
||||
throws Exception {
|
||||
String fname = "was_file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
File file = writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
git.commit().setMessage("Added file").call();
|
||||
|
||||
assertWorkDir(mkmap(fname, "a"));
|
||||
|
||||
// replace file with directory containing only directories, no files
|
||||
FileUtils.delete(file);
|
||||
|
||||
// create and add a file in the new directory to the index
|
||||
writeTrashFile(fname + "/dir", "file1", "c");
|
||||
git.add().addFilepattern(fname + "/dir/file1").call();
|
||||
|
||||
// create but do not add a file in the new directory to the index
|
||||
writeTrashFile(fname + "/dir", "file2", "d");
|
||||
|
||||
assertTrue("File must be a directory now", file.isDirectory());
|
||||
assertFalse("Must not delete non empty directory", file.delete());
|
||||
|
||||
// 2 extra files are created
|
||||
assertWorkDir(
|
||||
mkmap(fname + "/dir/file1", "c", fname + "/dir/file2", "d"));
|
||||
|
||||
// revert path to HEAD state
|
||||
git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call();
|
||||
assertWorkDir(mkmap(fname, "a"));
|
||||
|
||||
Status st = git.status().call();
|
||||
assertFalse(st.isClean());
|
||||
assertEquals(1, st.getAdded().size());
|
||||
assertTrue(st.getAdded().contains(fname + "/dir/file1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckoutOutChangesAutoCRLFfalse() throws IOException {
|
||||
setupCase(mk("foo"), mkmap("foo/bar", "foo\nbar"), mk("foo"));
|
||||
|
@ -1023,6 +1316,102 @@ public void testOverwriteUntrackedIgnoredFile() throws IOException,
|
|||
assertTrue(git.status().call().isClean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverwriteUntrackedFileModeChange()
|
||||
throws IOException, GitAPIException {
|
||||
String fname = "file.txt";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
File file = writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
git.commit().setMessage("create file").call();
|
||||
assertWorkDir(mkmap(fname, "a"));
|
||||
|
||||
// Create branch
|
||||
git.branchCreate().setName("side").call();
|
||||
|
||||
// Switch branches
|
||||
git.checkout().setName("side").call();
|
||||
|
||||
// replace file with directory containing files
|
||||
FileUtils.delete(file);
|
||||
|
||||
// create and add a file in the new directory to the index
|
||||
writeTrashFile(fname + "/dir1", "file1", "c");
|
||||
git.add().addFilepattern(fname + "/dir1/file1").call();
|
||||
|
||||
// create but do not add a file in the new directory to the index
|
||||
writeTrashFile(fname + "/dir2", "file2", "d");
|
||||
|
||||
assertTrue("File must be a directory now", file.isDirectory());
|
||||
assertFalse("Must not delete non empty directory", file.delete());
|
||||
|
||||
// 2 extra files are created
|
||||
assertWorkDir(
|
||||
mkmap(fname + "/dir1/file1", "c", fname + "/dir2/file2", "d"));
|
||||
|
||||
try {
|
||||
git.checkout().setName("master").call();
|
||||
fail("did not throw exception");
|
||||
} catch (Exception e) {
|
||||
// 2 extra files are still there
|
||||
assertWorkDir(mkmap(fname + "/dir1/file1", "c",
|
||||
fname + "/dir2/file2", "d"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverwriteUntrackedLinkModeChange()
|
||||
throws Exception {
|
||||
String fname = "file.txt";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
// Add a file
|
||||
writeTrashFile(fname, "a");
|
||||
git.add().addFilepattern(fname).call();
|
||||
|
||||
// Add a link to file
|
||||
String linkName = "link";
|
||||
File link = writeLink(linkName, fname).toFile();
|
||||
git.add().addFilepattern(linkName).call();
|
||||
git.commit().setMessage("Added file and link").call();
|
||||
|
||||
assertWorkDir(mkmap(linkName, "a", fname, "a"));
|
||||
|
||||
// Create branch
|
||||
git.branchCreate().setName("side").call();
|
||||
|
||||
// Switch branches
|
||||
git.checkout().setName("side").call();
|
||||
|
||||
// replace link with directory containing files
|
||||
FileUtils.delete(link);
|
||||
|
||||
// create and add a file in the new directory to the index
|
||||
writeTrashFile(linkName + "/dir1", "file1", "c");
|
||||
git.add().addFilepattern(linkName + "/dir1/file1").call();
|
||||
|
||||
// create but do not add a file in the new directory to the index
|
||||
writeTrashFile(linkName + "/dir2", "file2", "d");
|
||||
|
||||
assertTrue("Link must be a directory now", link.isDirectory());
|
||||
assertFalse("Must not delete non empty directory", link.delete());
|
||||
|
||||
// 2 extra files are created
|
||||
assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c",
|
||||
linkName + "/dir2/file2", "d"));
|
||||
|
||||
try {
|
||||
git.checkout().setName("master").call();
|
||||
fail("did not throw exception");
|
||||
} catch (Exception e) {
|
||||
// 2 extra files are still there
|
||||
assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c",
|
||||
linkName + "/dir2/file2", "d"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileModeChangeWithNoContentChangeUpdate() throws Exception {
|
||||
if (!FS.DETECTED.supportsExecute())
|
||||
|
@ -1219,7 +1608,8 @@ public void testFileModeChangeAndContentChangeNoConflict() throws Exception {
|
|||
assertNotNull(git.checkout().setName(Constants.MASTER).call());
|
||||
}
|
||||
|
||||
public void assertWorkDir(HashMap<String, String> i) throws CorruptObjectException,
|
||||
public void assertWorkDir(Map<String, String> i)
|
||||
throws CorruptObjectException,
|
||||
IOException {
|
||||
TreeWalk walk = new TreeWalk(db);
|
||||
walk.setRecursive(false);
|
||||
|
|
|
@ -21,4 +21,12 @@
|
|||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="src/org/eclipse/jgit/util/FileUtils.java" type="org.eclipse.jgit.util.FileUtils">
|
||||
<filter id="338792546">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.jgit.util.FileUtils"/>
|
||||
<message_argument value="createSymLink(File, String)"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
</component>
|
||||
|
|
|
@ -457,7 +457,7 @@ public void apply(DirCacheEntry ent) {
|
|||
|
||||
private void checkoutPath(DirCacheEntry entry, ObjectReader reader) {
|
||||
try {
|
||||
DirCacheCheckout.checkoutEntry(repo, entry, reader);
|
||||
DirCacheCheckout.checkoutEntry(repo, entry, reader, true);
|
||||
} catch (IOException e) {
|
||||
throw new JGitInternalException(MessageFormat.format(
|
||||
JGitText.get().checkoutConflictWithFile,
|
||||
|
|
|
@ -357,7 +357,7 @@ private void resetUntracked(RevTree tree) throws CheckoutConflictException,
|
|||
|
||||
private void checkoutPath(DirCacheEntry entry, ObjectReader reader) {
|
||||
try {
|
||||
DirCacheCheckout.checkoutEntry(repo, entry, reader);
|
||||
DirCacheCheckout.checkoutEntry(repo, entry, reader, true);
|
||||
} catch (IOException e) {
|
||||
throw new JGitInternalException(MessageFormat.format(
|
||||
JGitText.get().checkoutConflictWithFile,
|
||||
|
|
|
@ -447,7 +447,7 @@ private boolean doCheckout() throws CorruptObjectException, IOException,
|
|||
for (String path : updated.keySet()) {
|
||||
DirCacheEntry entry = dc.getEntry(path);
|
||||
if (!FileMode.GITLINK.equals(entry.getRawMode()))
|
||||
checkoutEntry(repo, entry, objectReader);
|
||||
checkoutEntry(repo, entry, objectReader, false);
|
||||
}
|
||||
|
||||
// commit the index builder - a new index is persisted
|
||||
|
@ -1127,6 +1127,13 @@ private boolean isModifiedSubtree_IndexTree(String path, ObjectId tree)
|
|||
* final filename.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> if the entry path on local file system exists as a non-empty
|
||||
* directory, and the target entry type is a link or file, the checkout will
|
||||
* fail with {@link IOException} since existing non-empty directory cannot
|
||||
* be renamed to file or link without deleting it recursively.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* TODO: this method works directly on File IO, we may need another
|
||||
* abstraction (like WorkingTreeIterator). This way we could tell e.g.
|
||||
* Eclipse that Files in the workspace got changed
|
||||
|
@ -1143,6 +1150,42 @@ private boolean isModifiedSubtree_IndexTree(String path, ObjectId tree)
|
|||
*/
|
||||
public static void checkoutEntry(Repository repo, DirCacheEntry entry,
|
||||
ObjectReader or) throws IOException {
|
||||
checkoutEntry(repo, entry, or, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the file in the working tree with content and mode from an entry
|
||||
* in the index. The new content is first written to a new temporary file in
|
||||
* the same directory as the real file. Then that new file is renamed to the
|
||||
* final filename.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> if the entry path on local file system exists as a file, it
|
||||
* will be deleted and if it exists as a directory, it will be deleted
|
||||
* recursively, independently if has any content.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* TODO: this method works directly on File IO, we may need another
|
||||
* abstraction (like WorkingTreeIterator). This way we could tell e.g.
|
||||
* Eclipse that Files in the workspace got changed
|
||||
* </p>
|
||||
*
|
||||
* @param repo
|
||||
* repository managing the destination work tree.
|
||||
* @param entry
|
||||
* the entry containing new mode and content
|
||||
* @param or
|
||||
* object reader to use for checkout
|
||||
* @param deleteRecursive
|
||||
* true to recursively delete final path if it exists on the file
|
||||
* system
|
||||
*
|
||||
* @throws IOException
|
||||
* @since 4.2
|
||||
*/
|
||||
public static void checkoutEntry(Repository repo, DirCacheEntry entry,
|
||||
ObjectReader or, boolean deleteRecursive) throws IOException {
|
||||
ObjectLoader ol = or.open(entry.getObjectId());
|
||||
File f = new File(repo.getWorkTree(), entry.getPathString());
|
||||
File parentDir = f.getParentFile();
|
||||
|
@ -1153,6 +1196,9 @@ public static void checkoutEntry(Repository repo, DirCacheEntry entry,
|
|||
&& opt.getSymLinks() == SymLinks.TRUE) {
|
||||
byte[] bytes = ol.getBytes();
|
||||
String target = RawParseUtils.decode(bytes);
|
||||
if (deleteRecursive && f.isDirectory()) {
|
||||
FileUtils.delete(f, FileUtils.RECURSIVE);
|
||||
}
|
||||
fs.createSymLink(f, target);
|
||||
entry.setLength(bytes.length);
|
||||
entry.setLastModified(fs.lastModified(f));
|
||||
|
@ -1183,11 +1229,18 @@ public static void checkoutEntry(Repository repo, DirCacheEntry entry,
|
|||
}
|
||||
}
|
||||
try {
|
||||
if (deleteRecursive && f.isDirectory()) {
|
||||
FileUtils.delete(f, FileUtils.RECURSIVE);
|
||||
}
|
||||
FileUtils.rename(tmpFile, f);
|
||||
} catch (IOException e) {
|
||||
throw new IOException(MessageFormat.format(
|
||||
JGitText.get().renameFileFailed, tmpFile.getPath(),
|
||||
f.getPath()));
|
||||
} finally {
|
||||
if (tmpFile.exists()) {
|
||||
FileUtils.delete(tmpFile);
|
||||
}
|
||||
}
|
||||
entry.setLastModified(f.lastModified());
|
||||
}
|
||||
|
|
|
@ -399,20 +399,25 @@ public static void createNewFile(File f) throws IOException {
|
|||
*
|
||||
* @param path
|
||||
* @param target
|
||||
* @return path to the created link
|
||||
* @throws IOException
|
||||
* @since 3.0
|
||||
* @since 4.2
|
||||
*/
|
||||
public static void createSymLink(File path, String target)
|
||||
public static Path createSymLink(File path, String target)
|
||||
throws IOException {
|
||||
Path nioPath = path.toPath();
|
||||
if (Files.exists(nioPath, LinkOption.NOFOLLOW_LINKS)) {
|
||||
Files.delete(nioPath);
|
||||
if (Files.isRegularFile(nioPath)) {
|
||||
delete(path);
|
||||
} else {
|
||||
delete(path, EMPTY_DIRECTORIES_ONLY | RECURSIVE);
|
||||
}
|
||||
}
|
||||
if (SystemReader.getInstance().isWindows()) {
|
||||
target = target.replace('/', '\\');
|
||||
}
|
||||
Path nioTarget = new File(target).toPath();
|
||||
Files.createSymbolicLink(nioPath, nioTarget);
|
||||
return Files.createSymbolicLink(nioPath, nioTarget);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue