Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would you include the current commit id in a Git project's files?

Tags:

git

I've got an open source static JavaScript + HTML application that's deployed in about three different places right now, one on my local machine, one on an internal server, and one on a stable external server.

I'd like to be able to tell immediately which version is deployed in which place, and I'd like bug reporters to have easy access to the version that they're reporting the bug on.

Ideally I'd like, as part of the commit process, for a file to be written with the hash of the commit. Of course, from what I know of Git this is impossible, as including the calculated hash as part of a file in a commit would change the calculated hash of that commit.

On the other hand, I could incorporate building this as part of a build process. I don't currently have a build process though, and I'd like to avoid adding a step if possible.

What's the cleanest way to do this?

like image 611
Peter Burns Avatar asked Feb 05 '09 01:02

Peter Burns


People also ask

How do I find my current commit ID?

Viewing a list of the latest commits. If you want to see what's happened recently in your project, you can use git log . This command will output a list of the latest commits in chronological order, with the latest commit first.

What is the commit ID in git?

Commit IDs are unique SHA-1 hashes that are created whenever a new commit is recorded. If you specify a commit ID when you add a repository, Domino will always pull the state of the repository specified by that commit in a detached HEAD state.

Where is git commit ID stored?

All git database is stored in . git/objects directory. You can find the commit in there. Just split the first two letters of commit SHA and look for a directory of that name.


1 Answers

There are some subtleties to this because of the nature of Git. The way I've done this is by copying what the Git developers themselves do. First, you'll want to use annotated tags which is probably a good idea anyway. To review, you can create a new tag like this:

$ git tag -a -m "Version 0.2" v0.2 HEAD

Then (as suggested in Otto's post) you can use git describe for a useful "version" string that will include the number of commits since the tag and the leading digits of the sha1 of the the current commit. Here's an example from one of my projects:

$ git describe
v1.0-3-gee47184

That is, this copy is 3 commits ahead of the "v1.0" tag and the commit sha1 begins with ee47184 (I'm not sure why they include that leading 'g').

The Git developers take it one step further and also include an extra bit if the working copy is modified (uncommitted). This requires a few more steps so it's all wrapped up in a script they name VERSION-GEN. When run, it prints the version string to standard output and also creates a VERSION-FILE file (the script is careful to not re-touch that file if the version hasn't changed -- so it's build-tool friendly). Then, you can include that VERSION-FILE file in your source code, help files, etc.

Using my example VERSION-GEN script (below), my version string for the above example is:

$ VERSION-GEN
version: 1.0-3-gee47

If I modify any of the tracked files it looks like this:

$ VERSION-GEN
version: 1.0-3-gee47-mod

Here's my slightly tweaked version of VERSION-GEN. Note that it expects that the tags marking versions are of the form v[0-9]* (e.g., v1.0 or v0.2 or v12.3.4 or v12.2-4feb2009 etc.)

#!/bin/sh

# Tag revisions like this:
# $ git tag -a -m "Version 0.2" v0.2 HEAD

VF=VERSION-FILE
DEFAULT_VERSION=UKNOWN

LF='
'

# First see if there is a version file (included in release tarballs),
# then try git-describe, then default.
if test -d .git -o -f .git &&
    VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
    case "$VN" in
    *$LF*) (exit 1) ;;
    v[0-9]*)
        git update-index -q --refresh
        test -z "$(git diff-index --name-only HEAD --)" ||
        VN="$VN-mod" ;;
    esac
then
        continue
    #VN=$(echo "$VN" | sed -e 's/-/./g');
else
    VN="$DEFAULT_VERSION"
fi

VN=$(expr "$VN" : v*'\(.*\)')

# Show the version to the user via stderr
echo >&2 "version: $VN"

# Parse the existing VERSION-FILE 
if test -r $VF
then
    VC=$(sed -e 's/^version: //' <$VF)
else
    VC=unset
fi

# If version has changed, update VERSION-FILE
test "$VN" = "$VC" || {
    echo "version: $VN" >$VF
    echo >&2 "($VF updated)"
}
like image 183
Pat Notz Avatar answered Oct 20 '22 02:10

Pat Notz