Search code examples
windowsgitbatch-fileescaping

Capturing git commit date (--format=%ci) in a Windows batch file?


Currently, for my C++ projects, I run a pre-compile operation that writes a separate header file that captures the git hash of the build, effectively giving me the ability to see exactly which commit any instance of a program is running from as it's running.

So far something like this works:

set file="%~dp0git_sha1.h"
echo #ifndef git_sha1H > %file%
echo #define git_sha1H >> %file%

set cmd=git rev-parse HEAD
set git_sha1=#define GIT_SHA1
for /f %%i in ('%cmd%') do set "git_sha1=%git_sha1% "%%i""
echo %git_sha1% >> %file%

echo #endif >> %file%

Now I'm attempting to add the HEAD's commit date which would be done with: git show -s --format=%ci HEAD

However, when duplicating the middle section to accommodate this command I run into all sorts of errors like fatal: ambiguous argument 'ci': unknown revision or path not in the working tree, unknown pretty format 'ci', etc.

I narrowed this down to unescaped characters in the for-loop and came up with something like this

set cmd2=git show -s --format^=%%ci HEAD
set git_date=#define GIT_DATE
for /f %%i in ('%cmd2%') do set "git_date=%git_date% "%%i""
echo %git_date% >> %file%

However, this STILL gives me fatal: ambiguous argument '%ci: unknown revision or path not in the working tree.

I read this as the escaped ^= is not being properly passed into git so that it's seeing --format %ci HEAD rather than --format=%ci HEAD, but I'm not entirely sure where I'm off here, especially when a separate echo %cmd2% debug line does show the correct command.

Any ideas?


Solution

  • Here's how I'd suggest you write your code, to appropriately use doublequotes and to write out to your .h file:

    @Echo Off
    Set "file=%~dp0git_sha1.h"
    Set "cmd=git rev-parse HEAD"
    Set "git_sha1=#define GIT_SHA1"
    Set "cmd2=git show -s --format=%%ci HEAD"
    Set "git_date=#define GIT_DATE"
    For /F "Delims=" %%A In ('%cmd%')Do Set "git_sha1=%git_sha1% "%%A""
    For /F "Delims=" %%A In ('%cmd2%')Do Set "git_date=%git_date% "%%A""
    
    (Echo #ifndef git_sha1H
        Echo #define git_sha1H
        Echo %git_sha1%
        Echo %git_date%
        Echo #endif)>"%file%"
    

    Please note that I've just added your %cmd2% output before the #endif in your output file.