private String createChangeSetLabel(GitModelCommit commit) {
    String format = store.getString(UIPreferences.SYNC_VIEW_CHANGESET_LABEL_FORMAT);

    RevCommit baseCommit = commit.getBaseCommit();
    Map<String, String> bindings = new HashMap<String, String>();
    bindings.put(BINDING_CHANGESET_DATE, DATE_FORMAT.format(baseCommit.getAuthorIdent().getWhen()));
    bindings.put(BINDING_CHANGESET_AUTHOR, baseCommit.getAuthorIdent().getName());
    bindings.put(BINDING_CHANGESET_COMMITTER, baseCommit.getCommitterIdent().getName());
    bindings.put(BINDING_CHANGESET_SHORT_MESSAGE, baseCommit.getShortMessage());

    return formatName(format, bindings);
  }
예제 #2
0
 public CommitHeaderPanel(String id, String repositoryName, RevCommit c) {
   super(id);
   add(
       new LinkPanel(
           "shortmessage",
           "title",
           c.getShortMessage(),
           CommitPage.class,
           WicketUtils.newObjectParameter(repositoryName, c.getName())));
   add(new Label("commitid", "(" + c.getName().substring(0, 8) + ")"));
   add(new Label("author", c.getAuthorIdent().getName()));
   add(WicketUtils.createDateLabel("date", c.getAuthorIdent().getWhen(), getTimeZone()));
 }
  @Test
  public void testSomeCommits()
      throws NoHeadException, NoMessageException, UnmergedPathException,
          ConcurrentRefUpdateException, JGitInternalException, WrongRepositoryStateException {

    // do 4 commits
    Git git = new Git(db);
    git.commit().setMessage("initial commit").call();
    git.commit().setMessage("second commit").setCommitter(committer).call();
    git.commit().setMessage("third commit").setAuthor(author).call();
    git.commit().setMessage("fourth commit").setAuthor(author).setCommitter(committer).call();
    Iterable<RevCommit> commits = git.log().call();

    // check that all commits came in correctly
    PersonIdent defaultCommitter = new PersonIdent(db);
    PersonIdent expectedAuthors[] = new PersonIdent[] {defaultCommitter, committer, author, author};
    PersonIdent expectedCommitters[] =
        new PersonIdent[] {defaultCommitter, committer, defaultCommitter, committer};
    String expectedMessages[] =
        new String[] {"initial commit", "second commit", "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);
  }
  @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);
  }
예제 #5
0
 private PersonIdent authorOf(final RevCommit c) {
   if (lastCommit != c) {
     lastCommit = c;
     lastAuthor = c.getAuthorIdent();
   }
   return lastAuthor;
 }
예제 #6
0
  @Override
  public PageData getRevisionData(FileSystemPage page, String label) {
    // Workaround for CachingPage
    if (label == null) {
      return persistence.getRevisionData(page, null);
    }
    String content, propertiesXml;
    RevCommit revCommit;
    Repository repository = getRepository(page);

    try {
      String fileSystemPath = getPath(page, repository);
      ObjectId rev = repository.resolve(label);
      RevWalk walk = new RevWalk(repository);
      revCommit = walk.parseCommit(rev);

      content = getRepositoryContent(repository, revCommit, fileSystemPath + "/" + contentFilename);
      propertiesXml =
          getRepositoryContent(repository, revCommit, fileSystemPath + "/" + propertiesFilename);
    } catch (IOException e) {
      throw new RuntimeException("Unable to get data for revision " + label, e);
    }

    final PageData pageData = new PageData(page);
    pageData.setContent(content);
    pageData.setProperties(
        parsePropertiesXml(propertiesXml, revCommit.getAuthorIdent().getWhen().getTime()));
    return pageData;
  }
