diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java index 34432c588..1310625a9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java @@ -53,7 +53,9 @@ import java.util.List; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.filter.RevFilter; import org.junit.Test; public class LogCommandTest extends RepositoryTestCase { @@ -210,4 +212,81 @@ public class LogCommandTest extends RepositoryTestCase { assertEquals("commit#2", commit.getShortMessage()); assertFalse(log.hasNext()); } + + @Test + public void logOnlyMergeCommits() throws Exception { + setCommitsAndMerge(); + Git git = Git.wrap(db); + + Iterable commits = git.log().all().call(); + Iterator i = commits.iterator(); + RevCommit commit = i.next(); + assertEquals("merge s0 with m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("s0", commit.getFullMessage()); + commit = i.next(); + assertEquals("m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("m0", commit.getFullMessage()); + assertFalse(i.hasNext()); + + commits = git.log().setRevFilter(RevFilter.ONLY_MERGES).call(); + i = commits.iterator(); + commit = i.next(); + assertEquals("merge s0 with m1", commit.getFullMessage()); + assertFalse(i.hasNext()); + } + + @Test + public void logNoMergeCommits() throws Exception { + setCommitsAndMerge(); + Git git = Git.wrap(db); + + Iterable commits = git.log().all().call(); + Iterator i = commits.iterator(); + RevCommit commit = i.next(); + assertEquals("merge s0 with m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("s0", commit.getFullMessage()); + commit = i.next(); + assertEquals("m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("m0", commit.getFullMessage()); + assertFalse(i.hasNext()); + + commits = git.log().setRevFilter(RevFilter.NO_MERGES).call(); + i = commits.iterator(); + commit = i.next(); + assertEquals("m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("s0", commit.getFullMessage()); + commit = i.next(); + assertEquals("m0", commit.getFullMessage()); + assertFalse(i.hasNext()); + } + + private void setCommitsAndMerge() throws Exception { + Git git = Git.wrap(db); + writeTrashFile("file1", "1\n2\n3\n4\n"); + git.add().addFilepattern("file1").call(); + RevCommit masterCommit0 = git.commit().setMessage("m0").call(); + + createBranch(masterCommit0, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + + writeTrashFile("file2", "1\n2\n3\n4\n5\n6\n7\n8\n"); + git.add().addFilepattern("file2").call(); + RevCommit c = git.commit().setMessage("s0").call(); + + checkoutBranch("refs/heads/master"); + + writeTrashFile("file3", "1\n2\n"); + git.add().addFilepattern("file3").call(); + git.commit().setMessage("m1").call(); + + git.merge().include(c.getId()) + .setStrategy(MergeStrategy.RESOLVE) + .setMessage("merge s0 with m1").call(); + } + } \ No newline at end of file diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java index 9690f799c..bb1a73814 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java @@ -65,6 +65,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.filter.AndRevFilter; import org.eclipse.jgit.revwalk.filter.MaxCountRevFilter; +import org.eclipse.jgit.revwalk.filter.RevFilter; import org.eclipse.jgit.revwalk.filter.SkipRevFilter; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.PathFilter; @@ -104,6 +105,8 @@ public class LogCommand extends GitCommand> { private boolean startSpecified = false; + private RevFilter revFilter; + private final List pathFilters = new ArrayList(); private int maxCount = -1; @@ -156,6 +159,11 @@ public class LogCommand extends GitCommand> { e); } } + + if (this.revFilter != null) { + walk.setRevFilter(this.revFilter); + } + setCallable(false); return walk; } @@ -342,4 +350,21 @@ public class LogCommand extends GitCommand> { , start), e); } } + + + /** + * Sets a filter for the LogCommand. + * + * + * @param aFilter + * the filter that this instance of LogCommand + * should use + * @return {@code this} + * @since 4.4 + */ + public LogCommand setRevFilter(RevFilter aFilter) { + checkCallable(); + this.revFilter = aFilter; + return this; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java index 2a5cb2b2a..14a98a10b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java @@ -82,6 +82,7 @@ import org.eclipse.jgit.revwalk.RevWalk; * Merge filters: *
    *
  • Skip all merges: {@link #NO_MERGES}.
  • + *
  • Skip all non-merges: {@link #ONLY_MERGES}
  • *
* *

@@ -143,6 +144,37 @@ public abstract class RevFilter { } } + /** + * Filter including only merge commits, excluding all commits with less than + * two parents (thread safe). + * + * @since 4.4 + */ + public static final RevFilter ONLY_MERGES = new OnlyMergesFilter(); + + private static final class OnlyMergesFilter extends RevFilter { + + @Override + public boolean include(RevWalk walker, RevCommit c) { + return c.getParentCount() >= 2; + } + + @Override + public RevFilter clone() { + return this; + } + + @Override + public boolean requiresCommitBody() { + return false; + } + + @Override + public String toString() { + return "ONLY_MERGES"; //$NON-NLS-1$ + } + } + /** Excludes commits with more than one parent (thread safe). */ public static final RevFilter NO_MERGES = new NoMergesFilter();