aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2023-02-01 01:21:11 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2023-02-01 01:23:34 +0100
commit580cb13f21ec0685a8a425d75a19a6dd78999acc (patch)
tree1beff71402f7f4a85e6fab65df1be3dd788a2306
parenteb3a708676e3487bbd97df384c09595034034d7e (diff)
parentef010db59435522e235d628e8abdd3056f37bef0 (diff)
downloadjgit-580cb13f21ec0685a8a425d75a19a6dd78999acc.tar.gz
jgit-580cb13f21ec0685a8a425d75a19a6dd78999acc.zip
Merge branch 'stable-6.4'
* stable-6.4: Shortcut during git fetch for avoiding looping through all local refs FetchCommand: fix fetchSubmodules to work on a Ref to a blob Silence API warnings introduced by I466dcde6 Allow the exclusions of refs prefixes from bitmap PackWriterBitmapPreparer: do not include annotated tags in bitmap BatchingProgressMonitor: avoid int overflow when computing percentage Speedup GC listing objects referenced from reflogs FileSnapshotTest: Add more MISSING_FILE coverage Change-Id: Id0ebfbd85eb815716383b9495eb7dd1f54cf4d74
-rw-r--r--Documentation/config-options.md1
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java14
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java52
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/TextProgressMonitorTest.java83
-rw-r--r--org.eclipse.jgit/.settings/.api_filters40
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java7
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java28
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java16
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java38
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java19
14 files changed, 300 insertions, 16 deletions
diff --git a/Documentation/config-options.md b/Documentation/config-options.md
index 5b61df04bc..612b8456ae 100644
--- a/Documentation/config-options.md
+++ b/Documentation/config-options.md
@@ -87,6 +87,7 @@ Proxy configuration uses the standard Java mechanisms via class `java.net.ProxyS
| `pack.bitmapContiguousCommitCount` | `100` | &#x20DE; | Count of most recent commits for which to build bitmaps. |
| `pack.bitmapDistantCommitSpan` | `5000` | &#x20DE; | Span of commits when building bitmaps for distant history. |
| `pack.bitmapExcessiveBranchCount` | `100` | &#x20DE; | The count of branches deemed "excessive". If the count of branches in a repository exceeds this number and bitmaps are enabled, "inactive" branches will have fewer bitmaps than "active" branches. |
+| `pack.bitmapExcludedRefsPrefixes` | | &#x20DE; | The refs prefixes to be excluded when building bitmaps. May be specified more than once to exclude multiple prefixes. |
| `pack.bitmapInactiveBranchAgeInDays` | `90` | &#x20DE; | Age in days that marks a branch as "inactive" for bitmap creation. |
| `pack.bitmapRecentCommitCount` | `20000` | &#x20DE; | Count at which to switch from `bitmapRecentCommitSpan` to `bitmapDistantCommitSpan`. |
| `pack.bitmapRecentCommitSpan` | `100` | &#x20DE; | Span of commits when building bitmaps for recent history. |
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java
index 5e87b8f59f..12773c2405 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java
@@ -209,6 +209,20 @@ public class FileSnapshotTest {
assertTrue(fs2.equals(fs1));
}
+ @Test
+ public void snapshotAndFileMissingIsNotModified() throws Exception {
+ File doesNotExist = trash.resolve("DOES_NOT_EXIST").toFile();
+ FileSnapshot missing = FileSnapshot.save(doesNotExist);
+ assertFalse(missing.isModified(doesNotExist));
+ }
+
+ @Test
+ public void missingFileEquals() throws Exception {
+ FileSnapshot missing = FileSnapshot.save(
+ trash.resolve("DOES_NOT_EXIST").toFile());
+ assertTrue(missing.equals(FileSnapshot.MISSING_FILE));
+ }
+
@SuppressWarnings("boxing")
@Test
public void detectFileModified() throws IOException {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java
index bb56c84e8e..0c09ad1510 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java
@@ -83,6 +83,40 @@ public class GcCommitSelectionTest extends GcTestCase {
}
@Test
+ public void testBitmapDoesNotIncludeAnnotatedTags() throws Exception {
+ /*
+ * Make sure that the bitmap generated for the following commit
+ * graph does not include commit2 because it is not reachable by any
+ * heads, despite being reachable from tag1 through the annotated-tag1.
+ *
+ * refs/heads/main
+ * ^
+ * |
+ * commit1 <-- commit2 <- annotated-tag1 <- tag1
+ * ^
+ * |
+ * commit0
+ */
+ String mainBranch = "refs/heads/main";
+ BranchBuilder bb = tr.branch(mainBranch);
+
+ String commitMsg = "commit msg";
+ String fileBody = "file body";
+ String tagName = "tag1";
+ bb.commit().message(commitMsg + " 1").add("file1", fileBody).create();
+ RevCommit commit1 = bb.commit().message(commitMsg + " 2").add("file2", fileBody).create();
+ RevCommit commit2 = bb.commit().message(commitMsg + " 3").add("file3", fileBody).create();
+ tr.lightweightTag(tagName, tr.tag(tagName, commit2));
+ tr.branch(mainBranch).update(commit1);
+
+ gc.setExpireAgeMillis(0);
+ gc.gc();
+
+ // Create only 2 bitmaps, for commit0 and commit1, excluding commit2
+ assertEquals(2, gc.getStatistics().numberOfBitmaps);
+ }
+
+ @Test
public void testBitmapSpansWithMerges() throws Exception {
/*
* Commits that are merged. Since 55 is in the oldest history it is
@@ -187,6 +221,24 @@ public class GcCommitSelectionTest extends GcTestCase {
}
@Test
+ public void testBitmapsForExcludedBranches() throws Exception {
+ createNewCommitOnNewBranch("main");
+ createNewCommitOnNewBranch("other");
+ PackConfig packConfig = new PackConfig();
+ packConfig.setBitmapExcludedRefsPrefixes(new String[] { "refs/heads/other" });
+ gc.setPackConfig(packConfig);
+ gc.gc();
+ assertEquals(1,
+ gc.getStatistics().numberOfBitmaps);
+ }
+
+ private void createNewCommitOnNewBranch(String branchName) throws Exception {
+ BranchBuilder bb = tr.branch("refs/heads/" + branchName);
+ String msg = "New branch " + branchName;
+ bb.commit().message(msg).add("some-filename.txt", msg).create();
+ }
+
+ @Test
public void testSelectionOrderingWithChains() throws Exception {
/*-
* Create a history like this, where 'N' is the number of seconds from
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/TextProgressMonitorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/TextProgressMonitorTest.java
new file mode 100644
index 0000000000..55ca2cdea3
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/TextProgressMonitorTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2023, SAP SE or an SAP affiliate company 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.lib;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TextProgressMonitorTest {
+
+ private TextProgressMonitor m;
+
+ private ByteArrayOutputStream buf;
+
+ @Before
+ public void setup() {
+ buf = new ByteArrayOutputStream();
+ m = new TextProgressMonitor(
+ new OutputStreamWriter(buf, StandardCharsets.UTF_8));
+ }
+
+ @Test
+ public void testSimple() throws Exception {
+ m.beginTask("task", 10);
+ for (int i = 0; i < 10; i++) {
+ m.update(1);
+ }
+ m.endTask();
+ Assert.assertArrayEquals(
+ new String[] { "", "task: 10% ( 1/10)",
+ "task: 20% ( 2/10)",
+ "task: 30% ( 3/10)",
+ "task: 40% ( 4/10)",
+ "task: 50% ( 5/10)",
+ "task: 60% ( 6/10)",
+ "task: 70% ( 7/10)",
+ "task: 80% ( 8/10)",
+ "task: 90% ( 9/10)",
+ "task: 100% (10/10)",
+ "task: 100% (10/10)\n" },
+ bufLines());
+ }
+
+ @Test
+ public void testLargeNumbers() throws Exception {
+ m.beginTask("task", 1_000_000_000);
+ for (int i = 0; i < 10; i++) {
+ m.update(100_000_000);
+ }
+ m.endTask();
+ Assert.assertArrayEquals(
+ new String[] { "",
+ "task: 10% ( 100000000/1000000000)",
+ "task: 20% ( 200000000/1000000000)",
+ "task: 30% ( 300000000/1000000000)",
+ "task: 40% ( 400000000/1000000000)",
+ "task: 50% ( 500000000/1000000000)",
+ "task: 60% ( 600000000/1000000000)",
+ "task: 70% ( 700000000/1000000000)",
+ "task: 80% ( 800000000/1000000000)",
+ "task: 90% ( 900000000/1000000000)",
+ "task: 100% (1000000000/1000000000)",
+ "task: 100% (1000000000/1000000000)\n" },
+ bufLines());
+ }
+
+ String[] bufLines() throws UnsupportedEncodingException {
+ String s = new String(buf.toString(StandardCharsets.UTF_8.name()));
+ return s.split("\r");
+ }
+}
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index cc152f9047..107b7d5ea3 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -3,6 +3,12 @@
<resource path="src/org/eclipse/jgit/lib/ConfigConstants.java" type="org.eclipse.jgit.lib.ConfigConstants">
<filter id="1142947843">
<message_arguments>
+ <message_argument value="5.13.2"/>
+ <message_argument value="CONFIG_KEY_BITMAP_EXCLUDED_REFS_PREFIXES"/>
+ </message_arguments>
+ </filter>
+ <filter id="1142947843">
+ <message_arguments>
<message_argument value="6.1.1"/>
<message_argument value="CONFIG_KEY_TRUST_PACKED_REFS_STAT"/>
</message_arguments>
@@ -32,4 +38,38 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/jgit/lib/Repository.java" type="org.eclipse.jgit.lib.Repository">
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="5.13.2"/>
+ <message_argument value="getReflogReader(Ref)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/jgit/storage/pack/PackConfig.java" type="org.eclipse.jgit.storage.pack.PackConfig">
+ <filter id="336658481">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.storage.pack.PackConfig"/>
+ <message_argument value="DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES"/>
+ </message_arguments>
+ </filter>
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="5.13.2"/>
+ <message_argument value="DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES"/>
+ </message_arguments>
+ </filter>
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="5.13.2"/>
+ <message_argument value="getBitmapExcludedRefsPrefixes()"/>
+ </message_arguments>
+ </filter>
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="5.13.2"/>
+ <message_argument value="setBitmapExcludedRefsPrefixes(String[])"/>
+ </message_arguments>
+ </filter>
+ </resource>
</component>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
index e7a8be0432..3c772c2765 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
@@ -151,6 +151,9 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> {
if (fetchHead == null) {
return;
}
+ if (revWalk.parseAny(fetchHead).getType() == Constants.OBJ_BLOB) {
+ return;
+ }
walk.setTree(revWalk.parseTree(fetchHead));
while (walk.next()) {
try (Repository submoduleRepo = walk.getRepository()) {
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 3ebce6c409..3e92cddacd 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
@@ -31,6 +31,7 @@ import java.util.Locale;
import java.util.Objects;
import java.util.Set;
+import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.attributes.AttributesNode;
@@ -530,6 +531,12 @@ public class FileRepository extends Repository {
return new ReflogReaderImpl(this, ref.getName());
}
+ @Override
+ public @NonNull ReflogReader getReflogReader(@NonNull Ref ref)
+ throws IOException {
+ return new ReflogReaderImpl(this, ref.getName());
+ }
+
/** {@inheritDoc} */
@Override
public AttributesNodeProvider createAttributesNodeProvider() {
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 273d658a13..d41aea4fdd 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
@@ -800,6 +800,10 @@ public class GC {
Set<ObjectId> tagTargets = new HashSet<>();
Set<ObjectId> indexObjects = listNonHEADIndexObjects();
+ Set<ObjectId> refsToExcludeFromBitmap = repo.getRefDatabase()
+ .getRefsByPrefix(pconfig.getBitmapExcludedRefsPrefixes())
+ .stream().map(Ref::getObjectId).collect(Collectors.toSet());
+
for (Ref ref : refsBefore) {
checkCancelled();
nonHeads.addAll(listRefLogObjects(ref, 0));
@@ -844,7 +848,7 @@ public class GC {
Pack heads = null;
if (!allHeadsAndTags.isEmpty()) {
heads = writePack(allHeadsAndTags, PackWriter.NONE, allTags,
- tagTargets, excluded);
+ refsToExcludeFromBitmap, tagTargets, excluded);
if (heads != null) {
ret.add(heads);
excluded.add(0, heads.getIndex());
@@ -852,13 +856,13 @@ public class GC {
}
if (!nonHeads.isEmpty()) {
Pack rest = writePack(nonHeads, allHeadsAndTags, PackWriter.NONE,
- tagTargets, excluded);
+ PackWriter.NONE, tagTargets, excluded);
if (rest != null)
ret.add(rest);
}
if (!txnHeads.isEmpty()) {
Pack txn = writePack(txnHeads, PackWriter.NONE, PackWriter.NONE,
- null, excluded);
+ PackWriter.NONE, null, excluded);
if (txn != null)
ret.add(txn);
}
@@ -1127,10 +1131,7 @@ public class GC {
* @throws IOException
*/
private Set<ObjectId> listRefLogObjects(Ref ref, long minTime) throws IOException {
- ReflogReader reflogReader = repo.getReflogReader(ref.getName());
- if (reflogReader == null) {
- return Collections.emptySet();
- }
+ ReflogReader reflogReader = repo.getReflogReader(ref);
List<ReflogEntry> rlEntries = reflogReader
.getReverseEntries();
if (rlEntries == null || rlEntries.isEmpty())
@@ -1234,6 +1235,7 @@ public class GC {
private Pack writePack(@NonNull Set<? extends ObjectId> want,
@NonNull Set<? extends ObjectId> have, @NonNull Set<ObjectId> tags,
+ @NonNull Set<ObjectId> excludedRefsTips,
Set<ObjectId> tagTargets, List<ObjectIdSet> excludeObjects)
throws IOException {
checkCancelled();
@@ -1265,7 +1267,8 @@ public class GC {
if (excludeObjects != null)
for (ObjectIdSet idx : excludeObjects)
pw.excludeObjects(idx);
- pw.preparePack(pm, want, have, PackWriter.NONE, tags);
+ pw.preparePack(pm, want, have, PackWriter.NONE,
+ union(tags, excludedRefsTips));
if (pw.getObjectCount() == 0)
return null;
checkCancelled();
@@ -1378,6 +1381,15 @@ public class GC {
}
}
+ private Set<? extends ObjectId> union(Set<ObjectId> tags,
+ Set<ObjectId> excludedRefsHeadsTips) {
+ HashSet<ObjectId> unionSet = new HashSet<>(
+ tags.size() + excludedRefsHeadsTips.size());
+ unionSet.addAll(tags);
+ unionSet.addAll(excludedRefsHeadsTips);
+ return unionSet;
+ }
+
private void checkCancelled() throws CancelledException {
if (pm.isCancelled() || Thread.currentThread().isInterrupted()) {
throw new CancelledException(JGitText.get().operationCanceled);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
index 771d574bd4..5a18f1e567 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
@@ -408,6 +408,9 @@ class PackWriterBitmapPreparer {
List<RevCommit> newWantsByNewest = new ArrayList<>(want.size());
Set<RevCommit> newWants = new HashSet<>(want.size());
for (AnyObjectId objectId : want) {
+ if(excludeFromBitmapSelection.contains(objectId)) {
+ continue;
+ }
RevObject ro = rw.peel(rw.parseAny(objectId));
if (!(ro instanceof RevCommit) || reuse.contains(ro)
|| excludeFromBitmapSelection.contains(ro)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
index 2caefa4d97..49e295aed8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
@@ -176,7 +176,7 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor {
}
} else {
// Display once per second or when 1% is done.
- int currPercent = lastWork * 100 / totalWork;
+ int currPercent = Math.round(lastWork * 100F / totalWork);
if (display) {
pm.onUpdate(taskName, lastWork, totalWork, currPercent);
output = true;
@@ -201,8 +201,8 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor {
if (totalWork == UNKNOWN) {
pm.onEndTask(taskName, lastWork);
} else {
- int pDone = lastWork * 100 / totalWork;
- pm.onEndTask(taskName, lastWork, totalWork, pDone);
+ int currPercent = Math.round(lastWork * 100F / totalWork);
+ pm.onEndTask(taskName, lastWork, totalWork, currPercent);
}
}
if (timerFuture != null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index f63f31041e..ed4bf315e2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -721,6 +721,12 @@ public final class ConfigConstants {
public static final String CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT = "bitmapexcessivebranchcount";
/**
+ * The "pack.bitmapExcludedRefsPrefixes" key
+ * @since 5.13.2
+ */
+ public static final String CONFIG_KEY_BITMAP_EXCLUDED_REFS_PREFIXES = "bitmapexcludedrefsprefixes";
+
+ /**
* The "pack.bitmapInactiveBranchAgeInDays" key
* @since 5.8
*/
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
index e594e528be..db2571c673 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -1695,6 +1695,22 @@ public abstract class Repository implements AutoCloseable {
throws IOException;
/**
+ * Get the reflog reader. Subclasses should override this method and provide
+ * a more efficient implementation.
+ *
+ * @param ref
+ * a Ref
+ * @return a {@link org.eclipse.jgit.lib.ReflogReader} for the supplied ref,
+ * or {@code null} if the ref does not exist.
+ * @throws IOException
+ * @since 5.13.2
+ */
+ public @Nullable ReflogReader getReflogReader(@NonNull Ref ref)
+ throws IOException {
+ return getReflogReader(ref.getName());
+ }
+
+ /**
* Return the information stored in the file $GIT_DIR/MERGE_MSG. In this
* file operations triggering a merge will store a template for the commit
* message of the merge commit.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
index 6aa8be642d..a10f6cf88a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
@@ -16,6 +16,7 @@ import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BIGFILE_THRESHOLD;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_EXCLUDED_REFS_PREFIXES;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BUILD_BITMAPS;
@@ -226,6 +227,14 @@ public class PackConfig {
public static final int DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS = 90;
/**
+ * Default refs prefixes excluded from the calculation of pack bitmaps.
+ *
+ * @see #setBitmapExcludedRefsPrefixes(String[])
+ * @since 5.13.2
+ */
+ public static final String[] DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES = new String[0];
+
+ /**
* Default max time to spend during the search for reuse phase. This
* optimization is disabled by default: {@value}
*
@@ -285,6 +294,8 @@ public class PackConfig {
private int bitmapInactiveBranchAgeInDays = DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS;
+ private String[] bitmapExcludedRefsPrefixes = DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES;
+
private Duration searchForReuseTimeout = DEFAULT_SEARCH_FOR_REUSE_TIMEOUT;
private boolean cutDeltaChains;
@@ -1145,6 +1156,27 @@ public class PackConfig {
}
/**
+ * Get the refs prefixes excluded from the Bitmap.
+ *
+ * @return the refs prefixes excluded from the Bitmap.
+ * @since 5.13.2
+ */
+ public String[] getBitmapExcludedRefsPrefixes() {
+ return bitmapExcludedRefsPrefixes;
+ }
+
+ /**
+ * Set the refs prefixes excluded from the Bitmap.
+ *
+ * @param excludedRefsPrefixes
+ * the refs prefixes excluded from the Bitmap.
+ * @since 5.13.2
+ */
+ public void setBitmapExcludedRefsPrefixes(String[] excludedRefsPrefixes) {
+ bitmapExcludedRefsPrefixes = excludedRefsPrefixes;
+ }
+
+ /**
* Set the max time to spend during the search for reuse phase.
*
* @param timeout
@@ -1220,6 +1252,12 @@ public class PackConfig {
setBitmapInactiveBranchAgeInDays(rc.getInt(CONFIG_PACK_SECTION,
CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS,
getBitmapInactiveBranchAgeInDays()));
+ String[] excludedRefsPrefixesArray = rc.getStringList(CONFIG_PACK_SECTION,
+ null,
+ CONFIG_KEY_BITMAP_EXCLUDED_REFS_PREFIXES);
+ if(excludedRefsPrefixesArray.length > 0) {
+ setBitmapExcludedRefsPrefixes(excludedRefsPrefixesArray);
+ }
setSearchForReuseTimeout(Duration.ofSeconds(rc.getTimeUnit(
CONFIG_PACK_SECTION, null,
CONFIG_KEY_SEARCH_FOR_REUSE_TIMEOUT,
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 28c3b6a0fa..e0eb126440 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
@@ -47,6 +47,7 @@ import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.revwalk.ObjectWalk;
+import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.util.StringUtils;
@@ -387,11 +388,19 @@ class FetchProcess {
private boolean askForIsComplete() throws TransportException {
try {
try (ObjectWalk ow = new ObjectWalk(transport.local)) {
- for (ObjectId want : askFor.keySet())
- ow.markStart(ow.parseAny(want));
- for (Ref ref : localRefs().values())
- ow.markUninteresting(ow.parseAny(ref.getObjectId()));
- ow.checkConnectivity();
+ boolean hasCommitObject = false;
+ for (ObjectId want : askFor.keySet()) {
+ RevObject obj = ow.parseAny(want);
+ ow.markStart(obj);
+ hasCommitObject |= obj.getType() == Constants.OBJ_COMMIT;
+ }
+ // Checking connectivity makes sense on commits only
+ if (hasCommitObject) {
+ for (Ref ref : localRefs().values()) {
+ ow.markUninteresting(ow.parseAny(ref.getObjectId()));
+ }
+ ow.checkConnectivity();
+ }
}
return transport.getDepth() == null; // if depth is set we need to request objects that are already available
} catch (MissingObjectException e) {