From ad07196d606941311a48198da93c4027b57fdcc6 Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Tue, 4 Jan 2022 12:30:10 -0800 Subject: [PATCH 1/5] PackExt: Define new extension for the object size index Change-Id: I6bbaf43b4e6fb456ca0e9e0c6efcfeded0f94d6d --- .../src/org/eclipse/jgit/internal/storage/pack/PackExt.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java index 1d02c0279..adad411c6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java @@ -33,7 +33,10 @@ public enum PackExt { REVERSE_INDEX("rev"), //$NON-NLS-1$ /** A commit graph file extension. */ - COMMIT_GRAPH("graph"); //$NON-NLS-1$ + COMMIT_GRAPH("graph"), //$NON-NLS-1$ + + /** An object size index. */ + OBJECT_SIZE_INDEX("objsize"); //$NON-NLS-1$ private final String ext; From cfacc43b522cd2f93b0addbb3d6479750d0b73c9 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Fri, 24 Feb 2023 15:18:39 +0100 Subject: [PATCH 2/5] Fix formatting in GC#doGc Change-Id: Ifa3adb66d4e0404bab4036d6b165d6c4dafe921a --- .../jgit/internal/storage/file/GC.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) 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 502262a5f..a350561cc 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 @@ -279,17 +279,17 @@ private Collection doGc() throws IOException, ParseException { if (!lock.lock()) { return Collections.emptyList(); } - pm.start(6 /* tasks */); - packRefs(); - // TODO: implement reflog_expire(pm, repo); - Collection newPacks = repack(); - prune(Collections.emptySet()); - // TODO: implement rerere_gc(pm); - if (shouldWriteCommitGraphWhenGc()) { - writeCommitGraph(refsToObjectIds(getAllRefs())); + pm.start(6 /* tasks */); + packRefs(); + // TODO: implement reflog_expire(pm, repo); + Collection newPacks = repack(); + prune(Collections.emptySet()); + // TODO: implement rerere_gc(pm); + if (shouldWriteCommitGraphWhenGc()) { + writeCommitGraph(refsToObjectIds(getAllRefs())); + } + return newPacks; } - return newPacks; - } } /** From ca2c57b2ec5400db9c9446056b001a83adc5ccd8 Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Tue, 28 Dec 2021 14:23:40 -0800 Subject: [PATCH 3/5] PackWriter: offer to write an object-size index for the pack PackWriter callers tell the writer what do the want to include in the pack and invoke #writePack(). Afterwards, they can invoke #writeIndex() to write the corresponding pack index. Mirror this for the object-size index, adding a #writeObjectSizeIndex() method. Change-Id: Ic319975c72c239cd6488303f7d4cced797e6fe00 --- .../internal/storage/file/PackWriterTest.java | 37 +++++++++++++++ .../internal/storage/pack/PackWriter.java | 45 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java index 3fe8f52fb..2a403c769 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java @@ -504,6 +504,43 @@ public void testWriteIndex() throws Exception { } } + @Test + public void testWriteObjectSizeIndex_noDeltas() throws Exception { + config.setMinBytesForObjSizeIndex(0); + HashSet interesting = new HashSet<>(); + interesting.add(ObjectId + .fromString("82c6b885ff600be425b4ea96dee75dca255b69e7")); + + NullProgressMonitor m1 = NullProgressMonitor.INSTANCE; + writer = new PackWriter(config, db.newObjectReader()); + writer.setUseBitmaps(false); + writer.setThin(false); + writer.setIgnoreMissingUninteresting(false); + writer.preparePack(m1, interesting, NONE); + writer.writePack(m1, m1, os); + + PackIndex idx; + try (ByteArrayOutputStream is = new ByteArrayOutputStream()) { + writer.writeIndex(is); + idx = PackIndex.read(new ByteArrayInputStream(is.toByteArray())); + } + + PackObjectSizeIndex objSizeIdx; + try (ByteArrayOutputStream objSizeStream = new ByteArrayOutputStream()) { + writer.writeObjectSizeIndex(objSizeStream); + objSizeIdx = PackObjectSizeIndexLoader.load( + new ByteArrayInputStream(objSizeStream.toByteArray())); + } + writer.close(); + + ObjectId knownBlob1 = ObjectId + .fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259"); + ObjectId knownBlob2 = ObjectId + .fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3"); + assertEquals(18009, objSizeIdx.getSize(idx.findPosition(knownBlob1))); + assertEquals(18787, objSizeIdx.getSize(idx.findPosition(knownBlob2))); + } + @Test public void testExclude() throws Exception { // TestRepository closes repo diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java index d42d348a1..bad572459 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java @@ -61,6 +61,7 @@ import org.eclipse.jgit.internal.storage.file.PackBitmapIndexBuilder; import org.eclipse.jgit.internal.storage.file.PackBitmapIndexWriterV1; import org.eclipse.jgit.internal.storage.file.PackIndexWriter; +import org.eclipse.jgit.internal.storage.file.PackObjectSizeIndexWriter; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.AsyncObjectSizeQueue; import org.eclipse.jgit.lib.BatchingProgressMonitor; @@ -1091,6 +1092,50 @@ public void writeIndex(OutputStream indexStream) throws IOException { stats.timeWriting += System.currentTimeMillis() - writeStart; } + /** + * Create an object size index file for the contents of the pack file just + * written. + *

+ * Called after + * {@link #writePack(ProgressMonitor, ProgressMonitor, OutputStream)} that + * populates the list of objects to pack and before + * {@link #writeBitmapIndex(OutputStream)} that destroys it. + *

+ * Writing this index is only required for local pack storage. Packs sent on + * the network do not need to create an object size index. + * + * @param objIdxStream + * output for the object size index data. Caller is responsible + * for closing this stream. + * @throws IOException + * errors while writing + */ + public void writeObjectSizeIndex(OutputStream objIdxStream) + throws IOException { + if (config.getMinBytesForObjSizeIndex() < 0) { + return; + } + + long writeStart = System.currentTimeMillis(); + // We only need to populate the size of blobs + AsyncObjectSizeQueue sizeQueue = reader + .getObjectSize(objectsLists[OBJ_BLOB], /* reportMissing= */false); + try { + while (sizeQueue.next()) { + ObjectToPack otp = sizeQueue.getCurrent(); + long sz = sizeQueue.getSize(); + otp.setFullSize(sz); + } + } finally { + sizeQueue.release(); + } + PackObjectSizeIndexWriter iw = PackObjectSizeIndexWriter.createWriter( + objIdxStream, config.getMinBytesForObjSizeIndex()); + // All indexed objects because their positions must match primary index order + iw.write(sortByName()); + stats.timeWriting += System.currentTimeMillis() - writeStart; + } + /** * Create a bitmap index file to match the pack file just written. *

From 2d0b9080488239018908c7712dc440461991907a Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Thu, 19 Jan 2023 01:46:50 +0100 Subject: [PATCH 4/5] BatchingProgressMonitor: expose time spent per task Display elapsed time per task if enabled via ProgressMonitor#showDuration or if system property or environment variable GIT_TRACE_PERFORMANCE is set to "true". If both the system property and the environment variable are set the system property takes precedence. E.g. using jgit CLI: $ GIT_TRACE_PERFORMANCE=true jgit clone https://foo.bar/foobar Cloning into 'foobar'... remote: Counting objects: 1 [0.002s] remote: Finding sources: 100% (15531/15531) [0.006s] Receiving objects: 100% (169737/169737) [13.045s] Resolving deltas: 100% (67579/67579) [1.842s] Change-Id: I4d624e7858b286aeddbe7d4e557589986d73659e --- .../eclipse/jgit/junit/StrictWorkMonitor.java | 5 + .../io/CancellableDigestOutputStreamTest.java | 5 + .../lib/ThreadSafeProgressMonitorTest.java | 5 + org.eclipse.jgit/.settings/.api_filters | 84 +++++++++++++++ .../jgit/lib/BatchingProgressMonitor.java | 100 ++++++++++++++++-- .../jgit/lib/EmptyProgressMonitor.java | 4 + .../eclipse/jgit/lib/NullProgressMonitor.java | 5 + .../org/eclipse/jgit/lib/ProgressMonitor.java | 9 ++ .../eclipse/jgit/lib/TextProgressMonitor.java | 30 +++--- .../jgit/lib/ThreadSafeProgressMonitor.java | 5 + .../transport/SideBandProgressMonitor.java | 30 +++--- .../org/eclipse/jgit/util/SystemReader.java | 25 +++++ 12 files changed, 274 insertions(+), 33 deletions(-) diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java index 96d7aac54..c77bca975 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java @@ -50,4 +50,9 @@ public void endTask() { public boolean isCancelled() { return false; } + + @Override + public void showDuration(boolean enabled) { + // not implemented + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/io/CancellableDigestOutputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/io/CancellableDigestOutputStreamTest.java index 09a7c0b28..58ed7850b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/io/CancellableDigestOutputStreamTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/io/CancellableDigestOutputStreamTest.java @@ -54,6 +54,11 @@ public void endTask() { public boolean isCancelled() { return cancelled; } + + @Override + public void showDuration(boolean enabled) { + // not implemented + } } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java index 8f84155dd..e21ff580b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java @@ -167,5 +167,10 @@ public void endTask() { public boolean isCancelled() { return false; } + + @Override + public void showDuration(boolean enabled) { + // not implemented + } } } diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index bc4e9ea1c..e215f7aa3 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -1,5 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -42,6 +92,14 @@ + + + + + + + + @@ -58,6 +116,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 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 49e295aed..f82605737 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java @@ -10,21 +10,29 @@ package org.eclipse.jgit.lib; +import java.time.Duration; +import java.time.Instant; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.eclipse.jgit.lib.internal.WorkQueue; +import org.eclipse.jgit.util.SystemReader; /** * ProgressMonitor that batches update events. */ public abstract class BatchingProgressMonitor implements ProgressMonitor { + private static boolean performanceTrace = SystemReader.getInstance() + .isPerformanceTraceEnabled(); + private long delayStartTime; private TimeUnit delayStartUnit = TimeUnit.MILLISECONDS; private Task task; + private Boolean showDuration; + /** * Set an optional delay before the first output. * @@ -76,6 +84,11 @@ public boolean isCancelled() { return false; } + @Override + public void showDuration(boolean enabled) { + showDuration = Boolean.valueOf(enabled); + } + /** * Update the progress monitor if the total work isn't known, * @@ -83,8 +96,12 @@ public boolean isCancelled() { * name of the task. * @param workCurr * number of units already completed. + * @param duration + * how long this task runs + * @since 6.5 */ - protected abstract void onUpdate(String taskName, int workCurr); + protected abstract void onUpdate(String taskName, int workCurr, + Duration duration); /** * Finish the progress monitor when the total wasn't known in advance. @@ -93,8 +110,12 @@ public boolean isCancelled() { * name of the task. * @param workCurr * total number of units processed. + * @param duration + * how long this task runs + * @since 6.5 */ - protected abstract void onEndTask(String taskName, int workCurr); + protected abstract void onEndTask(String taskName, int workCurr, + Duration duration); /** * Update the progress monitor when the total is known in advance. @@ -107,9 +128,12 @@ public boolean isCancelled() { * estimated number of units to process. * @param percentDone * {@code workCurr * 100 / workTotal}. + * @param duration + * how long this task runs + * @since 6.5 */ protected abstract void onUpdate(String taskName, int workCurr, - int workTotal, int percentDone); + int workTotal, int percentDone, Duration duration); /** * Finish the progress monitor when the total is known in advance. @@ -122,9 +146,58 @@ protected abstract void onUpdate(String taskName, int workCurr, * estimated number of units to process. * @param percentDone * {@code workCurr * 100 / workTotal}. + * @param duration + * duration of the task + * @since 6.5 */ protected abstract void onEndTask(String taskName, int workCurr, - int workTotal, int percentDone); + int workTotal, int percentDone, Duration duration); + + private boolean showDuration() { + return showDuration != null ? showDuration.booleanValue() + : performanceTrace; + } + + /** + * Append formatted duration if system property or environment variable + * GIT_TRACE_PERFORMANCE is set to "true". If both are defined the system + * property takes precedence. + * + * @param s + * StringBuilder to append the formatted duration to + * @param duration + * duration to format + * @since 6.5 + */ + @SuppressWarnings({ "boxing", "nls" }) + protected void appendDuration(StringBuilder s, Duration duration) { + if (!showDuration()) { + return; + } + long hours = duration.toHours(); + int minutes = duration.toMinutesPart(); + int seconds = duration.toSecondsPart(); + s.append(" ["); + if (hours > 0) { + s.append(hours).append(':'); + s.append(String.format("%02d", minutes)).append(':'); + s.append(String.format("%02d", seconds)); + } else if (minutes > 0) { + s.append(minutes).append(':'); + s.append(String.format("%02d", seconds)); + } else { + s.append(seconds); + } + s.append('.').append(String.format("%03d", duration.toMillisPart())); + if (hours > 0) { + s.append('h'); + } else if (minutes > 0) { + s.append('m'); + } else { + s.append('s'); + } + s.append(']'); + } private static class Task implements Runnable { /** Title of the current task. */ @@ -148,10 +221,13 @@ private static class Task implements Runnable { /** Percentage of {@link #totalWork} that is done. */ private int lastPercent; + private final Instant startTime; + Task(String taskName, int totalWork) { this.taskName = taskName; this.totalWork = totalWork; this.display = true; + this.startTime = Instant.now(); } void delay(long time, TimeUnit unit) { @@ -170,7 +246,7 @@ void update(BatchingProgressMonitor pm, int completed) { if (totalWork == UNKNOWN) { // Only display once per second, as the alarm fires. if (display) { - pm.onUpdate(taskName, lastWork); + pm.onUpdate(taskName, lastWork, elapsedTime()); output = true; restartTimer(); } @@ -178,12 +254,14 @@ void update(BatchingProgressMonitor pm, int completed) { // Display once per second or when 1% is done. int currPercent = Math.round(lastWork * 100F / totalWork); if (display) { - pm.onUpdate(taskName, lastWork, totalWork, currPercent); + pm.onUpdate(taskName, lastWork, totalWork, currPercent, + elapsedTime()); output = true; restartTimer(); lastPercent = currPercent; } else if (currPercent != lastPercent) { - pm.onUpdate(taskName, lastWork, totalWork, currPercent); + pm.onUpdate(taskName, lastWork, totalWork, currPercent, + elapsedTime()); output = true; lastPercent = currPercent; } @@ -199,14 +277,18 @@ private void restartTimer() { void end(BatchingProgressMonitor pm) { if (output) { if (totalWork == UNKNOWN) { - pm.onEndTask(taskName, lastWork); + pm.onEndTask(taskName, lastWork, elapsedTime()); } else { int currPercent = Math.round(lastWork * 100F / totalWork); - pm.onEndTask(taskName, lastWork, totalWork, currPercent); + pm.onEndTask(taskName, lastWork, totalWork, currPercent, elapsedTime()); } } if (timerFuture != null) timerFuture.cancel(false /* no interrupt */); } + + private Duration elapsedTime() { + return Duration.between(startTime, Instant.now()); + } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java index 6b201e6bc..94d28eb34 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java @@ -48,4 +48,8 @@ public boolean isCancelled() { return false; } + @Override + public void showDuration(boolean enabled) { + // not implemented + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java index 10904b695..127cca9d1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java @@ -52,4 +52,9 @@ public boolean isCancelled() { public void endTask() { // Do not report. } + + @Override + public void showDuration(boolean enabled) { + // don't show + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ProgressMonitor.java index 9ebb0a46b..2ce73ace8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ProgressMonitor.java @@ -65,4 +65,13 @@ public interface ProgressMonitor { * @return true if the user asked the process to stop working. */ boolean isCancelled(); + + /** + * Set whether the monitor should show elapsed time per task + * + * @param enabled + * whether to show elapsed time per task + * @since 6.5 + */ + void showDuration(boolean enabled); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java index 03a78eb8a..85aa0b663 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java @@ -17,6 +17,7 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.Writer; +import java.time.Duration; /** * A simple progress reporter printing on a stream. @@ -46,49 +47,53 @@ public TextProgressMonitor(Writer out) { /** {@inheritDoc} */ @Override - protected void onUpdate(String taskName, int workCurr) { + protected void onUpdate(String taskName, int workCurr, Duration duration) { StringBuilder s = new StringBuilder(); - format(s, taskName, workCurr); + format(s, taskName, workCurr, duration); send(s); } /** {@inheritDoc} */ @Override - protected void onEndTask(String taskName, int workCurr) { + protected void onEndTask(String taskName, int workCurr, Duration duration) { StringBuilder s = new StringBuilder(); - format(s, taskName, workCurr); + format(s, taskName, workCurr, duration); s.append("\n"); //$NON-NLS-1$ send(s); } - private void format(StringBuilder s, String taskName, int workCurr) { + private void format(StringBuilder s, String taskName, int workCurr, + Duration duration) { s.append("\r"); //$NON-NLS-1$ s.append(taskName); s.append(": "); //$NON-NLS-1$ while (s.length() < 25) s.append(' '); s.append(workCurr); + appendDuration(s, duration); } /** {@inheritDoc} */ @Override - protected void onUpdate(String taskName, int cmp, int totalWork, int pcnt) { + protected void onUpdate(String taskName, int cmp, int totalWork, int pcnt, + Duration duration) { StringBuilder s = new StringBuilder(); - format(s, taskName, cmp, totalWork, pcnt); + format(s, taskName, cmp, totalWork, pcnt, duration); send(s); } /** {@inheritDoc} */ @Override - protected void onEndTask(String taskName, int cmp, int totalWork, int pcnt) { + protected void onEndTask(String taskName, int cmp, int totalWork, int pcnt, + Duration duration) { StringBuilder s = new StringBuilder(); - format(s, taskName, cmp, totalWork, pcnt); + format(s, taskName, cmp, totalWork, pcnt, duration); s.append("\n"); //$NON-NLS-1$ send(s); } private void format(StringBuilder s, String taskName, int cmp, - int totalWork, int pcnt) { + int totalWork, int pcnt, Duration duration) { s.append("\r"); //$NON-NLS-1$ s.append(taskName); s.append(": "); //$NON-NLS-1$ @@ -106,9 +111,10 @@ private void format(StringBuilder s, String taskName, int cmp, s.append(pcnt); s.append("% ("); //$NON-NLS-1$ s.append(curStr); - s.append("/"); //$NON-NLS-1$ + s.append('/'); s.append(endStr); - s.append(")"); //$NON-NLS-1$ + s.append(')'); + appendDuration(s, duration); } private void send(StringBuilder s) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java index 180fbdc46..e55395556 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java @@ -158,6 +158,11 @@ public void endTask() { pm.endTask(); } + @Override + public void showDuration(boolean enabled) { + pm.showDuration(enabled); + } + private boolean isMainThread() { return Thread.currentThread() == mainThread; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandProgressMonitor.java index 83e8bc291..33308600d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandProgressMonitor.java @@ -12,6 +12,7 @@ import java.io.IOException; import java.io.OutputStream; +import java.time.Duration; import org.eclipse.jgit.lib.BatchingProgressMonitor; import org.eclipse.jgit.lib.Constants; @@ -29,48 +30,52 @@ class SideBandProgressMonitor extends BatchingProgressMonitor { /** {@inheritDoc} */ @Override - protected void onUpdate(String taskName, int workCurr) { + protected void onUpdate(String taskName, int workCurr, Duration duration) { StringBuilder s = new StringBuilder(); - format(s, taskName, workCurr); + format(s, taskName, workCurr, duration); s.append(" \r"); //$NON-NLS-1$ send(s); } /** {@inheritDoc} */ @Override - protected void onEndTask(String taskName, int workCurr) { + protected void onEndTask(String taskName, int workCurr, Duration duration) { StringBuilder s = new StringBuilder(); - format(s, taskName, workCurr); + format(s, taskName, workCurr, duration); s.append(", done\n"); //$NON-NLS-1$ send(s); } - private void format(StringBuilder s, String taskName, int workCurr) { + private void format(StringBuilder s, String taskName, int workCurr, + Duration duration) { s.append(taskName); s.append(": "); //$NON-NLS-1$ s.append(workCurr); + appendDuration(s, duration); } /** {@inheritDoc} */ @Override - protected void onUpdate(String taskName, int cmp, int totalWork, int pcnt) { + protected void onUpdate(String taskName, int cmp, int totalWork, int pcnt, + Duration duration) { StringBuilder s = new StringBuilder(); - format(s, taskName, cmp, totalWork, pcnt); + format(s, taskName, cmp, totalWork, pcnt, duration); s.append(" \r"); //$NON-NLS-1$ send(s); } /** {@inheritDoc} */ @Override - protected void onEndTask(String taskName, int cmp, int totalWork, int pcnt) { + protected void onEndTask(String taskName, int cmp, int totalWork, int pcnt, + Duration duration) { StringBuilder s = new StringBuilder(); - format(s, taskName, cmp, totalWork, pcnt); + format(s, taskName, cmp, totalWork, pcnt, duration); s.append("\n"); //$NON-NLS-1$ send(s); } private void format(StringBuilder s, String taskName, int cmp, - int totalWork, int pcnt) { + int totalWork, int pcnt, Duration duration) { s.append(taskName); s.append(": "); //$NON-NLS-1$ if (pcnt < 100) @@ -80,9 +85,10 @@ private void format(StringBuilder s, String taskName, int cmp, s.append(pcnt); s.append("% ("); //$NON-NLS-1$ s.append(cmp); - s.append("/"); //$NON-NLS-1$ + s.append('/'); s.append(totalWork); - s.append(")"); //$NON-NLS-1$ + s.append(')'); + appendDuration(s, duration); } private void send(StringBuilder s) { 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 5ced0713e..a8a77904a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java @@ -65,6 +65,21 @@ public abstract class SystemReader { private static volatile Boolean isLinux; + private static final String GIT_TRACE_PERFORMANCE = "GIT_TRACE_PERFORMANCE"; //$NON-NLS-1$ + + private static final boolean performanceTrace = initPerformanceTrace(); + + private static boolean initPerformanceTrace() { + String val = System.getenv(GIT_TRACE_PERFORMANCE); + if (val == null) { + val = System.getenv(GIT_TRACE_PERFORMANCE); + } + if (val != null) { + return Boolean.valueOf(val).booleanValue(); + } + return false; + } + static { SystemReader r = new Default(); r.init(); @@ -560,6 +575,16 @@ public boolean isLinux() { return isLinux.booleanValue(); } + /** + * Whether performance trace is enabled + * + * @return whether performance trace is enabled + * @since 6.5 + */ + public boolean isPerformanceTraceEnabled() { + return performanceTrace; + } + private String getOsName() { return AccessController.doPrivileged( (PrivilegedAction) () -> getProperty("os.name") //$NON-NLS-1$ From 0518a6b0c16c1bce210bc9b2626104ef05975ee1 Mon Sep 17 00:00:00 2001 From: Pavel Salamon Date: Thu, 12 Jan 2023 16:39:07 +0100 Subject: [PATCH 5/5] Change config pull.rebase=preserve to pull.rebase=merges The native git option to preserve merge commits during rebase has been changed from pull.rebase=preserve to pull.rebase=merges. This changeset in jgit makes the same config change. The old "preserve" option is no longer recognized and is replaced by new option called "merges". This makes jgit's rebase configuration compatible with native git versions 2.34 and newer where the old "preserve" option has been removed. Change-Id: Ic07ff954e258115e76465a1593ef3259f4c418a3 --- .../org/eclipse/jgit/api/PullCommandTest.java | 24 +++++++++---------- .../src/org/eclipse/jgit/api/PullCommand.java | 6 ++--- .../org/eclipse/jgit/api/RebaseCommand.java | 4 ++-- .../org/eclipse/jgit/lib/BranchConfig.java | 8 +++++-- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java index 6a84f0a38..7a0ffdbec 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java @@ -378,44 +378,44 @@ public void testPullMergeProgrammaticConfigurationImpliedTargetBranch() } private enum TestPullMode { - MERGE, REBASE, REBASE_PREASERVE + MERGE, REBASE, REBASE_MERGES } @Test /** global rebase config should be respected */ - public void testPullWithRebasePreserve1Config() throws Exception { + public void testPullWithRebaseMerges1Config() throws Exception { Callable setup = () -> { StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "preserve"); + config.setString("pull", null, "rebase", "merges"); config.save(); return target.pull().call(); }; - doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE); + doTestPullWithRebase(setup, TestPullMode.REBASE_MERGES); } @Test /** the branch-local config should win over the global config */ - public void testPullWithRebasePreserveConfig2() throws Exception { + public void testPullWithRebaseMergesConfig2() throws Exception { Callable setup = () -> { StoredConfig config = dbTarget.getConfig(); config.setString("pull", null, "rebase", "false"); - config.setString("branch", "master", "rebase", "preserve"); + config.setString("branch", "master", "rebase", "merges"); config.save(); return target.pull().call(); }; - doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE); + doTestPullWithRebase(setup, TestPullMode.REBASE_MERGES); } @Test /** the branch-local config should be respected */ - public void testPullWithRebasePreserveConfig3() throws Exception { + public void testPullWithRebaseMergesConfig3() throws Exception { Callable setup = () -> { StoredConfig config = dbTarget.getConfig(); - config.setString("branch", "master", "rebase", "preserve"); + config.setString("branch", "master", "rebase", "merges"); config.save(); return target.pull().call(); }; - doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE); + doTestPullWithRebase(setup, TestPullMode.REBASE_MERGES); } @Test @@ -435,7 +435,7 @@ public void testPullWithRebaseConfig1() throws Exception { public void testPullWithRebaseConfig2() throws Exception { Callable setup = () -> { StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "preserve"); + config.setString("pull", null, "rebase", "merges"); config.setString("branch", "master", "rebase", "true"); config.save(); return target.pull().call(); @@ -543,7 +543,7 @@ private void doTestPullWithRebase(Callable pullSetup, assertEquals(sourceCommit, next.getParent(1)); // since both parents are known do no further checks here } else { - if (expectedPullMode == TestPullMode.REBASE_PREASERVE) { + if (expectedPullMode == TestPullMode.REBASE_MERGES) { next = rw.next(); assertEquals(2, next.getParentCount()); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java index 281ecfd01..83ae0fc9d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java @@ -137,8 +137,8 @@ public PullCommand setRebase(boolean useRebase) { *

BranchRebaseMode.REBASE
*
Equivalent to {@code --rebase} on the command line: use rebase * instead of merge after fetching.
- *
BranchRebaseMode.PRESERVE
- *
Equivalent to {@code --preserve-merges} on the command line: rebase + *
BranchRebaseMode.MERGES
+ *
Equivalent to {@code --rebase-merges} on the command line: rebase * preserving local merge commits.
*
BranchRebaseMode.INTERACTIVE
*
Equivalent to {@code --interactive} on the command line: use @@ -362,7 +362,7 @@ public PullResult call() throws GitAPIException, .setStrategy(strategy) .setContentMergeStrategy(contentStrategy) .setPreserveMerges( - pullRebaseMode == BranchRebaseMode.PRESERVE) + pullRebaseMode == BranchRebaseMode.MERGES) .call(); result = new PullResult(fetchRes, remote, rebaseRes); } else { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java index 4e0d9d78c..1e5523f27 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -151,7 +151,7 @@ public class RebaseCommand extends GitCommand { /** * The folder containing the hashes of (potentially) rewritten commits when - * --preserve-merges is used. + * --rebase-merges is used. *

* Native git rebase --merge uses a file of that name to record * commits to copy notes at the end of the whole rebase. @@ -160,7 +160,7 @@ public class RebaseCommand extends GitCommand { private static final String REWRITTEN = "rewritten"; //$NON-NLS-1$ /** - * File containing the current commit(s) to cherry pick when --preserve-merges + * File containing the current commit(s) to cherry pick when --rebase-merges * is used. */ private static final String CURRENT_COMMIT = "current-commit"; //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java index aa613d07e..19495dff1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java @@ -30,8 +30,12 @@ public enum BranchRebaseMode implements Config.ConfigEnum { /** Value for rebasing */ REBASE("true"), //$NON-NLS-1$ - /** Value for rebasing preserving local merge commits */ - PRESERVE("preserve"), //$NON-NLS-1$ + /** + * Value for rebasing preserving local merge commits + * + * @since 6.5 used instead of deprecated "preserve" option + */ + MERGES("merges"), //$NON-NLS-1$ /** Value for rebasing interactively */ INTERACTIVE("interactive"), //$NON-NLS-1$ /** Value for not rebasing at all but merging */