version bookkeeping in files

Asked by Timmie on 2007-10-16

Is it possible with Bazaar to automatically write the changelog of a file into a comment section in the header of the file when checking out?

This would be nice for automatic version bookkeeping.

Thanks in advance for your answer.

Question information

Language:
English Edit question
Status:
Answered
For:
Bazaar Edit question
Assignee:
No assignee Edit question
Last query:
2007-10-17
Last reply:
2009-11-23
John A Meinel (jameinel) said : #1

I think you are looking for something like the CVS $Log$ keyword.

At the moment we do not have any keyword expansion. The way it was done in CVS was actually quite distasteful in any sort of distributed setup. (It committed the changed value, which means that those lines always conflict whenever you merge 2 branches. It is *not* fun to have 200 conflicts on just the $Id$ lines)

In general, we try to avoid changing your files for you. It would be possible to set up something like this in a post-commit hook. Though I would recommend putting the "bzr log" value into a separate (unversioned) file.

Timmie (timmie) said : #2

> Though I would recommend putting the "bzr log" value into a separate (unversioned) file.
Can this file created automatically?
Like
mybranch\script.py
mybranch\script_bzr.log

I see your -- understandable -- point not to change source file. But nevertheless, a not like
# This file is versioned by Bazaar DVCS. For a changelog please refer to script_bzr.log
could be a good reminder.

John A Meinel (jameinel) said : #3

Assuming you want to create it for every file that is modified you could create a post-commit hook that would do this.

You should be able to copy this code, and put it in ~/.bazaar/plugins/create_log_files.py

And then you want to ignore the auto generated log files:
bzr ignore "*_bzr.log"

I won't guarantee that it is 100% correct, but it should be close (it at least works in my limited testing):

import cStringIO
import os

from bzrlib import (
    branch,
    log,
    )

def log_name_for_filename(fname):
    basename = fname.rsplit('.', 1)[0] # Strip off the extension
    return basename + '_bzr.log'

def create_log_files(local_branch, master_branch, old_revno, old_rev_id, new_revno, new_rev_id):
    the_branch = local_branch
    if the_branch is None:
        the_branch = master_branch

    base_path = the_branch.bzrdir.root_transport.local_abspath('.')

    old_rev_tree = the_branch.repository.revision_tree(old_rev_id)
    new_rev_tree = the_branch.repository.revision_tree(new_rev_id)
    delta = new_rev_tree.changes_from(old_rev_tree)
    # Use delta.added, delta.modified, delta.renamed, etc to find the files that were modified
    paths = []
    paths.extend(path for path, file_id, kind in delta.added if kind == 'file')
    # paths.extend(path for path, file_id, kind in delta.removed if kind == 'file')
    # Renames should probably rename the .log file and then update it
    for old_path, new_path, file_id, kind, text_mod, meta_mod in delta.renamed:
        if kind != 'file':
            continue
        old_log_path = os.path.join(base_path, log_name_for_filename(old_path))
        new_log_path = os.path.join(base_path, log_name_for_filename(new_path))
        os.rename(old_log_path, new_log_path)
        paths.append(new_path)

    paths.extend(path for path, file_id, kind, text_mod, meta_mod in delta.modified
                 if kind == 'file')

    # Now you have a list of paths that should be updated
    log_paths = [log_name_for_filename(path) for path in paths]
    rev = the_branch.repository.get_revision(new_rev_id)
    # Work out what you want to log here, you could use a
    # bzrlib.log.LogFormatter

    log_rev = log.LogRevision(rev=rev, revno=new_revno)
    sio = cStringIO.StringIO()
    formatter = log.LongLogFormatter(to_file=sio)
    formatter.log_revision(log_rev)
    message = sio.getvalue()

    for path in log_paths:
        f = open(os.path.join(base_path, path), 'ab')
        try:
            f.write(message)
        finally:
            f.close()

branch.Branch.hooks.install_hook('post_commit', create_log_files)

I was hoping for something more simple than a full log -- I maintain a really simple project:
https://launchpad.net/make-static-udev
that is currently just one script and I don't expect I will have "releases" with proper version numbers. I was hoping to add into the documentation comment at the top something like:
"This script is revision $REVISION$, download the latest version from:
http://blegh"
so that people who pick up the script can see if their copy is out of date.

Is this possible, or is the answer the same as above?

Marius Kruger (amanica) said : #5

I think the bzr-keywords plugin may be able to help you:
https://launchpad.net/bzr-keywords
http://doc.bazaar-vcs.org/plugins/en/keywords-plugin.html

(I have not used it and don't know how well it works at present)

Can you help with this problem?

Provide an answer of your own, or ask Timmie for more information if necessary.

To post a message you must log in.