Implement log between two changesets for git

This commit is contained in:
René Pfeuffer
2018-11-05 16:42:20 +01:00
parent ef23178fad
commit 2508a1b9b7
4 changed files with 74 additions and 11 deletions

View File

@@ -398,6 +398,11 @@ public final class LogCommandBuilder
return this; return this;
} }
public LogCommandBuilder setAncestorChangeset(String ancestorChangeset) {
request.setAncestorChangeset(ancestorChangeset);
return this;
}
//~--- inner classes -------------------------------------------------------- //~--- inner classes --------------------------------------------------------
/** /**

View File

@@ -84,7 +84,8 @@ public final class LogCommandRequest implements Serializable, Resetable
&& Objects.equal(pagingStart, other.pagingStart) && Objects.equal(pagingStart, other.pagingStart)
&& Objects.equal(pagingLimit, other.pagingLimit) && Objects.equal(pagingLimit, other.pagingLimit)
&& Objects.equal(path, other.path) && Objects.equal(path, other.path)
&& Objects.equal(branch, other.branch); && Objects.equal(branch, other.branch)
&& Objects.equal(ancestorChangeset, other.ancestorChangeset);
//J+ //J+
} }
@@ -98,7 +99,7 @@ public final class LogCommandRequest implements Serializable, Resetable
public int hashCode() public int hashCode()
{ {
return Objects.hashCode(startChangeset, endChangeset, pagingStart, return Objects.hashCode(startChangeset, endChangeset, pagingStart,
pagingLimit, path, branch); pagingLimit, path, branch, ancestorChangeset);
} }
/** /**
@@ -114,6 +115,7 @@ public final class LogCommandRequest implements Serializable, Resetable
pagingLimit = 20; pagingLimit = 20;
path = null; path = null;
branch = null; branch = null;
ancestorChangeset = null;
} }
/** /**
@@ -133,6 +135,7 @@ public final class LogCommandRequest implements Serializable, Resetable
.add("pagingLimit", pagingLimit) .add("pagingLimit", pagingLimit)
.add("path", path) .add("path", path)
.add("branch", branch) .add("branch", branch)
.add("ancestorChangeset", ancestorChangeset)
.toString(); .toString();
//J+ //J+
} }
@@ -205,6 +208,10 @@ public final class LogCommandRequest implements Serializable, Resetable
this.startChangeset = startChangeset; this.startChangeset = startChangeset;
} }
public void setAncestorChangeset(String ancestorChangeset) {
this.ancestorChangeset = ancestorChangeset;
}
//~--- get methods ---------------------------------------------------------- //~--- get methods ----------------------------------------------------------
/** /**
@@ -284,6 +291,10 @@ public final class LogCommandRequest implements Serializable, Resetable
return pagingLimit < 0; return pagingLimit < 0;
} }
public String getAncestorChangeset() {
return ancestorChangeset;
}
//~--- fields --------------------------------------------------------------- //~--- fields ---------------------------------------------------------------
/** Field description */ /** Field description */
@@ -303,4 +314,6 @@ public final class LogCommandRequest implements Serializable, Resetable
/** Field description */ /** Field description */
private String startChangeset; private String startChangeset;
private String ancestorChangeset;
} }

View File

