示例#1
0
  /**
   * Run consistency checks against the object database.
   *
   * <p>This method completes silently if the checks pass. A temporary revision pool is constructed
   * during the checking.
   *
   * @param tips the tips to start checking from; if not supplied the refs of the repository are
   *     used instead.
   * @throws MissingObjectException
   * @throws IncorrectObjectTypeException
   * @throws IOException
   */
  public void fsck(RevObject... tips)
      throws MissingObjectException, IncorrectObjectTypeException, IOException {
    ObjectWalk ow = new ObjectWalk(db);
    if (tips.length != 0) {
      for (RevObject o : tips) ow.markStart(ow.parseAny(o));
    } else {
      for (Ref r : db.getAllRefs().values()) ow.markStart(ow.parseAny(r.getObjectId()));
    }

    ObjectChecker oc = new ObjectChecker();
    for (; ; ) {
      final RevCommit o = ow.next();
      if (o == null) break;

      final byte[] bin = db.open(o, o.getType()).getCachedBytes();
      oc.checkCommit(bin);
      assertHash(o, bin);
    }

    for (; ; ) {
      final RevObject o = ow.nextObject();
      if (o == null) break;

      final byte[] bin = db.open(o, o.getType()).getCachedBytes();
      oc.check(o.getType(), bin);
      assertHash(o, bin);
    }
  }
示例#2
0
  /**
   * Pop the next most recent object.
   *
   * @return next most recent object; null if traversal is over.
   * @throws MissingObjectException one or or more of the next objects are not available from the
   *     object database, but were thought to be candidates for traversal. This usually indicates a
   *     broken link.
   * @throws IncorrectObjectTypeException one or or more of the objects in a tree do not match the
   *     type indicated.
   * @throws IOException a pack file or loose object could not be read.
   */
  public RevObject nextObject()
      throws MissingObjectException, IncorrectObjectTypeException, IOException {
    if (last != null) treeWalk = last instanceof RevTree ? enter(last) : treeWalk.next();

    while (!treeWalk.eof()) {
      final FileMode mode = treeWalk.getEntryFileMode();
      switch (mode.getObjectType()) {
        case Constants.OBJ_BLOB:
          {
            treeWalk.getEntryObjectId(idBuffer);
            final RevBlob o = lookupBlob(idBuffer);
            if ((o.flags & SEEN) != 0) break;
            o.flags |= SEEN;
            if (shouldSkipObject(o)) break;
            last = o;
            return o;
          }
        case Constants.OBJ_TREE:
          {
            treeWalk.getEntryObjectId(idBuffer);
            final RevTree o = lookupTree(idBuffer);
            if ((o.flags & SEEN) != 0) break;
            o.flags |= SEEN;
            if (shouldSkipObject(o)) break;
            last = o;
            return o;
          }
        default:
          if (FileMode.GITLINK.equals(mode)) break;
          treeWalk.getEntryObjectId(idBuffer);
          throw new CorruptObjectException(
              MessageFormat.format(
                  JGitText.get().corruptObjectInvalidMode3,
                  mode,
                  idBuffer.name(),
                  treeWalk.getEntryPathString(),
                  currentTree.name()));
      }

      treeWalk = treeWalk.next();
    }

    last = null;
    for (; ; ) {
      final RevObject o = pendingObjects.next();
      if (o == null) return null;
      if ((o.flags & SEEN) != 0) continue;
      o.flags |= SEEN;
      if (shouldSkipObject(o)) continue;
      if (o instanceof RevTree) {
        currentTree = (RevTree) o;
        treeWalk = treeWalk.resetRoot(db, currentTree, curs);
      }
      return o;
    }
  }
  private void markCommon(final RevObject obj, final AckNackResult anr) throws IOException {
    if (statelessRPC && anr == AckNackResult.ACK_COMMON && !obj.has(STATE)) {
      StringBuilder s;

      s = new StringBuilder(6 + Constants.OBJECT_ID_STRING_LENGTH);
      s.append("have "); // $NON-NLS-1$
      s.append(obj.name());
      s.append('\n');
      pckState.writeString(s.toString());
      obj.add(STATE);
    }
    obj.add(COMMON);
    if (obj instanceof RevCommit) ((RevCommit) obj).carry(COMMON);
  }
