Merge branch 'stable-5.12' into stable-5.13

* stable-5.12:
  Use FileSnapshot without using configs for FileBasedConfig

Change-Id: I6a0266cbcaaf18d0d60f0abecb5434fd919c44b7
This commit is contained in:
Matthias Sohn 2021-12-31 00:29:40 +01:00
commit c8ab1392d1
3 changed files with 62 additions and 5 deletions

View File

@ -14,6 +14,7 @@
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertFalse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -22,6 +23,8 @@
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;
@ -58,11 +61,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
@ -266,6 +271,37 @@ public void testIncludeDontInlineIncludedLinesOnSave()
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);
}

View File

@ -106,6 +106,8 @@ static File getLockFile(File file) {
private boolean written;
private boolean snapshotNoConfig;
private FileSnapshot commitSnapshot;
private LockToken token;
@ -402,6 +404,21 @@ public void setNeedSnapshot(boolean on) {
needSnapshot = on;
}
/**
* 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.
*
@ -480,8 +497,12 @@ private void closeToken() {
}
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);
}
}
/**

View File

@ -219,7 +219,7 @@ public void save() throws IOException {
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()));