Git的2种强制Pull

2025/06 03 11:06

在版本机上,有可能本地文件被修改,拉取git时,有2种处理方法

1、全量重置

使用git reset –hard HEAD

2、仅对远程有修改的文件进行覆盖和更新,未修改的保持本地版本

可以先用git pull,获得输出后,再用git checkout filename 进行回滚

代码如下

using System;

namespace GitPull
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var workDir = System.Environment.CurrentDirectory;

            string fetchError = string.Empty;
            Execute(workDir, "git", "fetch", ref fetchError);

            for (int i = 0; i < 2; ++i)
            {
                string pullError = string.Empty;
                var pullOutput = Execute(workDir, "git", "pull", ref pullError);
                if (pullError.Length > 0)
                {
                    Checkouts(workDir,pullError);
                }
            }
        }

        private static void Checkouts(string workDir, string pullError)
        {
            var lines = pullError.Split('\n');
            if (lines.Length == 0)
            {
                return;
            }

            if (lines[0].Contains("Your local changes to the following files would be overwritten by merge:"))
            {
                for (int i = 1; i < lines.Length; i++)
                {
                    var line = lines[i];
                    if (line.StartsWith("Please commit your changes or stash them before you merge"))
                    {
                        break;
                    }

                    var filename = line.Trim();
                    GitCheckoutFile(workDir, filename);
                }
            }
        }

        private static void GitCheckoutFile(string workDir, string filename)
        {
            string err = string.Empty;
            Execute(workDir, "git", $"checkout {filename}", ref err);
        }

        private static string Execute(string workDir, string cmd, string args, ref string errInfo)
        {
            Console.WriteLine($"[Execute]{cmd} {args}");
            string output = string.Empty;
            var myProcess = new System.Diagnostics.Process();
            try
            {
                myProcess.StartInfo.UseShellExecute = false;
                myProcess.StartInfo.FileName = cmd;
                myProcess.StartInfo.CreateNoWindow = true;
                myProcess.StartInfo.Arguments = args;
                myProcess.StartInfo.RedirectStandardInput = true;
                myProcess.StartInfo.RedirectStandardOutput = true;
                myProcess.StartInfo.RedirectStandardError = true;
                myProcess.StartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8;
                myProcess.StartInfo.StandardErrorEncoding = System.Text.Encoding.UTF8;
                myProcess.Start();
                var pout = myProcess.StandardOutput.ReadToEnd();
                var perr = myProcess.StandardError.ReadToEnd();
                if (pout.Length > 0)
                {
                    output = pout;
                }
                if (perr.Length > 0)
                {
                    errInfo = perr;
                }
                myProcess.WaitForExit();
                myProcess.Close();
            }
            catch (System.Exception e)
            {
                output = e.ToString();
            }

            if (errInfo.Length > 0)
            {
                Console.WriteLine($"[Info]{errInfo}");
            }

            if (output.Length > 0)
            {
                Console.WriteLine($"[Info]{output}");
            }

            return output;
        }
    }
}