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的对比差异