예제 #7
0
  public CodeReviewCommit createCherryPickFromCommit(
      Repository repo,
      ObjectInserter inserter,
      RevCommit mergeTip,
      RevCommit originalCommit,
      PersonIdent cherryPickCommitterIdent,
      String commitMsg,
      CodeReviewRevWalk rw)
      throws MissingObjectException, IncorrectObjectTypeException, IOException,
          MergeIdenticalTreeException, MergeConflictException {

    final ThreeWayMerger m = newThreeWayMerger(repo, inserter);

    m.setBase(originalCommit.getParent(0));
    if (m.merge(mergeTip, originalCommit)) {
      ObjectId tree = m.getResultTreeId();
      if (tree.equals(mergeTip.getTree())) {
        throw new MergeIdenticalTreeException("identical tree");
      }

      CommitBuilder mergeCommit = new CommitBuilder();
      mergeCommit.setTreeId(tree);
      mergeCommit.setParentId(mergeTip);
      mergeCommit.setAuthor(originalCommit.getAuthorIdent());
      mergeCommit.setCommitter(cherryPickCommitterIdent);
      mergeCommit.setMessage(commitMsg);
      return rw.parseCommit(commit(inserter, mergeCommit));
    } else {
      throw new MergeConflictException("merge conflict");
    }
  }
예제 #8
0
  @Override
  public List<CommitDB> getCommits() {

    try {

      Iterable<RevCommit> revCommits;
      revCommits = git.log().all().call();
      List<CommitDB> commits = new ArrayList<CommitDB>();

      for (RevCommit revCommit : revCommits) {

        PersonIdent author = revCommit.getAuthorIdent();
        CommitDB commit =
            new CommitDB(0, author.getWhen(), revCommit.getFullMessage(), revCommit.getName());
        CommitterDB committerDb = new CommitterDB(0, author.getEmailAddress(), author.getName());
        commit.setCommitter(committerDb);
        commits.add(commit);
      }

      return commits;

    } catch (GitAPIException e) {
      throw new VisMinerAPIException(e.getMessage(), e);
    } catch (IOException e) {
      throw new VisMinerAPIException(e.getMessage(), e);
    }
  }
예제 #9
0
파일: Log.java 프로젝트: roewenstrunk/eXgit
  @Override
  public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {

    try {
      String localPath = args[0].getStringValue();
      if (!(localPath.endsWith("/"))) localPath += File.separator;

      //	        Repository localRepo = new FileRepository(localPath + ".git");
      //	        Git git = new Git(localRepo);

      Git git = Git.open(new Resource(localPath), FS);

      MemTreeBuilder builder = context.getDocumentBuilder();

      AttributesImpl attribs = new AttributesImpl();
      attribs.addAttribute(NAMESPACE_URI, "local-path", PREFIX + ":local-path", "CDATA", localPath);

      int nodeNr = builder.startElement(LOG_ELEMENT, attribs);

      for (RevCommit commit : git.log().call()) {
        //                commit.getParentCount();
        //                commit.getParents();

        attribs = new AttributesImpl();
        attribs.addAttribute(NAMESPACE_URI, "id", PREFIX + ":id", "CDATA", commit.name());

        attribs.addAttribute(
            NAMESPACE_URI,
            "time",
            PREFIX + ":time",
            "CDATA",
            String.valueOf(commit.getCommitTime()));

        builder.startElement(COMMIT_ELEMENT, attribs);

        PersonIdent authorIdent = commit.getAuthorIdent();
        builder.startElement(AUTHOR_ELEMENT, null);
        builder.startElement(AUTHOR_NAME_ELEMENT, null);
        builder.characters(authorIdent.getName());
        builder.endElement();
        builder.startElement(AUTHOR_EMAIL_ELEMENT, null);
        builder.characters(authorIdent.getEmailAddress());
        builder.endElement();
        builder.endElement();

        builder.startElement(MESSAGE_ELEMENT, null);
        builder.characters(commit.getFullMessage());
        builder.endElement();

        builder.endElement();
      }

      builder.endElement();

      return builder.getDocument().getNode(nodeNr);
    } catch (Throwable e) {
      throw new XPathException(this, Module.EXGIT001, e);
    }
  }
예제 #10
0
 private GitVersionInfo makeVersionInfo(RevCommit revCommit) {
   PersonIdent authorIdent = revCommit.getAuthorIdent();
   return new GitVersionInfo(
       revCommit.name(),
       authorIdent.getName(),
       authorIdent.getWhen(),
       revCommit.getShortMessage());
 }
