user20693: Is there any way to get the current Git tag/commit identifier into an Arduino sketch binary?
For normal desktop program development, you can pull some tricks with the Makefile (as pointed out in this StackExchange answer). However, there is no Makefile for an Arduino sketch. Right?
I could make a batch file that I run before every compile, but there is the very real possibility I will forget to run it, and incorrect version information is worse than no version information.
At the moment, I am using the preprocessor macros __DATE__ and __TIME__ to try and identify what version is running on the board. This works, but tracking backwards from a compile date/time to a source control commit is more guesswork than anything.

user10794: I'm not sure what the commit ID would prove. I use git for source control for my Arduino sketches, but a particular upload might be halfway between the previous commit and the next one. That is, the code on the board might not match any particular commit.
The date/time would at least identify approximately where in the commit stream the code is. 
A possibility would be to run a cron job that periodically (say, every minute) updates a .h file with the current commit ID from the branch, and include that in the sketch.

user40024: Inspired by Edgar's Bash script, I wrote a Windows Batch script do almost the same in adition to copying HEX file from the temp build directory to the project directory and insert commit hash, date, branch name and tag to it's name. I wrote a short article on how to use GIT to manage firmware versions.
:: How to use:
:: Add this file to you Arduino project directory and add the following line to platform.txt from Arduino core files
:: recipe.hooks.sketch.prebuild.1.pattern = {build.source.path}\fw_ver.bat GIT {build.path} {build.source.path}
:: recipe.hooks.objcopy.postobjcopy.2.pattern = {build.source.path}\fw_ver.bat SAVE {build.path} {build.source.path}

@echo off

:: arg1 -> "GIT" print version, commit number, brnach name and commit date , "SAVE" copy the .hex file from temp build directory to project directory
set arg1=%1
:: arg2 -> path to temp build directory
set arg2=%2
:: arg3 -> path to project source files
set arg3=%3

cd %arg3%

FOR /F "tokens=* USEBACKQ" %%F IN (`git describe --match^=NeVeRmAtCh --always --abbrev^=7`) DO (
SET commit=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`git show -s --format^=%%cd --date^=format:%%y_%%m_%%d %commit%`) DO (
SET date=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`git rev-parse --abbrev-ref HEAD`) DO (
SET branch=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`git describe --abbrev^=0`) DO (
SET ver=%%F
)
::Export to version.h
ECHO #define FW_VER "%ver%" > version.h
ECHO #define COMMIT_NUMBER "%commit%" >> version.h
ECHO #define COMMIT_DATE "%date%" >> version.h
ECHO #define COMMIT_BRANCH "%branch%" >> version.h

IF "%arg1%"=="GIT" (
@echo on
@echo version:%ver% Commit:%commit% Branch:%branch% Date:%date% 
@echo off
)
IF "%arg1%"=="SAVE" (
@echo on
@echo Save fw_%ver%_%branch%_%date%_%commit%.hex to %arg3%
COPY "%arg2%\fw.ino.hex" "fw_%ver%_%branch%_%date%_%commit%.hex"
)


user7508: Inspired by Cellie's answer, I investigated further and found a similar
method that can be implemented using the regular interface of the
Arduino IDE.
It appears that GitHub user Wackerbarth, while facing the very same
problem, opened an issue on the Arduino bug tracker:

It would be very useful to be able to add a recipe to the platform
  specification that is executed at the start of the build process.
  (pre-build)
In particular, my use case is to generate version strings which will
  be incorporated in the Rom image based on information extracted from a
  SCM repository.

He went on to submit a pull request for adding “hooks” to the
build process, which made it to release 1.6.2. See the documentation on
these Pre and post build hooks.
Here is how you can use this feature for including git commit
information into your program (tested on Arduino 1.8.5 / Ubuntu 16.04):

Save the following file under the name make-git-version, somewhere
in your PATH, and make it executable:

#!/bin/bash

# Go to the source directory.
[ -n "$1" ] && cd "$1" || exit 1

# Build a version string with git.
version=$(git describe --tags --always --dirty 2> /dev/null)

# If this is not a git repository, fallback to the compilation date.
[ -n "$version" ] || version=$(date -I)

# Save this in git-version.h.
echo "#define GIT_VERSION \"$version\"" > $2/sketch/git-version.h


