Fix adding symlinks to the index when core.symlinks=false

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>
This commit is contained in:
Thomas Wolf 2022-07-20 18:30:18 +02:00
parent 1ee0b9b79f
commit d9c0629ffe
2 changed files with 47 additions and 0 deletions

View File

@ -15,13 +15,16 @@
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.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 void testAddExistingSingleFile() throws IOException, GitAPIException {
}
}
@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");

View File

@ -1004,6 +1004,12 @@ public FileMode getIndexFileMode(DirCacheIterator indexIter) {
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;
}