Merge branch 'master' into stable-6.5

* master:
  Change config pull.rebase=preserve to pull.rebase=merges
  BatchingProgressMonitor: expose time spent per task
  PackWriter: offer to write an object-size index for the pack
  Fix formatting in GC#doGc
  PackExt: Define new extension for the object size index

Change-Id: I174db870e6c2fcb72ff535b39bb6e1c3358f11b8
This commit is contained in:
Matthias Sohn 2023-03-01 00:11:41 +01:00
commit e060ac836d
20 changed files with 393 additions and 63 deletions

View File

@ -50,4 +50,9 @@ public void endTask() {
public boolean isCancelled() {
return false;
}
@Override
public void showDuration(boolean enabled) {
// not implemented
}
}

View File

@ -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<PullResult> 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<PullResult> 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<PullResult> 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<PullResult> 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<PullResult> 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());
}

View File

@ -504,6 +504,43 @@ public void testWriteIndex() throws Exception {
}
}
@Test
public void testWriteObjectSizeIndex_noDeltas() throws Exception {
config.setMinBytesForObjSizeIndex(0);
HashSet<ObjectId> 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

View File

@ -54,6 +54,11 @@ public void endTask() {
public boolean isCancelled() {
return cancelled;
}
@Override
public void showDuration(boolean enabled) {
// not implemented
}
}
@Test

View File

@ -167,5 +167,10 @@ public void endTask() {
public boolean isCancelled() {
return false;
}
@Override
public void showDuration(boolean enabled) {
// not implemented
}
}
}

View File

@ -1,5 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.jgit" version="2">
<resource path="src/org/eclipse/jgit/lib/BatchingProgressMonitor.java" type="org.eclipse.jgit.lib.BatchingProgressMonitor">
<filter id="336695337">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.BatchingProgressMonitor"/>
<message_argument value="onEndTask(String, int, Duration)"/>
</message_arguments>
</filter>
<filter id="336695337">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.BatchingProgressMonitor"/>
<message_argument value="onEndTask(String, int, int, int, Duration)"/>
</message_arguments>
</filter>
<filter id="336695337">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.BatchingProgressMonitor"/>
<message_argument value="onUpdate(String, int, Duration)"/>
</message_arguments>
</filter>
<filter id="336695337">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.BatchingProgressMonitor"/>
<message_argument value="onUpdate(String, int, int, int, Duration)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.BatchingProgressMonitor"/>
<message_argument value="onEndTask(String, int)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.BatchingProgressMonitor"/>
<message_argument value="onEndTask(String, int, int, int)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.BatchingProgressMonitor"/>
<message_argument value="onUpdate(String, int)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.BatchingProgressMonitor"/>
<message_argument value="onUpdate(String, int, int, int)"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/jgit/lib/ConfigConstants.java" type="org.eclipse.jgit.lib.ConfigConstants">
<filter id="1142947843">
<message_arguments>
@ -42,6 +92,14 @@
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/jgit/lib/ProgressMonitor.java" type="org.eclipse.jgit.lib.ProgressMonitor">
<filter id="403804204">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.ProgressMonitor"/>
<message_argument value="showDuration(boolean)"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/jgit/lib/RefDatabase.java" type="org.eclipse.jgit.lib.RefDatabase">
<filter id="336658481">
<message_arguments>
@ -58,6 +116,32 @@
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/jgit/lib/TextProgressMonitor.java" type="org.eclipse.jgit.lib.TextProgressMonitor">
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.TextProgressMonitor"/>
<message_argument value="onEndTask(String, int)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.TextProgressMonitor"/>
<message_argument value="onEndTask(String, int, int, int)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.TextProgressMonitor"/>
<message_argument value="onUpdate(String, int)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.TextProgressMonitor"/>
<message_argument value="onUpdate(String, int, int, int)"/>
</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>

View File

@ -137,8 +137,8 @@ public PullCommand setRebase(boolean useRebase) {
* <dt>BranchRebaseMode.REBASE</dt>
* <dd>Equivalent to {@code --rebase} on the command line: use rebase
* instead of merge after fetching.</dd>
* <dt>BranchRebaseMode.PRESERVE</dt>
* <dd>Equivalent to {@code --preserve-merges} on the command line: rebase
* <dt>BranchRebaseMode.MERGES</dt>
* <dd>Equivalent to {@code --rebase-merges} on the command line: rebase
* preserving local merge commits.</dd>
* <dt>BranchRebaseMode.INTERACTIVE</dt>
* <dd>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 {

View File

@ -151,7 +151,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
/**
* The folder containing the hashes of (potentially) rewritten commits when
* --preserve-merges is used.
* --rebase-merges is used.
* <p>
* Native git rebase --merge uses a <em>file</em> 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<RebaseResult> {
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$

View File

@ -279,17 +279,17 @@ private Collection<Pack> doGc() throws IOException, ParseException {
if (!lock.lock()) {
return Collections.emptyList();
}
pm.start(6 /* tasks */);
packRefs();
// TODO: implement reflog_expire(pm, repo);
Collection<Pack> 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<Pack> newPacks = repack();
prune(Collections.emptySet());
// TODO: implement rerere_gc(pm);
if (shouldWriteCommitGraphWhenGc()) {
writeCommitGraph(refsToObjectIds(getAllRefs()));
}
return newPacks;
}
return newPacks;
}
}
/**

View File

@ -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;

View File

@ -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.
* <p>
* Called after
* {@link #writePack(ProgressMonitor, ProgressMonitor, OutputStream)} that
* populates the list of objects to pack and before
* {@link #writeBitmapIndex(OutputStream)} that destroys it.
* <p>
* 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<ObjectToPack> 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.
* <p>

View File

@ -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());
}
}
}

View File

@ -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 */

View File

@ -48,4 +48,8 @@ public boolean isCancelled() {
return false;
}
@Override
public void showDuration(boolean enabled) {
// not implemented
}
}

View File

@ -52,4 +52,9 @@ public boolean isCancelled() {
public void endTask() {
// Do not report.
}
@Override
public void showDuration(boolean enabled) {
// don't show
}
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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) {

View File

@ -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<String>) () -> getProperty("os.name") //$NON-NLS-1$