pre-commit hooks and $Id$ banners?

John Arbash Meinel john at
Sun Apr 23 16:24:00 BST 2006

Igor Goryachev wrote:
> Hello, everyone.
> Are there any plans on implementing pre-commit hooks? How could I help
> with that?
> And is it possible (and how better?) to implement banners $Id$,
> $Revision$ support like in CVS or Subversion? I do really need this
> because I work with specific OTP software which handles this stuff
> and acts somehow according to it.
> Thank you.

I did do some investigating about what would need to change to do it
"properly" (where at commit time the strings are stripped, and after
commit the strings are expanded).
I want to post some of my investigation, in case someone actually wants
to look into it.
This will be rather technical, since it is an implementation plan,
rather than just talking about the feature.

First, we would need to change how we detect what files have been
modified. Since now we have a sha1 mismatch between what is on disk, and
what is committed to the inventory. I can think of 2 ways to do this:

1) Change line 175 in, which reads in the files, and
computes their sha1 sum. This needs to change so that instead of just
plain reading a file, we actually filter the file, to unexpand the keywords.

   Doing it this way means that the working inventory looks like the
final inventory, but we have to unescape every file we come across. And
the value in .bzr/stat-cache doesn't match a simple 'sha1sum file/foo'.

2) Add a field to the working inventory. So that we have sha1, and we
have expanded_sha1. Then when doing something like 'bzr status' we
compare against the expanded sha1. Now the hashcache doesn't have to
change. If we want to allow per-file decisions about what is expanded
and what isn't (like svn), we probably need a new inventory field anyway.

Second, we would obviously need to change how we read the actual text
contents when we are committing a new snapshot. This seems as simple as
modifying 'work_tree.get_file_by_name()' so that it returns a ProxyFile,
instead of a regular python file. And that ProxyFile would unescape the

Third, we need a way for post-commit to update the working tree. And
this will depend on what method you want. SVN/CVS only update files
which have changed. If you look at the KeywordExpansion spec, we have
the statement:
"Anything that alters Branch.last_revision() results (e.g. commit, pull)
must update all keyword files".

Which is the idea that after a commit, we actually change *all* files
which have a $Rev$ tag, not just the one that changed this last time.

If we added a field to Inventory to indicate if a file is suppose to
expand fields, then we can just iterate through the inventory to figure
out what files we need to change.
The easiest thing is probably to add a function to WorkingTree which
does this, and then both commit and pull can call that.

In conclusion, it's doable. It would require some internal refactoring,
and probably couldn't just be accomplished by a plugin. I know it isn't
real high on my priority list, since I feel it is not the "correct" way
to keep track of the tree state.

Oh, and if you want to do this sort of thing the same way I do, you
might look into my "version-info" plugin, available from:

I think in the future this may be moved into bzr core. I wrote it as a
plugin, because I generally feel like developing in plugins whatever can
be done there, so that I get the functionality right away, and can have
it with whatever version I'm using.

But anyway, version-info is designed to have various (pluggable) output
formats, so that you can make your build script as simple as:

	bzr version-info --all --format=python >

I have a personal C++ format, but my trees tend to have >1 version files
for all the libraries, so it has to be a custom format for each library.
 Python creates a namespace for variables based on what file they are
in. In C++ you need to create a new namespace *inside* the file text.
And in C, you pretty much need to create a custom prefix to have a
namespace. So I don't know if we can create a universal --format=C, that
doesn't require extra parameters.

Sorry to have this get so long,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 254 bytes
Desc: OpenPGP digital signature
Url : 

More information about the bazaar mailing list