Как определить, содержит ли ветка коммит с клиентской библиотекой TFS WebApi? - PullRequest
0 голосов
/ 28 мая 2018

В основном, я хотел бы найти альтернативу API git branch - содержит с TFS WebApi клиентские библиотеки :

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 (рассматриваемый репозиторий слишком велик, и, если возможно, я бы предпочел избежать его клонирования)?

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Существует способ достичь этого с помощью доступного в настоящее время API - получить время фиксации, а затем проверить, находится ли такой фиксация в ветви за этот промежуток времени, хотя для этого требуется два отдельных вызова и могут возникнуть некоторые проблемы с:

  1. Дата коммиттера против даты автора - Я использую дату коммиттера, но не трачу достаточно времени, пытаясь действительно проверить его.

Использование:

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();
    }
}

PS: Существует также способ сделатьэто с GetBranchStatsBatchAsync, что более надежно - у нас были случаи, когда api не мог найти конкретные коммиты в диапазоне, ложно заявляя, что коммит не был в ветке (мы затем заменили логику на GetBranchStatsBatchAsync и с тех пор проблем не было).

PS: Код в настоящее время является оболочкой для синхронизации по асинхронным методам, поскольку, к сожалению, это требовалось в текущем проекте.Переработайте его в правильную асинхронную версию, если она вам подходит.

0 голосов
/ 29 мая 2018

Нет библиотеки клиента WebApi, соответствующей git branch--, содержит команду.

Однако в качестве обходного пути вы можете напрямую запустить команду git в своем коде C #.

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 );

Вы можете содержать свой сертификат, более подробную информацию см. Запуск команд git из функции C #

Другой способ - использование сценария powershell для запуска команды git и вызова TFS API.

...