/**
  * Returns a list of references in the repository matching "refs". If the repository is null or
  * empty, an empty list is returned.
  *
  * @param repository
  * @param refs if unspecified, all refs are returned
  * @param fullName if true, /refs/something/yadayadayada is returned. If false, yadayadayada is
  *     returned.
  * @param maxCount if < 0, all references are returned
  * @return list of references
  */
 private static List<RefModel> getRefs(
     Repository repository, String refs, boolean fullName, int maxCount) {
   List<RefModel> list = new ArrayList<RefModel>();
   if (maxCount == 0) {
     return list;
   }
   if (!hasCommits(repository)) {
     return list;
   }
   try {
     Map<String, Ref> map = repository.getRefDatabase().getRefs(refs);
     RevWalk rw = new RevWalk(repository);
     for (Entry<String, Ref> entry : map.entrySet()) {
       Ref ref = entry.getValue();
       RevObject object = rw.parseAny(ref.getObjectId());
       String name = entry.getKey();
       if (fullName && !(refs == null)) {
         name = refs + name;
       }
       list.add(new RefModel(name, ref, object));
     }
     rw.dispose();
     Collections.sort(list);
     Collections.reverse(list);
     if (maxCount > 0 && list.size() > maxCount) {
       list = new ArrayList<RefModel>(list.subList(0, maxCount));
     }
   } catch (IOException e) {
     // todo
     Logger.error(e, e.getMessage());
   }
   return list;
 }
Beispiel #2
0
  @Override
  public void onContentChanged() {
    super.onContentChanged();
    Log.d(TAG, "updateUI called");
    tagRef = repo().getTags().get(tagName);
    if (objectSummaryView == null) {
      Log.d(TAG, "onContentChanged() : objectSummaryView is null");
      return;
    }

    if (tagRef == null) {
      getSupportActionBar().setTitle("unknown tag");
    } else {
      ObjectId peeledObjectId = repo().peel(tagRef).getPeeledObjectId();
      ObjectId taggedId = peeledObjectId == null ? tagRef.getObjectId() : peeledObjectId;
      RevWalk revWalk = new RevWalk(repo());

      ObjectId tagId = tagRef.getObjectId();
      try {
        final RevObject immediateTagRefObject = revWalk.parseAny(tagId);

        objectSummaryView.setObject(immediateTagRefObject, repo());

        if (immediateTagRefObject instanceof RevTag) {
          revTag = revWalk.parseTag(tagId);
          getSupportActionBar().setTitle(revTag.getTagName());
        }

      } catch (IOException e) {
        Log.e(TAG, "Couldn't get parse tag", e);
        Toast.makeText(this, "Couldn't get tag " + tagId, Toast.LENGTH_LONG).show();
      }
    }
  }
  private DhtRef doPeel(final Ref leaf) throws MissingObjectException, IOException {
    RevWalk rw = new RevWalk(getRepository());
    try {
      DhtReader ctx = (DhtReader) rw.getObjectReader();
      RevObject obj = rw.parseAny(leaf.getObjectId());
      RefData.Builder d = RefData.newBuilder(((DhtRef) leaf).getRefData());

      ChunkKey oKey = ctx.findChunk(leaf.getObjectId());
      if (oKey != null) d.getTargetBuilder().setChunkKey(oKey.asString());
      else d.getTargetBuilder().clearChunkKey();

      if (obj instanceof RevTag) {
        ObjectId pId = rw.peel(obj);
        d.getPeeledBuilder().setObjectName(pId.name());

        ChunkKey pKey = ctx.findChunk(pId);
        if (pKey != null) d.getPeeledBuilder().setChunkKey(pKey.asString());
        else d.getPeeledBuilder().clearChunkKey();
      } else {
        d.clearPeeled();
      }

      d.setIsPeeled(true);
      d.setSequence(d.getSequence() + 1);
      return new DhtObjectIdRef(leaf.getName(), d.build());
    } finally {
      rw.release();
    }
  }
 private void markAdvertised(final AnyObjectId id) {
   try {
     walk.parseAny(id).add(ADVERTISED);
   } catch (IOException readError) {
     // We probably just do not have this object locally.
   }
 }
  private boolean sendWants(final Collection<Ref> want) throws IOException {
    final PacketLineOut p = statelessRPC ? pckState : pckOut;
    boolean first = true;
    for (final Ref r : want) {
      try {
        if (walk.parseAny(r.getObjectId()).has(REACHABLE)) {
          // We already have this object. Asking for it is
          // not a very good idea.
          //
          continue;
        }
      } catch (IOException err) {
        // Its OK, we don't have it, but we want to fix that
        // by fetching the object from the other side.
      }

      final StringBuilder line = new StringBuilder(46);
      line.append("want ");
      line.append(r.getObjectId().name());
      if (first) {
        line.append(enableCapabilities());
        first = false;
      }
      line.append('\n');
      p.writeString(line.toString());
    }
    if (first) return false;
    p.end();
    outNeedsEnd = false;
    return true;
  }