示例#4
0
  private static byte[] getDelta(ObjectReader reader, RevObject obj)
      throws IOException, MissingObjectException, StoredObjectRepresentationNotAvailableException {
    ObjectReuseAsIs asis = (ObjectReuseAsIs) reader;
    ObjectToPack target = asis.newObjectToPack(obj, obj.getType());

    PackWriter pw =
        new PackWriter(reader) {
          @Override
          public void select(ObjectToPack otp, StoredObjectRepresentation next) {
            otp.select(next);
          }
        };

    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    asis.selectObjectRepresentation(
        pw, NullProgressMonitor.INSTANCE, Collections.singleton(target));
    asis.copyObjectAsIs(new PackOutputStream(NullProgressMonitor.INSTANCE, buf, pw), target, true);

    // At this point the object header has no delta information,
    // because it was output as though it were a whole object.
    // Skip over the header and inflate.
    //
    byte[] bufArray = buf.toByteArray();
    int ptr = 0;
    while ((bufArray[ptr] & 0x80) != 0) ptr++;
    ptr++;

    @SuppressWarnings("resource" /* java 7 */)
    TemporaryBuffer.Heap raw = new TemporaryBuffer.Heap(bufArray.length);
    InflaterInputStream inf =
        new InflaterInputStream(new ByteArrayInputStream(bufArray, ptr, bufArray.length));
    raw.copy(inf);
    inf.close();
    return raw.toByteArray();
  }
示例#5
0
  /**
   * Mark an object to not produce in the output.
   *
   * <p>Uninteresting objects denote not just themselves but also their entire reachable chain, back
   * until the merge base of an uninteresting commit and an otherwise interesting commit.
   *
   * <p>Callers are encouraged to use {@link RevWalk#parseAny(AnyObjectId)} instead of {@link
   * RevWalk#lookupAny(AnyObjectId, int)}, as this method requires the object to be parsed before it
   * can be added as a root for the traversal.
   *
   * <p>The method will automatically parse an unparsed object, but error handling may be more
   * difficult for the application to explain why a RevObject is not actually valid. The object pool
   * of this walker would also be 'poisoned' by the invalid RevObject.
   *
   * <p>This method will automatically call {@link RevWalk#markStart(RevCommit)} if passed RevCommit
   * instance, or a RevTag that directly (or indirectly) references a RevCommit.
   *
   * @param o the object to start traversing from. The object passed must be
   * @throws MissingObjectException the object supplied is not available from the object database.
   *     This usually indicates the supplied object is invalid, but the reference was constructed
   *     during an earlier invocation to {@link RevWalk#lookupAny(AnyObjectId, int)}.
   * @throws IncorrectObjectTypeException the object was not parsed yet and it was discovered during
   *     parsing that it is not actually the type of the instance passed in. This usually indicates
   *     the caller used the wrong type in a {@link RevWalk#lookupAny(AnyObjectId, int)} call.
   * @throws IOException a pack file or loose object could not be read.
   */
  public void markUninteresting(RevObject o)
      throws MissingObjectException, IncorrectObjectTypeException, IOException {
    while (o instanceof RevTag) {
      o.flags |= UNINTERESTING;
      if (hasRevSort(RevSort.BOUNDARY)) addObject(o);
      o = ((RevTag) o).getObject();
      parseHeaders(o);
    }

    if (o instanceof RevCommit) super.markUninteresting((RevCommit) o);
    else if (o instanceof RevTree) markTreeUninteresting((RevTree) o);
    else o.flags |= UNINTERESTING;

    if (o.getType() != Constants.OBJ_COMMIT && hasRevSort(RevSort.BOUNDARY)) {
      addObject(o);
    }
  }
示例#6
0
 private static void assertHash(RevObject id, byte[] bin) {
   MessageDigest md = Constants.newMessageDigest();
   md.update(Constants.encodedTypeString(id.getType()));
   md.update((byte) ' ');
   md.update(Constants.encodeASCII(bin.length));
   md.update((byte) 0);
   md.update(bin);
   assertEquals(id, ObjectId.fromRaw(md.digest()));
 }
示例#7
0
  @Override
  protected void run() throws Exception {
    ObjectReader reader = db.newObjectReader();
    RevObject obj = new RevWalk(reader).parseAny(objectId);
    byte[] delta = getDelta(reader, obj);

    // We're crossing our fingers that this will be a delta. Double
    // check the size field in the header, it should match.
    //
    long size = reader.getObjectSize(obj, obj.getType());
    try {
      if (BinaryDelta.getResultSize(delta) != size)
        throw die("Object " + obj.name() + " is not a delta");
    } catch (ArrayIndexOutOfBoundsException bad) {
      throw die("Object " + obj.name() + " is not a delta");
    }

    outw.println(BinaryDelta.format(delta));
  }
