protected boolean hasIgnoreFile(Repository repository, RevCommit revCommit, String relativePath)
      throws Exception {

    if (_ignoreFileName == null) {
      return false;
    }

    try (TreeWalk treeWalk = new TreeWalk(repository)) {
      treeWalk.addTree(revCommit.getTree());

      if (revCommit.getParentCount() > 0) {
        RevCommit parentRevCommit = revCommit.getParent(0);

        treeWalk.addTree(parentRevCommit.getTree());
      }

      treeWalk.setRecursive(true);

      treeWalk.setFilter(
          AndTreeFilter.create(
              PathFilter.create(relativePath + "/" + _ignoreFileName), TreeFilter.ANY_DIFF));

      return treeWalk.next();
    }
  }
Beispiel #2
0
  public void buildCompositeCommits() throws IOException {
    revWalk = new RevWalk(repository);
    ByteArrayOutputStream diffTexts = new ByteArrayOutputStream();
    DiffFormatter df = new DiffFormatter(diffTexts);
    df.setRepository(repository);
    df.setDiffComparator(RawTextComparator.WS_IGNORE_ALL);
    df.setContext(0);
    df.setDiffAlgorithm(DiffAlgorithm.getAlgorithm(SupportedAlgorithm.HISTOGRAM));
    df.setDetectRenames(true);
    for (int idx = 0; idx < _commits.size(); idx++) {
      RevCommit commit = revWalk.parseCommit(_commits.get(idx));
      int p_count = commit.getParentCount();
      if (p_count == 0) {
        throw new RuntimeException("commit with no parent ?!?!");
      }
      RevCommit p = revWalk.parseCommit(commit.getParent(0).getId());
      List<DiffEntry> diffs = df.scan(p.getTree(), commit.getTree());
      for (DiffEntry d : diffs) {
        CompositeDiff cd = new CompositeDiff(d, commit);

        if (ParsingUtils.isSourceFile(d.getOldPath())
            || ParsingUtils.isSourceFile(d.getNewPath())) {
          extractCodeEdits(diffTexts, df, d, cd);
        }
        _diffs.add(cd);
      }
    }
    revWalk.release();
  }
  @Test
  public void testAddUnstagedChanges()
      throws IOException, NoHeadException, NoMessageException, ConcurrentRefUpdateException,
          JGitInternalException, WrongRepositoryStateException, NoFilepatternException {
    File file = new File(db.getWorkTree(), "a.txt");
    FileUtils.createNewFile(file);
    PrintWriter writer = new PrintWriter(file);
    writer.print("content");
    writer.close();

    Git git = new Git(db);
    git.add().addFilepattern("a.txt").call();
    RevCommit commit = git.commit().setMessage("initial commit").call();
    TreeWalk tw = TreeWalk.forPath(db, "a.txt", commit.getTree());
    assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", tw.getObjectId(0).getName());

    writer = new PrintWriter(file);
    writer.print("content2");
    writer.close();
    commit = git.commit().setMessage("second commit").call();
    tw = TreeWalk.forPath(db, "a.txt", commit.getTree());
    assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", tw.getObjectId(0).getName());

    commit = git.commit().setAll(true).setMessage("third commit").setAll(true).call();
    tw = TreeWalk.forPath(db, "a.txt", commit.getTree());
    assertEquals("db00fd65b218578127ea51f3dffac701f12f486a", tw.getObjectId(0).getName());
  }