Beispiel #6
0
 private ObjectIdRef doPeel(final Ref leaf) throws MissingObjectException, IOException {
   try (RevWalk rw = new RevWalk(getRepository())) {
     RevObject obj = rw.parseAny(leaf.getObjectId());
     if (obj instanceof RevTag) {
       return new ObjectIdRef.PeeledTag(
           leaf.getStorage(), leaf.getName(), leaf.getObjectId(), rw.peel(obj).copy());
     } else {
       return new ObjectIdRef.PeeledNonTag(leaf.getStorage(), leaf.getName(), leaf.getObjectId());
     }
   }
 }
Beispiel #7
0
  /**
   * Sets default values for not explicitly specified options. Then validates that all required data
   * has been provided.
   *
   * @param state the state of the repository we are working on
   * @param rw the RevWalk to use
   * @throws NoMessageException if the commit message has not been specified
   */
  private void processOptions(RepositoryState state, RevWalk rw) throws NoMessageException {
    if (committer == null) committer = new PersonIdent(repo);
    if (author == null && !amend) author = committer;
    if (allowEmpty == null)
      // JGit allows empty commits by default. Only when pathes are
      // specified the commit should not be empty. This behaviour differs
      // from native git but can only be adapted in the next release.
      // TODO(ch) align the defaults with native git
      allowEmpty = (only.isEmpty()) ? Boolean.TRUE : Boolean.FALSE;

    // when doing a merge commit parse MERGE_HEAD and MERGE_MSG files
    if (state == RepositoryState.MERGING_RESOLVED || isMergeDuringRebase(state)) {
      try {
        parents = repo.readMergeHeads();
        if (parents != null)
          for (int i = 0; i < parents.size(); i++) {
            RevObject ro = rw.parseAny(parents.get(i));
            if (ro instanceof RevTag) parents.set(i, rw.peel(ro));
          }
      } catch (IOException e) {
        throw new JGitInternalException(
            MessageFormat.format(
                JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_HEAD, e),
            e);
      }
      if (message == null) {
        try {
          message = repo.readMergeCommitMsg();
        } catch (IOException e) {
          throw new JGitInternalException(
              MessageFormat.format(
                  JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_MSG, e),
              e);
        }
      }
    } else if (state == RepositoryState.SAFE && message == null) {
      try {
        message = repo.readSquashCommitMsg();
        if (message != null) repo.writeSquashCommitMsg(null /* delete */);
      } catch (IOException e) {
        throw new JGitInternalException(
            MessageFormat.format(
                JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_MSG, e),
            e);
      }
    }
    if (message == null)
      // as long as we don't support -C option we have to have
      // an explicit message
      throw new NoMessageException(JGitText.get().commitMessageNotSpecified);
  }
 private int maxTimeWanted(final Collection<Ref> wants) {
   int maxTime = 0;
   for (final Ref r : wants) {
     try {
       final RevObject obj = walk.parseAny(r.getObjectId());
       if (obj instanceof RevCommit) {
         final int cTime = ((RevCommit) obj).getCommitTime();
         if (maxTime < cTime) maxTime = cTime;
       }
     } catch (IOException error) {
       // We don't have it, but we want to fetch (thus fixing error).
     }
   }
   return maxTime;
 }
