@Test
  public void testCommitRange()
      throws NoHeadException, NoMessageException, UnmergedPathException,
          ConcurrentRefUpdateException, JGitInternalException, WrongRepositoryStateException,
          IncorrectObjectTypeException, MissingObjectException {
    // do 4 commits and set the range to the second and fourth one
    Git git = new Git(db);
    git.commit().setMessage("first commit").call();
    RevCommit second = git.commit().setMessage("second commit").setCommitter(committer).call();
    git.commit().setMessage("third commit").setAuthor(author).call();
    RevCommit last =
        git.commit().setMessage("fourth commit").setAuthor(author).setCommitter(committer).call();
    Iterable<RevCommit> commits = git.log().addRange(second.getId(), last.getId()).call();

    // check that we have the third and fourth commit
    PersonIdent defaultCommitter = new PersonIdent(db);
    PersonIdent expectedAuthors[] = new PersonIdent[] {author, author};
    PersonIdent expectedCommitters[] = new PersonIdent[] {defaultCommitter, committer};
    String expectedMessages[] = new String[] {"third commit", "fourth commit"};
    int l = expectedAuthors.length - 1;
    for (RevCommit c : commits) {
      assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent().getName());
      assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent().getName());
      assertEquals(c.getFullMessage(), expectedMessages[l]);
      l--;
    }
    assertEquals(l, -1);
  }
예제 #2
0
 protected void assertRebase(TestRepository<?> testRepo, boolean contentMerge) throws IOException {
   Repository repo = testRepo.getRepository();
   RevCommit localHead = getHead(repo);
   RevCommit remoteHead = getRemoteHead();
   assert_()
       .withFailureMessage(String.format("%s not equal %s", localHead.name(), remoteHead.name()))
       .that(localHead.getId())
       .isNotEqualTo(remoteHead.getId());
   assertThat(remoteHead.getParentCount()).isEqualTo(1);
   if (!contentMerge) {
     assertThat(getLatestRemoteDiff()).isEqualTo(getLatestDiff(repo));
   }
   assertThat(remoteHead.getShortMessage()).isEqualTo(localHead.getShortMessage());
 }
  @Test
  @Transactional
  @Rollback
  public void testSave() {
    // RecCommit does not mock nicely.
    RevCommit rc = git.add("test", "ABC").commit("test").get();
    FileChanges changes = new FileChanges(repo, rc);
    FileChange fileChange = new FileChange();
    fileChange.setPath("/test/path");
    FileEdits edits = new FileEdits();
    edits.setChangeType(ChangeType.ADD);
    EditList el = new EditList();
    Edit edit = new Edit(10, 10, 10, 20);
    el.add(edit);
    edits.setEdits(el);
    fileChange.addEdit(edits);
    changes.addChange(fileChange);
    repoRepository.save(new Repo(changes.getRepository().getDirectory().getAbsolutePath()));
    fileChangeCallback.filesChanged(changes);

    Commit commit = commitRepository.findOne(rc.getId().getName());
    assertNotNull(commit);
    assertThat(commit.getLinesAdded(), equalTo(10L));
    assertThat(commit.getLinesRemoved(), equalTo(0L));
    assertThat(commit.getFiles().size(), equalTo(1));
  }
예제 #4
0
  @Test
  public void dontPackHEAD_bare() throws Exception {
    BranchBuilder bb = tr.branch("refs/heads/side");
    bb.commit().add("A", "A").add("B", "B").create();
    RevCommit second = bb.commit().add("A", "A2").add("B", "B2").create();

    // Convert the repo to be bare
    FileBasedConfig cfg = repo.getConfig();
    cfg.setBoolean(
        ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_BARE, true);
    cfg.save();
    Git git = Git.open(repo.getDirectory());
    repo = (FileRepository) git.getRepository();

    // check for the unborn branch master. HEAD should point to master and
    // master doesn't exist.
    assertEquals(repo.exactRef("HEAD").getTarget().getName(), "refs/heads/master");
    assertNull(repo.exactRef("HEAD").getTarget().getObjectId());
    gc.packRefs();
    assertSame(repo.exactRef("HEAD").getStorage(), Storage.LOOSE);
    assertEquals(repo.exactRef("HEAD").getTarget().getName(), "refs/heads/master");
    assertNull(repo.exactRef("HEAD").getTarget().getObjectId());

    // check for non-detached HEAD
    repo.updateRef(Constants.HEAD).link("refs/heads/side");
    gc.packRefs();
    assertSame(repo.exactRef("HEAD").getStorage(), Storage.LOOSE);
    assertEquals(repo.exactRef("HEAD").getTarget().getObjectId(), second.getId());
  }
예제 #5
0
  @Override
  public List<CommitInfo> log(
      String objectId,
      final String path,
      int limit,
      int pageOffset,
      boolean showRemoteRefs,
      int itemsPerPage) {

    try {
      if (itemsPerPage <= 1) {
        itemsPerPage = 50;
      }
      boolean pageResults = limit <= 0;
      Repository r = git.getRepository();

      // TODO not sure if this is the right String we should use for the sub module stuff...
      String repositoryName = getConfigDirectory().getPath();

      objectId = defaultObjectId(objectId);

      final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs);
      List<RevCommit> commits;
      if (pageResults) {
        // Paging result set
        commits = JGitUtils.getRevLog(r, objectId, pageOffset * itemsPerPage, itemsPerPage);
      } else {
        // Fixed size result set
        commits = JGitUtils.getRevLog(r, objectId, 0, limit);
      }

      List<CommitInfo> answer = new ArrayList<CommitInfo>();
      for (RevCommit entry : commits) {
        final Date date = JGitUtils.getCommitDate(entry);
        String author = entry.getAuthorIdent().getName();
        boolean merge = entry.getParentCount() > 1;

        // short message
        String shortMessage = entry.getShortMessage();
        String trimmedMessage = shortMessage;
        if (allRefs.containsKey(entry.getId())) {
          trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS);
        } else {
          trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG);
        }

        String name = entry.getName();
        String commitHash = getShortCommitHash(name);
        answer.add(
            new CommitInfo(
                commitHash, name, "log", author, date, merge, trimmedMessage, shortMessage));
      }
      return answer;
    } catch (Exception e) {
      throw new RuntimeIOException(e);
    }
  }
 private List<PatchSetInfo.ParentInfo> toParentInfos(final RevCommit[] parents, final RevWalk walk)
     throws IOException, MissingObjectException {
   List<PatchSetInfo.ParentInfo> pInfos = new ArrayList<>(parents.length);
   for (RevCommit parent : parents) {
     walk.parseBody(parent);
     RevId rev = new RevId(parent.getId().name());
     String msg = parent.getShortMessage();
     pInfos.add(new PatchSetInfo.ParentInfo(rev, msg));
   }
   return pInfos;
 }