示例#8
0
 @NotNull
 public ConvertTask convertTask(@NotNull ObjectReader reader, @NotNull TaskKey key)
     throws IOException {
   switch (key.getType()) {
     case Simple:
       {
         if (!reader.has(key.getObjectId())) {
           return keepMissingTask(key.getObjectId());
         }
         final RevObject revObject = new RevWalk(reader).parseAny(key.getObjectId());
         if (revObject instanceof RevCommit) {
           return convertCommitTask((RevCommit) revObject);
         }
         if (revObject instanceof RevTree) {
           return convertTreeTask(reader, revObject, false);
         }
         if (revObject instanceof RevBlob) {
           return copyTask(reader, revObject);
         }
         if (revObject instanceof RevTag) {
           return convertTagTask((RevTag) revObject);
         }
         throw new IllegalStateException(
             "Unsupported object type: " + key + " (" + revObject.getClass().getName() + ")");
       }
     case Root:
       {
         final RevObject revObject = new RevWalk(reader).parseAny(key.getObjectId());
         if (revObject instanceof RevTree) {
           return convertTreeTask(reader, revObject, true);
         }
         throw new IllegalStateException(
             "Unsupported object type: " + key + " (" + revObject.getClass().getName() + ")");
       }
     case Attribute:
       return createAttributesTask(reader, key.getObjectId());
     case UploadLfs:
       return convertLfsTask(reader, key.getObjectId());
     default:
       throw new IllegalStateException("Unknwon task key type: " + key.getType());
   }
 }
  protected static RevCommit resolveCommitIdByTagName(Repository repository, String tagName)
      throws IOException, GitAPIException {
    if (tagName == null || tagName.isEmpty()) return null;
    RevCommit revCommit = null;
    Map<String, Ref> tagMap = repository.getTags();
    Ref ref = tagMap.get(tagName);
    if (ref != null) {
      RevWalk walk = new RevWalk(repository);
      // some reduce memory effors as described in jgit user guide
      walk.setRetainBody(false);
      ObjectId from;

      from = repository.resolve("refs/heads/master");
      if (from == null) {
        Git git = new Git(repository);
        String lastTagName = git.describe().call();
        from = repository.resolve("refs/tags/" + lastTagName);
      }
      ObjectId to = repository.resolve("refs/remotes/origin/master");

      if (from == null) {
        throw new IllegalStateException("cannot determinate start commit");
      }
      walk.markStart(walk.parseCommit(from));
      walk.markUninteresting(walk.parseCommit(to));
      try {

        RevObject revObject = walk.parseAny(ref.getObjectId());
        if (revObject != null) {
          revCommit = walk.parseCommit(revObject.getId());
        }

      } finally {
        walk.close();
      }
    }

    return revCommit;
  }
示例#10
0
  private void checkConnectivity() throws IOException {
    ObjectIdSubclassMap<ObjectId> baseObjects = null;
    ObjectIdSubclassMap<ObjectId> providedObjects = null;

    if (checkReferencedIsReachable) {
      baseObjects = parser.getBaseObjectIds();
      providedObjects = parser.getNewObjectIds();
    }
    parser = null;

    final ObjectWalk ow = new ObjectWalk(db);
    ow.setRetainBody(false);
    if (checkReferencedIsReachable) {
      ow.sort(RevSort.TOPO);
      if (!baseObjects.isEmpty()) ow.sort(RevSort.BOUNDARY, true);
    }

    for (final ReceiveCommand cmd : commands) {
      if (cmd.getResult() != Result.NOT_ATTEMPTED) continue;
      if (cmd.getType() == ReceiveCommand.Type.DELETE) continue;
      ow.markStart(ow.parseAny(cmd.getNewId()));
    }
    for (final ObjectId have : advertisedHaves) {
      RevObject o = ow.parseAny(have);
      ow.markUninteresting(o);

      if (checkReferencedIsReachable && !baseObjects.isEmpty()) {
        o = ow.peel(o);
        if (o instanceof RevCommit) o = ((RevCommit) o).getTree();
        if (o instanceof RevTree) ow.markUninteresting(o);
      }
    }

    RevCommit c;
    while ((c = ow.next()) != null) {
      if (checkReferencedIsReachable //
          && !c.has(RevFlag.UNINTERESTING) //
          && !providedObjects.contains(c))
        throw new MissingObjectException(c, Constants.TYPE_COMMIT);
    }

    RevObject o;
    while ((o = ow.nextObject()) != null) {
      if (o.has(RevFlag.UNINTERESTING)) continue;

      if (checkReferencedIsReachable) {
        if (providedObjects.contains(o)) continue;
        else throw new MissingObjectException(o, o.getType());
      }

      if (o instanceof RevBlob && !db.hasObject(o))
        throw new MissingObjectException(o, Constants.TYPE_BLOB);
    }

    if (checkReferencedIsReachable) {
      for (ObjectId id : baseObjects) {
        o = ow.parseAny(id);
        if (!o.has(RevFlag.UNINTERESTING)) throw new MissingObjectException(o, o.getType());
      }
    }
  }
示例#11
0
 private void addObject(final RevObject o) {
   if ((o.flags & IN_PENDING) == 0) {
     o.flags |= IN_PENDING;
     pendingObjects.add(o);
   }
 }