From a1a8c6d77ec5bea13c4f5ca428e425d95e14e003 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 16 Aug 2011 12:32:10 -0700 Subject: [PATCH] PackWriter: support excluding objects already in other packs This can be useful when implementing garbage collection and there are packs that should not be copied, such as huge packs that have a sibling ".keep" file alongside of them. Callers driving PackWriter need to initialize the list of packs not to include objects from by passing each index to excludeObjects(). Change-Id: Id7f34df69df97be406bcae184308e92b0e8690fd Signed-off-by: Shawn O. Pearce Signed-off-by: Chris Aniszczyk --- .../eclipse/jgit/storage/pack/PackWriter.java | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java index 766f0dfc7..d3bd693aa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java @@ -99,6 +99,7 @@ import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.storage.file.PackIndex; import org.eclipse.jgit.storage.file.PackIndexWriter; import org.eclipse.jgit.util.BlockList; import org.eclipse.jgit.util.TemporaryBuffer; @@ -157,6 +158,10 @@ public class PackWriter { private Set tagTargets = Collections.emptySet(); + private PackIndex[] excludeInPacks; + + private PackIndex excludeInPackLast; + private Deflater myDeflater; private final ObjectReader reader; @@ -425,6 +430,25 @@ public class PackWriter { return stats.totalObjects; } + /** + * Add a pack index whose contents should be excluded from the result. + * + * @param idx + * objects in this index will not be in the output pack. + */ + public void excludeObjects(PackIndex idx) { + if (excludeInPacks == null) { + excludeInPacks = new PackIndex[] { idx }; + excludeInPackLast = idx; + } else { + int cnt = excludeInPacks.length; + PackIndex[] newList = new PackIndex[cnt + 1]; + System.arraycopy(excludeInPacks, 0, newList, 0, cnt); + newList[cnt] = idx; + excludeInPacks = newList; + } + } + /** * Prepare the list of objects to be written to the pack stream. *

@@ -721,6 +745,9 @@ public class PackWriter { if (writeMonitor == null) writeMonitor = NullProgressMonitor.INSTANCE; + excludeInPacks = null; + excludeInPackLast = null; + boolean needSearchForReuse = reuseSupport != null && ( reuseDeltas || config.isReuseObjects() @@ -1459,6 +1486,8 @@ public class PackWriter { BlockList commits = new BlockList(); RevCommit c; while ((c = walker.next()) != null) { + if (exclude(c)) + continue; if (c.has(inCachedPack)) { CachedPack pack = tipToPack.get(c); if (includesAllTips(pack, include, walker)) { @@ -1524,6 +1553,8 @@ public class PackWriter { while ((o = walker.nextObject()) != null) { if (o.has(RevFlag.UNINTERESTING)) continue; + if (exclude(o)) + continue; int pathHash = walker.getPathHashCode(); byte[] pathBuf = walker.getPathBuffer(); @@ -1537,6 +1568,8 @@ public class PackWriter { while ((o = walker.nextObject()) != null) { if (o.has(RevFlag.UNINTERESTING)) continue; + if (exclude(o)) + continue; addObject(o, walker.getPathHashCode()); countingMonitor.update(1); } @@ -1608,7 +1641,8 @@ public class PackWriter { */ public void addObject(final RevObject object) throws IncorrectObjectTypeException { - addObject(object, 0); + if (!exclude(object)) + addObject(object, 0); } private void addObject(final RevObject object, final int pathHashCode) { @@ -1622,6 +1656,20 @@ public class PackWriter { objectsMap.add(otp); } + private boolean exclude(AnyObjectId objectId) { + if (excludeInPacks == null) + return false; + if (excludeInPackLast.hasObject(objectId)) + return true; + for (PackIndex idx : excludeInPacks) { + if (idx.hasObject(objectId)) { + excludeInPackLast = idx; + return true; + } + } + return false; + } + /** * Select an object representation for this writer. *