]> source.dussan.org Git - jgit.git/commitdiff
Checkout should be able to override modified symbolic links 40/62840/5
authorAndrey Loskutov <loskutov@gmx.de>
Wed, 16 Dec 2015 15:41:34 +0000 (16:41 +0100)
committerAndrey Loskutov <loskutov@gmx.de>
Thu, 17 Dec 2015 09:42:44 +0000 (10:42 +0100)
Handle existing symlink as a file, not as directory if deleting a file
before creating (overriding) a symlink.

Bug: 484491
Change-Id: I29dbf57d1daec2ba98454975b093e1d381d05196
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java
org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java

index db811cdf59757dc64f1a7134ea287887bb89db3e..3343af06ddeaa08a1256993ee2852f9ba57f41a6 100644 (file)
 package org.eclipse.jgit.api;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
 
 import org.eclipse.jgit.api.CheckoutCommand.Stage;
 import org.eclipse.jgit.api.errors.JGitInternalException;
@@ -59,6 +61,9 @@ import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.lib.RepositoryState;
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -73,6 +78,8 @@ public class PathCheckoutCommandTest extends RepositoryTestCase {
 
        private static final String FILE3 = "Test3.txt";
 
+       private static final String LINK = "link";
+
        Git git;
 
        RevCommit initialCommit;
@@ -98,6 +105,64 @@ public class PathCheckoutCommandTest extends RepositoryTestCase {
                git.commit().setMessage("Third commit").call();
        }
 
+       @Test
+       public void testUpdateSymLink() throws Exception {
+               Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
+
+               Path path = writeLink(LINK, FILE1);
+               git.add().addFilepattern(LINK).call();
+               git.commit().setMessage("Added link").call();
+               assertEquals("3", read(path.toFile()));
+
+               writeLink(LINK, FILE2);
+               assertEquals("c", read(path.toFile()));
+
+               CheckoutCommand co = git.checkout();
+               co.addPath(LINK).call();
+
+               assertEquals("3", read(path.toFile()));
+       }
+
+       @Test
+       public void testUpdateBrokenSymLinkToDirectory() throws Exception {
+               Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
+
+               Path path = writeLink(LINK, "f");
+               git.add().addFilepattern(LINK).call();
+               git.commit().setMessage("Added link").call();
+               assertEquals("f", FileUtils.readSymLink(path.toFile()));
+               assertTrue(path.toFile().exists());
+
+               writeLink(LINK, "link_to_nowhere");
+               assertFalse(path.toFile().exists());
+               assertEquals("link_to_nowhere", FileUtils.readSymLink(path.toFile()));
+
+               CheckoutCommand co = git.checkout();
+               co.addPath(LINK).call();
+
+               assertEquals("f", FileUtils.readSymLink(path.toFile()));
+       }
+
+       @Test
+       public void testUpdateBrokenSymLink() throws Exception {
+               Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
+
+               Path path = writeLink(LINK, FILE1);
+               git.add().addFilepattern(LINK).call();
+               git.commit().setMessage("Added link").call();
+               assertEquals("3", read(path.toFile()));
+               assertEquals(FILE1, FileUtils.readSymLink(path.toFile()));
+
+               writeLink(LINK, "link_to_nowhere");
+               assertFalse(path.toFile().exists());
+               assertEquals("link_to_nowhere", FileUtils.readSymLink(path.toFile()));
+
+               CheckoutCommand co = git.checkout();
+               co.addPath(LINK).call();
+
+               assertEquals("3", read(path.toFile()));
+       }
+
        @Test
        public void testUpdateWorkingDirectory() throws Exception {
                CheckoutCommand co = git.checkout();
index 0d7d31b3ad6dc2741f159418f0434c2701f5b16f..1f78e0208736ad53c323b7ba96086c1b5d1e91de 100644 (file)
@@ -54,6 +54,7 @@ import java.util.regex.Matcher;
 
 import org.eclipse.jgit.junit.JGitTestUtil;
 import org.junit.After;
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -424,18 +425,27 @@ public class FileUtilTest {
        @Test
        public void testCreateSymlink() throws IOException {
                FS fs = FS.DETECTED;
-               try {
-                       fs.createSymLink(new File(trash, "x"), "y");
-               } catch (IOException e) {
-                       if (fs.supportsSymlinks())
-                               fail("FS claims to support symlinks but attempt to create symlink failed");
-                       return;
-               }
-               assertTrue(fs.supportsSymlinks());
+               // show test as ignored if the FS doesn't support symlinks
+               Assume.assumeTrue(fs.supportsSymlinks());
+               fs.createSymLink(new File(trash, "x"), "y");
                String target = fs.readSymLink(new File(trash, "x"));
                assertEquals("y", target);
        }
 
+       @Test
+       public void testCreateSymlinkOverrideExisting() throws IOException {
+               FS fs = FS.DETECTED;
+               // show test as ignored if the FS doesn't support symlinks
+               Assume.assumeTrue(fs.supportsSymlinks());
+               File file = new File(trash, "x");
+               fs.createSymLink(file, "y");
+               String target = fs.readSymLink(file);
+               assertEquals("y", target);
+               fs.createSymLink(file, "z");
+               target = fs.readSymLink(file);
+               assertEquals("z", target);
+       }
+
        @Test
        public void testRelativize_doc() {
                // This is the javadoc example
index 727ea79cc949a9c063c053c1702bcf5857a84408..aa101f73f94d98383f46d56f65283ecba66ac1f9 100644 (file)
@@ -409,7 +409,9 @@ public class FileUtils {
                        throws IOException {
                Path nioPath = path.toPath();
                if (Files.exists(nioPath, LinkOption.NOFOLLOW_LINKS)) {
-                       if (Files.isRegularFile(nioPath)) {
+                       BasicFileAttributes attrs = Files.readAttributes(nioPath,
+                                       BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
+                       if (attrs.isRegularFile() || attrs.isSymbolicLink()) {
                                delete(path);
                        } else {
                                delete(path, EMPTY_DIRECTORIES_ONLY | RECURSIVE);