diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2022-05-25 16:47:37 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2022-05-25 16:47:37 +0200 |
commit | e8c39394516704e3af1542b375235a34ccce3df6 (patch) | |
tree | c1d1a8105d3e6a15dd79cecceb39eb27a46d24cc /org.eclipse.jgit | |
parent | e1efd4dd1fd4d2683c3340d005d8a965f987b00b (diff) | |
parent | ca62b3447befebfdab8503807d6441839bceb47d (diff) | |
download | jgit-e8c39394516704e3af1542b375235a34ccce3df6.tar.gz jgit-e8c39394516704e3af1542b375235a34ccce3df6.zip |
Merge branch 'master' into stable-6.2
* master:
RewriteGenerator: Fully buffering of input is no longer necessary
Update Orbit to S20220517184036
PackFileSnapshot: Resolve warnings by using "equals" instead of "=="
Remove stray files (probes or lock files) created by background threads
Change-Id: I1522fcd03fb7ef0d7512b5d0b3bc09271e918c48
Diffstat (limited to 'org.eclipse.jgit')
8 files changed, 134 insertions, 32 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFileSnapshot.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFileSnapshot.java index 17bd863528..a784af8c3f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFileSnapshot.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFileSnapshot.java @@ -15,6 +15,7 @@ import java.io.RandomAccessFile; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.util.Equality; class PackFileSnapshot extends FileSnapshot { @@ -61,7 +62,8 @@ class PackFileSnapshot extends FileSnapshot { } boolean isChecksumChanged(File packFile) { - return wasChecksumChanged = checksum != MISSING_CHECKSUM + return wasChecksumChanged = !Equality.isSameInstance(checksum, + MISSING_CHECKSUM) && !checksum.equals(readChecksum(packFile)); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index a50eaf1a8a..a25948e50b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -143,8 +143,19 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { */ static final int TOPO_QUEUED = 1 << 6; + /** + * Set on a RevCommit when a {@link TreeRevFilter} has been applied. + * <p> + * This flag is processed by the {@link RewriteGenerator} to check if a + * {@link TreeRevFilter} has been applied. + * + * @see TreeRevFilter + * @see RewriteGenerator + */ + static final int TREE_REV_FILTER_APPLIED = 1 << 7; + /** Number of flag bits we keep internal for our own use. See above flags. */ - static final int RESERVED_FLAGS = 7; + static final int RESERVED_FLAGS = 8; private static final int APP_FLAGS = -1 & ~((1 << RESERVED_FLAGS) - 1); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java index 4565a4b5de..1adef07ad9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java @@ -24,14 +24,7 @@ import org.eclipse.jgit.errors.MissingObjectException; * commit that matched the revision walker's filters. * <p> * This generator is the second phase of a path limited revision walk and - * assumes it is receiving RevCommits from {@link TreeRevFilter}, - * after they have been fully buffered by {@link AbstractRevQueue}. The full - * buffering is necessary to allow the simple loop used within our own - * {@link #rewrite(RevCommit)} to pull completely through a strand of - * {@link RevWalk#REWRITE} colored commits and come up with a simplification - * that makes the DAG dense. Not fully buffering the commits first would cause - * this loop to abort early, due to commits not being parsed and colored - * correctly. + * assumes it is receiving RevCommits from {@link TreeRevFilter}. * * @see TreeRevFilter */ @@ -43,9 +36,12 @@ class RewriteGenerator extends Generator { private final Generator source; + private final FIFORevQueue pending; + RewriteGenerator(Generator s) { super(s.firstParent); source = s; + pending = new FIFORevQueue(s.firstParent); } @Override @@ -62,10 +58,19 @@ class RewriteGenerator extends Generator { @Override RevCommit next() throws MissingObjectException, IncorrectObjectTypeException, IOException { - final RevCommit c = source.next(); + RevCommit c = pending.next(); + if (c == null) { - return null; + c = source.next(); + if (c == null) { + // We are done: Both the source generator and our internal list + // are completely exhausted. + return null; + } } + + applyFilterToParents(c); + boolean rewrote = false; final RevCommit[] pList = c.parents; final int nParents = pList.length; @@ -91,10 +96,41 @@ class RewriteGenerator extends Generator { return c; } - private RevCommit rewrite(RevCommit p) { + /** + * Makes sure that the {@link TreeRevFilter} has been applied to all parents + * of this commit by the previous {@link PendingGenerator}. + * + * @param c + * @throws MissingObjectException + * @throws IncorrectObjectTypeException + * @throws IOException + */ + private void applyFilterToParents(RevCommit c) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + for (RevCommit parent : c.parents) { + while ((parent.flags & RevWalk.TREE_REV_FILTER_APPLIED) == 0) { + + RevCommit n = source.next(); + + if (n != null) { + pending.add(n); + } else { + // Source generator is exhausted; filter has been applied to + // all commits + return; + } + + } + + } + } + + private RevCommit rewrite(RevCommit p) throws MissingObjectException, + IncorrectObjectTypeException, IOException { for (;;) { - final RevCommit[] pList = p.parents; - if (pList.length > 1) { + + if (p.parents.length > 1) { // This parent is a merge, so keep it. // return p; @@ -114,14 +150,16 @@ class RewriteGenerator extends Generator { return p; } - if (pList.length == 0) { + if (p.parents.length == 0) { // We can't go back any further, other than to // just delete the parent entirely. // return null; } - p = pList[0]; + applyFilterToParents(p.parents[0]); + p = p.parents[0]; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java index bfcea6ea8f..a79901ca10 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java @@ -125,12 +125,6 @@ class StartGenerator extends Generator { } if ((g.outputType() & NEEDS_REWRITE) != 0) { - // Correction for an upstream NEEDS_REWRITE is to buffer - // fully and then apply a rewrite generator that can - // pull through the rewrite chain and produce a dense - // output graph. - // - g = new FIFORevQueue(g); g = new RewriteGenerator(g); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java index 822fc5320c..92d72268d1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java @@ -41,6 +41,8 @@ public class TreeRevFilter extends RevFilter { private static final int UNINTERESTING = RevWalk.UNINTERESTING; + private static final int FILTER_APPLIED = RevWalk.TREE_REV_FILTER_APPLIED; + private final int rewriteFlag; private final TreeWalk pathFilter; @@ -101,6 +103,7 @@ public class TreeRevFilter extends RevFilter { public boolean include(RevWalk walker, RevCommit c) throws StopWalkException, MissingObjectException, IncorrectObjectTypeException, IOException { + c.flags |= FILTER_APPLIED; // Reset the tree filter to scan this commit and parents. // RevCommit[] pList = c.parents; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java index 567e40936a..cba5e1697c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java @@ -180,9 +180,10 @@ public class FileBasedConfig extends StoredConfig { } final LockFile lf = new LockFile(getFile()); - if (!lf.lock()) - throw new LockFailedException(getFile()); try { + if (!lf.lock()) { + throw new LockFailedException(getFile()); + } lf.setNeedSnapshotNoConfig(true); lf.write(out); if (!lf.commit()) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/Equality.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/Equality.java new file mode 100644 index 0000000000..da1684630b --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/Equality.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2022, Fabio Ponciroli <ponch78@gmail.com> 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.util; + +/** + * Equality utilities. + * + * @since: 6.2 + */ +public class Equality { + + /** + * Compare by reference + * + * @param a + * First object to compare + * @param b + * Second object to compare + * @return {@code true} if the objects are identical, {@code false} + * otherwise + * + * @since 6.2 + */ + @SuppressWarnings("ReferenceEquality") + public static <T> boolean isSameInstance(T a, T b) { + return a == b; + } +}
\ No newline at end of file diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index 9237c0a9b2..e8f38d8fd9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -47,7 +47,6 @@ import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; @@ -262,8 +261,9 @@ public abstract class FS { * * @see java.util.concurrent.Executors#newCachedThreadPool() */ - private static final Executor FUTURE_RUNNER = new ThreadPoolExecutor(0, - 5, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), + private static final ExecutorService FUTURE_RUNNER = new ThreadPoolExecutor( + 0, 5, 30L, TimeUnit.SECONDS, + new LinkedBlockingQueue<Runnable>(), runnable -> { Thread t = new Thread(runnable, "JGit-FileStoreAttributeReader-" //$NON-NLS-1$ @@ -285,8 +285,9 @@ public abstract class FS { * small keep-alive time to avoid delays on shut-down. * </p> */ - private static final Executor SAVE_RUNNER = new ThreadPoolExecutor(0, 1, - 1L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), + private static final ExecutorService SAVE_RUNNER = new ThreadPoolExecutor( + 0, 1, 1L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<Runnable>(), runnable -> { Thread t = new Thread(runnable, "JGit-FileStoreAttributeWriter-" //$NON-NLS-1$ @@ -296,6 +297,18 @@ public abstract class FS { return t; }); + static { + // Shut down the SAVE_RUNNER on System.exit() + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + SAVE_RUNNER.shutdownNow(); + SAVE_RUNNER.awaitTermination(100, TimeUnit.MILLISECONDS); + } catch (Exception e) { + // Ignore; we're shutting down + } + })); + } + /** * Whether FileStore attributes should be determined asynchronously * @@ -452,11 +465,13 @@ public abstract class FS { return null; } // fall through and return fallback - } catch (IOException | InterruptedException - | ExecutionException | CancellationException e) { + } catch (IOException | ExecutionException | CancellationException e) { LOG.error(e.getMessage(), e); } catch (TimeoutException | SecurityException e) { // use fallback + } catch (InterruptedException e) { + LOG.error(e.getMessage(), e); + Thread.currentThread().interrupt(); } LOG.debug("{}: use fallback timestamp resolution for directory {}", //$NON-NLS-1$ Thread.currentThread(), dir); @@ -474,6 +489,7 @@ public abstract class FS { Path probe = dir.resolve(".probe-" + UUID.randomUUID()); //$NON-NLS-1$ Instant end = Instant.now().plusSeconds(3); try { + probe.toFile().deleteOnExit(); Files.createFile(probe); do { n++; @@ -540,6 +556,7 @@ public abstract class FS { } Path probe = dir.resolve(".probe-" + UUID.randomUUID()); //$NON-NLS-1$ try { + probe.toFile().deleteOnExit(); Files.createFile(probe); Duration fsResolution = getFsResolution(s, dir, probe); Duration clockResolution = measureClockResolution(); |