0

I have a handful of repositories (maybe 15 or 20), most with several hundred commits. I would like to be able to call a batch file that has git write a log of each to a text file so I can parse them (once I have the separate files, I believe I can do easily, and plan to use C# most likely).

I know I can use git-bash in separate commands to do something like:

cd "<path to my repo>"
git --no-pager log > log.txt

This gets me the files I want, but how can this be accomplished in a batch file?
Can I use git-bash in this way? Do I have to use git.exe instead?

If it's not a good idea to do this via a batch file, is it possible to do this in C# with Process.Start?

Some of the questions I've focused on so far:
How do I export a git log to a text file? (how I leaned to use git-bash to create a text log)
Run git commands from a C# function
Running Bash Commands from C#

But I'm still not sure how to call what I want on each of the individual repositories. Especially in a batch file, where to my limited knowledge, each line is a standalone command (eliminating git-bash.exe as a possibility?).

Update

I've tried using the below code:

public void RunGitForLogs()
{
    Process process = new Process();

    ProcessStartInfo processStartInfo = new ProcessStartInfo();
    processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    processStartInfo.FileName = @"C:\Program Files\Git\bin\git.exe";
    processStartInfo.WorkingDirectory = @"E:\git\myRepo";
    processStartInfo.Arguments = @"log --no-pager > C:\users\me\desktop\log.txt";
    processStartInfo.RedirectStandardOutput = true;
    processStartInfo.RedirectStandardError = true;
    processStartInfo.UseShellExecute = false;

    process.StartInfo = processStartInfo;
    process.Start();

    var outStd = new List<string>();
    var outErr = new List<string>();

    //https://stackoverflow.com/a/16276776/2957232
    while (process.StandardOutput.Peek() > -1)
        outStd .Add(process.StandardOutput.ReadLine());

    while (process.StandardError.Peek() > -1)
        outErr .Add(process.StandardError.ReadLine());

    process.WaitForExit();
}  

But in outErr I get the following lines:

fatal: ambiguous argument '>': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git [...] -- [...]'

Using "status" as an argument works as expected for this repo (Many lines in outStd, nothing in outErr).

Community
  • 1
  • 1
Code Stranger
  • 103
  • 1
  • 10
  • This seems like it should be pretty straightforward, yet I am not seeing anything via my searching... Weird. I would assume this would be a useful thing for people to have already done at some point. – Broots Waymb Jun 27 '16 at 20:59
  • It's very possible to do this via `Process.Start(...)` as long as you set the working directory via a `ProcessStartInfo` object. – Patrick Bell Jun 27 '16 at 21:00
  • @ext0 - Would you be able to write that up as an answer? I'm experimenting with the answers in the last link OP posted now in order to write something up, but I'm not having the best time with that... – Broots Waymb Jun 27 '16 at 21:22
  • @DangerZone - I think you mean in the Update 1 of the question. But same here. Also ran into some issues there. – Code Stranger Jun 27 '16 at 21:28
  • @CodeStranger - Yes, that is what I mean, sorry. – Broots Waymb Jun 27 '16 at 21:39
  • @CodeStranger I'm not sure how much I can elaborate on, because I'm not currently on my work machine that has `git` installed. My recommendation would be to create a new `Process` object for each git repository that you are scanning, and set the `WorkingDirectory` field of the `ProcessStartInfo` object that you initialize the `Process` object with. Also, about your issue with `git.exe`, make sure you have the FULL path (including "\git.exe") and ensure that the whole path is surrounded in quotes. – Patrick Bell Jun 27 '16 at 21:40
  • @ext0 - I feel like I'm close, but If I set the `Arguments` of the `ProcessStartInfo` to "git status" (trying a more simp'e example here) I get "'git' is not a git command...." from StandardError. If I remove "git" and just do "status", VS hangs up/times out on retrieving any StandardError message. So I'm missing something here I think. – Code Stranger Jun 27 '16 at 21:49
  • @CodeStranger Arguments won't be `git status`, but just `status` (assuming you're setting the `FileName` property to the `git.exe` full path. Also, if you want to pipe `StandardError` to your system, you need to set the `RedirectStandardError` property to true, as well as setting `UseShellExecute` to false. – Patrick Bell Jun 27 '16 at 21:52
  • @ext0 - Ok, not sure why it was locking up... but I got that figured out and it appears to work (with help from http://stackoverflow.com/a/16276776/5424295). The output window is behaving kinda weird... but maybe I can sort that out another time, assuming nothing bad is happening... – Code Stranger Jun 27 '16 at 21:59
  • Actually @ext0, still having issues after switching to log. I get the error `fatal: ambiguous argument '>': unknown revision or path not in the working tree.` when using `@"log > C:\users\me\desktop\log.txt"` as the `Arguments`. Any idea why? Please excuse my unfamiliarity with git here... – Code Stranger Jun 27 '16 at 22:02
  • @CodeStranger All good! Can I see the current code you are working with? – Patrick Bell Jun 27 '16 at 22:03
  • Thanks for the attempted edit DangerZone, but I can edit my own details. I think we are trying the same thing though... I've added the specific code and error I'm getting in the update above, @ext0 – Code Stranger Jun 28 '16 at 14:18
  • @CodeStranger Ill check it out on my lunch break. – Patrick Bell Jun 28 '16 at 14:20
  • @CodeStranger I would recommend not trying to pipe the output to that log directly, but take the StdOut of it and handle that programmatically. Now, it appears that your error is regarding the syntax of your `git` arguments. When I run `git log --no-pager`, I get an error indicating that `--no-pager` is not a valid flag. Why don't you try just `log` as the argument and see what StdOut gives you? – Patrick Bell Jun 28 '16 at 15:32
  • @ext0 - It seems to work... kind of. It only writes the first 5 lines of output (most recent commit ID, author, date, blank/newline, the message, and another blank/newline). Then the first `while` loop ends for some reason and it hangs indefinitely (as far as I can tell, before exiting) on the `while (process.StandardError.Peek() > -1)` line. – Code Stranger Jun 28 '16 at 15:53
  • @CodeStranger I really don't like that method of checking the input's and outputs. My recommendation would be to load them into streams, wait for process exit, and check the streams afterwards, to ensure you got all of the data, as it appears it is prematurely exiting because it believes the stream is done because the `Peak()` method doesn't return anything (but, in reality, `git.exe` just hasn't had time to shove data into the err or input streams yet). – Patrick Bell Jun 28 '16 at 15:56
  • I ended up finding this answer that seems to have solved the problem: http://stackoverflow.com/a/7608823/5424295 – Code Stranger Jun 28 '16 at 16:08

