Rev 25: Fix directory last-changed calculation and unbreak all tests. in http://bazaar.launchpad.net/~bzr/bzr-hg/trunk
Robert Collins
robertc at robertcollins.net
Wed Jul 11 15:19:04 BST 2007
At http://bazaar.launchpad.net/~bzr/bzr-hg/trunk
------------------------------------------------------------
revno: 25
revision-id: robertc at robertcollins.net-20070711141855-1w3axdt9zt2p7gqz
parent: robertc at robertcollins.net-20070711083143-fhg84pyfszi1fi2u
committer: Robert Collins <robertc at robertcollins.net>
branch nick: trunk
timestamp: Thu 2007-07-12 00:18:55 +1000
message:
Fix directory last-changed calculation and unbreak all tests.
modified:
__init__.py __init__.py-20060531211707-2fy7rwqqcmfgf8ve-1
=== modified file '__init__.py'
--- a/__init__.py 2007-07-11 08:31:43 +0000
+++ b/__init__.py 2007-07-11 14:18:55 +0000
@@ -205,6 +205,9 @@
"""ensure that file can be added by adding its parents.
this is horribly inefficient at the moment, proof of concept.
+
+ This is called for every path under each dir, and will update the
+ .revision for it older each time as the file age is determined.
"""
path = os.path.dirname(file)
if path == '':
@@ -216,6 +219,7 @@
new_best = pick_best_creator_revision(current_best, file_revision_id)
if new_best != current_best:
# new revision found, push this up
+ # XXX could hand in our result as a hint?
add_dir_for(path, file_revision_id)
# and update our chosen one
directories[path] = file_revision_id
@@ -245,12 +249,15 @@
# TODO currently we just pick *a* tail.
file_tails = []
current_manifest = manifest
+ # cls - changelogs
parent_cls = set(self._hgrepo.changelog.parents(hgid))
good_id = hgid
done_cls = set()
+ # walk the graph, any node at a time to find the last change point.
while parent_cls:
current_cl = parent_cls.pop()
- if current_cl != mercurial.node.nullid:
+ # the nullid isn't useful.
+ if current_cl == mercurial.node.nullid:
continue
if current_cl not in known_manifests:
current_manifest_id = self._hgrepo.changelog.read(current_cl)[0]
@@ -260,15 +267,44 @@
done_cls.add(current_cl)
if current_manifest.get(file, None) != file_revision:
continue
- # same in parent
+ # unchanged in parent, advance to the parent.
good_id = current_cl
for parent_cl in self._hgrepo.changelog.parents(current_cl):
if parent_cl not in done_cls:
parent_cls.add(parent_cl)
modified_revision = bzrrevid_from_hg(good_id)
-# modified_revision = bzrrevid_from_hg(
-# self._hgrepo.changelog.index[changelog_index][7])
- add_dir_for(file, modified_revision)
+ # dont use the following, it doesn't give the right results consistently.
+ # modified_revision = bzrrevid_from_hg(
+ # self._hgrepo.changelog.index[changelog_index][7])
+ # now walk to find the introducing revision.
+ parent_cl_ids = set([(None, hgid)])
+ good_id = hgid
+ done_cls = set()
+ while parent_cl_ids:
+ current_cl_id_child, current_cl_id = parent_cl_ids.pop()
+ # the nullid isn't useful.
+ if current_cl_id == mercurial.node.nullid:
+ continue
+ if current_cl_id not in known_manifests:
+ current_manifest_id = self._hgrepo.changelog.read(current_cl_id)[0]
+ known_manifests[current_cl_id] = self._hgrepo.manifest.read(
+ current_manifest_id)
+ current_manifest = known_manifests[current_cl_id]
+ done_cls.add(current_cl_id)
+ if current_manifest.get(file, None) is None:
+ # file is not in current manifest: its a tail, cut here.
+ good_id = current_cl_id_child
+ continue
+ # walk to the parents
+ if (mercurial.node.nullid, mercurial.node.nullid) == self._hgrepo.changelog.parents(current_cl_id):
+ # we have reached the root:
+ good_id = current_cl_id
+ continue
+ for parent_cl in self._hgrepo.changelog.parents(current_cl_id):
+ if parent_cl not in done_cls:
+ parent_cl_ids.add((current_cl_id, parent_cl))
+ introduced_at_path_revision = bzrrevid_from_hg(good_id)
+ add_dir_for(file, introduced_at_path_revision)
entry = result.add_path(file, 'file', file_id=path_id(file))
entry.text_size = revlog.size(revlog.nodemap[file_revision])
# its a shame we need to pull the text out. is there a better way?
@@ -777,6 +813,8 @@
self.revone_inventory = revone_inventory
self.revidone = tip
#====== end revision one
+ # in revisiontwo we add a new file to dir, which should not change
+ # the revision_id on the inventory.
self.build_tree(['hg/dir/d'])
self.tree.add(['dir/d'])
self.tree.commit('bar')
@@ -799,6 +837,19 @@
entry.revision = tip
entry.executable = False
self.revidthree = tip
+ #====== end revision three
+ # in revision four we change the file dir/c, which should not alter
+ # the last-changed field for 'dir'.
+ self.build_tree_contents([('hg/dir/c', 'new contents')])
+ self.tree.commit('change dir/c')
+ self.revfour_inventory = copy.deepcopy(self.revthree_inventory)
+ tip = self.tree.last_revision()
+ entry = self.revfour_inventory['hg:dir:c']
+ entry.revision = tip
+ entry.text_size = len('new contents')
+ entry.text_sha1 = "7ffa72b76d5d66da37f4b614b7a822c01f23c183"
+ self.revidfour = tip
+ #====== end revision four
def test_inventory_from_manifest(self):
repo = self.tree.branch.repository
@@ -811,6 +862,9 @@
left = self.revthree_inventory
right = repo.get_inventory(self.revidthree)
self.assertEqual(left._byid, right._byid)
+ left = self.revfour_inventory
+ right = repo.get_inventory(self.revidfour)
+ self.assertEqual(left._byid, right._byid)
def test_initial_revision_from_changelog(self):
converted_rev = self.tree.branch.repository.get_revision(self.revidone)
@@ -852,7 +906,7 @@
bzrtree.pull(self.tree.branch)
self.assertFileEqual('contents of hg/a\n', 'bzr/a')
self.assertFileEqual('contents of hg/b\n', 'bzr/b')
- self.assertFileEqual('contents of hg/dir/c\n', 'bzr/dir/c')
+ self.assertFileEqual('new contents', 'bzr/dir/c')
# TODO: test that a last-modified in a merged branch is correctly assigned
More information about the bazaar-commits
mailing list