Beispiel #4
0
  private DiffEntry findRename(RevCommit parent, RevCommit commit, PathFilter path)
      throws IOException {
    if (renameDetector == null) return null;

    treeWalk.setFilter(TreeFilter.ANY_DIFF);
    treeWalk.reset(parent.getTree(), commit.getTree());
    renameDetector.reset();
    renameDetector.addAll(DiffEntry.scan(treeWalk));
    for (DiffEntry ent : renameDetector.compute()) {
      if (isRename(ent) && ent.getNewPath().equals(path.getPath())) return ent;
    }
    return null;
  }
 private void addTrees(Map<SubtreeConfig, RevCommit> parentCommits, TreeWalk treeWalk)
     throws IOException {
   for (Map.Entry<SubtreeConfig, RevCommit> entry : parentCommits.entrySet()) {
     String directory = entry.getKey().getSubtreeDirectory();
     RevCommit parentCommit = entry.getValue();
     if (".".equals(directory)) {
       treeWalk.addTree(parentCommit.getTree());
     } else {
       byte[] prefix = directory.getBytes(RawParseUtils.UTF8_CHARSET);
       CanonicalTreeParser treeParser =
           new CanonicalTreeParser(prefix, treeWalk.getObjectReader(), parentCommit.getTree());
       treeWalk.addTree(treeParser);
     }
   }
 }
    @Override
    public ChangeKind load(Key key) throws IOException {
      if (Objects.equal(key.prior, key.next)) {
        return ChangeKind.NO_CODE_CHANGE;
      }

      RevWalk walk = new RevWalk(key.repo);
      try {
        RevCommit prior = walk.parseCommit(key.prior);
        walk.parseBody(prior);
        RevCommit next = walk.parseCommit(key.next);
        walk.parseBody(next);

        if (!next.getFullMessage().equals(prior.getFullMessage())) {
          if (next.getTree() == prior.getTree() && isSameParents(prior, next)) {
            return ChangeKind.NO_CODE_CHANGE;
          } else {
            return ChangeKind.REWORK;
          }
        }

        if (prior.getParentCount() != 1 || next.getParentCount() != 1) {
          // Trivial rebases done by machine only work well on 1 parent.
          return ChangeKind.REWORK;
        }

        if (next.getTree() == prior.getTree() && isSameParents(prior, next)) {
          return ChangeKind.TRIVIAL_REBASE;
        }

        // A trivial rebase can be detected by looking for the next commit
        // having the same tree as would exist when the prior commit is
        // cherry-picked onto the next commit's new first parent.
        ThreeWayMerger merger =
            MergeUtil.newThreeWayMerger(
                key.repo, MergeUtil.createDryRunInserter(), key.strategyName);
        merger.setBase(prior.getParent(0));
        if (merger.merge(next.getParent(0), prior)
            && merger.getResultTreeId().equals(next.getTree())) {
          return ChangeKind.TRIVIAL_REBASE;
        } else {
          return ChangeKind.REWORK;
        }
      } finally {
        key.repo = null;
        walk.release();
      }
    }
Beispiel #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");
    }
  }
Beispiel #8
0
 @Override
 public String getContent(String objectId, String blobPath) {
   objectId = defaultObjectId(objectId);
   Repository r = git.getRepository();
   RevCommit commit = JGitUtils.getCommit(r, objectId);
   return JGitUtils.getStringContent(r, commit.getTree(), blobPath, encodings);
 }
Beispiel #9
0
  /**
   * Returns the diff between the two commits for the specified file or folder formatted as a patch.
   *
   * @param repository
   * @param baseCommit if base commit is unspecified, the patch is generated against the primary
   *     parent of the specified commit.
   * @param commit
   * @param path if path is specified, the patch is generated only for the specified file or folder.
   *     if unspecified, the patch is generated for the entire diff between the two commits.
   * @return patch as a string
   */
  public static String getCommitPatch(
      Repository repository, RevCommit baseCommit, RevCommit commit, String path) {
    String diff = null;
    try {
      final ByteArrayOutputStream os = new ByteArrayOutputStream();
      RawTextComparator cmp = RawTextComparator.DEFAULT;
      PatchFormatter df = new PatchFormatter(os);
      df.setRepository(repository);
      df.setDiffComparator(cmp);
      df.setDetectRenames(true);

      RevTree commitTree = commit.getTree();
      RevTree baseTree;
      if (baseCommit == null) {
        if (commit.getParentCount() > 0) {
          final RevWalk rw = new RevWalk(repository);
          RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
          baseTree = parent.getTree();
        } else {
          // FIXME initial commit. no parent?!
          baseTree = commitTree;
        }
      } else {
        baseTree = baseCommit.getTree();
      }

      List<DiffEntry> diffEntries = df.scan(baseTree, commitTree);
      if (path != null && path.length() > 0) {
        for (DiffEntry diffEntry : diffEntries) {
          if (diffEntry.getNewPath().equalsIgnoreCase(path)) {
            df.format(diffEntry);
            break;
          }
        }
      } else {
        df.format(diffEntries);
      }
      diff = df.getPatch(commit);
      df.flush();
    } catch (Throwable t) {
      try {
        error(t, repository, "failed to generate commit diff!");
      } catch (Exception e) {
      }
    }
    return diff;
  }
