.net 通过system.management.automation.powershell连续提交git时,作者和提交消息不正确

gblwokeq  于 2023-10-21  发布在  .NET
关注(0)|答案(1)|浏览(109)

我的.NET应用程序监视一个目录,并定期使用GIT来暂存和提交所有更改。我使用System.Management.Automation运行PowerShell来调用不同的GIT命令。该目录包含JSON文件。每个更改的文件都应该作为一次提交提交。
这是每10分钟运行一次的代码:

using (PowerShell powershell = PowerShell.Create())
{
    //Get all changes to files
    powershell.AddScript($"git status --porcelain");
    Collection<PSObject> changes = powershell.Invoke();
    
    //Loop over all changes detected by GIT (e.g. "M filename.json")               
    foreach (string change in changes.Select(x => x.BaseObject.ToString()))
    {
        //Get the name of the changed file (e.g. "filename.json")
        Match filematch = MY_REGEX.Match(change);
        if (filematch.Success)
        {
            string author = null;                    
            //Read the author from the file
            //...                   

            //Stage the changed file (e.g. git add filename)
            powershell.AddScript($"git add {filematch.Value}");
            powershell.Invoke();

            //Commit (e.g. git commit --author "Author <mail>" -m "Message")
            powershell.AddScript($"git commit --author {author} -m ""Changed {filematch.Value}""");
            powershell.Invoke();
        }
    }        
}

假设目录中有两个已更改的文件,git status --porcelain将返回:
| 地位|文件名|
| --|--|
| M| file1.json |
| M| file2.json |
我的代码获取文件名,暂存更改并提交它们。我希望创建两个提交:
| 承诺|提交消息|作者|改变文件|
| --|--|--|--|
| 2 |“已更改file2.json”|“作者档案2<...>“| file2.json |
| 1 |“已更改file1.json”|“作者文件1<...>“| file1.json |
我得到的:
| 承诺|提交消息|作者|改变文件|
| --|--|--|--|
| 2 |“已更改文件1.json”|“作者文件1<...>“| file2.json |
| 1 |“已更改file1.json”|“作者文件1<...>“| file1.json |
这两个提交被正确地创建,并且对file 1和file 2所做的更改被正确地提交。但是,第二次提交的提交消息和作者与第一次提交相同。
我不是GITMaven,但我认为问题源于从同一个powershell会话连续提交。似乎作者和提交消息可能保存在本地的某个地方,当我使用同一个powershell会话来调用多个提交时,它不知何故变得混乱。我知道在.git目录中有一个COMMIT_EDITMSG文件,它似乎保存了最后一个(?)提交消息。如果我每次提交都传递它,为什么它需要把它安全地保存到一个文件中?
一个想法是延迟下面的提交命令,直到前一个提交完成。一个简单的睡眠将是一个相当肮脏的解决方案。在调用下一次提交之前,我更喜欢检查git提交是否真的完成了。
编辑:我尝试在每次提交后添加一个Thread.Slepp(10000)。然而,行为并没有改变。但是我能够确认传递给命令的提交消息确实正确地写入了COMMIT_EDITMSG文件。我读到过这个文件,它可以作为提交消息的临时存储。在执行第一次提交之后,它包含"Changed: file1.json",在第二次提交之后,它包含"Changed: file2.json",但是分配给提交的实际提交消息是不正确的。
编辑2:我尝试为每个提交使用一个单独的powershell会话-使用这种方法一切都按预期工作:

using (PowerShell powershell = PowerShell.Create())
{
    //Get the changed files with git status
              
    foreach (string change in changes)   
    {
       using (PowerShell newSession = PowerShell.Create())
       {
            //Process and commit every file with a new session
       }
    }        
}

这让我更加确定问题出在git在同一个powershell会话中执行多个后续提交时的行为。

oo7oh9g9

oo7oh9g91#

你可以尝试一种解决方法,为每个提交创建一个单独的PowerShell会话,有效地从每个提交的干净状态开始(作者在git state上下文中):

foreach (string change in changes.Select(x => x.BaseObject.ToString()))
{
    Match filematch = MY_REGEX.Match(aenderung);
    if (filematch.Success)
    {
        string author = null;                    

        // Start a new PowerShell session for each commit
        using (PowerShell psCommit = PowerShell.Create())
        {
            // Stage the changed file
            psCommit.AddScript($"git add {filematch.Value}");
            psCommit.Invoke();

            // Commit with specific author and message
            psCommit.AddScript($"git commit --author {author} -m \"Changed {filematch.Value}\"");
            psCommit.Invoke();
        }
    }
}

相关问题