Beispiel #9
0
  /**
   * Sets default values for not explicitly specified options. Then validates that all required data
   * has been provided.
   *
   * @param state the state of the repository we are working on
   * @param rw the RevWalk to use
   * @throws NoMessageException if the commit message has not been specified
   */
  private void processOptions(RepositoryState state, RevWalk rw) throws NoMessageException {
    if (committer == null) committer = new PersonIdent(repo);
    if (author == null && !amend) author = committer;

    // when doing a merge commit parse MERGE_HEAD and MERGE_MSG files
    if (state == RepositoryState.MERGING_RESOLVED || isMergeDuringRebase(state)) {
      try {
        parents = repo.readMergeHeads();
        if (parents != null)
          for (int i = 0; i < parents.size(); i++) {
            RevObject ro = rw.parseAny(parents.get(i));
            if (ro instanceof RevTag) parents.set(i, rw.peel(ro));
          }
      } catch (IOException e) {
        throw new JGitInternalException(
            MessageFormat.format(
                JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_HEAD, e),
            e);
      }
      if (message == null) {
        try {
          message = repo.readMergeCommitMsg();
        } catch (IOException e) {
          throw new JGitInternalException(
              MessageFormat.format(
                  JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_MSG, e),
              e);
        }
      }
    } else if (state == RepositoryState.SAFE && message == null) {
      try {
        message = repo.readSquashCommitMsg();
        if (message != null) repo.writeSquashCommitMsg(null /* delete */);
      } catch (IOException e) {
        throw new JGitInternalException(
            MessageFormat.format(
                JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR, Constants.MERGE_MSG, e),
            e);
      }
    }
    if (message == null)
      // as long as we don't support -C option we have to have
      // an explicit message
      throw new NoMessageException(JGitText.get().commitMessageNotSpecified);
  }
Beispiel #10
0
  @Override
  protected Result doUpdate(Result desiredResult) throws IOException {
    ObjectIdRef newRef;
    RevObject obj = rw.parseAny(getNewObjectId());
    if (obj instanceof RevTag) {
      newRef =
          new ObjectIdRef.PeeledTag(
              Storage.PACKED, dstRef.getName(), getNewObjectId(), rw.peel(obj).copy());
    } else {
      newRef = new ObjectIdRef.PeeledNonTag(Storage.PACKED, dstRef.getName(), getNewObjectId());
    }

    if (getRefDatabase().compareAndPut(dstRef, newRef)) {
      getRefDatabase().stored(newRef);
      return desiredResult;
    }
    return Result.LOCK_FAILURE;
  }
Beispiel #11
0
  /**
   * Merge together two or more tree-ish objects.
   *
   * <p>Any tree-ish may be supplied as inputs. Commits and/or tags pointing at trees or commits may
   * be passed as input objects.
   *
   * @param tips source trees to be combined together. The merge base is not included in this set.
   * @return true if the merge was completed without conflicts; false if the merge strategy cannot
   *     handle this merge or there were conflicts preventing it from automatically resolving all
   *     paths.
   * @throws IncorrectObjectTypeException one of the input objects is not a commit, but the strategy
   *     requires it to be a commit.
   * @throws IOException one or more sources could not be read, or outputs could not be written to
   *     the Repository.
   */
  public boolean merge(final AnyObjectId[] tips) throws IOException {
    sourceObjects = new RevObject[tips.length];
    for (int i = 0; i < tips.length; i++) sourceObjects[i] = walk.parseAny(tips[i]);

    sourceCommits = new RevCommit[sourceObjects.length];
    for (int i = 0; i < sourceObjects.length; i++) {
      try {
        sourceCommits[i] = walk.parseCommit(sourceObjects[i]);
      } catch (IncorrectObjectTypeException err) {
        sourceCommits[i] = null;
      }
    }

    sourceTrees = new RevTree[sourceObjects.length];
    for (int i = 0; i < sourceObjects.length; i++)
      sourceTrees[i] = walk.parseTree(sourceObjects[i]);

    return mergeImpl();
  }