Beispiel #10
0
 @Override
 public RevCommit next() throws MissingObjectException, IncorrectObjectTypeException, IOException {
   for (; ; ) {
     final RevCommit r = super.next();
     if (r == null) return null;
     if ((r.flags & UNINTERESTING) != 0) {
       markTreeUninteresting(r.getTree());
       if (hasRevSort(RevSort.BOUNDARY)) {
         pendingObjects.add(r.getTree());
         return r;
       }
       continue;
     }
     pendingObjects.add(r.getTree());
     return r;
   }
 }
Beispiel #11
0
 private boolean find(RevCommit commit, PathFilter path) throws IOException {
   treeWalk.setFilter(path);
   treeWalk.reset(commit.getTree());
   if (treeWalk.next() && isFile(treeWalk.getRawMode(0))) {
     treeWalk.getObjectId(idBuf, 0);
     return true;
   }
   return false;
 }
  private String getRepositoryContent(Repository repository, RevCommit revCommit, String fileName)
      throws IOException {
    TreeWalk treewalk = TreeWalk.forPath(repository, fileName, revCommit.getTree());

    if (treewalk != null) {
      return new String(repository.open(treewalk.getObjectId(0)).getBytes());
    } else {
      return null;
    }
  }
Beispiel #13
0
 public CommitBuilder parent(RevCommit p) throws Exception {
   if (parents.isEmpty()) {
     DirCacheBuilder b = tree.builder();
     parseBody(p);
     b.addTree(new byte[0], DirCacheEntry.STAGE_0, pool.getObjectReader(), p.getTree());
     b.finish();
   }
   parents.add(p);
   return this;
 }
Beispiel #14
0
 public List<PathInfo> getPathInfos(boolean recursive) throws IOException {
   TreeWalk tw = new TreeWalk(reader);
   tw.addTree(revision.getTree());
   tw.setRecursive(recursive);
   List<PathInfo> paths = Lists.newArrayList();
   while (tw.next()) {
     paths.add(new PathInfo(tw));
   }
   return paths;
 }
Beispiel #15
0
 private TreeWalk createTreeWalk(RevCommit commit, boolean isRecursive, boolean honorIgnores)
     throws Exception {
   TreeWalk treeWalk = new TreeWalk(db);
   treeWalk.setRecursive(isRecursive);
   treeWalk.addTree(commit.getTree());
   treeWalk.addTree(new DirCacheIterator(db.readDirCache()));
   treeWalk.addTree(new FileTreeIterator(db));
   if (!honorIgnores) treeWalk.setFilter(new IndexDiffFilter(1, 2, honorIgnores));
   else treeWalk.setFilter(new IndexDiffFilter(1, 2));
   return treeWalk;
 }
Beispiel #16
0
  protected ObjectId getObjectId(String fileName) throws IOException {
    if (revision == null) {
      return null;
    }

    TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree());
    if (tw != null) {
      return tw.getObjectId(0);
    }

    return null;
  }
Beispiel #17
0
  protected byte[] readFile(String fileName) throws IOException {
    if (revision == null) {
      return new byte[] {};
    }

    TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree());
    if (tw != null) {
      ObjectLoader obj = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB);
      return obj.getCachedBytes(Integer.MAX_VALUE);

    } else {
      return new byte[] {};
    }
  }
 public List<String> readElementsAt(Repository repository, String commit) throws IOException {
   RevWalk revWalk = new RevWalk(repository);
   RevCommit revCommit = revWalk.parseCommit(ObjectId.fromString(commit));
   RevTree tree = revCommit.getTree();
   List<String> items = new ArrayList<>();
   TreeWalk treeWalk = new TreeWalk(repository);
   treeWalk.addTree(tree);
   treeWalk.setRecursive(true);
   treeWalk.setPostOrderTraversal(true);
   while (treeWalk.next()) {
     items.add(treeWalk.getPathString());
   }
   return items;
 }
  @Override
  public byte[] getData(String commitName, String filePath) {

    try {

      RevCommit revCommit = revWalk.parseCommit(ObjectId.fromString(commitName));
      RevTree tree = revCommit.getTree();
      TreeWalk treeWalk = TreeWalk.forPath(reader, filePath, tree);

      if (treeWalk == null) return null;
      else return reader.open(treeWalk.getObjectId(0)).getBytes();

    } catch (IOException e) {
      throw new VisMinerAPIException(e.getMessage(), e);
    }
  }
