質問

There is a sha value represent to the status for git repository in current status?

The sha value to be updated each time the Object Database updated and References changed if git has this sha value.

In other words, the sha value represent to the current version of whole repository.

Here is my code for calculate a sha for current references. There is a git level API or interface?

private string CalcBranchesSha(bool includeTags = false)
{
    var sb = new StringBuilder();
    sb.Append(":HEAD");
    if (_repository.Head.Tip != null)
        sb.Append(_repository.Head.Tip.Sha);
    sb.Append(';');
    foreach (var branch in _repository.Branches.OrderBy(s => s.Name))
    {
        sb.Append(':');
        sb.Append(branch.Name);
        if (branch.Tip != null)
            sb.Append(branch.Tip.Sha);
    }
    sb.Append(';');
    if (includeTags)
    {
        foreach (var tag in _repository.Tags.OrderBy(s => s.Name))
        {
            sb.Append(':');
            sb.Append(tag.Name);
            if (tag.Target != null)
                sb.Append(tag.Target.Sha);
        }
    }
    return sb.ToString().CalcSha();
}
役に立ちましたか?

解決

There is a sha value represent to the status for git repository in current status?

In git parlance, the status of a repository usually refers to the paths that have differences between the working directory, the index and the current HEAD commit.

However, it doesn't look like you're after this. From what I understand, you're trying to calculate a checksum that represents the state of the current repository (ie. what your branches and tags point to).

Regarding the code, it may be improved in some ways to get a more precise checksum:

  • Account for all the references (beside refs/tags and refs/heads) in the repository (think refs/stash, refs/notes or the generated backup references in refs/original when one rewrite the history of a repository).
  • Consider disambiguating symbolic from direct references. (ie: HEAD->master->08a4217 should lead to a different checksum than HEAD->08a4127)

Below a modified version of the code which deals with those two points above, by leveraging the Refs namespace:

private string CalculateRepositoryStateSha(IRepository repo)
{
    var sb = new StringBuilder();

    sb.Append(":HEAD");
    sb.Append(repo.Refs.Head.TargetIdentifier);
    sb.Append(';');

    foreach (var reference in repo.Refs.OrderBy(r => r.CanonicalName))
    {
        sb.Append(':');
        sb.Append(reference.CanonicalName);
        sb.Append(reference.TargetIdentifier);
        sb.Append(';');
    }

    return sb.ToString().CalcSha();
}

Please keep in mind the following limits:

  • This doesn't consider the changes to the index or the workdir (eg. the same checksum will be returned either a file has been staged or not)
  • There are ways to create object in the object database without modifying the references. Those kind of changes won't be reflected with the code above. One possible hack-ish way to do this could be to also append to the StringBuuilder, the number of object in the object database (ie. repo.ObjectDatabase.Count()), but that may hinder the overall performance as this will enumerate all the objects each time the checksum is calculated).

There is a git level API or interface?

I don't know of any equivalent native function in git (although similar result may be achieved through some scripting). There's nothing native in libgit2 or Libgit2Sharp APIs.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top