aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2023-02-01 00:30:52 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2023-02-01 00:33:20 +0100
commitda21265a141b68ea3069afd79107f7d374027bc0 (patch)
tree5dbbe3c3e63c42ece49858c38c33b2804b3a48d3 /org.eclipse.jgit/src
parent41b33a16b87dbc7246f81089ef58f4bb530e4b1d (diff)
parent21e902dd7fa4ff53dc35fd7c48f8b5edc52f8eea (diff)
downloadjgit-da21265a141b68ea3069afd79107f7d374027bc0.tar.gz
jgit-da21265a141b68ea3069afd79107f7d374027bc0.zip
Merge branch 'stable-5.13' into stable-6.0
* stable-5.13: 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: I58ad4c210a5e7e5a1ba6b22315b04211c8909950
Diffstat (limited to 'org.eclipse.jgit/src')
-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
9 files changed, 110 insertions, 16 deletions
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 90c1515b06..7290d83df0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
@@ -140,6 +140,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 53a1cd6390..b37155717c 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 ca4f7a21e3..8c0aca5153 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
@@ -794,6 +794,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));
@@ -838,7 +842,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());
@@ -846,13 +850,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);
}
@@ -1017,10 +1021,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())
@@ -1124,6 +1125,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();
@@ -1155,7 +1157,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();
@@ -1268,6 +1271,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 924328d8a6..6f76326bc9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -621,6 +621,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 2b4deb32f0..1c1aa7b310 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
@@ -46,6 +46,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;
@@ -377,11 +378,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 true;
} catch (MissingObjectException e) {