Azure Devops API:通过 Sha1 前缀、分支名称或标记名称查找 Git 提交?
Azure Devops API: Find a Git commit by Sha1 prefix, branch name or tag name?
在本地 Git 安装中,我可以使用“git show”来查找特定提交,给定 SHA1 哈希前缀、分支名称或标记名称。
如何使用 TFS/Azure Devops API 实现相同的目标?
我已经尝试了 Microsoft.TeamFoundation.SourceControl.WebApi.GitHttpClientBase.[GetCommitsAsync][1]()
,但是对于 SearchCriteria.ItemVersion
and CompareVersion
,我需要提供一个 VersionType
(分支、标签或提交),所以不像 git-show我已经必须知道我有什么样的标识符。此外,如果是“Commit”,它必须是一个完整的 SHA1 哈希;前缀不行。此外,我想找到一个提交,而不是整个列表。
并且 Microsoft.TeamFoundation.SourceControl.WebApi.GitHttpClientBase.GetCommitAsync()
仅适用于完整的 SHA1 哈希,不适用于前缀、分支或标记。
是否有任何 API 调用等同于“git show”?
如果版本很重要,它是 TFS 服务器 2019 (Dev17.M153.5)。
Azure DevOps 在 UI 的提交页面上有一个搜索框。将其与部分散列一起使用可提供以下查询条件。它使用 GET Commit REST method:
{
"fromCommitId": "b86c400000000000000000000000000000000000",
"toCommitId": "b86c4fffffffffffffffffffffffffffffffffff",
"skip": 0,
"maxResultCount": 25
}
或者将 searchCriteria.itemVersion.version
设置为确切的名称,将 searchCriteria.itemVersion.versionType
设置为 branch
或 tag
或 commit
以搜索特定的提交,以防您知道全名(分支、标签或完整的提交 ID)。
我使用 Chrome 开发工具来捕获请求。最坏的情况是短哈希不是唯一的,它将 return 多个选项。
对于分支和标签,您还可以 use the refs
API,它有一个开始选项和一个包含选项来查找您要查找的引用。
示例:
GET https://dev.azure.com/fabrikam/_apis/git/repositories/{repositoryId}/refs?filter=heads/&filterContains=replacer&api-version=6.0
搜索 filter=heads/
分支和 filter=tags/
标签,或者将主过滤器留空以搜索两者。
理论上这个 API 可以 return 多个对象,因为它使用 startsWith
作为 filter
和 contains
作为 filterContains
.
根据 Jesse 的提示,我想出了这个实现:
public async Task<GitCommit> GetCommitClever(string id)
{
return await GetCommitFromTag(id)
?? await GetCommitFromBranch(id)
?? await GetCommitFromHashPrefix(id);
}
private async Task<GitCommit> GetCommit(string commitId)
{
return await m_gitClient.GetCommitAsync(commitId, m_repo.Id).ConfigureAwait(false);
}
private async Task<GitCommit> GetCommitFromTag(string id)
{
var refs = await m_gitClient.GetRefsAsync(m_repo.Id, filter: "tags/" + id).ConfigureAwait(false);
if (refs == null || refs.Count != 1)
{
return null;
}
var tag = await m_gitClient.GetAnnotatedTagAsync(m_repo.ProjectReference.Id, m_repo.Id, refs[0].ObjectId).ConfigureAwait(false);
return await GetCommit(tag.TaggedObject.ObjectId);
}
private async Task<GitCommit> GetCommitFromBranch(string id)
{
var refs = await m_gitClient.GetRefsAsync(m_repo.Id, filter: "heads/" + id).ConfigureAwait(false);
if (refs == null || refs.Count != 1)
{
return null;
}
return await GetCommit(refs.Single().ObjectId).ConfigureAwait(false);
}
private async Task<GitCommit> GetCommitFromHashPrefix(string id)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(id, @"\A\b[0-9a-fA-F]+\b\Z"))
{
throw new ArgumentException($"Branch or tag '{id}' not found.");
}
GitQueryCommitsCriteria crit = new GitQueryCommitsCriteria()
{
FromCommitId = id.PadRight(40, '0'),
ToCommitId = id.PadRight(40, 'f')
};
var refs = await m_gitClient.GetCommitsAsync(m_repo.Id, crit, top: 2).ConfigureAwait(false);
if (refs == null || refs.Count == 0)
{
throw new ArgumentException($"Commit '{id}' not found.");
}
if (refs.Count > 1)
{
throw new ArgumentException($"Commit id '{id}' not unique.");
}
return await GetCommit(refs.Single().CommitId).ConfigureAwait(false);
}
// Using these private members:
private GitHttpClient m_gitClient;
private GitRepository m_repo;
还有改进的余地;例如如果你有一个标签“foobar”和一个分支“foo”,那么通过 id“foo”获取提交将 return 标签而不是更好匹配的分支。但我只需要有限的聪明,就这样吧。
在本地 Git 安装中,我可以使用“git show”来查找特定提交,给定 SHA1 哈希前缀、分支名称或标记名称。
如何使用 TFS/Azure Devops API 实现相同的目标?
我已经尝试了 Microsoft.TeamFoundation.SourceControl.WebApi.GitHttpClientBase.[GetCommitsAsync][1]()
,但是对于 SearchCriteria.ItemVersion
and CompareVersion
,我需要提供一个 VersionType
(分支、标签或提交),所以不像 git-show我已经必须知道我有什么样的标识符。此外,如果是“Commit”,它必须是一个完整的 SHA1 哈希;前缀不行。此外,我想找到一个提交,而不是整个列表。
并且 Microsoft.TeamFoundation.SourceControl.WebApi.GitHttpClientBase.GetCommitAsync()
仅适用于完整的 SHA1 哈希,不适用于前缀、分支或标记。
是否有任何 API 调用等同于“git show”?
如果版本很重要,它是 TFS 服务器 2019 (Dev17.M153.5)。
Azure DevOps 在 UI 的提交页面上有一个搜索框。将其与部分散列一起使用可提供以下查询条件。它使用 GET Commit REST method:
{
"fromCommitId": "b86c400000000000000000000000000000000000",
"toCommitId": "b86c4fffffffffffffffffffffffffffffffffff",
"skip": 0,
"maxResultCount": 25
}
或者将 searchCriteria.itemVersion.version
设置为确切的名称,将 searchCriteria.itemVersion.versionType
设置为 branch
或 tag
或 commit
以搜索特定的提交,以防您知道全名(分支、标签或完整的提交 ID)。
我使用 Chrome 开发工具来捕获请求。最坏的情况是短哈希不是唯一的,它将 return 多个选项。
对于分支和标签,您还可以 use the refs
API,它有一个开始选项和一个包含选项来查找您要查找的引用。
示例:
GET https://dev.azure.com/fabrikam/_apis/git/repositories/{repositoryId}/refs?filter=heads/&filterContains=replacer&api-version=6.0
搜索 filter=heads/
分支和 filter=tags/
标签,或者将主过滤器留空以搜索两者。
理论上这个 API 可以 return 多个对象,因为它使用 startsWith
作为 filter
和 contains
作为 filterContains
.
根据 Jesse 的提示,我想出了这个实现:
public async Task<GitCommit> GetCommitClever(string id)
{
return await GetCommitFromTag(id)
?? await GetCommitFromBranch(id)
?? await GetCommitFromHashPrefix(id);
}
private async Task<GitCommit> GetCommit(string commitId)
{
return await m_gitClient.GetCommitAsync(commitId, m_repo.Id).ConfigureAwait(false);
}
private async Task<GitCommit> GetCommitFromTag(string id)
{
var refs = await m_gitClient.GetRefsAsync(m_repo.Id, filter: "tags/" + id).ConfigureAwait(false);
if (refs == null || refs.Count != 1)
{
return null;
}
var tag = await m_gitClient.GetAnnotatedTagAsync(m_repo.ProjectReference.Id, m_repo.Id, refs[0].ObjectId).ConfigureAwait(false);
return await GetCommit(tag.TaggedObject.ObjectId);
}
private async Task<GitCommit> GetCommitFromBranch(string id)
{
var refs = await m_gitClient.GetRefsAsync(m_repo.Id, filter: "heads/" + id).ConfigureAwait(false);
if (refs == null || refs.Count != 1)
{
return null;
}
return await GetCommit(refs.Single().ObjectId).ConfigureAwait(false);
}
private async Task<GitCommit> GetCommitFromHashPrefix(string id)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(id, @"\A\b[0-9a-fA-F]+\b\Z"))
{
throw new ArgumentException($"Branch or tag '{id}' not found.");
}
GitQueryCommitsCriteria crit = new GitQueryCommitsCriteria()
{
FromCommitId = id.PadRight(40, '0'),
ToCommitId = id.PadRight(40, 'f')
};
var refs = await m_gitClient.GetCommitsAsync(m_repo.Id, crit, top: 2).ConfigureAwait(false);
if (refs == null || refs.Count == 0)
{
throw new ArgumentException($"Commit '{id}' not found.");
}
if (refs.Count > 1)
{
throw new ArgumentException($"Commit id '{id}' not unique.");
}
return await GetCommit(refs.Single().CommitId).ConfigureAwait(false);
}
// Using these private members:
private GitHttpClient m_gitClient;
private GitRepository m_repo;
还有改进的余地;例如如果你有一个标签“foobar”和一个分支“foo”,那么通过 id“foo”获取提交将 return 标签而不是更好匹配的分支。但我只需要有限的聪明,就这样吧。