@@ -43,6 +43,7 @@ import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter;
@@ -198,6 +199,14 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
endId = repository.resolve(request.getEndChangeset()); endId = repository.resolve(request.getEndChangeset());
} }
Ref branch = getBranchOrDefault(repository,request.getBranch());
ObjectId ancestorId = null;
if (!Strings.isNullOrEmpty(request.getAncestorChangeset())) {
ancestorId = computeCommonAncestor(request, repository, startId, branch);
}
revWalk = new RevWalk(repository); revWalk = new RevWalk(repository);
converter = new GitChangesetConverter(repository, revWalk); converter = new GitChangesetConverter(repository, revWalk);
@@ -208,8 +217,6 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
PathFilter.create(request.getPath()), TreeFilter.ANY_DIFF)); PathFilter.create(request.getPath()), TreeFilter.ANY_DIFF));
} }
Ref branch = getBranchOrDefault(repository,request.getBranch());
if (branch != null) { if (branch != null) {
if (startId != null) { if (startId != null) {
revWalk.markStart(revWalk.lookupCommit(startId)); revWalk.markStart(revWalk.lookupCommit(startId));
@@ -217,11 +224,16 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
revWalk.markStart(revWalk.lookupCommit(branch.getObjectId())); revWalk.markStart(revWalk.lookupCommit(branch.getObjectId()));
} }
Iterator<RevCommit> iterator = revWalk.iterator(); Iterator<RevCommit> iterator = revWalk.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
RevCommit commit = iterator.next(); RevCommit commit = iterator.next();
if (commit.getId().equals(ancestorId)) {
break;
}
if ((counter >= start) if ((counter >= start)
&& ((limit < 0) || (counter < start + limit))) { && ((limit < 0) || (counter < start + limit))) {
changesetList.add(converter.createChangeset(commit)); changesetList.add(converter.createChangeset(commit));
@@ -229,7 +241,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
counter++; counter++;
if ((endId != null) && commit.getId().equals(endId)) { if (commit.getId().equals(endId)) {
break; break;
} }
} }
@@ -263,4 +275,17 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
return changesets; return changesets;
} }
private ObjectId computeCommonAncestor(LogCommandRequest request, Repository repository, ObjectId startId, Ref branch) throws IOException {
try (RevWalk mergeBaseWalk = new RevWalk(repository)) {
mergeBaseWalk.setRevFilter(RevFilter.MERGE_BASE);
if (startId != null) {
mergeBaseWalk.markStart(mergeBaseWalk.lookupCommit(startId));
} else {
mergeBaseWalk.markStart(mergeBaseWalk.lookupCommit(branch.getObjectId()));
}
mergeBaseWalk.markStart(mergeBaseWalk.parseCommit(repository.resolve(request.getAncestorChangeset())));
return mergeBaseWalk.next().getId();
}
}
} }

View File

@@ -64,7 +64,7 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
* Tests log command with the usage of a default branch. * Tests log command with the usage of a default branch.
*/ */
@Test @Test
public void testGetDefaultBranch() throws Exception { public void testGetDefaultBranch() {
// without default branch, the repository head should be used // without default branch, the repository head should be used
ChangesetPagingResult result = createCommand().getChangesets(new LogCommandRequest()); ChangesetPagingResult result = createCommand().getChangesets(new LogCommandRequest());
@@ -92,7 +92,7 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
} }
@Test @Test
public void testGetAll() throws Exception public void testGetAll()
{ {
ChangesetPagingResult result = ChangesetPagingResult result =
createCommand().getChangesets(new LogCommandRequest()); createCommand().getChangesets(new LogCommandRequest());
@@ -103,7 +103,7 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
} }
@Test @Test
public void testGetAllByPath() throws Exception public void testGetAllByPath()
{ {
LogCommandRequest request = new LogCommandRequest(); LogCommandRequest request = new LogCommandRequest();
@@ -119,7 +119,7 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
} }
@Test @Test
public void testGetAllWithLimit() throws Exception public void testGetAllWithLimit()
{ {
LogCommandRequest request = new LogCommandRequest(); LogCommandRequest request = new LogCommandRequest();
@@ -143,7 +143,7 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
} }
@Test @Test
public void testGetAllWithPaging() throws Exception public void testGetAllWithPaging()
{ {
LogCommandRequest request = new LogCommandRequest(); LogCommandRequest request = new LogCommandRequest();
@@ -194,7 +194,7 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
} }
@Test @Test
public void testGetRange() throws Exception public void testGetRange()
{ {
LogCommandRequest request = new LogCommandRequest(); LogCommandRequest request = new LogCommandRequest();
@@ -216,6 +216,26 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", c2.getId()); assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", c2.getId());
} }
@Test
public void testGetAncestor()
{
LogCommandRequest request = new LogCommandRequest();
request.setBranch("test-branch");
request.setAncestorChangeset("master");
ChangesetPagingResult result = createCommand().getChangesets(request);
assertNotNull(result);
assertEquals(1, result.getTotal());
assertEquals(1, result.getChangesets().size());
Changeset c = result.getChangesets().get(0);
assertNotNull(c);
assertEquals("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4", c.getId());
}
@Test @Test
public void shouldFindDefaultBranchFromHEAD() throws Exception { public void shouldFindDefaultBranchFromHEAD() throws Exception {
setRepositoryHeadReference("ref: refs/heads/test-branch"); setRepositoryHeadReference("ref: refs/heads/test-branch");