예제 #7
0
 @Test
 public void submitWithFastForward() throws Exception {
   RevCommit oldHead = getRemoteHead();
   PushOneCommit.Result change = createChange();
   submit(change.getChangeId());
   RevCommit head = getRemoteHead();
   assertThat(head.getId()).isEqualTo(change.getCommitId());
   assertThat(head.getParent(0)).isEqualTo(oldHead);
   assertSubmitter(change.getChangeId(), 1);
   assertPersonEquals(admin.getIdent(), head.getAuthorIdent());
   assertPersonEquals(admin.getIdent(), head.getCommitterIdent());
 }
 private String getObjectIdOfCommit() throws Exception {
   String branch = repository.getFullBranch();
   if (ObjectId.isId(branch)) return branch;
   if (branch.startsWith(Constants.R_REFS)) {
     RevCommit commit = revWalk.parseCommit(repository.resolve(branch));
     return commit.getId().getName();
   }
   if (branch.startsWith(Constants.R_TAGS)) {
     RevTag tag = revWalk.parseTag(repository.resolve(branch));
     return tag.getObject().getId().name();
   }
   throw new IllegalStateException("Can't resolve commit");
 }
 private String getAbbreviatedId(GitModelCommit commit) {
   RevCommit remoteCommit = commit.getBaseCommit();
   ObjectReader reader = commit.getRepository().newObjectReader();
   ObjectId commitId = remoteCommit.getId();
   AbbreviatedObjectId shortId;
   try {
     shortId = reader.abbreviate(commitId, 6);
   } catch (IOException e) {
     shortId = AbbreviatedObjectId.fromObjectId(ObjectId.zeroId());
     Activator.logError(e.getMessage(), e);
   } finally {
     reader.release();
   }
   return shortId.name();
 }
예제 #10
0
 /**
  * @param gitConfigFolder e.g. /your/project/root/.git
  * @return Returns last commit's UUID, "nocommit" if there are no commits and returns null if an
  *     exception occured
  */
 public static String getLastCommitUuid(String gitConfigFolder) throws MojoExecutionException {
   try {
     Repository repo =
         new RepositoryBuilder()
             .setGitDir(new File(gitConfigFolder))
             .readEnvironment()
             .findGitDir()
             .build();
     RevWalk walk = new RevWalk(repo);
     ObjectId head = repo.resolve("HEAD");
     if (head != null) {
       RevCommit lastCommit = walk.parseCommit(head);
       return lastCommit.getId().getName();
     } else {
       return "nocommit";
     }
   } catch (Exception e) {
     throw new MojoExecutionException("Error trying to get the last git commit uuid", e);
   }
 }
예제 #11
0
  @Test
  public void testConflicting() throws Exception {
    try (Git git = new Git(db)) {
      writeTrashFile("a", "1\na\n3\n");
      writeTrashFile("b", "1\nb\n3\n");
      git.add().addFilepattern("a").addFilepattern("b").call();
      RevCommit initialCommit = git.commit().setMessage("initial").call();

      // create side branch with two modifications
      createBranch(initialCommit, "refs/heads/side");
      checkoutBranch("refs/heads/side");
      writeTrashFile("a", "1\na(side)\n3\n");
      writeTrashFile("b", "1\nb\n3\n(side)");
      git.add().addFilepattern("a").addFilepattern("b").call();
      RevCommit secondCommit = git.commit().setMessage("side").call();

      // update a on master to generate conflict
      checkoutBranch("refs/heads/master");
      writeTrashFile("a", "1\na(main)\n3\n");
      git.add().addFilepattern("a").call();
      git.commit().setMessage("main").call();

      // merge side with master
      MergeResult result =
          git.merge().include(secondCommit.getId()).setStrategy(MergeStrategy.RESOLVE).call();
      assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
    }

    FileTreeIterator iterator = new FileTreeIterator(db);
    IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
    diff.diff();

    assertEquals("[b]", new TreeSet<String>(diff.getChanged()).toString());
    assertEquals("[]", diff.getAdded().toString());
    assertEquals("[]", diff.getRemoved().toString());
    assertEquals("[]", diff.getMissing().toString());
    assertEquals("[]", diff.getModified().toString());
    assertEquals("[a]", diff.getConflicting().toString());
    assertEquals(StageState.BOTH_MODIFIED, diff.getConflictingStageStates().get("a"));
    assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
  }
예제 #12
0
  private static void lastCommit(Git git, String path, AnyObjectId revId, JSONObject jsonObject) {
    JSONObject latestCommitObj = new JSONObject();
    JSONObject authorObj = new JSONObject();
    JSONObject committerObj = new JSONObject();
    Iterable<RevCommit> log = null;
    try {
      if (path != null) {
        log = git.log().addPath(path).setMaxCount(1).call();
      } else if (revId != null) {
        log = git.log().add(revId).setMaxCount(1).call();
      }
      Iterator<RevCommit> it = log.iterator();
      while (it.hasNext()) {
        RevCommit rev = (RevCommit) it.next();
        PersonIdent committer = rev.getCommitterIdent();
        committerObj.put("Name", committer.getName());
        committerObj.put("Email", committer.getEmailAddress());
        committerObj.put("Date", committer.getWhen().toString());

        PersonIdent author = rev.getAuthorIdent();
        authorObj.put("Name", author.getName());
        String authorEmail = author.getEmailAddress();
        authorObj.put("Email", authorEmail);
        authorObj.put("Date", author.getWhen().toString());

        latestCommitObj.put("Author", authorObj);
        latestCommitObj.put("Committer", committerObj);
        latestCommitObj.put("Message", rev.getFullMessage());
        latestCommitObj.put("SHA1", rev.getId().getName());
        latestCommitObj.put("AvatarURL", getImageLink(authorEmail));

        jsonObject.put("LastCommit", latestCommitObj);
      }
    } catch (GitAPIException e) {
    } catch (MissingObjectException e) {
    } catch (IncorrectObjectTypeException e) {
    } catch (JSONException e) {
    }
  }
예제 #13
0
  @Test
  public void submitMultipleChanges() throws Exception {
    RevCommit initialHead = getRemoteHead();

    testRepo.reset(initialHead);
    PushOneCommit.Result change2 = createChange("Change 2", "b", "b");

    testRepo.reset(initialHead);
    PushOneCommit.Result change3 = createChange("Change 3", "c", "c");

    testRepo.reset(initialHead);
    PushOneCommit.Result change4 = createChange("Change 4", "d", "d");

    // Change 2 stays untouched.
    approve(change2.getChangeId());
    // Change 3 is a fast-forward, no need to merge.
    submit(change3.getChangeId());

    RevCommit tip = getRemoteLog().get(0);
    assertThat(tip.getShortMessage()).isEqualTo(change3.getCommit().getShortMessage());
    assertThat(tip.getParent(0).getId()).isEqualTo(initialHead.getId());
    assertPersonEquals(admin.getIdent(), tip.getAuthorIdent());
    assertPersonEquals(admin.getIdent(), tip.getCommitterIdent());

    // We need to merge change 4.
    submit(change4.getChangeId());

    tip = getRemoteLog().get(0);
    assertThat(tip.getParent(1).getShortMessage()).isEqualTo(change4.getCommit().getShortMessage());
    assertThat(tip.getParent(0).getShortMessage()).isEqualTo(change3.getCommit().getShortMessage());

    assertPersonEquals(admin.getIdent(), tip.getAuthorIdent());
    assertPersonEquals(serverIdent.get(), tip.getCommitterIdent());

    assertNew(change2.getChangeId());
  }