Locate the file named platform.txt in the Arduino installation
directory (currently in arduino-1.8.5/hardware/arduino/avr for the
AVR boards). In the same directory, create a file named
platform.local.txt with the following content:

recipe.hooks.sketch.prebuild.1.pattern=make-git-version "{build.source.path}" "{build.path}"


In your sketch, include "git-version.h" and use it like so:

#include "git-version.h"

void setup() {
  Serial.begin(9600);
  Serial.println("This is version " GIT_VERSION);
}


Create an empty file in your sketch directory named git-version.h.

Note that the git-version.h in the current directory is only needed
for the first compilation. The real git-version.h will be in the
temporary build directory.

user50500: If you're using Platformio, add this in platformio.ini file
build_flags = 
    !echo '-D GIT_VERSION=\\"'$(git rev-parse HEAD)'\\"'

And use it like this:
Serial.printf("Firmware version: %s\n", GIT_VERSION);

Check out relevant docs:
http://docs.platformio.org/en/latest/projectconf/section_env_build.html#dynamic-build-flags

user63711: I met the same problem and based on the previous answers I wrote this script for Arduino IDE. I'm using it successfully on different OSs for many months to now. In the repository, you can find the instructions to install it.

user45394: I struggled with Arduino (ESP32) versioning also.
To make it somewhat more practical and less error prone I made some scripts to assist this process.
Using these scripts is as easy as adding them to your sketch folder and adding
#include "gitTagVersion.h"
...
Serial.println( sketchVersion );

to your Arduino sketch.
That is all that is needed.
The output in the example above will be something like v1.0.0-3-gab3fb04.
That breaks down to tag v1.0.0, we had 3 commits since that tag, at commit ab3fb04.
HOW TO INSTALL AND USE?
There are 2 scripts involved, the first script is a replacement for the Arduino  Verify button.
Save it as verify.sh:
echo "const char * sketchVersion = \"$(git describe --tags --always --dirty)\";" > gitTagVersion.h
~/arduino-1.8.5/arduino --verify test.ino
rm gitTagVersion.h

And the second script replaces the Upload button.
Save it as upload.sh:
echo "const char * sketchVersion = \"$(git describe --tags --always --dirty)\";" > gitTagVersion.h
~/arduino-1.8.5/arduino --upload test.ino --pref custom_DebugLevel=esp32_none
rm gitTagVersion.h

Some things to note about these scripts:

The scripts REPLACE the buttons.
You won’t be able to use the buttons anymore, as these buttons don’t
generate the necessary version info from git.
Using them will result in this error:

fatal error: gitTagVersion.h:    No such file or directory

The scripts are hardcoded to use Arduino 1.8.5 and have to be updated
if you update your Arduino IDE.
These script only work in Linux with a vanilla Arduino install.
If you use Windows, or are on a Mac the scripts will not work.
To change the debug output (using the LOGx_ESP macros) on ESP32
builds, change the custom_DebugLevel in the Upload script to
esp32_xxxx, where xxxx is none, info, error, debug or verbose.

I posted this also on my blog and esp32.com

20693: <p>Is there any way to get the current Git tag/commit identifier into an Arduino sketch binary?</p>

<p>For normal desktop program development, you can pull some tricks with the Makefile (as pointed out in <a href="https://stackoverflow.com/a/6526504/1480315">this StackExchange answer</a>). However, there is no Makefile for an Arduino sketch. Right?</p>

<p>I could make a batch file that I run before every compile, but there is the very real possibility I will forget to run it, and incorrect version information is worse than no version information.</p>

<p>At the moment, I am using the preprocessor macros <code>__DATE__</code> and <code>__TIME__</code> to try and identify what version is running on the board. This works, but tracking backwards from a compile date/time to a source control commit is more guesswork than anything.</p>
 10794: <p>I'm not sure what the commit ID would prove. I use git for source control for my Arduino sketches, but a particular upload might be halfway between the previous commit and the next one. That is, the code on the board might not match any particular commit.</p>

<p>The date/time would at least identify approximately where in the commit stream the code is. </p>

<p>A possibility would be to run a cron job that periodically (say, every minute) updates a .h file with the current commit ID from the branch, and include that in the sketch.</p>
 40024: <p>Inspired by Edgar's Bash script, I wrote a Windows <strong>Batch</strong> script do almost the same in adition to copying HEX file from the temp build directory to the project directory and insert commit hash, date, branch name and tag to it's name. I wrote a short article on <a href="https://atadiat.com/en/e-how-to-use-git-to-manage-firmware-versions/" rel="nofollow noreferrer">how to use GIT to manage firmware versions</a>.</p>

