private async Task <CmdResult2> RunGitCmsAsync(
            string gitArgs, GitOptions options, string sessionId, CancellationToken ct)
        {
            AdjustOptions(options, sessionId);

            // Log.Debug($"Running: {GitCmdPath} {gitArgs}");
            CmdOptions cmdOptions = ToCmdOptions(options);
            string     gitCmdPath = GitCmdPath;
            CmdResult2 result     = await cmd.RunAsync(gitCmdPath, gitArgs, cmdOptions, ct);

            if (result.IsFaulted &&
                !result.IsCanceled &&
                !(result.ExitCode == 1 && string.IsNullOrEmpty(result.Error)))
            {
                Track.Event("Git-error", $"{result.ElapsedMs}ms: Exit {result.ExitCode}: {result.Command} {result.Arguments}\nError:\n{result.ErrorMessage}");
            }
            else
            {
                Track.Event("Git", $"{result.ElapsedMs}ms: {result.Command} {result.Arguments}");
                var replace = result.ToString().Replace($"\"{gitCmdPath}\"", "git");
                Log.Debug($"{result.ElapsedMs}ms: {replace}");
            }

            return(result);
        }
        private async Task <CmdResult2> CmdAsync(
            string gitArgs, GitOptions options, CancellationToken ct)
        {
            CmdResult2 result;
            bool       isRetry  = false;
            string     username = null;

            do
            {
                using (CredentialSession session = new CredentialSession(credentialService, username))
                {
                    result = await RunGitCmsAsync(gitArgs, options, session.SessionId, ct);

                    username = session.Username;
                    session.ConfirmValidCrededntial(!IsAuthenticationFailed(result));
                    isRetry = IsAuthenticationFailed(result) &&
                              session.IsCredentialRequested &&
                              !session.IsAskPassCanceled;

                    if (isRetry)
                    {
                        UiThread.Run(() => message.ShowError($"Invalid credentials for {session.TargetUri}"));
                    }
                }
            } while (isRetry);


            return(result);
        }
        public async Task <CmdResult2> RunCmdWitProgressAsync(
            string gitArgs, Action <string> lines, CancellationToken ct)
        {
            GitOptions options = new GitOptions {
                ErrorLines = lines
            };

            return(await CmdAsync(gitArgs, options, ct));
        }
        public async Task <R <CmdResult2> > RunAsync(
            string gitArgs, Action <string> outputLines, CancellationToken ct)
        {
            GitOptions options = new GitOptions
            {
                OutputLines      = outputLines,
                IsOutputDisabled = true,
            };

            return(AsR(await CmdAsync(gitArgs, options, ct)));
        }
        private void AdjustOptions(GitOptions options, string sessionId)
        {
            options.WorkingDirectory = options.WorkingDirectory ?? workingFolder.Path;

            // Used to enable credentials handling
            options.EnvironmentVariables = environment =>
            {
                // If git needs to ask for command line credentials, redirect that to GitMind to answer
                string instanceDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                environment["Path"]              = $"{instanceDir};{environment["Path"]}";
                environment["GIT_ASKPASS"]       = "******";
                environment["GITMIND_SESSIONID"] = sessionId;
            };
        }
        private static CmdOptions ToCmdOptions(GitOptions options)
        {
            string workingDirectory =
                options.WorkingDirectory != null && Directory.Exists(options.WorkingDirectory)
                                ? options.WorkingDirectory : null;

            return(new CmdOptions()
            {
                OutputLines = options.OutputLines,
                ErrorLines = options.ErrorLines,
                IsErrortDisabled = options.IsErrortDisabled,
                EnvironmentVariables = options.EnvironmentVariables,
                WorkingDirectory = workingDirectory,
                IsOutputDisabled = options.IsOutputDisabled,
                ErrorProgress = options.ErrorProgress
            });
        }
 public async Task <R <CmdResult2> > RunAsync(
     string gitArgs, GitOptions options, CancellationToken ct)
 {
     return(AsR(await CmdAsync(gitArgs, options, ct)));
 }