예제 #14
0
 protected RevCommit commitThenPush(Git git, String branch, CommitCommand commit)
     throws Exception {
   RevCommit answer = commit.call();
   if (LOG.isDebugEnabled()) {
     LOG.debug("Committed " + answer.getId() + " " + answer.getFullMessage());
   }
   if (isPushOnCommit()) {
     Iterable<PushResult> results = doPush(git);
     for (PushResult result : results) {
       if (LOG.isDebugEnabled()) {
         LOG.debug(
             "Pushed "
                 + result.getMessages()
                 + " "
                 + result.getURI()
                 + " branch: "
                 + branch
                 + " updates: "
                 + toString(result.getRemoteUpdates()));
       }
     }
   }
   return answer;
 }
  private Image decorateImage(final Image image, Object element) {

    RepositoryTreeNode node = (RepositoryTreeNode) element;
    switch (node.getType()) {
      case TAG:
        // fall through
      case ADDITIONALREF:
        // fall through
      case REF:
        // if the branch or tag is checked out,
        // we want to decorate the corresponding
        // node with a little check indicator
        String refName = ((Ref) node.getObject()).getName();
        Ref leaf = ((Ref) node.getObject()).getLeaf();

        String branchName;
        String compareString;

        try {
          branchName = node.getRepository().getFullBranch();
          if (branchName == null) return image;
          if (refName.startsWith(Constants.R_HEADS)) {
            // local branch: HEAD would be on the branch
            compareString = refName;
          } else if (refName.startsWith(Constants.R_TAGS)) {
            // tag: HEAD would be on the commit id to which the tag is
            // pointing
            ObjectId id = node.getRepository().resolve(refName);
            if (id == null) return image;
            RevWalk rw = new RevWalk(node.getRepository());
            RevTag tag = rw.parseTag(id);
            compareString = tag.getObject().name();

          } else if (refName.startsWith(Constants.R_REMOTES)) {
            // remote branch: HEAD would be on the commit id to which
            // the branch is pointing
            ObjectId id = node.getRepository().resolve(refName);
            if (id == null) return image;
            RevWalk rw = new RevWalk(node.getRepository());
            RevCommit commit = rw.parseCommit(id);
            compareString = commit.getId().name();
          } else if (refName.equals(Constants.HEAD)) return getDecoratedImage(image);
          else {
            String leafname = leaf.getName();
            if (leafname.startsWith(Constants.R_REFS)
                && leafname.equals(node.getRepository().getFullBranch()))
              return getDecoratedImage(image);
            else if (leaf.getObjectId().equals(node.getRepository().resolve(Constants.HEAD)))
              return getDecoratedImage(image);
            // some other symbolic reference
            return image;
          }
        } catch (IOException e1) {
          return image;
        }

        if (compareString.equals(branchName)) {
          return getDecoratedImage(image);
        }

        return image;

      default:
        return image;
    }
  }
예제 #16
0
  /**
   * Executes the {@code commit} command with all the options and parameters collected by the setter
   * methods of this class. Each instance of this class should only be used for one invocation of
   * the command (means: one call to {@link #call()})
   *
   * @return a {@link RevCommit} object representing the successful commit.
   * @throws NoHeadException when called on a git repo without a HEAD reference
   * @throws NoMessageException when called without specifying a commit message
   * @throws UnmergedPathsException when the current index contained unmerged paths (conflicts)
   * @throws ConcurrentRefUpdateException when HEAD or branch ref is updated concurrently by someone
   *     else
   * @throws WrongRepositoryStateException when repository is not in the right state for committing
   * @throws AbortedByHookException if there are either pre-commit or commit-msg hooks present in
   *     the repository and one of them rejects the commit.
   */
  public RevCommit call()
      throws GitAPIException, NoHeadException, NoMessageException, UnmergedPathsException,
          ConcurrentRefUpdateException, WrongRepositoryStateException, AbortedByHookException {
    checkCallable();
    Collections.sort(only);

    try (RevWalk rw = new RevWalk(repo)) {
      RepositoryState state = repo.getRepositoryState();
      if (!state.canCommit())
        throw new WrongRepositoryStateException(
            MessageFormat.format(JGitText.get().cannotCommitOnARepoWithState, state.name()));

      if (!noVerify) {
        Hooks.preCommit(repo, hookOutRedirect).call();
      }

      processOptions(state, rw);

      if (all && !repo.isBare() && repo.getWorkTree() != null) {
        try (Git git = new Git(repo)) {
          git.add()
              .addFilepattern(".") // $NON-NLS-1$
              .setUpdate(true)
              .call();
        } catch (NoFilepatternException e) {
          // should really not happen
          throw new JGitInternalException(e.getMessage(), e);
        }
      }

      Ref head = repo.getRef(Constants.HEAD);
      if (head == null)
        throw new NoHeadException(JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);

      // determine the current HEAD and the commit it is referring to
      ObjectId headId = repo.resolve(Constants.HEAD + "^{commit}"); // $NON-NLS-1$
      if (headId == null && amend)
        throw new WrongRepositoryStateException(JGitText.get().commitAmendOnInitialNotPossible);

      if (headId != null)
        if (amend) {
          RevCommit previousCommit = rw.parseCommit(headId);
          for (RevCommit p : previousCommit.getParents()) parents.add(p.getId());
          if (author == null) author = previousCommit.getAuthorIdent();
        } else {
          parents.add(0, headId);
        }

      if (!noVerify) {
        message = Hooks.commitMsg(repo, hookOutRedirect).setCommitMessage(message).call();
      }

      // lock the index
      DirCache index = repo.lockDirCache();
      try (ObjectInserter odi = repo.newObjectInserter()) {
        if (!only.isEmpty()) index = createTemporaryIndex(headId, index, rw);

        // Write the index as tree to the object database. This may
        // fail for example when the index contains unmerged paths
        // (unresolved conflicts)
        ObjectId indexTreeId = index.writeTree(odi);

        if (insertChangeId) insertChangeId(indexTreeId);

        // Create a Commit object, populate it and write it
        CommitBuilder commit = new CommitBuilder();
        commit.setCommitter(committer);
        commit.setAuthor(author);
        commit.setMessage(message);

        commit.setParentIds(parents);
        commit.setTreeId(indexTreeId);
        ObjectId commitId = odi.insert(commit);
        odi.flush();

        RevCommit revCommit = rw.parseCommit(commitId);
        RefUpdate ru = repo.updateRef(Constants.HEAD);
        ru.setNewObjectId(commitId);
        if (reflogComment != null) {
          ru.setRefLogMessage(reflogComment, false);
        } else {
          String prefix =
              amend
                  ? "commit (amend): " //$NON-NLS-1$
                  : parents.size() == 0
                      ? "commit (initial): " //$NON-NLS-1$
                      : "commit: "; //$NON-NLS-1$
          ru.setRefLogMessage(prefix + revCommit.getShortMessage(), false);
        }
        if (headId != null) ru.setExpectedOldObjectId(headId);
        else ru.setExpectedOldObjectId(ObjectId.zeroId());
        Result rc = ru.forceUpdate();
        switch (rc) {
          case NEW:
          case FORCED:
          case FAST_FORWARD:
            {
              setCallable(false);
              if (state == RepositoryState.MERGING_RESOLVED || isMergeDuringRebase(state)) {
                // Commit was successful. Now delete the files
                // used for merge commits
                repo.writeMergeCommitMsg(null);
                repo.writeMergeHeads(null);
              } else if (state == RepositoryState.CHERRY_PICKING_RESOLVED) {
                repo.writeMergeCommitMsg(null);
                repo.writeCherryPickHead(null);
              } else if (state == RepositoryState.REVERTING_RESOLVED) {
                repo.writeMergeCommitMsg(null);
                repo.writeRevertHead(null);
              }
              return revCommit;
            }
          case REJECTED:
          case LOCK_FAILURE:
            throw new ConcurrentRefUpdateException(
                JGitText.get().couldNotLockHEAD, ru.getRef(), rc);
          default:
            throw new JGitInternalException(
                MessageFormat.format(
                    JGitText.get().updatingRefFailed, Constants.HEAD, commitId.toString(), rc));
        }
      } finally {
        index.unlock();
      }
    } catch (UnmergedPathException e) {
      throw new UnmergedPathsException(e);
    } catch (IOException e) {
      throw new JGitInternalException(
          JGitText.get().exceptionCaughtDuringExecutionOfCommitCommand, e);
    }
  }
