7

I need to obtain the name of the branch that is associated with a specific commit using JGit. I used JGit to obtain the complete list of commit SHA's for a repository and now I need to know the name of the branch it belongs to.

Appreciate if someone can let me know how I can achieve this.

fap
  • 663
  • 1
  • 5
  • 14
Tony P
  • 211
  • 5
  • 12
  • 1
    Just to mention only the tips (most recent commit) of branches are actually "associated" to the branch. For other commits, you can only guess by looking at the commits graph and history. – everton Nov 03 '17 at 01:44

2 Answers2

4

In Git, a commit does not belong to a branch. A commit is immutable, whereas branches can change their name as well as the commit they point to.

A commit is reachable from a branch (or tag, or other ref) if there is a branch that either directly points to the commit or to a successor of the commit.

In JGit the NameRevCommand can be used to find a branch, if any, that directly points to a commit. For example:

Map<ObjectId, String> map = git
  .nameRev()
  .addPrefix("refs/heads")
  .add(ObjectId.fromString("<SHA-1>"))
  .call();

The above snippet looks in the refs/heads namespace for a ref that points to the given commit. The returned map contains at most one entry where the key is the given commit id and the value denotes the branch which points to it.

Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
  • What does it mean when given map is empty (just ran into such issue where "master" is expected – Antoniossss Oct 26 '18 at 13:28
  • Seems that no ref was found that points to the commit id given with `add`. Does native Git return something? – Rüdiger Herrmann Oct 26 '18 at 14:23
  • Didn't check (as it is temporary repository, fetched only single branch). I suspect this has something to do withe fact that I am actually using fetch_head - eg. I had to use "additionalRefs" to make `log` work as `refs` are empty in repository database. If i fetch with `.all()`, branch name is found (and no need to use `additionalRefs`. – Antoniossss Oct 26 '18 at 19:52
  • You may try to use `addRef` with the `Ref` for `FETCH_HEAD` to have the command consider it. – Rüdiger Herrmann Oct 27 '18 at 16:53
2

As the document says,

Class ListBranchCommand

ListBranchCommand setContains(String containsCommitish)

setContains

public ListBranchCommand setContains(String containsCommitish)

If this is set, only the branches that contain the specified commit-ish as an ancestor are returned.

Parameters:
containsCommitish - a commit ID or ref name

Returns:
this instance

Since:
3.4

This api is corresponding to git branch --contains <commit-ish>

You may also need this api if you'd like to list the remote branches (-r) or both the remote and local branches (-a),

setListMode

public ListBranchCommand setListMode(ListBranchCommand.ListMode listMode)

Parameters:
listMode - optional: corresponds to the -r/-a options; by default, only local branches will be listed

Returns:
this instance

Sample:

#list all the branches that "HEAD" belongs to.
try {
    Git git = Git.open(new File("D:/foo/.git"));
    List<Ref> refs = git.branchList().setContains("HEAD").setListMode(ListBranchCommand.ListMode.ALL).call();
    System.out.println(refs);
} catch (Exception e) {
    System.out.println(e);
}
ElpieKay
  • 27,194
  • 6
  • 32
  • 53