repository = new TestRepository<>(
+ repo)) {
+ RevCommit commit = repository.branch("/refs/ref1" + repoName)
+ .commit().add("blob1", "blob1" + repoName).create();
+ repository.branch("/refs/ref2" + repoName).commit()
+ .add("blob2", "blob2" + repoName).parent(commit).create();
+ }
+ new DfsGarbageCollector(repo).pack(null);
+ return repo;
+ }
+
+ private void asyncRun(Callable> call) {
pool.execute(() -> {
try {
call.call();
@@ -203,4 +325,11 @@ private void asyncRun(ExecutorService pool, Callable> call) {
}
});
}
+
+ private void waitForExecutorPoolTermination() throws Exception {
+ pool.shutdown();
+ pool.awaitTermination(500, MILLISECONDS);
+ assertTrue("Threads did not complete, likely due to a deadlock.",
+ pool.isTerminated());
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
index fe3c1db50..9ee54d5b6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
@@ -55,6 +55,7 @@
import org.eclipse.jgit.junit.MockSystemReader;
import org.eclipse.jgit.merge.MergeConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SystemReader;
@@ -1471,14 +1472,17 @@ public void testCommitTemplateEmptyConfig()
// no values defined nowhere
Config config = new Config(null);
assertNull(config.get(CommitConfig.KEY).getCommitTemplatePath());
- assertNull(config.get(CommitConfig.KEY).getCommitTemplateContent());
+ assertNull(config.get(CommitConfig.KEY)
+ .getCommitTemplateContent(null));
}
@Test
public void testCommitTemplateConfig()
throws ConfigInvalidException, IOException {
+ File workTree = tmp.newFolder("dummy-worktree");
File tempFile = tmp.newFile("testCommitTemplate-");
+ Repository repo = FileRepositoryBuilder.create(workTree);
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
String expectedTemplatePath = tempFile.getPath();
@@ -1492,7 +1496,32 @@ public void testCommitTemplateConfig()
.getCommitEncoding();
assertEquals(expectedTemplatePath, templatePath);
assertEquals(templateContent,
- config.get(CommitConfig.KEY).getCommitTemplateContent());
+ config.get(CommitConfig.KEY).getCommitTemplateContent(repo));
+ assertNull("no commitEncoding has been set so it must be null",
+ commitEncoding);
+ }
+
+ @Test
+ public void testCommitTemplateConfigRelativePath()
+ throws ConfigInvalidException, IOException {
+
+ File workTree = tmp.newFolder("dummy-worktree");
+ File tempFile = tmp.newFile("testCommitTemplate-");
+ String templateContent = "content of the template";
+ JGitTestUtil.write(tempFile, templateContent);
+ String expectedTemplatePath = "../" + tempFile.getName();
+
+ Config config = parse(
+ "[commit]\n\ttemplate = " + expectedTemplatePath + "\n");
+
+ String templatePath = config.get(CommitConfig.KEY)
+ .getCommitTemplatePath();
+ String commitEncoding = config.get(CommitConfig.KEY)
+ .getCommitEncoding();
+ assertEquals(expectedTemplatePath, templatePath);
+ assertEquals(templateContent, config.get(CommitConfig.KEY)
+ .getCommitTemplateContent(
+ new RepositoryBuilder().setWorkTree(workTree).build()));
assertNull("no commitEncoding has been set so it must be null",
commitEncoding);
}
@@ -1501,6 +1530,8 @@ public void testCommitTemplateConfig()
public void testCommitTemplateEncoding()
throws ConfigInvalidException, IOException {
Config config = new Config(null);
+ File workTree = tmp.newFolder("dummy-worktree");
+ Repository repo = FileRepositoryBuilder.create(workTree);
File tempFile = tmp.newFile("testCommitTemplate-");
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
@@ -1508,7 +1539,7 @@ public void testCommitTemplateEncoding()
config = parse("[i18n]\n\tcommitEncoding = utf-8\n"
+ "[commit]\n\ttemplate = " + expectedTemplatePath + "\n");
assertEquals(templateContent,
- config.get(CommitConfig.KEY).getCommitTemplateContent());
+ config.get(CommitConfig.KEY).getCommitTemplateContent(repo));
String commitEncoding = config.get(CommitConfig.KEY)
.getCommitEncoding();
assertEquals("commitEncoding has been set to utf-8 it must be utf-8",
@@ -1520,6 +1551,8 @@ public void testCommitTemplatePathInHomeDirecory()
throws ConfigInvalidException, IOException {
Config config = new Config(null);
File tempFile = tmp.newFile("testCommitTemplate-");
+ File workTree = tmp.newFolder("dummy-worktree");
+ Repository repo = FileRepositoryBuilder.create(workTree);
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
// proper evaluation of the ~/ directory
@@ -1535,35 +1568,39 @@ public void testCommitTemplatePathInHomeDirecory()
.getCommitTemplatePath();
assertEquals(expectedTemplatePath, templatePath);
assertEquals(templateContent,
- config.get(CommitConfig.KEY).getCommitTemplateContent());
+ config.get(CommitConfig.KEY).getCommitTemplateContent(repo));
}
@Test(expected = ConfigInvalidException.class)
public void testCommitTemplateWithInvalidEncoding()
throws ConfigInvalidException, IOException {
Config config = new Config(null);
+ File workTree = tmp.newFolder("dummy-worktree");
File tempFile = tmp.newFile("testCommitTemplate-");
+ Repository repo = FileRepositoryBuilder.create(workTree);
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
config = parse("[i18n]\n\tcommitEncoding = invalidEcoding\n"
+ "[commit]\n\ttemplate = " + tempFile.getPath() + "\n");
- config.get(CommitConfig.KEY).getCommitTemplateContent();
+ config.get(CommitConfig.KEY).getCommitTemplateContent(repo);
}
@Test(expected = FileNotFoundException.class)
public void testCommitTemplateWithInvalidPath()
throws ConfigInvalidException, IOException {
Config config = new Config(null);
+ File workTree = tmp.newFolder("dummy-worktree");
File tempFile = tmp.newFile("testCommitTemplate-");
+ Repository repo = FileRepositoryBuilder.create(workTree);
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
// commit message encoding
- String expectedTemplatePath = "nonExistingTemplate";
+ String expectedTemplatePath = "/nonExistingTemplate";
config = parse("[commit]\n\ttemplate = " + expectedTemplatePath + "\n");
String templatePath = config.get(CommitConfig.KEY)
.getCommitTemplatePath();
assertEquals(expectedTemplatePath, templatePath);
- config.get(CommitConfig.KEY).getCommitTemplateContent();
+ config.get(CommitConfig.KEY).getCommitTemplateContent(repo);
}
private static void assertValueRoundTrip(String value)
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
index f4bbb4c9f..1c5a52180 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
@@ -34,7 +34,6 @@
import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
-import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.internal.storage.pack.CachedPack;
import org.eclipse.jgit.internal.storage.pack.CachedPackUriProvider;
import org.eclipse.jgit.junit.TestRepository;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java
index b69bb8f3e..ca5370e91 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java
@@ -71,12 +71,12 @@ class Candidate {
/**
* Score assigned to the rename to this candidate.
*
- * Consider the history "A<-B<-C". If the result file S in C was renamed to
- * R in B, the rename score for this rename will be held in this field by
- * the candidate object for B. By storing the score with B, the application
- * can see what the rename score was as it makes the transition from C/S to
- * B/R. This may seem backwards since it was C that performed the rename,
- * but the application doesn't learn about path R until B.
+ * Consider the history "A<-B<-C". If the result file S in C was
+ * renamed to R in B, the rename score for this rename will be held in this
+ * field by the candidate object for B. By storing the score with B, the
+ * application can see what the rename score was as it makes the transition
+ * from C/S to B/R. This may seem backwards since it was C that performed
+ * the rename, but the application doesn't learn about path R until B.
*/
int renameScore;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java
index e226dbf3c..2236eecbf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java
@@ -27,7 +27,7 @@ class Region {
/** First position in the {@link Candidate} that owns this Region. */
int sourceStart;
- /** Length of the region, always >= 1. */
+ /** Length of the region, always >= 1. */
int length;
Region(int rs, int ss, int len) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
index ec21954aa..49da95c9a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
@@ -29,12 +29,12 @@
import java.util.Collections;
import java.util.List;
+import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.AmbiguousObjectException;
import org.eclipse.jgit.errors.BinaryBlobException;
-import org.eclipse.jgit.errors.CancelledException;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
@@ -578,7 +578,7 @@ private List detectRenames(List files)
renameDetector.addAll(files);
try {
return renameDetector.compute(reader, progressMonitor);
- } catch (CancelledException e) {
+ } catch (CanceledException e) {
// TODO: consider propagating once bug 536323 is tackled
// (making DiffEntry.scan() and DiffFormatter.scan() and
// format() cancellable).
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
index 225921ecc..c33f53add 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
@@ -23,9 +23,9 @@
import java.util.HashMap;
import java.util.List;
+import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.diff.SimilarityIndex.TableFullException;
-import org.eclipse.jgit.errors.CancelledException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.FileMode;
@@ -336,6 +336,7 @@ public void add(DiffEntry entry) {
* Detect renames in the current file set.
*
* This convenience function runs without a progress monitor.
+ *
*
* @return an unmodifiable list of {@link org.eclipse.jgit.diff.DiffEntry}s
* representing all files that have been changed.
@@ -343,7 +344,12 @@ public void add(DiffEntry entry) {
* file contents cannot be read from the repository.
*/
public List compute() throws IOException {
- return compute(NullProgressMonitor.INSTANCE);
+ try {
+ return compute(NullProgressMonitor.INSTANCE);
+ } catch (CanceledException e) {
+ // Won't happen with a NullProgressMonitor
+ return Collections.emptyList();
+ }
}
/**
@@ -355,13 +361,11 @@ public List compute() throws IOException {
* representing all files that have been changed.
* @throws java.io.IOException
* file contents cannot be read from the repository.
- * @throws CancelledException
+ * @throws CanceledException
* if rename detection was cancelled
*/
- // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException in next major
- // version
public List compute(ProgressMonitor pm)
- throws IOException, CancelledException {
+ throws IOException, CanceledException {
if (!done) {
try {
return compute(objectReader, pm);
@@ -383,13 +387,11 @@ public List compute(ProgressMonitor pm)
* representing all files that have been changed.
* @throws java.io.IOException
* file contents cannot be read from the repository.
- * @throws CancelledException
+ * @throws CanceledException
* if rename detection was cancelled
*/
- // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException in next major
- // version
public List compute(ObjectReader reader, ProgressMonitor pm)
- throws IOException, CancelledException {
+ throws IOException, CanceledException {
final ContentSource cs = ContentSource.create(reader);
return compute(new ContentSource.Pair(cs, cs), pm);
}
@@ -405,13 +407,11 @@ public List compute(ObjectReader reader, ProgressMonitor pm)
* representing all files that have been changed.
* @throws java.io.IOException
* file contents cannot be read from the repository.
- * @throws CancelledException
+ * @throws CanceledException
* if rename detection was cancelled
*/
- // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException in next major
- // version
public List compute(ContentSource.Pair reader, ProgressMonitor pm)
- throws IOException, CancelledException {
+ throws IOException, CanceledException {
if (!done) {
done = true;
@@ -451,15 +451,15 @@ public void reset() {
done = false;
}
- private void advanceOrCancel(ProgressMonitor pm) throws CancelledException {
+ private void advanceOrCancel(ProgressMonitor pm) throws CanceledException {
if (pm.isCancelled()) {
- throw new CancelledException(JGitText.get().renameCancelled);
+ throw new CanceledException(JGitText.get().renameCancelled);
}
pm.update(1);
}
private void breakModifies(ContentSource.Pair reader, ProgressMonitor pm)
- throws IOException, CancelledException {
+ throws IOException, CanceledException {
ArrayList newEntries = new ArrayList<>(entries.size());
pm.beginTask(JGitText.get().renamesBreakingModifies, entries.size());
@@ -486,7 +486,7 @@ private void breakModifies(ContentSource.Pair reader, ProgressMonitor pm)
entries = newEntries;
}
- private void rejoinModifies(ProgressMonitor pm) throws CancelledException {
+ private void rejoinModifies(ProgressMonitor pm) throws CanceledException {
HashMap nameMap = new HashMap<>();
ArrayList newAdded = new ArrayList<>(added.size());
@@ -541,7 +541,7 @@ private int calculateModifyScore(ContentSource.Pair reader, DiffEntry d)
private void findContentRenames(ContentSource.Pair reader,
ProgressMonitor pm)
- throws IOException, CancelledException {
+ throws IOException, CanceledException {
int cnt = Math.max(added.size(), deleted.size());
if (getRenameLimit() == 0 || cnt <= getRenameLimit()) {
SimilarityRenameDetector d;
@@ -562,7 +562,7 @@ private void findContentRenames(ContentSource.Pair reader,
@SuppressWarnings("unchecked")
private void findExactRenames(ProgressMonitor pm)
- throws CancelledException {
+ throws CanceledException {
pm.beginTask(JGitText.get().renamesFindingExact, //
added.size() + added.size() + deleted.size()
+ added.size() * deleted.size());
@@ -651,7 +651,7 @@ private void findExactRenames(ProgressMonitor pm)
matrix[mNext] = SimilarityRenameDetector.encode(score, delIdx, addIdx);
mNext++;
if (pm.isCancelled()) {
- throw new CancelledException(
+ throw new CanceledException(
JGitText.get().renameCancelled);
}
}
@@ -744,7 +744,7 @@ private static DiffEntry bestPathMatch(DiffEntry src, List list) {
@SuppressWarnings("unchecked")
private HashMap populateMap(
List diffEntries, ProgressMonitor pm)
- throws CancelledException {
+ throws CanceledException {
HashMap map = new HashMap<>();
for (DiffEntry de : diffEntries) {
Object old = map.put(id(de), de);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
index 5871b4aee..9ac94895b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
@@ -20,9 +20,9 @@
import java.util.BitSet;
import java.util.List;
+import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.diff.SimilarityIndex.TableFullException;
-import org.eclipse.jgit.errors.CancelledException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.NullProgressMonitor;
@@ -115,7 +115,7 @@ void setSkipBinaryFiles(boolean value) {
skipBinaryFiles = value;
}
- void compute(ProgressMonitor pm) throws IOException, CancelledException {
+ void compute(ProgressMonitor pm) throws IOException, CanceledException {
if (pm == null)
pm = NullProgressMonitor.INSTANCE;
@@ -130,9 +130,7 @@ void compute(ProgressMonitor pm) throws IOException, CancelledException {
//
for (--mNext; mNext >= 0; mNext--) {
if (pm.isCancelled()) {
- // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException
- // in next major version
- throw new CancelledException(JGitText.get().renameCancelled);
+ throw new CanceledException(JGitText.get().renameCancelled);
}
long ent = matrix[mNext];
int sIdx = srcFile(ent);
@@ -202,7 +200,7 @@ private static List compactDstList(List in) {
}
private int buildMatrix(ProgressMonitor pm)
- throws IOException, CancelledException {
+ throws IOException, CanceledException {
// Allocate for the worst-case scenario where every pair has a
// score that we need to consider. We might not need that many.
//
@@ -228,10 +226,7 @@ private int buildMatrix(ProgressMonitor pm)
for (int dstIdx = 0; dstIdx < dsts.size(); dstIdx++) {
if (pm.isCancelled()) {
- // TODO(ms): use
- // org.eclipse.jgit.api.errors.CanceledException in next
- // major version
- throw new CancelledException(
+ throw new CanceledException(
JGitText.get().renameCancelled);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
index 07162db4c..e0c1e9391 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
@@ -280,12 +280,12 @@ public String getPathString() {
* number of bytes of cache[cacheIdx].path
that
* matches this tree's path. The value at array position
* cache[cacheIdx].path[pathOff-1]
is always '/' if
- * pathOff
is > 0.
+ * pathOff
is > 0.
* @param ow
* the writer to use when serializing to the store.
* @return identity of this tree.
* @throws UnmergedPathException
- * one or more paths contain higher-order stages (stage > 0),
+ * one or more paths contain higher-order stages (stage > 0),
* which cannot be stored in a tree object.
* @throws IOException
* an unexpected error occurred writing to the object store.
@@ -401,7 +401,7 @@ final boolean contains(byte[] a, int aOff, int aLen) {
* number of bytes of cache[cacheIdx].path
that
* matches this tree's path. The value at array position
* cache[cacheIdx].path[pathOff-1]
is always '/' if
- * pathOff
is > 0.
+ * pathOff
is > 0.
*/
void validate(final DirCacheEntry[] cache, final int cCnt, int cIdx,
final int pathOff) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/StoredObjectRepresentationNotAvailableException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/StoredObjectRepresentationNotAvailableException.java
index 0708123e9..de210b01c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/StoredObjectRepresentationNotAvailableException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/StoredObjectRepresentationNotAvailableException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, Google Inc. and others
+ * Copyright (C) 2010, 2021 Google Inc. and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -7,29 +7,23 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-
package org.eclipse.jgit.errors;
-import org.eclipse.jgit.internal.storage.pack.ObjectToPack;
-
/**
* A previously selected representation is no longer available.
*/
-public class StoredObjectRepresentationNotAvailableException extends Exception { //TODO remove unused ObjectToPack in 5.0
+public class StoredObjectRepresentationNotAvailableException extends Exception {
+
private static final long serialVersionUID = 1L;
/**
- * Construct an error for an object.
+ * Creates a new instance.
*
- * @param otp
- * the object whose current representation is no longer present.
* @param cause
- * cause
- * @since 4.10
+ * {@link Throwable} that caused this exception
+ * @since 6.0
*/
- public StoredObjectRepresentationNotAvailableException(ObjectToPack otp,
- Throwable cause) {
+ public StoredObjectRepresentationNotAvailableException(Throwable cause) {
super(cause);
- // Do nothing.
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
index 095927f3c..e0a822479 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -578,10 +578,10 @@ public RevCommit call() throws GitAPIException {
DirCache index = DirCache.newInCore();
ObjectInserter inserter = repo.newObjectInserter();
+
try (RevWalk rw = new RevWalk(repo)) {
prepareIndex(renamedProjects, index, inserter);
ObjectId treeId = index.writeTree(inserter);
-
long prevDelay = 0;
for (int i = 0; i < LOCK_FAILURE_MAX_RETRIES - 1; i++) {
try {
@@ -597,7 +597,7 @@ public RevCommit call() throws GitAPIException {
}
// In the last try, just propagate the exceptions
return commitTreeOnCurrentTip(inserter, rw, treeId);
- } catch (GitAPIException | IOException | InterruptedException e) {
+ } catch (IOException | InterruptedException e) {
throw new ManifestErrorException(e);
}
}
@@ -609,12 +609,11 @@ public RevCommit call() throws GitAPIException {
}
return git.commit().setMessage(RepoText.get().repoCommitMessage)
.call();
- } catch (GitAPIException | IOException e) {
+ } catch (IOException e) {
throw new ManifestErrorException(e);
}
}
-
private void prepareIndex(List projects, DirCache index,
ObjectInserter inserter) throws IOException, GitAPIException {
Config cfg = new Config();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
index e87bfe24e..54c527c03 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
@@ -104,9 +104,10 @@ public static DfsBlockCache getInstance() {
private final ReentrantLock[] loadLocks;
/**
- * A separate pool of locks to prevent concurrent loads for same index or bitmap from PackFile.
+ * A separate pool of locks per pack extension to prevent concurrent loads
+ * for same index or bitmap from PackFile.
*/
- private final ReentrantLock[] refLocks;
+ private final ReentrantLock[][] refLocks;
/** Maximum number of bytes the cache should hold. */
private final long maxBytes;
@@ -173,13 +174,16 @@ private DfsBlockCache(DfsBlockCacheConfig cfg) {
}
table = new AtomicReferenceArray<>(tableSize);
- loadLocks = new ReentrantLock[cfg.getConcurrencyLevel()];
+ int concurrencyLevel = cfg.getConcurrencyLevel();
+ loadLocks = new ReentrantLock[concurrencyLevel];
for (int i = 0; i < loadLocks.length; i++) {
loadLocks[i] = new ReentrantLock(true /* fair */);
}
- refLocks = new ReentrantLock[cfg.getConcurrencyLevel()];
- for (int i = 0; i < refLocks.length; i++) {
- refLocks[i] = new ReentrantLock(true /* fair */);
+ refLocks = new ReentrantLock[PackExt.values().length][concurrencyLevel];
+ for (int i = 0; i < PackExt.values().length; i++) {
+ for (int j = 0; j < concurrencyLevel; ++j) {
+ refLocks[i][j] = new ReentrantLock(true /* fair */);
+ }
}
maxBytes = cfg.getBlockLimit();
@@ -636,7 +640,8 @@ private ReentrantLock lockFor(DfsStreamKey key, long position) {
}
private ReentrantLock lockForRef(DfsStreamKey key) {
- return refLocks[(key.hash >>> 1) % refLocks.length];
+ int slot = (key.hash >>> 1) % refLocks[key.packExtPos].length;
+ return refLocks[key.packExtPos][slot];
}
private static AtomicLong[] newCounters() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
index b5bf03fcb..bb76df1d5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
@@ -415,8 +415,7 @@ void copyAsIs(PackOutputStream out, DfsObjectToPack src,
try {
readFully(src.offset, buf, 0, 20, ctx);
} catch (IOException ioError) {
- throw new StoredObjectRepresentationNotAvailableException(src,
- ioError);
+ throw new StoredObjectRepresentationNotAvailableException(ioError);
}
int c = buf[0] & 0xff;
final int typeCode = (c >> 4) & 7;
@@ -537,12 +536,11 @@ void copyAsIs(PackOutputStream out, DfsObjectToPack src,
Long.valueOf(src.offset), getFileName()),
dataFormat);
- throw new StoredObjectRepresentationNotAvailableException(src,
+ throw new StoredObjectRepresentationNotAvailableException(
corruptObject);
} catch (IOException ioError) {
- throw new StoredObjectRepresentationNotAvailableException(src,
- ioError);
+ throw new StoredObjectRepresentationNotAvailableException(ioError);
}
if (quickCopy != null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java
index 29d11104d..d8e191c4e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java
@@ -23,10 +23,10 @@
import java.util.zip.Deflater;
import org.eclipse.jgit.internal.storage.file.PackIndex;
-import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ProgressMonitor;
+import org.eclipse.jgit.transport.PackLock;
import org.eclipse.jgit.transport.PackParser;
import org.eclipse.jgit.transport.PackedObjectInfo;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
index 40c075ec5..93c620159 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
@@ -1530,7 +1530,8 @@ private void addRepackAllOption() {
}
/**
- * @return {@code true} if number of packs > gc.autopacklimit (default 50)
+ * @return {@code true} if number of packs > gc.autopacklimit (default
+ * 50)
*/
boolean tooManyPacks() {
int autopacklimit = repo.getConfig().getInt(
@@ -1549,7 +1550,8 @@ boolean tooManyPacks() {
* Quickly estimate number of loose objects, SHA1 is distributed evenly so
* counting objects in one directory (bucket 17) is sufficient
*
- * @return {@code true} if number of loose objects > gc.auto (default 6700)
+ * @return {@code true} if number of loose objects > gc.auto (default
+ * 6700)
*/
boolean tooManyLooseObjects() {
int auto = getLooseObjectLimit();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java
index dba8ccd99..1c23ff20c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java
@@ -34,6 +34,7 @@
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.storage.pack.PackConfig;
+import org.eclipse.jgit.transport.PackLock;
import org.eclipse.jgit.transport.PackParser;
import org.eclipse.jgit.transport.PackedObjectInfo;
import org.eclipse.jgit.util.FileUtils;
@@ -431,7 +432,7 @@ private PackLock renameAndOpenPack(String lockMessage)
File packDir = new File(db.getDirectory(), "pack"); //$NON-NLS-1$
PackFile finalPack = new PackFile(packDir, id, PackExt.PACK);
PackFile finalIdx = finalPack.create(PackExt.INDEX);
- final PackLock keep = new PackLock(finalPack, db.getFS());
+ final PackLockImpl keep = new PackLockImpl(finalPack, db.getFS());
if (!packDir.exists() && !packDir.mkdir() && !packDir.exists()) {
// The objects/pack directory isn't present, and we are unable
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
index 5efd4c5bf..289c732f4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
@@ -521,12 +521,11 @@ private void copyAsIs2(PackOutputStream out, LocalObjectToPack src,
Long.valueOf(src.offset), getPackFile()),
dataFormat);
- throw new StoredObjectRepresentationNotAvailableException(src,
+ throw new StoredObjectRepresentationNotAvailableException(
corruptObject);
} catch (IOException ioError) {
- throw new StoredObjectRepresentationNotAvailableException(src,
- ioError);
+ throw new StoredObjectRepresentationNotAvailableException(ioError);
}
if (quickCopy != null) {
@@ -611,7 +610,7 @@ private synchronized void beginCopyAsIs(ObjectToPack otp)
try {
doOpen();
} catch (IOException thisPackNotValid) {
- throw new StoredObjectRepresentationNotAvailableException(otp,
+ throw new StoredObjectRepresentationNotAvailableException(
thisPackNotValid);
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLock.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLockImpl.java
similarity index 88%
rename from org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLock.java
rename to org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLockImpl.java
index 482b143e3..7cc5f5054 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLock.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLockImpl.java
@@ -14,6 +14,7 @@
import java.io.IOException;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.transport.PackLock;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
@@ -21,7 +22,7 @@
* Keeps track of a {@link org.eclipse.jgit.internal.storage.file.Pack}'s
* associated .keep
file.
*/
-public class PackLock {
+public class PackLockImpl implements PackLock {
private final File keepFile;
/**
@@ -32,7 +33,7 @@ public class PackLock {
* @param fs
* the filesystem abstraction used by the repository.
*/
- public PackLock(File packFile, FS fs) {
+ public PackLockImpl(File packFile, FS fs) {
final File p = packFile.getParentFile();
final String n = packFile.getName();
keepFile = new File(p, n.substring(0, n.length() - 5) + ".keep"); //$NON-NLS-1$
@@ -59,12 +60,7 @@ public boolean lock(String msg) throws IOException {
return lf.commit();
}
- /**
- * Remove the .keep
file that holds this pack in place.
- *
- * @throws java.io.IOException
- * if deletion of .keep file failed
- */
+ @Override
public void unlock() throws IOException {
FileUtils.delete(keepFile);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
index 2dbb7859b..648d4a182 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
@@ -142,7 +142,7 @@ public OpenSshConfigFile(@NonNull File home, @NonNull File config,
* real host name, or it may just be a "Host" block in the
* configuration file.
* @param port
- * the user supplied; <= 0 if none
+ * the user supplied; <= 0 if none
* @param userName
* the user supplied, may be {@code null} or empty if none given
* @return the configuration for the requested name.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
index e4e7cd6e0..22e1f9818 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
@@ -18,6 +18,8 @@
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
import java.text.MessageFormat;
+
+import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.JGitText;
@@ -77,6 +79,9 @@ public String getCommitEncoding() {
* {@code commit.template}. If no {@code i18n.commitEncoding} is specified,
* UTF-8 fallback is used.
*
+ * @param repository
+ * to resolve relative path in local git repo config
+ *
* @return content of the commit template or {@code null} if not present.
* @throws IOException
* if the template file can not be read
@@ -84,9 +89,10 @@ public String getCommitEncoding() {
* if the template file does not exists
* @throws ConfigInvalidException
* if a {@code commitEncoding} is specified and is invalid
+ * @since 6.0
*/
@Nullable
- public String getCommitTemplateContent()
+ public String getCommitTemplateContent(@NonNull Repository repository)
throws FileNotFoundException, IOException, ConfigInvalidException {
if (commitTemplatePath == null) {
@@ -94,11 +100,17 @@ public String getCommitTemplateContent()
}
File commitTemplateFile;
+ FS fileSystem = repository.getFS();
if (commitTemplatePath.startsWith("~/")) { //$NON-NLS-1$
- commitTemplateFile = FS.DETECTED.resolve(FS.DETECTED.userHome(),
+ commitTemplateFile = fileSystem.resolve(fileSystem.userHome(),
commitTemplatePath.substring(2));
} else {
- commitTemplateFile = FS.DETECTED.resolve(null, commitTemplatePath);
+ commitTemplateFile = fileSystem.resolve(null, commitTemplatePath);
+ }
+ if (!commitTemplateFile.isAbsolute()) {
+ commitTemplateFile = fileSystem.resolve(
+ repository.getWorkTree().getAbsoluteFile(),
+ commitTemplatePath);
}
Charset commitMessageEncoding = getEncoding();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
index d344deac2..f48e1e68c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
@@ -28,7 +28,6 @@
import org.eclipse.jgit.errors.RemoteRepositoryException;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.MutableObjectId;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java
index 47d156b66..f04e573fe 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java
@@ -35,7 +35,6 @@
import org.eclipse.jgit.errors.PackProtocolException;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java
index d06ef65c7..9dc062066 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java
@@ -18,7 +18,6 @@
import java.util.Set;
import org.eclipse.jgit.errors.TransportException;
-import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
index 34bad6e02..7d7b3ee0a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
@@ -37,7 +37,6 @@
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.file.LockFile;
-import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.BatchingProgressMonitor;
import org.eclipse.jgit.lib.Constants;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackLock.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackLock.java
new file mode 100644
index 000000000..bf2140759
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackLock.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Thomas Wolf and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.transport;
+
+import java.io.IOException;
+
+/**
+ * A {@code PackLock} describes a {@code .keep} file that holds a pack in place.
+ * If {@link PackParser#parse(org.eclipse.jgit.lib.ProgressMonitor)} creates
+ * such a pack lock, it returns the lock so that it can be unlocked once the
+ * pack doesn't need a {@code .keep} file anymore.
+ *
+ * @since 6.0
+ */
+public interface PackLock {
+
+ /**
+ * Remove the {@code .keep} file that holds a pack in place.
+ *
+ * @throws java.io.IOException
+ * if deletion of the {@code .keep} file failed
+ */
+ void unlock() throws IOException;
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
index 715cbb48f..e43ea0261 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
@@ -29,7 +29,6 @@
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.TooLargeObjectInPackException;
import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.internal.storage.pack.BinaryDelta;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.BatchingProgressMonitor;
@@ -490,7 +489,7 @@ public ReceivedPackStatistics getReceivedPackStatistics() {
* {@link #setLockMessage(String)}.
* @throws java.io.IOException
* the stream is malformed, or contains corrupt objects.
- * @since 3.0
+ * @since 6.0
*/
public final PackLock parse(ProgressMonitor progress) throws IOException {
return parse(progress, progress);
@@ -509,7 +508,7 @@ public final PackLock parse(ProgressMonitor progress) throws IOException {
* {@link #setLockMessage(String)}.
* @throws java.io.IOException
* the stream is malformed, or contains corrupt objects.
- * @since 3.0
+ * @since 6.0
*/
public PackLock parse(ProgressMonitor receiving, ProgressMonitor resolving)
throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
index 58f8895e0..871ba50a6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -48,7 +48,6 @@
import org.eclipse.jgit.errors.TooLargePackException;
import org.eclipse.jgit.errors.UnpackException;
import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.internal.submodule.SubmoduleValidator;
import org.eclipse.jgit.internal.submodule.SubmoduleValidator.SubmoduleValidationException;
import org.eclipse.jgit.internal.transport.connectivity.FullConnectivityChecker;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java
index d98bd2307..1226a6b5e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java
@@ -28,7 +28,7 @@ public interface SshConfigStore {
* @param hostName
* to look up
* @param port
- * the user supplied; <= 0 if none
+ * the user supplied; <= 0 if none
* @param userName
* the user supplied, may be {@code null} or empty if none given
* @return the configuration for the requested name.
@@ -68,7 +68,7 @@ public interface SshConfigStore {
* @param hostName
* host name to look up
* @param port
- * port number; <= 0 if none
+ * port number; <= 0 if none
* @param userName
* the user name, may be {@code null} or empty if none given
* @return the configuration for the requested name.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java
index a6b20451d..d67fe074e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java
@@ -32,7 +32,6 @@
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.file.ObjectDirectory;
import org.eclipse.jgit.internal.storage.file.PackIndex;
-import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.internal.storage.file.UnpackedObject;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
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 dd656e5f2..d0007ec21 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -59,6 +59,8 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
@@ -94,6 +96,9 @@ public abstract class FS {
*/
protected static final Entry[] NO_ENTRIES = {};
+ private static final Pattern VERSION = Pattern
+ .compile("\\s(\\d+)\\.(\\d+)\\.(\\d+)"); //$NON-NLS-1$
+
private volatile Boolean supportSymlinks;
/**
@@ -1516,26 +1521,76 @@ protected File discoverGitSystemConfig() {
return null;
}
- // Trick Git into printing the path to the config file by using "echo"
- // as the editor.
- Map env = new HashMap<>();
- env.put("GIT_EDITOR", "echo"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (parseVersion(v) < makeVersion(2, 8, 0)) {
+ // --show-origin was introduced in git 2.8.0. For older git: trick
+ // it into printing the path to the config file by using "echo" as
+ // the editor.
+ Map env = new HashMap<>();
+ env.put("GIT_EDITOR", "echo"); //$NON-NLS-1$ //$NON-NLS-2$
+ String w;
+ try {
+ w = readPipe(gitExe.getParentFile(),
+ new String[] { gitExe.getPath(), "config", "--system", //$NON-NLS-1$ //$NON-NLS-2$
+ "--edit" }, //$NON-NLS-1$
+ SystemReader.getInstance().getDefaultCharset().name(),
+ env);
+ } catch (CommandFailedException e) {
+ LOG.warn(e.getMessage());
+ return null;
+ }
+ if (StringUtils.isEmptyOrNull(w)) {
+ return null;
+ }
+
+ return new File(w);
+ }
String w;
try {
w = readPipe(gitExe.getParentFile(),
new String[] { gitExe.getPath(), "config", "--system", //$NON-NLS-1$ //$NON-NLS-2$
- "--edit" }, //$NON-NLS-1$
- SystemReader.getInstance().getDefaultCharset().name(), env);
+ "--show-origin", "--list", "-z" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ SystemReader.getInstance().getDefaultCharset().name());
} catch (CommandFailedException e) {
LOG.warn(e.getMessage());
return null;
}
- if (StringUtils.isEmptyOrNull(w)) {
+ if (w == null) {
return null;
}
+ // We get NUL-terminated items; the first one will be a file name,
+ // prefixed by "file:". (Using -z is crucial, otherwise git quotes file
+ // names with special characters.)
+ int nul = w.indexOf(0);
+ if (nul <= 0) {
+ return null;
+ }
+ w = w.substring(0, nul);
+ int colon = w.indexOf(':');
+ if (colon < 0) {
+ return null;
+ }
+ w = w.substring(colon + 1);
+ return w.isEmpty() ? null : new File(w);
+ }
- return new File(w);
+ private long parseVersion(String version) {
+ Matcher m = VERSION.matcher(version);
+ if (m.find()) {
+ try {
+ return makeVersion(
+ Integer.parseInt(m.group(1)),
+ Integer.parseInt(m.group(2)),
+ Integer.parseInt(m.group(3)));
+ } catch (NumberFormatException e) {
+ // Ignore
+ }
+ }
+ return -1;
+ }
+
+ private long makeVersion(int major, int minor, int patch) {
+ return ((major * 10_000L) + minor) * 10_000L + patch;
}
/**
diff --git a/pom.xml b/pom.xml
index f7629411b..f5b66d13c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -162,7 +162,7 @@
1.21
4.3.1
3.1.0
- 9.4.44.v20210927
+ 10.0.6
0.15.3
4.5.13
4.4.14