예제 #17
0
  public ComparePage(PageParameters params) {
    super(params);
    Repository r = getRepository();
    RepositoryModel repository = getRepositoryModel();

    if (StringUtils.isEmpty(objectId)) {
      // seleciton form
      add(new Label("comparison").setVisible(false));
    } else {
      // active comparison
      Fragment comparison = new Fragment("comparison", "comparisonFragment", this);
      add(comparison);

      RevCommit fromCommit;
      RevCommit toCommit;

      String[] parts = objectId.split("\\.\\.");
      if (parts[0].startsWith("refs/") && parts[1].startsWith("refs/")) {
        // set the ref models
        fromRefId.setObject(parts[0]);
        toRefId.setObject(parts[1]);

        fromCommit = getCommit(r, fromRefId.getObject());
        toCommit = getCommit(r, toRefId.getObject());
      } else {
        // set the id models
        fromCommitId.setObject(parts[0]);
        toCommitId.setObject(parts[1]);

        fromCommit = getCommit(r, fromCommitId.getObject());
        toCommit = getCommit(r, toCommitId.getObject());
      }

      // prepare submodules
      getSubmodules(toCommit);

      final String startId = fromCommit.getId().getName();
      final String endId = toCommit.getId().getName();

      // commit ids
      fromCommitId.setObject(startId);
      toCommitId.setObject(endId);

      final DiffOutput diff = DiffUtils.getDiff(r, fromCommit, toCommit, DiffOutputType.HTML);

      // add compare diffstat
      int insertions = 0;
      int deletions = 0;
      for (PathChangeModel pcm : diff.stat.paths) {
        insertions += pcm.insertions;
        deletions += pcm.deletions;
      }
      comparison.add(new DiffStatPanel("diffStat", insertions, deletions));

      // compare page links
      //			comparison.add(new BookmarkablePageLink<Void>("patchLink", PatchPage.class,
      //					WicketUtils.newRangeParameter(repositoryName, fromCommitId.toString(),
      // toCommitId.getObject())));

      // display list of commits
      comparison.add(
          new LogPanel(
              "commitList", repositoryName, objectId, r, 0, 0, repository.showRemoteBranches));

      // changed paths list
      comparison.add(new CommitLegendPanel("commitLegend", diff.stat.paths));
      ListDataProvider<PathChangeModel> pathsDp =
          new ListDataProvider<PathChangeModel>(diff.stat.paths);
      DataView<PathChangeModel> pathsView =
          new DataView<PathChangeModel>("changedPath", pathsDp) {
            private static final long serialVersionUID = 1L;
            int counter;

            @Override
            public void populateItem(final Item<PathChangeModel> item) {
              final PathChangeModel entry = item.getModelObject();
              Label changeType = new Label("changeType", "");
              WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);
              setChangeTypeTooltip(changeType, entry.changeType);
              item.add(changeType);
              item.add(new DiffStatPanel("diffStat", entry.insertions, entry.deletions, true));

              boolean hasSubmodule = false;
              String submodulePath = null;
              if (entry.isTree()) {
                // tree
                item.add(
                    new LinkPanel(
                        "pathName",
                        null,
                        entry.path,
                        TreePage.class,
                        WicketUtils.newPathParameter(repositoryName, endId, entry.path)));
              } else if (entry.isSubmodule()) {
                // submodule
                String submoduleId = entry.objectId;
                SubmoduleModel submodule = getSubmodule(entry.path);
                submodulePath = submodule.gitblitPath;
                hasSubmodule = submodule.hasSubmodule;

                // add relative link
                item.add(
                    new LinkPanel(
                        "pathName",
                        "list",
                        entry.path + " @ " + getShortObjectId(submoduleId),
                        "#" + entry.path));
              } else {
                // add relative link
                item.add(new LinkPanel("pathName", "list", entry.path, "#" + entry.path));
              }

              // quick links
              if (entry.isSubmodule()) {
                // submodule
                item.add(new ExternalLink("patch", "").setEnabled(false));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "view",
                            CommitPage.class,
                            WicketUtils.newObjectParameter(submodulePath, entry.objectId))
                        .setEnabled(hasSubmodule));
                item.add(new ExternalLink("blame", "").setEnabled(false));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "history",
                            HistoryPage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
              } else {
                // tree or blob
                item.add(
                    new BookmarkablePageLink<Void>(
                            "patch",
                            PatchPage.class,
                            WicketUtils.newBlobDiffParameter(
                                repositoryName, startId, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "view",
                            BlobPage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "raw",
                            RawPage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "blame",
                            BlamePage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(
                            !entry.changeType.equals(ChangeType.ADD)
                                && !entry.changeType.equals(ChangeType.DELETE)));
                item.add(
                    new BookmarkablePageLink<Void>(
                            "history",
                            HistoryPage.class,
                            WicketUtils.newPathParameter(repositoryName, endId, entry.path))
                        .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
              }
              WicketUtils.setAlternatingBackground(item, counter);
              counter++;
            }
          };
      comparison.add(pathsView);
      comparison.add(new Label("diffText", diff.content).setEscapeModelStrings(false));
    }

    //
    // ref selection form
    //
    SessionlessForm<Void> refsForm =
        new SessionlessForm<Void>("compareRefsForm", getClass(), getPageParameters()) {

          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit() {
            String from = ComparePage.this.fromRefId.getObject();
            String to = ComparePage.this.toRefId.getObject();

            PageParameters params = WicketUtils.newRangeParameter(repositoryName, from, to);
            String relativeUrl = urlFor(ComparePage.class, params).toString();
            String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
            getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
          }
        };

    List<String> refs = new ArrayList<String>();
    for (RefModel ref : JGitUtils.getLocalBranches(r, true, -1)) {
      refs.add(ref.getName());
    }
    if (repository.showRemoteBranches) {
      for (RefModel ref : JGitUtils.getRemoteBranches(r, true, -1)) {
        refs.add(ref.getName());
      }
    }
    for (RefModel ref : JGitUtils.getTags(r, true, -1)) {
      refs.add(ref.getName());
    }
    refsForm.add(
        new DropDownChoice<String>("fromRef", fromRefId, refs).setEnabled(refs.size() > 0));
    refsForm.add(new DropDownChoice<String>("toRef", toRefId, refs).setEnabled(refs.size() > 0));
    add(refsForm);

    //
    // manual ids form
    //
    SessionlessForm<Void> idsForm =
        new SessionlessForm<Void>("compareIdsForm", getClass(), getPageParameters()) {

          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit() {
            String from = ComparePage.this.fromCommitId.getObject();
            String to = ComparePage.this.toCommitId.getObject();

            PageParameters params = WicketUtils.newRangeParameter(repositoryName, from, to);
            String relativeUrl = urlFor(ComparePage.class, params).toString();
            String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
            getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
          }
        };

    TextField<String> fromIdField = new TextField<String>("fromId", fromCommitId);
    WicketUtils.setInputPlaceholder(fromIdField, getString("gb.from") + "...");
    idsForm.add(fromIdField);

    TextField<String> toIdField = new TextField<String>("toId", toCommitId);
    WicketUtils.setInputPlaceholder(toIdField, getString("gb.to") + "...");
    idsForm.add(toIdField);
    add(idsForm);

    r.close();
  }
