5

私はコミットをループしていLibGit2Sharpます:

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

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

Authorおよびのようなプロパティを取得できますMessageが、それがどのブランチに属しているかについては何も表示されません。理想的には、ブランチオブジェクトへのポインタが必要ですが、このシナリオでは名前でも問題ありません。

これは、デバッガーが表示するものです。

ここに画像の説明を入力してください

これは私が探しているものです:

ここに画像の説明を入力してください

最も関連性の高いブランチ名を表示するTortoiseGitの動作:

ここに画像の説明を入力してください

リポジトリの例:https ://docs.google.com/open?id = 0B-3-X85VysdNcmZIaGVTSDZSenVGbTJxYlI2SUlsZw

4

3 に答える 3

7

現在、を模倣する組み込みの方法はありません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の開発ブランチの現在のヒントに対して正常にテストされています。

アップデート:

コメントでの議論に続いて、ここにあなたの要求を満たすことを願っている小さなアップデートがあります。

以下のコードは、検索されたコミットを含むすべてのブランチを返します。コミットがたまたま少なくとも1つのブランチの先端である場合、それらのブランチが代わりに返されます。

[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;
    }
}
于 2012-02-26T10:48:58.503 に答える
2

Gitはコミットでブランチ情報を保存しません。履歴DAGを調べて、参照からコミットに到達できるかどうかを確認する必要があります。

通常のgitを使用したコマンドラインで実行しますgit branch --contains $SHA1

于 2012-02-26T10:10:52.570 に答える
1

knittlが言ったように、gitはその情報を保存しません。コミットは、いくつかのメタデータを含むリポジトリの固定状態です。コミットは不変であり、コミットが属するブランチは変更される可能性があるため、ブランチ情報をコミットに直接保存することはできません。

したがって、特定のコミットが実際に特定のブランチに属しているかどうかを確認するには、そのブランチのコミットをウォークスルーし、それらを1つのコミットと比較する必要があります。

これを高速化するために、各ブランチのすべてのコミットを次の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));

    …
}
于 2012-02-26T10:27:14.100 に答える