Support cherry-picking a root commit
Handle the case of the commit to be picked not having any parents. Since JGit implements cherry-pick as a 3-way-merge between the commit to be picked and the target commit, using the parent of the picked commit as merge base, this is super simple: just don't set a base tree. The merger will not find any merge base and will supply an empty tree iterator for the base. Bug: 581832 Change-Id: I88985f1b1723db5b35ce58bf228bc48d23d6fca3 Signed-off-by: Thomas Wolf <twolf@apache.org>
This commit is contained in:
parent
3ed4cdda6b
commit
8bc13fb79d
|
@ -100,41 +100,73 @@ private void doTestCherryPick(boolean noCommit) throws IOException,
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequentialCherryPick() throws IOException, JGitInternalException,
|
||||
GitAPIException {
|
||||
try (Git git = new Git(db)) {
|
||||
writeTrashFile("a", "first line\nsec. line\nthird line\n");
|
||||
git.add().addFilepattern("a").call();
|
||||
RevCommit firstCommit = git.commit().setMessage("create a").call();
|
||||
@Test
|
||||
public void testSequentialCherryPick()
|
||||
throws IOException, JGitInternalException, GitAPIException {
|
||||
try (Git git = new Git(db)) {
|
||||
writeTrashFile("a", "first line\nsec. line\nthird line\n");
|
||||
git.add().addFilepattern("a").call();
|
||||
RevCommit firstCommit = git.commit().setMessage("create a").call();
|
||||
|
||||
writeTrashFile("a", "first line\nsec. line\nthird line\nfourth line\n");
|
||||
git.add().addFilepattern("a").call();
|
||||
RevCommit enlargingA = git.commit().setMessage("enlarged a").call();
|
||||
writeTrashFile("a",
|
||||
"first line\nsec. line\nthird line\nfourth line\n");
|
||||
git.add().addFilepattern("a").call();
|
||||
RevCommit enlargingA = git.commit().setMessage("enlarged a").call();
|
||||
|
||||
writeTrashFile("a",
|
||||
"first line\nsecond line\nthird line\nfourth line\n");
|
||||
git.add().addFilepattern("a").call();
|
||||
RevCommit fixingA = git.commit().setMessage("fixed a").call();
|
||||
writeTrashFile("a",
|
||||
"first line\nsecond line\nthird line\nfourth line\n");
|
||||
git.add().addFilepattern("a").call();
|
||||
RevCommit fixingA = git.commit().setMessage("fixed a").call();
|
||||
|
||||
git.branchCreate().setName("side").setStartPoint(firstCommit).call();
|
||||
checkoutBranch("refs/heads/side");
|
||||
git.branchCreate().setName("side").setStartPoint(firstCommit)
|
||||
.call();
|
||||
checkoutBranch("refs/heads/side");
|
||||
|
||||
writeTrashFile("b", "nothing to do with a");
|
||||
git.add().addFilepattern("b").call();
|
||||
git.commit().setMessage("create b").call();
|
||||
writeTrashFile("b", "nothing to do with a");
|
||||
git.add().addFilepattern("b").call();
|
||||
git.commit().setMessage("create b").call();
|
||||
|
||||
CherryPickResult result = git.cherryPick().include(enlargingA).include(fixingA).call();
|
||||
assertEquals(CherryPickResult.CherryPickStatus.OK, result.getStatus());
|
||||
CherryPickResult result = git.cherryPick().include(enlargingA)
|
||||
.include(fixingA).call();
|
||||
assertEquals(CherryPickResult.CherryPickStatus.OK,
|
||||
result.getStatus());
|
||||
|
||||
Iterator<RevCommit> history = git.log().call().iterator();
|
||||
assertEquals("fixed a", history.next().getFullMessage());
|
||||
assertEquals("enlarged a", history.next().getFullMessage());
|
||||
assertEquals("create b", history.next().getFullMessage());
|
||||
assertEquals("create a", history.next().getFullMessage());
|
||||
assertFalse(history.hasNext());
|
||||
}
|
||||
}
|
||||
Iterator<RevCommit> history = git.log().call().iterator();
|
||||
assertEquals("fixed a", history.next().getFullMessage());
|
||||
assertEquals("enlarged a", history.next().getFullMessage());
|
||||
assertEquals("create b", history.next().getFullMessage());
|
||||
assertEquals("create a", history.next().getFullMessage());
|
||||
assertFalse(history.hasNext());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRootCherryPick()
|
||||
throws IOException, JGitInternalException, GitAPIException {
|
||||
try (Git git = new Git(db)) {
|
||||
writeTrashFile("a", "a");
|
||||
writeTrashFile("b", "b");
|
||||
git.add().addFilepattern("a").addFilepattern("b").call();
|
||||
RevCommit firstCommit = git.commit().setMessage("Create a and b")
|
||||
.call();
|
||||
|
||||
git.checkout().setOrphan(true).setName("orphan").call();
|
||||
git.rm().addFilepattern("a").addFilepattern("b").call();
|
||||
writeTrashFile("a", "a");
|
||||
git.add().addFilepattern("a").call();
|
||||
git.commit().setMessage("Orphan a").call();
|
||||
|
||||
CherryPickResult result = git.cherryPick().include(firstCommit)
|
||||
.call();
|
||||
assertEquals(CherryPickResult.CherryPickStatus.OK,
|
||||
result.getStatus());
|
||||
|
||||
Iterator<RevCommit> history = git.log().call().iterator();
|
||||
assertEquals("Create a and b", history.next().getFullMessage());
|
||||
assertEquals("Orphan a", history.next().getFullMessage());
|
||||
assertFalse(history.hasNext());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCherryPickDirtyIndex() throws Exception {
|
||||
|
|
|
@ -142,7 +142,9 @@ public CherryPickResult call() throws GitAPIException, NoMessageException,
|
|||
new String[] { "BASE", ourName, cherryPickName }); //$NON-NLS-1$
|
||||
resolveMerger
|
||||
.setWorkingTreeIterator(new FileTreeIterator(repo));
|
||||
resolveMerger.setBase(srcParent.getTree());
|
||||
if (srcParent != null) {
|
||||
resolveMerger.setBase(srcParent.getTree());
|
||||
}
|
||||
noProblems = merger.merge(newHead, srcCommit);
|
||||
failingPaths = resolveMerger.getFailingPaths();
|
||||
unmergedPaths = resolveMerger.getUnmergedPaths();
|
||||
|
@ -217,12 +219,16 @@ private RevCommit getParentCommit(RevCommit srcCommit, RevWalk revWalk)
|
|||
IOException {
|
||||
final RevCommit srcParent;
|
||||
if (mainlineParentNumber == null) {
|
||||
if (srcCommit.getParentCount() != 1)
|
||||
int nOfParents = srcCommit.getParentCount();
|
||||
if (nOfParents == 0) {
|
||||
return null;
|
||||
} else if (nOfParents != 1) {
|
||||
throw new MultipleParentsNotAllowedException(
|
||||
MessageFormat.format(
|
||||
JGitText.get().canOnlyCherryPickCommitsWithOneParent,
|
||||
srcCommit.name(),
|
||||
Integer.valueOf(srcCommit.getParentCount())));
|
||||
}
|
||||
srcParent = srcCommit.getParent(0);
|
||||
} else {
|
||||
if (mainlineParentNumber.intValue() > srcCommit.getParentCount()) {
|
||||
|
|
Loading…
Reference in New Issue