예제 #18
0
파일: GitUtils.java 프로젝트: snjeza/core
  public static CherryPickResult cherryPickNoMerge(final Git git, Ref src)
      throws GitAPIException, CantMergeCommitWithZeroParentsException {
    // Does the same as the original git-cherryPick
    // except commiting after running merger
    Repository repo = git.getRepository();

    RevCommit newHead = null;
    List<Ref> cherryPickedRefs = new LinkedList<Ref>();

    RevWalk revWalk = new RevWalk(repo);
    try {
      // get the head commit
      Ref headRef = repo.getRef(Constants.HEAD);
      if (headRef == null)
        throw new NoHeadException(JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
      RevCommit headCommit = revWalk.parseCommit(headRef.getObjectId());

      newHead = headCommit;

      // get the commit to be cherry-picked
      // handle annotated tags
      ObjectId srcObjectId = src.getPeeledObjectId();
      if (srcObjectId == null) srcObjectId = src.getObjectId();
      RevCommit srcCommit = revWalk.parseCommit(srcObjectId);

      // get the parent of the commit to cherry-pick
      if (srcCommit.getParentCount() == 0)
        throw new CantMergeCommitWithZeroParentsException(
            "Commit with zero parents cannot be merged");

      if (srcCommit.getParentCount() > 1)
        throw new MultipleParentsNotAllowedException(
            MessageFormat.format(
                JGitText.get().canOnlyCherryPickCommitsWithOneParent,
                srcCommit.name(),
                Integer.valueOf(srcCommit.getParentCount())));

      RevCommit srcParent = srcCommit.getParent(0);
      revWalk.parseHeaders(srcParent);

      ResolveMerger merger = (ResolveMerger) MergeStrategy.RESOLVE.newMerger(repo);
      merger.setWorkingTreeIterator(new FileTreeIterator(repo));
      merger.setBase(srcParent.getTree());
      if (merger.merge(headCommit, srcCommit)) {
        DirCacheCheckout dco =
            new DirCacheCheckout(
                repo, headCommit.getTree(), repo.lockDirCache(), merger.getResultTreeId());
        dco.setFailOnConflict(true);
        dco.checkout();

        cherryPickedRefs.add(src);
      } else {
        if (merger.failed()) return new CherryPickResult(merger.getFailingPaths());

        // there are merge conflicts
        String message =
            new MergeMessageFormatter()
                .formatWithConflicts(srcCommit.getFullMessage(), merger.getUnmergedPaths());

        repo.writeCherryPickHead(srcCommit.getId());
        repo.writeMergeCommitMsg(message);

        return CherryPickResult.CONFLICT;
      }
    } catch (IOException e) {
      throw new JGitInternalException(
          MessageFormat.format(JGitText.get().exceptionCaughtDuringExecutionOfCherryPickCommand, e),
          e);
    } finally {
      revWalk.release();
    }

    return new CherryPickResult(newHead, cherryPickedRefs);
  }
예제 #19
0
  public HistoryPanel(
      String wicketId,
      final String repositoryName,
      final String objectId,
      final String path,
      Repository r,
      int limit,
      int pageOffset,
      boolean showRemoteRefs) {
    super(wicketId);
    boolean pageResults = limit <= 0;
    int itemsPerPage = GitBlit.getInteger(Keys.web.itemsPerPage, 50);
    if (itemsPerPage <= 1) {
      itemsPerPage = 50;
    }

    RevCommit commit = JGitUtils.getCommit(r, objectId);
    List<PathChangeModel> paths = JGitUtils.getFilesInCommit(r, commit);

    Map<String, SubmoduleModel> submodules = new HashMap<String, SubmoduleModel>();
    for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) {
      submodules.put(model.path, model);
    }

    PathModel matchingPath = null;
    for (PathModel p : paths) {
      if (p.path.equals(path)) {
        matchingPath = p;
        break;
      }
    }
    if (matchingPath == null) {
      // path not in commit
      // manually locate path in tree
      TreeWalk tw = new TreeWalk(r);
      tw.reset();
      tw.setRecursive(true);
      try {
        tw.addTree(commit.getTree());
        tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path)));
        while (tw.next()) {
          if (tw.getPathString().equals(path)) {
            matchingPath =
                new PathChangeModel(
                    tw.getPathString(),
                    tw.getPathString(),
                    0,
                    tw.getRawMode(0),
                    tw.getObjectId(0).getName(),
                    commit.getId().getName(),
                    ChangeType.MODIFY);
          }
        }
      } catch (Exception e) {
      } finally {
        tw.release();
      }
    }

    final boolean isTree = matchingPath == null ? true : matchingPath.isTree();
    final boolean isSubmodule = matchingPath == null ? true : matchingPath.isSubmodule();

    // submodule
    SubmoduleModel submodule = getSubmodule(submodules, repositoryName, matchingPath.path);
    final String submodulePath;
    final boolean hasSubmodule;
    if (submodule != null) {
      submodulePath = submodule.gitblitPath;
      hasSubmodule = submodule.hasSubmodule;
    } else {
      submodulePath = "";
      hasSubmodule = false;
    }

    final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs);
    List<RevCommit> commits;
    if (pageResults) {
      // Paging result set
      commits = JGitUtils.getRevLog(r, objectId, path, pageOffset * itemsPerPage, itemsPerPage);
    } else {
      // Fixed size result set
      commits = JGitUtils.getRevLog(r, objectId, path, 0, limit);
    }

    // inaccurate way to determine if there are more commits.
    // works unless commits.size() represents the exact end.
    hasMore = commits.size() >= itemsPerPage;

    add(new CommitHeaderPanel("commitHeader", repositoryName, commit));

    // breadcrumbs
    add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, path, objectId));

    final int hashLen = GitBlit.getInteger(Keys.web.shortCommitIdLength, 6);
    ListDataProvider<RevCommit> dp = new ListDataProvider<RevCommit>(commits);
    DataView<RevCommit> logView =
        new DataView<RevCommit>("commit", dp) {
          private static final long serialVersionUID = 1L;
          int counter;

          public void populateItem(final Item<RevCommit> item) {
            final RevCommit entry = item.getModelObject();
            final Date date = JGitUtils.getCommitDate(entry);

            item.add(
                WicketUtils.createDateLabel("commitDate", date, getTimeZone(), getTimeUtils()));

            // author search link
            String author = entry.getAuthorIdent().getName();
            LinkPanel authorLink =
                new LinkPanel(
                    "commitAuthor",
                    "list",
                    author,
                    GitSearchPage.class,
                    WicketUtils.newSearchParameter(
                        repositoryName, objectId, author, Constants.SearchType.AUTHOR));
            setPersonSearchTooltip(authorLink, author, Constants.SearchType.AUTHOR);
            item.add(authorLink);

            // merge icon
            if (entry.getParentCount() > 1) {
              item.add(WicketUtils.newImage("commitIcon", "commit_merge_16x16.png"));
            } else {
              item.add(WicketUtils.newBlankImage("commitIcon"));
            }

            String shortMessage = entry.getShortMessage();
            String trimmedMessage = shortMessage;
            if (allRefs.containsKey(entry.getId())) {
              trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS);
            } else {
              trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG);
            }
            LinkPanel shortlog =
                new LinkPanel(
                    "commitShortMessage",
                    "list subject",
                    trimmedMessage,
                    CommitPage.class,
                    WicketUtils.newObjectParameter(repositoryName, entry.getName()));
            if (!shortMessage.equals(trimmedMessage)) {
              WicketUtils.setHtmlTooltip(shortlog, shortMessage);
            }
            item.add(shortlog);

            item.add(new RefsPanel("commitRefs", repositoryName, entry, allRefs));

            if (isTree) {
              // tree
              item.add(new Label("hashLabel", getString("gb.tree") + "@"));
              LinkPanel commitHash =
                  new LinkPanel(
                      "hashLink",
                      null,
                      entry.getName().substring(0, hashLen),
                      TreePage.class,
                      WicketUtils.newObjectParameter(repositoryName, entry.getName()));
              WicketUtils.setCssClass(commitHash, "shortsha1");
              WicketUtils.setHtmlTooltip(commitHash, entry.getName());
              item.add(commitHash);

              Fragment links = new Fragment("historyLinks", "treeLinks", this);
              links.add(
                  new BookmarkablePageLink<Void>(
                      "commitdiff",
                      CommitDiffPage.class,
                      WicketUtils.newObjectParameter(repositoryName, entry.getName())));
              item.add(links);
            } else if (isSubmodule) {
              // submodule
              item.add(new Label("hashLabel", submodulePath + "@"));
              Repository repository = GitBlit.self().getRepository(repositoryName);
              String submoduleId = JGitUtils.getSubmoduleCommitId(repository, path, entry);
              repository.close();
              LinkPanel commitHash =
                  new LinkPanel(
                      "hashLink",
                      null,
                      submoduleId.substring(0, hashLen),
                      TreePage.class,
                      WicketUtils.newObjectParameter(submodulePath, submoduleId));
              WicketUtils.setCssClass(commitHash, "shortsha1");
              WicketUtils.setHtmlTooltip(commitHash, submoduleId);
              item.add(commitHash.setEnabled(hasSubmodule));

              Fragment links = new Fragment("historyLinks", "treeLinks", this);
              links.add(
                  new BookmarkablePageLink<Void>(
                      "commitdiff",
                      CommitDiffPage.class,
                      WicketUtils.newObjectParameter(repositoryName, entry.getName())));
              item.add(links);
            } else {
              // commit
              item.add(new Label("hashLabel", getString("gb.blob") + "@"));
              LinkPanel commitHash =
                  new LinkPanel(
                      "hashLink",
                      null,
                      entry.getName().substring(0, hashLen),
                      BlobPage.class,
                      WicketUtils.newPathParameter(repositoryName, entry.getName(), path));
              WicketUtils.setCssClass(commitHash, "sha1");
              WicketUtils.setHtmlTooltip(commitHash, entry.getName());
              item.add(commitHash);

              Fragment links = new Fragment("historyLinks", "blobLinks", this);
              links.add(
                  new BookmarkablePageLink<Void>(
                      "commitdiff",
                      CommitDiffPage.class,
                      WicketUtils.newObjectParameter(repositoryName, entry.getName())));
              links.add(
                  new BookmarkablePageLink<Void>(
                          "difftocurrent",
                          BlobDiffPage.class,
                          WicketUtils.newBlobDiffParameter(
                              repositoryName, entry.getName(), objectId, path))
                      .setEnabled(counter > 0));
              item.add(links);
            }

            WicketUtils.setAlternatingBackground(item, counter);
            counter++;
          }
        };
    add(logView);

    // determine to show pager, more, or neither
    if (limit <= 0) {
      // no display limit
      add(new Label("moreHistory", "").setVisible(false));
    } else {
      if (pageResults) {
        // paging
        add(new Label("moreHistory", "").setVisible(false));
      } else {
        // more
        if (commits.size() == limit) {
          // show more
          add(
              new LinkPanel(
                  "moreHistory",
                  "link",
                  new StringResourceModel("gb.moreHistory", this, null),
                  HistoryPage.class,
                  WicketUtils.newPathParameter(repositoryName, objectId, path)));
        } else {
          // no more
          add(new Label("moreHistory", "").setVisible(false));
        }
      }
    }
  }
