summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorJonathan Nieder <jrn@google.com>2017-04-17 14:53:19 -0400
committerGerrit Code Review @ Eclipse.org <gerrit@eclipse.org>2017-04-17 14:53:27 -0400
commitf9e13efe4780ca9ab9bd0725005012b852fe4f58 (patch)
treeb66051e222483b44d5d882c6bbf0ed1e87e5ad45 /org.eclipse.jgit
parenta6df70569ad5f87d4cac5c450d2f8d5c978669a2 (diff)
parentc2e6e7abc98b0c9716de61d6bcb586f0e353e9b0 (diff)
downloadjgit-f9e13efe4780ca9ab9bd0725005012b852fe4f58.tar.gz
jgit-f9e13efe4780ca9ab9bd0725005012b852fe4f58.zip
Merge "Process all "have"s even when MissingObjectException is encountered"
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java101
1 files changed, 67 insertions, 34 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java
index 7e3e189be7..34762495cf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java
@@ -44,7 +44,7 @@
package org.eclipse.jgit.internal.storage.pack;
import java.io.IOException;
-import java.util.Set;
+import java.util.Arrays;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
@@ -84,7 +84,55 @@ final class PackWriterBitmapWalker {
return countOfBitmapIndexMisses;
}
- BitmapBuilder findObjects(Set<? extends ObjectId> start, BitmapBuilder seen, boolean ignoreMissingStart)
+ BitmapBuilder findObjects(Iterable<? extends ObjectId> start, BitmapBuilder seen, boolean ignoreMissing)
+ throws MissingObjectException, IncorrectObjectTypeException,
+ IOException {
+ if (!ignoreMissing) {
+ return findObjectsWalk(start, seen, false);
+ }
+
+ try {
+ return findObjectsWalk(start, seen, true);
+ } catch (MissingObjectException ignore) {
+ // An object reachable from one of the "start"s is missing.
+ // Walk from the "start"s one at a time so it can be excluded.
+ }
+
+ final BitmapBuilder result = bitmapIndex.newBitmapBuilder();
+ for (ObjectId obj : start) {
+ Bitmap bitmap = bitmapIndex.getBitmap(obj);
+ if (bitmap != null) {
+ result.or(bitmap);
+ }
+ }
+
+ for (ObjectId obj : start) {
+ if (result.contains(obj)) {
+ continue;
+ }
+ try {
+ result.or(findObjectsWalk(Arrays.asList(obj), result, false));
+ } catch (MissingObjectException ignore) {
+ // An object reachable from this "start" is missing.
+ //
+ // This can happen when the client specified a "have" line
+ // pointing to an object that is present but unreachable:
+ // "git prune" and "git fsck" only guarantee that the object
+ // database will continue to contain all objects reachable
+ // from a ref and does not guarantee connectivity for other
+ // objects in the object database.
+ //
+ // In this situation, skip the relevant "start" and move on
+ // to the next one.
+ //
+ // TODO(czhen): Make findObjectsWalk resume the walk instead
+ // once RevWalk and ObjectWalk support that.
+ }
+ }
+ return result;
+ }
+
+ private BitmapBuilder findObjectsWalk(Iterable<? extends ObjectId> start, BitmapBuilder seen, boolean ignoreMissingStart)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {
final BitmapBuilder bitmapResult = bitmapIndex.newBitmapBuilder();
@@ -117,39 +165,24 @@ final class PackWriterBitmapWalker {
new AddUnseenToBitmapFilter(seen, bitmapResult));
}
- try {
- while (walker.next() != null) {
- // Iterate through all of the commits. The BitmapRevFilter does
- // the work.
- //
- // filter.include returns true for commits that do not have
- // a bitmap in bitmapIndex and are not reachable from a
- // bitmap in bitmapIndex encountered earlier in the walk.
- // Thus the number of commits returned by next() measures how
- // much history was traversed without being able to make use
- // of bitmaps.
- pm.update(1);
- countOfBitmapIndexMisses++;
- }
-
- RevObject ro;
- while ((ro = walker.nextObject()) != null) {
- bitmapResult.addObject(ro, ro.getType());
- pm.update(1);
- }
- } catch (MissingObjectException e) {
- if (!ignoreMissingStart) {
- throw e;
- }
- // Even when none of the objects we started the walk from is missing,
- // an object reachable from one can be. RevWalk and ObjectWalk don't
- // provide a way to ignore the missing object and continue, so bail
- // out early with an undersized bitmap.
+ while (walker.next() != null) {
+ // Iterate through all of the commits. The BitmapRevFilter does
+ // the work.
//
- // The resulting packfile is likely to be much too large, but that's
- // better than serving an error.
- //
- // TODO(czhen): Resume the walk instead once RevWalk supports that.
+ // filter.include returns true for commits that do not have
+ // a bitmap in bitmapIndex and are not reachable from a
+ // bitmap in bitmapIndex encountered earlier in the walk.
+ // Thus the number of commits returned by next() measures how
+ // much history was traversed without being able to make use
+ // of bitmaps.
+ pm.update(1);
+ countOfBitmapIndexMisses++;
+ }
+
+ RevObject ro;
+ while ((ro = walker.nextObject()) != null) {
+ bitmapResult.addObject(ro, ro.getType());
+ pm.update(1);
}
}