If you use bazaar (bzr) and end up with several branches for the same project, you can end up wondering if one branch contains all the commits in another, e.g. you need to check that all the work done in a successful experimental branch has been moved into the trunk.
This small python program does that:
leo.repo> bzrin free_layout trunk Checking for commits of revs in 'free_layout' in 'trunk' Status of 'free_layout': unknown: .thumbnails/ demo.jpg nohup.out Status of 'trunk': unknown: *.g1.dml Counting revs in free_layout 6026 revs in free_layout Counting revs in trunk 6683 revs in trunk All revs in free_layout exist in trunk : OK
`bzrin` checks that all the commits in the "free_layout" branch have been merged into the trunk - in this case they have, and you can safely delete "free_layout".
The code uses `subprocess` rather than the python bzr bindings to do its work, but it gets the job done and has proved very useful for tidying up a directory full of branches for various subprojects.
#!/usr/bin/python """Check that the latest commit in bzr branch A exists in bzr branch B """ # bzrin2 # Author: Terry Brown # Created: Mon Sep 8 12:18:21 CDT 2008 import subprocess, sys, os import tempfile # ? because subprocess.PIPE hangs in .wait() ? def emit(s): sys.stdout.write(s) def main(): branch = tuple(sys.argv[1:3]) emit("Checking for commits of revs in '%s' in '%s'\n" % branch) # show status for i in branch: emit("Status of '%s':\n" % i) cmd = subprocess.Popen(('bzr status '+i).split()) cmd.wait() revs =  for i in branch: emit("Counting revs in %s\n" % i) revs.append(set()) tmpFile, tmpName = tempfile.mkstemp() cmd = subprocess.Popen(('bzr log --show-ids --levels=0 '+i).split(), stdout = tmpFile) os.close(tmpFile) cmd.wait() source = file(tmpName) for line in source: content = line.strip() if content.startswith('revision-id:'): id_ = content.split(None,1) while not line.strip() == 'message:': line = source.next() line = source.next() msg =  while not line.strip().startswith('-'*10): msg.append(line.strip()) try: line = source.next() except StopIteration: # end of file break revs[-1].add((id_, tuple(msg))) os.remove(tmpName) emit("%d revs in %s\n" % (len(revs[-1]), i)) diff = revs.difference(revs) if not diff: emit ("All revs in %s exist in %s : OK\n" % branch) else: emit ("WARNING: %s contains revs NOT in %s\n" % branch) for i in diff: emit("%s\n%s\n" % (i, ''.join([' '+m for m in i]))) emit ("WARNING: %s contains revs NOT in %s\n" % branch) if __name__ == '__main__': main()