예제 #11
0
 private Revision asRevision(final RevCommit commit) {
   final PersonIdent author = commit.getAuthorIdent();
   return new RevisionImpl(
       commit.name(),
       author.getName(),
       author.getEmailAddress(),
       author.getWhen(),
       commit.getFullMessage());
 }
예제 #12
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);
    }
  }
 public PatchSetInfo get(RevWalk rw, RevCommit src, PatchSet.Id psi) throws IOException {
   rw.parseBody(src);
   PatchSetInfo info = new PatchSetInfo(psi);
   info.setSubject(src.getShortMessage());
   info.setMessage(src.getFullMessage());
   info.setAuthor(toUserIdentity(src.getAuthorIdent()));
   info.setCommitter(toUserIdentity(src.getCommitterIdent()));
   info.setRevId(src.getName());
   return info;
 }
예제 #14
0
 public CommitInfo createCommitInfo(RevCommit entry) {
   final Date date = GitFacade.getCommitDate(entry);
   String author = entry.getAuthorIdent().getName();
   boolean merge = entry.getParentCount() > 1;
   String shortMessage = entry.getShortMessage();
   String trimmedMessage = Strings.trimString(shortMessage, 78);
   String name = entry.getName();
   String commitHashText = getShortCommitHash(name);
   return new CommitInfo(commitHashText, name, author, date, merge, trimmedMessage, shortMessage);
 }
  @Test
  public void testCommit() throws Exception {
    try (Git git = new Git(db)) {
      revCommit = git.commit().setMessage("squash_me").call();

      Ref master = db.exactRef("refs/heads/master");
      String message = msgFormatter.format(Arrays.asList(revCommit), master);
      assertEquals(
          "Squashed commit of the following:\n\ncommit "
              + revCommit.getName()
              + "\nAuthor: "
              + revCommit.getAuthorIdent().getName()
              + " <"
              + revCommit.getAuthorIdent().getEmailAddress()
              + ">\nDate:   "
              + dateFormatter.formatDate(author)
              + "\n\n\tsquash_me\n",
          message);
    }
  }
예제 #16
0
  @Override
  public Date getLastCommitDate(String treeName) {

    try {

      RevCommit lastCommit = revWalk.parseCommit(repository.resolve(treeName));
      return lastCommit.getAuthorIdent().getWhen();

    } catch (IOException e) {
      throw new VisMinerAPIException(e.getMessage(), e);
    }
  }
예제 #17
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 Git.Head getHead(final Repository repository) throws IOException {
   ObjectId revision = repository.resolve(Constants.HEAD);
   RevCommit commit = new RevWalk(repository).parseCommit(revision);
   Git.Head head =
       new Git.Head(
           revision.getName(),
           commit.getAuthorIdent().getName(),
           commit.getAuthorIdent().getEmailAddress(),
           commit.getCommitterIdent().getName(),
           commit.getCommitterIdent().getEmailAddress(),
           commit.getFullMessage());
   return head;
 }
