├── VERSION ├── post-commit ├── post-merge ├── bump └── README.md /VERSION: -------------------------------------------------------------------------------- 1 | 0.1.0-SNAPSHOT 2 | -------------------------------------------------------------------------------- /post-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ "$_BUMP" != "1" ] 3 | then 4 | bump -p 5 | export _BUMP=1 6 | git commit VERSION -m "[auto] bumped version to $(cat VERSION)" 7 | fi 8 | -------------------------------------------------------------------------------- /post-merge: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ "$_BUMP" != "1" ] 3 | then 4 | branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,') 5 | if [ branch == "master" ] 6 | then 7 | bump -m 8 | else 9 | bump -n 10 | fi 11 | 12 | export _BUMP=1 13 | git commit VERSION -m "[auto] bumped version to $(cat VERSION)" 14 | fi 15 | -------------------------------------------------------------------------------- /bump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | """ 4 | A quick and dirty SemVer bump script. 5 | """ 6 | 7 | from __future__ import print_function 8 | 9 | import argparse 10 | from collections import namedtuple 11 | import re 12 | import sys 13 | 14 | parser = argparse.ArgumentParser(description=__doc__) 15 | group = parser.add_mutually_exclusive_group(required=True) 16 | group.add_argument("-m", "--major", action="store_true", default=False, help="Bump the major part.") 17 | group.add_argument("-n", "--minor", action="store_true", default=False, help="Bump the minor part.") 18 | group.add_argument("-p", "--patch", action="store_true", default=False, help="Bump the patch part.") 19 | 20 | 21 | class Version(namedtuple('Version', ['major', 'minor', 'patch'])): 22 | 23 | def bump_patch(self): 24 | return Version(self.major, self.minor, self.patch + 1) 25 | 26 | def bump_minor(self): 27 | return Version(self.major, self.minor + 1, 0) 28 | 29 | def bump_major(self): 30 | return Version(self.major + 1, 0, 0) 31 | 32 | def __str__(self): 33 | return "{0}.{1}.{2}".format(self.major, self.minor, self.patch) 34 | 35 | __INITIAL__ = Version(0, 0, 0) 36 | 37 | 38 | def main(opts): 39 | v = None 40 | try: 41 | with open("VERSION") as f: 42 | v = re.split(re.compile("\\.|-"), f.read()) or __INITIAL__ 43 | v = Version(*map(int, v[0:3])) 44 | 45 | except ValueError: 46 | print("failed to parse the existing VERSION file, assuming v0.0.0") 47 | v = __INITIAL__ 48 | 49 | except IOError: 50 | print("failed to find a VERSION file, assuming v0.0.0") 51 | v = __INITIAL__ 52 | 53 | if opts.major: 54 | v = v.bump_major() 55 | 56 | elif opts.minor: 57 | v = v.bump_minor() 58 | 59 | elif opts.patch: 60 | v = v.bump_patch() 61 | 62 | print(v) 63 | 64 | open("VERSION", 'w').write(str(v)) 65 | 66 | sys.exit(0) 67 | 68 | 69 | if __name__ == "__main__": 70 | main(parser.parse_args()) 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Git Bump 2 | Version numbers are an amazing thing. They make it trivial to figure out whether 3 | or not a program is at the most recent version, and there are even some 4 | relatively sane standards such as [semantic versioning](http://semver.org) which the 5 | Clojure community has adopted as the standard format for version numbers. 6 | 7 | As a [git flow](http://nvie.com/posts/a-successful-git-branching-model/) adherent, while my branching strategy may be elegant I often 8 | find that I neglect my version number bumping. This repo represents one lazy 9 | evening's solution thereto: a VERSION file bump script in Python and a pair of 10 | git-hooks scripts which leverage that file to generate auto-commits that bump 11 | the version file so you don't have to. 12 | 13 | ## Behavior 14 | This setup uses two hooks - the `post-commit` hook and the `post-merge` hook. 15 | 16 | - post-commit - "patch" bump (+ 0.0.1) 17 | - post-merge - "minor" bump (+ 0.1.0) when merging to non-master branches 18 | - post-merge - "major" bump (+ 1.0.0) when merging to "master" 19 | 20 | The idea clearly being that, when combined with git flow, the result will be a 21 | sane and strictly increasing version number indicative of the state of the 22 | project. 23 | 24 | ## Installation 25 | The file `bump.py` must be located on your path.. I use `~/bin`. The files 26 | `post-merge` and `post-commit` must be added to the `.git/hooks` folder of any 27 | and all repos which use this strategy. 28 | 29 | ## Drawbacks 30 | First of all, this tool will at present generate a boatload of auto-commits as 31 | for every commit it will add a subsequent `[auto]` commit that increments the 32 | patch number. Second of all, the version number is a naive counter in the 33 | extreme and is quite likely to encounter conflicts and collisions between banches. 34 | 35 | This will be mitigated by the fact that merges will generate an `[auto]` with a 36 | minor version bump so under git-flow the MASTER branch will step by 1.0.0 once 37 | conflicts with minor and patch version numbers are resolved. The DEVELOP branch 38 | will step by 0.1.0, again because conflicts with the patch number will be 39 | squashed when merging into the development branch, and finally the individual 40 | FEATURE branches will walk by 0.0.1 blithely independant of one-another. 41 | 42 | So basically it may fill your repo with junk, but it'll be useful junk. 43 | 44 | ## License 45 | Copyright Reid McKenzie 2012, made available under the 46 | [WTFPBL](http://sam.zoy.org/wtfpl/) for your enjoyment. 47 | --------------------------------------------------------------------------------