Having a software project with a compiled programming language there is a problem having the executable file to determine from what source codes it was assembled. In this article, we describe how to automate the addition of a commit to executable files and how to get the source code from it later.
In general, git is a repository of objects. Objects in git come in 4 types:
- blob - to store data.
- tree - to store links to blob and other trees.
- commit - to point to a specific tree object, i.e. labeling a snapshot of a project at a specific point in time.
- tag - for marking commit, as some version of the project.
Any object can be accessed by its “object name” - a set of 40 numbers and letters (hexadecimal representation), which is the SHA1 data of this object. Thus, the state of the project source codes in the GIT can be described by the “object name” of a commit or simply by a commit. You can get the current commit in one line and with a comment to it using the following command:
git log --pretty=oneline -n1
Now you just need to add it to the executable files and display it to the user, for example, when you start the program with the --version parameter.
You can automate this process with the help of hooks — user actions that will be performed when certain operations are performed by git. There are
various hooks , but we will only need a post-commit (called after processing git commit), post-checkout (called after processing git checkout) and post-merge (called after processing git merge, which is called including with git pull) . Hooks are executable files that are located in the $ GIT_DIR / hooks directory.
In order for the hooks to be in the git repository, it is convenient to create a git_hooks folder and make a symlink on $ GIT_DIR / hooks. Create 3 post-commit, post-checkout, post-merge files with the same content in this directory. For example, we use the C / C ++ project and want to store the commit as a string in the header file, then these files will look like this:
')
Now you can insert the following code in the project, which will display the version of the commit.
#include git_commit.h … printf("Git commit: %s\n", git_commit_str);
Each time git commit, git checkout, git pull is called (if the local version is different from the remote one), the git_commit.h file will be overwritten and the project will need to be rebuilt in order for the commit to be displayed. Later, having an executable file, you can get the source code of this file using git checkout COMMIT or view the source code in a web browser if you use github at
github.com/USER/PROJECT/tree/COMMIT .
By the way, in SVN the same operation can be done in a similar way. In SVN, the status of project source codes is described using the global revision number, which can be obtained using the svnversion command, and hooks can be hung on post-commit and post-revprop-change events.