我在本地添加了很多开源项目,我写了一个脚本可以每天自动从开源项目更新代码
我在写开源项目的时候,在需要写之前更新项目,但是每次更新都需要等很久,能否可以自动更新开源项目的代码,这样每次需要更新的就很少,提高开发的速度。我找到了 Git 的命令可以更新项目,本文主要就是通过写一个程序自动使用 Git 命令更新
可以通过找到所有 Git 文件夹,执行 git fetch --all
命令更新项目
所以步骤就是写 cmd 命令行调用,然后写 Git 命令,接着是找到磁盘的所有 Git 文件夹,然后调用 Git 命令更新
写一个类执行 cmd 命令
public static class Control
{
static Control()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
}
public static string Command(string str)
{
// string str = Console.ReadLine();
//System.Console.InputEncoding = System.Text.Encoding.UTF8;//乱码
Process p = new Process
{
StartInfo =
{
FileName = "cmd.exe",
UseShellExecute = false, //是否使用操作系统shell启动
RedirectStandardInput = true, //接受来自调用程序的输入信息
RedirectStandardOutput = true, //由调用程序获取输出信息
RedirectStandardError = true, //重定向标准错误输出
CreateNoWindow = true, //不显示程序窗口
StandardOutputEncoding = Encoding.GetEncoding("GBK") //Encoding.UTF8
//Encoding.GetEncoding("GBK");//乱码
}
};
p.Start(); //启动程序
//向cmd窗口发送输入信息
p.StandardInput.WriteLine(str + "&exit");
p.StandardInput.AutoFlush = true;
//p.StandardInput.WriteLine("exit");
//向标准输入写入要执行的命令。这里使用&是批处理命令的符号,表示前面一个命令不管是否执行成功都执行后面(exit)命令,如果不执行exit命令,后面调用ReadToEnd()方法会假死
//同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令,后者表示必须前一个命令执行失败才会执行后面的命令
bool exited = false;
// 超时
Task.Run(() =>
{
Task.Delay(TimeSpan.FromMinutes(1)).ContinueWith(_ =>
{
if (exited)
{
return;
}
try
{
if (!p.HasExited)
{
Console.WriteLine($"{str} 超时");
p.Kill();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
});
});
//获取cmd窗口的输出信息
string output = p.StandardOutput.ReadToEnd();
//Console.WriteLine(output);
output += p.StandardError.ReadToEnd();
//Console.WriteLine(output);
//StreamReader reader = p.StandardOutput;
//string line=reader.ReadLine();
//while (!reader.EndOfStream)
//{
// str += line + " ";
// line = reader.ReadLine();
//}
p.WaitForExit(); //等待程序执行完退出进程
p.Close();
exited = true;
return output + "\r\n";
}
}
然后需要有一个类可以用于通过命令行调用 Git 执行代码
public class GitCommand
{
/// <inheritdoc />
public GitCommand(DirectoryInfo repo)
{
Repo = repo;
}
public DirectoryInfo Repo { get; }
public void FetchAll()
{
Control("fetch --all");
}
private string Control(string str)
{
str = FileStr() + str;
Log(str);
str = RegeejairhemFurwhurrahuki.Control.Command(str);
Log(str);
return str;
}
private static void Log(string str)
{
Console.WriteLine(str);
}
private string FileStr()
{
return string.Format(GitStr, Repo.FullName);
}
private const string GitStr = "git -C {0} ";
}
不知道有没小伙伴找到一个好用的执行 Git 命令的库
然后找到磁盘所有 Git 文件夹修改项目
static void Main(string[] args)
{
List<DirectoryInfo> deviceList = FindDevice();
foreach (var device in deviceList)
{
Log($"开始读取{device}盘符内容");
try
{
FindDirectory(device, 10);
}
catch (Exception e)
{
Log(e.ToString());
}
}
}
/// <summary>
/// 寻找文件夹
/// </summary>
/// <param name="directory"></param>
/// <param name="deep">寻找深度</param>
private static void FindDirectory(DirectoryInfo directory, int deep)
{
try
{
Log($"开始读取 {directory.FullName} 文件夹,当前递归深度{deep}");
deep--;
var gitFolder = new DirectoryInfo(Path.Combine(directory.FullName, GitFolder));
if (CheckIsGitFolder(gitFolder))
{
Log($"找到{gitFolder.FullName}文件夹");
try
{
UpdateGitFile(directory);
}
catch (Exception e)
{
Log(e.ToString());
}
}
else
{
//Log($"因为{directory.FullName}不是");
if (deep == 0)
{
Log($"达到递归深度{directory.FullName}不再继续寻找子文件夹");
return;
}
var subDirectoryList = directory.GetDirectories();
Log($"在{directory.FullName}找到{subDirectoryList.Length}个文件夹");
foreach (var temp in subDirectoryList)
{
FindDirectory(temp, deep);
}
}
}
catch (Exception e)
{
Log(e.ToString());
}
}
private static void UpdateGitFile(DirectoryInfo directory)
{
var gitCommand = new GitCommand(directory);
gitCommand.FetchAll();
}
private const string GitFolder = ".git";
/// <summary>
/// 判断当前是否一个 git 文件夹
/// </summary>
/// <param name="directory"></param>
private static bool CheckIsGitFolder(DirectoryInfo directory)
{
return directory.Exists;
}
private static void Log(string str)
{
Console.WriteLine(str);
//File.AppendAllText("log.txt", str + "\r\n");
}
/// <summary>
/// 找到所有驱动器
/// </summary>
/// <returns></returns>
private static List<DirectoryInfo> FindDevice()
{
var deviceList = new List<DirectoryInfo>();
for (int i = 0; i < 'Z' - 'A' + 1; i++)
{
var device = (char)('A' + i) + ":\\";
if (Directory.Exists(device))
{
deviceList.Add(new DirectoryInfo(device));
}
}
return deviceList;
}
代码请看 github
本文会经常更新,请阅读原文: https://dotnet-campus.github.io//post/%E8%87%AA%E5%8A%A8%E6%9B%B4%E6%96%B0%E6%89%80%E6%9C%89-Git-%E4%BB%93%E5%BA%93.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 lindexi (包含链接: https://dotnet-campus.github.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。