예제 #20
0
 private ObjectId commit(final String authorName, final String authorEmail, final String comment)
     throws GitAPIException {
   final RevCommit commit =
       git.commit().setMessage(comment).setAuthor(authorName, authorEmail).call();
   return commit.getId();
 }
예제 #21
0
  public static List<PathChangeModel> getFilesInCommit(Repository repository, RevCommit commit) {
    List<PathChangeModel> list = new ArrayList<PathChangeModel>();
    if (!hasCommits(repository)) {
      return list;
    }
    RevWalk rw = new RevWalk(repository);
    try {
      if (commit == null) {
        ObjectId object = getDefaultBranch(repository);
        commit = rw.parseCommit(object);
      }

      if (commit.getParentCount() == 0) {
        TreeWalk tw = new TreeWalk(repository);
        tw.reset();
        tw.setRecursive(true);
        tw.addTree(commit.getTree());
        while (tw.next()) {
          list.add(
              new PathChangeModel(
                  tw.getPathString(),
                  tw.getPathString(),
                  0,
                  tw.getRawMode(0),
                  commit.getId().getName(),
                  ChangeType.ADD));
        }
        tw.release();
      } else {
        RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
        DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
        df.setRepository(repository);
        df.setDiffComparator(RawTextComparator.DEFAULT);
        df.setDetectRenames(true);
        List<DiffEntry> diffs = df.scan(parent.getTree(), commit.getTree());
        for (DiffEntry diff : diffs) {
          if (diff.getChangeType().equals(ChangeType.DELETE)) {
            list.add(
                new PathChangeModel(
                    diff.getOldPath(),
                    diff.getOldPath(),
                    0,
                    diff.getNewMode().getBits(),
                    commit.getId().getName(),
                    diff.getChangeType()));
          } else {
            list.add(
                new PathChangeModel(
                    diff.getNewPath(),
                    diff.getNewPath(),
                    0,
                    diff.getNewMode().getBits(),
                    commit.getId().getName(),
                    diff.getChangeType()));
          }
        }
      }
    } catch (Throwable t) {
      // todo
      Logger.error(t, t.getMessage());
    } finally {
      rw.dispose();
    }
    return list;
  }
