Git 客户端,采用 C# 编写。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

152 lines
4.6 KiB

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Permissions;
using System.Text;
using GitUIPluginInterfaces;
namespace GitCommands
{
public sealed class GitCommandsInstance : IGitCommands, IDisposable
{
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public Process CmdStartProcess(string cmd, string arguments)
{
GitCommandHelpers.SetEnvironmentVariable();
var ssh = GitCommandHelpers.UseSsh(arguments);
Kill();
Settings.GitLog.Log(cmd + " " + arguments);
//process used to execute external commands
Process process = new Process() { StartInfo = GitCommandHelpers.CreateProcessStartInfo() };
process.StartInfo.CreateNoWindow = (!ssh && !Settings.ShowGitCommandLine);
process.StartInfo.FileName = cmd;
process.StartInfo.Arguments = arguments;
process.StartInfo.WorkingDirectory = Settings.WorkingDir;
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.StartInfo.LoadUserProfile = true;
process.EnableRaisingEvents = true;
if (!StreamOutput)
{
process.OutputDataReceived += ProcessOutputDataReceived;
process.ErrorDataReceived += ProcessErrorDataReceived;
}
Output = new StringBuilder();
ErrorOutput = new StringBuilder();
process.Exited += ProcessExited;
process.Start();
myProcess = process;
if (!StreamOutput)
{
process.BeginErrorReadLine();
process.BeginOutputReadLine();
}
return process;
}
public void Kill()
{
//If there was another process running, kill it
if (myProcess == null)
return;
try
{
if (!myProcess.HasExited)
{
myProcess.Kill();
}
myProcess.Close();
}
catch (Exception ex)
{
Trace.WriteLine(ex);
}
}
public void Dispose()
{
Kill();
}
public string RunGit(string arguments)
{
return GitCommandHelpers.RunCmd(Settings.GitCommand, arguments);
}
public event DataReceivedEventHandler DataReceived;
public event EventHandler Exited;
private void ProcessExited(object sender, EventArgs e)
{
ExitCode = myProcess.ExitCode;
if (Exited != null)
{
//The process is exited already, but this command waits also until all output is recieved.
//Only WaitForExit when someone is conntected 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...
myProcess.WaitForExit();
Exited(this, e);
}
myProcess = null;
}
private void ProcessErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (CollectOutput)
Output.Append(e.Data + Environment.NewLine);
if (DataReceived != null)
DataReceived(this, e);
}
private void ProcessOutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (CollectOutput)
Output.Append(e.Data + Environment.NewLine);
if (DataReceived != null)
DataReceived(this, e);
}
public IList<IGitSubmodule> GetSubmodules()
{
var submodules = GitCommandHelpers.RunCmd(Settings.GitCommand, "submodule status").Split('\n');
IList<IGitSubmodule> submoduleList = new List<IGitSubmodule>();
string lastLine = null;
foreach (var submodule in submodules)
{
if (submodule.Length < 43)
continue;
if (submodule.Equals(lastLine))
continue;
lastLine = submodule;
submoduleList.Add(GitCommandHelpers.CreateGitSubmodule(submodule));
}
return submoduleList;
}
public bool CollectOutput = true;
public bool StreamOutput;
public int ExitCode { get; set; }
public StringBuilder Output { get; private set; }
public StringBuilder ErrorOutput { get; private set; }
private Process myProcess;
}
}