1 Answers1

1

Probably not the most beautiful way of doing this, but this line called from a windows .cmd file works for me:

cmd.exe /c start /d"c:\my\git\repo\dir" /b git.exe --no-pager log > log.txt
Alex Zhmerik
  • 365
  • 1
  • 10
  • Does this assume you have git.exe in your path? I tried replacing "git.exe" with the full path to the exe and got "Windows cannot find '--no-pager'.......". – Broots Waymb Jun 27 '16 at 21:19
  • Yeah, I'm not so sure either @DangerZone. If I **only** replace the repo path, it complains about git.exe, if I give it the full path to that, it complains about --no-pager. If I were able to get this to work, I'd happily accept it as an answer. – Code Stranger Jun 27 '16 at 21:24
  • Yes, it is in my path.You can also make the git path your current directory before calling this line. – Alex Zhmerik Jun 27 '16 at 21:30
  • @AlexJ - If I do that, I I get an "Access is denied" message. Not sure why. I would not be able to run this as an admin either. – Code Stranger Jun 27 '16 at 21:38
  • Access is denied to write log.txt to the root of c:. Set the whole path to the log file: e.g. cmd.exe /c start /d"c:\my\git\repo\dir" /b git.exe --no-pager log > u:\mylogs\log.txt – Alex Zhmerik Jun 27 '16 at 21:39
  • Ah, ok that makes perfect sense. I guess I assumed it would use the root of the git repo like it does in git-bash. Thank you! – Code Stranger Jun 27 '16 at 21:42