Unity git 获取当前修改或者新增的文件列表

直接上代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using UnityEngine;

public class GitFileStatusCheckerTools : MonoBehaviour
{
    // 获取Git变更文件列表(新增/修改)
    public static List<string> GetGitModifiedFiles()
    {
        var results = new List<string>();
        string projectRoot = GetGitRepositoryRoot();

        if (string.IsNullOrEmpty(projectRoot))
        {
            UnityEngine.Debug.LogWarning("Not a git repository");
            return results;
        }

        ProcessStartInfo startInfo = new ProcessStartInfo
        {
            FileName = "git",
            Arguments = "status --porcelain",
            WorkingDirectory = projectRoot,
            RedirectStandardOutput = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };

        using (Process process = new Process())
        {
            process.StartInfo = startInfo;
            process.Start();

            while (!process.StandardOutput.EndOfStream)
            {
                string line = process.StandardOutput.ReadLine();
                if (IsValidChange(line, out string filePath))
                {
                    string unityPath = ConvertToUnityPath(filePath);
                    results.Add(unityPath);
                }
            }

            process.WaitForExit();
        }

        return results;
    }

    // 获取Git仓库根目录
    private static string GetGitRepositoryRoot()
    {
        string currentPath = Directory.GetCurrentDirectory();
        DirectoryInfo directory = new DirectoryInfo(currentPath);

        while (directory != null)
        {
            if (Directory.Exists(Path.Combine(directory.FullName, ".git")))
            {
                return directory.FullName;
            }
            directory = directory.Parent;
        }
        return null;
    }

    // 验证是否为有效变更(修改或新增)
    private static bool IsValidChange(string statusLine, out string filePath)
    {
        filePath = "";
        if (string.IsNullOrEmpty(statusLine)) return false;
        bool isDebug = false;
        // 使用正则表达式匹配状态码
        var match = Regex.Match(statusLine, @"^(|M|A|\?\?)\s+(.*)");
        if (match.Success)
        {
            string[] statusList = statusLine.TrimStart().Split(' ');
            if (statusList.Length < 2)
            {
                UnityEngine.Debug.Log($"statusLine:{statusLine} 拆分路径错误 异常中间没有空格分割 split length < 2  length:{statusList.Length}");
                return false;
            }
            filePath = statusList[1];
            if(isDebug)
            {
                UnityEngine.Debug.Log($"statusLine:{statusLine}\n filePath:{filePath}");
            }
            // 处理带空格的文件名(引号包裹)
            if (filePath.StartsWith("\"") && filePath.EndsWith("\""))
            {
                filePath = filePath.Substring(1, filePath.Length - 2);
            }
            return true;
        }
        return false;
    }

    // 转换为Unity相对路径
    private static string ConvertToUnityPath(string fullPath)
    {
        string projectRoot = GetGitRepositoryRoot();
        string relativePath = fullPath
            .Replace(projectRoot, "")
            .TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
            .Replace(Path.DirectorySeparatorChar, '/');

        return AddAssetPrefixSmart(relativePath);
    }

    private static string AddAssetPrefixSmart(string relativePath)
    {
        const string assetsPrefix = "Assets/";

        // 情况1:已经是合法Unity路径
        if (relativePath.StartsWith(assetsPrefix, StringComparison.Ordinal))
        {
            return relativePath;
        }

        // 情况2:非Assets开头但确实在Assets目录下
        string[] pathSegments = relativePath.Split('/');
        if (pathSegments.Length > 0 && pathSegments[0] == "Assets")
        {
            return relativePath;
        }

        // 情况3:需要添加前缀
        return $"{assetsPrefix}{relativePath}";
    }
}

调用测试代码:


    [MenuItem("CustomTools/测试获取git修改文件列表", false)]
    public static void TestGetModifiedFiles()
    {
        List<string> files = GitFileStatusCheckerTools.GetGitModifiedFiles();
        foreach (var path in files)
        {
            Debug.Log($"有修改 path: {path}");
        }
    }

这样就获取到哪些文件新增或者修改 就可以做一些特殊处理 提交或者是修改 不用每次都记录全文件md5了 依赖git的对比差异

你可能感兴趣的:(unity,git,游戏引擎)