Beispiel #12
0
  @Override
  protected void run() throws Exception {
    Git git = new Git(db);
    if (tagName != null) {
      TagCommand command = git.tag().setForceUpdate(force).setMessage(message).setName(tagName);

      if (object != null) {
        RevWalk walk = new RevWalk(db);
        command.setObjectId(walk.parseAny(object));
      }

      command.call();
    } else {
      ListTagCommand command = git.tagList();
      List<RevTag> list = command.call();
      for (RevTag revTag : list) {
        out.println(revTag.getTagName());
      }
    }
  }
  /**
   * Create pack basing on fixed objects list, then precisely verify content. No delta reuse here.
   *
   * @throws IOException
   * @throws MissingObjectException
   */
  public void testWritePack3() throws MissingObjectException, IOException {
    writer.setReuseDeltas(false);
    final ObjectId forcedOrder[] =
        new ObjectId[] {
          ObjectId.fromString("82c6b885ff600be425b4ea96dee75dca255b69e7"),
          ObjectId.fromString("c59759f143fb1fe21c197981df75a7ee00290799"),
          ObjectId.fromString("aabf2ffaec9b497f0950352b3e582d73035c2035"),
          ObjectId.fromString("902d5476fa249b7abc9d84c611577a81381f0327"),
          ObjectId.fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259"),
          ObjectId.fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3")
        };
    final RevWalk parser = new RevWalk(db);
    final RevObject forcedOrderRevs[] = new RevObject[forcedOrder.length];
    for (int i = 0; i < forcedOrder.length; i++)
      forcedOrderRevs[i] = parser.parseAny(forcedOrder[i]);

    createVerifyOpenPack(Arrays.asList(forcedOrderRevs).iterator());

    assertEquals(forcedOrder.length, writer.getObjectsNumber());
    verifyObjectsOrder(forcedOrder);
    assertEquals("ed3f96b8327c7c66b0f8f70056129f0769323d86", writer.computeName().name());
  }
  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;
  }
