C# git 命令行过程

pei*_*ent 5 c# command-prompt git-config windows-process git-bash

我们的组织使用 VisualStudioOnline、GitHub 和 BitBucket 作为各种存储库。我一直在尝试在 C# 中找到一种方法来定期自动执行pull来自各个存储库的更改。git我尝试启动这样的过程,然后重定向标准输入/输出。

var p = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = @"C:\Program Files (x86)\Git\bin\sh.exe",
        RedirectStandardInput = true,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        Arguments = "--login -i"
    }
};

p.Start();

using (var so = p.StandardOutput)
{
    using (var si = p.StandardInput)
    {
        if (si.BaseStream.CanWrite)
        {
            ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在块内部,我可以执行git如下命令:

  • si.WriteLine("cd \"P:/code/testapp\"");它将git shell 导航到该目录
  • si.WriteLine("git rev-parse HEAD"); 这将为我提供该位置存储库的最新哈希值。

我可以看到 bash shell 中返回的哈希值,也可以通过标准输入读取它,如下所示var hash = so.ReadLine();

当我尝试si.WriteLint("git pull");这样做时,它会要求输入用户名和密码,这是我所期望的,但这不是通过标准输入/输出完成的。我无法var prompt = so.ReadLine();收到输入用户名或密码的提示,也无法si.WriteLine("username");在提示中输入密码。

我已经尝试了很多方法来让它发挥作用,但到目前为止还没有运气。 警告:前面的代码很乱,只是试图快速制作原型,而不是创造杰作


尝试 1:使用如上所示的标准输入/输出重定向来尝试写入/读取用户名/密码的提示。


尝试 2:尝试获取 bash 正在使用的 ssh-agent 进程git并向其写入

si.WriteLine("ssh-agent --help");
var sshAgentInfo = string.Empty;
var tmp = a.ReadLine();
while (a.Peek() != -1)
{
    sshAgentInfo += tmp;
    tmp = a.ReadLine();
}

var begPos = sshAgentInfo.IndexOf("SSH_AGENT_PID=", StringComparison.Ordinal);
begPos = begPos + "SSH_AGENT_PID=".Length;
var endPos = sshAgentInfo.IndexOf(";", begPos, StringComparison.Ordinal);
var processId = int.Parse(sshAgentInfo.Substring(begPos, endPos - begPos));
var sshProcess = Process.GetProcessById(processId);
sshProcess.StartInfo.RedirectStandardInput = true;
sshProcess.StartInfo.RedirectStandardInput = true;
using (var si1 = sshProcess.StandardInput) { ... }
Run Code Online (Sandbox Code Playgroud)

尝试 3:利用凭证git config credential.helper wincred 这一次和第四次尝试非常相似。再次尝试弄清楚如何从命令行在这些凭据管理器中设置密码。


尝试 4:利用Git-Credential-Manager-for-Windows 我尝试查看此处的文档,似乎有一个增强请求要做一些类似的事情。

这两种尝试似乎都有类似的问题。git shell 似乎正在调用另一个进程,该进程处理与 git shell 分开的标准输入和输出。我对后两者的区别和希望是,有没有办法直接调用这些凭证管理器来为不同的网址设置用户名/密码?在 .git 目录中,配置文件具有凭据设置来告诉它使用哪个管理器,并以纯文本形式存储用户名和电子邮件。

如果我通过计算机上的 shell 调用git pull并通过该 shell 输入我的凭据一次,它似乎会存储它们,但是有没有办法允许用户通过网站输入他们的凭据,然后通过命令行调用管理器安全地存储该信息以供将来自动使用?

我也遇到过这个。我还没有机会尝试,但是这是做这样的事情的可行选择吗?

任何帮助将不胜感激。