4

I want to find the first commit for a specific branch, using Eclipse's JGit library. For example if I have

master -- a -- c -- d -- e
          \
  feature  b -- f -- g -- h
            \
    another  j -- k -- l

// findBranchRoot() is the magic method we want to create
repository.resolve("feature").findBranchRoot().getId(); // this would return b
repository.resolve("another").findBranchRoot().getId(); // this would return j

Does anyone know how to do that?

Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
TheCrafter
  • 1,909
  • 2
  • 23
  • 44

2 Answers2

3

The problem you're going to have is that—and bear with me, here—commits aren't "on" branches. To see this, consider the graph you drew. It's ambiguous. Unavoidably so. You drew

A---C---D---E          master
 \
  B---F---G---H        feature
   \
    J---k---L          another

and there is simply no way to determine whether B was made "on" feature or another (or, for that matter, which of the three A was made "on").

A---C---D---E          master
 \
  B---J---K---L        another
   \
    F---G---H          feature

shows exactly the same history. It's all in how you choose to interpret it.

If you want to tie a commit to some external administrative record, put a marker in the commit message, that'll do it, but in Git itself (and to the actual work) it's the history structure that matters, not how bits of it are referred to in this repo or that.

If it comes time to publish feature or another, you're going to need to push commit B either way, unless it's already been pushed as part of some other work. Ancestry matters. Branch names don't.

jthill
  • 55,082
  • 5
  • 77
  • 137
0

If first commit means the most recent/youngest commit of a branch, you can use the ObjectId returned by Repository::resolve to obtain the RevCommit (JGit's representation of a commit object) with a RevWalk:

ObjectId commitId = repository.resolve("refs/heads/feature");
try(RevWalk revWalk = new RevWalk(repository)) {
  RevCommit commit = revWalk.parseCommit(commitId);
}

I recommend to pass the fully qualified ref to resolve (as in the example). Otherwise chances are you get an AmbiguousObjectException or the method returns a note or tag of the same short name.

Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79