예제 #19
0
  private void createHeaderArea(Composite parent, FormToolkit toolkit, int span) {
    RevCommit commit = getCommit().getRevCommit();
    Composite top = toolkit.createComposite(parent);
    GridDataFactory.fillDefaults().grab(true, false).span(span, 1).applyTo(top);
    GridLayoutFactory.fillDefaults().numColumns(2).applyTo(top);

    Composite userArea = toolkit.createComposite(top);
    GridLayoutFactory.fillDefaults().spacing(2, 2).numColumns(1).applyTo(userArea);
    GridDataFactory.fillDefaults().grab(true, false).applyTo(userArea);

    PersonIdent author = commit.getAuthorIdent();
    if (author != null) createUserArea(userArea, toolkit, author, true);

    PersonIdent committer = commit.getCommitterIdent();
    if (committer != null && !committer.equals(author))
      createUserArea(userArea, toolkit, committer, false);

    int count = commit.getParentCount();
    if (count > 0) {
      Composite parents = toolkit.createComposite(top);
      GridLayoutFactory.fillDefaults().spacing(2, 2).numColumns(2).applyTo(parents);
      GridDataFactory.fillDefaults().grab(false, false).applyTo(parents);

      for (int i = 0; i < count; i++) {
        final RevCommit parentCommit = commit.getParent(i);
        toolkit
            .createLabel(parents, UIText.CommitEditorPage_LabelParent)
            .setForeground(toolkit.getColors().getColor(IFormColors.TB_TOGGLE));
        final Hyperlink link =
            toolkit.createHyperlink(
                parents, parentCommit.abbreviate(PARENT_LENGTH).name(), SWT.NONE);
        link.addHyperlinkListener(
            new HyperlinkAdapter() {

              public void linkActivated(HyperlinkEvent e) {
                try {
                  CommitEditor.open(
                      new RepositoryCommit(getCommit().getRepository(), parentCommit));
                  if ((e.getStateMask() & SWT.MOD1) != 0) getEditor().close(false);
                } catch (PartInitException e1) {
                  Activator.logError("Error opening commit editor", e1); // $NON-NLS-1$
                }
              }
            });
      }
    }

    createTagsArea(userArea, toolkit, 2);
  }
예제 #20
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());
  }
예제 #21
0
 // format the output like in --pretty="%H<#>%aN<#>%at<#>%cN<#>%ct<#>%s
 private String printCommit(RevCommit c) {
   String out = "";
   PersonIdent author = c.getAuthorIdent();
   PersonIdent committer = c.getCommitterIdent();
   // long commitTime = (long)c.getCommitTime() == committer.getWhen().getTime() / 1000 (in
   // seconds)
   out +=
       ""
           + c.name()
           + GitWorks.log_sep
           + author.getName()
           + GitWorks.log_sep
           + author.getWhen().getTime()
           + GitWorks.log_sep
           + committer.getName()
           + GitWorks.log_sep
           + committer.getWhen().getTime()
           + GitWorks.log_sep
           + c.getShortMessage(); // c.getFullMessage(); c.getShortMessage();
   return out;
 }
예제 #22
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) {
    }
  }
예제 #23
0
  public List<CommitDB> getCommitsByTree(String treeName, TreeType type) {

    Iterable<RevCommit> revCommits = null;

    if (type == TreeType.BRANCH) {
      revCommits = getCommitsFromBranch(treeName);
    } else if (type == TreeType.TAG) {
      revCommits = getCommitsFromTag(treeName);
    }

    List<CommitDB> commits = new ArrayList<CommitDB>();
    for (RevCommit revCommit : revCommits) {
      CommitDB commit =
          new CommitDB(
              0,
              revCommit.getAuthorIdent().getWhen(),
              revCommit.getFullMessage(),
              revCommit.getName());
      commits.add(commit);
    }

    return commits;
  }
예제 #24
0
  private void createMessageArea(Composite parent, FormToolkit toolkit, int span) {
    Section messageSection = createSection(parent, toolkit, span);
    Composite messageArea = createSectionClient(messageSection, toolkit);

    messageSection.setText(UIText.CommitEditorPage_SectionMessage);

    RevCommit commit = getCommit().getRevCommit();
    String message = commit.getFullMessage();

    PersonIdent author = commit.getAuthorIdent();
    if (author != null) message = replaceSignedOffByLine(message, author);
    PersonIdent committer = commit.getCommitterIdent();
    if (committer != null) message = replaceSignedOffByLine(message, committer);

    SpellcheckableMessageArea textContent =
        new SpellcheckableMessageArea(messageArea, message, true, toolkit.getBorderStyle()) {

          @Override
          protected IAdaptable getDefaultTarget() {
            return new PlatformObject() {
              public Object getAdapter(Class adapter) {
                return Platform.getAdapterManager().getAdapter(getEditorInput(), adapter);
              }
            };
          }

          protected void createMarginPainter() {
            // Disabled intentionally
          }
        };
    if ((toolkit.getBorderStyle() & SWT.BORDER) == 0)
      textContent.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
    GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 80).grab(true, true).applyTo(textContent);

    updateSectionClient(messageSection, messageArea, toolkit);
  }
