Rev 4476: merge trunk again in file:///home/vila/src/bzr/bugs/206577-send-strict/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Wed Jul 1 09:38:13 BST 2009
At file:///home/vila/src/bzr/bugs/206577-send-strict/
------------------------------------------------------------
revno: 4476 [merge]
revision-id: v.ladeuil+lp at free.fr-20090701083812-9p6w0aim50nk22em
parent: v.ladeuil+lp at free.fr-20090701072036-z0v9p3wk5hwsu480
parent: pqm at pqm.ubuntu.com-20090701083204-fzy3czqk0ifjyri2
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 206577-send-strict
timestamp: Wed 2009-07-01 10:38:12 +0200
message:
merge trunk again
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/errors.py errors.py-20050309040759-20512168c4e14fbd
bzrlib/revision.py revision.py-20050309040759-e77802c08f3999d5
bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
bzrlib/tests/blackbox/test_revision_info.py test_revision_info.py-20050917162600-21dab3877aa348d7
bzrlib/tests/blackbox/test_revno.py test_revno.py-20051204214528-2f0bf83a71b7656a
bzrlib/tests/test_revision.py testrevision.py-20050804210559-46f5e1eb67b01289
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2009-06-30 12:35:25 +0000
+++ b/NEWS 2009-07-01 08:38:12 +0000
@@ -26,6 +26,10 @@
speified. The configuration option ``push_strict`` can be used to set the
default for this behavior. (Vincent Ladeuil, #284038, #322808, #65286)
+* ``bzr revno`` and ``bzr revision-info`` now have a ``--tree`` option to
+ show revision info for the working tree instead of the branch.
+ (Matthew Fuller, John Arbash Meinel)
+
* ``bzr send`` now aborts if uncommitted changes (including pending merges)
are present in the working tree and no revision is specified. The
configuration option ``send_strict`` can be used to set the default for this
@@ -141,6 +145,11 @@
or ``bzr+ssh://`` is now much faster and involves no VFS operations.
This speeds up commands like ``bzr pull -r 123``. (Andrew Bennetts)
+* ``revision-info`` now properly aligns the revnos/revids in the output
+ and doesn't traceback when given revisions not in the current branch.
+ Performance is also significantly improved when requesting multiple revs
+ at once. (Matthew Fuller, John Arbash Meinel)
+
Documentation
*************
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2009-07-01 07:20:36 +0000
+++ b/bzrlib/builtins.py 2009-07-01 08:38:12 +0000
@@ -474,11 +474,36 @@
_see_also = ['info']
takes_args = ['location?']
+ takes_options = [
+ Option('tree', help='Show revno of working tree'),
+ ]
@display_command
- def run(self, location=u'.'):
- self.outf.write(str(Branch.open_containing(location)[0].revno()))
- self.outf.write('\n')
+ def run(self, tree=False, location=u'.'):
+ if tree:
+ try:
+ wt = WorkingTree.open_containing(location)[0]
+ wt.lock_read()
+ except (errors.NoWorkingTree, errors.NotLocalUrl):
+ raise errors.NoWorkingTree(location)
+ try:
+ revid = wt.last_revision()
+ try:
+ revno_t = wt.branch.revision_id_to_dotted_revno(revid)
+ except errors.NoSuchRevision:
+ revno_t = ('???',)
+ revno = ".".join(str(n) for n in revno_t)
+ finally:
+ wt.unlock()
+ else:
+ b = Branch.open_containing(location)[0]
+ b.lock_read()
+ try:
+ revno = b.revno()
+ finally:
+ b.unlock()
+
+ self.outf.write(str(revno) + '\n')
class cmd_revision_info(Command):
@@ -494,31 +519,56 @@
short_name='d',
type=unicode,
),
+ Option('tree', help='Show revno of working tree'),
]
@display_command
- def run(self, revision=None, directory=u'.', revision_info_list=[]):
-
- revs = []
- if revision is not None:
- revs.extend(revision)
- if revision_info_list is not None:
- for rev in revision_info_list:
- revs.append(RevisionSpec.from_string(rev))
-
- b = Branch.open_containing(directory)[0]
-
- if len(revs) == 0:
- revs.append(RevisionSpec.from_string('-1'))
-
- for rev in revs:
- revision_id = rev.as_revision_id(b)
- try:
- revno = '%4d' % (b.revision_id_to_revno(revision_id))
- except errors.NoSuchRevision:
- dotted_map = b.get_revision_id_to_revno_map()
- revno = '.'.join(str(i) for i in dotted_map[revision_id])
- print '%s %s' % (revno, revision_id)
+ def run(self, revision=None, directory=u'.', tree=False,
+ revision_info_list=[]):
+
+ try:
+ wt = WorkingTree.open_containing(directory)[0]
+ b = wt.branch
+ wt.lock_read()
+ except (errors.NoWorkingTree, errors.NotLocalUrl):
+ wt = None
+ b = Branch.open_containing(directory)[0]
+ b.lock_read()
+ try:
+ revision_ids = []
+ if revision is not None:
+ revision_ids.extend(rev.as_revision_id(b) for rev in revision)
+ if revision_info_list is not None:
+ for rev_str in revision_info_list:
+ rev_spec = RevisionSpec.from_string(rev_str)
+ revision_ids.append(rev_spec.as_revision_id(b))
+ # No arguments supplied, default to the last revision
+ if len(revision_ids) == 0:
+ if tree:
+ if wt is None:
+ raise errors.NoWorkingTree(directory)
+ revision_ids.append(wt.last_revision())
+ else:
+ revision_ids.append(b.last_revision())
+
+ revinfos = []
+ maxlen = 0
+ for revision_id in revision_ids:
+ try:
+ dotted_revno = b.revision_id_to_dotted_revno(revision_id)
+ revno = '.'.join(str(i) for i in dotted_revno)
+ except errors.NoSuchRevision:
+ revno = '???'
+ maxlen = max(maxlen, len(revno))
+ revinfos.append([revno, revision_id])
+ finally:
+ if wt is None:
+ b.unlock()
+ else:
+ wt.unlock()
+
+ for ri in revinfos:
+ self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
class cmd_add(Command):
@@ -1067,7 +1117,14 @@
and (strict is None or strict)): # Default to True:
changes = tree.changes_from(tree.basis_tree())
if changes.has_changed() or len(tree.get_parent_ids()) > 1:
- raise errors.UncommittedChanges(tree)
+ raise errors.UncommittedChanges(
+ tree, more='Use --no-strict to force the push.')
+ if tree.last_revision() != tree.branch.last_revision():
+ # The tree has lost sync with its branch, there is little
+ # chance that the user is aware of it but he can still force
+ # the push with --no-strict
+ raise errors.OutOfDateTree(
+ tree, more='Use --no-strict to force the push.')
# Get the stacked_on branch, if any
if stacked_on is not None:
=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py 2009-06-30 08:06:35 +0000
+++ b/bzrlib/errors.py 2009-06-30 15:54:23 +0000
@@ -2093,11 +2093,16 @@
class OutOfDateTree(BzrError):
- _fmt = "Working tree is out of date, please run 'bzr update'."
+ _fmt = "Working tree is out of date, please run 'bzr update'.%(more)s"
- def __init__(self, tree):
+ def __init__(self, tree, more=None):
+ if more is None:
+ more = ''
+ else:
+ more = ' ' + more
BzrError.__init__(self)
self.tree = tree
+ self.more = more
class PublicBranchOutOfDate(BzrError):
@@ -2779,13 +2784,17 @@
class UncommittedChanges(BzrError):
_fmt = ('Working tree "%(display_url)s" has uncommitted changes'
- ' (See bzr status).')
+ ' (See bzr status).%(more)s')
- def __init__(self, tree):
+ def __init__(self, tree, more=None):
+ if more is None:
+ more = ''
+ else:
+ more = ' ' + more
import bzrlib.urlutils as urlutils
display_url = urlutils.unescape_for_display(
tree.bzrdir.root_transport.base, 'ascii')
- BzrError.__init__(self, tree=tree, display_url=display_url)
+ BzrError.__init__(self, tree=tree, display_url=display_url, more=more)
class MissingTemplateVariable(BzrError):
=== modified file 'bzrlib/revision.py'
--- a/bzrlib/revision.py 2009-06-19 03:47:11 +0000
+++ b/bzrlib/revision.py 2009-06-30 16:16:55 +0000
@@ -111,8 +111,13 @@
def get_summary(self):
"""Get the first line of the log message for this revision.
+
+ Return an empty string if message is None.
"""
- return self.message.lstrip().split('\n', 1)[0]
+ if self.message:
+ return self.message.lstrip().split('\n', 1)[0]
+ else:
+ return ''
@symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((1, 13, 0)))
def get_apparent_author(self):
=== modified file 'bzrlib/tests/blackbox/test_push.py'
--- a/bzrlib/tests/blackbox/test_push.py 2009-06-30 09:19:06 +0000
+++ b/bzrlib/tests/blackbox/test_push.py 2009-06-30 15:54:23 +0000
@@ -47,8 +47,10 @@
changes_scenarios = [
('uncommitted',
dict(_changes_type= '_uncommitted_changes')),
- ('pending_merges',
+ ('pending-merges',
dict(_changes_type= '_pending_merges')),
+ ('out-of-sync-trees',
+ dict(_changes_type= '_out_of_sync_trees')),
]
tests.multiply_tests(changes_tests, changes_scenarios, result)
# No parametrization for the remaining tests
@@ -588,7 +590,7 @@
self.assertEqual('', out)
-class TestPushStrict(tests.TestCaseWithTransport):
+class TestPushStrictMixin(object):
def make_local_branch_and_tree(self):
self.tree = self.make_branch_and_tree('local')
@@ -604,17 +606,21 @@
conf = self.tree.branch.get_config()
conf.set_user_option('push_strict', value)
+ _default_command = ['push', '../to']
+ _default_wd = 'local'
+ _default_errors = ['Working tree ".*/local/" has uncommitted '
+ 'changes \(See bzr status\)\.',]
+ _default_pushed_revid = 'modified'
+
def assertPushFails(self, args):
- self.run_bzr_error(['Working tree ".*/local/"'
- ' has uncommitted changes \(See bzr status\)\.',],
- ['push', '../to'] + args,
- working_dir='local', retcode=3)
+ self.run_bzr_error(self._default_errors, self._default_command + args,
+ working_dir=self._default_wd, retcode=3)
def assertPushSucceeds(self, args, pushed_revid=None):
- self.run_bzr(['push', '../to'] + args,
- working_dir='local')
+ self.run_bzr(self._default_command + args,
+ working_dir=self._default_wd)
if pushed_revid is None:
- pushed_revid = 'modified'
+ pushed_revid = self._default_pushed_revid
tree_to = workingtree.WorkingTree.open('to')
repo_to = tree_to.branch.repository
self.assertTrue(repo_to.has_revision(pushed_revid))
@@ -622,7 +628,8 @@
-class TestPushStrictWithoutChanges(TestPushStrict):
+class TestPushStrictWithoutChanges(tests.TestCaseWithTransport,
+ TestPushStrictMixin):
def setUp(self):
super(TestPushStrictWithoutChanges, self).setUp()
@@ -646,7 +653,8 @@
self.assertPushSucceeds([])
-class TestPushStrictWithChanges(TestPushStrict):
+class TestPushStrictWithChanges(tests.TestCaseWithTransport,
+ TestPushStrictMixin):
_changes_type = None # Set by load_tests
@@ -671,6 +679,18 @@
self.tree.merge_from_branch(other_tree.branch)
self.tree.revert(filenames=['other-file'], backups=False)
+ def _out_of_sync_trees(self):
+ self.make_local_branch_and_tree()
+ self.run_bzr(['checkout', '--lightweight', 'local', 'checkout'])
+ # Make a change and commit it
+ self.build_tree_contents([('local/file', 'modified in local')])
+ self.tree.commit('modify file', rev_id='modified-in-local')
+ # Exercise commands from the checkout directory
+ self._default_wd = 'checkout'
+ self._default_errors = ["Working tree is out of date, please run"
+ " 'bzr update'\.",]
+ self._default_pushed_revid = 'modified-in-local'
+
def test_push_default(self):
self.assertPushFails([])
=== modified file 'bzrlib/tests/blackbox/test_revision_info.py'
--- a/bzrlib/tests/blackbox/test_revision_info.py 2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/blackbox/test_revision_info.py 2009-06-30 16:59:21 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005 Canonical Ltd
+# Copyright (C) 2004, 2005, 2009 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -47,9 +47,9 @@
# Expected return values
values = {
- '1' : ' 1 a at r-0-1\n',
+ '1' : '1 a at r-0-1\n',
'1.1.1': '1.1.1 a at r-0-1.1.1\n',
- '2' : ' 2 a at r-0-2\n'
+ '2' : '2 a at r-0-2\n'
}
# Make sure with no arg it defaults to the head
@@ -60,7 +60,9 @@
self.check_output(values['1.1.1'], 'revision-info 1.1.1')
self.check_output(values['2'], 'revision-info 2')
self.check_output(values['1']+values['2'], 'revision-info 1 2')
- self.check_output(values['1']+values['1.1.1']+values['2'],
+ self.check_output(' '+values['1']+
+ values['1.1.1']+
+ ' '+values['2'],
'revision-info 1 1.1.1 2')
self.check_output(values['2']+values['1'], 'revision-info 2 1')
@@ -70,7 +72,9 @@
self.check_output(values['1.1.1'], 'revision-info --revision 1.1.1')
self.check_output(values['2'], 'revision-info -r 2')
self.check_output(values['1']+values['2'], 'revision-info -r 1..2')
- self.check_output(values['1']+values['1.1.1']+values['2'],
+ self.check_output(' '+values['1']+
+ values['1.1.1']+
+ ' '+values['2'],
'revision-info -r 1..1.1.1..2')
self.check_output(values['2']+values['1'], 'revision-info -r 2..1')
@@ -85,4 +89,40 @@
wt = self.make_branch_and_tree('branch')
wt.commit('Commit one', rev_id='a at r-0-1')
- self.check_output(' 1 a at r-0-1\n', 'revision-info -d branch')
+ self.check_output('1 a at r-0-1\n', 'revision-info -d branch')
+
+ def test_revision_info_tree(self):
+ # Make branch and checkout
+ wt = self.make_branch_and_tree('branch')
+ wt.commit('Commit one', rev_id='a at r-0-1')
+
+ # Make checkout and move the branch forward
+ wt.branch.create_checkout('checkout', lightweight=True)
+ wt.commit('Commit two', rev_id='a at r-0-2')
+
+ # Make sure the checkout gives the right answer for branch and
+ # tree
+ self.check_output('2 a at r-0-2\n', 'revision-info -d checkout')
+ self.check_output('1 a at r-0-1\n', 'revision-info --tree -d checkout')
+
+ def test_revision_info_tree_no_working_tree(self):
+ # Make branch with no tree
+ b = self.make_branch('branch')
+
+ # Try getting the --tree revision-info
+ out,err = self.run_bzr('revision-info --tree -d branch', retcode=3)
+ self.assertEqual('', out)
+ self.assertEqual('bzr: ERROR: No WorkingTree exists for "branch".\n',
+ err)
+
+ def test_revision_info_not_in_history(self):
+ builder = self.make_branch_builder('branch')
+ builder.start_series()
+ builder.build_snapshot('A-id', None, [
+ ('add', ('', 'root-id', 'directory', None))])
+ builder.build_snapshot('B-id', ['A-id'], [])
+ builder.build_snapshot('C-id', ['A-id'], [])
+ builder.finish_series()
+ self.check_output(' 1 A-id\n??? B-id\n 2 C-id\n',
+ 'revision-info -d branch'
+ ' revid:A-id revid:B-id revid:C-id')
=== modified file 'bzrlib/tests/blackbox/test_revno.py'
--- a/bzrlib/tests/blackbox/test_revno.py 2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/blackbox/test_revno.py 2009-06-30 16:59:21 +0000
@@ -1,5 +1,4 @@
-# Copyright (C) 2005 Canonical Ltd
-# -*- coding: utf-8 -*-
+# Copyright (C) 2005, 2006, 2007, 2009 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -21,10 +20,9 @@
import os
-from bzrlib.branch import Branch
-from bzrlib.tests import TestCaseInTempDir
+from bzrlib import tests
-class TestRevno(TestCaseInTempDir):
+class TestRevno(tests.TestCaseWithTransport):
def test_revno(self):
@@ -50,4 +48,72 @@
self.assertEquals(int(bzr('revno a')), 2)
self.assertEquals(int(bzr('revno a/baz')), 2)
-
+ def test_revno_tree(self):
+ # Make branch and checkout
+ wt = self.make_branch_and_tree('branch')
+ checkout = wt.branch.create_checkout('checkout', lightweight=True)
+
+ # Get the checkout out of date
+ self.build_tree(['branch/file'])
+ wt.add(['file'])
+ wt.commit('mkfile')
+
+ # Make sure revno says we're on 1
+ out,err = self.run_bzr('revno checkout')
+ self.assertEqual('', err)
+ self.assertEqual('1\n', out)
+
+ # Make sure --tree knows it's still on 0
+ out,err = self.run_bzr('revno --tree checkout')
+ self.assertEqual('', err)
+ self.assertEqual('0\n', out)
+
+ def test_revno_tree_no_tree(self):
+ # Make treeless branch
+ b = self.make_branch('branch')
+
+ # Try getting it's --tree revno
+ out,err = self.run_bzr('revno --tree branch', retcode=3)
+ self.assertEqual('', out)
+ self.assertEqual('bzr: ERROR: No WorkingTree exists for "branch".\n',
+ err)
+
+ def test_dotted_revno_tree(self):
+ builder = self.make_branch_builder('branch')
+ builder.start_series()
+ builder.build_snapshot('A-id', None, [
+ ('add', ('', 'root-id', 'directory', None)),
+ ('add', ('file', 'file-id', 'file', 'content\n'))])
+ builder.build_snapshot('B-id', ['A-id'], [])
+ builder.build_snapshot('C-id', ['A-id', 'B-id'], [])
+ builder.finish_series()
+ b = builder.get_branch()
+ co_b = b.create_checkout('checkout_b', lightweight=True,
+ revision_id='B-id')
+ out, err = self.run_bzr('revno checkout_b')
+ self.assertEqual('', err)
+ self.assertEqual('2\n', out)
+ out, err = self.run_bzr('revno --tree checkout_b')
+ self.assertEqual('', err)
+ self.assertEqual('1.1.1\n', out)
+
+ def test_stale_revno_tree(self):
+ builder = self.make_branch_builder('branch')
+ builder.start_series()
+ builder.build_snapshot('A-id', None, [
+ ('add', ('', 'root-id', 'directory', None)),
+ ('add', ('file', 'file-id', 'file', 'content\n'))])
+ builder.build_snapshot('B-id', ['A-id'], [])
+ builder.build_snapshot('C-id', ['A-id'], [])
+ builder.finish_series()
+ b = builder.get_branch()
+ # The branch is now at "C-id", but the checkout is still at "B-id"
+ # which is no longer in the history
+ co_b = b.create_checkout('checkout_b', lightweight=True,
+ revision_id='B-id')
+ out, err = self.run_bzr('revno checkout_b')
+ self.assertEqual('', err)
+ self.assertEqual('2\n', out)
+ out, err = self.run_bzr('revno --tree checkout_b')
+ self.assertEqual('', err)
+ self.assertEqual('???\n', out)
=== modified file 'bzrlib/tests/test_revision.py'
--- a/bzrlib/tests/test_revision.py 2009-04-09 23:59:02 +0000
+++ b/bzrlib/tests/test_revision.py 2009-06-03 10:24:28 +0000
@@ -208,6 +208,8 @@
self.assertEqual('a', r.get_summary())
r.message = '\na\nb'
self.assertEqual('a', r.get_summary())
+ r.message = None
+ self.assertEqual('', r.get_summary())
def test_get_apparent_author(self):
r = revision.Revision('1')
More information about the bazaar-commits
mailing list