dotnet으로 git 커밋 구문 분석
이 문서에서는 dotnet을 사용하여 git 커밋을 구문 분석하는 방법을 설명합니다. 이 코드는 관심 있는 사람들을 위해 이 github 저장소에서 액세스할 수 있습니다.
git log에서 모든 기사를 가져오려는 주된 이유는 릴리스 정보 때문입니다. 제 경우에는 어제 한 일을 추적하고 싶습니다.
즉, 커밋 메시지에서 JIRA 티켓을 추출할 수 있어야 합니다. 또한 커밋 메시지와 커밋 해시를 추출할 수 있기를 원합니다.
정규식을 사용하여 커밋 메시지를 구문 분석하는 것이 좋은 방법입니다. 다음 정규식을 사용하여 커밋 메시지를 구문 분석할 것입니다.
foreach (Match match in Regex.Matches(c.Message, @"([\S]+)-\d+",
RegexOptions.None,
TimeSpan.FromSeconds(2)))
{
entries.Add(match.Value);
}
티켓 번호 앞의 모든 단어를 잡습니다. 예를 들어 다음 커밋 메시지가 있는 경우:
git commit -m "ABC-1234: This is a commit message"
커밋 메시지에서 ABC-1234를 추출합니다.
일반적인 구문 분석 논리의 경우 이 기사의 코드를 수정했습니다.
dotnet 6.0을 사용하면 모든 논리를 단일 파일에 넣을 수 있습니다.
이 모든 논리를 함께 결합하면 이후로 명령줄 인수를 구문 분석하여 모든 커밋을 가져온 다음 커밋 메시지를 구문 분석하여 JIRA 티켓을 얻을 수 있습니다.
git log
를 사용하면 표준 git 커밋은 헤더가 콜론, 커밋 sha sha1 해시 및 커밋 메시지로 정의됩니다.commit 226198d2f8e61206ad9eb47b32124f77801ca026
Author: David Li <[email protected]>
Date: Tue Aug 23 22:26:45 2022 -0700
feat: adding media_nlp post closes #16
dotnet 6.0을 사용하고 있으므로 새로운 최상위 문을 사용하여 코드를 더 간결하게 만들 수 있습니다. 명령줄 인수를 가져오려면 CommandLine 라이브러리를 사용해야 합니다.
var cmdArgs = Environment.GetCommandLineArgs();
Parser.Default.ParseArguments<CommandLineOptions>(cmdArgs)
.WithParsed<CommandLineOptions>(o =>{});
public class CommandLineOptions
{
[Option('s', "since", Required = false, Default = "yesterday", HelpText = "Since Time")]
public string Since { get; set; }
[Option('a', "author", Required = false, Default = "David Li", HelpText = "Author to search git logs for")]
public string Author { get; set; }
[Option('d', "dir", Required = false, HelpText = "local path to repository to parse")]
public string Repo { get; set; }
}
o
에는 CommandLineOptions 유형의 인수가 있습니다. 그런 다음 이후 인수를 사용하여 모든 커밋을 가져올 수 있습니다. 우리는 어제부터 내 커밋을 분석하기 위해 통과할 것입니다.명령줄 인수를 가져온 후 C#에서 git을 실행하는 다음 코드를 사용할 수 있습니다. Python에서는
subprocess
라고 합니다. 그런 다음 git의 응답을 구문 분석하여 커밋 해시와 커밋 메시지를 가져와야 합니다. public static string RunProcess(string command)
{
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "git";
p.StartInfo.Arguments = command;
p.Start();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
return output;
}
public static string AllLogs(string since, string author)
{
var args_string = string.Format("log --all --since=\"{0}\" --before=0am --author=\"{1}\"", since, author);
var output = RunProcess(args_string);
return output;
}
그런 다음 모든 결과를 구문 분석하기 위해 다음 코드를 사용할 수 있습니다. 행이 헤더인지 확인하기 위해 행 길이가 0보다 큰지, for 문자에 대한 문자 및 콜론 문자가 있는지 찾습니다.
static bool StartsWithHeader(string line)
{
if (line.Length > 0 && char.IsLetter(line[0]))
{
var seq = line.SkipWhile(ch => Char.IsLetter(ch) && ch != ':');
return seq.FirstOrDefault() == ':';
}
return false;
}
결과를 구문 분석하기 위해 "커밋 메시지"를 찾는 모든 코드 라인을 반복합니다.
public static List<GitCommit> ParseResults(string output)
{
GitCommit commit = null;
var commits = new List<GitCommit>();
bool processingMessage = false;
using (var strReader = new StringReader(output))
{
do
{
var line = strReader.ReadLine();
if (line == null) {
continue;
}
if (line.StartsWith("commit "))
{
if (commit != null)
commits.Add(commit);
commit = new GitCommit();
commit.Sha = line.Split(' ')[1];
}
if (StartsWithHeader(line))
{
var header = line.Split(':')[0];
var val = string.Join(":", line.Split(':').Skip(1)).Trim();
// headers
commit.Headers.Add(header, val);
}
if (string.IsNullOrEmpty(line) && commit.Message != null)
{
// commit message divider
processingMessage = !processingMessage;
}
if (line.Length > 0 && processingMessage)
{
// commit message.
commit.Message += line;
}
}
while (strReader.Peek() != -1);
}
if (commit != null)
commits.Add(commit);
return commits;
}
이 모든 논리를 결합하여 어제의 모든 커밋을 구문 분석한 다음 커밋 메시지를 구문 분석하여 JIRA 티켓을 얻을 수 있습니다.
var cmdArgs = Environment.GetCommandLineArgs();
Parser.Default.ParseArguments<CommandLineOptions>(cmdArgs)
.WithParsed<CommandLineOptions>(o =>
{
string output = Utils.AllLogs(o.Since, o.Author);
Console.WriteLine(output);
var commits = Utils.ParseResults(output);
Console.WriteLine(commits);
// pull entries with #{number} and JIRA-1 project regex
var entries = new List<String>();
// iterate across all commmits and print out the commit message
Console.WriteLine("Messages: ");
foreach (var c in commits)
{
Console.WriteLine(c.Message);
foreach (Match match in Regex.Matches(c.Message, @"([\S]+)-\d+",
RegexOptions.None,
TimeSpan.FromSeconds(2)))
{
// Console.WriteLine("Found '{0}' at position {1}", match.Value, match.Index);
entries.Add(match.Value);
}
}
Console.WriteLine("----------------");
Console.WriteLine("Issues found: ");
// print all entries
foreach (var e in entries)
{
Console.WriteLine(e);
}
});
참조
Reference
이 문제에 관하여(dotnet으로 git 커밋 구문 분석), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/friendlyuser/parsing-git-commits-with-dotnet-2mpl텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)