|
63 | 63 | import org.eclipse.jgit.diff.DiffFormatter;
|
64 | 64 | import org.eclipse.jgit.diff.RawText;
|
65 | 65 | import org.eclipse.jgit.diff.RawTextComparator;
|
| 66 | +import org.eclipse.jgit.lib.Config; |
66 | 67 | import org.eclipse.jgit.lib.Constants;
|
67 | 68 | import org.eclipse.jgit.lib.ObjectId;
|
68 | 69 | import org.eclipse.jgit.lib.ObjectLoader;
|
69 | 70 | import org.eclipse.jgit.lib.ObjectReader;
|
70 | 71 | import org.eclipse.jgit.lib.PersonIdent;
|
71 | 72 | import org.eclipse.jgit.lib.Ref;
|
| 73 | +import org.eclipse.jgit.revwalk.FollowFilter; |
72 | 74 | import org.eclipse.jgit.revwalk.RevCommit;
|
73 | 75 | import org.eclipse.jgit.revwalk.RevTree;
|
74 | 76 | import org.eclipse.jgit.revwalk.RevWalk;
|
75 | 77 | import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
|
76 | 78 | import org.eclipse.jgit.treewalk.AbstractTreeIterator;
|
77 | 79 | import org.eclipse.jgit.treewalk.CanonicalTreeParser;
|
78 | 80 | import org.eclipse.jgit.treewalk.TreeWalk;
|
| 81 | +import org.eclipse.jgit.treewalk.filter.AndTreeFilter; |
79 | 82 | import org.eclipse.jgit.treewalk.filter.PathFilter;
|
| 83 | +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; |
| 84 | +import org.eclipse.jgit.treewalk.filter.TreeFilter; |
80 | 85 | import org.eclipse.jgit.util.io.CountingOutputStream;
|
81 | 86 | import org.eclipse.jgit.util.io.NullOutputStream;
|
82 | 87 | import org.jetbrains.annotations.NotNull;
|
@@ -600,63 +605,70 @@ History getHistory(File file, String sinceRevision) throws HistoryException {
|
600 | 605 | final List<HistoryEntry> entries = new ArrayList<>();
|
601 | 606 | final List<String> renamedFiles = new ArrayList<>();
|
602 | 607 |
|
603 |
| - try (org.eclipse.jgit.lib.Repository repository = getJGitRepository(getDirectoryName())) { |
604 |
| - try (Git git = new Git(repository)) { |
| 608 | + try (org.eclipse.jgit.lib.Repository repository = getJGitRepository(getDirectoryName()); |
| 609 | + RevWalk walk = new RevWalk(repository)) { |
605 | 610 |
|
606 |
| - // TODO: does log() take current branch into account ? |
607 |
| - LogCommand log = git.log(); |
608 |
| - if (sinceRevision != null) { |
609 |
| - log.addRange(repository.resolve(sinceRevision), repository.resolve("HEAD")); |
610 |
| - } |
| 611 | + // TODO: does the walk take current branch into account ? |
| 612 | + |
| 613 | + if (sinceRevision != null) { |
| 614 | + walk.markUninteresting(walk.lookupCommit(repository.resolve(sinceRevision))); |
| 615 | + } |
| 616 | + walk.markStart(walk.parseCommit(repository.resolve(Constants.HEAD))); |
| 617 | + |
| 618 | + String relativePath = RuntimeEnvironment.getInstance().getPathRelativeToSourceRoot(file); |
| 619 | + if (!getDirectoryNameRelative().equals(relativePath)) { |
| 620 | + if (isHandleRenamedFiles()) { |
| 621 | + Config config = repository.getConfig(); |
| 622 | + config.setBoolean("diff", null, "renames", true); |
| 623 | + org.eclipse.jgit.diff.DiffConfig dc = config.get(org.eclipse.jgit.diff.DiffConfig.KEY); |
| 624 | + FollowFilter followFilter = FollowFilter.create(getRepoRelativePath(file), dc); |
| 625 | + walk.setTreeFilter(followFilter); |
| 626 | + } else { |
| 627 | + // TODO: untested, should be simpler (taken from LogCommand) |
| 628 | + List<PathFilter> pathFilters = new ArrayList<>(); |
| 629 | + pathFilters.add(PathFilter.create(getRepoRelativePath(file))); |
| 630 | + List<TreeFilter> filters = new ArrayList<>(); |
| 631 | + filters.add(AndTreeFilter.create(PathFilterGroup.create(pathFilters), TreeFilter.ANY_DIFF)); |
| 632 | + if (filters.size() == 1) { |
| 633 | + filters.add(TreeFilter.ANY_DIFF); |
| 634 | + } |
611 | 635 |
|
612 |
| - String relativePath = RuntimeEnvironment.getInstance().getPathRelativeToSourceRoot(file); |
613 |
| - if (!getDirectoryNameRelative().equals(relativePath)) { |
614 |
| - log.addPath(getRepoRelativePath(file)); |
| 636 | + walk.setTreeFilter(AndTreeFilter.create(filters)); |
615 | 637 | }
|
| 638 | + } |
616 | 639 |
|
617 |
| - // TODO: convert log to RevWalk (with FollowFilter for renamed file handling) |
618 |
| - Iterable<RevCommit> commits = log.call(); |
619 |
| - for (RevCommit commit : commits) { |
620 |
| - int numParents = commit.getParentCount(); |
621 |
| - if (numParents > 1 && !isMergeCommitsEnabled()) { |
622 |
| - continue; |
623 |
| - } |
| 640 | + for (RevCommit commit : walk) { |
| 641 | + int numParents = commit.getParentCount(); |
| 642 | + if (numParents > 1 && !isMergeCommitsEnabled()) { |
| 643 | + continue; |
| 644 | + } |
624 | 645 |
|
625 |
| - HistoryEntry historyEntry = new HistoryEntry(commit.getId().abbreviate(GIT_ABBREV_LEN).name(), |
626 |
| - new Date((long) commit.getCommitTime() * 1000), |
627 |
| - commit.getAuthorIdent().getName() + |
628 |
| - " <" + commit.getAuthorIdent().getEmailAddress() + ">", |
629 |
| - null, commit.getFullMessage(), true); |
630 |
| - |
631 |
| - SortedSet<String> files = new TreeSet<>(); |
632 |
| - if (numParents == 1) { |
633 |
| - getFiles(repository, commit.getParent(0), commit, files, renamedFiles); |
634 |
| - } else if (numParents == 0) { // first commit (TODO: could be dangling ?) |
635 |
| - try (TreeWalk treeWalk = new TreeWalk(repository)) { |
636 |
| - treeWalk.addTree(commit.getTree()); |
637 |
| - treeWalk.setRecursive(true); |
638 |
| - |
639 |
| - while (treeWalk.next()) { |
640 |
| - files.add(getDirectoryNameRelative() + "/" + treeWalk.getPathString()); |
641 |
| - } |
| 646 | + HistoryEntry historyEntry = new HistoryEntry(commit.getId().abbreviate(GIT_ABBREV_LEN).name(), |
| 647 | + new Date((long) commit.getCommitTime() * 1000), |
| 648 | + commit.getAuthorIdent().getName() + |
| 649 | + " <" + commit.getAuthorIdent().getEmailAddress() + ">", |
| 650 | + null, commit.getFullMessage(), true); |
| 651 | + |
| 652 | + SortedSet<String> files = new TreeSet<>(); |
| 653 | + if (numParents == 1) { |
| 654 | + getFiles(repository, commit.getParent(0), commit, files, renamedFiles); |
| 655 | + } else if (numParents == 0) { // first commit (TODO: could be dangling ?) |
| 656 | + try (TreeWalk treeWalk = new TreeWalk(repository)) { |
| 657 | + treeWalk.addTree(commit.getTree()); |
| 658 | + treeWalk.setRecursive(true); |
| 659 | + |
| 660 | + while (treeWalk.next()) { |
| 661 | + files.add(getDirectoryNameRelative() + "/" + treeWalk.getPathString()); |
642 | 662 | }
|
643 |
| - } else { |
644 |
| - getFiles(repository, commit.getParent(0), commit, files, renamedFiles); |
645 | 663 | }
|
646 |
| - |
647 |
| - historyEntry.setFiles(files); |
648 |
| - entries.add(historyEntry); |
| 664 | + } else { |
| 665 | + getFiles(repository, commit.getParent(0), commit, files, renamedFiles); |
649 | 666 | }
|
650 |
| - } catch (NoHeadException e) { |
651 |
| - // TODO |
652 |
| - e.printStackTrace(); |
653 |
| - } catch (GitAPIException e) { |
654 |
| - // TODO |
655 |
| - e.printStackTrace(); |
656 |
| - } catch (ForbiddenSymlinkException e) { |
657 |
| - e.printStackTrace(); |
| 667 | + |
| 668 | + historyEntry.setFiles(files); |
| 669 | + entries.add(historyEntry); |
658 | 670 | }
|
659 |
| - } catch (IOException e) { |
| 671 | + } catch (IOException | ForbiddenSymlinkException e) { |
660 | 672 | e.printStackTrace();
|
661 | 673 | }
|
662 | 674 |
|
|
0 commit comments