Rev 3014: (robertc) Various lock and write-group correctness issues which show in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Thu Nov 22 21:20:40 GMT 2007
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 3014
revision-id:pqm at pqm.ubuntu.com-20071122212030-ehfexlt3qzptnsdv
parent: pqm at pqm.ubuntu.com-20071122201722-4l5bgljqn7qdux7f
parent: robertc at robertcollins.net-20071122023439-1stck34grarbn91o
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2007-11-22 21:20:30 +0000
message:
(robertc) Various lock and write-group correctness issues which show
up when packs are the default format. (Robert Collins, #154204).
modified:
bzrlib/annotate.py annotate.py-20050922133147-7c60541d2614f022
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/repofmt/pack_repo.py pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/revisionspec.py revisionspec.py-20050907152633-17567659fd5c0ddb
bzrlib/sign_my_commits.py sign_my_commits.py-20060215152201-5a6363365180e671
bzrlib/tests/blackbox/test_info.py test_info.py-20060215045507-bbdd2d34efab9e0a
bzrlib/tests/blackbox/test_reconcile.py test_fix.py-20060223013051-9a188e15a5ee9451
bzrlib/tests/blackbox/test_versioning.py versioning.py-20050622071821-3ddf5e2e5e93c602
bzrlib/tests/interrepository_implementations/test_interrepository.py test_interrepository.py-20060220061411-1ec13fa99e5e3eee
bzrlib/tests/test_annotate.py test_annotate.py-20061213215015-sttc9agsxomls7q0-1
bzrlib/tests/test_commit.py test_commit.py-20050914060732-279f057f8c295434
bzrlib/tests/test_dirstate.py test_dirstate.py-20060728012006-d6mvoihjb3je9peu-2
bzrlib/tests/test_fetch.py testfetch.py-20050825090644-f73e07e7dfb1765a
bzrlib/tests/test_graph.py test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
bzrlib/tests/test_memorytree.py test_memorytree.py-20060906023413-4wlkalbdpsxi2r4y-3
bzrlib/tests/test_merge_core.py test_merge_core.py-20050824132511-eb99b23a0eec641b
bzrlib/tests/test_merge_directive.py test_merge_directive-20070228184838-ja62280spt1g7f4x-2
bzrlib/transport/local.py local_transport.py-20050711165921-9b1f142bfe480c24
------------------------------------------------------------
revno: 3010.1.17
revision-id:robertc at robertcollins.net-20071122023439-1stck34grarbn91o
parent: robertc at robertcollins.net-20071122023349-i0nc5or8vpvdu84q
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 13:34:39 +1100
message:
Lock correctness and commit_group management for re-sign, in builtins.
modified:
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
------------------------------------------------------------
revno: 3010.1.16
revision-id:robertc at robertcollins.net-20071122023349-i0nc5or8vpvdu84q
parent: robertc at robertcollins.net-20071122022357-17rpgugyooepb30y
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 13:33:49 +1100
message:
Lock correctness in test_versioning
modified:
bzrlib/tests/blackbox/test_versioning.py versioning.py-20050622071821-3ddf5e2e5e93c602
------------------------------------------------------------
revno: 3010.1.15
revision-id:robertc at robertcollins.net-20071122022357-17rpgugyooepb30y
parent: robertc at robertcollins.net-20071122020949-kpvph7srqw3h60p1
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 13:23:57 +1100
message:
Manage write groups in sign_my_commits, for efficiency.
modified:
bzrlib/sign_my_commits.py sign_my_commits.py-20060215152201-5a6363365180e671
------------------------------------------------------------
revno: 3010.1.14
revision-id:robertc at robertcollins.net-20071122020949-kpvph7srqw3h60p1
parent: robertc at robertcollins.net-20071122020018-a30xrdfzxfwi8g2h
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 13:09:49 +1100
message:
Handle packs in blackbox.test_reconcile.
modified:
bzrlib/tests/blackbox/test_reconcile.py test_fix.py-20060223013051-9a188e15a5ee9451
------------------------------------------------------------
revno: 3010.1.13
revision-id:robertc at robertcollins.net-20071122020018-a30xrdfzxfwi8g2h
parent: robertc at robertcollins.net-20071122003315-ldoyi2mi3nma5qnf
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 13:00:18 +1100
message:
Use the info code functions to determine format strings in the blackbox tests, and handle repositories that do not lock like packs.
modified:
bzrlib/tests/blackbox/test_info.py test_info.py-20060215045507-bbdd2d34efab9e0a
------------------------------------------------------------
revno: 3010.1.12
revision-id:robertc at robertcollins.net-20071122003315-ldoyi2mi3nma5qnf
parent: robertc at robertcollins.net-20071122003029-puc7qosvic1beace
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 11:33:15 +1100
message:
Lock branches while doing revision specification lookups.
modified:
bzrlib/revisionspec.py revisionspec.py-20050907152633-17567659fd5c0ddb
------------------------------------------------------------
revno: 3010.1.11
revision-id:robertc at robertcollins.net-20071122003029-puc7qosvic1beace
parent: robertc at robertcollins.net-20071122002958-szgbifl258kcstzp
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 11:30:29 +1100
message:
Provide file modes to files created by pack repositories
modified:
bzrlib/repofmt/pack_repo.py pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
------------------------------------------------------------
revno: 3010.1.10
revision-id:robertc at robertcollins.net-20071122002958-szgbifl258kcstzp
parent: robertc at robertcollins.net-20071122000512-27cvsv9vs6k0s4hn
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 11:29:58 +1100
message:
Honour file modes for write streams.
modified:
bzrlib/transport/local.py local_transport.py-20050711165921-9b1f142bfe480c24
------------------------------------------------------------
revno: 3010.1.9
revision-id:robertc at robertcollins.net-20071122000512-27cvsv9vs6k0s4hn
parent: robertc at robertcollins.net-20071121235702-y3gnrt33q6ng81mz
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 11:05:12 +1100
message:
test_merge_directive locking correctness.
modified:
bzrlib/tests/test_merge_directive.py test_merge_directive-20070228184838-ja62280spt1g7f4x-2
------------------------------------------------------------
revno: 3010.1.8
revision-id:robertc at robertcollins.net-20071121235702-y3gnrt33q6ng81mz
parent: robertc at robertcollins.net-20071121234250-hnltm60sryng2w55
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 10:57:02 +1100
message:
test_merge_core locking correctness.
modified:
bzrlib/tests/test_merge_core.py test_merge_core.py-20050824132511-eb99b23a0eec641b
------------------------------------------------------------
revno: 3010.1.7
revision-id:robertc at robertcollins.net-20071121234250-hnltm60sryng2w55
parent: robertc at robertcollins.net-20071121233940-3l1xpdnxqdneogqe
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 10:42:50 +1100
message:
Locking in test_memorytree.
modified:
bzrlib/tests/test_memorytree.py test_memorytree.py-20060906023413-4wlkalbdpsxi2r4y-3
------------------------------------------------------------
revno: 3010.1.6
revision-id:robertc at robertcollins.net-20071121233940-3l1xpdnxqdneogqe
parent: robertc at robertcollins.net-20071121233632-63hxiuhd5kcweg21
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 10:39:40 +1100
message:
Locking in test_graph.
modified:
bzrlib/tests/test_graph.py test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
------------------------------------------------------------
revno: 3010.1.5
revision-id:robertc at robertcollins.net-20071121233632-63hxiuhd5kcweg21
parent: robertc at robertcollins.net-20071121233532-6pr4b7vvq3s01b7m
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 10:36:32 +1100
message:
Test that missing_revision_ids handles the case of the source not having the requested revision correctly with and without find_ghosts.
modified:
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/interrepository_implementations/test_interrepository.py test_interrepository.py-20060220061411-1ec13fa99e5e3eee
------------------------------------------------------------
revno: 3010.1.4
revision-id:robertc at robertcollins.net-20071121233532-6pr4b7vvq3s01b7m
parent: robertc at robertcollins.net-20071121221702-winh9l8xzqt177px
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 10:35:32 +1100
message:
Make the knit specific fetch tests knit specific, and lock the branch when looking at historical texts in test_fetch.
modified:
bzrlib/tests/test_fetch.py testfetch.py-20050825090644-f73e07e7dfb1765a
------------------------------------------------------------
revno: 3010.1.3
revision-id:robertc at robertcollins.net-20071121221702-winh9l8xzqt177px
parent: robertc at robertcollins.net-20071121221620-lnx3jph93gfq2t03
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 09:17:02 +1100
message:
Lock RevisionTrees correctly in commit tests.
modified:
bzrlib/tests/test_commit.py test_commit.py-20050914060732-279f057f8c295434
------------------------------------------------------------
revno: 3010.1.2
revision-id:robertc at robertcollins.net-20071121221620-lnx3jph93gfq2t03
parent: robertc at robertcollins.net-20071121215711-meep8d5qazsufllc
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 09:16:20 +1100
message:
Use valid file-ids for dirstate tests.
modified:
bzrlib/tests/test_dirstate.py test_dirstate.py-20060728012006-d6mvoihjb3je9peu-2
------------------------------------------------------------
revno: 3010.1.1
revision-id:robertc at robertcollins.net-20071121215711-meep8d5qazsufllc
parent: pqm at pqm.ubuntu.com-20071121045727-gqycrul94d0ssir1
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack.read-locks
timestamp: Thu 2007-11-22 08:57:11 +1100
message:
Lock the tree's used to test annotate_file, and add a docstring for annotate_file explaining its needs.
modified:
bzrlib/annotate.py annotate.py-20050922133147-7c60541d2614f022
bzrlib/tests/test_annotate.py test_annotate.py-20061213215015-sttc9agsxomls7q0-1
=== modified file 'bzrlib/annotate.py'
--- a/bzrlib/annotate.py 2007-10-16 16:02:01 +0000
+++ b/bzrlib/annotate.py 2007-11-21 21:57:11 +0000
@@ -39,6 +39,20 @@
def annotate_file(branch, rev_id, file_id, verbose=False, full=False,
to_file=None, show_ids=False):
+ """Annotate file_id at revision rev_id in branch.
+
+ The branch should already be read_locked() when annotate_file is called.
+
+ :param branch: The branch to look for revision numbers and history from.
+ :param rev_id: The revision id to annotate.
+ :param file_id: The file_id to annotate.
+ :param verbose: Show all details rather than truncating to ensure
+ reasonable text width.
+ :param full: XXXX Not sure what this does.
+ :param to_file: The file to output the annotation to; if None stdout is
+ used.
+ :param show_ids: Show revision ids in the annotation output.
+ """
if to_file is None:
to_file = sys.stdout
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2007-11-20 14:43:47 +0000
+++ b/bzrlib/builtins.py 2007-11-22 02:34:39 +0000
@@ -2115,7 +2115,6 @@
if revision is not None and len(revision) != 1:
raise errors.BzrCommandError("bzr cat --revision takes exactly"
" one number")
-
tree = None
try:
tree, b, relpath = \
@@ -2125,6 +2124,14 @@
if revision is not None and revision[0].get_branch() is not None:
b = Branch.open(revision[0].get_branch())
+ b.lock_read()
+ try:
+ return self._run(tree, b, relpath, filename, revision,
+ name_from_revision)
+ finally:
+ b.unlock()
+
+ def _run(self, tree, b, relpath, filename, revision, name_from_revision):
if tree is None:
tree = b.basis_tree()
if revision is None:
@@ -2686,14 +2693,21 @@
branch1 = Branch.open_containing(branch)[0]
branch2 = Branch.open_containing(other)[0]
-
- last1 = ensure_null(branch1.last_revision())
- last2 = ensure_null(branch2.last_revision())
-
- graph = branch1.repository.get_graph(branch2.repository)
- base_rev_id = graph.find_unique_lca(last1, last2)
-
- print 'merge base is revision %s' % base_rev_id
+ branch1.lock_read()
+ try:
+ branch2.lock_read()
+ try:
+ last1 = ensure_null(branch1.last_revision())
+ last2 = ensure_null(branch2.last_revision())
+
+ graph = branch1.repository.get_graph(branch2.repository)
+ base_rev_id = graph.find_unique_lca(last1, last2)
+
+ print 'merge base is revision %s' % base_rev_id
+ finally:
+ branch2.unlock()
+ finally:
+ branch1.unlock()
class cmd_merge(Command):
@@ -3422,20 +3436,41 @@
takes_options = ['revision']
def run(self, revision_id_list=None, revision=None):
- import bzrlib.gpg as gpg
if revision_id_list is not None and revision is not None:
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
if revision_id_list is None and revision is None:
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
b = WorkingTree.open_containing(u'.')[0].branch
+ b.lock_write()
+ try:
+ return self._run(b, revision_id_list, revision)
+ finally:
+ b.unlock()
+
+ def _run(self, b, revision_id_list, revision):
+ import bzrlib.gpg as gpg
gpg_strategy = gpg.GPGStrategy(b.get_config())
if revision_id_list is not None:
- for revision_id in revision_id_list:
- b.repository.sign_revision(revision_id, gpg_strategy)
+ b.repository.start_write_group()
+ try:
+ for revision_id in revision_id_list:
+ b.repository.sign_revision(revision_id, gpg_strategy)
+ except:
+ b.repository.abort_write_group()
+ raise
+ else:
+ b.repository.commit_write_group()
elif revision is not None:
if len(revision) == 1:
revno, rev_id = revision[0].in_history(b)
- b.repository.sign_revision(rev_id, gpg_strategy)
+ b.repository.start_write_group()
+ try:
+ b.repository.sign_revision(rev_id, gpg_strategy)
+ except:
+ b.repository.abort_write_group()
+ raise
+ else:
+ b.repository.commit_write_group()
elif len(revision) == 2:
# are they both on rh- if so we can walk between them
# might be nice to have a range helper for arbitrary
@@ -3446,9 +3481,16 @@
to_revno = b.revno()
if from_revno is None or to_revno is None:
raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
- for revno in range(from_revno, to_revno + 1):
- b.repository.sign_revision(b.get_rev_id(revno),
- gpg_strategy)
+ b.repository.start_write_group()
+ try:
+ for revno in range(from_revno, to_revno + 1):
+ b.repository.sign_revision(b.get_rev_id(revno),
+ gpg_strategy)
+ except:
+ b.repository.abort_write_group()
+ raise
+ else:
+ b.repository.commit_write_group()
else:
raise errors.BzrCommandError('Please supply either one revision, or a range.')
@@ -3965,6 +4007,9 @@
outfile = open(output, 'wb')
try:
branch = Branch.open_containing(from_)[0]
+ # we may need to write data into branch's repository to calculate
+ # the data to send.
+ branch.lock_write()
if output is None:
config = branch.get_config()
if mail_to is None:
@@ -4052,6 +4097,7 @@
finally:
if output != '-':
outfile.close()
+ branch.unlock()
class cmd_bundle_revisions(cmd_send):
=== modified file 'bzrlib/repofmt/pack_repo.py'
--- a/bzrlib/repofmt/pack_repo.py 2007-11-13 21:39:37 +0000
+++ b/bzrlib/repofmt/pack_repo.py 2007-11-22 00:30:29 +0000
@@ -187,7 +187,7 @@
}
def __init__(self, upload_transport, index_transport, pack_transport,
- upload_suffix=''):
+ upload_suffix='', file_mode=None):
"""Create a NewPack instance.
:param upload_transport: A writable transport for the pack to be
@@ -199,6 +199,7 @@
upload_transport.clone('../packs').
:param upload_suffix: An optional suffix to be given to any temporary
files created during the pack creation. e.g '.autopack'
+ :param file_mode: An optional file mode to create the new files with.
"""
# The relative locations of the packs are constrained, but all are
# passed in because the caller has them, so as to avoid object churn.
@@ -223,6 +224,8 @@
self.index_transport = index_transport
# where is the pack renamed to when it is finished?
self.pack_transport = pack_transport
+ # What file mode to upload the pack and indices with.
+ self._file_mode = file_mode
# tracks the content written to the .pack file.
self._hash = md5.new()
# a four-tuple with the length in bytes of the indices, once the pack
@@ -239,7 +242,7 @@
self.start_time = time.time()
# open an output stream for the data added to the pack.
self.write_stream = self.upload_transport.open_write_stream(
- self.random_name)
+ self.random_name, mode=self._file_mode)
if 'pack' in debug.debug_flags:
mutter('%s: create_pack: pack stream open: %s%s t+%6.3fs',
time.ctime(), self.upload_transport.base, self.random_name,
@@ -368,7 +371,8 @@
"""
index_name = self.index_name(index_type, self.name)
self.index_sizes[self.index_offset(index_type)] = \
- self.index_transport.put_file(index_name, index.finish())
+ self.index_transport.put_file(index_name, index.finish(),
+ mode=self._file_mode)
if 'pack' in debug.debug_flags:
# XXX: size might be interesting?
mutter('%s: create_pack: wrote %s index: %s%s t+%6.3fs',
@@ -533,7 +537,8 @@
"""Open a pack for the pack we are creating."""
return NewPack(self._pack_collection._upload_transport,
self._pack_collection._index_transport,
- self._pack_collection._pack_transport, upload_suffix=self.suffix)
+ self._pack_collection._pack_transport, upload_suffix=self.suffix,
+ file_mode=self._pack_collection.repo.control_files._file_mode)
def _create_pack_from_packs(self):
self.pb.update("Opening pack", 0, 5)
@@ -1245,7 +1250,8 @@
# changing it.
for key, value in disk_nodes:
builder.add_node(key, value)
- self.transport.put_file('pack-names', builder.finish())
+ self.transport.put_file('pack-names', builder.finish(),
+ mode=self.repo.control_files._file_mode)
# move the baseline forward
self._packs_at_load = disk_nodes
# now clear out the obsolete packs directory
@@ -1288,7 +1294,8 @@
if not self.repo.is_write_locked():
raise errors.NotWriteLocked(self)
self._new_pack = NewPack(self._upload_transport, self._index_transport,
- self._pack_transport, upload_suffix='.pack')
+ self._pack_transport, upload_suffix='.pack',
+ file_mode=self.repo.control_files._file_mode)
# allow writing: queue writes to a new index
self.revision_index.add_writable_index(self._new_pack.revision_index,
self._new_pack)
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py 2007-11-18 19:25:42 +0000
+++ b/bzrlib/repository.py 2007-11-22 21:20:30 +0000
@@ -792,14 +792,15 @@
(format, data_list, StringIO(knit_bytes).read))
@needs_read_lock
- def missing_revision_ids(self, other, revision_id=None):
+ def missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
"""Return the revision ids that other has that this does not.
These are returned in topological order.
revision_id: only return revision ids included by revision_id.
"""
- return InterRepository.get(other, self).missing_revision_ids(revision_id)
+ return InterRepository.get(other, self).missing_revision_ids(
+ revision_id, find_ghosts)
@staticmethod
def open(base):
@@ -2054,7 +2055,7 @@
raise NotImplementedError(self.fetch)
@needs_read_lock
- def missing_revision_ids(self, revision_id=None):
+ def missing_revision_ids(self, revision_id=None, find_ghosts=True):
"""Return the revision ids that source has that target does not.
These are returned in topological order.
@@ -2221,7 +2222,7 @@
return f.count_copied, f.failed_revisions
@needs_read_lock
- def missing_revision_ids(self, revision_id=None):
+ def missing_revision_ids(self, revision_id=None, find_ghosts=True):
"""See InterRepository.missing_revision_ids()."""
# we want all revisions to satisfy revision_id in source.
# but we don't want to stat every file here and there.
@@ -2299,7 +2300,7 @@
return f.count_copied, f.failed_revisions
@needs_read_lock
- def missing_revision_ids(self, revision_id=None):
+ def missing_revision_ids(self, revision_id=None, find_ghosts=True):
"""See InterRepository.missing_revision_ids()."""
if revision_id is not None:
source_ids = self.source.get_ancestry(revision_id)
@@ -2376,7 +2377,7 @@
# sensibly detect 'new revisions' without doing a full index scan.
elif _mod_revision.is_null(revision_id):
# nothing to do:
- return
+ return (0, [])
else:
try:
revision_ids = self.missing_revision_ids(revision_id,
@@ -2392,9 +2393,9 @@
# a pack creation, but for now it is simpler to think about as
# 'upload data, then repack if needed'.
self.target._pack_collection.autopack()
- return pack.get_revision_count()
+ return (pack.get_revision_count(), [])
else:
- return 0
+ return (0, [])
@needs_read_lock
def missing_revision_ids(self, revision_id=None, find_ghosts=True):
@@ -2421,6 +2422,12 @@
target_index.iter_entries(target_keys))
missing_revs.update(next_revs - have_revs)
searcher.stop_searching_any(have_revs)
+ if next_revs - have_revs == set([revision_id]):
+ # we saw the start rev itself, but no parents from it (or
+ # next_revs would have been updated to e.g. set(). We remove
+ # have_revs because if we found revision_id locally we
+ # stop_searching at the first time around.
+ raise errors.NoSuchRevision(self.source, revision_id)
return missing_revs
elif revision_id is not None:
source_ids = self.source.get_ancestry(revision_id)
=== modified file 'bzrlib/revisionspec.py'
--- a/bzrlib/revisionspec.py 2007-08-20 13:03:46 +0000
+++ b/bzrlib/revisionspec.py 2007-11-22 00:33:15 +0000
@@ -639,22 +639,28 @@
for r, b in ((revision_a, branch), (revision_b, other_branch)):
if r in (None, revision.NULL_REVISION):
raise errors.NoCommits(b)
- revision_source = revision.MultipleRevisionSources(
- branch.repository, other_branch.repository)
- graph = branch.repository.get_graph(other_branch.repository)
- revision_a = revision.ensure_null(revision_a)
- revision_b = revision.ensure_null(revision_b)
- if revision.NULL_REVISION in (revision_a, revision_b):
- rev_id = revision.NULL_REVISION
- else:
- rev_id = graph.find_unique_lca(revision_a, revision_b)
- if rev_id == revision.NULL_REVISION:
- raise errors.NoCommonAncestor(revision_a, revision_b)
+ branch.lock_read()
+ other_branch.lock_read()
try:
- revno = branch.revision_id_to_revno(rev_id)
- except errors.NoSuchRevision:
- revno = None
- return RevisionInfo(branch, revno, rev_id)
+ revision_source = revision.MultipleRevisionSources(
+ branch.repository, other_branch.repository)
+ graph = branch.repository.get_graph(other_branch.repository)
+ revision_a = revision.ensure_null(revision_a)
+ revision_b = revision.ensure_null(revision_b)
+ if revision.NULL_REVISION in (revision_a, revision_b):
+ rev_id = revision.NULL_REVISION
+ else:
+ rev_id = graph.find_unique_lca(revision_a, revision_b)
+ if rev_id == revision.NULL_REVISION:
+ raise errors.NoCommonAncestor(revision_a, revision_b)
+ try:
+ revno = branch.revision_id_to_revno(rev_id)
+ except errors.NoSuchRevision:
+ revno = None
+ return RevisionInfo(branch, revno, rev_id)
+ finally:
+ branch.unlock()
+ other_branch.unlock()
SPEC_TYPES.append(RevisionSpec_ancestor)
=== modified file 'bzrlib/sign_my_commits.py'
--- a/bzrlib/sign_my_commits.py 2007-07-10 10:33:45 +0000
+++ b/bzrlib/sign_my_commits.py 2007-11-22 02:23:57 +0000
@@ -65,18 +65,25 @@
count = 0
repo.lock_write()
try:
- for rev_id in repo.get_ancestry(branch.last_revision())[1:]:
- if repo.has_signature_for_revision_id(rev_id):
- continue
- rev = repo.get_revision(rev_id)
- if rev.committer != committer:
- continue
- # We have a revision without a signature who has a
- # matching committer, start signing
- print rev_id
- count += 1
- if not dry_run:
- repo.sign_revision(rev_id, gpg_strategy)
+ repo.start_write_group()
+ try:
+ for rev_id in repo.get_ancestry(branch.last_revision())[1:]:
+ if repo.has_signature_for_revision_id(rev_id):
+ continue
+ rev = repo.get_revision(rev_id)
+ if rev.committer != committer:
+ continue
+ # We have a revision without a signature who has a
+ # matching committer, start signing
+ print rev_id
+ count += 1
+ if not dry_run:
+ repo.sign_revision(rev_id, gpg_strategy)
+ except:
+ repo.abort_write_group()
+ raise
+ else:
+ repo.commit_write_group()
finally:
repo.unlock()
print 'Signed %d revisions' % (count,)
=== modified file 'bzrlib/tests/blackbox/test_info.py'
--- a/bzrlib/tests/blackbox/test_info.py 2007-11-15 04:08:32 +0000
+++ b/bzrlib/tests/blackbox/test_info.py 2007-11-22 21:20:30 +0000
@@ -24,6 +24,7 @@
from bzrlib import (
bzrdir,
errors,
+ info,
osutils,
repository,
urlutils,
@@ -486,7 +487,7 @@
repo = branch.repository
out, err = self.run_bzr('info branch -v')
self.assertEqualDiff(
-"""Standalone branch (format: dirstate-tags)
+"""Standalone branch (format: %s)
Location:
branch root: branch
@@ -502,7 +503,8 @@
Repository:
0 revisions
0 KiB
-""" % (format.get_branch_format().get_format_description(),
+""" % (info.describe_format(repo.bzrdir, repo, branch, None),
+ format.get_branch_format().get_format_description(),
format.repository_format.get_format_description(),
), out)
self.assertEqual('', err)
@@ -1106,7 +1108,7 @@
), out)
self.assertEqual('', err)
- def assertCheckoutStatusOutput(self,
+ def assertCheckoutStatusOutput(self,
command_string, lco_tree, shared_repo=None,
repo_branch=None,
tree_locked=False,
@@ -1131,6 +1133,10 @@
:param tree_locked: If true, expect the tree to be locked.
:param branch_locked: If true, expect the branch to be locked.
:param repo_locked: If true, expect the repository to be locked.
+ Note that the lco_tree.branch.repository is inspected, and if is not
+ actually locked then this parameter is overridden. This is because
+ pack repositories do not have any public API for obtaining an
+ exclusive repository wide lock.
:param verbose: If true, expect verbose output
"""
def friendly_location(url):
@@ -1156,6 +1162,8 @@
format = {True: 'dirstate or dirstate-tags or knitpack-experimental'
' or rich-root',
False: 'dirstate'}[light_checkout]
+ if repo_locked:
+ repo_locked = lco_tree.branch.repository.get_physical_lock_status()
if repo_locked or branch_locked or tree_locked:
def locked_message(a_bool):
if a_bool:
=== modified file 'bzrlib/tests/blackbox/test_reconcile.py'
--- a/bzrlib/tests/blackbox/test_reconcile.py 2007-10-03 06:37:01 +0000
+++ b/bzrlib/tests/blackbox/test_reconcile.py 2007-11-22 02:09:49 +0000
@@ -42,10 +42,15 @@
def test_trivial_reconcile(self):
t = bzrdir.BzrDir.create_standalone_workingtree('.')
(out, err) = self.run_bzr('reconcile')
+ if t.branch.repository._reconcile_backsup_inventory:
+ does_backup_text = "Inventory ok.\n"
+ else:
+ does_backup_text = ""
self.assertEqualDiff(out, "Reconciling repository %s\n"
- "Inventory ok.\n"
+ "%s"
"Reconciliation complete.\n" %
- t.bzrdir.root_transport.base)
+ (t.bzrdir.root_transport.base,
+ does_backup_text))
self.assertEqualDiff(err, "")
def test_does_something_reconcile(self):
@@ -60,9 +65,15 @@
repo.commit_write_group()
repo.unlock()
(out, err) = self.run_bzr('reconcile')
- self.assertEqualDiff(out, "Reconciling repository %s\n"
- "Backup Inventory created.\n"
- "Inventory regenerated.\n"
- "Reconciliation complete.\n" %
- t.bzrdir.root_transport.base)
+ if repo._reconcile_backsup_inventory:
+ does_backup_text = (
+ "Backup Inventory created.\n"
+ "Inventory regenerated.\n")
+ else:
+ does_backup_text = ""
+ expected = ("Reconciling repository %s\n"
+ "%s"
+ "Reconciliation complete.\n" %
+ (t.bzrdir.root_transport.base, does_backup_text))
+ self.assertEqualDiff(expected, out)
self.assertEqualDiff(err, "")
=== modified file 'bzrlib/tests/blackbox/test_versioning.py'
--- a/bzrlib/tests/blackbox/test_versioning.py 2007-06-28 12:26:11 +0000
+++ b/bzrlib/tests/blackbox/test_versioning.py 2007-11-22 02:33:49 +0000
@@ -148,24 +148,30 @@
old = b.repository.revision_tree(b.get_rev_id(1))
new = b.repository.revision_tree(b.get_rev_id(2))
+ new.lock_read()
eq(new.get_file_by_path('b/two').read(), 'old contents')
eq(new.get_file_by_path('top').read(), 'old contents')
eq(new.get_file_by_path('a/one').read(), 'new contents')
+ new.unlock()
os.chdir('a')
# commit from here should do nothing
run_bzr(['commit', '.', '-m', 'commit subdir only', '--unchanged'])
v3 = b.repository.revision_tree(b.get_rev_id(3))
+ v3.lock_read()
eq(v3.get_file_by_path('b/two').read(), 'old contents')
eq(v3.get_file_by_path('top').read(), 'old contents')
eq(v3.get_file_by_path('a/one').read(), 'new contents')
+ v3.unlock()
# commit in subdirectory commits whole tree
run_bzr(['commit', '-m', 'commit whole tree from subdir'])
v4 = b.repository.revision_tree(b.get_rev_id(4))
+ v4.lock_read()
eq(v4.get_file_by_path('b/two').read(), 'new contents')
eq(v4.get_file_by_path('top').read(), 'new contents')
+ v4.unlock()
# TODO: factor out some kind of assert_tree_state() method
=== modified file 'bzrlib/tests/interrepository_implementations/test_interrepository.py'
--- a/bzrlib/tests/interrepository_implementations/test_interrepository.py 2007-10-30 17:39:11 +0000
+++ b/bzrlib/tests/interrepository_implementations/test_interrepository.py 2007-11-21 23:36:32 +0000
@@ -275,6 +275,20 @@
self.assertEqual(['rev2'],
repo_b.missing_revision_ids(repo_a))
+ def test_missing_revision_ids_absent_requested_raises(self):
+ # Asking for missing revisions with a tip that is itself absent in the
+ # source raises NoSuchRevision.
+ repo_b = self.make_to_repository('target')
+ repo_a = self.bzrdir.open_repository()
+ # No pizza revisions anywhere
+ self.assertFalse(repo_a.has_revision('pizza'))
+ self.assertFalse(repo_b.has_revision('pizza'))
+ # Asking specifically for an absent revision errors.
+ self.assertRaises(NoSuchRevision, repo_b.missing_revision_ids, repo_a,
+ revision_id='pizza', find_ghosts=True)
+ self.assertRaises(NoSuchRevision, repo_b.missing_revision_ids, repo_a,
+ revision_id='pizza', find_ghosts=False)
+
def test_missing_revision_ids_revision_limited(self):
# revision ids in repository A that are not referenced by the
# requested revision are not returned.
=== modified file 'bzrlib/tests/test_annotate.py'
--- a/bzrlib/tests/test_annotate.py 2007-08-31 19:38:52 +0000
+++ b/bzrlib/tests/test_annotate.py 2007-11-21 21:57:11 +0000
@@ -149,6 +149,8 @@
tree1.commit('merge 2', rev_id='rev-3',
committer='sal at foo.com',
timestamp=1166046003.00, timezone=0)
+ tree1.lock_read()
+ self.addCleanup(tree1.unlock)
return tree1, tree2
def create_deeply_merged_trees(self):
@@ -175,6 +177,7 @@
rev-6
"""
tree1, tree2 = self.create_merged_trees()
+ tree1.unlock()
tree3 = tree2.bzrdir.clone('tree3').open_workingtree()
@@ -202,6 +205,7 @@
timestamp=1166046005.00, timezone=0)
self.assertEqual(0, tree1.merge_from_branch(tree4.branch))
tree1.commit('merge five and six', rev_id='rev-6')
+ tree1.lock_read()
return tree1
def test_annotate_shows_dotted_revnos(self):
@@ -325,6 +329,8 @@
committer=u'p\xe9rez',
timestamp=1166046000.00, timezone=0)
+ tree1.lock_read()
+ self.addCleanup(tree1.unlock)
# this passes if no exception is raised
to_file = StringIO()
annotate.annotate_file(tree1.branch, 'rev-1', 'a-id', to_file=to_file)
@@ -362,6 +368,8 @@
author='Author <author at example.com>',
timestamp=1166046000.00, timezone=0)
+ tree1.lock_read()
+ self.addCleanup(tree1.unlock)
to_file = StringIO()
annotate.annotate_file(tree1.branch, 'rev-1', 'a-id', to_file=to_file)
self.assertEqual('1 committ | hello\n', to_file.getvalue())
=== modified file 'bzrlib/tests/test_commit.py'
--- a/bzrlib/tests/test_commit.py 2007-11-01 09:52:45 +0000
+++ b/bzrlib/tests/test_commit.py 2007-11-21 22:17:02 +0000
@@ -95,11 +95,16 @@
eq(rev.message, 'add hello')
tree1 = b.repository.revision_tree(rh[0])
+ tree1.lock_read()
text = tree1.get_file_text(file_id)
- eq(text, 'hello world')
+ tree1.unlock()
+ self.assertEqual('hello world', text)
tree2 = b.repository.revision_tree(rh[1])
- eq(tree2.get_file_text(file_id), 'version 2')
+ tree2.lock_read()
+ text = tree2.get_file_text(file_id)
+ tree2.unlock()
+ self.assertEqual('version 2', text)
def test_delete_commit(self):
"""Test a commit with a deleted file"""
@@ -168,11 +173,15 @@
eq(b.revno(), 3)
tree2 = b.repository.revision_tree('test at rev-2')
+ tree2.lock_read()
+ self.addCleanup(tree2.unlock)
self.assertTrue(tree2.has_filename('hello'))
self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
tree3 = b.repository.revision_tree('test at rev-3')
+ tree3.lock_read()
+ self.addCleanup(tree3.unlock)
self.assertFalse(tree3.has_filename('hello'))
self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
@@ -189,6 +198,8 @@
eq = self.assertEquals
tree1 = b.repository.revision_tree('test at rev-1')
+ tree1.lock_read()
+ self.addCleanup(tree1.unlock)
eq(tree1.id2path('hello-id'), 'hello')
eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
self.assertFalse(tree1.has_filename('fruity'))
@@ -197,6 +208,8 @@
eq(ie.revision, 'test at rev-1')
tree2 = b.repository.revision_tree('test at rev-2')
+ tree2.lock_read()
+ self.addCleanup(tree2.unlock)
eq(tree2.id2path('hello-id'), 'fruity')
eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
self.check_inventory_shape(tree2.inventory, ['fruity'])
=== modified file 'bzrlib/tests/test_dirstate.py'
--- a/bzrlib/tests/test_dirstate.py 2007-11-15 01:07:51 +0000
+++ b/bzrlib/tests/test_dirstate.py 2007-11-21 22:16:20 +0000
@@ -420,7 +420,7 @@
def get_tree_with_a_file(self):
tree = self.make_branch_and_tree('tree')
self.build_tree(['tree/a file'])
- tree.add('a file', 'a file id')
+ tree.add('a file', 'a-file-id')
return tree
def test_non_empty_no_parents_to_dirstate(self):
@@ -431,7 +431,7 @@
(('', '', tree.get_root_id()), # common details
[('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree
]),
- (('', 'a file', 'a file id'), # common
+ (('', 'a file', 'a-file-id'), # common
[('f', '', 0, False, dirstate.DirState.NULLSTAT), # current
]),
])
@@ -450,7 +450,7 @@
[('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree
('d', '', 0, False, rev_id), # first parent details
]),
- (('', 'a file', 'a file id'), # common
+ (('', 'a file', 'a-file-id'), # common
[('f', '', 0, False, dirstate.DirState.NULLSTAT), # current
('f', 'c3ed76e4bfd45ff1763ca206055bca8e9fc28aa8', 24, False,
rev_id), # first parent
@@ -478,7 +478,7 @@
('d', '', 0, False, rev_id), # first parent details
('d', '', 0, False, rev_id2), # second parent details
]),
- (('', 'a file', 'a file id'), # common
+ (('', 'a file', 'a-file-id'), # common
[('f', '', 0, False, dirstate.DirState.NULLSTAT), # current
('f', 'c3ed76e4bfd45ff1763ca206055bca8e9fc28aa8', 24, False,
rev_id), # first parent
@@ -1008,12 +1008,12 @@
(('', '', 'TREE_ROOT'), [
('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree
]),
- (('', 'a file', 'a file id'), [
+ (('', 'a file', 'a-file-id'), [
('f', '1'*20, 19, False, dirstate.pack_stat(stat)), # current tree
]),
]
try:
- state.add('a file', 'a file id', 'file', stat, '1'*20)
+ state.add('a file', 'a-file-id', 'file', stat, '1'*20)
# having added it, it should be in the output of iter_entries.
self.assertEqual(expected_entries, list(state._iter_entries()))
# saving and reloading should not affect this.
@@ -1038,7 +1038,7 @@
state = dirstate.DirState.initialize('dirstate')
try:
self.assertRaises(errors.NotVersionedError, state.add,
- 'unversioned/a file', 'a file id', 'file', None, None)
+ 'unversioned/a file', 'a-file-id', 'file', None, None)
finally:
state.unlock()
@@ -1115,7 +1115,7 @@
(('', 'a dir', 'a dir id'), [
('d', '', 0, False, dirstate.pack_stat(dirstat)), # current tree
]),
- (('a dir', 'a file', 'a file id'), [
+ (('a dir', 'a file', 'a-file-id'), [
('f', '1'*20, 25, False,
dirstate.pack_stat(filestat)), # current tree details
]),
@@ -1123,7 +1123,7 @@
state = dirstate.DirState.initialize('dirstate')
try:
state.add('a dir', 'a dir id', 'directory', dirstat, None)
- state.add('a dir/a file', 'a file id', 'file', filestat, '1'*20)
+ state.add('a dir/a file', 'a-file-id', 'file', filestat, '1'*20)
# added it, it should be in the output of iter_entries.
self.assertEqual(expected_entries, list(state._iter_entries()))
# saving and reloading should not affect this.
=== modified file 'bzrlib/tests/test_fetch.py'
--- a/bzrlib/tests/test_fetch.py 2007-10-16 16:02:01 +0000
+++ b/bzrlib/tests/test_fetch.py 2007-11-21 23:35:32 +0000
@@ -231,6 +231,8 @@
br2 = Branch.open('br2')
br1 = Branch.open('br1')
wt2 = WorkingTree.open('br2').merge_from_branch(br1)
+ br2.lock_read()
+ self.addCleanup(br2.unlock)
for rev_id, text in [('1-2', 'original from 1\n'),
('1-3', 'agreement\n'),
('2-1', 'contents in 2\n'),
@@ -264,7 +266,8 @@
def test_weaves_are_retrieved_once(self):
self.build_tree(("source/", "source/file", "target/"))
- wt = self.make_branch_and_tree('source')
+ # This test depends on knit dasta storage.
+ wt = self.make_branch_and_tree('source', format='dirstate-tags')
branch = wt.branch
wt.add(["file"], ["id"])
wt.commit("added file")
=== modified file 'bzrlib/tests/test_graph.py'
--- a/bzrlib/tests/test_graph.py 2007-10-22 05:44:49 +0000
+++ b/bzrlib/tests/test_graph.py 2007-11-21 23:39:40 +0000
@@ -162,7 +162,7 @@
def make_graph(self, ancestors):
tree = self.prepare_memory_tree('.')
self.build_ancestry(tree, ancestors)
- tree.unlock()
+ self.addCleanup(tree.unlock)
return tree.branch.repository.get_graph()
def prepare_memory_tree(self, location):
@@ -271,13 +271,14 @@
"""Ensure we do unique_lca using data from two repos"""
mainline_tree = self.prepare_memory_tree('mainline')
self.build_ancestry(mainline_tree, mainline)
- mainline_tree.unlock()
+ self.addCleanup(mainline_tree.unlock)
# This is cheating, because the revisions in the graph are actually
# different revisions, despite having the same revision-id.
feature_tree = self.prepare_memory_tree('feature')
self.build_ancestry(feature_tree, feature_branch)
- feature_tree.unlock()
+ self.addCleanup(feature_tree.unlock)
+
graph = mainline_tree.branch.repository.get_graph(
feature_tree.branch.repository)
self.assertEqual('rev2b', graph.find_unique_lca('rev2a', 'rev3b'))
=== modified file 'bzrlib/tests/test_memorytree.py'
--- a/bzrlib/tests/test_memorytree.py 2007-11-13 16:42:56 +0000
+++ b/bzrlib/tests/test_memorytree.py 2007-11-21 23:42:50 +0000
@@ -143,6 +143,8 @@
tree.unlock()
# and we should have a revision that is accessible outside the tree lock
revtree = tree.branch.repository.revision_tree(revision_id)
+ revtree.lock_read()
+ self.addCleanup(revtree.unlock)
self.assertEqual('barshoom', revtree.get_file('foo-id').read())
def test_unversion(self):
=== modified file 'bzrlib/tests/test_merge_core.py'
--- a/bzrlib/tests/test_merge_core.py 2007-08-29 16:09:51 +0000
+++ b/bzrlib/tests/test_merge_core.py 2007-11-21 23:57:02 +0000
@@ -725,6 +725,8 @@
this, other = self.set_up_trees()
self.assertRaises(errors.RevisionNotPresent, Merger.from_revision_ids,
progress.DummyProgress(), this, 'rev2b')
+ this.lock_write()
+ self.addCleanup(this.unlock)
merger = Merger.from_revision_ids(progress.DummyProgress(), this,
'rev2b', other_branch=other.branch)
self.assertEqual('rev2b', merger.other_rev_id)
@@ -743,8 +745,12 @@
def test_from_mergeable(self):
this, other = self.set_up_trees()
other.commit('rev3', rev_id='rev3')
+ this.lock_write()
+ self.addCleanup(this.unlock)
md = merge_directive.MergeDirective2.from_objects(
other.branch.repository, 'rev3', 0, 0, 'this')
+ other.lock_read()
+ self.addCleanup(other.unlock)
merger, verified = Merger.from_mergeable(this, md,
progress.DummyProgress())
md.patch = None
=== modified file 'bzrlib/tests/test_merge_directive.py'
--- a/bzrlib/tests/test_merge_directive.py 2007-08-15 20:49:22 +0000
+++ b/bzrlib/tests/test_merge_directive.py 2007-11-22 00:05:12 +0000
@@ -565,9 +565,13 @@
def from_objects(self, repository, revision_id, time, timezone,
target_branch, patch_type='bundle', local_target_branch=None,
public_branch=None, message=None):
- return merge_directive.MergeDirective.from_objects(
- repository, revision_id, time, timezone, target_branch,
- patch_type, local_target_branch, public_branch, message)
+ repository.lock_write()
+ try:
+ return merge_directive.MergeDirective.from_objects( repository,
+ revision_id, time, timezone, target_branch, patch_type,
+ local_target_branch, public_branch, message)
+ finally:
+ repository.unlock()
def make_merge_directive(self, revision_id, testament_sha1, time, timezone,
target_branch, patch=None, patch_type=None,
=== modified file 'bzrlib/transport/local.py'
--- a/bzrlib/transport/local.py 2007-10-04 22:00:07 +0000
+++ b/bzrlib/transport/local.py 2007-11-22 00:29:58 +0000
@@ -307,7 +307,10 @@
"""See Transport.open_write_stream."""
# initialise the file
self.put_bytes_non_atomic(relpath, "", mode=mode)
- handle = open(self._abspath(relpath), 'wb')
+ abspath = self._abspath(relpath)
+ handle = open(abspath, 'wb')
+ if mode is not None:
+ self._check_mode_and_size(abspath, handle.fileno(), mode)
transport._file_streams[self.abspath(relpath)] = handle
return transport.FileFileStream(self, relpath, handle)
More information about the bazaar-commits
mailing list