9

I'm looking at the JGit Documentation, currently at version 3.5.1.201410131835-r, and I cannot find the equivalent of git-merge-base.

I would like to determine if a branch is up-to-date, behind, ahead, or diverged, as shown in git: check if pull needed.

What is the most concise way in JGit to find as good common ancestors as possible for a merge?

Community
  • 1
  • 1
Ed I
  • 7,008
  • 3
  • 41
  • 50

4 Answers4

13

You can use RevFilter.MERGE_BASE for that:

RevWalk walk = new RevWalk(repository);
walk.setRevFilter(RevFilter.MERGE_BASE);
walk.markStart(commit1);
walk.markStart(commit2);
RevCommit mergeBase = walk.next();

Also note that there is BranchTrackingStatus if all you are interested in is ahead/behind count of a branch compared to its remote-tracking branch.

Per https://www.eclipse.org/forums/index.php/t/1091725/, you may need to re-parse the commits with walk.parseCommit().

mernst
  • 7,437
  • 30
  • 45
robinst
  • 30,027
  • 10
  • 102
  • 108
  • Is there an equivalent to adding "--fork-point" because I'm not getting the same results as "git merge-base --fork-point"? – Peter Kahn Feb 12 '16 at 00:58
  • @PeterKahn: Does this work?: https://gist.github.com/robinst/997da20d09a82d85a3e9 (I'm pretty sure it can be done more efficiently, so use with care) – robinst Feb 12 '16 at 04:30
  • @robinst thanks. I'll try that. I found this to work but it's a little kludgy and I'm not sure how we'll it will work if there are merges between sibling or cousin branches. http://stackoverflow.com/a/35353202/9950 – Peter Kahn Feb 12 '16 at 04:49
  • 1
    Can it handle an octopus merge-base? Do you just keep adding markStart() calls? – G. Sylvie Davies Jan 11 '17 at 04:47
  • 1
    FYI make sure you're using `walk.parseCommit()` to ensure `commit1.parents` and `commit2.parents` aren't missing. I spent a good hour trying to figure out what's wrong. – Saket Jun 20 '20 at 23:49
1

Here it is with JGit using BranchTrackingStatus:

public enum TrackingStatus {
    SAME, BEHIND, AHEAD, DIVERGED
}

public TrackingStatus getTrackingStatus() throws IOException, GitAPIException {
    Repository userRepo = new FileRepository(<path_to_.git_file>);
    Git git = new Git(userRepo);
    git.fetch().call();
    BranchTrackingStatus bts = BranchTrackingStatus.of(git.getRepository(),
                                                       git.getRepository().getBranch());
    int aheadCount = bts.getAheadCount();
    int behindCount = bts.getBehindCount();
    if (aheadCount == 0 && behindCount == 0) {
        return TrackingStatus.SAME;
    } else if (aheadCount > 0 && behindCount == 0) {
        return TrackingStatus.AHEAD;
    } else if (aheadCount == 0 && behindCount > 0) {
        return TrackingStatus.BEHIND;
    } else {
        return TrackingStatus.DIVERGED;
    }
}
0

jgit has this:

RevCommit org.eclipse.jgit.merge.Merger.getBaseCommit(RevCommit a, RevCommit b) throws IncorrectObjectTypeException, IOException

take a try

Stefan Ferstl
  • 5,135
  • 3
  • 33
  • 41
Feng
  • 4,933
  • 2
  • 14
  • 9
0

This method is protected, so cannot be used directly:

protected RevCommit getBaseCommit(RevCommit a, RevCommit b) throws IncorrectObjectTypeException, IOException

woytech
  • 701
  • 1
  • 6
  • 15
fei-li
  • 1