Pregunta

Do you know what is the reasonable way to find the closest tag that contain certain commit?

git describe --contains my-commit-hash

works fine but I don't see a way to do the same with LibGit2Sharp

I was trying to do something like

foreach (var childCommit in GetChildrenOrSelf(commit))
{
    var tag = repo.Tags[childCommit];
    if (tag != null)
        return tag;
}

But I could not find an easy way to implement GetChildrenOrSelf

According to this How to find all commits having a particular parent? - it is not a simple task.

Can you advise anything?

¿Fue útil?

Solución

Git describe is a work in progress in libgit2. You can subscribe to issue libgit2/libgit2#1066 to get notifications about its future progress.

Although that's only a first step to achieve your goal, you may get some help from the repo.Refs.ReachableFrom() method. It retrieves all the References that can reach a set of particular Commits.

The tests give a first start describing how to leverage this method. One of them even highlights how to only retrieve tags.

var result = repo.Refs.ReachableFrom(
    repo.Refs.Where(r => r.IsTag()),
    new[] { repo.Lookup<Commit>(myCommitHash) });

Now, in order to determine the "closest" tag, you'd have to find, among those tags, the one that is separated by the smallest number of commits from your target commit. The following method should just do that:

private Reference Closest(IRepository repo,
    IEnumerable<Reference> result, Commit commit)
{
    int max = int.MaxValue;
    Reference cl = null;

    var f = new CommitFilter { Until = commit.Id };

    foreach (var reference in result)
    {
        f.Since = reference;
        var c = repo.Commits.QueryBy(f).Count();

        if (c >= max)
        {
            continue;
        }

        max = c;
        cl = reference;
    }

    return cl;
}

Note 1: Depending on your tag naming scheme you may be able to skip this last phase (by selecting the oldest tag without performing any count, for instance: v0.17 has huge chances to be "closer" to the commit than v0.21).

Note 2: This method isn't the most effective one as it will perform a huge number of revwalks. However, it should help you until git-describe is natively implemented in libgit2.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top