]> source.dussan.org Git - jgit.git/commitdiff
PackWriter: support excluding objects already in other packs 97/3997/8
authorShawn O. Pearce <spearce@spearce.org>
Tue, 16 Aug 2011 19:32:10 +0000 (12:32 -0700)
committerChris Aniszczyk <zx@twitter.com>
Sun, 21 Aug 2011 20:59:26 +0000 (13:59 -0700)
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 <spearce@spearce.org>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java

index 766f0dfc7ad314eea61d73222399a8f35cbf908c..d3bd693aa835179a5df6a6543f8c9357abbe1adc 100644 (file)
@@ -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<ObjectId> 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.
         * <p>
@@ -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<RevCommit> commits = new BlockList<RevCommit>();
                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.
         * <p>