As I moved from Mercurial to Git I got hit with annoying problem. You see, in mercurial it is trivial to get commit number and commit hash. All you need is:
FOR /F "delims=" %%N IN ('hg id -i 2^> NUL') DO @SET HG_NODE=%%N% FOR /F "delims=+" %%N IN ('hg id -n 2^> NUL') DO @SET HG_NODE_NUMBER=%%N%
Yes, it is not the most beautiful code but it does get the job done. With
-i parameter we get hash and
-n is what gives us commit number. And commit number is so useful for automated builds. Yes, hash will uniquely identify the build but humans tend to work better with numbers – e.g.
setup-53-1d294c0f2737.exe is much better than
setup-1d294c0f2737.exe alone. If numbers are there it becomes trivial to determine what is the latest build.
Mercurial has also one more trick in its sleeve. If changes are not committed yet, it will add small plus sign to its output, e.g.
setup-53-1d294c0f2737+.exe. Now with one glance in a full directory you can determine order in which builds were done, what branch are they on, and if all changes were committed at the time of build.
How do you do the same in Git?
Getting revision number is trivial. Just ask git to count them all:
FOR /F "delims=" %%N IN ('git rev-list --count HEAD') DO @SET VERSION_NUMBER=%%N%
Getting hash is similarly easy:
FOR /F "delims=" %%N IN ('git log -n 1 --format^=%%h') DO @SET VERSION_HASH=%%N%
But there is one problem here. Hash is exactly the same whether all changes are committed or not, i.e. there is no plus sign if there are some uncommitted changes during build. And I believe such indication is crucial for any automated build environment. Fortunately Git will give you wanted information with a bit effort:
git diff --exit-code --quiet IF ERRORLEVEL 1 SET VERSION_HASH=%VERSION_HASH%+
So final code to get Git hash and commit number equivalent to what I had in Mercurial was:
FOR /F "delims=" %%N IN ('git log -n 1 --format^=%%h') DO @SET VERSION_HASH=%%N% git diff --exit-code --quiet IF ERRORLEVEL 1 SET VERSION_HASH=%VERSION_HASH%+