I found a solution using the CherryPickCommand
and RebaseCommand
. Using the example above, I switch to branch at Z
.
A-----B------C------D------E------F------G------H
\
\
Z
Then, I cherry pick the RevCommits C
, D
, and E
using .include(RevCommit)
for each commit. Then I use .call()
to add the commits onto my new branch, resulting in the diagram below:
A-----B------C------D------E------F------G------H
\
\
Z------C------D------E
Next, I squash C
, D
, and E
into a single commit with RebaseCommand
. First, I set the upstream commi with .setUpstream("HEAD~3")
to move back 3 commits. Then I run the interactive handler using a callback function shown below:
runInteractively(new InteractiveHandler() {
@Override
public String modifyCommitMessage(String commit)
{
return rebaseMessage;
}
@Override
public void prepareSteps(List<RebaseTodoLine> steps)
{
try
{
steps.get(0).setAction(RebaseTodoLine.Action.PICK);
for (int j = 1; j < steps.size(); j++)
{
RebaseTodoLine step = steps.get(j);
step.setAction(RebaseTodoLine.Action.SQUASH);
}
}
catch (IllegalTodoFileModification e)
{
System.out.println("Cannot prepare step: " + e);
e.printStackTrace();
}
}
});
This effectively gives instructions to the interactive command line prompt that you see in normal git rebase operations. Now, my repo looks as follows:
A-----B------C------D------E------F------G------H
\
\
Z------Y
Where:
Y is the squashed commit of C, D, and E
And that's it!
To finish the example, I would do the same for commits F
and G
.
If there is a direct method to add and squash the commits in one move, I would be very interested. For now, this works and avoids duplication of the entire branch.