]> source.dussan.org Git - jgit.git/commitdiff
Fix adding symlinks to the index when core.symlinks=false 08/194808/2
authorThomas Wolf <twolf@apache.org>
Wed, 20 Jul 2022 16:30:18 +0000 (18:30 +0200)
committerThomas Wolf <twolf@apache.org>
Sat, 13 Aug 2022 13:14:15 +0000 (15:14 +0200)
With core.symlinks=false, symlinks are checked out as plain files.
When such a file is re-added to the index, and the index already
contains a symlink there, add the file as a symlink. Previous code
changed the index entry to a regular file.

Bug: 580412
Change-Id: I5497bedc3da89c8b10120b8077c56bc5b67cb791
Signed-off-by: Thomas Wolf <twolf@apache.org>
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java

index 5dfdfcfe6b442887d89a0ee0e839cd250d7b2328..57661a7ecaf1cf570a408af0b180ad9310a528f1 100644 (file)
@@ -15,13 +15,16 @@ import static org.eclipse.jgit.util.FileUtils.RECURSIVE;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.nio.file.Files;
 import java.util.Set;
 
+import org.eclipse.jgit.api.ResetCommand.ResetType;
 import org.eclipse.jgit.api.errors.FilterFailedException;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.NoFilepatternException;
@@ -34,6 +37,7 @@ import org.eclipse.jgit.junit.RepositoryTestCase;
 import org.eclipse.jgit.lfs.BuiltinLFS;
 import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.CoreConfig.SymLinks;
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
@@ -99,6 +103,43 @@ public class AddCommandTest extends RepositoryTestCase {
                }
        }
 
+       @Test
+       public void testAddLink() throws IOException, GitAPIException {
+               assumeTrue(db.getFS().supportsSymlinks());
+               try (Git git = new Git(db)) {
+                       writeTrashFile("a.txt", "a");
+                       File link = new File(db.getWorkTree(), "link");
+                       db.getFS().createSymLink(link, "a.txt");
+                       git.add().addFilepattern(".").call();
+                       assertEquals(
+                                       "[a.txt, mode:100644, content:a][link, mode:120000, content:a.txt]",
+                                       indexState(CONTENT));
+                       git.commit().setMessage("link").call();
+                       StoredConfig config = db.getConfig();
+                       config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
+                                       ConfigConstants.CONFIG_KEY_SYMLINKS, SymLinks.FALSE);
+                       config.save();
+                       Files.delete(link.toPath());
+                       git.reset().setMode(ResetType.HARD).call();
+                       assertTrue(Files.isRegularFile(link.toPath()));
+                       assertEquals(
+                                       "[a.txt, mode:100644, content:a][link, mode:120000, content:a.txt]",
+                                       indexState(CONTENT));
+                       writeTrashFile("link", "b.txt");
+                       git.add().addFilepattern("link").call();
+                       assertEquals(
+                                       "[a.txt, mode:100644, content:a][link, mode:120000, content:b.txt]",
+                                       indexState(CONTENT));
+                       config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
+                                       ConfigConstants.CONFIG_KEY_SYMLINKS, SymLinks.TRUE);
+                       config.save();
+                       git.add().addFilepattern("link").call();
+                       assertEquals(
+                                       "[a.txt, mode:100644, content:a][link, mode:100644, content:b.txt]",
+                                       indexState(CONTENT));
+               }
+       }
+
        @Test
        public void testCleanFilter() throws IOException, GitAPIException {
                writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
index b108b0a95919d2ba0dc11d266bbd04056233eae4..d8a61ec97ac5c8fddd6e715b68b7a6e92592e387 100644 (file)
@@ -1004,6 +1004,12 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
                        return wtMode;
                }
                final FileMode iMode = indexIter.getEntryFileMode();
+               if (iMode == FileMode.SYMLINK
+                               && getOptions().getSymLinks() == SymLinks.FALSE
+                               && (wtMode == FileMode.REGULAR_FILE
+                                               || wtMode == FileMode.EXECUTABLE_FILE)) {
+                       return iMode;
+               }
                if (getOptions().isFileMode() && iMode != FileMode.GITLINK && iMode != FileMode.TREE) {
                        return wtMode;
                }