예제 #25
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);
        }
      }
    }
  }
예제 #26
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);
    }
  }
예제 #27
0
  /**
   * Update the submodules in one branch of one repository.
   *
   * @param subscriber the branch of the repository which should be changed.
   * @param updates submodule updates which should be updated to.
   * @throws SubmoduleException
   */
  private void updateGitlinks(
      ReviewDb db, Branch.NameKey subscriber, Collection<SubmoduleSubscription> updates)
      throws SubmoduleException {
    PersonIdent author = null;

    Repository pdb = null;
    RevWalk recRw = null;

    StringBuilder msgbuf = new StringBuilder("Updated git submodules\n\n");
    try {
      boolean sameAuthorForAll = true;

      pdb = repoManager.openRepository(subscriber.getParentKey());
      if (pdb.getRef(subscriber.get()) == null) {
        throw new SubmoduleException(
            "The branch was probably deleted from the subscriber repository");
      }

      DirCache dc = readTree(pdb, pdb.getRef(subscriber.get()));
      DirCacheEditor ed = dc.editor();

      for (SubmoduleSubscription s : updates) {
        try (Repository subrepo = repoManager.openRepository(s.getSubmodule().getParentKey());
            RevWalk rw = CodeReviewCommit.newRevWalk(subrepo)) {
          Ref ref = subrepo.getRefDatabase().exactRef(s.getSubmodule().get());
          if (ref == null) {
            ed.add(new DeletePath(s.getPath()));
            continue;
          }

          final ObjectId updateTo = ref.getObjectId();
          RevCommit newCommit = rw.parseCommit(updateTo);

          if (author == null) {
            author = newCommit.getAuthorIdent();
          } else if (!author.equals(newCommit.getAuthorIdent())) {
            sameAuthorForAll = false;
          }

          DirCacheEntry dce = dc.getEntry(s.getPath());
          ObjectId oldId = null;
          if (dce != null) {
            if (!dce.getFileMode().equals(FileMode.GITLINK)) {
              log.error(
                  "Requested to update gitlink "
                      + s.getPath()
                      + " in "
                      + s.getSubmodule().getParentKey().get()
                      + " but entry "
                      + "doesn't have gitlink file mode.");
              continue;
            }
            oldId = dce.getObjectId();
          } else {
            // This submodule did not exist before. We do not want to add
            // the full submodule history to the commit message, so omit it.
            oldId = updateTo;
          }

          ed.add(
              new PathEdit(s.getPath()) {
                @Override
                public void apply(DirCacheEntry ent) {
                  ent.setFileMode(FileMode.GITLINK);
                  ent.setObjectId(updateTo);
                }
              });
          if (verboseSuperProject) {
            msgbuf.append("Project: " + s.getSubmodule().getParentKey().get());
            msgbuf.append(" " + s.getSubmodule().getShortName());
            msgbuf.append(" " + updateTo.getName());
            msgbuf.append("\n\n");

            try {
              rw.markStart(newCommit);

              if (oldId != null) {
                rw.markUninteresting(rw.parseCommit(oldId));
              }
              for (RevCommit c : rw) {
                msgbuf.append(c.getFullMessage() + "\n\n");
              }
            } catch (IOException e) {
              logAndThrowSubmoduleException(
                  "Could not perform a revwalk to " + "create superproject commit message", e);
            }
          }
        }
      }
      ed.finish();

      if (!sameAuthorForAll || author == null) {
        author = myIdent;
      }

      ObjectInserter oi = pdb.newObjectInserter();
      ObjectId tree = dc.writeTree(oi);

      ObjectId currentCommitId = pdb.getRef(subscriber.get()).getObjectId();

      CommitBuilder commit = new CommitBuilder();
      commit.setTreeId(tree);
      commit.setParentIds(new ObjectId[] {currentCommitId});
      commit.setAuthor(author);
      commit.setCommitter(myIdent);
      commit.setMessage(msgbuf.toString());
      oi.insert(commit);
      oi.flush();

      ObjectId commitId = oi.idFor(Constants.OBJ_COMMIT, commit.build());

      final RefUpdate rfu = pdb.updateRef(subscriber.get());
      rfu.setForceUpdate(false);
      rfu.setNewObjectId(commitId);
      rfu.setExpectedOldObjectId(currentCommitId);
      rfu.setRefLogMessage("Submit to " + subscriber.getParentKey().get(), true);

      switch (rfu.update()) {
        case NEW:
        case FAST_FORWARD:
          gitRefUpdated.fire(subscriber.getParentKey(), rfu);
          changeHooks.doRefUpdatedHook(subscriber, rfu, account);
          // TODO since this is performed "in the background" no mail will be
          // sent to inform users about the updated branch
          break;

        default:
          throw new IOException(rfu.getResult().name());
      }
      recRw = new RevWalk(pdb);
      // Recursive call: update subscribers of the subscriber
      updateSuperProjects(db, Sets.newHashSet(subscriber));
    } catch (IOException e) {
      throw new SubmoduleException("Cannot update gitlinks for " + subscriber.get(), e);
    } finally {
      if (recRw != null) {
        recRw.close();
      }
      if (pdb != null) {
        pdb.close();
      }
    }
  }