<pre><code>:: How to use:
:: Add this file to you Arduino project directory and add the following line to platform.txt from Arduino core files
:: recipe.hooks.sketch.prebuild.1.pattern = {build.source.path}\fw_ver.bat GIT {build.path} {build.source.path}
:: recipe.hooks.objcopy.postobjcopy.2.pattern = {build.source.path}\fw_ver.bat SAVE {build.path} {build.source.path}

@echo off

:: arg1 -&gt; "GIT" print version, commit number, brnach name and commit date , "SAVE" copy the .hex file from temp build directory to project directory
set arg1=%1
:: arg2 -&gt; path to temp build directory
set arg2=%2
:: arg3 -&gt; path to project source files
set arg3=%3

cd %arg3%

FOR /F "tokens=* USEBACKQ" %%F IN (`git describe --match^=NeVeRmAtCh --always --abbrev^=7`) DO (
SET commit=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`git show -s --format^=%%cd --date^=format:%%y_%%m_%%d %commit%`) DO (
SET date=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`git rev-parse --abbrev-ref HEAD`) DO (
SET branch=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`git describe --abbrev^=0`) DO (
SET ver=%%F
)
::Export to version.h
ECHO #define FW_VER "%ver%" &gt; version.h
ECHO #define COMMIT_NUMBER "%commit%" &gt;&gt; version.h
ECHO #define COMMIT_DATE "%date%" &gt;&gt; version.h
ECHO #define COMMIT_BRANCH "%branch%" &gt;&gt; version.h

IF "%arg1%"=="GIT" (
@echo on
@echo version:%ver% Commit:%commit% Branch:%branch% Date:%date% 
@echo off
)
IF "%arg1%"=="SAVE" (
@echo on
@echo Save fw_%ver%_%branch%_%date%_%commit%.hex to %arg3%
COPY "%arg2%\fw.ino.hex" "fw_%ver%_%branch%_%date%_%commit%.hex"
)
</code></pre>
 7508: <p>Inspired by Cellie's answer, I investigated further and found a similar
method that can be implemented using the regular interface of the
Arduino IDE.</p>

<p>It appears that GitHub user Wackerbarth, while facing the very same
problem, opened <a href="https://github.com/arduino/Arduino/issues/2732" rel="nofollow noreferrer">an issue on the Arduino bug tracker</a>:</p>

<blockquote>
  <p>It would be very useful to be able to add a recipe to the platform
  specification that is executed at the start of the build process.
  (pre-build)</p>
  
  <p>In particular, my use case is to generate version strings which will
  be incorporated in the Rom image based on information extracted from a
  SCM repository.</p>
</blockquote>

<p>He went on to submit <a href="https://github.com/arduino/Arduino/pull/2738" rel="nofollow noreferrer">a pull request</a> for adding “hooks” to the
build process, which made it to release 1.6.2. See the documentation on
these <a href="https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification#pre-and-post-build-hooks-since-ide-165" rel="nofollow noreferrer">Pre and post build hooks</a>.</p>

<p>Here is how you can use this feature for including git commit
information into your program (tested on Arduino 1.8.5 / Ubuntu 16.04):</p>

<ol>
<li>Save the following file under the name <code>make-git-version</code>, somewhere
in your <code>PATH</code>, and make it executable:</li>
</ol>

<pre class="lang-sh prettyprint-override"><code>#!/bin/bash

# Go to the source directory.
[ -n "$1" ] &amp;&amp; cd "$1" || exit 1

# Build a version string with git.
version=$(git describe --tags --always --dirty 2&gt; /dev/null)

# If this is not a git repository, fallback to the compilation date.
[ -n "$version" ] || version=$(date -I)

# Save this in git-version.h.
echo "#define GIT_VERSION \"$version\"" &gt; $2/sketch/git-version.h
</code></pre>

<ol start="2">
<li>Locate the file named <code>platform.txt</code> in the Arduino installation
directory (currently in <code>arduino-1.8.5/hardware/arduino/avr</code> for the
AVR boards). In the same directory, create a file named
<code>platform.local.txt</code> with the following content:</li>
</ol>

