Showing posts with label svn. Show all posts
Showing posts with label svn. Show all posts

11 March, 2011

numbering commits

svn gives each commit a unique number. mercurial does somethign similar. CVS doesn't. git has commit IDs btu they are big and dont' have an intrinsic order (if you dehash two commit IDs you can figure out relative order but its not apparent from the IDs themselves)

I'm interested in numbering the commits on a git branch that is imported from CVS, so there's a well defined linear order (unlike in git in general).

I hacked together this script:

#!/bin/bash

COMMITCOUNT=$( git rev-list origin | wc -l)

echo There are $COMMITCOUNT commits on the origin branch

# this strips whitespace
export COUNT=$(($COMMITCOUNT))

git rev-list origin | while read commitid ; do
  echo numbering $commitid as $COUNT
  TAG=cvs$COUNT
  git tag $TAG $commitid
  COUNT=$(( $COUNT -1))
done

which works like this:

$ ./number-cvs 
There are 205 commits on the origin branch
numbering fea9db3bc7b3e36f82a97d3bb194eb60ecb3b57f as 205
numbering aedbfe81cc1dbf3d6f833225aa41826854398a3c as 204
numbering f040d23565211acb637d3325d240d675fe1e61a6 as 203
numbering eef4a46ce30de2836402a373e8eae49fc1b75935 as 202
numbering 2bb5b931be9beb0d90a2796b85585149465f8fc3 as 201
numbering a4372569c60bcb6d92a63b258389b5f1a210dd40 as 200
fatal: tag 'cvs200' already exists
numbering bbd6af71ef17fcb05a9cf86a372837dcf470e30b as 199
fatal: tag 'cvs199' already exists
numbering 6e1dc4d7d59b3515a3f46c17517c1bb85172c7bc as 198
fatal: tag 'cvs198' already exists
numbering 87c59d4b1bf4c7b1bcb64af078a66290d74f6ebf as 197
fatal: tag 'cvs197' already exists
[...]

This being a hack, I don't attempt to handle previously tagged revisions and instead let git tag give a fatal error that isn't really fatal...

Now I end up with commit tags that look like cvs200, cvs201, ...

17 April, 2010

versions from version control systems

Sometimes its nice for built software to contain version information from the version control system - this means less to users and more to developers.

This is useful when people, for whatever reason, incorrectly report their version: "please test the release candidate for version 1.0 // I found bug B // That's strange because I thought bug B only got introduced yesterday in the dev code // oh yes, well I checked out the dev code and tested that, not actually version 1.0"; or "I have a new bug C // Are you building from a pristine source checkout? // Yes // Why does your log file contain a warning message that the source was modified? // oh, well I hacked at component Q // yes, that's why you're seeing bug C."

Different version control systems have different version representations. SVN has a sequential revision number; git has directory tree hashes; darcs doesn't seem to have any explicit version representation.

So here is code I've used at different times for svn, git and darcs:

For darcs, here's code I found in darcs issue tracker 1142:
echo "$(darcs show tags | head -1) (+ $(darcs changes --count --from-tag .) patches)"
which gives the most recent tag in the repository and how many additional patches have been added:
v1.1 (+ 39 patches)

For svn, we used something like this in Swift
R=$(svn info | grep '^Revision' | sed "s/Revision: /$1-r/")
M=$(svn status | grep --invert-match '^\?' > /dev/null && echo "($1 modified locally)")
echo $R $M
which we use to form version strings like this:
swift-r1833 (swift modified locally)

Using git-svn, so that I was interested in the SVN version information rather than git version information, swap out R and M above for these:
    R=$(git svn info | grep '^Revision' | sed "s/Revision: /$1-r/")
    if git status -a >/dev/null ; then
      M="($1 modified locally)"
    fi 

Both of the above two return the version of the last change in a particular checkout. When there are many modules, its sometimes desirable to give version information for those modules independently. The svnversion command that gives that:
svnversion -c somecomponent
that will produce different output forms that vary depending on the state of the checkout but at simplest gives something like:
4168

To get similar per-directory handling for git, you can do something like this anywhere except in the root of a repository:
SUBDIRPREFIX=$(git rev-parse --show-prefix | sed 's%/$%%')
cd ./$(git rev-parse --show-cdup)
git ls-tree HEAD $SUBDIRPREFIX | (read a b c d ; echo $c)
which will emit a tree hash.

So there are a bunch of different techniques for different version control systems. It would be nice if they were all a bit more consistent - really cool would be a single command that knew all version control systems and could output in a consistent format.