Rev 386: Fix file ids in checkouts. in http://people.samba.org/bzr/jelmer/bzr-svn/bzr.dev
Jelmer Vernooij
jelmer at samba.org
Mon Jan 8 16:04:02 GMT 2007
------------------------------------------------------------
revno: 386
revision-id: jelmer at samba.org-20070108160335-ddcgxfqunj2fch2u
parent: jelmer at samba.org-20070108044938-qsw6iptrtrff0kw9
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: main
timestamp: Mon 2007-01-08 17:03:35 +0100
message:
Fix file ids in checkouts.
modified:
checkout.py workingtree.py-20060306120941-b083cb0fdd4a69de
tests/test_workingtree.py test_workingtree.py-20060622191524-0di7bc3q1ckdbybb-1
=== modified file 'checkout.py'
--- a/checkout.py 2007-01-08 04:49:38 +0000
+++ b/checkout.py 2007-01-08 16:03:35 +0000
@@ -31,12 +31,14 @@
from branch import SvnBranch
from repository import (SvnRepository, escape_svn_path, SVN_PROP_BZR_MERGE,
- SVN_PROP_SVK_MERGE, revision_id_to_svk_feature)
+ SVN_PROP_SVK_MERGE, SVN_PROP_BZR_FILEIDS,
+ revision_id_to_svk_feature)
from scheme import BranchingScheme
from transport import (SvnRaTransport, svn_config, bzr_to_svn_url,
_create_auth_baton)
from tree import SvnBasisTree
+from copy import copy
import os
import svn.core, svn.wc
@@ -80,7 +82,7 @@
self.base_revid = branch.repository.generate_revision_id(
self.base_revnum, branch.branch_path)
- self._set_inventory(self.read_working_inventory(), dirty=False)
+ self.read_working_inventory()
self.controldir = os.path.join(self.basedir, svn.wc.get_adm_dir(), 'bzr')
try:
@@ -140,14 +142,18 @@
return svn.wc.is_adm_dir(path)
def remove(self, files, verbose=False, to_file=None):
+ assert isinstance(files, list)
wc = self._get_wc(write_lock=True)
try:
for file in files:
svn.wc.delete2(self.abspath(file), wc, None, None, None)
- # FIXME: Make sure bzr:file-ids entry also gets deleted
finally:
svn.wc.adm_close(wc)
+ for file in files:
+ self._change_fileid_mapping(None, file)
+ self.read_working_inventory()
+
def _get_wc(self, relpath="", write_lock=False):
return svn.wc.adm_open3(None, self.abspath(relpath).rstrip("/"),
write_lock, 0, None)
@@ -160,28 +166,37 @@
def move(self, from_paths, to_name):
revt = svn.core.svn_opt_revision_t()
revt.kind = svn.core.svn_opt_revision_working
- to_wc = self._get_wc(to_name, write_lock=True)
- try:
- for entry in from_paths:
+ for entry in from_paths:
+ try:
+ to_wc = self._get_wc(to_name, write_lock=True)
svn.wc.copy(self.abspath(entry), to_wc,
os.path.basename(entry), None, None)
- # FIXME: Make sure bzr:file-ids entry gets added
- finally:
- svn.wc.adm_close(to_wc)
+ finally:
+ svn.wc.adm_close(to_wc)
+ try:
+ from_wc = self._get_wc(write_lock=True)
+ svn.wc.delete2(self.abspath(entry), from_wc, None, None, None)
+ finally:
+ svn.wc.adm_close(from_wc)
+ new_name = "%s/%s" % (to_name, os.path.basename(entry))
+ self._change_fileid_mapping(self.inventory.path2id(entry), new_name)
+ self._change_fileid_mapping(None, entry)
- for entry in from_paths:
- self.remove([entry])
+ self.read_working_inventory()
def rename_one(self, from_rel, to_rel):
revt = svn.core.svn_opt_revision_t()
revt.kind = svn.core.svn_opt_revision_unspecified
(to_wc, to_file) = self._get_rel_wc(to_rel, write_lock=True)
+ from_id = self.inventory.path2id(from_rel)
try:
svn.wc.copy(self.abspath(from_rel), to_wc, to_file, None, None)
svn.wc.delete2(self.abspath(from_rel), to_wc, None, None, None)
- # FIXME: Make sure bzr:file-ids entry gets renamed
finally:
svn.wc.adm_close(to_wc)
+ self._change_fileid_mapping(None, from_rel)
+ self._change_fileid_mapping(from_id, to_rel)
+ self.read_working_inventory()
def path_to_file_id(self, revnum, current_revnum, path):
"""Generate a bzr file id from a Subversion file name.
@@ -240,8 +255,7 @@
find_copies(subrelpath)
svn.wc.adm_close(wc)
- def find_ids(entry):
- # FIXME: Check bzr:file-ids property as well
+ def find_ids(entry, rootwc):
relpath = entry.url[len(entry.repos):].strip("/")
assert entry.schedule in (svn.wc.schedule_normal,
svn.wc.schedule_delete,
@@ -261,12 +275,15 @@
if entry.copyfrom_url and list(find_copies(entry.copyfrom_url)) == [relpath]:
return self.path_to_file_id(entry.copyfrom_rev, entry.revision,
entry.copyfrom_url[len(entry.repos):])
+ ids = self._get_new_file_ids(rootwc)
+ if ids.has_key(relpath):
+ return (ids[relpath], None)
return ("NEW-" + escape_svn_path(entry.url[len(entry.repos):].strip("/")), None)
def add_dir_to_inv(relpath, wc, parent_id):
entries = svn.wc.entries_read(wc, False)
entry = entries[""]
- (id, revid) = find_ids(entry)
+ (id, revid) = find_ids(entry, rootwc)
if id is None:
mutter('no id for %r' % entry.url)
return
@@ -297,25 +314,27 @@
finally:
svn.wc.adm_close(subwc)
else:
- (subid, subrevid) = find_ids(entry)
+ (subid, subrevid) = find_ids(entry, rootwc)
if subid:
add_file_to_inv(subrelpath, subid, subrevid, id)
else:
mutter('no id for %r' % entry.url)
- wc = self._get_wc()
+ rootwc = self._get_wc()
try:
- add_dir_to_inv("", wc, None)
+ add_dir_to_inv("", rootwc, None)
finally:
- svn.wc.adm_close(wc)
+ svn.wc.adm_close(rootwc)
+ self._set_inventory(inv, dirty=False)
return inv
def set_last_revision(self, revid):
mutter('setting last revision to %r' % revid)
if revid is None or revid == NULL_REVISION:
self.base_revid = revid
- self.base_tree = FIXME
+ self.base_revnum = 0
+ self.base_tree = RevisionTree(self, Inventory(), revid)
return
(bp, rev) = self.branch.repository.parse_revision_id(revid)
@@ -395,6 +414,9 @@
return revid
def add(self, files, ids=None):
+ if ids:
+ ids = copy(ids)
+ ids.reverse()
assert isinstance(files, list)
wc = self._get_wc(write_lock=True)
try:
@@ -403,9 +425,7 @@
svn.wc.add2(os.path.join(self.basedir, f), wc, None, 0,
None, None, None)
if ids:
- # FIXME: set bzr:file-ids instead
- svn.wc.prop_set2('bzr:fileid', ids.pop(), relpath, wc,
- False)
+ self._change_fileid_mapping(ids.pop(), f, wc)
except SubversionException, (_, num):
if num == svn.core.SVN_ERR_ENTRY_EXISTS:
continue
@@ -414,6 +434,7 @@
raise
finally:
svn.wc.adm_close(wc)
+ self.read_working_inventory()
def basis_tree(self):
if self.base_revid is None or self.base_revid == NULL_REVISION:
@@ -436,6 +457,38 @@
path = self._inventory.id2path(file_id)
return fingerprint_file(open(self.abspath(path)))['sha1']
+ def _change_fileid_mapping(self, id, path, wc=None):
+ if wc is None:
+ subwc = self._get_wc(write_lock=True)
+ else:
+ subwc = wc
+ new_entries = self._get_new_file_ids(subwc)
+ if id is None:
+ if new_entries.has_key(path):
+ del new_entries[path]
+ else:
+ new_entries[path] = id
+ committed = self.branch.repository.branchprop_list.get_property(
+ self.branch.branch_path,
+ self.base_revnum,
+ SVN_PROP_BZR_FILEIDS, "")
+ existing = committed + "".join(map(lambda (path, id): "%s\t%s\n" % (path, id), new_entries.items()))
+ if existing != "":
+ svn.wc.prop_set(SVN_PROP_BZR_FILEIDS, str(existing), self.basedir, subwc)
+ if wc is None:
+ svn.wc.adm_close(subwc)
+
+ def _get_new_file_ids(self, wc):
+ committed = self.branch.repository.branchprop_list.get_property(
+ self.branch.branch_path,
+ self.base_revnum,
+ SVN_PROP_BZR_FILEIDS, "")
+ existing = svn.wc.prop_get(SVN_PROP_BZR_FILEIDS, self.basedir, wc)
+ if existing is None:
+ return {}
+ else:
+ return dict(map(lambda x: x.split("\t"), existing[len(committed):].splitlines()))
+
def _get_bzr_merges(self):
return self.branch.repository.branchprop_list.get_property(
self.branch.branch_path,
=== modified file 'tests/test_workingtree.py'
--- a/tests/test_workingtree.py 2007-01-03 22:24:00 +0000
+++ b/tests/test_workingtree.py 2007-01-08 16:03:35 +0000
@@ -362,3 +362,66 @@
self.assertTrue(os.path.exists("dc/.svn"))
self.assertTrue(not os.path.exists("dc/.bzr"))
bzrdir.open_workingtree()
+
+ def test_file_id_consistent(self):
+ self.make_client('a', 'dc')
+ self.build_tree({'dc/file': 'data'})
+ tree = WorkingTree.open("dc")
+ tree.add(["file"])
+ oldid = tree.inventory.path2id("file")
+ tree = WorkingTree.open("dc")
+ newid = tree.inventory.path2id("file")
+ self.assertEqual(oldid, newid)
+
+ def test_file_id_kept(self):
+ self.make_client('a', 'dc')
+ self.build_tree({'dc/file': 'data'})
+ tree = WorkingTree.open("dc")
+ tree.add(["file"], ["fooid"])
+ self.assertEqual("fooid", tree.inventory.path2id("file"))
+ tree = WorkingTree.open("dc")
+ self.assertEqual("fooid", tree.inventory.path2id("file"))
+
+ def test_file_rename_id(self):
+ self.make_client('a', 'dc')
+ self.build_tree({'dc/file': 'data'})
+ tree = WorkingTree.open("dc")
+ tree.add(["file"], ["fooid"])
+ tree.commit("msg")
+ tree.rename_one("file", "file2")
+ self.assertEqual(None, tree.inventory.path2id("file"))
+ self.assertEqual("fooid", tree.inventory.path2id("file2"))
+ tree = WorkingTree.open("dc")
+ self.assertEqual("fooid", tree.inventory.path2id("file2"))
+
+ def test_file_id_kept_2(self):
+ self.make_client('a', 'dc')
+ self.build_tree({'dc/file': 'data', 'dc/other': 'blaid'})
+ tree = WorkingTree.open("dc")
+ tree.add(["file", "other"], ["fooid", "blaid"])
+ self.assertEqual("fooid", tree.inventory.path2id("file"))
+ self.assertEqual("blaid", tree.inventory.path2id("other"))
+
+ def test_file_remove_id(self):
+ self.make_client('a', 'dc')
+ self.build_tree({'dc/file': 'data'})
+ tree = WorkingTree.open("dc")
+ tree.add(["file"], ["fooid"])
+ tree.commit("msg")
+ tree.remove(["file"])
+ self.assertEqual(None, tree.inventory.path2id("file"))
+ tree = WorkingTree.open("dc")
+ self.assertEqual(None, tree.inventory.path2id("file"))
+
+ def test_file_move_id(self):
+ self.make_client('a', 'dc')
+ self.build_tree({'dc/file': 'data', 'dc/dir': None})
+ tree = WorkingTree.open("dc")
+ tree.add(["file", "dir"], ["fooid", "blaid"])
+ tree.commit("msg")
+ tree.move(["file"], "dir")
+ self.assertEqual(None, tree.inventory.path2id("file"))
+ self.assertEqual("fooid", tree.inventory.path2id("dir/file"))
+ tree = WorkingTree.open("dc")
+ self.assertEqual(None, tree.inventory.path2id("file"))
+ self.assertEqual("fooid", tree.inventory.path2id("dir/file"))
More information about the bazaar-commits
mailing list