Узнать ветку коммита в LibGit2Sharp? - PullRequest
4 голосов
/ 26 февраля 2012

Я перебираю коммиты в LibGit2Sharp:

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

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

Я могу получить свойства типа Author и Message, но я не вижу ничего о том, к какой ветви он принадлежит?В идеале я хотел бы иметь указатель на объект ветви, но в этом случае подойдет даже имя.

Вот что показывает отладчик:

enter image description here

Это то, что я ищу:

enter image description here

Поведение TortoiseGit при отображении наиболее релевантного имени ветви:

enter image description here

Пример репозитория: https://docs.google.com/open?id=0B-3-X85VysdNcmZIaGVTSDZSenVGbTJxYlI2SUlsZw

Ответы [ 3 ]

5 голосов
/ 26 февраля 2012

В настоящее время нет встроенного способа имитации git branch --contains <commit>.

Однако вы можете обойти это ограничение, явно обойдя каждую ветвь и сравнив каждый выданный коммит с искомым.

Следующий тест демонстрирует это

[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;
    }
}

Примечание: Этот код был успешно протестирован с текущей версией ветки разработки LibGit2Sharp.

UPDATE:

После обсуждения в комментариях, вот небольшое обновление, которое, я надеюсь, удовлетворит вашу просьбу.

Приведенный ниже код вернет все ветви, содержащие искомый коммит. Если коммит окажется кончиком хотя бы одной ветви, эти ветви будут возвращены.

[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;
    }
}
1 голос
/ 26 февраля 2012

Как сказал Книттл, git не хранит эту информацию.Фиксация - это фиксированное состояние репозитория с некоторыми метаданными.Так как коммит является неизменным и какие ветви он может изменить, информация о ветвях не может быть сохранена непосредственно в коммите.

Итак, чтобы выяснить, принадлежит ли определенный коммит к какой-либо ветке, вам нужнопройдитесь по коммитам этой ветви и сравните их с одним коммитом.

Чтобы сделать это быстрее, вы можете сохранить все коммиты для каждой ветви в HashSet<T>, например:

var branchCommits =
    repo.Branches.Select(
        b => new
             {
                 b.Name,
                 Commits = new HashSet<Commit>(b.Commits)
             })
        .ToArray();

foreach (Commit commit in branch.Commits)
{
    var commitBranches = branchCommits.Where(b => b.Commits.Contains(commit));

    …
}
1 голос
/ 26 февраля 2012

Git не хранит информацию о ветвях с коммитами. Вам придется пройтись по истории DAG и посмотреть, достижим ли коммит из ссылок.

В командной строке с обычным git вы запускаете git branch --contains $SHA1

...