From ad02a7cbada59560fde64f9ecb361aabbd08b235 Mon Sep 17 00:00:00 2001
From: David Pursehouse
Date: Fri, 9 Aug 2019 12:11:41 +0900
Subject: Stop using deprecated Constants.CHARACTER_ENCODING
Change-Id: I105b8a05bc64f249879a0795a059958553cc60c6
Signed-off-by: David Pursehouse
---
org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index d4282e0b85..e37f207315 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -46,11 +46,11 @@
*/
package org.eclipse.jgit.merge;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.time.Instant.EPOCH;
import static org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm.HISTOGRAM;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_DIFF_SECTION;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_ALGORITHM;
-import static org.eclipse.jgit.lib.Constants.CHARACTER_ENCODING;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import java.io.BufferedOutputStream;
@@ -1029,7 +1029,7 @@ public class ResolveMerger extends ThreeWayMerger {
db != null ? nonNullRepo().getDirectory() : null, inCoreLimit);
try {
new MergeFormatter().formatMerge(buf, result,
- Arrays.asList(commitNames), CHARACTER_ENCODING);
+ Arrays.asList(commitNames), UTF_8.name());
buf.close();
} catch (IOException e) {
buf.destroy();
--
cgit v1.2.3
From 42000a71e3b73639f8ba2858f8ba8e7941a1ab1c Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Sat, 10 Aug 2019 00:39:16 +0200
Subject: LockFile: log exception if creation of lock file failed
Change-Id: I4de75d12ec9e61193494916307289378cdb6220e
Signed-off-by: Matthias Sohn
---
.../resources/org/eclipse/jgit/internal/JGitText.properties | 5 +++--
org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java | 1 +
.../src/org/eclipse/jgit/internal/storage/file/LockFile.java | 7 ++++++-
3 files changed, 10 insertions(+), 3 deletions(-)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 290a0a28ef..cba892ef68 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -302,8 +302,9 @@ expectedLessThanGot=expected less than ''{0}'', got ''{1}''
expectedPktLineWithService=expected pkt-line with ''# service=-'', got ''{0}''
expectedReceivedContentType=expected Content-Type {0}; received Content-Type {1}
expectedReportForRefNotReceived={0}: expected report for ref {1} not received
-failedAtomicFileCreation=Atomic file creation failed, number of hard links to file {0} was not 2 but {1}"
-failedToDetermineFilterDefinition=An exception occured while determining filter definitions
+failedAtomicFileCreation=Atomic file creation failed, number of hard links to file {0} was not 2 but {1}
+failedCreateLockFile=Creating lock file {} failed
+failedToDetermineFilterDefinition=An exception occurred while determining filter definitions
failedUpdatingRefs=failed updating refs
failureDueToOneOfTheFollowing=Failure due to one of the following:
failureUpdatingFETCH_HEAD=Failure updating FETCH_HEAD: {0}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index 00aaa42b47..23950100d2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -364,6 +364,7 @@ public class JGitText extends TranslationBundle {
/***/ public String expectedReceivedContentType;
/***/ public String expectedReportForRefNotReceived;
/***/ public String failedAtomicFileCreation;
+ /***/ public String failedCreateLockFile;
/***/ public String failedToDetermineFilterDefinition;
/***/ public String failedUpdatingRefs;
/***/ public String failureDueToOneOfTheFollowing;
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 420e737543..f7e78b94f7 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
@@ -165,7 +165,12 @@ public class LockFile {
*/
public boolean lock() throws IOException {
FileUtils.mkdirs(lck.getParentFile(), true);
- token = FS.DETECTED.createNewFileAtomic(lck);
+ try {
+ token = FS.DETECTED.createNewFileAtomic(lck);
+ } catch (IOException e) {
+ LOG.error(JGitText.get().failedCreateLockFile, lck, e);
+ throw e;
+ }
if (token.isCreated()) {
haveLck = true;
try {
--
cgit v1.2.3
From a7338dd1e5173b081d0ec1a7f31f48ed34b07d70 Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Sat, 10 Aug 2019 23:28:07 +0200
Subject: Remove FileBasedConfig.load(boolean) introduced in d45219ba
We can't add this method to the super class StoredConfig since that
abstracts from filesystem storage. MockSystemReader.MockConfig is a
StoredConfig and is also used by tests for dfs based storage. Hence
remove this leaky abstraction.
This implies we always use the fallback FileStoreAttributes which means
a config file modification is considered racy within the first 2
seconds. This should not be an issue since typically configs change
rarely and re-reading a config within the racy period is relatively
cheap since configs are small.
Change-Id: Ia2615addc24a7cadf3c566ee842c6f4f07e159a5
Signed-off-by: Matthias Sohn
---
org.eclipse.jgit/.settings/.api_filters | 8 -------
.../eclipse/jgit/storage/file/FileBasedConfig.java | 28 ++--------------------
org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java | 22 ++++++++---------
3 files changed, 12 insertions(+), 46 deletions(-)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index 7aa7301b03..5874cd51f0 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -78,14 +78,6 @@
-
-
-
-
-
-
-
-
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 633632dc01..e7b0941f2d 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
@@ -149,37 +149,13 @@ public class FileBasedConfig extends StoredConfig {
*/
@Override
public void load() throws IOException, ConfigInvalidException {
- load(true);
- }
-
- /**
- * Load the configuration as a Git text style configuration file.
- *
- * If the file does not exist, this configuration is cleared, and thus
- * behaves the same as though the file exists, but is empty.
- *
- * @param useFileSnapshotWithConfig
- * if {@code true} use the FileSnapshot with config, otherwise
- * use it without config
- * @throws IOException
- * if IO failed
- * @throws ConfigInvalidException
- * if config is invalid
- * @since 5.1.9
- */
- public void load(boolean useFileSnapshotWithConfig)
- throws IOException, ConfigInvalidException {
final int maxStaleRetries = 5;
int retries = 0;
while (true) {
final FileSnapshot oldSnapshot = snapshot;
final FileSnapshot newSnapshot;
- if (useFileSnapshotWithConfig) {
- newSnapshot = FileSnapshot.save(getFile());
- } else {
- // don't use config in this snapshot to avoid endless recursion
- newSnapshot = FileSnapshot.saveNoConfig(getFile());
- }
+ // don't use config in this snapshot to avoid endless recursion
+ newSnapshot = FileSnapshot.saveNoConfig(getFile());
try {
final byte[] in = IO.readFully(getFile());
final ObjectId newHash = hash(in);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index 19c04619df..509e6d2280 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -100,7 +100,7 @@ import org.eclipse.jgit.internal.storage.file.FileSnapshot;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry;
import org.eclipse.jgit.treewalk.FileTreeIterator.FileModeStrategy;
import org.eclipse.jgit.treewalk.WorkingTreeIterator.Entry;
@@ -510,17 +510,17 @@ public abstract class FS {
private static Optional readFromConfig(
FileStore s) {
- FileBasedConfig userConfig = SystemReader.getInstance()
+ StoredConfig userConfig = SystemReader.getInstance()
.openUserConfig(null, FS.DETECTED);
try {
- userConfig.load(false);
+ userConfig.load();
} catch (IOException e) {
LOG.error(MessageFormat.format(JGitText.get().readConfigFailed,
- userConfig.getFile().getAbsolutePath()), e);
+ userConfig), e);
} catch (ConfigInvalidException e) {
LOG.error(MessageFormat.format(
JGitText.get().repositoryConfigFileInvalid,
- userConfig.getFile().getAbsolutePath(),
+ userConfig,
e.getMessage()));
}
String key = getConfigKey(s);
@@ -544,7 +544,7 @@ public abstract class FS {
private static void saveToConfig(FileStore s,
FileStoreAttributes c) {
- FileBasedConfig userConfig = SystemReader.getInstance()
+ StoredConfig userConfig = SystemReader.getInstance()
.openUserConfig(null, FS.DETECTED);
long resolution = c.getFsTimestampResolution().toNanos();
TimeUnit resolutionUnit = getUnit(resolution);
@@ -562,7 +562,7 @@ public abstract class FS {
String key = getConfigKey(s);
while (!succeeded && retries < max_retries) {
try {
- userConfig.load(false);
+ userConfig.load();
userConfig.setString(
ConfigConstants.CONFIG_FILESYSTEM_SECTION, key,
ConfigConstants.CONFIG_KEY_TIMESTAMP_RESOLUTION,
@@ -581,7 +581,7 @@ public abstract class FS {
// race with another thread, wait a bit and try again
try {
LOG.warn(MessageFormat.format(JGitText.get().cannotLock,
- userConfig.getFile().getAbsolutePath()));
+ userConfig));
retries++;
Thread.sleep(20);
} catch (InterruptedException e1) {
@@ -589,13 +589,11 @@ public abstract class FS {
}
} catch (IOException e) {
LOG.error(MessageFormat.format(
- JGitText.get().cannotSaveConfig,
- userConfig.getFile().getAbsolutePath()), e);
+ JGitText.get().cannotSaveConfig, userConfig), e);
} catch (ConfigInvalidException e) {
LOG.error(MessageFormat.format(
JGitText.get().repositoryConfigFileInvalid,
- userConfig.getFile().getAbsolutePath(),
- e.getMessage()));
+ userConfig, e.getMessage()));
}
}
}
--
cgit v1.2.3
From cc29da8e0f228867205331ec918e3cc17dcfecb8 Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Mon, 12 Aug 2019 07:14:54 +0200
Subject: Ensure root cause of lock creation failures is logged
Change-Id: I91cdf1e085a29c0aabd6d22c6ebe848b2d75f42c
Signed-off-by: Matthias Sohn
---
org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
index 8795329bf9..03b94ee118 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
@@ -48,6 +48,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.nio.charset.Charset;
+import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -422,7 +423,7 @@ public class FS_POSIX extends FS {
* An implementation of the File#createNewFile() semantics which can create
* a unique file atomically also on NFS. If the config option
* {@code core.supportsAtomicCreateNewFile = true} (which is the default)
- * then simply File#createNewFile() is called.
+ * then simply Files#createFile() is called.
*
* But if {@code core.supportsAtomicCreateNewFile = false} then after
* successful creation of the lock file a hard link to that lock file is
@@ -443,14 +444,17 @@ public class FS_POSIX extends FS {
*/
@Override
public LockToken createNewFileAtomic(File file) throws IOException {
- if (!file.createNewFile()) {
+ Path path;
+ try {
+ path = file.toPath();
+ Files.createFile(path);
+ } catch (FileAlreadyExistsException e) {
return token(false, null);
}
if (supportsAtomicCreateNewFile() || !supportsUnixNLink) {
return token(true, null);
}
Path link = null;
- Path path = file.toPath();
try {
link = Files.createLink(Paths.get(uniqueLinkPath(file)), path);
Integer nlink = (Integer) (Files.getAttribute(path,
--
cgit v1.2.3
From 6ef225c5191f0e0c7ffc621843528568455d72a1 Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Mon, 12 Aug 2019 12:18:16 +0200
Subject: Handle InvalidPathException in FS_POSIX#createNewFileAtomic
Bug: 547400
Change-Id: Ic3541e360a2968ba3532a3d3fa4828b0d0463c02
Signed-off-by: Matthias Sohn
---
org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
index 03b94ee118..8561f6f3a2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
@@ -50,6 +50,7 @@ import java.io.PrintStream;
import java.nio.charset.Charset;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
@@ -448,7 +449,7 @@ public class FS_POSIX extends FS {
try {
path = file.toPath();
Files.createFile(path);
- } catch (FileAlreadyExistsException e) {
+ } catch (FileAlreadyExistsException | InvalidPathException e) {
return token(false, null);
}
if (supportsAtomicCreateNewFile() || !supportsUnixNLink) {
--
cgit v1.2.3
From 9b4a55c0b65074e6abec4b9aff1b602ee6a976b9 Mon Sep 17 00:00:00 2001
From: Vishal Devgire
Date: Tue, 9 Apr 2019 13:01:36 +0530
Subject: Make supportsAtomicCreateNewFile return true as default
The method org.eclipse.jgit.util.FS.supportsAtomicCreateNewFile()
should default to true as mentioned in docs [1]
org.eclipse.jgit.util.FS_POSIX.supportsAtomicCreateNewFile() method
will set the value to false if the git config
core.supportsatomiccreatenewfile is not set.
It should default to true if the configuration is undefined.
[1]
https://github.com/eclipse/jgit/blob/4169a95a65683e39e7a6a8f2b11b543e2bc754db/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java#L372
Bug: 544164
Change-Id: I16ccf989a89da2cf4975c200b3228b25ba4c0d55
Signed-off-by: Vishal Devgire
Signed-off-by: Matthias Sohn
---
org.eclipse.jgit.test/META-INF/MANIFEST.MF | 2 +
.../tst/org/eclipse/jgit/util/FS_POSIXTest.java | 125 +++++++++++++++++++++
.../src/org/eclipse/jgit/util/FS_POSIX.java | 7 +-
3 files changed, 133 insertions(+), 1 deletion(-)
create mode 100644 org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index 89ce34dbf4..48ae7cf5e4 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -68,6 +68,8 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
org.junit.rules;version="[4.12,5.0.0)",
org.junit.runner;version="[4.12,5.0.0)",
org.junit.runners;version="[4.12,5.0.0)",
+ org.mockito;version="[2.23.0,3.0.0)",
+ org.mockito.stubbing;version="2.23.0",
org.slf4j;version="[1.7.0,2.0.0)",
org.tukaani.xz;version="[1.6.0,2.0)"
Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java
new file mode 100644
index 0000000000..9683f93e69
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2019, Vishal Devgire
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.util;
+
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FS_POSIXTest {
+ private SystemReader originalSystemReaderInstance;
+
+ private FileBasedConfig mockSystemConfig;
+
+ private FileBasedConfig mockUserConfig;
+
+ @Before
+ public void setUp() throws Exception {
+ SystemReader systemReader = Mockito.mock(SystemReader.class);
+
+ originalSystemReaderInstance = SystemReader.getInstance();
+ SystemReader.setInstance(systemReader);
+
+ mockSystemConfig = mock(FileBasedConfig.class);
+ mockUserConfig = mock(FileBasedConfig.class);
+ when(systemReader.openSystemConfig(any(), any()))
+ .thenReturn(mockSystemConfig);
+ when(systemReader.openUserConfig(any(), any()))
+ .thenReturn(mockUserConfig);
+
+ when(mockSystemConfig.getString(ConfigConstants.CONFIG_CORE_SECTION,
+ null, ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION))
+ .thenReturn(null);
+ }
+
+ @After
+ public void tearDown() {
+ SystemReader.setInstance(originalSystemReaderInstance);
+ }
+
+ @Test
+ public void supportsAtomicCreateNewFile_shouldReturnSupportedAsDefault() {
+ assertTrue(new FS_POSIX().supportsAtomicCreateNewFile());
+ }
+
+ @Test
+ public void supportsAtomicCreateNewFile_shouldReturnTrueIfFlagIsSetInUserConfig() {
+ setAtomicCreateCreationFlag(mockUserConfig, "true");
+ assertTrue(new FS_POSIX().supportsAtomicCreateNewFile());
+ }
+
+ @Test
+ public void supportsAtomicCreateNewFile_shouldReturnTrueIfFlagIsSetInSystemConfig() {
+ setAtomicCreateCreationFlag(mockSystemConfig, "true");
+ assertTrue(new FS_POSIX().supportsAtomicCreateNewFile());
+ }
+
+ @Test
+ public void supportsAtomicCreateNewFile_shouldReturnFalseIfFlagUnsetInUserConfig() {
+ setAtomicCreateCreationFlag(mockUserConfig, "false");
+ assertFalse(new FS_POSIX().supportsAtomicCreateNewFile());
+ }
+
+ @Test
+ public void supportsAtomicCreateNewFile_shouldReturnFalseIfFlagUnsetInSystemConfig() {
+ setAtomicCreateCreationFlag(mockSystemConfig, "false");
+ assertFalse(new FS_POSIX().supportsAtomicCreateNewFile());
+ }
+
+ private void setAtomicCreateCreationFlag(FileBasedConfig config,
+ String value) {
+ when(config.getString(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION))
+ .thenReturn(value);
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
index 8561f6f3a2..1c42f78577 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
@@ -122,6 +122,10 @@ public class FS_POSIX extends FS {
ret = getAtomicFileCreationSupportOption(
SystemReader.getInstance().openSystemConfig(null, this));
}
+
+ if (ret == AtomicFileCreation.UNDEFINED) {
+ ret = AtomicFileCreation.SUPPORTED;
+ }
supportsAtomicCreateNewFile = ret;
}
@@ -139,7 +143,8 @@ public class FS_POSIX extends FS {
? AtomicFileCreation.SUPPORTED
: AtomicFileCreation.NOT_SUPPORTED;
} catch (IOException | ConfigInvalidException e) {
- return AtomicFileCreation.SUPPORTED;
+ LOG.error(e.getMessage(), e);
+ return AtomicFileCreation.UNDEFINED;
}
}
--
cgit v1.2.3
From 2d84bb43410469b44bca145c3d06a0386c0e2175 Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Mon, 12 Aug 2019 17:40:39 +0200
Subject: Improve retry handling when saving FileStoreAttributes fails
- fix handling of interrupts in FileStoreAttributes#saveToConfig
- increase retry wait time to 100ms
- don't wait after last retry
- dont retry if failure is caused by another exception than
LockFailedException
Change-Id: I108c012717d2bcce71f2c6cb9cf0879de704ebc2
Signed-off-by: Matthias Sohn
---
.../org/eclipse/jgit/internal/JGitText.properties | 1 +
.../src/org/eclipse/jgit/internal/JGitText.java | 1 +
org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java | 18 ++++++++++++++----
3 files changed, 16 insertions(+), 4 deletions(-)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index cba892ef68..1579dc7a7a 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -430,6 +430,7 @@ localRefIsMissingObjects=Local ref {0} is missing object(s).
localRepository=local repository
lockCountMustBeGreaterOrEqual1=lockCount must be >= 1
lockError=lock error: {0}
+lockFailedRetry=locking {0} failed after {1} retries
lockOnNotClosed=Lock on {0} not closed.
lockOnNotHeld=Lock on {0} not held.
malformedpersonIdentString=Malformed PersonIdent string (no < was found): {0}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index 23950100d2..a6110e57d5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -491,6 +491,7 @@ public class JGitText extends TranslationBundle {
/***/ public String localRepository;
/***/ public String lockCountMustBeGreaterOrEqual1;
/***/ public String lockError;
+ /***/ public String lockFailedRetry;
/***/ public String lockOnNotClosed;
/***/ public String lockOnNotHeld;
/***/ public String malformedpersonIdentString;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index 509e6d2280..6efd02f479 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -580,20 +580,30 @@ public abstract class FS {
} catch (LockFailedException e) {
// race with another thread, wait a bit and try again
try {
- LOG.warn(MessageFormat.format(JGitText.get().cannotLock,
- userConfig));
retries++;
- Thread.sleep(20);
+ if (retries < max_retries) {
+ Thread.sleep(100);
+ LOG.debug("locking {} failed, retries {}/{}", //$NON-NLS-1$
+ userConfig, Integer.valueOf(retries),
+ Integer.valueOf(max_retries));
+ } else {
+ LOG.warn(MessageFormat.format(
+ JGitText.get().lockFailedRetry, userConfig,
+ Integer.valueOf(retries)));
+ }
} catch (InterruptedException e1) {
- Thread.interrupted();
+ Thread.currentThread().interrupt();
+ break;
}
} catch (IOException e) {
LOG.error(MessageFormat.format(
JGitText.get().cannotSaveConfig, userConfig), e);
+ break;
} catch (ConfigInvalidException e) {
LOG.error(MessageFormat.format(
JGitText.get().repositoryConfigFileInvalid,
userConfig, e.getMessage()));
+ break;
}
}
}
--
cgit v1.2.3
From b51bb4f7bd305287fed885161fbef1cf3bd16613 Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Thu, 15 Aug 2019 01:36:41 +0200
Subject: Fix javadoc for SystemReader#getInstance
The existing javadoc was copied from another method and not adapted.
Change-Id: I39a7e5d719b2c379de9bd1a4710a55a73700c6f0
Signed-off-by: Matthias Sohn
---
org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
index 953c9768f9..b61a6f1914 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
@@ -152,16 +152,16 @@ public abstract class SystemReader {
private static SystemReader INSTANCE = DEFAULT;
/**
- * Get time since epoch, with up to millisecond resolution.
+ * Get the current SystemReader instance
*
- * @return time since epoch, with up to millisecond resolution.
+ * @return the current SystemReader instance.
*/
public static SystemReader getInstance() {
return INSTANCE;
}
/**
- * Set the new instance to use when accessing properties.
+ * Set a new SystemReader instance to use when accessing properties.
*
* @param newReader
* the new instance to use when accessing properties, or null for
--
cgit v1.2.3
From f383206ace187ec92672b806e18a54e8d398a27d Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Thu, 15 Aug 2019 01:25:28 +0200
Subject: Cache user global and system-wide git configurations
So far the git configuration and the system wide git configuration were
always reloaded when jgit accessed these global configuration files to
access global configuration options which are not in the context of a
single git repository. Cache these configurations in SystemReader and
only reload them if their file metadata observed using FileSnapshot
indicates a modification.
Change-Id: I092fe11a5d95f1c5799273cacfc7a415d0b7786c
Signed-off-by: Matthias Sohn
Signed-off-by: Thomas Wolf
---
.../jgit/http/test/SmartClientSmartServerTest.java | 18 ++-
.../jgit/junit/LocalDiskRepositoryTestCase.java | 9 +-
.../org/eclipse/jgit/junit/MockSystemReader.java | 41 ++++++-
org.eclipse.jgit.lfs/.settings/.api_filters | 11 ++
.../eclipse/jgit/lfs/InstallBuiltinLfsCommand.java | 41 ++++---
.../tst/org/eclipse/jgit/api/CloneCommandTest.java | 6 +-
.../tst/org/eclipse/jgit/util/FS_POSIXTest.java | 74 +++++++-----
org.eclipse.jgit/.settings/.api_filters | 26 ++++
.../org/eclipse/jgit/internal/JGitText.properties | 5 +-
.../src/org/eclipse/jgit/internal/JGitText.java | 5 +-
.../jgit/internal/storage/file/FileRepository.java | 85 +++----------
.../src/org/eclipse/jgit/transport/HttpConfig.java | 11 +-
.../org/eclipse/jgit/transport/TransportHttp.java | 10 +-
org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java | 25 ++--
.../src/org/eclipse/jgit/util/FS_POSIX.java | 64 ++++------
.../src/org/eclipse/jgit/util/SystemReader.java | 133 +++++++++++++++++----
16 files changed, 337 insertions(+), 227 deletions(-)
create mode 100644 org.eclipse.jgit.lfs/.settings/.api_filters
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
index b26324d4f2..78bf778cc8 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
@@ -107,7 +107,6 @@ import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.transport.AbstractAdvertiseRefsHook;
import org.eclipse.jgit.transport.AdvertiseRefsHook;
import org.eclipse.jgit.transport.CredentialItem;
@@ -127,7 +126,6 @@ import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import org.eclipse.jgit.transport.resolver.UploadPackFactory;
-import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.HttpSupport;
import org.eclipse.jgit.util.SystemReader;
import org.hamcrest.Matchers;
@@ -652,8 +650,8 @@ public class SmartClientSmartServerTest extends HttpTestCase {
@Test
public void testInitialClone_RedirectMax() throws Exception {
- FileBasedConfig userConfig = SystemReader.getInstance()
- .openUserConfig(null, FS.DETECTED);
+ StoredConfig userConfig = SystemReader.getInstance()
+ .getUserConfig();
userConfig.setInt("http", null, "maxRedirects", 4);
userConfig.save();
initialClone_Redirect(4, 302);
@@ -661,8 +659,8 @@ public class SmartClientSmartServerTest extends HttpTestCase {
@Test
public void testInitialClone_RedirectTooOften() throws Exception {
- FileBasedConfig userConfig = SystemReader.getInstance()
- .openUserConfig(null, FS.DETECTED);
+ StoredConfig userConfig = SystemReader.getInstance()
+ .getUserConfig();
userConfig.setInt("http", null, "maxRedirects", 3);
userConfig.save();
Repository dst = createBareRepository();
@@ -701,8 +699,8 @@ public class SmartClientSmartServerTest extends HttpTestCase {
@Test
public void testInitialClone_RedirectOnPostAllowed() throws Exception {
- FileBasedConfig userConfig = SystemReader.getInstance()
- .openUserConfig(null, FS.DETECTED);
+ StoredConfig userConfig = SystemReader.getInstance()
+ .getUserConfig();
userConfig.setString("http", null, "followRedirects", "true");
userConfig.save();
Repository dst = createBareRepository();
@@ -764,8 +762,8 @@ public class SmartClientSmartServerTest extends HttpTestCase {
@Test
public void testInitialClone_RedirectForbidden() throws Exception {
- FileBasedConfig userConfig = SystemReader.getInstance()
- .openUserConfig(null, FS.DETECTED);
+ StoredConfig userConfig = SystemReader.getInstance()
+ .getUserConfig();
userConfig.setString("http", null, "followRedirects", "false");
userConfig.save();
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
index f8f0c18cba..29579d007f 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
@@ -137,14 +137,15 @@ public abstract class LocalDiskRepositoryTestCase {
// the same one here
FS.getFileStoreAttributes(tmp.toPath().getParent());
- mockSystemReader.userGitConfig = new FileBasedConfig(new File(tmp,
- "usergitconfig"), FS.DETECTED);
+ FileBasedConfig userConfig = new FileBasedConfig(
+ new File(tmp, "usergitconfig"), FS.DETECTED);
// We have to set autoDetach to false for tests, because tests expect to be able
// to clean up by recursively removing the repository, and background GC might be
// in the middle of writing or deleting files, which would disrupt this.
- mockSystemReader.userGitConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION,
+ userConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION,
null, ConfigConstants.CONFIG_KEY_AUTODETACH, false);
- mockSystemReader.userGitConfig.save();
+ userConfig.save();
+ mockSystemReader.setUserGitConfig(userConfig);
ceilTestDirectories(getCeilings());
author = new PersonIdent("J. Author", "jauthor@example.com");
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
index 92b531d191..123fdb305f 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
@@ -60,6 +60,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SystemReader;
@@ -100,10 +101,36 @@ public class MockSystemReader extends SystemReader {
final Map values = new HashMap<>();
- FileBasedConfig userGitConfig;
+ private FileBasedConfig userGitConfig;
FileBasedConfig systemGitConfig;
+ /**
+ * Set the user-level git config
+ *
+ * @param userGitConfig
+ * set another user-level git config
+ * @return the old user-level git config
+ */
+ public FileBasedConfig setUserGitConfig(FileBasedConfig userGitConfig) {
+ FileBasedConfig old = this.userGitConfig;
+ this.userGitConfig = userGitConfig;
+ return old;
+ }
+
+ /**
+ * Set the system-level git config
+ *
+ * @param systemGitConfig
+ * the new system-level git config
+ * @return the old system-level config
+ */
+ public FileBasedConfig setSystemGitConfig(FileBasedConfig systemGitConfig) {
+ FileBasedConfig old = this.systemGitConfig;
+ this.systemGitConfig = systemGitConfig;
+ return old;
+ }
+
/**
* Constructor for MockSystemReader
*/
@@ -166,6 +193,18 @@ public class MockSystemReader extends SystemReader {
return systemGitConfig;
}
+ @Override
+ public StoredConfig getUserConfig()
+ throws IOException, ConfigInvalidException {
+ return userGitConfig;
+ }
+
+ @Override
+ public StoredConfig getSystemConfig()
+ throws IOException, ConfigInvalidException {
+ return systemGitConfig;
+ }
+
/** {@inheritDoc} */
@Override
public String getHostname() {
diff --git a/org.eclipse.jgit.lfs/.settings/.api_filters b/org.eclipse.jgit.lfs/.settings/.api_filters
new file mode 100644
index 0000000000..db45ade674
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/.api_filters
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/InstallBuiltinLfsCommand.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/InstallBuiltinLfsCommand.java
index 028b19b2ab..b7b0535ea5 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/InstallBuiltinLfsCommand.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/InstallBuiltinLfsCommand.java
@@ -43,14 +43,12 @@
package org.eclipse.jgit.lfs;
import java.io.IOException;
-import java.text.MessageFormat;
+import org.eclipse.jgit.api.errors.InvalidConfigurationException;
import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.lfs.internal.LfsText;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.LfsFactory.LfsInstallCommand;
import org.eclipse.jgit.util.SystemReader;
@@ -70,12 +68,28 @@ public class InstallBuiltinLfsCommand implements LfsInstallCommand {
private Repository repository;
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IOException
+ * if an I/O error occurs while accessing a git config or
+ * executing {@code git lfs install} in an external process
+ * @throws InvalidConfigurationException
+ * if a git configuration is invalid
+ * @throws InterruptedException
+ * if the current thread is interrupted while waiting for the
+ * {@code git lfs install} executed in an external process
+ */
@Override
- public Void call() throws Exception {
+ public Void call() throws IOException, InvalidConfigurationException,
+ InterruptedException {
StoredConfig cfg = null;
if (repository == null) {
- cfg = loadUserConfig();
+ try {
+ cfg = SystemReader.getInstance().getUserConfig();
+ } catch (ConfigInvalidException e) {
+ throw new InvalidConfigurationException(e.getMessage(), e);
+ }
} else {
cfg = repository.getConfig();
}
@@ -116,19 +130,4 @@ public class InstallBuiltinLfsCommand implements LfsInstallCommand {
return this;
}
- private StoredConfig loadUserConfig() throws IOException {
- FileBasedConfig c = SystemReader.getInstance().openUserConfig(null,
- FS.DETECTED);
- try {
- c.load();
- } catch (ConfigInvalidException e1) {
- throw new IOException(MessageFormat
- .format(LfsText.get().userConfigInvalid, c.getFile()
- .getAbsolutePath(), e1),
- e1);
- }
-
- return c;
- }
-
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
index 0d7009dca4..613ca5ce95 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
@@ -68,9 +68,9 @@ import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.submodule.SubmoduleStatus;
import org.eclipse.jgit.submodule.SubmoduleStatusType;
import org.eclipse.jgit.submodule.SubmoduleWalk;
@@ -633,8 +633,8 @@ public class CloneCommandTest extends RepositoryTestCase {
ConfigConstants.CONFIG_BRANCH_SECTION, "test",
ConfigConstants.CONFIG_KEY_REBASE, null));
- FileBasedConfig userConfig = SystemReader.getInstance().openUserConfig(
- null, git.getRepository().getFS());
+ StoredConfig userConfig = SystemReader.getInstance()
+ .getUserConfig();
userConfig.setString(ConfigConstants.CONFIG_BRANCH_SECTION, null,
ConfigConstants.CONFIG_KEY_AUTOSETUPREBASE,
ConfigConstants.CONFIG_KEY_ALWAYS);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java
index 9683f93e69..87349a25a4 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java
@@ -43,48 +43,63 @@
package org.eclipse.jgit.util;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.jgit.junit.MockSystemReader;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.Mockito;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
public class FS_POSIXTest {
private SystemReader originalSystemReaderInstance;
- private FileBasedConfig mockSystemConfig;
+ private FileBasedConfig systemConfig;
+
+ private FileBasedConfig userConfig;
- private FileBasedConfig mockUserConfig;
+ private Path tmp;
@Before
public void setUp() throws Exception {
- SystemReader systemReader = Mockito.mock(SystemReader.class);
+ tmp = Files.createTempDirectory("jgit_test_");
+ MockSystemReader mockSystemReader = new MockSystemReader();
+ SystemReader.setInstance(mockSystemReader);
+
+ // Measure timer resolution before the test to avoid time critical tests
+ // are affected by time needed for measurement.
+ // The MockSystemReader must be configured first since we need to use
+ // the same one here
+ FS.getFileStoreAttributes(tmp.getParent());
+ systemConfig = new FileBasedConfig(
+ new File(tmp.toFile(), "systemgitconfig"), FS.DETECTED);
+ userConfig = new FileBasedConfig(systemConfig,
+ new File(tmp.toFile(), "usergitconfig"), FS.DETECTED);
+ // We have to set autoDetach to false for tests, because tests expect to
+ // be able to clean up by recursively removing the repository, and
+ // background GC might be in the middle of writing or deleting files,
+ // which would disrupt this.
+ userConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+ ConfigConstants.CONFIG_KEY_AUTODETACH, false);
+ userConfig.save();
+ mockSystemReader.setSystemGitConfig(systemConfig);
+ mockSystemReader.setUserGitConfig(userConfig);
originalSystemReaderInstance = SystemReader.getInstance();
- SystemReader.setInstance(systemReader);
-
- mockSystemConfig = mock(FileBasedConfig.class);
- mockUserConfig = mock(FileBasedConfig.class);
- when(systemReader.openSystemConfig(any(), any()))
- .thenReturn(mockSystemConfig);
- when(systemReader.openUserConfig(any(), any()))
- .thenReturn(mockUserConfig);
-
- when(mockSystemConfig.getString(ConfigConstants.CONFIG_CORE_SECTION,
- null, ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION))
- .thenReturn(null);
+ SystemReader.setInstance(mockSystemReader);
}
@After
- public void tearDown() {
+ public void tearDown() throws IOException {
SystemReader.setInstance(originalSystemReaderInstance);
+ FileUtils.delete(tmp.toFile(), FileUtils.RECURSIVE | FileUtils.RETRY);
}
@Test
@@ -94,32 +109,31 @@ public class FS_POSIXTest {
@Test
public void supportsAtomicCreateNewFile_shouldReturnTrueIfFlagIsSetInUserConfig() {
- setAtomicCreateCreationFlag(mockUserConfig, "true");
+ setAtomicCreateCreationFlag(userConfig, "true");
assertTrue(new FS_POSIX().supportsAtomicCreateNewFile());
}
@Test
public void supportsAtomicCreateNewFile_shouldReturnTrueIfFlagIsSetInSystemConfig() {
- setAtomicCreateCreationFlag(mockSystemConfig, "true");
+ setAtomicCreateCreationFlag(systemConfig, "true");
assertTrue(new FS_POSIX().supportsAtomicCreateNewFile());
}
@Test
public void supportsAtomicCreateNewFile_shouldReturnFalseIfFlagUnsetInUserConfig() {
- setAtomicCreateCreationFlag(mockUserConfig, "false");
+ setAtomicCreateCreationFlag(userConfig, "false");
assertFalse(new FS_POSIX().supportsAtomicCreateNewFile());
}
@Test
public void supportsAtomicCreateNewFile_shouldReturnFalseIfFlagUnsetInSystemConfig() {
- setAtomicCreateCreationFlag(mockSystemConfig, "false");
+ setAtomicCreateCreationFlag(systemConfig, "false");
assertFalse(new FS_POSIX().supportsAtomicCreateNewFile());
}
private void setAtomicCreateCreationFlag(FileBasedConfig config,
String value) {
- when(config.getString(ConfigConstants.CONFIG_CORE_SECTION, null,
- ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION))
- .thenReturn(value);
+ config.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION, value);
}
}
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index 5874cd51f0..f05afaf537 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -248,4 +248,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 1579dc7a7a..dc1db81402 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -17,6 +17,7 @@ applyingCommit=Applying {0}
archiveFormatAlreadyAbsent=Archive format already absent: {0}
archiveFormatAlreadyRegistered=Archive format already registered with different implementation: {0}
argumentIsNotAValidCommentString=Invalid comment: {0}
+assumeAtomicCreateNewFile=Reading option "core.supportsAtomicFileCreation" failed, fallback to default assuming atomic file creation is supported
atLeastOnePathIsRequired=At least one path is required.
atLeastOnePatternIsRequired=At least one pattern is required.
atLeastTwoFiltersNeeded=At least two filters needed.
@@ -562,6 +563,7 @@ pushNotPermitted=push not permitted
pushOptionsNotSupported=Push options not supported; received {0}
rawLogMessageDoesNotParseAsLogEntry=Raw log message does not parse as log entry
readConfigFailed=Reading config file ''{0}'' failed
+readFileStoreAttributesFailed=Reading FileStore attributes from user config failed
readerIsRequired=Reader is required
readingObjectsFromLocalRepositoryFailed=reading objects from local repository failed: {0}
readLastModifiedFailed=Reading lastModified of {0} failed
@@ -618,6 +620,7 @@ rewinding=Rewinding to commit {0}
s3ActionDeletion=Deletion
s3ActionReading=Reading
s3ActionWriting=Writing
+saveFileStoreAttributesFailed=Saving measured FileStore attributes to user config failed
searchForReuse=Finding sources
searchForSizes=Getting sizes
secondsAgo={0} seconds ago
@@ -777,7 +780,7 @@ uriNotConfigured=Submodule URI not configured
uriNotFound={0} not found
uriNotFoundWithMessage={0} not found: {1}
URINotSupported=URI not supported: {0}
-userConfigFileInvalid=User config file {0} invalid {1}
+userConfigInvalid=Git config in the user's home directory {0} is invalid {1}
walkFailure=Walk failure.
wantNotValid=want {0} not valid
weeksAgo={0} weeks ago
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index a6110e57d5..4c60266248 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -78,6 +78,7 @@ public class JGitText extends TranslationBundle {
/***/ public String archiveFormatAlreadyAbsent;
/***/ public String archiveFormatAlreadyRegistered;
/***/ public String argumentIsNotAValidCommentString;
+ /***/ public String assumeAtomicCreateNewFile;
/***/ public String atLeastOnePathIsRequired;
/***/ public String atLeastOnePatternIsRequired;
/***/ public String atLeastTwoFiltersNeeded;
@@ -623,6 +624,7 @@ public class JGitText extends TranslationBundle {
/***/ public String pushOptionsNotSupported;
/***/ public String rawLogMessageDoesNotParseAsLogEntry;
/***/ public String readConfigFailed;
+ /***/ public String readFileStoreAttributesFailed;
/***/ public String readerIsRequired;
/***/ public String readingObjectsFromLocalRepositoryFailed;
/***/ public String readLastModifiedFailed;
@@ -679,6 +681,7 @@ public class JGitText extends TranslationBundle {
/***/ public String s3ActionDeletion;
/***/ public String s3ActionReading;
/***/ public String s3ActionWriting;
+ /***/ public String saveFileStoreAttributesFailed;
/***/ public String searchForReuse;
/***/ public String searchForSizes;
/***/ public String secondsAgo;
@@ -838,7 +841,7 @@ public class JGitText extends TranslationBundle {
/***/ public String uriNotFound;
/***/ public String uriNotFoundWithMessage;
/***/ public String URINotSupported;
- /***/ public String userConfigFileInvalid;
+ /***/ public String userConfigInvalid;
/***/ public String walkFailure;
/***/ public String wantNotValid;
/***/ public String weeksAgo;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
index 5ced68646f..356d64b563 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
@@ -81,15 +81,17 @@ import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.ReflogReader;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.storage.pack.PackConfig;
-import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
import org.eclipse.jgit.util.StringUtils;
import org.eclipse.jgit.util.SystemReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Represents a Git repository. A repository holds all objects and refs used for
@@ -116,10 +118,10 @@ import org.eclipse.jgit.util.SystemReader;
* This implementation only handles a subtly undocumented subset of git features.
*/
public class FileRepository extends Repository {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(FileRepository.class);
private static final String UNNAMED = "Unnamed repository; edit this file to name it for gitweb."; //$NON-NLS-1$
- private final FileBasedConfig systemConfig;
- private final FileBasedConfig userConfig;
private final FileBasedConfig repoConfig;
private final RefDatabase refs;
private final ObjectDirectory objectDatabase;
@@ -178,32 +180,16 @@ public class FileRepository extends Repository {
*/
public FileRepository(BaseRepositoryBuilder options) throws IOException {
super(options);
-
- if (StringUtils.isEmptyOrNull(SystemReader.getInstance().getenv(
- Constants.GIT_CONFIG_NOSYSTEM_KEY)))
- systemConfig = SystemReader.getInstance().openSystemConfig(null,
- getFS());
- else
- systemConfig = new FileBasedConfig(null, FS.DETECTED) {
- @Override
- public void load() {
- // empty, do not load
- }
-
- @Override
- public boolean isOutdated() {
- // regular class would bomb here
- return false;
- }
- };
- userConfig = SystemReader.getInstance().openUserConfig(systemConfig,
- getFS());
+ StoredConfig userConfig = null;
+ try {
+ userConfig = SystemReader.getInstance().getUserConfig();
+ } catch (ConfigInvalidException e) {
+ LOG.error(e.getMessage(), e);
+ throw new IOException(e.getMessage(), e);
+ }
repoConfig = new FileBasedConfig(userConfig, getFS().resolve(
getDirectory(), Constants.CONFIG),
getFS());
-
- loadSystemConfig();
- loadUserConfig();
loadRepoConfig();
repoConfig.addChangeListener(new ConfigChangedListener() {
@@ -247,28 +233,6 @@ public class FileRepository extends Repository {
}
}
- private void loadSystemConfig() throws IOException {
- try {
- systemConfig.load();
- } catch (ConfigInvalidException e) {
- throw new IOException(MessageFormat.format(JGitText
- .get().systemConfigFileInvalid, systemConfig.getFile()
- .getAbsolutePath(),
- e), e);
- }
- }
-
- private void loadUserConfig() throws IOException {
- try {
- userConfig.load();
- } catch (ConfigInvalidException e) {
- throw new IOException(MessageFormat.format(JGitText
- .get().userConfigFileInvalid, userConfig.getFile()
- .getAbsolutePath(),
- e), e);
- }
- }
-
private void loadRepoConfig() throws IOException {
try {
repoConfig.load();
@@ -398,26 +362,13 @@ public class FileRepository extends Repository {
/** {@inheritDoc} */
@Override
public FileBasedConfig getConfig() {
- if (systemConfig.isOutdated()) {
- try {
- loadSystemConfig();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- if (userConfig.isOutdated()) {
- try {
- loadUserConfig();
- } catch (IOException e) {
- throw new RuntimeException(e);
+ try {
+ SystemReader.getInstance().getUserConfig();
+ if (repoConfig.isOutdated()) {
+ loadRepoConfig();
}
- }
- if (repoConfig.isOutdated()) {
- try {
- loadRepoConfig();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ } catch (IOException | ConfigInvalidException e) {
+ throw new RuntimeException(e);
}
return repoConfig;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java
index 101ce35685..ce9e1b3def 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java
@@ -53,8 +53,7 @@ import java.util.function.Supplier;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
-import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.util.StringUtils;
import org.eclipse.jgit.util.SystemReader;
import org.slf4j.Logger;
@@ -210,14 +209,12 @@ public class HttpConfig {
* to get the configuration values for
*/
public HttpConfig(URIish uri) {
- FileBasedConfig userConfig = SystemReader.getInstance()
- .openUserConfig(null, FS.DETECTED);
+ StoredConfig userConfig = null;
try {
- userConfig.load();
+ userConfig = SystemReader.getInstance().getUserConfig();
} catch (IOException | ConfigInvalidException e) {
// Log it and then work with default values.
- LOG.error(MessageFormat.format(JGitText.get().userConfigFileInvalid,
- userConfig.getFile().getAbsolutePath(), e));
+ LOG.error(e.getMessage(), e);
init(new Config(), uri);
return;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
index 8b41ab0466..0df1b70cb7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -108,11 +108,9 @@ import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.lib.SymbolicRef;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.transport.HttpAuthMethod.Type;
import org.eclipse.jgit.transport.HttpConfig.HttpRedirectMode;
import org.eclipse.jgit.transport.http.HttpConnection;
-import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.HttpSupport;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
@@ -715,15 +713,13 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
}
private void updateSslVerifyUser(boolean value) {
- FileBasedConfig userConfig = SystemReader.getInstance()
- .openUserConfig(null, FS.DETECTED);
+ StoredConfig userConfig = null;
try {
- userConfig.load();
+ userConfig = SystemReader.getInstance().getUserConfig();
updateSslVerify(userConfig, value);
} catch (IOException | ConfigInvalidException e) {
// Log it, but otherwise ignore here.
- LOG.error(MessageFormat.format(JGitText.get().userConfigFileInvalid,
- userConfig.getFile().getAbsolutePath(), e));
+ LOG.error(e.getMessage(), e);
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index 6efd02f479..7d37cfa659 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -510,18 +510,12 @@ public abstract class FS {
private static Optional readFromConfig(
FileStore s) {
- StoredConfig userConfig = SystemReader.getInstance()
- .openUserConfig(null, FS.DETECTED);
+ StoredConfig userConfig;
try {
- userConfig.load();
- } catch (IOException e) {
- LOG.error(MessageFormat.format(JGitText.get().readConfigFailed,
- userConfig), e);
- } catch (ConfigInvalidException e) {
- LOG.error(MessageFormat.format(
- JGitText.get().repositoryConfigFileInvalid,
- userConfig,
- e.getMessage()));
+ userConfig = SystemReader.getInstance().getUserConfig();
+ } catch (IOException | ConfigInvalidException e) {
+ LOG.error(JGitText.get().readFileStoreAttributesFailed, e);
+ return Optional.empty();
}
String key = getConfigKey(s);
Duration resolution = Duration.ofNanos(userConfig.getTimeUnit(
@@ -544,8 +538,13 @@ public abstract class FS {
private static void saveToConfig(FileStore s,
FileStoreAttributes c) {
- StoredConfig userConfig = SystemReader.getInstance()
- .openUserConfig(null, FS.DETECTED);
+ StoredConfig userConfig;
+ try {
+ userConfig = SystemReader.getInstance().getUserConfig();
+ } catch (IOException | ConfigInvalidException e) {
+ LOG.error(JGitText.get().saveFileStoreAttributesFailed, e);
+ return;
+ }
long resolution = c.getFsTimestampResolution().toNanos();
TimeUnit resolutionUnit = getUnit(resolution);
long resolutionValue = resolutionUnit.convert(resolution,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
index 1c42f78577..eda8afb10f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
@@ -42,6 +42,9 @@
*/
package org.eclipse.jgit.util;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
@@ -67,10 +70,9 @@ import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.errors.CommandFailedException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.lib.StoredConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -87,7 +89,7 @@ public class FS_POSIX extends FS {
private volatile boolean supportsUnixNLink = true;
- private volatile AtomicFileCreation supportsAtomicCreateNewFile = AtomicFileCreation.UNDEFINED;
+ private volatile AtomicFileCreation supportsAtomicFileCreation = AtomicFileCreation.UNDEFINED;
private enum AtomicFileCreation {
SUPPORTED, NOT_SUPPORTED, UNDEFINED
@@ -112,42 +114,6 @@ public class FS_POSIX extends FS {
}
}
- private void determineAtomicFileCreationSupport() {
- // @TODO: enhance SystemReader to support this without copying code
- AtomicFileCreation ret = getAtomicFileCreationSupportOption(
- SystemReader.getInstance().openUserConfig(null, this));
- if (ret == AtomicFileCreation.UNDEFINED
- && StringUtils.isEmptyOrNull(SystemReader.getInstance()
- .getenv(Constants.GIT_CONFIG_NOSYSTEM_KEY))) {
- ret = getAtomicFileCreationSupportOption(
- SystemReader.getInstance().openSystemConfig(null, this));
- }
-
- if (ret == AtomicFileCreation.UNDEFINED) {
- ret = AtomicFileCreation.SUPPORTED;
- }
- supportsAtomicCreateNewFile = ret;
- }
-
- private AtomicFileCreation getAtomicFileCreationSupportOption(
- FileBasedConfig config) {
- try {
- config.load();
- String value = config.getString(ConfigConstants.CONFIG_CORE_SECTION,
- null,
- ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION);
- if (value == null) {
- return AtomicFileCreation.UNDEFINED;
- }
- return StringUtils.toBoolean(value)
- ? AtomicFileCreation.SUPPORTED
- : AtomicFileCreation.NOT_SUPPORTED;
- } catch (IOException | ConfigInvalidException e) {
- LOG.error(e.getMessage(), e);
- return AtomicFileCreation.UNDEFINED;
- }
- }
-
/** {@inheritDoc} */
@Override
public FS newInstance() {
@@ -362,10 +328,24 @@ public class FS_POSIX extends FS {
/** {@inheritDoc} */
@Override
public boolean supportsAtomicCreateNewFile() {
- if (supportsAtomicCreateNewFile == AtomicFileCreation.UNDEFINED) {
- determineAtomicFileCreationSupport();
+ if (supportsAtomicFileCreation == AtomicFileCreation.UNDEFINED) {
+ try {
+ StoredConfig config = SystemReader.getInstance().getUserConfig();
+ String value = config.getString(CONFIG_CORE_SECTION, null,
+ CONFIG_KEY_SUPPORTSATOMICFILECREATION);
+ if (value != null) {
+ supportsAtomicFileCreation = StringUtils.toBoolean(value)
+ ? AtomicFileCreation.SUPPORTED
+ : AtomicFileCreation.NOT_SUPPORTED;
+ } else {
+ supportsAtomicFileCreation = AtomicFileCreation.SUPPORTED;
+ }
+ } catch (IOException | ConfigInvalidException e) {
+ LOG.warn(JGitText.get().assumeAtomicCreateNewFile, e);
+ supportsAtomicFileCreation = AtomicFileCreation.SUPPORTED;
+ }
}
- return supportsAtomicCreateNewFile == AtomicFileCreation.SUPPORTED;
+ return supportsAtomicFileCreation == AtomicFileCreation.SUPPORTED;
}
@Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
index b61a6f1914..d554562a75 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
@@ -47,6 +47,7 @@
package org.eclipse.jgit.util;
import java.io.File;
+import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.AccessController;
@@ -56,12 +57,17 @@ import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;
+import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectChecker;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.time.MonotonicClock;
import org.eclipse.jgit.util.time.MonotonicSystemClock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Interface to read values from the system.
@@ -72,6 +78,10 @@ import org.eclipse.jgit.util.time.MonotonicSystemClock;
*
*/
public abstract class SystemReader {
+
+ private final static Logger LOG = LoggerFactory
+ .getLogger(SystemReader.class);
+
private static final SystemReader DEFAULT;
private static Boolean isMacOS;
@@ -87,6 +97,10 @@ public abstract class SystemReader {
private static class Default extends SystemReader {
private volatile String hostname;
+ private volatile FileBasedConfig systemConfig;
+
+ private volatile FileBasedConfig userConfig;
+
@Override
public String getenv(String variable) {
return System.getenv(variable);
@@ -99,28 +113,69 @@ public abstract class SystemReader {
@Override
public FileBasedConfig openSystemConfig(Config parent, FS fs) {
- File configFile = fs.getGitSystemConfig();
- if (configFile == null) {
- return new FileBasedConfig(null, fs) {
- @Override
- public void load() {
- // empty, do not load
- }
-
- @Override
- public boolean isOutdated() {
- // regular class would bomb here
- return false;
- }
- };
+ if (systemConfig == null) {
+ systemConfig = createSystemConfig(parent, fs);
}
- return new FileBasedConfig(parent, configFile, fs);
+ return systemConfig;
+ }
+
+ protected FileBasedConfig createSystemConfig(Config parent, FS fs) {
+ if (StringUtils.isEmptyOrNull(getenv(Constants.GIT_CONFIG_NOSYSTEM_KEY))) {
+ File configFile = fs.getGitSystemConfig();
+ if (configFile != null) {
+ return new FileBasedConfig(parent, configFile, fs);
+ }
+ }
+ return new FileBasedConfig(null, fs) {
+ @Override
+ public void load() {
+ // empty, do not load
+ }
+
+ @Override
+ public boolean isOutdated() {
+ // regular class would bomb here
+ return false;
+ }
+ };
}
@Override
public FileBasedConfig openUserConfig(Config parent, FS fs) {
- final File home = fs.userHome();
- return new FileBasedConfig(parent, new File(home, ".gitconfig"), fs); //$NON-NLS-1$
+ if (userConfig == null) {
+ File home = fs.userHome();
+ userConfig = new FileBasedConfig(parent,
+ new File(home, ".gitconfig"), fs); //$NON-NLS-1$
+ }
+ return userConfig;
+ }
+
+ @Override
+ public StoredConfig getSystemConfig()
+ throws IOException, ConfigInvalidException {
+ if (systemConfig == null) {
+ systemConfig = createSystemConfig(null, FS.DETECTED);
+ }
+ if (systemConfig.isOutdated()) {
+ LOG.debug("loading system config {}", systemConfig); //$NON-NLS-1$
+ systemConfig.load();
+ }
+ return systemConfig;
+ }
+
+ @Override
+ public StoredConfig getUserConfig()
+ throws IOException, ConfigInvalidException {
+ if (userConfig == null) {
+ userConfig = openUserConfig(getSystemConfig(), FS.DETECTED);
+ } else {
+ getSystemConfig();
+ }
+ if (userConfig.isOutdated()) {
+ LOG.debug("loading user config {}", userConfig); //$NON-NLS-1$
+ userConfig.load();
+ }
+ return userConfig;
}
@Override
@@ -149,7 +204,7 @@ public abstract class SystemReader {
}
}
- private static SystemReader INSTANCE = DEFAULT;
+ private static volatile SystemReader INSTANCE = DEFAULT;
/**
* Get the current SystemReader instance
@@ -225,7 +280,10 @@ public abstract class SystemReader {
public abstract String getProperty(String key);
/**
- * Open the git configuration found in the user home
+ * Open the git configuration found in the user home. Use
+ * {@link #getUserConfig()} to get the current git configuration in the user
+ * home since it manages automatic reloading when the gitconfig file was
+ * modified and avoids unnecessary reloads.
*
* @param parent
* a config with values not found directly in the returned config
@@ -237,7 +295,10 @@ public abstract class SystemReader {
public abstract FileBasedConfig openUserConfig(Config parent, FS fs);
/**
- * Open the gitconfig configuration found in the system-wide "etc" directory
+ * Open the gitconfig configuration found in the system-wide "etc"
+ * directory. Use {@link #getSystemConfig()} to get the current system-wide
+ * git configuration since it manages automatic reloading when the gitconfig
+ * file was modified and avoids unnecessary reloads.
*
* @param parent
* a config with values not found directly in the returned
@@ -250,6 +311,38 @@ public abstract class SystemReader {
*/
public abstract FileBasedConfig openSystemConfig(Config parent, FS fs);
+ /**
+ * Get the git configuration found in the user home. The configuration will
+ * be reloaded automatically if the configuration file was modified. Also
+ * reloads the system config if the system config file was modified. If the
+ * configuration file wasn't modified returns the cached configuration.
+ *
+ * @return the git configuration found in the user home
+ * @throws ConfigInvalidException
+ * if configuration is invalid
+ * @throws IOException
+ * if something went wrong when reading files
+ * @since 5.1.9
+ */
+ public abstract StoredConfig getUserConfig()
+ throws IOException, ConfigInvalidException;
+
+ /**
+ * Get the gitconfig configuration found in the system-wide "etc" directory.
+ * The configuration will be reloaded automatically if the configuration
+ * file was modified otherwise returns the cached system level config.
+ *
+ * @return the gitconfig configuration found in the system-wide "etc"
+ * directory
+ * @throws ConfigInvalidException
+ * if configuration is invalid
+ * @throws IOException
+ * if something went wrong when reading files
+ * @since 5.1.9
+ */
+ public abstract StoredConfig getSystemConfig()
+ throws IOException, ConfigInvalidException;
+
/**
* Get the current system time
*
--
cgit v1.2.3
From 31356f5d181ea1a1c43b44d9dfbe9e8e81aed984 Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Sat, 17 Aug 2019 00:16:32 +0200
Subject: FileUtils#lastModifiedInstant should not log error if path doesn't
exist
Change-Id: Id8447735beb24becb41612d3d29d5351f8273d22
Signed-off-by: Matthias Sohn
---
org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
index 80f188cb2c..9f7d9a236e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -55,6 +55,7 @@ import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.LinkOption;
+import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
@@ -677,9 +678,14 @@ public class FileUtils {
try {
return Files.getLastModifiedTime(path, LinkOption.NOFOLLOW_LINKS)
.toInstant();
+ } catch (NoSuchFileException e) {
+ LOG.debug(
+ "Cannot read lastModifiedInstant since path {} does not exist", //$NON-NLS-1$
+ path);
+ return Instant.EPOCH;
} catch (IOException e) {
LOG.error(MessageFormat
- .format(JGitText.get().readLastModifiedFailed, path));
+ .format(JGitText.get().readLastModifiedFailed, path), e);
return Instant.ofEpochMilli(path.toFile().lastModified());
}
}
--
cgit v1.2.3
From a4216e5382026ff9956af82322c7c5af24e0f245 Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Sat, 17 Aug 2019 00:18:50 +0200
Subject: Fix NPE in ObjectIdOwnerMap#get
Change-Id: I3812961a27ac410d610ef50c73a28f21bb05ae79
Signed-off-by: Matthias Sohn
---
org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java | 3 +++
1 file changed, 3 insertions(+)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java
index 9df593375d..74c712c46c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java
@@ -135,6 +135,9 @@ public class ObjectIdOwnerMap
*/
@SuppressWarnings("unchecked")
public V get(AnyObjectId toFind) {
+ if (toFind == null) {
+ return null;
+ }
int h = toFind.w1;
V obj = directory[h & mask][h >>> SEGMENT_SHIFT];
for (; obj != null; obj = (V) obj.next)
--
cgit v1.2.3
From 86a567f6152315f5d55309c7119885d0fa3476ce Mon Sep 17 00:00:00 2001
From: Matthias Sohn
Date: Sat, 17 Aug 2019 00:20:01 +0200
Subject: Fix NPE in RebaseTodoFile#parseComments
Change-Id: I5487f3c2609eaf2a0ddf71ebb2f6c9701fb7600c
Signed-off-by: Matthias Sohn
---
.../src/org/eclipse/jgit/lib/RebaseTodoFile.java | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
(limited to 'org.eclipse.jgit')
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java
index 06b4b227c8..0d31851836 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java
@@ -137,11 +137,13 @@ public class RebaseTodoFile {
if (skip != -1) {
// try to parse the line as non-comment
line = parseLine(buf, skip, lineEnd);
- // successfully parsed as non-comment line
- // mark this line as a comment explicitly
- line.setAction(Action.COMMENT);
- // use the read line as comment string
- line.setComment(commentString);
+ if (line != null) {
+ // successfully parsed as non-comment line
+ // mark this line as a comment explicitly
+ line.setAction(Action.COMMENT);
+ // use the read line as comment string
+ line.setComment(commentString);
+ }
}
} catch (Exception e) {
// parsing as non-comment line failed
--
cgit v1.2.3