如何确定分支是否包含使用 TFS WebApi 客户端库的提交?
How to determine whether a branch contains a commit with TFS WebApi client library?
基本上我想找到 API 替代 with TFS WebApi client libraries:
var commitId = "123456789abcdef";
var branchName = "branch";
var tpc = new TfsTeamProjectCollection(new Uri(""));
var git = tpc.GetClient<GitHttpClient>();
var isInBranch = git.?????(branchName, commitId);
有办法实现吗?
或者我是否应该使用 git.exe/libgit 对本地克隆进行操作(所讨论的存储库有点太大,如果可能的话,我更愿意避免克隆它)?
没有对应于git分支的任何WebApi客户端库--包含命令。
不过,作为解决方法,您可以在 C# 代码中直接 运行 git 命令。
string gitCommand = "git";
string gitAddArgument = @"add -A" ;
string gitCommitArgument = @"commit ""explanations_of_changes"" "
string gitPushArgument = @"push our_remote"
Process.Start(gitCommand, gitAddArgument );
Process.Start(gitCommand, gitCommitArgument );
Process.Start(gitCommand, gitPushArgument );
您可以包含您的认证,更多详情请参考Run git commands from a C# function
另一种方法是使用 powershell 脚本 运行 git 命令并调用 TFS API.
现在最好的方法是 GetBranchStatsBatchAsync
。
GetCommits
解决方案并不真正可靠 - 我们遇到过一些情况,其中 API 无法在范围内找到特定的提交,错误地声明提交不在分支中(然后我们替换了GetBranchStatsBatchAsync 的逻辑可用并且此后没有问题)。
Old/unreliable解决方案
有一种无需 GetBranchStatsBatchAsync
即可实现的方法 - 获取提交时间,然后检查该提交是否在该时间间隔内的分支中,尽管它需要两次单独的调用并且可能有一些 问题与:
- Committer date vs Author date - 我使用提交者日期,但没有花足够的时间来真正检查它。
用法是:
GitHttpClient git = ...;
var isInBranch = git.BranchContains(
project: "project",
repositoryId: "repository",
branch: "master",
commitId: "12345678910...")
密码是:
public static class GitHttpClientExt
{
/// <summary>
/// Gets a value indicating whether a branch with name <paramref name="branch"/> (like 'master', 'dev') contains the commit with specified <paramref name="commitId"/>.
/// Just like the <code>git branch --contains</code> it doesn't take possible reversions into account.
/// </summary>
public static Boolean BranchContains(this GitHttpClient git, String project, String repositoryId, String branch, String commitId)
{
var commitToFind = git.TryGetCommit(project: project, repositoryId: repositoryId, commitId: commitId);
if (commitToFind == null)
{
return false;
}
var committedDate = commitToFind.Committer.Date; // TODO: It will usually be the same as the author's, but I have failed to check what date TFS actually uses in date queries.
var criteria = new GitQueryCommitsCriteria
{
ItemVersion = new GitVersionDescriptor
{
Version = branch,
VersionType = GitVersionType.Branch
},
FromDate = DateToString(committedDate.AddSeconds(-1)), // Zero length interval seems to work, but just in case
ToDate = DateToString(committedDate.AddSeconds(1)),
};
var commitIds = git
.GetAllCommits(
project: project,
repositoryId: repositoryId,
searchCriteria: criteria)
.Select(c => c.CommitId);
return commitIds.Contains(commitId);
}
/// <summary>
/// Gets the string representation of <paramref name="dateTime"/> usable in query objects for <see cref="GitHttpClient"/>.
/// </summary>
public static String DateToString(DateTimeOffset dateTime)
{
return dateTime.ToString(CultureInfo.InvariantCulture);
}
/// <summary>Tries to retrieve git commit with specified <paramref name="commitId"/> for a project.</summary>
public static GitCommitRef TryGetCommit(this GitHttpClient git, String project, String repositoryId, String commitId)
{
return git
.GetAllCommits(
project: project,
repositoryId: repositoryId,
searchCriteria: new GitQueryCommitsCriteria
{
Ids = new List<String>
{
commitId
}
})
.SingleOrDefault();
}
/// <summary>Retrieve all(up to <see cref="Int32.MaxValue"/>) git (unless <paramref name="top"/> is set) commits for a project</summary>
public static List<GitCommitRef> GetAllCommits(
this GitHttpClient git,
String project,
String repositoryId,
GitQueryCommitsCriteria searchCriteria,
Int32? skip = null,
Int32? top = (Int32.MaxValue - 1)) // Current API somehow fails (silently!) on Int32.MaxValue;
{
return git
.GetCommitsAsync(
project: project,
repositoryId: repositoryId,
searchCriteria: searchCriteria,
skip: skip,
top: top)
.GetAwaiter()
.GetResult();
}
}
P.S.: 该代码当前是异步方法的同步包装器,因为不幸的是,当前项目需要它。如果适合您,请将其重做为合适的异步版本。
基本上我想找到 API 替代
var commitId = "123456789abcdef";
var branchName = "branch";
var tpc = new TfsTeamProjectCollection(new Uri(""));
var git = tpc.GetClient<GitHttpClient>();
var isInBranch = git.?????(branchName, commitId);
有办法实现吗?
或者我是否应该使用 git.exe/libgit 对本地克隆进行操作(所讨论的存储库有点太大,如果可能的话,我更愿意避免克隆它)?
没有对应于git分支的任何WebApi客户端库--包含命令。
不过,作为解决方法,您可以在 C# 代码中直接 运行 git 命令。
string gitCommand = "git";
string gitAddArgument = @"add -A" ;
string gitCommitArgument = @"commit ""explanations_of_changes"" "
string gitPushArgument = @"push our_remote"
Process.Start(gitCommand, gitAddArgument );
Process.Start(gitCommand, gitCommitArgument );
Process.Start(gitCommand, gitPushArgument );
您可以包含您的认证,更多详情请参考Run git commands from a C# function
另一种方法是使用 powershell 脚本 运行 git 命令并调用 TFS API.
现在最好的方法是 GetBranchStatsBatchAsync
。
GetCommits
解决方案并不真正可靠 - 我们遇到过一些情况,其中 API 无法在范围内找到特定的提交,错误地声明提交不在分支中(然后我们替换了GetBranchStatsBatchAsync 的逻辑可用并且此后没有问题)。
Old/unreliable解决方案
有一种无需 GetBranchStatsBatchAsync
即可实现的方法 - 获取提交时间,然后检查该提交是否在该时间间隔内的分支中,尽管它需要两次单独的调用并且可能有一些 问题与:
- Committer date vs Author date - 我使用提交者日期,但没有花足够的时间来真正检查它。
用法是:
GitHttpClient git = ...;
var isInBranch = git.BranchContains(
project: "project",
repositoryId: "repository",
branch: "master",
commitId: "12345678910...")
密码是:
public static class GitHttpClientExt
{
/// <summary>
/// Gets a value indicating whether a branch with name <paramref name="branch"/> (like 'master', 'dev') contains the commit with specified <paramref name="commitId"/>.
/// Just like the <code>git branch --contains</code> it doesn't take possible reversions into account.
/// </summary>
public static Boolean BranchContains(this GitHttpClient git, String project, String repositoryId, String branch, String commitId)
{
var commitToFind = git.TryGetCommit(project: project, repositoryId: repositoryId, commitId: commitId);
if (commitToFind == null)
{
return false;
}
var committedDate = commitToFind.Committer.Date; // TODO: It will usually be the same as the author's, but I have failed to check what date TFS actually uses in date queries.
var criteria = new GitQueryCommitsCriteria
{
ItemVersion = new GitVersionDescriptor
{
Version = branch,
VersionType = GitVersionType.Branch
},
FromDate = DateToString(committedDate.AddSeconds(-1)), // Zero length interval seems to work, but just in case
ToDate = DateToString(committedDate.AddSeconds(1)),
};
var commitIds = git
.GetAllCommits(
project: project,
repositoryId: repositoryId,
searchCriteria: criteria)
.Select(c => c.CommitId);
return commitIds.Contains(commitId);
}
/// <summary>
/// Gets the string representation of <paramref name="dateTime"/> usable in query objects for <see cref="GitHttpClient"/>.
/// </summary>
public static String DateToString(DateTimeOffset dateTime)
{
return dateTime.ToString(CultureInfo.InvariantCulture);
}
/// <summary>Tries to retrieve git commit with specified <paramref name="commitId"/> for a project.</summary>
public static GitCommitRef TryGetCommit(this GitHttpClient git, String project, String repositoryId, String commitId)
{
return git
.GetAllCommits(
project: project,
repositoryId: repositoryId,
searchCriteria: new GitQueryCommitsCriteria
{
Ids = new List<String>
{
commitId
}
})
.SingleOrDefault();
}
/// <summary>Retrieve all(up to <see cref="Int32.MaxValue"/>) git (unless <paramref name="top"/> is set) commits for a project</summary>
public static List<GitCommitRef> GetAllCommits(
this GitHttpClient git,
String project,
String repositoryId,
GitQueryCommitsCriteria searchCriteria,
Int32? skip = null,
Int32? top = (Int32.MaxValue - 1)) // Current API somehow fails (silently!) on Int32.MaxValue;
{
return git
.GetCommitsAsync(
project: project,
repositoryId: repositoryId,
searchCriteria: searchCriteria,
skip: skip,
top: top)
.GetAwaiter()
.GetResult();
}
}
P.S.: 该代码当前是异步方法的同步包装器,因为不幸的是,当前项目需要它。如果适合您,请将其重做为合适的异步版本。