예제 #28
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);
    }
  }
예제 #29
0
  @Override
  public Document execute(
      Repository repository, Git git, CallSpecification spec, DocumentWriter writer, Values values)
      throws GitAPIException, IOException {
    if (spec.parameterCount() == 0) {
      // This is the top-level "/branches" node
      writer.setPrimaryType(GitLexicon.TREES);

      // Generate the child references to the branches and tags. Branches are likely used more
      // often, so list them first...
      addBranchesAsChildren(git, spec, writer);
      addTagsAsChildren(git, spec, writer);
      addCommitsAsChildren(git, spec, writer, pageSize);

    } else if (spec.parameterCount() == 1) {
      // This is a particular branch/tag/commit node ...
      String branchOrTagOrObjectId = spec.parameter(0);
      ObjectId objId = resolveBranchOrTagOrCommitId(repository, branchOrTagOrObjectId);
      RevWalk walker = new RevWalk(repository);
      walker.setRetainBody(true); // we need to parse the commit for the top-level
      try {
        RevCommit commit = walker.parseCommit(objId);

        // Add the properties for this node ...
        String committer = commit.getCommitterIdent().getName();
        String author = commit.getAuthorIdent().getName();
        DateTime committed = values.dateFrom(commit.getCommitTime());
        writer.setPrimaryType(GitLexicon.FOLDER);
        writer.addProperty(JcrLexicon.CREATED, committed);
        writer.addProperty(JcrLexicon.CREATED_BY, committer);
        writer.addProperty(GitLexicon.OBJECT_ID, objId.name());
        writer.addProperty(GitLexicon.AUTHOR, author);
        writer.addProperty(GitLexicon.COMMITTER, committer);
        writer.addProperty(GitLexicon.COMMITTED, committed);
        writer.addProperty(GitLexicon.TITLE, commit.getShortMessage());
        writer.addProperty(
            GitLexicon.HISTORY,
            GitHistory.referenceToHistory(objId, branchOrTagOrObjectId, values));
        writer.addProperty(GitLexicon.DETAIL, GitCommitDetails.referenceToCommit(objId, values));

        // Add the top-level children of the directory ...
        addInformationForPath(repository, git, writer, commit, "", spec, values);

      } finally {
        walker.dispose();
      }

    } else {
      // This is a folder or file within the directory structure ...
      String branchOrTagOrObjectId = spec.parameter(0);
      String path = spec.parametersAsPath(1);
      ObjectId objId = resolveBranchOrTagOrCommitId(repository, branchOrTagOrObjectId);
      RevWalk walker = new RevWalk(repository);
      walker.setRetainBody(false); // we don't need top-level commit information
      try {
        // Get the commit information ...
        RevCommit commit = walker.parseCommit(objId);

        // Add the top-level children of the directory ...
        addInformationForPath(repository, git, writer, commit, path, spec, values);

      } finally {
        walker.dispose();
      }
    }
    return writer.document();
  }