Beispiel #20
0
  private void doCheckout(final Ref branch) throws IOException {
    if (branch == null) throw die(CLIText.get().cannotChekoutNoHeadsAdvertisedByRemote);
    if (!Constants.HEAD.equals(branch.getName())) {
      RefUpdate u = db.updateRef(Constants.HEAD);
      u.disableRefLog();
      u.link(branch.getName());
    }

    final RevCommit commit = parseCommit(branch);
    final RefUpdate u = db.updateRef(Constants.HEAD);
    u.setNewObjectId(commit);
    u.forceUpdate();

    DirCache dc = db.lockDirCache();
    DirCacheCheckout co = new DirCacheCheckout(db, dc, commit.getTree());
    co.checkout();
  }
 /**
  * Returns the list of files in the specified folder at the specified commit. If the repository
  * does not exist or is empty, an empty list is returned.
  *
  * @param repository
  * @param path if unspecified, root folder is assumed.
  * @param commit if null, HEAD is assumed.
  * @return list of files in specified path
  */
 public static List<PathModel> getFilesInPath(
     Repository repository, String path, RevCommit commit) {
   List<PathModel> list = new ArrayList<PathModel>();
   if (!hasCommits(repository)) {
     return list;
   }
   if (commit == null) {
     commit = getCommit(repository, null);
   }
   final TreeWalk tw = new TreeWalk(repository);
   try {
     tw.addTree(commit.getTree());
     if (!(path == null)) {
       PathFilter f = PathFilter.create(path);
       tw.setFilter(f);
       tw.setRecursive(false);
       boolean foundFolder = false;
       while (tw.next()) {
         if (!foundFolder && tw.isSubtree()) {
           tw.enterSubtree();
         }
         if (tw.getPathString().equals(path)) {
           foundFolder = true;
           continue;
         }
         if (foundFolder) {
           list.add(getPathModel(tw, path, commit));
         }
       }
     } else {
       tw.setRecursive(false);
       while (tw.next()) {
         list.add(getPathModel(tw, null, commit));
       }
     }
   } catch (IOException e) {
     // error(e, repository, "{0} failed to get files for commit {1}", commit.getName());
     Logger.error(e, e.getMessage());
   } finally {
     tw.release();
   }
   Collections.sort(list);
   return list;
 }
Beispiel #22
0
 private void fillTreeItemWithGitDirectory(
     RepositoryMapping m, TreeItem treeItem, boolean isAlternative) {
   if (m.getGitDir() == null)
     treeItem.setText(2, UIText.ExistingOrNewPage_SymbolicValueEmptyMapping);
   else {
     IPath relativePath = new Path(m.getGitDir());
     if (isAlternative) {
       IPath withoutLastSegment = relativePath.removeLastSegments(1);
       IPath path;
       if (withoutLastSegment.isEmpty()) path = Path.fromPortableString("."); // $NON-NLS-1$
       else path = withoutLastSegment;
       treeItem.setText(0, path.toString());
     }
     treeItem.setText(2, relativePath.toOSString());
     try {
       IProject project = m.getContainer().getProject();
       Repository repo =
           new RepositoryBuilder().setGitDir(m.getGitDirAbsolutePath().toFile()).build();
       File workTree = repo.getWorkTree();
       IPath workTreePath = Path.fromOSString(workTree.getAbsolutePath());
       if (workTreePath.isPrefixOf(project.getLocation())) {
         IPath makeRelativeTo = project.getLocation().makeRelativeTo(workTreePath);
         String repoRelativePath =
             makeRelativeTo.append("/.project").toPortableString(); // $NON-NLS-1$
         ObjectId headCommitId = repo.resolve(Constants.HEAD);
         if (headCommitId != null) {
           // Not an empty repo
           RevWalk revWalk = new RevWalk(repo);
           RevCommit headCommit = revWalk.parseCommit(headCommitId);
           RevTree headTree = headCommit.getTree();
           TreeWalk projectInRepo = TreeWalk.forPath(repo, repoRelativePath, headTree);
           if (projectInRepo != null) {
             // the .project file is tracked by this repo
             treeItem.setChecked(true);
           }
           revWalk.dispose();
         }
       }
       repo.close();
     } catch (IOException e1) {
       Activator.logError(UIText.ExistingOrNewPage_FailedToDetectRepositoryMessage, e1);
     }
   }
 }
  @Override
  public List<String> getSnapshotFiles(String commitUid) {

    try {

      RevCommit lastCommit = revWalk.parseCommit(repository.resolve(commitUid));

      treeWalk.reset();
      treeWalk.addTree(lastCommit.getTree());
      treeWalk.setRecursive(true);

      List<String> files = new ArrayList<String>();
      while (treeWalk.next()) {
        String path = repositoryPath + "/" + treeWalk.getPathString();
        files.add(StringUtils.sha1(path));
      }

      return files;

    } catch (IOException e) {
      throw new VisMinerAPIException(e.getMessage(), e);
    }
  }
