Rev 2228: Add -d option to push, pull, merge commands. in file:///home/mbp/bzr/Work/tags/
Martin Pool
mbp at sourcefrog.net
Sun Jan 21 12:42:17 GMT 2007
------------------------------------------------------------
revno: 2228
revision-id: mbp at sourcefrog.net-20070121124213-8ksq92nrm3tzn6s9
parent: mbp at sourcefrog.net-20070121085653-ptonrp6w7ini27un
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: tags
timestamp: Sun 2007-01-21 23:42:13 +1100
message:
Add -d option to push, pull, merge commands.
Tags now propagate between repositories by commands that move history around:
branch, push, pull, merge.
Add Repository.supports_tags method.
All Repository tag methods now raise TagsNotSupported if they're not.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/blackbox/test_tags.py test_tags.py-20070116132048-5h4qak2cm22jlb9e-1
=== modified file 'NEWS'
--- a/NEWS 2007-01-03 02:09:52 +0000
+++ b/NEWS 2007-01-21 12:42:13 +0000
@@ -1,3 +1,12 @@
+ IMPROVEMENTS:
+
+ * New option ``-d`` for pull and other commands, specifying the
+ branch or tree to operate on rather than the working directory.
+ (Martin Pool)
+
+ * Builtin tags support, created by the ``tag`` command and stored
+ in the repository. (Martin Pool)
+
IN DEVELOPMENT
IMPROVEMENTS:
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2007-01-19 08:47:51 +0000
+++ b/bzrlib/builtins.py 2007-01-21 12:42:13 +0000
@@ -499,18 +499,29 @@
location can be accessed.
"""
- takes_options = ['remember', 'overwrite', 'revision', 'verbose']
+ takes_options = ['remember', 'overwrite', 'revision', 'verbose',
+ Option('directory',
+ help='branch to pull into, '
+ 'rather than the one containing the working directory',
+ short_name='d',
+ type=unicode,
+ ),
+ ]
takes_args = ['location?']
encoding_type = 'replace'
- def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
+ def run(self, location=None, remember=False, overwrite=False,
+ revision=None, verbose=False,
+ directory=None):
# FIXME: too much stuff is in the command class
+ if directory is None:
+ directory = u'.'
try:
- tree_to = WorkingTree.open_containing(u'.')[0]
+ tree_to = WorkingTree.open_containing(directory)[0]
branch_to = tree_to.branch
except errors.NoWorkingTree:
tree_to = None
- branch_to = Branch.open_containing(u'.')[0]
+ branch_to = Branch.open_containing(directory)[0]
reader = None
if location is not None:
@@ -530,7 +541,6 @@
self.outf.write("Using saved location: %s\n" % display_url)
location = stored_loc
-
if reader is not None:
install_bundle(branch_to.repository, reader)
branch_from = branch_to
@@ -554,6 +564,7 @@
count = tree_to.pull(branch_from, overwrite, rev_id)
else:
count = branch_to.pull(branch_from, overwrite, rev_id)
+ _copy_tags_maybe(branch_from, branch_to)
note('%d revision(s) pulled.' % (count,))
if verbose:
@@ -592,18 +603,27 @@
"""
takes_options = ['remember', 'overwrite', 'verbose',
- Option('create-prefix',
- help='Create the path leading up to the branch '
- 'if it does not already exist')]
+ Option('create-prefix',
+ help='Create the path leading up to the branch '
+ 'if it does not already exist'),
+ Option('directory',
+ help='branch to push from, '
+ 'rather than the one containing the working directory',
+ short_name='d',
+ type=unicode,
+ ),
+ ]
takes_args = ['location?']
encoding_type = 'replace'
def run(self, location=None, remember=False, overwrite=False,
- create_prefix=False, verbose=False):
+ create_prefix=False, verbose=False,
+ directory=None):
# FIXME: Way too big! Put this into a function called from the
# command.
-
- br_from = Branch.open_containing('.')[0]
+ if directory is None:
+ directory = '.'
+ br_from = Branch.open_containing(directory)[0]
stored_loc = br_from.get_push_location()
if location is None:
if stored_loc is None:
@@ -674,6 +694,7 @@
except errors.DivergedBranches:
raise errors.BzrCommandError('These branches have diverged.'
' Try using "merge" and then "push".')
+ _copy_tags_maybe(br_from, br_to)
note('%d revision(s) pushed.' % (count,))
if verbose:
@@ -759,11 +780,28 @@
raise errors.BzrCommandError(msg)
if name:
branch.control_files.put_utf8('branch-name', name)
+ _copy_tags_maybe(br_from, branch)
note('Branched %d revision(s).' % branch.revno())
finally:
br_from.unlock()
+def _copy_tags_maybe(from_branch, to_branch):
+ """Copy tags between repositories if necessary and possible.
+
+ This method has common command-line behaviour about handling
+ error cases.
+ """
+ from_repo = from_branch.repository
+ to_repo = to_branch.repository
+ if not from_repo.supports_tags():
+ # obviously nothing to copy
+ return
+ # TODO: give a warning if the source format supports tags and actually has
+ # tags, but the destination doesn't accept them.
+ from_repo.copy_tags_to(to_repo)
+
+
class cmd_checkout(Command):
"""Create a new checkout of an existing branch.
@@ -2235,6 +2273,10 @@
default, use --remember. The value will only be saved if the remote
location can be accessed.
+ The results of the merge are placed into the destination working
+ directory, where they can be reviewed (with bzr diff), tested, and then
+ committed to record the result of the merge.
+
Examples:
To merge the latest revision from bzr.dev
@@ -2253,15 +2295,21 @@
"""
takes_args = ['branch?']
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
- Option('show-base', help="Show base revision text in "
- "conflicts"),
- Option('uncommitted', help='Apply uncommitted changes'
- ' from a working copy, instead of branch changes'),
- Option('pull', help='If the destination is already'
- ' completely merged into the source, pull from the'
- ' source rather than merging. When this happens,'
- ' you do not need to commit the result.'),
- ]
+ Option('show-base', help="Show base revision text in "
+ "conflicts"),
+ Option('uncommitted', help='Apply uncommitted changes'
+ ' from a working copy, instead of branch changes'),
+ Option('pull', help='If the destination is already'
+ ' completely merged into the source, pull from the'
+ ' source rather than merging. When this happens,'
+ ' you do not need to commit the result.'),
+ Option('directory',
+ help='branch to push from, '
+ 'rather than the one containing the working directory',
+ short_name='d',
+ type=unicode,
+ ),
+ ]
def help(self):
from inspect import getdoc
@@ -2269,11 +2317,13 @@
def run(self, branch=None, revision=None, force=False, merge_type=None,
show_base=False, reprocess=False, remember=False,
- uncommitted=False, pull=False):
+ uncommitted=False, pull=False,
+ directory=None,
+ ):
if merge_type is None:
merge_type = _mod_merge.Merge3Merger
-
- tree = WorkingTree.open_containing(u'.')[0]
+ if directory is None: directory = u'.'
+ tree = WorkingTree.open_containing(directory)[0]
if branch is not None:
try:
@@ -2328,6 +2378,10 @@
if tree.branch.get_parent() is None or remember:
tree.branch.set_parent(other_branch.base)
+ # pull tags now... it's a bit inconsistent to do it ahead of copying
+ # the history but that's done inside the merge code
+ _copy_tags_maybe(other_branch, tree.branch)
+
if path != "":
interesting_files = [path]
else:
@@ -2341,6 +2395,7 @@
reprocess=reprocess,
show_base=show_base,
pull=pull,
+ this_dir=directory,
pb=pb, file_list=interesting_files)
finally:
pb.finished()
@@ -2995,7 +3050,16 @@
class cmd_tag(Command):
- """Create a tag naming a revision"""
+ """Create a tag naming a revision.
+
+ Tags give human-meaningful names to revisions. Commands that take a -r
+ (--revision) option can be given -rtag:X, where X is any previously
+ created tag.
+
+ Tags are stored in the repository, and apply to all branches stored
+ in the repository. Tags are copied from one branch to another along
+ when you branch, push, pull or merge.
+ """
takes_args = ['tag_name']
takes_options = [
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py 2007-01-21 08:56:53 +0000
+++ b/bzrlib/repository.py 2007-01-21 12:42:13 +0000
@@ -88,13 +88,22 @@
def _not_supported(self, *a, **k):
raise errors.TagsNotSupported(self.repository)
+ def supports_tags(self):
+ return False
+
set_tag = _not_supported
+ get_tag_dict = _not_supported
+ _set_tag_dict = _not_supported
+ lookup_tag = _not_supported
class _BasicTagStore(_TagStore):
"""Tag storage in an unversioned repository control file.
"""
+ def supports_tags(self):
+ return True
+
def set_tag(self, tag_name, tag_target):
"""Add a tag definition to the repository.
@@ -876,6 +885,9 @@
def _set_tag_dict(self, new_dict):
return self._tag_store._set_tag_dict(new_dict)
+ def supports_tags(self):
+ return self._tag_store.supports_tags()
+
def copy_tags_to(self, to_repository):
"""Copy tags to another repository.
@@ -2003,6 +2015,8 @@
# A default implementation is provided even though not all
# Repositories will support tags... we'll just get an error back from
# the underlying method.
+ if self.target == self.source:
+ return
self.target.lock_write()
try:
self.target._set_tag_dict(self.source.get_tag_dict())
=== modified file 'bzrlib/tests/blackbox/test_tags.py'
--- a/bzrlib/tests/blackbox/test_tags.py 2007-01-19 08:47:51 +0000
+++ b/bzrlib/tests/blackbox/test_tags.py 2007-01-21 12:42:13 +0000
@@ -19,7 +19,11 @@
from bzrlib.branch import Branch
from bzrlib.bzrdir import BzrDir
from bzrlib.tests import TestCaseWithTransport
-from bzrlib.repository import RepositoryFormatKnit2
+from bzrlib.repository import (
+ Repository,
+ RepositoryFormatKnit2,
+ )
+from bzrlib.workingtree import WorkingTree
class TestTagging(TestCaseWithTransport):
@@ -55,3 +59,30 @@
# can also create tags using -r
self.run_bzr('tag', '-d', 'branch', 'tag2', '-r1')
self.assertEquals(repo.lookup_tag('tag2'), 'first-revid')
+
+ def test_branch_push_pull_merge_copies_tags(self):
+ t = self.make_branch_and_tree('branch1')
+ t.commit(allow_pointless=True, message='initial commit',
+ rev_id='first-revid')
+ repo1 = t.branch.repository
+ repo1.set_tag('tag1', 'first-revid')
+ # branching copies the tag across
+ self.run_bzr('branch', 'branch1', 'branch2')
+ repo2 = Repository.open('branch2')
+ self.assertEquals(repo2.lookup_tag('tag1'), 'first-revid')
+ # make a new tag and pull it
+ repo1.set_tag('tag2', 'twa')
+ self.run_bzr('pull', '-d', 'branch2', 'branch1')
+ self.assertEquals(repo2.lookup_tag('tag2'), 'twa')
+ # make a new tag and push it
+ repo1.set_tag('tag3', 'san')
+ self.run_bzr('push', '-d', 'branch1', 'branch2')
+ self.assertEquals(repo2.lookup_tag('tag3'), 'san')
+ # make a new tag and merge it
+ t.commit(allow_pointless=True, message='second commit',
+ rev_id='second-revid')
+ t2 = WorkingTree.open('branch2')
+ t2.commit(allow_pointless=True, message='commit in second')
+ repo1.set_tag('tag4', 'second-revid')
+ self.run_bzr('merge', '-d', 'branch2', 'branch1')
+ self.assertEquals(repo2.lookup_tag('tag4'), 'second-revid')
More information about the bazaar-commits
mailing list