diff options
author | Ronald Bhuleskar <funronald@google.com> | 2022-08-03 16:41:43 -0700 |
---|---|---|
committer | Ronald Bhuleskar <funronald@google.com> | 2022-08-16 21:32:25 -0700 |
commit | 6297491e8adb85e43d60ffe75fb71f335e733449 (patch) | |
tree | 2b0e16f7108eef11d9b92f152db9b53e5669b691 /org.eclipse.jgit | |
parent | ab3799be37834a0ab9ac394eae1fe7c2766ee516 (diff) | |
download | jgit-6297491e8adb85e43d60ffe75fb71f335e733449.tar.gz jgit-6297491e8adb85e43d60ffe75fb71f335e733449.zip |
Adds FilteredRevCommit that can overwrites its parents in the DAG.
Change-Id: I1ea63a3b56074099688fc45d6a22943a8ae3c2ae
Diffstat (limited to 'org.eclipse.jgit')
3 files changed, 142 insertions, 8 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FilteredRevCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FilteredRevCommit.java new file mode 100644 index 0000000000..16beac3903 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FilteredRevCommit.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2022, Google LLC. + * + * 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; + +/** + * A filtered commit reference that overrides its parent in the DAG. + * + * @since 6.3 + */ +public class FilteredRevCommit extends RevCommit { + private RevCommit[] overriddenParents; + + /** + * Create a new commit reference wrapping an underlying commit reference. + * + * @param commit + * commit that is being wrapped + */ + public FilteredRevCommit(RevCommit commit) { + this(commit, NO_PARENTS); + } + + /** + * Create a new commit reference wrapping an underlying commit reference. + * + * @param commit + * commit that is being wrapped + * @param parents + * overridden parents for the commit + */ + public FilteredRevCommit(RevCommit commit, RevCommit... parents) { + super(commit); + this.overriddenParents = parents; + this.parents = NO_PARENTS; + } + + /** + * Update parents on the commit + * + * @param overriddenParents + * parents to be overwritten + */ + public void setParents(RevCommit... overriddenParents) { + this.overriddenParents = overriddenParents; + } + + /** + * Get the number of parent commits listed in this commit. + * + * @return number of parents; always a positive value but can be 0 if it has + * no parents. + */ + @Override + public int getParentCount() { + return overriddenParents.length; + } + + /** + * Get the nth parent from this commit's parent list. + * + * @param nth + * parent index to obtain. Must be in the range 0 through + * {@link #getParentCount()}-1. + * @return the specified parent. + * @throws java.lang.ArrayIndexOutOfBoundsException + * an invalid parent index was specified. + */ + @Override + public RevCommit getParent(int nth) { + return overriddenParents[nth]; + } + + /** + * Obtain an array of all parents (<b>NOTE - THIS IS NOT A COPY</b>). + * + * <p> + * This method is exposed only to provide very fast, efficient access to + * this commit's parent list. Applications relying on this list should be + * very careful to ensure they do not modify its contents during their use + * of it. + * + * @return the array of parents. + */ + @Override + public RevCommit[] getParents() { + return overriddenParents; + } +} 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 70490eec79..7f1e887074 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java @@ -109,7 +109,7 @@ public class RevCommit extends RevObject { * * @since 6.3 */ - protected RevCommit[] parents; + RevCommit[] parents; int commitTime; // An int here for performance, overflows in 2038 @@ -127,6 +127,22 @@ public class RevCommit extends RevObject { super(id); } + /** + * Create a new commit reference. + * + * @param orig + * commit to be copied from. + */ + RevCommit(RevCommit orig) { + super(orig.getId()); + this.buffer = orig.buffer; + this.commitTime = orig.commitTime; + this.flags = orig.flags; + this.parents = orig.parents; + this.tree = orig.tree; + this.inDegree = orig.inDegree; + } + @Override void parseHeaders(RevWalk walk) throws MissingObjectException, IncorrectObjectTypeException, IOException { 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..9ec331b697 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java @@ -11,6 +11,8 @@ package org.eclipse.jgit.revwalk; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; @@ -38,10 +40,13 @@ class RewriteGenerator extends Generator { private final FIFORevQueue pending; + private final Map<RevCommit, FilteredRevCommit> transformedCommits; + RewriteGenerator(Generator s) { super(s.firstParent); source = s; pending = new FIFORevQueue(s.firstParent); + transformedCommits = new HashMap<>(); } @Override @@ -58,10 +63,10 @@ class RewriteGenerator extends Generator { @Override RevCommit next() throws MissingObjectException, IncorrectObjectTypeException, IOException { - RevCommit c = pending.next(); + FilteredRevCommit c = (FilteredRevCommit) pending.next(); if (c == null) { - c = source.next(); + c = transform(source.next()); if (c == null) { // We are done: Both the source generator and our internal list // are completely exhausted. @@ -79,9 +84,9 @@ class RewriteGenerator extends Generator { final RevCommit newp = rewrite(oldp); if (firstParent) { if (newp == null) { - c.parents = RevCommit.NO_PARENTS; + c.setParents(RevCommit.NO_PARENTS); } else { - c.parents = new RevCommit[] { newp }; + c.setParents(newp); } return c; } @@ -91,7 +96,7 @@ class RewriteGenerator extends Generator { } } if (rewrote) { - c.parents = cleanup(pList); + c.setParents(cleanup(pList)); } return c; } @@ -111,7 +116,7 @@ class RewriteGenerator extends Generator { for (RevCommit parent : c.getParents()) { while ((parent.flags & RevWalk.TREE_REV_FILTER_APPLIED) == 0) { - RevCommit n = source.next(); + FilteredRevCommit n = transform(source.next()); if (n != null) { pending.add(n); @@ -130,6 +135,8 @@ class RewriteGenerator extends Generator { IncorrectObjectTypeException, IOException { for (;;) { + p = transform(p); + if (p.getParentCount() > 1) { // This parent is a merge, so keep it. // @@ -158,9 +165,25 @@ class RewriteGenerator extends Generator { } applyFilterToParents(p.getParent(0)); - p = p.getParent(0); + p = transform(p.getParent(0)); + + } + } + private FilteredRevCommit transform(RevCommit c) { + if (c == null) { + return null; } + + if (c instanceof FilteredRevCommit) { + return (FilteredRevCommit) c; + } + + if (!transformedCommits.containsKey(c)) { + transformedCommits.put(c, new FilteredRevCommit(c, c.getParents())); + } + + return transformedCommits.get(c); } private RevCommit[] cleanup(RevCommit[] oldList) { |