8

libgit2sharp を使用して、次のことを行いたいと思います。

foreach( Commit commit in repo.Commits )
{
    // How to implement assignedTags?
    foreach( Tag tag in commit.assignedTags ) {}
}

現在のコミットに割り当てられているすべてのタグを取得したい。それを行う最良の方法は何ですか?すべてのタグを反復処理してtag.Target.Sha == commit.Sha、それはあまり高性能ではありません。別の方法はありますか?

4

2 に答える 2

9

したがって、現在のコミットに割り当てられているすべてのタグを取得したいと考えています。それを行う最良の方法は何ですか?すべてのタグを反復処理してtag.Target.Sha == commit.Sha、それはあまり高性能ではありません。別の方法はありますか?

タグに関しては、考慮すべき点が 2 つあります。

  • タグは、コミット以外のものを指すことができます (たとえば、ツリーまたはブロブ)
  • タグは別のタグを指すことができます (連鎖した注釈付きタグ)

以下のコードは、上記の点を考慮して、ニーズに合うはずです。

注: repo.Commits現在のブランチ ( ) から到達可能なコミットのみを列挙しHEADます。以下のコードはこれを拡張して、到達可能なすべてのコミットを簡単に参照できるようにします。

...

using (var repo = new Repository("Path/to/your/repo"))
{
    // Build up a cached dictionary of all the tags that point to a commit
    var dic = TagsPerPeeledCommitId(repo);

    // Let's enumerate all the reachable commits (similarly to `git log --all`)
    foreach (Commit commit in repo.Commits.QueryBy(new CommitFilter {Since = repo.Refs}))
    {
        foreach (var tags in AssignedTags(commit, dic))
        {
            Console.WriteLine("Tag {0} points at {1}", tags.Name, commit.Id);
        }
    }
}

....

private static IEnumerable<Tag> AssignedTags(Commit commit, Dictionary<ObjectId, List<Tag>> tags)
{
    if (!tags.ContainsKey(commit.Id))
    {
        return Enumerable.Empty<Tag>();
    }

    return tags[commit.Id];
}

private static Dictionary<ObjectId, List<Tag>> TagsPerPeeledCommitId(Repository repo)
{
    var tagsPerPeeledCommitId = new Dictionary<ObjectId, List<Tag>>();

    foreach (Tag tag in repo.Tags)
    {
        GitObject peeledTarget = tag.PeeledTarget;

        if (!(peeledTarget is Commit))
        {
            // We're not interested by Tags pointing at Blobs or Trees
            continue;
        }

        ObjectId commitId = peeledTarget.Id;

        if (!tagsPerPeeledCommitId.ContainsKey(commitId))
        {
            // A Commit may be pointed at by more than one Tag
            tagsPerPeeledCommitId.Add(commitId, new List<Tag>());
        }

        tagsPerPeeledCommitId[commitId].Add(tag);
    }

    return tagsPerPeeledCommitId;
}
于 2013-11-06T12:34:45.547 に答える