diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2021-12-30 23:51:41 +0100 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2021-12-30 23:51:41 +0100 |
commit | a461472bd5ce5020f5c88522648156b3bb592926 (patch) | |
tree | 76eebcaa9d3145196dad0328fc8fbb39c8aedaa9 | |
parent | 1c689d18c466e0f77d22f5c396f529d41c70c77b (diff) | |
parent | d87e5e07a542ff40b3fb3e3ca02c170a127b9e2a (diff) | |
download | jgit-a461472bd5ce5020f5c88522648156b3bb592926.tar.gz jgit-a461472bd5ce5020f5c88522648156b3bb592926.zip |
Merge branch 'stable-5.5' into stable-5.6stable-5.6
* stable-5.5:
Use FileSnapshot without using configs for FileBasedConfig
Change-Id: If904289feecd1e0d8466c1fb998f160f14d54b61
3 files changed, 62 insertions, 5 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java index 5100d258d7..8b9869ae4a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java @@ -46,6 +46,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.util.FileUtils.pathToString; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -54,6 +55,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.StringTokenizer; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.junit.MockSystemReader; @@ -90,11 +93,13 @@ public class FileBasedConfigTest { private Path trash; + private MockSystemReader mockSystemReader; + @Before public void setUp() throws Exception { - SystemReader.setInstance(new MockSystemReader()); + mockSystemReader = new MockSystemReader(); + SystemReader.setInstance(mockSystemReader); trash = Files.createTempDirectory("tmp_"); - FS.getFileStoreAttributes(trash.getParent()); } @After @@ -298,6 +303,37 @@ public class FileBasedConfigTest { assertEquals(ALICE_EMAIL, config.getString(USER, null, EMAIL)); } + @Test + public void testSavedConfigFileShouldNotReadUserGitConfig() + throws IOException { + AtomicBoolean userConfigTimeRead = new AtomicBoolean(false); + + Path userConfigFile = createFile(CONTENT1.getBytes(), "home"); + mockSystemReader.setUserGitConfig( + new FileBasedConfig(userConfigFile.toFile(), FS.DETECTED) { + + @Override + public long getTimeUnit(String section, String subsection, + String name, long defaultValue, TimeUnit wantUnit) { + userConfigTimeRead.set(true); + return super.getTimeUnit(section, subsection, name, + defaultValue, wantUnit); + } + }); + + Path file = createFile(CONTENT2.getBytes(), "repo"); + FileBasedConfig fileBasedConfig = new FileBasedConfig(file.toFile(), + FS.DETECTED); + fileBasedConfig.save(); + + // Needed to trigger the read of FileSnapshot filesystem settings + fileBasedConfig.isOutdated(); + assertFalse( + "User config should not be read when accessing config files " + + "for avoiding deadlocks", + userConfigTimeRead.get()); + } + private Path createFile(byte[] content) throws IOException { return createFile(content, null); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java index 78262e9773..d06b5a72d1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java @@ -106,6 +106,8 @@ public class LockFile { private boolean written; + private boolean snapshotNoConfig; + private FileSnapshot commitSnapshot; private LockToken token; @@ -403,6 +405,21 @@ public class LockFile { } /** + * Request that {@link #commit()} remember the + * {@link org.eclipse.jgit.internal.storage.file.FileSnapshot} without using + * config file to get filesystem timestamp resolution. + * This method should be invoked before the file is accessed. + * It is used by FileBasedConfig to avoid endless recursion. + * + * @param on + * true if the commit method must remember the FileSnapshot. + */ + public void setNeedSnapshotNoConfig(boolean on) { + needSnapshot = on; + snapshotNoConfig = on; + } + + /** * Request that {@link #commit()} force dirty data to the drive. * * @param on @@ -480,8 +497,12 @@ public class LockFile { } private void saveStatInformation() { - if (needSnapshot) - commitSnapshot = FileSnapshot.save(lck); + if (needSnapshot) { + commitSnapshot = snapshotNoConfig ? + // don't use config in this snapshot to avoid endless recursion + FileSnapshot.saveNoConfig(lck) + : FileSnapshot.save(lck); + } } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java index f1ff9e6ba0..380c23deb6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java @@ -252,7 +252,7 @@ public class FileBasedConfig extends StoredConfig { if (!lf.lock()) throw new LockFailedException(getFile()); try { - lf.setNeedSnapshot(true); + lf.setNeedSnapshotNoConfig(true); lf.write(out); if (!lf.commit()) throw new IOException(MessageFormat.format(JGitText.get().cannotCommitWriteTo, getFile())); |