예제 #22
0
 public String getRevisionLink(RevCommit revision) {
   return revision.getId().toString();
 }
예제 #23
0
 public Object execute(ExecutionEvent event) throws ExecutionException {
   boolean compareMode =
       Boolean.TRUE.toString().equals(event.getParameter(HistoryViewCommands.COMPARE_MODE_PARAM));
   IStructuredSelection selection = getSelection(getPage());
   if (selection.size() < 1) return null;
   Object input = getPage().getInputInternal().getSingleFile();
   if (input == null) return null;
   IWorkbenchPage workBenchPage =
       HandlerUtil.getActiveWorkbenchWindowChecked(event).getActivePage();
   boolean errorOccurred = false;
   List<ObjectId> ids = new ArrayList<ObjectId>();
   String gitPath = null;
   if (input instanceof IFile) {
     IFile resource = (IFile) input;
     final RepositoryMapping map = RepositoryMapping.getMapping(resource);
     gitPath = map.getRepoRelativePath(resource);
     Iterator<?> it = selection.iterator();
     while (it.hasNext()) {
       RevCommit commit = (RevCommit) it.next();
       String commitPath = getRenamedPath(gitPath, commit);
       IFileRevision rev = null;
       try {
         rev = CompareUtils.getFileRevision(commitPath, commit, map.getRepository(), null);
       } catch (IOException e) {
         Activator.logError(
             NLS.bind(UIText.GitHistoryPage_errorLookingUpPath, gitPath, commit.getId()), e);
         errorOccurred = true;
       }
       if (rev != null) {
         if (compareMode) {
           ITypedElement right =
               CompareUtils.getFileRevisionTypedElement(commitPath, commit, map.getRepository());
           final GitCompareFileRevisionEditorInput in =
               new GitCompareFileRevisionEditorInput(
                   SaveableCompareEditorInput.createFileElement(resource), right, null);
           try {
             CompareUtils.openInCompare(workBenchPage, in);
           } catch (Exception e) {
             errorOccurred = true;
           }
         } else
           try {
             EgitUiEditorUtils.openEditor(
                 getPart(event).getSite().getPage(), rev, new NullProgressMonitor());
           } catch (CoreException e) {
             Activator.logError(UIText.GitHistoryPage_openFailed, e);
             errorOccurred = true;
           }
       } else ids.add(commit.getId());
     }
   }
   if (input instanceof File) {
     File fileInput = (File) input;
     Repository repo = getRepository(event);
     gitPath = getRepoRelativePath(repo, fileInput);
     Iterator<?> it = selection.iterator();
     while (it.hasNext()) {
       RevCommit commit = (RevCommit) it.next();
       String commitPath = getRenamedPath(gitPath, commit);
       IFileRevision rev = null;
       try {
         rev = CompareUtils.getFileRevision(commitPath, commit, repo, null);
       } catch (IOException e) {
         Activator.logError(
             NLS.bind(UIText.GitHistoryPage_errorLookingUpPath, commitPath, commit.getId()), e);
         errorOccurred = true;
       }
       if (rev != null) {
         if (compareMode)
           try {
             ITypedElement left =
                 CompareUtils.getFileRevisionTypedElement(
                     gitPath, new RevWalk(repo).parseCommit(repo.resolve(Constants.HEAD)), repo);
             ITypedElement right =
                 CompareUtils.getFileRevisionTypedElement(commitPath, commit, repo);
             final GitCompareFileRevisionEditorInput in =
                 new GitCompareFileRevisionEditorInput(left, right, null);
             CompareUtils.openInCompare(workBenchPage, in);
           } catch (IOException e) {
             errorOccurred = true;
           }
         else
           try {
             EgitUiEditorUtils.openEditor(
                 getPart(event).getSite().getPage(), rev, new NullProgressMonitor());
           } catch (CoreException e) {
             Activator.logError(UIText.GitHistoryPage_openFailed, e);
             errorOccurred = true;
           }
       } else ids.add(commit.getId());
     }
   }
   if (errorOccurred) Activator.showError(UIText.GitHistoryPage_openFailed, null);
   if (ids.size() > 0) {
     StringBuilder idList = new StringBuilder(""); // $NON-NLS-1$
     for (ObjectId objectId : ids) idList.append(objectId.getName()).append(' ');
     MessageDialog.openError(
         getPart(event).getSite().getShell(),
         UIText.GitHistoryPage_fileNotFound,
         NLS.bind(UIText.GitHistoryPage_notContainedInCommits, gitPath, idList.toString()));
   }
   return null;
 }
