public override void StartProcess(string command, string arguments, string workdir, Dictionary <string, string> envVariables)
        {
            try
            {
                GitCommandHelpers.SetEnvironmentVariable();

                bool ssh = GitCommandHelpers.UseSsh(arguments);

                KillProcess();

                string quotedCmd = command;
                if (quotedCmd.IndexOf(' ') != -1)
                {
                    quotedCmd = quotedCmd.Quote();
                }

                DateTime executionStartTimestamp = DateTime.Now;

                //process used to execute external commands
                var process = new Process();
                ProcessStartInfo startInfo = GitCommandHelpers.CreateProcessStartInfo(command, arguments, workdir, GitModule.SystemEncoding);
                startInfo.CreateNoWindow = (!ssh && !AppSettings.ShowGitCommandLine);
                foreach (var envVariable in envVariables)
                {
                    startInfo.EnvironmentVariables.Add(envVariable.Key, envVariable.Value);
                }
                process.StartInfo = startInfo;

                process.EnableRaisingEvents = true;
                process.OutputDataReceived += (sender, args) => FireDataReceived(new TextEventArgs((args.Data ?? "") + '\n'));
                process.ErrorDataReceived  += (sender, args) => FireDataReceived(new TextEventArgs((args.Data ?? "") + '\n'));
                process.Exited += delegate
                {
                    this.InvokeAsync(new Action(() =>
                    {
                        if (_process == null)
                        {
                            return;
                        }
                        // From GitCommandsInstance:
                        //The process is exited already, but this command waits also until all output is received.
                        //Only WaitForExit when someone is connected to the exited event. For some reason a
                        //null reference is thrown sometimes when staging/unstaging in the commit dialog when
                        //we wait for exit, probably a timing issue...
                        try
                        {
                            _process.WaitForExit();
                        }
                        catch
                        {
                            // NOP
                        }
                        _exitcode = _process.ExitCode;
                        _process  = null;
                        _timer.Stop(true);
                        FireProcessExited();
                    }));
                };

                process.Exited += (sender, args) =>
                {
                    DateTime executionEndTimestamp = DateTime.Now;
                    AppSettings.GitLog.Log(quotedCmd + " " + arguments, executionStartTimestamp, executionEndTimestamp);
                };

                process.Start();
                _process = process;
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
            }
            catch (Exception ex)
            {
                ex.Data.Add("command", command);
                ex.Data.Add("arguments", arguments);
                throw;
            }
        }
        public override void StartProcess(string command, string arguments, string workdir, Dictionary <string, string> envVariables)
        {
            try
            {
                EnvironmentConfiguration.SetEnvironmentVariables();

                bool ssh = GitCommandHelpers.UseSsh(arguments);

                KillProcess();

                // process used to execute external commands
                var process = new Process();
                ProcessStartInfo startInfo = GitCommandHelpers.CreateProcessStartInfo(command, arguments, workdir, GitModule.SystemEncoding);
                startInfo.CreateNoWindow = !ssh && !AppSettings.ShowGitCommandLine;

                foreach (var(name, value) in envVariables)
                {
                    startInfo.EnvironmentVariables.Add(name, value);
                }

                process.StartInfo = startInfo;

                process.EnableRaisingEvents = true;
                process.OutputDataReceived += (sender, args) => FireDataReceived(new TextEventArgs((args.Data ?? "") + '\n'));
                process.ErrorDataReceived  += (sender, args) => FireDataReceived(new TextEventArgs((args.Data ?? "") + '\n'));
                process.Exited += delegate
                {
                    this.InvokeAsync(() =>
                    {
                        if (_process == null)
                        {
                            return;
                        }

                        // The process is exited already, but this command waits also until all output is received.
                        // Only WaitForExit when someone is connected to the exited event. For some reason a
                        // null reference is thrown sometimes when staging/unstaging in the commit dialog when
                        // we wait for exit, probably a timing issue...
                        try
                        {
                            _process.WaitForExit();
                        }
                        catch
                        {
                            // NOP
                        }

                        _exitcode = _process.ExitCode;
                        _process  = null;
                        _timer.Stop(true);
                        FireProcessExited();
                    }).FileAndForget();
                };

                var operation = CommandLog.LogProcessStart(command, arguments);
                process.Exited += (s, e) => operation.LogProcessEnd();
                process.Start();
                operation.SetProcessId(process.Id);
                _process = process;
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
            }
            catch (Exception ex)
            {
                ex.Data.Add("command", command);
                ex.Data.Add("arguments", arguments);
                throw;
            }
        }