Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to make git auto generate a version number file for a --version option?

I have a project that is moving out of the alpha phase and that I'm ready to start releasing regularly. I know GitHub has a 'magic' release button but I generally don't like 'magic' features that I don't know exactly what they do:

https://github.com/blog/1547-release-your-software

As far as I can tell this 'magic' release feature on GitHub just creates a tag on the source repository for a certain state of the code or uses an existing tag. According to that link the tag names must reflect the semantic version number i.e. Major.Minor.Patch ex: v10.1.2 or some thing like that.

Generally the accepted Git way to do releases seems to be to simply create tags. What I'd like to do is for Git to automatically create some sort of file in my code tree named version.txt or version.h file that contains the name of the git tag I created so that this file can be automatically sourced when the user issues myporgram --version on the command line. Preferably I'd like an auto generated header file since this gets integrated into the binary when the program is built. Is there some way to do this automatically or do I have to automatically pipe the tag number into the file before I issue the git tag command?

like image 644
os x nerd Avatar asked Nov 02 '15 15:11

os x nerd


People also ask

How do I increment a version number in git?

Adding +semver: breaking or +semver: major will cause the major version to be increased, +semver: feature or +semver:minor will bump minor and +semver:patch or +semver:fix will bump the patch.

Which command is used to add a version number to your git repo?

By using tags: Tags in Git can be used to add a version number.

Can git be used for version control?

Git is an open source distributed version control system that helps software teams create projects of all sizes with efficiency, speed, and asynchronicity.

What is git semantic versioning?

Using semantic versioning in your project means being responsible for double-checking your version number before you release your code. As soon as your code is released into a production environment, you have to assume that somebody is using the code, and you should not change the version number.


2 Answers

See nice solution in here: https://coderwall.com/p/mk18zq/automatic-git-version-tagging-for-npm-modules

Basically do it the other way around. Create a text file or header file. Lets say: Version.h:

#define VERSION 10.1.2

And create post-commit hook which looks for changes in the file. To deploy: modify the version and commit the file. The hook will create a matching tag.

like image 125
Igal S. Avatar answered Oct 20 '22 07:10

Igal S.


I know this question is old, but I just came across it because I'm trying to do the same thing. The one other answer here shows how to create a new Git tag every time a version file changes, but I and the OP want to do the reverse: Update a code file to contain a new version number every time I create a new Git tag for a "release." Here's how I did it in my C++ project:

First, create a header file called, for example, include/myproj/git_version.hpp that defines some constants:

#pragma once
namespace myproject {
extern const int MAJOR_VERSION;
extern const int MINOR_VERSION;
extern const int PATCH_VERSION;
extern const int COMMITS_AHEAD_OF_VERSION;
extern const char* VERSION_STRING;
extern const char* VERSION_STRING_PLUS_COMMITS;
}

Second, create a pre-commit hook (.git/hooks/pre-commit) that generates the corresponding .cpp file defining the constants, using the output of git describe:

#!/bin/bash

version_regex='v([0-9]+)\.([0-9]+)\.?([0-9]*)-([0-9]+)-g([0-9|a-z]+)'
git_string=$(git describe --tags --long)

if [[ $git_string =~ $version_regex ]]; then
    major_version="${BASH_REMATCH[1]}"
    minor_version="${BASH_REMATCH[2]}"
    patch_version="${BASH_REMATCH[3]}"
    commits_ahead="${BASH_REMATCH[4]}"
else
    echo "Error: git describe did not output a valid version string. Unable to update git_version.cpp" >&2
    exit 1
fi

version_num="${major_version}.${minor_version}.${patch_version}"
version_num_plus_commits="${version_num}+${commits_ahead}"

# Working directory of a git hook is always the root of the repo
cat > $(pwd)/src/git_version.cpp <<EOM
#include <myproject/git_version.hpp>

namespace myproject {
const int MAJOR_VERSION = $major_version;
const int MINOR_VERSION = $minor_version;
const int PATCH_VERSION = $patch_version;
const int COMMITS_AHEAD_OF_VERSION = $commits_ahead;
const char* VERSION_STRING = "${version_num}";
const char* VERSION_STRING_PLUS_COMMITS = "${version_num_plus_commits}";
}
EOM

git add $(pwd)/src/git_version.cpp

Note that the updated version of the git_constants.cpp file will be included as part of the commit, so any commit based on a new tag will also include a constants file reflecting the version in that tag.

This isn't perfect, because it requires you to create a new commit to update the constants file even if all you want to do is create a new tag (which otherwise wouldn't require a new commit). On the other hand, it does allow your in-code version number to track the number of commits, which is more fine-grained than the tagged versions alone.

like image 35
Edward Avatar answered Oct 20 '22 07:10

Edward