MSysGit管道编码

本文关键字:编码 管道 MSysGit | 更新日期: 2023-09-27 17:54:43

我试图将一个git进程的输出作为输入管道传输到另一个git命令。但我就是不能成功。Git版本1.9.5.msysgit.0

我想用代码做什么:

git show e46b22be3031ed53e80472002d332a2588f122c9 | git patch-id
Output:
c2a55fcbc40da401f84ae3b72c250e55f827001a e46b22be3031ed53e80472002d332a2588f122c9

我已经将输出管道传输到一个文件中,这样我就可以进行比较了:

git show e46b22be3031ed53e80472002d332a2588f122c9 > git.show.txt

从文件重定向输入会产生预期的结果:

git patch-id < commit.show.txt
Output:
c2a55fcbc40da401f84ae3b72c250e55f827001a e46b22be3031ed53e80472002d332a2588f122c9

为了帮助我解决这个问题,我写了一个代理应用程序:

  1. 从git show
  2. 读取管道输入
  3. 将管道输入写入文件,以便与git.show.txt
  4. 进行比较。
  5. 将管道输入写入输出,以便下一个应用程序可以将其管道化

现在的用法是:

git show e46b22be3031ed53e80472002d332a2588f122c9 | ConsolePipeConsumer.exe | git patch-id
Incorrect Output:
cf55b48fa7c9ed6f7214641c4d709667abfeb078 e46b22be3031ed53e80472002d332a2588f122c9

我写的临时文件是二进制的,等于git.show.txt,所以读取输入如预期的那样工作。

我就是想不出代理应用程序的标准输出的代码页。能想到的我都试过了。还是还有什么东西不见了?

代码如下:

using System;
using System.IO;
using System.Text;
namespace ConsolePipeConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var encoding = Encoding.Default;                
                Console.SetIn(new StreamReader(Console.OpenStandardInput(8192), encoding));
                Console.Error.WriteLine("StdOut.Encoding={0}", Console.Out.Encoding);
                // What encoding to use for output?
                //Console.SetOut(new StreamWriter(Console.OpenStandardOutput(8192), encoding));
                int c;
                var sb = new StringBuilder();
                while ((c = Console.Read()) >= 0)
                {
                    sb.Append((char)c);
                }
                Console.Write(sb.ToString());
                var tmp = Path.GetTempFileName();
                File.WriteAllText(tmp, sb.ToString(), encoding);
                Console.Error.WriteLine("Piped input written to: " + tmp);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.ToString());
            }
        }
    }
}

MSysGit管道编码

似乎错误是我没有冲洗控制台。在退出代理应用程序之前退出。

我还按照Edward Thompson的建议通过读写字节来改进代码。

下面是一个代理应用程序的工作实现:

  1. 接受管道输出,例如git
  2. 写关于输入
  3. 的调试信息
  4. 然后将完全相同的数据传输到输出。

代码如下:

<!-- language: c# -->    
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
namespace ConsolePipeConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var pid = Process.GetCurrentProcess().Id;
                var buffer = new byte[1024];
                var tmp = new FileInfo(Path.GetTempFileName());
                using (var reader = new BinaryReader(Console.OpenStandardInput(8192)))
                using (var writer = new BinaryWriter(Console.OpenStandardOutput(8192)))
                using (var tmpWriter = new BinaryWriter(tmp.Create()))
                {
                    int c;
                    int len = 0;
                    while ((c = reader.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        writer.Write(buffer, 0, c);
                        tmpWriter.Write(buffer, 0, c);
                        len += c;
                    }
                    Console.Error.WriteLine("[{0}] Input length: {1}", pid, len);
                    Console.Error.WriteLine("[{0}] Piped input written to: ", pid);
                    Console.Error.WriteLine("[{0}] {1} (File Size={2})", pid, tmp, tmp.Length);
                    writer.Flush();
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.ToString());
            }
        }
    }
}