使用libgit2sharp我想执行以下操作:
foreach( Commit commit in repo.Commits )
{
// How to implement assignedTags?
foreach( Tag tag in commit.assignedTags ) {}
}
我想将所有标签分配给当前提交。什么是最好的方法呢?迭代所有标签并查看是否tag.Target.Sha == commit.Sha
?多数表现不太好。还有另一种方式吗?
答案 0 :(得分:8)
所以我希望将所有标签分配给当前提交。什么是最好的方法呢?迭代所有标签并查看是否
tag.Target.Sha == commit.Sha
?多数表现不太好。还有另一种方式吗?
对于标签,有两件事需要考虑。
以下代码应符合您的需要,并考虑以上几点。
注意: 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;
}
答案 1 :(得分:0)
这是nulltoken的另一个版本的答案,但使用ILookup
类而不是字典。有点好的IMO:
private static ILookup<ObjectId, Tag> CreateCommitIdToTagLookup(Repository repo)
{
var commitIdToTagLookup =
repo.Tags
.Select(tag => new { Commit = tag.PeeledTarget as Commit, Tag = tag })
.Where(x => x.Commit != null)
.ToLookup(x => x.Commit.Id, x => x.Tag);
return commitIdToTagLookup;
}
和简单的用法示例:
using (var repo = new Repository("Path/to/your/repo"))
{
var commitIdToTagLookup = CreateCommitIdToTagLookup(repo);
foreach (var commit in repo.Commits)
{
foreach (var tag in commitIdToTagLookup[commit.Id])
{
Console.WriteLine($"Tag {tag.FriendlyName} points at {commit.Id}");
}
}
}