<pre class="lang-none prettyprint-override"><code>recipe.hooks.sketch.prebuild.1.pattern=make-git-version "{build.source.path}" "{build.path}"
</code></pre>

<ol start="3">
<li>In your sketch, include <code>"git-version.h"</code> and use it like so:</li>
</ol>

<pre class="lang-c++ prettyprint-override"><code>#include "git-version.h"

void setup() {
  Serial.begin(9600);
  Serial.println("This is version " GIT_VERSION);
}
</code></pre>

<ol start="4">
<li>Create an empty file in your sketch directory named <code>git-version.h</code>.</li>
</ol>

<p>Note that the <code>git-version.h</code> in the current directory is only needed
for the first compilation. The real <code>git-version.h</code> will be in the
temporary build directory.</p>
 50500: <p>If you're using Platformio, add this in platformio.ini file</p>

<pre><code>build_flags = 
    !echo '-D GIT_VERSION=\\"'$(git rev-parse HEAD)'\\"'
</code></pre>

<p>And use it like this:</p>

<pre><code>Serial.printf("Firmware version: %s\n", GIT_VERSION);
</code></pre>

<p>Check out relevant docs:
<a href="http://docs.platformio.org/en/latest/projectconf/section_env_build.html#dynamic-build-flags" rel="nofollow noreferrer">http://docs.platformio.org/en/latest/projectconf/section_env_build.html#dynamic-build-flags</a></p>
 63711: <p>I met the same problem and based on the previous answers I wrote this <a href="https://github.com/fabiuz7/git-describe-arduino" rel="nofollow noreferrer">script</a> for Arduino IDE. I'm using it successfully on different OSs for many months to now. In the repository, you can find the instructions to install it.</p>
 45394: <p>I struggled with Arduino (ESP32) versioning also.
To make it somewhat more practical and less error prone I made some scripts to assist this process.</p>

<p>Using these scripts is as easy as adding them to your sketch folder and adding</p>

<pre><code>#include "gitTagVersion.h"
...
Serial.println( sketchVersion );
</code></pre>

<p>to your Arduino sketch.
That is all that is needed.</p>

<p>The output in the example above will be something like v1.0.0-3-gab3fb04.
<br>That breaks down to tag <code>v1.0.0</code>, we had <code>3</code> commits since that tag, at commit <code>ab3fb04</code>.</p>

<p>HOW TO INSTALL AND USE?</p>

<p>There are 2 scripts involved, the first script is a replacement for the Arduino  Verify button.
Save it as verify.sh:</p>

<pre><code>echo "const char * sketchVersion = \"$(git describe --tags --always --dirty)\";" &gt; gitTagVersion.h
~/arduino-1.8.5/arduino --verify test.ino
rm gitTagVersion.h
</code></pre>

<p>And the second script replaces the Upload button.
Save it as upload.sh:</p>

<pre><code>echo "const char * sketchVersion = \"$(git describe --tags --always --dirty)\";" &gt; gitTagVersion.h
~/arduino-1.8.5/arduino --upload test.ino --pref custom_DebugLevel=esp32_none
rm gitTagVersion.h
</code></pre>

<p>Some things to note about these scripts:</p>

<ul>
<li><p>The scripts REPLACE the buttons.
You won’t be able to use the buttons anymore, as these buttons don’t
generate the necessary version info from git.</p>

<p>Using them will result in this error:</p>

<blockquote>
  <p>fatal error: gitTagVersion.h:    No such file or directory</p>
</blockquote></li>
<li><p>The scripts are hardcoded to use Arduino 1.8.5 and have to be updated
if you update your Arduino IDE.</p></li>
<li><p>These script only work in Linux with a vanilla Arduino install.</p></li>
<li><p>If you use Windows, or are on a Mac the scripts will not work.</p></li>
<li><p>To change the debug output (using the LOGx_ESP macros) on ESP32
builds, change the custom_DebugLevel in the Upload script to
esp32_xxxx, where xxxx is none, info, error, debug or verbose.</p></li>
</ul>

<p>I posted this also on my <a href="http://wasietsmet.nl/arduino/add-git-tag-and-version-number-to-an-arduino-sketch/" rel="nofollow noreferrer">blog</a> and <a href="https://esp32.com/viewtopic.php?f=19&amp;t=5213" rel="nofollow noreferrer">esp32.com</a></p>