Beispiel #15
0
  private void validateCommands() {
    for (final ReceiveCommand cmd : commands) {
      final Ref ref = cmd.getRef();
      if (cmd.getResult() != Result.NOT_ATTEMPTED) continue;

      if (cmd.getType() == ReceiveCommand.Type.DELETE && !isAllowDeletes()) {
        // Deletes are not supported on this repository.
        //
        cmd.setResult(Result.REJECTED_NODELETE);
        continue;
      }

      if (cmd.getType() == ReceiveCommand.Type.CREATE) {
        if (!isAllowCreates()) {
          cmd.setResult(Result.REJECTED_NOCREATE);
          continue;
        }

        if (ref != null && !isAllowNonFastForwards()) {
          // Creation over an existing ref is certainly not going
          // to be a fast-forward update. We can reject it early.
          //
          cmd.setResult(Result.REJECTED_NONFASTFORWARD);
          continue;
        }

        if (ref != null) {
          // A well behaved client shouldn't have sent us a
          // create command for a ref we advertised to it.
          //
          cmd.setResult(
              Result.REJECTED_OTHER_REASON,
              MessageFormat.format(JGitText.get().refAlreadyExists, ref));
          continue;
        }
      }

      if (cmd.getType() == ReceiveCommand.Type.DELETE
          && ref != null
          && !ObjectId.zeroId().equals(cmd.getOldId())
          && !ref.getObjectId().equals(cmd.getOldId())) {
        // Delete commands can be sent with the old id matching our
        // advertised value, *OR* with the old id being 0{40}. Any
        // other requested old id is invalid.
        //
        cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().invalidOldIdSent);
        continue;
      }

      if (cmd.getType() == ReceiveCommand.Type.UPDATE) {
        if (ref == null) {
          // The ref must have been advertised in order to be updated.
          //
          cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef);
          continue;
        }

        if (!ref.getObjectId().equals(cmd.getOldId())) {
          // A properly functioning client will send the same
          // object id we advertised.
          //
          cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().invalidOldIdSent);
          continue;
        }

        // Is this possibly a non-fast-forward style update?
        //
        RevObject oldObj, newObj;
        try {
          oldObj = walk.parseAny(cmd.getOldId());
        } catch (IOException e) {
          cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd.getOldId().name());
          continue;
        }

        try {
          newObj = walk.parseAny(cmd.getNewId());
        } catch (IOException e) {
          cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd.getNewId().name());
          continue;
        }

        if (oldObj instanceof RevCommit && newObj instanceof RevCommit) {
          try {
            if (!walk.isMergedInto((RevCommit) oldObj, (RevCommit) newObj)) {
              cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
            }
          } catch (MissingObjectException e) {
            cmd.setResult(Result.REJECTED_MISSING_OBJECT, e.getMessage());
          } catch (IOException e) {
            cmd.setResult(Result.REJECTED_OTHER_REASON);
          }
        } else {
          cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
        }
      }

      if (!cmd.getRefName().startsWith(Constants.R_REFS)
          || !Repository.isValidRefName(cmd.getRefName())) {
        cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().funnyRefname);
      }
    }
  }
  private void negotiate(final ProgressMonitor monitor) throws IOException, CancelledException {
    final MutableObjectId ackId = new MutableObjectId();
    int resultsPending = 0;
    int havesSent = 0;
    int havesSinceLastContinue = 0;
    boolean receivedContinue = false;
    boolean receivedAck = false;

    if (statelessRPC) state.writeTo(out, null);

    negotiateBegin();
    SEND_HAVES:
    for (; ; ) {
      final RevCommit c = walk.next();
      if (c == null) break SEND_HAVES;

      pckOut.writeString("have " + c.getId().name() + "\n");
      havesSent++;
      havesSinceLastContinue++;

      if ((31 & havesSent) != 0) {
        // We group the have lines into blocks of 32, each marked
        // with a flush (aka end). This one is within a block so
        // continue with another have line.
        //
        continue;
      }

      if (monitor.isCancelled()) throw new CancelledException();

      pckOut.end();
      resultsPending++; // Each end will cause a result to come back.

      if (havesSent == 32 && !statelessRPC) {
        // On the first block we race ahead and try to send
        // more of the second block while waiting for the
        // remote to respond to our first block request.
        // This keeps us one block ahead of the peer.
        //
        continue;
      }

      READ_RESULT:
      for (; ; ) {
        final AckNackResult anr = pckIn.readACK(ackId);
        switch (anr) {
          case NAK:
            // More have lines are necessary to compute the
            // pack on the remote side. Keep doing that.
            //
            resultsPending--;
            break READ_RESULT;

          case ACK:
            // The remote side is happy and knows exactly what
            // to send us. There is no further negotiation and
            // we can break out immediately.
            //
            multiAck = MultiAck.OFF;
            resultsPending = 0;
            receivedAck = true;
            if (statelessRPC) state.writeTo(out, null);
            break SEND_HAVES;

          case ACK_CONTINUE:
          case ACK_COMMON:
          case ACK_READY:
            // The server knows this commit (ackId). We don't
            // need to send any further along its ancestry, but
            // we need to continue to talk about other parts of
            // our local history.
            //
            markCommon(walk.parseAny(ackId), anr);
            receivedAck = true;
            receivedContinue = true;
            havesSinceLastContinue = 0;
            break;
        }

        if (monitor.isCancelled()) throw new CancelledException();
      }

      if (statelessRPC) state.writeTo(out, null);

      if (receivedContinue && havesSinceLastContinue > MAX_HAVES) {
        // Our history must be really different from the remote's.
        // We just sent a whole slew of have lines, and it did not
        // recognize any of them. Avoid sending our entire history
        // to them by giving up early.
        //
        break SEND_HAVES;
      }
    }

    // Tell the remote side we have run out of things to talk about.
    //
    if (monitor.isCancelled()) throw new CancelledException();

    // When statelessRPC is true we should always leave SEND_HAVES
    // loop above while in the middle of a request. This allows us
    // to just write done immediately.
    //
    pckOut.writeString("done\n");
    pckOut.flush();

    if (!receivedAck) {
      // Apparently if we have never received an ACK earlier
      // there is one more result expected from the done we
      // just sent to the remote.
      //
      multiAck = MultiAck.OFF;
      resultsPending++;
    }

    READ_RESULT:
    while (resultsPending > 0 || multiAck != MultiAck.OFF) {
      final AckNackResult anr = pckIn.readACK(ackId);
      resultsPending--;
      switch (anr) {
        case NAK:
          // A NAK is a response to an end we queued earlier
          // we eat it and look for another ACK/NAK message.
          //
          break;

        case ACK:
          // A solitary ACK at this point means the remote won't
          // speak anymore, but is going to send us a pack now.
          //
          break READ_RESULT;

        case ACK_CONTINUE:
        case ACK_COMMON:
        case ACK_READY:
          // We will expect a normal ACK to break out of the loop.
          //
          multiAck = MultiAck.CONTINUE;
          break;
      }

      if (monitor.isCancelled()) throw new CancelledException();
    }
  }