예제 #24
0
  protected void addInformationForPath(
      Repository repository,
      Git git,
      DocumentWriter writer,
      RevCommit commit,
      String path,
      CallSpecification spec,
      Values values)
      throws GitAPIException, IOException {
    // Make sure the path is in the canonical form we need ...
    if (path.startsWith("/")) {
      if (path.length() == 1) path = "";
      else path = path.substring(1);
    }

    // Now see if we're actually referring to the "jcr:content" node ...
    boolean isContentNode = false;
    if (path.endsWith(JCR_CONTENT_SUFFIX)) {
      isContentNode = true;
      path = path.substring(0, path.length() - JCR_CONTENT_SUFFIX.length());
    }

    // Create the TreeWalk that we'll use to navigate the files/directories ...
    final TreeWalk tw = new TreeWalk(repository);
    tw.addTree(commit.getTree());
    if ("".equals(path)) {
      // This is the top-level directory, so we don't need to pre-walk to find anything ...
      tw.setRecursive(false);
      while (tw.next()) {
        String childName = tw.getNameString();
        String childId = spec.childId(childName);
        writer.addChild(childId, childName);
      }
    } else {
      // We need to first find our path *before* we can walk the children ...
      PathFilter filter = PathFilter.create(path);
      tw.setFilter(filter);
      while (tw.next()) {
        if (filter.isDone(tw)) {
          break;
        } else if (tw.isSubtree()) {
          tw.enterSubtree();
        }
      }
      // Now that the TreeWalk is the in right location given by the 'path', we can get the
      if (tw.isSubtree()) {
        // The object at the 'path' is a directory, so go into it ...
        tw.enterSubtree();

        // Find the commit in which this folder was last modified ...
        // This may not be terribly efficient, but it seems to work faster on subsequent runs ...
        RevCommit folderCommit = git.log().addPath(path).call().iterator().next();

        // Add folder-related properties ...
        String committer = folderCommit.getCommitterIdent().getName();
        String author = folderCommit.getAuthorIdent().getName();
        DateTime committed = values.dateFrom(folderCommit.getCommitTime());
        writer.setPrimaryType(GitLexicon.FOLDER);
        writer.addProperty(JcrLexicon.CREATED, committed);
        writer.addProperty(JcrLexicon.CREATED_BY, committer);
        writer.addProperty(GitLexicon.OBJECT_ID, folderCommit.getId().name());
        writer.addProperty(GitLexicon.AUTHOR, author);
        writer.addProperty(GitLexicon.COMMITTER, committer);
        writer.addProperty(GitLexicon.COMMITTED, committed);
        writer.addProperty(GitLexicon.TITLE, folderCommit.getShortMessage());

        // And now walk the contents of the directory ...
        while (tw.next()) {
          String childName = tw.getNameString();
          String childId = spec.childId(childName);
          writer.addChild(childId, childName);
        }
      } else {
        // The path specifies a file (or a content node) ...

        // Find the commit in which this folder was last modified ...
        // This may not be terribly efficient, but it seems to work faster on subsequent runs ...
        RevCommit fileCommit = git.log().addPath(path).call().iterator().next();

        // Add file-related properties ...
        String committer = fileCommit.getCommitterIdent().getName();
        String author = fileCommit.getAuthorIdent().getName();
        DateTime committed = values.dateFrom(fileCommit.getCommitTime());
        if (isContentNode) {
          writer.setPrimaryType(GitLexicon.RESOURCE);
          writer.addProperty(JcrLexicon.LAST_MODIFIED, committed);
          writer.addProperty(JcrLexicon.LAST_MODIFIED_BY, committer);
          writer.addProperty(GitLexicon.OBJECT_ID, fileCommit.getId().name());
          writer.addProperty(GitLexicon.AUTHOR, author);
          writer.addProperty(GitLexicon.COMMITTER, committer);
          writer.addProperty(GitLexicon.COMMITTED, committed);
          writer.addProperty(GitLexicon.TITLE, fileCommit.getShortMessage());
          // Create the BinaryValue ...
          ObjectId fileObjectId = tw.getObjectId(0);
          ObjectLoader fileLoader = repository.open(fileObjectId);
          BinaryKey key = new BinaryKey(fileObjectId.getName());
          BinaryValue value = values.binaryFor(key, fileLoader.getSize());
          if (value == null) {
            // It wasn't found in the binary store ...
            if (fileLoader.isLarge()) {
              // Too large to hold in memory, so use the binary store (which reads the file
              // immediately) ...
              value = values.binaryFrom(fileLoader.openStream());
            } else {
              // This is small enough to fit into a byte[], but it still may be pretty big ...
              value =
                  new GitBinaryValue(
                      fileObjectId,
                      fileLoader,
                      connector.getSourceName(),
                      name,
                      connector.getMimeTypeDetector());
            }
          }
          writer.addProperty(JcrLexicon.DATA, value);
          if (connector.includeMimeType()) {
            try {
              String filename =
                  spec.parameter(spec.parameterCount() - 1); // the last is 'jcr:content'
              String mimeType = value.getMimeType(filename);
              if (mimeType != null) writer.addProperty(JcrLexicon.MIMETYPE, mimeType);
            } catch (RepositoryException e) {
              // do nothing
            } catch (IOException e) {
              // do nothing
            }
          }
        } else {
          writer.setPrimaryType(GitLexicon.FILE);
          writer.addProperty(JcrLexicon.CREATED, committed);
          writer.addProperty(JcrLexicon.CREATED_BY, committer);
          writer.addProperty(GitLexicon.OBJECT_ID, fileCommit.getId().name());
          writer.addProperty(GitLexicon.AUTHOR, author);
          writer.addProperty(GitLexicon.COMMITTER, committer);
          writer.addProperty(GitLexicon.COMMITTED, committed);
          writer.addProperty(GitLexicon.TITLE, fileCommit.getShortMessage());

          // Add the "jcr:content" child node ...
          String childId = spec.childId(JCR_CONTENT);
          writer.addChild(childId, JCR_CONTENT);
        }
      }
    }
  }
예제 #25
0
  @Override
  public List<CommitInfo> history(
      String objectId,
      String path,
      int limit,
      int pageOffset,
      boolean showRemoteRefs,
      int itemsPerPage) {
    try {
      if (itemsPerPage <= 1) {
        itemsPerPage = 50;
      }
      boolean pageResults = limit <= 0;
      Repository r = git.getRepository();

      // TODO not sure if this is the right String we should use for the sub module stuff...
      String repositoryName = getConfigDirectory().getPath();

      objectId = defaultObjectId(objectId);
      RevCommit commit = JGitUtils.getCommit(r, objectId);
      List<PathModel.PathChangeModel> paths = JGitUtils.getFilesInCommit(r, commit);

      Map<String, SubmoduleModel> submodules = new HashMap<String, SubmoduleModel>();
      for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) {
        submodules.put(model.path, model);
      }

      PathModel matchingPath = null;
      for (PathModel p : paths) {
        if (p.path.equals(path)) {
          matchingPath = p;
          break;
        }
      }
      if (matchingPath == null) {
        // path not in commit
        // manually locate path in tree
        TreeWalk tw = new TreeWalk(r);
        tw.reset();
        tw.setRecursive(true);
        try {
          tw.addTree(commit.getTree());
          tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path)));
          while (tw.next()) {
            if (tw.getPathString().equals(path)) {
              matchingPath =
                  new PathModel.PathChangeModel(
                      tw.getPathString(),
                      tw.getPathString(),
                      0,
                      tw.getRawMode(0),
                      tw.getObjectId(0).getName(),
                      commit.getId().getName(),
                      ChangeType.MODIFY);
            }
          }
        } catch (Exception e) {
        } finally {
          tw.release();
        }
      }

      final boolean isTree = matchingPath == null ? true : matchingPath.isTree();
      final boolean isSubmodule = matchingPath == null ? true : matchingPath.isSubmodule();

      // submodule
      SubmoduleModel submodule = null;
      if (matchingPath != null) {
        submodule = getSubmodule(submodules, repositoryName, matchingPath.path);
      }
      final String submodulePath;
      final boolean hasSubmodule;
      if (submodule != null) {
        submodulePath = submodule.gitblitPath;
        hasSubmodule = submodule.hasSubmodule;
      } else {
        submodulePath = "";
        hasSubmodule = false;
      }

      final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs);
      List<RevCommit> commits;
      if (pageResults) {
        // Paging result set
        commits = JGitUtils.getRevLog(r, objectId, path, pageOffset * itemsPerPage, itemsPerPage);
      } else {
        // Fixed size result set
        commits = JGitUtils.getRevLog(r, objectId, path, 0, limit);
      }

      // inaccurate way to determine if there are more commits.
      // works unless commits.size() represents the exact end.
      boolean hasMore = commits.size() >= itemsPerPage;

      List<CommitInfo> results = new ArrayList<CommitInfo>();
      for (RevCommit entry : commits) {
        final Date date = JGitUtils.getCommitDate(entry);
        String author = entry.getAuthorIdent().getName();
        boolean merge = entry.getParentCount() > 1;

        String shortMessage = entry.getShortMessage();
        String trimmedMessage = shortMessage;
        if (allRefs.containsKey(entry.getId())) {
          trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS);
        } else {
          trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG);
        }
        String name = entry.getName();
        String commitHashText = getShortCommitHash(name);

        String kind;
        if (isTree) {
          kind = "tree";
        } else if (isSubmodule) {
          kind = "submodule";
        } else kind = "file";

        results.add(
            new CommitInfo(
                commitHashText, name, kind, author, date, merge, trimmedMessage, shortMessage));
      }
      return results;
    } catch (Exception e) {
      throw new RuntimeIOException(e);
    }
  }
예제 #26
0
  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();
    }
  }