Incorrect author and commit message when doing consecutiv git commits via system.management.automation.powershell

88 views Asked by At

My .NET application monitors a directory and periodically uses GIT to stage and commit all changes. I use System.Management.Automation to run a PowerShell to invoke the different GIT commands. The directory contains JSON files. Each changed file should be commited as a single commit.

This is the code that is run every 10 minutes:

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();
        }
    }        
}

Assuming there are two changed files in the directory, the git status --porcelain would return:

Status Filename
M file1.json
M file2.json

My code gets the filename, stages the changes and commits them. I expect two commits to be created:

Commit Commit Message Author Changed file
2 "Changed file2.json" "Author File 2 <...>" file2.json
1 "Changed file1.json" "Author File 1 <...>" file1.json

What I get:

Commit Commit Message Author Changed file
2 "Changed file1.json" "Author File 1 <...>" file2.json
1 "Changed file1.json" "Author File 1 <...>" file1.json

The two commits are created correctly, and the changes made to file1 and file2 are commited correctly. However, the commit message and author of the second commit are the same as the first commit.

I am not an expert with GIT, but I assume the problems originates from doing the commits consecutively from the same powershell session. It appears that the author and commit message might be saved somewhere locally and as I use the same powershell session to invoke multiple commits, it somehow gets confused. I know there is a COMMIT_EDITMSG file in the .git directory that appears to hold the last (?) commit message. Why does it need to safe that to a file if I pass it with each commit?

One idea was to delay the following commit commands until the previous commit is finished. A simple sleep would be a pretty dirty solution. I would prefer to check wether the git commit is actually finished before invoking the next commit.

EDIT: I tried adding a Thread.Slepp(10000) in the loop after every commit. However, the behaviour did not change. But I was able to confirm that the commit messages passed to the command are indeed correctly written to the COMMIT_EDITMSG file. I read about this file that acts as sort of a temporary storage for the commit message. After doing the first commit, it contains "Changed: file1.json" and after the second "Changed: file2.json", but the actual commit message assigned to the commit is not correct.

EDIT2: I tried using a seperate powershell session for each commit - everything works as expected with this approach:

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
       }
    }        
}

This makes me even more certain that the issue is the behaviour of git when performing multiple subsequent commits from the same powershell session.

0

There are 0 answers