diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2025-02-01 02:41:43 +0100 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2025-02-01 02:41:43 +0100 |
commit | a6688497bfa44bb5d972e2b32acbf6db55d2ac51 (patch) | |
tree | 8c95c68a39421005fc5a06c7ba3abecb427d0717 | |
parent | 63c886834aa8c1934b4db00c751bff620c0f5729 (diff) | |
parent | 3ae99c1b926733fd4f64d78d55bb73a809d9cde9 (diff) | |
download | jgit-a6688497bfa44bb5d972e2b32acbf6db55d2ac51.tar.gz jgit-a6688497bfa44bb5d972e2b32acbf6db55d2ac51.zip |
Merge branch 'stable-7.1' into stable-7.2
* stable-7.1:
RevWalk: Add an isMergedIntoAnyCommit() method
Pack: separate an open/close accounting lock
http.server/BUILD: expose servlet resources as target
Change-Id: Ie53048a5154a4a40f7c0f9da3b8b829d305ab323
3 files changed, 85 insertions, 30 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java index 0a045c917b..ffc7c96f69 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java @@ -14,6 +14,7 @@ import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import java.util.Collection; +import java.util.HashSet; import java.util.List; import org.eclipse.jgit.api.Git; @@ -121,7 +122,7 @@ public class RevWalkUtilsReachableTest extends RevWalkTestCase { Collection<Ref> sortedRefs = RefComparator.sort(allRefs); List<Ref> actual = RevWalkUtils.findBranchesReachableFrom(commit, rw, sortedRefs); - assertEquals(refsThatShouldContainCommit, actual); + assertEquals(new HashSet<>(refsThatShouldContainCommit), new HashSet<>(actual)); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java index 8d2a86386f..1a7b5de1d7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java @@ -95,6 +95,9 @@ public class Pack implements Iterable<PackIndex.MutableEntry> { private RandomAccessFile fd; + /** For managing open/close accounting of {@link #fd}. */ + private final Object activeLock = new Object(); + /** Serializes reads performed against {@link #fd}. */ private final Object readLock = new Object(); @@ -645,37 +648,48 @@ public class Pack implements Iterable<PackIndex.MutableEntry> { throw new EOFException(); } - private synchronized void beginCopyAsIs() + private void beginCopyAsIs() throws StoredObjectRepresentationNotAvailableException { - if (++activeCopyRawData == 1 && activeWindows == 0) { - try { - doOpen(); - } catch (IOException thisPackNotValid) { - throw new StoredObjectRepresentationNotAvailableException( - thisPackNotValid); + synchronized (activeLock) { + if (++activeCopyRawData == 1 && activeWindows == 0) { + try { + doOpen(); + } catch (IOException thisPackNotValid) { + throw new StoredObjectRepresentationNotAvailableException( + thisPackNotValid); + } } } } - private synchronized void endCopyAsIs() { - if (--activeCopyRawData == 0 && activeWindows == 0) - doClose(); + private void endCopyAsIs() { + synchronized (activeLock) { + if (--activeCopyRawData == 0 && activeWindows == 0) { + doClose(); + } + } } - synchronized boolean beginWindowCache() throws IOException { - if (++activeWindows == 1) { - if (activeCopyRawData == 0) - doOpen(); - return true; + boolean beginWindowCache() throws IOException { + synchronized (activeLock) { + if (++activeWindows == 1) { + if (activeCopyRawData == 0) { + doOpen(); + } + return true; + } + return false; } - return false; } - synchronized boolean endWindowCache() { - final boolean r = --activeWindows == 0; - if (r && activeCopyRawData == 0) - doClose(); - return r; + boolean endWindowCache() { + synchronized (activeLock) { + boolean r = --activeWindows == 0; + if (r && activeCopyRawData == 0) { + doClose(); + } + return r; + } } private void doOpen() throws IOException { 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 9f0e28d0ce..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,9 +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.Optional; +import java.util.Map; +import java.util. +Optional; +import java.util.Set; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; @@ -523,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>. * @@ -545,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; @@ -561,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; @@ -582,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; } |