Beispiel #24
0
  /**
   * Create an iterator to walk the merge base of two commits.
   *
   * @param aIdx index of the first commit in {@link #sourceObjects}.
   * @param bIdx index of the second commit in {@link #sourceObjects}.
   * @return the new iterator
   * @throws IncorrectObjectTypeException one of the input objects is not a commit.
   * @throws IOException objects are missing or multiple merge bases were found.
   */
  protected AbstractTreeIterator mergeBase(final int aIdx, final int bIdx) throws IOException {
    if (sourceCommits[aIdx] == null)
      throw new IncorrectObjectTypeException(sourceObjects[aIdx], Constants.TYPE_COMMIT);
    if (sourceCommits[bIdx] == null)
      throw new IncorrectObjectTypeException(sourceObjects[bIdx], Constants.TYPE_COMMIT);

    walk.reset();
    walk.setRevFilter(RevFilter.MERGE_BASE);
    walk.markStart(sourceCommits[aIdx]);
    walk.markStart(sourceCommits[bIdx]);
    final RevCommit base = walk.next();
    if (base == null) return new EmptyTreeIterator();
    final RevCommit base2 = walk.next();
    if (base2 != null) {
      throw new IOException(
          MessageFormat.format(
              JGitText.get().multipleMergeBasesFor,
              sourceCommits[aIdx].name(),
              sourceCommits[bIdx].name(),
              base.name(),
              base2.name()));
    }
    return openTree(base.getTree());
  }
Beispiel #25
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.get(PreCommitHook.NAME)).call();
      }

      processOptions(state, rw);

      if (all && !repo.isBare()) {
        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.exactRef(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.get(CommitMsgHook.NAME))
                .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);

        // Check for empty commits
        if (headId != null && !allowEmpty.booleanValue()) {
          RevCommit headCommit = rw.parseCommit(headId);
          headCommit.getTree();
          if (indexTreeId.equals(headCommit.getTree())) {
            throw new EmtpyCommitException(JGitText.get().emptyCommit);
          }
        }

        // 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 (!useDefaultReflogMessage) {
          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);
              }
              Hooks.postCommit(repo, hookOutRedirect.get(PostCommitHook.NAME)).call();

              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);
    }
  }
