diff options
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/revwalk')
40 files changed, 785 insertions, 301 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java index dda108bc69..73ae62a23f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java @@ -79,8 +79,6 @@ abstract class AbstractRevQueue extends Generator { } /** - * {@inheritDoc} - * <p> * Remove the first commit from the queue. */ @Override diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapWalker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapWalker.java index 8cd5eb2238..7e65ffb8f6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapWalker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapWalker.java @@ -50,12 +50,15 @@ public final class BitmapWalker { /** * Create a BitmapWalker. * - * @param walker walker to use when traversing the object graph. - * @param bitmapIndex index to obtain bitmaps from. - * @param pm progress monitor to report progress on. + * @param walker + * walker to use when traversing the object graph. + * @param bitmapIndex + * index to obtain bitmaps from. + * @param pm + * progress monitor to report progress on. */ - public BitmapWalker( - ObjectWalk walker, BitmapIndex bitmapIndex, ProgressMonitor pm) { + public BitmapWalker(ObjectWalk walker, BitmapIndex bitmapIndex, + ProgressMonitor pm) { this.walker = walker; this.bitmapIndex = bitmapIndex; this.pm = (pm == null) ? NullProgressMonitor.INSTANCE : pm; @@ -178,8 +181,9 @@ public final class BitmapWalker { for (ObjectId obj : start) { Bitmap bitmap = bitmapIndex.getBitmap(obj); - if (bitmap != null) + if (bitmap != null) { bitmapResult.or(bitmap); + } } boolean marked = false; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java index cdd8073d6e..e855d8f700 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java @@ -45,8 +45,6 @@ abstract class BlockRevQueue extends AbstractRevQueue { } /** - * {@inheritDoc} - * <p> * Reconfigure this queue to share the same free list as another. * <p> * Multiple revision queues can be connected to the same free list, making @@ -56,6 +54,11 @@ abstract class BlockRevQueue extends AbstractRevQueue { * <p> * Free lists are not thread-safe. Applications must ensure that all queues * sharing the same free list are doing so from only a single thread. + * + * @param q + * another FIFO queue that wants to share our queue's free list. + * + * @see Generator#shareFreeList */ @Override public void shareFreeList(BlockRevQueue q) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevPriorityQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevPriorityQueue.java new file mode 100644 index 0000000000..233dd64a3c --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevPriorityQueue.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2023, GerritForge Ltd + * + * 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.revwalk; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.internal.JGitText; + +import java.io.IOException; +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * A queue of commits sorted by commit time order using a Java PriorityQueue. + * For the commits with the same commit time insertion order will be preserved. + */ +class DateRevPriorityQueue extends DateRevQueue { + private PriorityQueue<RevCommitEntry> queue; + + private final AtomicInteger sequence = new AtomicInteger(1); + + /** + * Create an empty queue of commits sorted by commit time order. + */ + public DateRevPriorityQueue() { + this(false); + } + + /** + * Create an empty queue of commits sorted by commit time order. + * + * @param firstParent + * treat first element as a parent + */ + DateRevPriorityQueue(boolean firstParent) { + super(firstParent); + initPriorityQueue(); + } + + private void initPriorityQueue() { + sequence.set(1); + queue = new PriorityQueue<>(Comparator.comparingInt( + (RevCommitEntry ent) -> ent.getEntry().getCommitTime()) + .reversed() + .thenComparingInt(RevCommitEntry::getInsertSequenceNumber)); + } + + DateRevPriorityQueue(Generator s) throws MissingObjectException, + IncorrectObjectTypeException, IOException { + this(s.firstParent); + for (;;) { + final RevCommit c = s.next(); + if (c == null) { + break; + } + add(c); + } + } + + @Override + public void add(RevCommit c) { + // PriorityQueue does not accept null values. To keep the same behaviour + // do the same check and throw the same exception before creating entry + if (c == null) { + throw new NullPointerException(JGitText.get().nullRevCommit); + } + queue.add(new RevCommitEntry(sequence.getAndIncrement(), c)); + } + + @Override + public RevCommit next() { + RevCommitEntry entry = queue.poll(); + return entry == null ? null : entry.getEntry(); + } + + /** + * Peek at the next commit, without removing it. + * + * @return the next available commit; null if there are no commits left. + */ + @Override + public @Nullable RevCommit peek() { + RevCommitEntry entry = queue.peek(); + return entry == null ? null : entry.getEntry(); + } + + /** + * {@inheritDoc} + */ + @Override + public void clear() { + sequence.set(1); + queue.clear(); + } + + @Override + boolean everbodyHasFlag(int f) { + return queue.stream().map(RevCommitEntry::getEntry) + .noneMatch(c -> (c.flags & f) == 0); + } + + @Override + boolean anybodyHasFlag(int f) { + return queue.stream().map(RevCommitEntry::getEntry) + .anyMatch(c -> (c.flags & f) != 0); + } + + @Override + int outputType() { + return outputType | SORT_COMMIT_TIME_DESC; + } + + @Override + public String toString() { + final StringBuilder s = new StringBuilder(); + for (RevCommitEntry e : queue) { + describe(s, e.getEntry()); + } + return s.toString(); + } + + private static class RevCommitEntry { + private final int insertSequenceNumber; + + private final RevCommit entry; + + public RevCommitEntry(int insertSequenceNumber, RevCommit entry) { + this.insertSequenceNumber = insertSequenceNumber; + this.entry = entry; + } + + public int getInsertSequenceNumber() { + return insertSequenceNumber; + } + + public RevCommit getEntry() { + return entry; + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java index 0cabf07057..905dcb62ad 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java @@ -8,11 +8,11 @@ * * SPDX-License-Identifier: BSD-3-Clause */ - package org.eclipse.jgit.revwalk; import java.io.IOException; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; @@ -36,11 +36,17 @@ public class DateRevQueue extends AbstractRevQueue { private int last = -1; - /** Create an empty date queue. */ + /** Create an empty DateRevQueue. */ public DateRevQueue() { super(false); } + /** + * Create an empty DateRevQueue. + * + * @param firstParent + * treat first element as a parent + */ DateRevQueue(boolean firstParent) { super(firstParent); } @@ -56,7 +62,6 @@ public class DateRevQueue extends AbstractRevQueue { } } - /** {@inheritDoc} */ @Override public void add(RevCommit c) { sinceLastIndex++; @@ -102,7 +107,6 @@ public class DateRevQueue extends AbstractRevQueue { } } - /** {@inheritDoc} */ @Override public RevCommit next() { final Entry q = head; @@ -135,11 +139,10 @@ public class DateRevQueue extends AbstractRevQueue { * * @return the next available commit; null if there are no commits left. */ - public RevCommit peek() { + public @Nullable RevCommit peek() { return head != null ? head.commit : null; } - /** {@inheritDoc} */ @Override public void clear() { head = null; @@ -173,7 +176,6 @@ public class DateRevQueue extends AbstractRevQueue { return outputType | SORT_COMMIT_TIME_DESC; } - /** {@inheritDoc} */ @Override public String toString() { final StringBuilder s = new StringBuilder(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java index ec0824cb0b..664f8fa3a7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java @@ -55,10 +55,15 @@ class DepthGenerator extends Generator { /** * @param w - * @param s Parent generator + * walk used for depth filtering + * @param s + * Parent generator * @throws MissingObjectException + * if an object is missing * @throws IncorrectObjectTypeException + * if an object has an unexpected type * @throws IOException + * if an IO error occurred */ DepthGenerator(DepthWalk w, Generator s) throws MissingObjectException, IncorrectObjectTypeException, IOException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java index 5277563ac4..a7ffd34233 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java @@ -35,6 +35,8 @@ public interface DepthWalk { int getDepth(); /** + * Get deepen-since value + * * @return the deepen-since value; if not 0, this walk only returns commits * whose commit time is at or after this limit * @since 5.2 @@ -44,6 +46,8 @@ public interface DepthWalk { } /** + * Get deepen-not values + * * @return the objects specified by the client using --shallow-exclude * @since 5.2 */ @@ -51,7 +55,11 @@ public interface DepthWalk { return Collections.emptyList(); } - /** @return flag marking commits that should become unshallow. */ + /** + * Get unshallow flag + * + * @return flag marking commits that should become unshallow. + */ /** * Get flag marking commits that should become unshallow. * @@ -67,7 +75,10 @@ public interface DepthWalk { RevFlag getReinterestingFlag(); /** - * @return flag marking commits that are to be excluded because of --shallow-exclude + * Get deepen-not flag + * + * @return flag marking commits that are to be excluded because of + * --shallow-exclude * @since 5.2 */ RevFlag getDeepenNotFlag(); @@ -85,12 +96,18 @@ public interface DepthWalk { */ boolean makesChildBoundary; - /** @return depth of this commit, as found by the shortest path. */ + /** + * Get depth + * + * @return depth of this commit, as found by the shortest path. + */ public int getDepth() { return depth; } /** + * Whether at least one commit was excluded due to shallow fetch + * * @return true if at least one of this commit's parents was excluded * due to a shallow fetch setting, false otherwise * @since 5.2 @@ -126,8 +143,12 @@ public interface DepthWalk { private final RevFlag DEEPEN_NOT; /** - * @param repo Repository to walk - * @param depth Maximum depth to return + * Create RevWalk + * + * @param repo + * Repository to walk + * @param depth + * Maximum depth to return */ public RevWalk(Repository repo, int depth) { super(repo); @@ -140,8 +161,12 @@ public interface DepthWalk { } /** - * @param or ObjectReader to use - * @param depth Maximum depth to return + * Create RevWalk + * + * @param or + * ObjectReader to use + * @param depth + * Maximum depth to return */ public RevWalk(ObjectReader or, int depth) { super(or); @@ -159,8 +184,11 @@ public interface DepthWalk { * @param c * Commit to mark * @throws IOException + * if an IO error occurred * @throws IncorrectObjectTypeException + * if object has an unexpected type * @throws MissingObjectException + * if object is missing */ public void markRoot(RevCommit c) throws MissingObjectException, IncorrectObjectTypeException, IOException { @@ -228,6 +256,8 @@ public interface DepthWalk { } /** + * Convert to ObjectWalk with same objects + * * @since 4.5 */ @Override @@ -256,8 +286,12 @@ public interface DepthWalk { private final RevFlag DEEPEN_NOT; /** - * @param repo Repository to walk - * @param depth Maximum depth to return + * Create ObjectWalk + * + * @param repo + * Repository to walk + * @param depth + * Maximum depth to return */ public ObjectWalk(Repository repo, int depth) { super(repo); @@ -270,8 +304,12 @@ public interface DepthWalk { } /** - * @param or Object Reader - * @param depth Maximum depth to return + * Create ObjectWalk + * + * @param or + * Object Reader + * @param depth + * Maximum depth to return */ public ObjectWalk(ObjectReader or, int depth) { super(or); @@ -289,8 +327,11 @@ public interface DepthWalk { * @param o * Commit to mark * @throws IOException + * if an IO error occurred * @throws IncorrectObjectTypeException + * if object has an unexpected type * @throws MissingObjectException + * if object is missing */ public void markRoot(RevObject o) throws MissingObjectException, IncorrectObjectTypeException, IOException { @@ -313,8 +354,11 @@ public interface DepthWalk { * @param c * Commit to mark * @throws MissingObjectException + * if object is missing * @throws IncorrectObjectTypeException + * if object has an unexpected type * @throws IOException + * if an IO error occurred */ public void markUnshallow(RevObject c) throws MissingObjectException, IncorrectObjectTypeException, IOException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java index 0f8eddd6d4..996745c158 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java @@ -37,7 +37,6 @@ public class FIFORevQueue extends BlockRevQueue { super(s); } - /** {@inheritDoc} */ @Override public void add(RevCommit c) { Block b = tail; @@ -82,7 +81,6 @@ public class FIFORevQueue extends BlockRevQueue { head = b; } - /** {@inheritDoc} */ @Override public RevCommit next() { final Block b = head; @@ -99,7 +97,6 @@ public class FIFORevQueue extends BlockRevQueue { return c; } - /** {@inheritDoc} */ @Override public void clear() { head = null; @@ -135,7 +132,6 @@ public class FIFORevQueue extends BlockRevQueue { } } - /** {@inheritDoc} */ @Override public String toString() { final StringBuilder s = new StringBuilder(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java index 3b54123f0b..12e6c4ea98 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java @@ -11,12 +11,14 @@ package org.eclipse.jgit.revwalk; import java.io.IOException; +import java.util.Optional; +import java.util.Set; import org.eclipse.jgit.diff.DiffConfig; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.treewalk.TreeWalk; -import org.eclipse.jgit.treewalk.filter.PathFilter; +import org.eclipse.jgit.treewalk.filter.ChangedPathTreeFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; /** @@ -54,41 +56,49 @@ public class FollowFilter extends TreeFilter { * @since 3.0 */ public static FollowFilter create(String path, DiffConfig cfg) { - return new FollowFilter(PathFilter.create(path), cfg); + return new FollowFilter(ChangedPathTreeFilter.create(path), cfg); } - private final PathFilter path; + private final ChangedPathTreeFilter path; final DiffConfig cfg; private RenameCallback renameCallback; - FollowFilter(PathFilter path, DiffConfig cfg) { + FollowFilter(ChangedPathTreeFilter path, DiffConfig cfg) { this.path = path; this.cfg = cfg; } - /** @return the path this filter matches. */ /** * Get the path this filter matches. * * @return the path this filter matches. */ public String getPath() { - return path.getPath(); + return path.getPaths().get(0); } - /** {@inheritDoc} */ @Override public boolean include(TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { - return path.include(walker) && ANY_DIFF.include(walker); + return path.include(walker); + } + + @Override + public boolean shouldTreeWalk(RevCommit c, RevWalk rw, + MutableBoolean cpfUsed) { + return path.shouldTreeWalk(c, rw, cpfUsed); } - /** {@inheritDoc} */ @Override public boolean shouldBeRecursive() { - return path.shouldBeRecursive() || ANY_DIFF.shouldBeRecursive(); + return path.shouldBeRecursive(); + } + + @Override + public Optional<Set<byte[]>> getPathsBestEffort() { + return path.getPathsBestEffort(); } /** {@inheritDoc} */ @@ -97,13 +107,10 @@ public class FollowFilter extends TreeFilter { return new FollowFilter(path.clone(), cfg); } - /** {@inheritDoc} */ @SuppressWarnings("nls") @Override public String toString() { - return "(FOLLOW(" + path.toString() + ")" // - + " AND " // - + ANY_DIFF.toString() + ")"; + return "(FOLLOW(" + path.toString() + "))"; } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java index 74e4c1edb7..af50794014 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java @@ -51,7 +51,6 @@ public final class FooterKey { return name; } - /** {@inheritDoc} */ @SuppressWarnings("nls") @Override public String toString() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java index 3d128a6bd3..fa7fb316c9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java @@ -11,6 +11,9 @@ package org.eclipse.jgit.revwalk; import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import org.eclipse.jgit.util.RawParseUtils; @@ -47,6 +50,137 @@ public final class FooterLine { } /** + * Extract the footer lines from the given message. + * + * @param str + * the message to extract footers from. + * @return ordered list of footer lines; empty list if no footers found. + * @see RevCommit#getFooterLines() + * @since 6.7 + */ + public static List<FooterLine> fromMessage( + String str) { + return fromMessage(str.getBytes()); + } + + /** + * Extract the footer lines from the given message. + * + * @param raw + * the raw message to extract footers from. + * @return ordered list of footer lines; empty list if no footers found. + * @see RevCommit#getFooterLines() + * @since 6.7 + */ + public static List<FooterLine> fromMessage( + byte[] raw) { + // Find the end of the last paragraph. + int parEnd = raw.length; + for (; parEnd > 0 && (raw[parEnd - 1] == '\n' + || raw[parEnd - 1] == ' '); --parEnd) { + // empty + } + + // The first non-header line is never a footer. + int msgB = RawParseUtils.nextLfSkippingSplitLines(raw, + RawParseUtils.hasAnyKnownHeaders(raw) + ? RawParseUtils.commitMessage(raw, 0) + : 0); + ArrayList<FooterLine> r = new ArrayList<>(4); + Charset enc = RawParseUtils.guessEncoding(raw); + + // Search for the beginning of last paragraph + int parStart = parEnd; + for (; parStart > msgB; --parStart) { + if (parStart < 2) { + // Too close to beginning: this is not a raw message + parStart = 0; + break; + } + if (raw[parStart - 1] == '\n' && raw[parStart - 2] == '\n') { + break; + } + } + + for (int ptr = parStart; ptr < parEnd;) { + int keyStart = ptr; + int keyEnd = RawParseUtils.endOfFooterLineKey(raw, ptr); + if (keyEnd < 0) { + // Not a well-formed footer line, skip it. + ptr = RawParseUtils.nextLF(raw, ptr); + continue; + } + + // Skip over the ': *' at the end of the key before the value. + int valStart; + int valEnd; + for (valStart = keyEnd + 1; valStart < raw.length + && raw[valStart] == ' '; ++valStart) { + // empty + } + + for(ptr = valStart;;) { + ptr = RawParseUtils.nextLF(raw, ptr); + // Next line starts with whitespace for a multiline footer. + if (ptr == raw.length || raw[ptr] != ' ') { + valEnd = raw[ptr - 1] == '\n' ? ptr - 1 : ptr; + break; + } + } + if (keyStart == msgB) { + // Fist line cannot be a footer + continue; + } + r.add(new FooterLine(raw, enc, keyStart, keyEnd, valStart, valEnd)); + } + + return r; + } + + /** + * Get the values of all footer lines with the given key. + * + * @param footers + * list of footers to find the values in. + * @param keyName + * footer key to find values of, case-insensitive. + * @return values of footers with key of {@code keyName}, ordered by their + * order of appearance. Duplicates may be returned if the same + * footer appeared more than once. Empty list if no footers appear + * with the specified key, or there are no footers at all. + * @see #fromMessage + * @since 6.7 + */ + public static List<String> getValues(List<FooterLine> footers, String keyName) { + return getValues(footers, new FooterKey(keyName)); + } + + /** + * Get the values of all footer lines with the given key. + * + * @param footers + * list of footers to find the values in. + * @param key + * footer key to find values of, case-insensitive. + * @return values of footers with key of {@code keyName}, ordered by their + * order of appearance. Duplicates may be returned if the same + * footer appeared more than once. Empty list if no footers appear + * with the specified key, or there are no footers at all. + * @see #fromMessage + * @since 6.7 + */ + public static List<String> getValues(List<FooterLine> footers, FooterKey key) { + if (footers.isEmpty()) + return Collections.emptyList(); + ArrayList<String> r = new ArrayList<>(footers.size()); + for (FooterLine f : footers) { + if (f.matches(key)) + r.add(f.getValue()); + } + return r; + } + + /** * Whether keys match * * @param key @@ -90,7 +224,7 @@ public final class FooterLine { * character encoding. */ public String getValue() { - return RawParseUtils.decode(enc, buffer, valStart, valEnd); + return RawParseUtils.decode(enc, buffer, valStart, valEnd).replaceAll("\n +", " "); //$NON-NLS-1$ //$NON-NLS-2$ } /** @@ -117,7 +251,28 @@ public final class FooterLine { return RawParseUtils.decode(enc, buffer, lt, gt - 1); } - /** {@inheritDoc} */ + /** + * @return start offset of the footer relative to the original raw message + * byte buffer + * + * @see #fromMessage(byte[]) + * @since 6.9 + */ + public int getStartOffset() { + return keyStart; + } + + /** + * @return end offset of the footer relative to the original raw message + * byte buffer + * + * @see #fromMessage(byte[]) + * @since 6.9 + */ + public int getEndOffset() { + return valEnd; + } + @Override public String toString() { return getKey() + ": " + getValue(); //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java index 3493dcfb47..d97812ff45 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java @@ -71,8 +71,11 @@ abstract class Generator { * * @return next available commit; null if no more are to be returned. * @throws MissingObjectException + * if an object is missing * @throws IncorrectObjectTypeException + * if an object has an unexpected type * @throws IOException + * if an IO error occurred */ abstract RevCommit next() throws MissingObjectException, IncorrectObjectTypeException, IOException; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java index 4773ca8427..ae67ca7599 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java @@ -34,7 +34,6 @@ public class LIFORevQueue extends BlockRevQueue { super(s); } - /** {@inheritDoc} */ @Override public void add(RevCommit c) { Block b = head; @@ -47,7 +46,6 @@ public class LIFORevQueue extends BlockRevQueue { b.unpop(c); } - /** {@inheritDoc} */ @Override public RevCommit next() { final Block b = head; @@ -62,7 +60,6 @@ public class LIFORevQueue extends BlockRevQueue { return c; } - /** {@inheritDoc} */ @Override public void clear() { head = null; @@ -89,7 +86,6 @@ public class LIFORevQueue extends BlockRevQueue { return false; } - /** {@inheritDoc} */ @Override public String toString() { final StringBuilder s = new StringBuilder(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java index a213dd47c6..be29dc3138 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java @@ -12,7 +12,7 @@ package org.eclipse.jgit.revwalk; import java.io.IOException; import java.text.MessageFormat; -import java.util.LinkedList; +import java.util.ArrayDeque; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; @@ -47,7 +47,8 @@ class MergeBaseGenerator extends Generator { private int recarryTest; private int recarryMask; private int mergeBaseAncestor = -1; - private LinkedList<RevCommit> ret = new LinkedList<>(); + + private ArrayDeque<RevCommit> ret = new ArrayDeque<>(); private CarryStack stack; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java index 4e48a5c328..7c763bc9b8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java @@ -43,7 +43,7 @@ import org.eclipse.jgit.util.RawParseUtils; * Tree and blob objects reachable from interesting commits are automatically * scheduled for inclusion in the results of {@link #nextObject()}, returning * each object exactly once. Objects are sorted and returned according to the - * the commits that reference them and the order they appear within a tree. + * commits that reference them and the order they appear within a tree. * Ordering can be affected by changing the * {@link org.eclipse.jgit.revwalk.RevSort} used to order the commits that are * returned first. @@ -164,29 +164,6 @@ public class ObjectWalk extends RevWalk { } /** - * Create an object reachability checker that will use bitmaps if possible. - * - * This reachability checker accepts any object as target. For checks - * exclusively between commits, see - * {@link RevWalk#createReachabilityChecker()}. - * - * @return an object reachability checker, using bitmaps if possible. - * - * @throws IOException - * when the index fails to load. - * - * @since 5.8 - * @deprecated use - * {@code ObjectReader#createObjectReachabilityChecker(ObjectWalk)} - * instead. - */ - @Deprecated - public final ObjectReachabilityChecker createObjectReachabilityChecker() - throws IOException { - return reader.createObjectReachabilityChecker(this); - } - - /** * Mark an object or commit to start graph traversal from. * <p> * Callers are encouraged to use @@ -300,14 +277,12 @@ public class ObjectWalk extends RevWalk { addObject(o); } - /** {@inheritDoc} */ @Override public void sort(RevSort s) { super.sort(s); boundary = hasRevSort(RevSort.BOUNDARY); } - /** {@inheritDoc} */ @Override public void sort(RevSort s, boolean use) { super.sort(s, use); @@ -357,7 +332,6 @@ public class ObjectWalk extends RevWalk { visitationPolicy = requireNonNull(policy); } - /** {@inheritDoc} */ @Override public RevCommit next() throws MissingObjectException, IncorrectObjectTypeException, IOException { @@ -645,6 +619,8 @@ public class ObjectWalk extends RevWalk { } /** + * Get the current traversal depth from the root tree object + * * @return the current traversal depth from the root tree object * @since 5.4 */ @@ -762,7 +738,6 @@ public class ObjectWalk extends RevWalk { pathBuf = newBuf; } - /** {@inheritDoc} */ @Override public void dispose() { super.dispose(); @@ -771,7 +746,6 @@ public class ObjectWalk extends RevWalk { freeVisit = null; } - /** {@inheritDoc} */ @Override protected void reset(int retainFlags) { super.reset(retainFlags); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java index d499084b42..5afb669a15 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java @@ -26,42 +26,8 @@ import org.eclipse.jgit.errors.MissingObjectException; * @since 5.4 */ public interface ReachabilityChecker { - - /** - * Check if all targets are reachable from the {@code starter} commits. - * <p> - * Caller should parse the objectIds (preferably with - * {@code walk.parseCommit()} and handle missing/incorrect type objects - * before calling this method. - * - * @param targets - * commits to reach. - * @param starters - * known starting points. - * @return An unreachable target if at least one of the targets is - * unreachable. An empty optional if all targets are reachable from - * the starters. - * - * @throws MissingObjectException - * if any of the incoming objects doesn't exist in the - * repository. - * @throws IncorrectObjectTypeException - * if any of the incoming objects is not a commit or a tag. - * @throws IOException - * if any of the underlying indexes or readers can not be - * opened. - * - * @deprecated see {{@link #areAllReachable(Collection, Stream)} - */ - @Deprecated - default Optional<RevCommit> areAllReachable(Collection<RevCommit> targets, - Collection<RevCommit> starters) throws MissingObjectException, - IncorrectObjectTypeException, IOException { - return areAllReachable(targets, starters.stream()); - } - /** - * Check if all targets are reachable from the {@code starter} commits. + * Check if all targets are reachable from the {@code starters} commits. * <p> * Caller should parse the objectIds (preferably with * {@code walk.parseCommit()} and handle missing/incorrect type objects diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RenameCallback.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RenameCallback.java index ba3399ce9f..9856f2c252 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RenameCallback.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RenameCallback.java @@ -23,8 +23,30 @@ public abstract class RenameCallback { * Called whenever a diff was found that is actually a rename or copy of a * file. * + * <p>Subclass of this class have to override this to receive diffEntry for + * the rename. + * * @param entry * the entry representing the rename/copy */ public abstract void renamed(DiffEntry entry); + + /** + * Called whenever a diff was found that is actually a rename or copy of a + * file along with the commit that caused it. + * + * <p>Subclass of this class have an option to override this if it wants to + * know what commit generated the diffEntry. Otherwise defaults to the + * {@link RenameCallback#renamed(DiffEntry)} function. + * + * @param entry + * the entry representing the rename/copy + * @param commit + * commit at which callback occurred + * + * @since 6.7 + */ + public void renamed(DiffEntry entry, RevCommit commit) { + renamed(entry); + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevBlob.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevBlob.java index f5abbb870a..1f81b6a922 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevBlob.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevBlob.java @@ -33,7 +33,6 @@ public class RevBlob extends RevObject { super(id); } - /** {@inheritDoc} */ @Override public final int getType() { return Constants.OBJ_BLOB; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java index b64c9ce906..871545fca2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java @@ -1,6 +1,6 @@ /* - * Copyright (C) 2008-2009, Google Inc. - * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others + * Copyright (C) 2008, 2009 Google Inc. + * Copyright (C) 2008, 2024 Shawn O. Pearce <spearce@spearce.org> 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 @@ -11,20 +11,18 @@ package org.eclipse.jgit.revwalk; -import static java.nio.charset.StandardCharsets.UTF_8; +import static org.eclipse.jgit.util.RawParseUtils.guessEncoding; import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.MutableObjectId; @@ -222,7 +220,6 @@ public class RevCommit extends RevObject { flags |= PARSED; } - /** {@inheritDoc} */ @Override public final int getType() { return Constants.OBJ_COMMIT; @@ -404,14 +401,14 @@ public class RevCommit extends RevObject { * @since 5.1 */ public final byte[] getRawGpgSignature() { - final byte[] raw = buffer; - final byte[] header = { 'g', 'p', 'g', 's', 'i', 'g' }; - final int start = RawParseUtils.headerStart(header, raw, 0); + byte[] raw = buffer; + byte[] header = { 'g', 'p', 'g', 's', 'i', 'g' }; + int start = RawParseUtils.headerStart(header, raw, 0); if (start < 0) { return null; } - final int end = RawParseUtils.headerEnd(raw, start); - return Arrays.copyOfRange(raw, start, end); + int end = RawParseUtils.nextLfSkippingSplitLines(raw, start); + return RawParseUtils.headerValue(raw, start, end); } /** @@ -484,7 +481,8 @@ public class RevCommit extends RevObject { if (msgB < 0) { return ""; //$NON-NLS-1$ } - return RawParseUtils.decode(guessEncoding(), raw, msgB, raw.length); + return RawParseUtils.decode(guessEncoding(buffer), raw, msgB, + raw.length); } /** @@ -510,7 +508,8 @@ public class RevCommit extends RevObject { } int msgE = RawParseUtils.endOfParagraph(raw, msgB); - String str = RawParseUtils.decode(guessEncoding(), raw, msgB, msgE); + String str = RawParseUtils.decode(guessEncoding(buffer), raw, msgB, + msgE); if (hasLF(raw, msgB, msgE)) { str = StringUtils.replaceLineBreaksWithSpace(str); } @@ -525,6 +524,30 @@ public class RevCommit extends RevObject { } /** + * Parse the commit message and return its first line, i.e., everything up + * to but not including the first newline, if any. + * + * @return the first line of the decoded commit message as a string; never + * {@code null}. + * @since 7.2 + */ + public final String getFirstMessageLine() { + int msgB = RawParseUtils.commitMessage(buffer, 0); + if (msgB < 0) { + return ""; //$NON-NLS-1$ + } + int msgE = msgB; + byte[] raw = buffer; + while (msgE < raw.length && raw[msgE] != '\n') { + msgE++; + } + if (msgE > msgB && msgE > 0 && raw[msgE - 1] == '\r') { + msgE--; + } + return RawParseUtils.decode(guessEncoding(buffer), buffer, msgB, msgE); + } + + /** * Determine the encoding of the commit message buffer. * <p> * Locates the "encoding" header (if present) and returns its value. Due to @@ -562,14 +585,6 @@ public class RevCommit extends RevObject { return RawParseUtils.parseEncoding(buffer); } - private Charset guessEncoding() { - try { - return getEncoding(); - } catch (IllegalCharsetNameException | UnsupportedCharsetException e) { - return UTF_8; - } - } - /** * Parse the footer lines (e.g. "Signed-off-by") for machine processing. * <p> @@ -578,8 +593,9 @@ public class RevCommit extends RevObject { * the order of the line's appearance in the commit message itself. * <p> * A footer line's key must match the pattern {@code ^[A-Za-z0-9-]+:}, while - * the value is free-form, but must not contain an LF. Very common keys seen - * in the wild are: + * the value is free-form. The Value may be split over multiple lines with + * each subsequent line starting with at least one whitespace. Very common + * keys seen in the wild are: * <ul> * <li>{@code Signed-off-by} (agrees to Developer Certificate of Origin) * <li>{@code Acked-by} (thinks change looks sane in context) @@ -592,50 +608,14 @@ public class RevCommit extends RevObject { * @return ordered list of footer lines; empty list if no footers found. */ public final List<FooterLine> getFooterLines() { - final byte[] raw = buffer; - int ptr = raw.length - 1; - while (raw[ptr] == '\n') // trim any trailing LFs, not interesting - ptr--; - - final int msgB = RawParseUtils.commitMessage(raw, 0); - final ArrayList<FooterLine> r = new ArrayList<>(4); - final Charset enc = guessEncoding(); - for (;;) { - ptr = RawParseUtils.prevLF(raw, ptr); - if (ptr <= msgB) - break; // Don't parse commit headers as footer lines. - - final int keyStart = ptr + 2; - if (raw[keyStart] == '\n') - break; // Stop at first paragraph break, no footers above it. - - final int keyEnd = RawParseUtils.endOfFooterLineKey(raw, keyStart); - if (keyEnd < 0) - continue; // Not a well formed footer line, skip it. - - // Skip over the ': *' at the end of the key before the value. - // - int valStart = keyEnd + 1; - while (valStart < raw.length && raw[valStart] == ' ') - valStart++; - - // Value ends at the LF, and does not include it. - // - int valEnd = RawParseUtils.nextLF(raw, valStart); - if (raw[valEnd - 1] == '\n') - valEnd--; - - r.add(new FooterLine(raw, enc, keyStart, keyEnd, valStart, valEnd)); - } - Collections.reverse(r); - return r; + return FooterLine.fromMessage(buffer); } /** * Get the values of all footer lines with the given key. * * @param keyName - * footer key to find values of, case insensitive. + * footer key to find values of, case-insensitive. * @return values of footers with key of {@code keyName}, ordered by their * order of appearance. Duplicates may be returned if the same * footer appeared more than once. Empty list if no footers appear @@ -643,30 +623,22 @@ public class RevCommit extends RevObject { * @see #getFooterLines() */ public final List<String> getFooterLines(String keyName) { - return getFooterLines(new FooterKey(keyName)); + return FooterLine.getValues(getFooterLines(), keyName); } /** * Get the values of all footer lines with the given key. * - * @param keyName - * footer key to find values of, case insensitive. + * @param key + * footer key to find values of, case-insensitive. * @return values of footers with key of {@code keyName}, ordered by their * order of appearance. Duplicates may be returned if the same * footer appeared more than once. Empty list if no footers appear * with the specified key, or there are no footers at all. * @see #getFooterLines() */ - public final List<String> getFooterLines(FooterKey keyName) { - final List<FooterLine> src = getFooterLines(); - if (src.isEmpty()) - return Collections.emptyList(); - final ArrayList<String> r = new ArrayList<>(src.size()); - for (FooterLine f : src) { - if (f.matches(keyName)) - r.add(f.getValue()); - } - return r; + public final List<String> getFooterLines(FooterKey key) { + return FooterLine.getValues(getFooterLines(), key); } /** @@ -688,6 +660,21 @@ public class RevCommit extends RevObject { } /** + * Get the changed path filter of the commit. + * <p> + * This is null when there is no commit graph file, the commit is not in the + * commit graph file, or the commit graph file was generated without changed + * path filters. + * + * @param rw A revwalk to load the commit graph (if available) + * @return the changed path filter + * @since 6.7 + */ + public ChangedPathFilter getChangedPathFilter(RevWalk rw) { + return null; + } + + /** * Reset this commit to allow another RevWalk with the same instances. * <p> * Subclasses <b>must</b> call <code>super.reset()</code> to ensure the @@ -713,7 +700,6 @@ public class RevCommit extends RevObject { buffer = null; } - /** {@inheritDoc} */ @Override public String toString() { final StringBuilder s = new StringBuilder(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java index 4d3664da11..c7a03992b7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java @@ -14,6 +14,7 @@ import java.io.IOException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter; import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; @@ -44,7 +45,6 @@ class RevCommitCG extends RevCommit { this.graphPosition = graphPosition; } - /** {@inheritDoc} */ @Override void parseCanonical(RevWalk walk, byte[] raw) throws IOException { if (walk.isRetainBody()) { @@ -53,7 +53,6 @@ class RevCommitCG extends RevCommit { parseInGraph(walk); } - /** {@inheritDoc} */ @Override void parseHeaders(RevWalk walk) throws MissingObjectException, IncorrectObjectTypeException, IOException { @@ -98,9 +97,14 @@ class RevCommitCG extends RevCommit { flags |= PARSED; } - /** {@inheritDoc} */ @Override int getGeneration() { return generation; } + + /** {@inheritDoc} */ + @Override + public ChangedPathFilter getChangedPathFilter(RevWalk rw) { + return rw.commitGraph().getChangedPathFilter(graphPosition); + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitList.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitList.java index 59213a8e60..58f5d425cc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitList.java @@ -25,7 +25,6 @@ import org.eclipse.jgit.revwalk.filter.RevFilter; public class RevCommitList<E extends RevCommit> extends RevObjectList<E> { private RevWalk walker; - /** {@inheritDoc} */ @Override public void clear() { super.clear(); @@ -313,7 +312,6 @@ public class RevCommitList<E extends RevCommit> extends RevObjectList<E> { * walker specified by {@link #source(RevWalk)} is pumped until the * specified commit is loaded. Callers can test the final size of the list * by {@link #size()} to determine if the high water mark specified was met. - * <p> * * @param commitToLoad * commit the caller wants this list to contain when the fill diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java index a0160ddbef..3221bf6e8f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java @@ -67,7 +67,6 @@ public class RevFlag { return walker; } - /** {@inheritDoc} */ @Override public String toString() { return name; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java index 4d2684a0f0..55ea30d24b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java @@ -132,7 +132,6 @@ public abstract class RevObject extends ObjectIdOwnerMap.Entry { flags &= ~set.mask; } - /** {@inheritDoc} */ @Override public String toString() { final StringBuilder s = new StringBuilder(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java index 0393f55957..ad8aeedeb9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java @@ -47,7 +47,6 @@ public class RevObjectList<E extends RevObject> extends AbstractList<E> { // Initialized above. } - /** {@inheritDoc} */ @Override public void add(int index, E element) { if (index != size) @@ -58,7 +57,6 @@ public class RevObjectList<E extends RevObject> extends AbstractList<E> { size++; } - /** {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public E set(int index, E element) { @@ -80,7 +78,6 @@ public class RevObjectList<E extends RevObject> extends AbstractList<E> { return (E) old; } - /** {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public E get(int index) { @@ -95,13 +92,11 @@ public class RevObjectList<E extends RevObject> extends AbstractList<E> { return s != null ? (E) s.contents[index] : null; } - /** {@inheritDoc} */ @Override public int size() { return size; } - /** {@inheritDoc} */ @Override public void clear() { contents = new Block(0); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java index b9d145008b..0737a78085 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java @@ -38,8 +38,17 @@ import org.eclipse.jgit.util.StringUtils; */ public class RevTag extends RevObject { - private static final byte[] hSignature = Constants - .encodeASCII("-----BEGIN PGP SIGNATURE-----"); //$NON-NLS-1$ + private static final byte[] SIGNATURE_START = Constants + .encodeASCII("-----BEGIN"); //$NON-NLS-1$ + + private static final byte[] GPG_SIGNATURE_START = Constants + .encodeASCII(Constants.GPG_SIGNATURE_PREFIX); + + private static final byte[] CMS_SIGNATURE_START = Constants + .encodeASCII(Constants.CMS_SIGNATURE_PREFIX); + + private static final byte[] SSH_SIGNATURE_START = Constants + .encodeASCII(Constants.SSH_SIGNATURE_PREFIX); /** * Parse an annotated tag from its canonical format. @@ -149,7 +158,6 @@ public class RevTag extends RevObject { flags |= PARSED; } - /** {@inheritDoc} */ @Override public final int getType() { return Constants.OBJ_TAG; @@ -209,20 +217,27 @@ public class RevTag extends RevObject { return msgB; } // Find the last signature start and return the rest - int start = nextStart(hSignature, raw, msgB); + int start = nextStart(SIGNATURE_START, raw, msgB); if (start < 0) { return start; } int next = RawParseUtils.nextLF(raw, start); while (next < raw.length) { - int newStart = nextStart(hSignature, raw, next); + int newStart = nextStart(SIGNATURE_START, raw, next); if (newStart < 0) { break; } start = newStart; next = RawParseUtils.nextLF(raw, start); } - return start; + // SIGNATURE_START is just a prefix. Check that it is one of the known + // full signature start tags. + if (RawParseUtils.match(raw, start, GPG_SIGNATURE_START) > 0 + || RawParseUtils.match(raw, start, CMS_SIGNATURE_START) > 0 + || RawParseUtils.match(raw, start, SSH_SIGNATURE_START) > 0) { + return start; + } + return -1; } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTree.java index 8119af468a..d81af0c029 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTree.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTree.java @@ -33,7 +33,6 @@ public class RevTree extends RevObject { super(id); } - /** {@inheritDoc} */ @Override public final int getType() { return Constants.OBJ_TREE; 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 3737c6b67b..41f98bad84 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -19,8 +19,14 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util. +Optional; +import java.util.Set; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; @@ -30,9 +36,9 @@ import org.eclipse.jgit.errors.LargeObjectException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.RevWalkException; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.AsyncObjectLoaderQueue; -import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.MutableObjectId; import org.eclipse.jgit.lib.NullProgressMonitor; @@ -220,7 +226,6 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { /** * Create a new revision walker for a given repository. - * <p> * * @param or * the reader the walker will obtain data from. The reader is not @@ -236,7 +241,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { idBuffer = new MutableObjectId(); objects = new ObjectIdOwnerMap<>(); roots = new ArrayList<>(); - queue = new DateRevQueue(false); + queue = newDateRevQueue(false); pending = new StartGenerator(this); sorting = EnumSet.of(RevSort.NONE); filter = RevFilter.ALL; @@ -245,6 +250,30 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { commitGraph = null; } + static AbstractRevQueue newDateRevQueue(boolean firstParent) { + if(usePriorityQueue()) { + return new DateRevPriorityQueue(firstParent); + } + + return new DateRevQueue(firstParent); + } + + static DateRevQueue newDateRevQueue(Generator g) throws IOException { + if(usePriorityQueue()) { + return new DateRevPriorityQueue(g); + } + + return new DateRevQueue(g); + } + + @SuppressWarnings("boxing") + private static boolean usePriorityQueue() { + return Optional + .ofNullable(System.getProperty("REVWALK_USE_PRIORITY_QUEUE")) //$NON-NLS-1$ + .map(Boolean::parseBoolean) + .orElse(false); + } + /** * Get the reader this walker is using to load objects. * @@ -255,23 +284,6 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { } /** - * Get a reachability checker for commits over this revwalk. - * - * @return the most efficient reachability checker for this repository. - * @throws IOException - * if it cannot open any of the underlying indices. - * - * @since 5.4 - * @deprecated use {@code ObjectReader#createReachabilityChecker(RevWalk)} - * instead. - */ - @Deprecated - public final ReachabilityChecker createReachabilityChecker() - throws IOException { - return reader.createReachabilityChecker(this); - } - - /** * {@inheritDoc} * <p> * Release any resources used by this walker's reader. @@ -454,7 +466,6 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { * <p> * A commit is merged into a ref if we can find a path of commits that leads * from that specific ref and ends at <code>commit</code>. - * <p> * * @param commit * commit the caller thinks is reachable from <code>refs</code>. @@ -476,7 +487,6 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { * <p> * A commit is merged into a ref if we can find a path of commits that leads * from that specific ref and ends at <code>commit</code>. - * <p> * * @param commit * commit the caller thinks is reachable from <code>refs</code>. @@ -518,6 +528,27 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { } /** + * Determine if a <code>commit</code> is merged into any of the given + * <code>revs</code>. + * + * @param commit + * commit the caller thinks is reachable from <code>revs</code>. + * @param revs + * commits to start iteration from, and which is most likely a + * descendant (child) of <code>commit</code>. + * @return true if commit is merged into any of the revs; false otherwise. + * @throws java.io.IOException + * a pack file or loose object could not be read. + * @since 6.10.1 + */ + public boolean isMergedIntoAnyCommit(RevCommit commit, Collection<RevCommit> revs) + throws IOException { + return getCommitsMergedInto(commit, revs, + GetMergedIntoStrategy.RETURN_ON_FIRST_FOUND, + NullProgressMonitor.INSTANCE).size() > 0; + } + + /** * Determine if a <code>commit</code> is merged into all of the given * <code>refs</code>. * @@ -540,7 +571,26 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { private List<Ref> getMergedInto(RevCommit needle, Collection<Ref> haystacks, Enum returnStrategy, ProgressMonitor monitor) throws IOException { + Map<RevCommit, List<Ref>> refsByCommit = new HashMap<>(); + for (Ref r : haystacks) { + RevObject o = peel(parseAny(r.getObjectId())); + if (!(o instanceof RevCommit)) { + continue; + } + refsByCommit.computeIfAbsent((RevCommit) o, c -> new ArrayList<>()).add(r); + } + monitor.update(1); List<Ref> result = new ArrayList<>(); + for (RevCommit c : getCommitsMergedInto(needle, refsByCommit.keySet(), + returnStrategy, monitor)) { + result.addAll(refsByCommit.get(c)); + } + return result; + } + + private Set<RevCommit> getCommitsMergedInto(RevCommit needle, Collection<RevCommit> haystacks, + Enum returnStrategy, ProgressMonitor monitor) throws IOException { + Set<RevCommit> result = new HashSet<>(); List<RevCommit> uninteresting = new ArrayList<>(); List<RevCommit> marked = new ArrayList<>(); RevFilter oldRF = filter; @@ -556,16 +606,11 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { needle.parseHeaders(this); } int cutoff = needle.getGeneration(); - for (Ref r : haystacks) { + for (RevCommit c : haystacks) { if (monitor.isCancelled()) { return result; } monitor.update(1); - RevObject o = peel(parseAny(r.getObjectId())); - if (!(o instanceof RevCommit)) { - continue; - } - RevCommit c = (RevCommit) o; reset(UNINTERESTING | TEMP_MARK); markStart(c); boolean commitFound = false; @@ -577,7 +622,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { } if (References.isSameObject(next, needle) || (next.flags & TEMP_MARK) != 0) { - result.add(r); + result.add(c); if (returnStrategy == GetMergedIntoStrategy.RETURN_ON_FIRST_FOUND) { return result; } @@ -824,6 +869,8 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { } /** + * Whether only first-parent links should be followed when walking + * * @return whether only first-parent links should be followed when walking. * * @since 5.5 @@ -848,7 +895,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { assertNotStarted(); assertNoCommitsMarkedStart(); firstParent = enable; - queue = new DateRevQueue(firstParent); + queue = newDateRevQueue(firstParent); pending = new StartGenerator(this); } @@ -1197,6 +1244,8 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { /** * Asynchronous object parsing. * + * @param <T> + * Type of returned {@code ObjectId} * @param objectIds * objects to open from the object store. The supplied collection * must not be modified until the queue has finished. @@ -1566,7 +1615,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { } roots.clear(); - queue = new DateRevQueue(firstParent); + queue = newDateRevQueue(firstParent); pending = new StartGenerator(this); } @@ -1587,7 +1636,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { firstParent = false; objects.clear(); roots.clear(); - queue = new DateRevQueue(firstParent); + queue = newDateRevQueue(firstParent); pending = new StartGenerator(this); shallowCommitsInitialized = false; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java index e52e916318..4bfe2fda02 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java @@ -51,8 +51,11 @@ public final class RevWalkUtils { * should be done until there are no more commits * @return the number of commits * @throws org.eclipse.jgit.errors.MissingObjectException + * if object is missing * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException + * if object has unexpected type * @throws java.io.IOException + * if an IO error occurred */ public static int count(final RevWalk walk, final RevCommit start, final RevCommit end) throws MissingObjectException, @@ -80,8 +83,11 @@ public final class RevWalkUtils { * should be done until there are no more commits * @return the commits found * @throws org.eclipse.jgit.errors.MissingObjectException + * if object is missing * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException + * if object has unexpected type * @throws java.io.IOException + * if an IO error occurred */ public static List<RevCommit> find(final RevWalk walk, final RevCommit start, final RevCommit end) @@ -116,8 +122,11 @@ public final class RevWalkUtils { * the set of branches we want to see reachability from * @return the list of branches a given commit is reachable from * @throws org.eclipse.jgit.errors.MissingObjectException + * if object is missing * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException + * if object has unexpected type * @throws java.io.IOException + * if an IO error occurred */ public static List<Ref> findBranchesReachableFrom(RevCommit commit, RevWalk revWalk, Collection<Ref> refs) @@ -147,8 +156,11 @@ public final class RevWalkUtils { * the callback for progress and cancellation * @return the list of branches a given commit is reachable from * @throws org.eclipse.jgit.errors.MissingObjectException + * if object is missing * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException + * if object has unexpected type * @throws java.io.IOException + * if an IO error occurred * @since 5.4 */ public static List<Ref> findBranchesReachableFrom(RevCommit commit, 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 2c88bb872e..4a93f4d745 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java @@ -101,9 +101,13 @@ class RewriteGenerator extends Generator { * of this commit by the previous {@link PendingGenerator}. * * @param c + * given commit * @throws MissingObjectException + * if an object is missing * @throws IncorrectObjectTypeException + * if an object has an unexpected type * @throws IOException + * if an IO error occurred */ private void applyFilterToParents(RevCommit c) throws MissingObjectException, IncorrectObjectTypeException, 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 a79901ca10..6854b6083d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java @@ -93,10 +93,11 @@ class StartGenerator extends Generator { final DateRevQueue pending; int pendingOutputType = 0; - if (q instanceof DateRevQueue) + if (q instanceof DateRevQueue) { pending = (DateRevQueue)q; - else - pending = new DateRevQueue(q); + } else { + pending = RevWalk.newDateRevQueue(q); + } if (tf != TreeFilter.ALL) { int rewriteFlag; if (w.getRewriteParents()) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java index 452545a04e..c9d8ff90fd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java @@ -33,8 +33,11 @@ class TopoNonIntermixSortGenerator extends Generator { * @param s * generator to pull all commits out of, and into this buffer. * @throws MissingObjectException + * if an object is missing * @throws IncorrectObjectTypeException + * if an object has an unexpected type * @throws IOException + * if an IO error occurred */ TopoNonIntermixSortGenerator(Generator s) throws MissingObjectException, IncorrectObjectTypeException, IOException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java index 4739f78fc0..950b0a45b4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java @@ -33,8 +33,11 @@ class TopoSortGenerator extends Generator { * @param s * generator to pull all commits out of, and into this buffer. * @throws MissingObjectException + * if an object is missing * @throws IncorrectObjectTypeException + * if an object has an unexpected type * @throws IOException + * if an IO error occurred */ TopoSortGenerator(Generator s) throws MissingObjectException, IncorrectObjectTypeException, IOException { 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 f921449ffa..e9a3e72c7f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java @@ -17,7 +17,6 @@ import org.eclipse.jgit.diff.DiffConfig; import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.diff.RenameDetector; -import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.StopWalkException; @@ -25,6 +24,7 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.revwalk.filter.RevFilter; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.TreeFilter; +import org.eclipse.jgit.treewalk.filter.TreeFilter.MutableBoolean; /** * Filter applying a {@link org.eclipse.jgit.treewalk.filter.TreeFilter} against @@ -47,6 +47,14 @@ public class TreeRevFilter extends RevFilter { private final TreeWalk pathFilter; + private final MutableBoolean changedPathFilterUsed = new MutableBoolean(); + + private long changedPathFilterTruePositive = 0; + + private long changedPathFilterFalsePositive = 0; + + private long changedPathFilterNegative = 0; + /** * Create a {@link org.eclipse.jgit.revwalk.filter.RevFilter} from a * {@link org.eclipse.jgit.treewalk.filter.TreeFilter}. @@ -92,13 +100,11 @@ public class TreeRevFilter extends RevFilter { this.rewriteFlag = rewriteFlag; } - /** {@inheritDoc} */ @Override public RevFilter clone() { throw new UnsupportedOperationException(); } - /** {@inheritDoc} */ @Override public boolean include(RevWalk walker, RevCommit c) throws StopWalkException, MissingObjectException, @@ -119,17 +125,34 @@ public class TreeRevFilter extends RevFilter { } trees[nParents] = c.getTree(); tw.reset(trees); + changedPathFilterUsed.reset(); if (nParents == 1) { // We have exactly one parent. This is a very common case. // int chgs = 0, adds = 0; - while (tw.next()) { - chgs++; - if (tw.getRawMode(0) == 0 && tw.getRawMode(1) != 0) { - adds++; - } else { - break; // no point in looking at this further. + TreeFilter tf = pathFilter.getFilter(); + boolean mustCalculateChgs = tf.shouldTreeWalk(c, walker, + changedPathFilterUsed); + if (mustCalculateChgs) { + while (tw.next()) { + chgs++; + if (tw.getRawMode(0) == 0 && tw.getRawMode(1) != 0) { + adds++; + } else { + break; // no point in looking at this further. + } + } + if (changedPathFilterUsed.get()) { + if (chgs > 0) { + changedPathFilterTruePositive++; + } else { + changedPathFilterFalsePositive++; + } + } + } else { + if (changedPathFilterUsed.get()) { + changedPathFilterNegative++; } } @@ -149,7 +172,8 @@ public class TreeRevFilter extends RevFilter { // commit. We need to update our filter to its older // name, if we can discover it. Find out what that is. // - updateFollowFilter(trees, ((FollowFilter) tw.getFilter()).cfg); + updateFollowFilter(trees, ((FollowFilter) tw.getFilter()).cfg, + c); } return true; } else if (nParents == 0) { @@ -241,15 +265,47 @@ public class TreeRevFilter extends RevFilter { return false; } - /** {@inheritDoc} */ @Override public boolean requiresCommitBody() { return false; } - private void updateFollowFilter(ObjectId[] trees, DiffConfig cfg) - throws MissingObjectException, IncorrectObjectTypeException, - CorruptObjectException, IOException { + /** + * Return how many times a changed path filter correctly predicted that a + * path was changed in a commit, for statistics gathering purposes. + * + * @return count of true positives + * @since 6.7 + */ + public long getChangedPathFilterTruePositive() { + return changedPathFilterTruePositive; + } + + /** + * Return how many times a changed path filter wrongly predicted that a path + * was changed in a commit, for statistics gathering purposes. + * + * @return count of false positives + * @since 6.7 + */ + public long getChangedPathFilterFalsePositive() { + return changedPathFilterFalsePositive; + } + + /** + * Return how many times a changed path filter predicted that a path was not + * changed in a commit (allowing that commit to be skipped), for statistics + * gathering purposes. + * + * @return count of negatives + * @since 6.7 + */ + public long getChangedPathFilterNegative() { + return changedPathFilterNegative; + } + + private void updateFollowFilter(ObjectId[] trees, DiffConfig cfg, + RevCommit commit) throws IOException { TreeWalk tw = pathFilter; FollowFilter oldFilter = (FollowFilter) tw.getFilter(); tw.setFilter(TreeFilter.ANY_DIFF); @@ -266,7 +322,7 @@ public class TreeRevFilter extends RevFilter { newFilter = FollowFilter.create(ent.getOldPath(), cfg); RenameCallback callback = oldFilter.getRenameCallback(); if (callback != null) { - callback.renamed(ent); + callback.renamed(ent, commit); // forward the callback to the new follow filter ((FollowFilter) newFilter).setRenameCallback(callback); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java index 6ac490a345..c9186b5491 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java @@ -12,6 +12,7 @@ package org.eclipse.jgit.revwalk.filter; import java.io.IOException; +import java.time.Instant; import java.util.Date; import org.eclipse.jgit.errors.IncorrectObjectTypeException; @@ -30,9 +31,24 @@ public abstract class CommitTimeRevFilter extends RevFilter { * @param ts * the point in time to cut on. * @return a new filter to select commits on or before <code>ts</code>. + * + * @deprecated Use {@link #before(Instant)} instead. */ + @Deprecated(since="7.2") public static final RevFilter before(Date ts) { - return before(ts.getTime()); + return before(ts.toInstant()); + } + + /** + * Create a new filter to select commits before a given date/time. + * + * @param ts + * the point in time to cut on. + * @return a new filter to select commits on or before <code>ts</code>. + * @since 7.2 + */ + public static RevFilter before(Instant ts) { + return new Before(ts); } /** @@ -43,7 +59,7 @@ public abstract class CommitTimeRevFilter extends RevFilter { * @return a new filter to select commits on or before <code>ts</code>. */ public static final RevFilter before(long ts) { - return new Before(ts); + return new Before(Instant.ofEpochMilli(ts)); } /** @@ -52,9 +68,24 @@ public abstract class CommitTimeRevFilter extends RevFilter { * @param ts * the point in time to cut on. * @return a new filter to select commits on or after <code>ts</code>. + * + * @deprecated Use {@link #after(Instant)} instead. */ + @Deprecated(since="7.2") public static final RevFilter after(Date ts) { - return after(ts.getTime()); + return after(ts.toInstant()); + } + + /** + * Create a new filter to select commits after a given date/time. + * + * @param ts + * the point in time to cut on. + * @return a new filter to select commits on or after <code>ts</code>. + * @since 7.2 + */ + public static RevFilter after(Instant ts) { + return new After(ts); } /** @@ -65,7 +96,7 @@ public abstract class CommitTimeRevFilter extends RevFilter { * @return a new filter to select commits on or after <code>ts</code>. */ public static final RevFilter after(long ts) { - return new After(ts); + return after(Instant.ofEpochMilli(ts)); } /** @@ -75,9 +106,28 @@ public abstract class CommitTimeRevFilter extends RevFilter { * @param since the point in time to cut on. * @param until the point in time to cut off. * @return a new filter to select commits between the given date/times. + * + * @deprecated Use {@link #between(Instant, Instant)} instead. */ + @Deprecated(since="7.2") public static final RevFilter between(Date since, Date until) { - return between(since.getTime(), until.getTime()); + return between(since.toInstant(), until.toInstant()); + } + + /** + * Create a new filter to select commits after or equal a given date/time + * <code>since</code> and before or equal a given date/time + * <code>until</code>. + * + * @param since + * the point in time to cut on. + * @param until + * the point in time to cut off. + * @return a new filter to select commits between the given date/times. + * @since 7.2 + */ + public static RevFilter between(Instant since, Instant until) { + return new Between(since, until); } /** @@ -87,9 +137,12 @@ public abstract class CommitTimeRevFilter extends RevFilter { * @param since the point in time to cut on, in milliseconds. * @param until the point in time to cut off, in millisconds. * @return a new filter to select commits between the given date/times. + * + * @deprecated Use {@link #between(Instant, Instant)} instead. */ + @Deprecated(since="7.2") public static final RevFilter between(long since, long until) { - return new Between(since, until); + return new Between(Instant.ofEpochMilli(since), Instant.ofEpochMilli(until)); } final int when; @@ -98,21 +151,23 @@ public abstract class CommitTimeRevFilter extends RevFilter { when = (int) (ts / 1000); } - /** {@inheritDoc} */ + CommitTimeRevFilter(Instant t) { + when = (int) t.getEpochSecond(); + } + @Override public RevFilter clone() { return this; } - /** {@inheritDoc} */ @Override public boolean requiresCommitBody() { return false; } private static class Before extends CommitTimeRevFilter { - Before(long ts) { - super(ts); + Before(Instant t) { + super(t); } @Override @@ -125,14 +180,12 @@ public abstract class CommitTimeRevFilter extends RevFilter { @SuppressWarnings("nls") @Override public String toString() { - return super.toString() + "(" + new Date(when * 1000L) + ")"; + return super.toString() + "(" + Instant.ofEpochSecond(when) + ")"; } } private static class After extends CommitTimeRevFilter { - After(long ts) { - super(ts); - } + After(Instant t) { super(t); } @Override public boolean include(RevWalk walker, RevCommit cmit) @@ -150,16 +203,16 @@ public abstract class CommitTimeRevFilter extends RevFilter { @SuppressWarnings("nls") @Override public String toString() { - return super.toString() + "(" + new Date(when * 1000L) + ")"; + return super.toString() + "(" + Instant.ofEpochSecond(when) + ")"; } } private static class Between extends CommitTimeRevFilter { private final int until; - Between(long since, long until) { + Between(Instant since, Instant until) { super(since); - this.until = (int) (until / 1000); + this.until = (int) until.getEpochSecond(); } @Override @@ -172,8 +225,8 @@ public abstract class CommitTimeRevFilter extends RevFilter { @SuppressWarnings("nls") @Override public String toString() { - return super.toString() + "(" + new Date(when * 1000L) + " - " - + new Date(until * 1000L) + ")"; + return super.toString() + "(" + Instant.ofEpochSecond(when) + " - " + + Instant.ofEpochSecond(until) + ")"; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/MaxCountRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/MaxCountRevFilter.java index 0e3a803b64..09bcb33f2e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/MaxCountRevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/MaxCountRevFilter.java @@ -46,7 +46,6 @@ public class MaxCountRevFilter extends RevFilter { this.maxCount = maxCount; } - /** {@inheritDoc} */ @Override public boolean include(RevWalk walker, RevCommit cmit) throws StopWalkException, MissingObjectException, @@ -57,7 +56,6 @@ public class MaxCountRevFilter extends RevFilter { return true; } - /** {@inheritDoc} */ @Override public RevFilter clone() { return new MaxCountRevFilter(maxCount); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/NotRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/NotRevFilter.java index 1482c51291..8fcebc9fa1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/NotRevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/NotRevFilter.java @@ -38,13 +38,11 @@ public class NotRevFilter extends RevFilter { a = one; } - /** {@inheritDoc} */ @Override public RevFilter negate() { return a; } - /** {@inheritDoc} */ @Override public boolean include(RevWalk walker, RevCommit c) throws MissingObjectException, IncorrectObjectTypeException, @@ -52,19 +50,16 @@ public class NotRevFilter extends RevFilter { return !a.include(walker, c); } - /** {@inheritDoc} */ @Override public boolean requiresCommitBody() { return a.requiresCommitBody(); } - /** {@inheritDoc} */ @Override public RevFilter clone() { return new NotRevFilter(a.clone()); } - /** {@inheritDoc} */ @Override public String toString() { return "NOT " + a.toString(); //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java index 256e4794cd..8430646305 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java @@ -264,7 +264,6 @@ public abstract class RevFilter { @Override public abstract RevFilter clone(); - /** {@inheritDoc} */ @Override public String toString() { String n = getClass().getName(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java index 16d9f76143..f9ee632b50 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java @@ -91,13 +91,11 @@ public abstract class RevFlagFilter extends RevFilter { flags = m; } - /** {@inheritDoc} */ @Override public RevFilter clone() { return this; } - /** {@inheritDoc} */ @Override public String toString() { return super.toString() + flags; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SkipRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SkipRevFilter.java index 84df36a2d2..bf93b7ba3e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SkipRevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SkipRevFilter.java @@ -45,7 +45,6 @@ public class SkipRevFilter extends RevFilter { this.skip = skip; } - /** {@inheritDoc} */ @Override public boolean include(RevWalk walker, RevCommit cmit) throws StopWalkException, MissingObjectException, @@ -55,7 +54,6 @@ public class SkipRevFilter extends RevFilter { return true; } - /** {@inheritDoc} */ @Override public RevFilter clone() { return new SkipRevFilter(skip); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SubStringRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SubStringRevFilter.java index 7f00dfd504..ff1fea2418 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SubStringRevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SubStringRevFilter.java @@ -67,7 +67,6 @@ public abstract class SubStringRevFilter extends RevFilter { pattern = new RawSubStringPattern(patternText); } - /** {@inheritDoc} */ @Override public boolean include(RevWalk walker, RevCommit cmit) throws MissingObjectException, IncorrectObjectTypeException, @@ -75,7 +74,6 @@ public abstract class SubStringRevFilter extends RevFilter { return pattern.match(text(cmit)) >= 0; } - /** {@inheritDoc} */ @Override public boolean requiresCommitBody() { return true; @@ -90,13 +88,11 @@ public abstract class SubStringRevFilter extends RevFilter { */ protected abstract RawCharSequence text(RevCommit cmit); - /** {@inheritDoc} */ @Override public RevFilter clone() { return this; // Typically we are actually thread-safe. } - /** {@inheritDoc} */ @SuppressWarnings("nls") @Override public String toString() { |