[MERGE] pre_commit hook (was: [RFC] pre_commit hook)
John Arbash Meinel
john at arbash-meinel.com
Wed Aug 15 15:05:34 BST 2007
John Arbash Meinel has voted approve.
Status is now: Semi-approved
Comment:
To start with, I think this is reasonable as is, I just have a few
comments to discuss.
+ if change != 'unchanged' and path != '':
+ self.affected_ids.setdefault(change, []).append(ie.file_id)
^- I wonder if it makes more sense to fill the dictionary with the
different types pointing to empty lists at the start. That way we don't
have to worry about setdefault().
I'm just thinking that an initial add of 10,000 files is going to have a
bit of overhead here. Though I suppose it should be profiled before we
worry about it.
But since there are only a few possible cases, it seems easier to do it
that way.
+ def test_pre_commit_ids(self):
+ self.build_tree(['rootfile', 'dir/', 'dir/subfile'])
+ tree = self.make_branch_and_tree('.')
+ tree.lock_write()
+ tree.set_root_id('root_id')
+ tree.add('rootfile', 'rootfile_id')
+ tree.put_file_bytes_non_atomic('rootfile_id', 'abc')
+ tree.add('dir', 'dir_id')
+ tree.add('dir/subfile', 'dir_subfile_id')
+ tree.put_file_bytes_non_atomic('dir_subfile_id', 'def')
+ Branch.hooks.install_hook("pre_commit",
self.capture_pre_commit_hook)
+ rev1 = tree.commit('first revision')
+ tree.unversion(['dir_id'])
+ rev2 = tree.commit('second revision')
+ tree.put_file_bytes_non_atomic('rootfile_id', 'ghi')
+ rev3 = tree.commit('third revision')
+ tree.unlock()
+ tree.lock_write()
+ tree.rename_one('rootfile', 'renamed')
+ rev4 = tree.commit('fourth revision')
+ tree.unlock()
+ tree.lock_write()
+ tree.put_file_bytes_non_atomic('rootfile_id', 'jkl')
+ tree.rename_one('renamed', 'rootfile')
+ rev5 = tree.commit('fifth revision')
+ tree.unlock()
+ self.assertEqual([
+ ('pre_commit', 0, NULL_REVISION, 1, rev1,
+ {'added': ['dir_id', 'dir_subfile_id', 'rootfile_id']} ),
+ ('pre_commit', 1, rev1, 2, rev2,
+ {'deleted': ['dir_id', 'dir_subfile_id']} ),
+ ('pre_commit', 2, rev2, 3, rev3,
+ {'modified': ['rootfile_id']} ),
+ ('pre_commit', 3, rev3, 4, rev4,
+ {'renamed': ['rootfile_id']} ),
+ ('pre_commit', 4, rev4, 5, rev5,
+ {'modified and renamed': ['rootfile_id']} )
+ ],
+ self.hook_calls)
^- I would have preferred these as separate tests, because as it stands
the test is a little bit hard to read.
Also, you really should have try/finally for:
tree.lock_write():
try:
do stuff
finally:
tree.unlock()
Otherwise, if something fails in the middle, you will get a mixed
traceback, when it also warns that the tree wasn't unlocked. Oh, and if
you are going to do them one after the other, you should be able to just
lock the tree across the whole set. No need to keep unlocking it. (If
there is, let us know, because that would be a sign of a problem).
+ ('pre_commit', 4, rev4, 5, rev5,
+ {'modified and renamed': ['rootfile_id']} )
+ ],
^- This one specifically makes me wonder if we want to be using the
simple "change" value. 'modified', 'renamed', 'added', 'deleted' seem
reasonable, 'modified and renamed' seems a little weird to use as a key.
Not enough to say we shouldn't do it. But just a little.
Anyway, these are just thoughts, not anything that I would merge
without. Someone else can decide if they want to be more strict about
it. Good job overall.
For details, see:
http://bundlebuggy.aaronbentley.com/request/%3Caac8d3110708150229q23b6eba5l3c30d445be0a9862%40mail.gmail.com%3E
More information about the bazaar
mailing list