diff options
Diffstat (limited to 'org.eclipse.jgit.pgm')
-rw-r--r-- | org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java | 63 | ||||
-rw-r--r-- | org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java | 10 |
2 files changed, 62 insertions, 11 deletions
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java index 83ef6eb875..48a05915e4 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java @@ -51,6 +51,7 @@ import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.Collection; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -65,11 +66,12 @@ import org.eclipse.jgit.diff.RawTextIgnoreLeadingWhitespace; import org.eclipse.jgit.diff.RawTextIgnoreTrailingWhitespace; import org.eclipse.jgit.diff.RawTextIgnoreWhitespaceChange; import org.eclipse.jgit.diff.RenameDetector; +import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.TextProgressMonitor; +import org.eclipse.jgit.revwalk.FollowFilter; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; @@ -195,20 +197,26 @@ class Log extends RevWalkTextBuiltin { private void showDiff(RevCommit c) throws IOException { final TreeWalk tw = new TreeWalk(db); - tw.reset(); tw.setRecursive(true); + tw.reset(); tw.addTree(c.getParent(0).getTree()); tw.addTree(c.getTree()); - tw.setFilter(AndTreeFilter.create(TreeFilter.ANY_DIFF, pathFilter)); + tw.setFilter(AndTreeFilter.create(pathFilter, TreeFilter.ANY_DIFF)); List<DiffEntry> files = DiffEntry.scan(tw); - if (detectRenames) { - RenameDetector rd = new RenameDetector(db); - if (renameLimit != null) - rd.setRenameLimit(renameLimit.intValue()); - rd.addAll(files); - files = rd.compute(new TextProgressMonitor()); - } + if (pathFilter instanceof FollowFilter && isAdd(files)) { + // The file we are following was added here, find where it + // came from so we can properly show the rename or copy, + // then continue digging backwards. + // + tw.reset(); + tw.addTree(c.getParent(0).getTree()); + tw.addTree(c.getTree()); + tw.setFilter(TreeFilter.ANY_DIFF); + files = updateFollowFilter(detectRenames(DiffEntry.scan(tw))); + + } else if (detectRenames) + files = detectRenames(files); if (showNameAndStatusOnly) { Diff.nameStatus(out, files); @@ -220,4 +228,39 @@ class Log extends RevWalkTextBuiltin { } out.println(); } + + private List<DiffEntry> detectRenames(List<DiffEntry> files) + throws IOException { + RenameDetector rd = new RenameDetector(db); + if (renameLimit != null) + rd.setRenameLimit(renameLimit.intValue()); + rd.addAll(files); + return rd.compute(); + } + + private boolean isAdd(List<DiffEntry> files) { + String oldPath = ((FollowFilter) pathFilter).getPath(); + for (DiffEntry ent : files) { + if (ent.getChangeType() == ChangeType.ADD + && ent.getNewName().equals(oldPath)) + return true; + } + return false; + } + + private List<DiffEntry> updateFollowFilter(List<DiffEntry> files) { + String oldPath = ((FollowFilter) pathFilter).getPath(); + for (DiffEntry ent : files) { + if (isRename(ent) && ent.getNewName().equals(oldPath)) { + pathFilter = FollowFilter.create(ent.getOldName()); + return Collections.singletonList(ent); + } + } + return Collections.emptyList(); + } + + private static boolean isRename(DiffEntry ent) { + return ent.getChangeType() == ChangeType.RENAME + || ent.getChangeType() == ChangeType.COPY; + } } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java index beb961d99c..bf3924b70b 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java @@ -53,6 +53,7 @@ import org.kohsuke.args4j.Option; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler; +import org.eclipse.jgit.revwalk.FollowFilter; import org.eclipse.jgit.revwalk.ObjectWalk; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevFlag; @@ -110,6 +111,11 @@ abstract class RevWalkTextBuiltin extends TextBuiltin { enableRevSort(RevSort.BOUNDARY, on); } + @Option(name = "--follow", metaVar = "metaVar_path") + void follow(final String path) { + pathFilter = FollowFilter.create(path); + } + @Argument(index = 0, metaVar = "metaVar_commitish") private final List<RevCommit> commits = new ArrayList<RevCommit>(); @@ -139,7 +145,9 @@ abstract class RevWalkTextBuiltin extends TextBuiltin { for (final RevSort s : sorting) walk.sort(s, true); - if (pathFilter != TreeFilter.ALL) + if (pathFilter instanceof FollowFilter) + walk.setTreeFilter(pathFilter); + else if (pathFilter != TreeFilter.ALL) walk.setTreeFilter(AndTreeFilter.create(pathFilter, TreeFilter.ANY_DIFF)); |