Beispiel #26
0
  void updateSubmoduleSubscriptions(ReviewDb db, Branch.NameKey destBranch)
      throws SubmoduleException {
    if (urlProvider.get() == null) {
      logAndThrowSubmoduleException(
          "Cannot establish canonical web url used "
              + "to access gerrit. It should be provided in gerrit.config file.");
    }
    try (Repository repo = repoManager.openRepository(destBranch.getParentKey());
        RevWalk rw = new RevWalk(repo)) {

      ObjectId id = repo.resolve(destBranch.get());
      RevCommit commit = rw.parseCommit(id);

      Set<SubmoduleSubscription> oldSubscriptions =
          Sets.newHashSet(db.submoduleSubscriptions().bySuperProject(destBranch));

      Set<SubmoduleSubscription> newSubscriptions;
      TreeWalk tw = TreeWalk.forPath(repo, GIT_MODULES, commit.getTree());
      if (tw != null
          && (FileMode.REGULAR_FILE.equals(tw.getRawMode(0))
              || FileMode.EXECUTABLE_FILE.equals(tw.getRawMode(0)))) {
        BlobBasedConfig bbc = new BlobBasedConfig(null, repo, commit, GIT_MODULES);

        String thisServer = new URI(urlProvider.get()).getHost();

        newSubscriptions =
            subSecParserFactory.create(bbc, thisServer, destBranch).parseAllSections();
      } else {
        newSubscriptions = Collections.emptySet();
      }

      Set<SubmoduleSubscription> alreadySubscribeds = new HashSet<>();
      for (SubmoduleSubscription s : newSubscriptions) {
        if (oldSubscriptions.contains(s)) {
          alreadySubscribeds.add(s);
        }
      }

      oldSubscriptions.removeAll(newSubscriptions);
      newSubscriptions.removeAll(alreadySubscribeds);

      if (!oldSubscriptions.isEmpty()) {
        db.submoduleSubscriptions().delete(oldSubscriptions);
      }
      if (!newSubscriptions.isEmpty()) {
        db.submoduleSubscriptions().insert(newSubscriptions);
      }

    } catch (OrmException e) {
      logAndThrowSubmoduleException(
          "Database problem at update of subscriptions table from " + GIT_MODULES + " file.", e);
    } catch (ConfigInvalidException e) {
      logAndThrowSubmoduleException(
          "Problem at update of subscriptions table: " + GIT_MODULES + " config file is invalid.",
          e);
    } catch (IOException e) {
      logAndThrowSubmoduleException(
          "Problem at update of subscriptions table from " + GIT_MODULES + ".", e);
    } catch (URISyntaxException e) {
      logAndThrowSubmoduleException(
          "Incorrect gerrit canonical web url provided in gerrit.config file.", e);
    }
  }
  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));
        }
      }
    }
  }
  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;
  }
  /**
   * Execute the SubmoduleUpdateCommand command.
   *
   * @return a collection of updated submodule paths
   * @throws ConcurrentRefUpdateException
   * @throws CheckoutConflictException
   * @throws InvalidMergeHeadsException
   * @throws InvalidConfigurationException
   * @throws NoHeadException
   * @throws NoMessageException
   * @throws RefNotFoundException
   * @throws WrongRepositoryStateException
   * @throws GitAPIException
   */
  public Collection<String> call()
      throws InvalidConfigurationException, NoHeadException, ConcurrentRefUpdateException,
          CheckoutConflictException, InvalidMergeHeadsException, WrongRepositoryStateException,
          NoMessageException, NoHeadException, RefNotFoundException, GitAPIException {
    checkCallable();

    try {
      SubmoduleWalk generator = SubmoduleWalk.forIndex(repo);
      if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths));
      List<String> updated = new ArrayList<String>();
      while (generator.next()) {
        // Skip submodules not registered in .gitmodules file
        if (generator.getModulesPath() == null) continue;
        // Skip submodules not registered in parent repository's config
        String url = generator.getConfigUrl();
        if (url == null) continue;

        Repository submoduleRepo = generator.getRepository();
        // Clone repository is not present
        if (submoduleRepo == null) {
          CloneCommand clone = Git.cloneRepository();
          configure(clone);
          clone.setURI(url);
          clone.setDirectory(generator.getDirectory());
          clone.setGitDir(
              new File(new File(repo.getDirectory(), Constants.MODULES), generator.getPath()));
          if (monitor != null) clone.setProgressMonitor(monitor);
          submoduleRepo = clone.call().getRepository();
        }

        try {
          RevWalk walk = new RevWalk(submoduleRepo);
          RevCommit commit = walk.parseCommit(generator.getObjectId());

          String update = generator.getConfigUpdate();
          if (ConfigConstants.CONFIG_KEY_MERGE.equals(update)) {
            MergeCommand merge = new MergeCommand(submoduleRepo);
            merge.include(commit);
            merge.setStrategy(strategy);
            merge.call();
          } else if (ConfigConstants.CONFIG_KEY_REBASE.equals(update)) {
            RebaseCommand rebase = new RebaseCommand(submoduleRepo);
            rebase.setUpstream(commit);
            rebase.setStrategy(strategy);
            rebase.call();
          } else {
            // Checkout commit referenced in parent repository's
            // index as a detached HEAD
            DirCacheCheckout co =
                new DirCacheCheckout(submoduleRepo, submoduleRepo.lockDirCache(), commit.getTree());
            co.setFailOnConflict(true);
            co.checkout();
            RefUpdate refUpdate = submoduleRepo.updateRef(Constants.HEAD, true);
            refUpdate.setNewObjectId(commit);
            refUpdate.forceUpdate();
          }
        } finally {
          submoduleRepo.close();
        }
        updated.add(generator.getPath());
      }
      return updated;
    } catch (IOException e) {
      throw new JGitInternalException(e.getMessage(), e);
    } catch (ConfigInvalidException e) {
      throw new InvalidConfigurationException(e.getMessage(), e);
    }
  }
Beispiel #30
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);
    }
  }