Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expanding Git SHA1 information into a checkin without archiving?

Is there a way to include git commit hashes inside a file everytime I commit? I can only find out how to do this during archiving but I haven't been able to find out how to do this for every commit.

I'm doing scientific programming with git as revision control, so this kind of functionality would be very helpful for reproducibility reasons (i.e., have the git hash automatically included in all result files and figures).

like image 786
Tim Lin Avatar asked May 17 '10 22:05

Tim Lin


2 Answers

You can easily put SHA-1 of file (to be more exact SHA-1 of blob, i.e. SHA-1 of contents of the file) by using $Id$ keywork and ident gitattribute.

If you want to put SHA-1 of commit, there is no out-of-the-box solution, but you can use clean and smudge commands of filter gitattribute. Note that would badly affect performance, as after commit each file would have to be modified to reflect new commit made.


Although as said in other answers to this question, you would do better on embedding version number in generated files when building, like e.g. Linux kernel and git project itself do it.

like image 130
Jakub Narębski Avatar answered Sep 22 '22 01:09

Jakub Narębski


Greg explained in his answer why this would be impossible

  • Git is a content VCS (versus a revision control or a VCS)
  • the SHA1 key represent the content
  • it cannot be part of the content
    Actually, as mentioned by Jakub Narębski in his answer, you can add the SHA-1 of the blob (content) itself (see git attributes)
    As mentioned in the question "To put the prefix ?<revision-number> to codes by Git/Svn", Git has no "keyword expansion" mechanism.

ident

When the attribute ident is set for a path, git replaces $Id$ in the blob object with $Id:, followed by the 40-character hexadecimal blob object name, followed by a dollar sign $ upon checkout.
Any byte sequence that begins with $Id: and ends with $ in the worktree file is replaced with $Id$ upon check-in.

That means the usual workaround is, through some kind of build process, to include the information you need in a versioned but separate file.
In your case, a file with the list of all other files and their SHA1 value.
Such files might be generated at each commit (amending the commit which just took place) for instance.


As an example of a separate file, Jefromi points out the VERSION file of Git itself, build by this script

elif test -d .git -o -f .git &&
         VN=$(git describe --match "v[0-9]*" --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-dirty" ;;
         esac
then
like image 35
VonC Avatar answered Sep 20 '22 01:09

VonC