Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find out the branch a commit belongs to in LibGit2Sharp?

I am looping through commits in LibGit2Sharp:

Repository repo = new Repository("Z:/www/gg");

foreach (LibGit2Sharp.Commit commit in repo.Commits)
{
    ...
}

I can retrieve properties like Author and Message, but I do not see anything about what branch it belongs to? Ideally I would like to have a pointer to the branch object, but even a name would be fine in this scenario.

This is what the debugger shows up:

enter image description here

This is what I am looking for:

enter image description here

TortoiseGit's behavior of showing the most relevant branch name:

enter image description here

Example repository: https://docs.google.com/open?id=0B-3-X85VysdNcmZIaGVTSDZSenVGbTJxYlI2SUlsZw

like image 623
Tower Avatar asked Feb 26 '12 09:02

Tower


2 Answers

There is currently no built-in way to mimic git branch --contains <commit>.

However, you might work around this limit by explicitly walking each branch and comparing each popped commit against the searched one.

Following test demonstrates this

[Test]
public void CanSearchBranchesContainingASpecificCommit()
{
    using (var repo = new Repository(StandardTestRepoPath))
    {
        const string commitSha = "5b5b025afb0b4c913b4c338a42934a3863bf3644";
        IEnumerable<Branch> branches = ListBranchesContaininingCommit(repo, commitSha);

        branches.Count().ShouldEqual(6);
    }
}

private IEnumerable<Branch> ListBranchesContaininingCommit(Repository repo, string commitSha)
{
    foreach (var branch in repo.Branches)
    {
        var commits = repo.Commits.QueryBy(new CommitFilter { Since = branch }).Where(c => c.Sha == commitSha);

        if (!commits.Any())
        {
            continue;
        }

        yield return branch;
    }
}

Note: This code has been successfully tested against the current tip of the development branch of LibGit2Sharp.

UPDATE:

Following the discussion in the comments, here's a little update which I hope will fulfill your request.

The code below will return all the branches containing the searched commit. If the commit happens to be the tip of at least one branch, those branches will be returned instead.

[Test]
public void CanSearchBranchesContainingASpecificCommit()
{
    using (var repo = new Repository(StandardTestRepoPath))
    {
        const string commitSha = "5b5b025afb0b4c913b4c338a42934a3863bf3644";
        IEnumerable<Branch> branches = ListBranchesContaininingCommit(repo, commitSha);

        branches.Count().ShouldEqual(6);

        const string otherCommitSha = "4a202b346bb0fb0db7eff3cffeb3c70babbd2045";
        branches = ListBranchesContaininingCommit(repo, otherCommitSha);

        branches.Count().ShouldEqual(1); // origin/packed-test
    }
}

private IEnumerable<Branch> ListBranchesContaininingCommit(Repository repo, string commitSha)
{
    bool directBranchHasBeenFound = false;
    foreach (var branch in repo.Branches)
    {
        if (branch.Tip.Sha != commitSha)
        {
            continue;
        }

        directBranchHasBeenFound = true;
        yield return branch;
    }

    if (directBranchHasBeenFound)
    {
        yield break;
    }

    foreach (var branch in repo.Branches)
    {
        var commits = repo.Commits.QueryBy(new CommitFilter { Since = branch }).Where(c => c.Sha == commitSha);

        if (!commits.Any())
        {
            continue;
        }

        yield return branch;
    }
}
like image 165
nulltoken Avatar answered Oct 02 '22 02:10

nulltoken


Git does not store branch information with commits. You'd have to walk the history DAG and see if the commit is reachable from the refs.

On the commandline with normal git you would run git branch --contains $SHA1

like image 26
knittl Avatar answered Oct 02 '22 02:10

knittl