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 b8b276767..f28f222c0 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 @@ -1116,6 +1116,7 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor, final Map tipToPack = new HashMap(); final RevFlag inCachedPack = walker.newFlag("inCachedPack"); final RevFlag include = walker.newFlag("include"); + final RevFlag added = walker.newFlag("added"); final RevFlagSet keepOnRestart = new RevFlagSet(); keepOnRestart.add(inCachedPack); @@ -1177,13 +1178,15 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor, int typesToPrune = 0; final int maxBases = config.getDeltaSearchWindowSize(); Set baseTrees = new HashSet(); - RevObject o; - while ((o = walker.next()) != null) { - if (o.has(inCachedPack)) { - CachedPack pack = tipToPack.get(o); + List commits = new ArrayList(); + RevCommit c; + while ((c = walker.next()) != null) { + if (c.has(inCachedPack)) { + CachedPack pack = tipToPack.get(c); if (includesAllTips(pack, include, walker)) { useCachedPack(walker, keepOnRestart, // wantObjs, haveObjs, pack); + commits = new ArrayList(); countingMonitor.endTask(); countingMonitor.beginTask(JGitText.get().countingObjects, @@ -1192,16 +1195,36 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor, } } - if (o.has(RevFlag.UNINTERESTING)) { + if (c.has(RevFlag.UNINTERESTING)) { if (baseTrees.size() <= maxBases) - baseTrees.add(((RevCommit) o).getTree()); + baseTrees.add(c.getTree()); continue; } - addObject(o, 0); + commits.add(c); countingMonitor.update(1); } + if (objectsLists[Constants.OBJ_COMMIT] instanceof ArrayList) { + ArrayList list = (ArrayList) objectsLists[Constants.OBJ_COMMIT]; + list.ensureCapacity(list.size() + commits.size()); + } + for (RevCommit cmit : commits) { + if (!cmit.has(added)) { + cmit.add(added); + addObject(cmit, 0); + } + + for (int i = 0; i < cmit.getParentCount(); i++) { + RevCommit p = cmit.getParent(i); + if (!p.has(added) && !p.has(RevFlag.UNINTERESTING)) { + p.add(added); + addObject(p, 0); + } + } + } + commits = null; + for (CachedPack p : cachedPacks) { for (ObjectId d : p.hasObject(objectsLists[Constants.OBJ_COMMIT])) { if (baseTrees.size() <= maxBases) @@ -1213,6 +1236,7 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor, BaseSearch bases = new BaseSearch(countingMonitor, baseTrees, // objectsMap, edgeObjects, reader); + RevObject o; while ((o = walker.nextObject()) != null) { if (o.has(RevFlag.UNINTERESTING)) continue; @@ -1284,9 +1308,6 @@ private void useCachedPack(ObjectWalk walker, RevFlagSet keepOnRestart, for (ObjectId id : pack.getTips()) baseObj.add(walker.lookupOrNull(id)); - objectsMap.clear(); - objectsLists[Constants.OBJ_COMMIT] = new ArrayList(); - setThin(true); walker.resetRetain(keepOnRestart); walker.sort(RevSort.TOPO);