1069
690
' directory exists, but does not already'
1070
691
' have a control directory. This flag will'
1071
692
' allow push to proceed.'),
1073
help='Create a stacked branch that references the public location '
1074
'of the parent branch.'),
1075
Option('stacked-on',
1076
help='Create a stacked branch that refers to another branch '
1077
'for the commit history. Only the work not present in the '
1078
'referenced branch is included in the branch created.',
1081
help='Refuse to push if there are uncommitted changes in'
1082
' the working tree, --no-strict disables the check.'),
1084
694
takes_args = ['location?']
1085
695
encoding_type = 'replace'
1087
697
def run(self, location=None, remember=False, overwrite=False,
1088
create_prefix=False, verbose=False, revision=None,
1089
use_existing_dir=False, directory=None, stacked_on=None,
1090
stacked=False, strict=None):
1091
from bzrlib.push import _show_push_branch
698
create_prefix=False, verbose=False,
699
use_existing_dir=False,
701
# FIXME: Way too big! Put this into a function called from the
1093
703
if directory is None:
1095
# Get the source branch
1097
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1099
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1100
if strict is None: strict = True # default value
1101
# Get the tip's revision_id
1102
revision = _get_one_revision('push', revision)
1103
if revision is not None:
1104
revision_id = revision.in_history(br_from).rev_id
1107
if strict and tree is not None and revision_id is None:
1108
if (tree.has_changes(tree.basis_tree())
1109
or len(tree.get_parent_ids()) > 1):
1110
raise errors.UncommittedChanges(
1111
tree, more='Use --no-strict to force the push.')
1112
if tree.last_revision() != tree.branch.last_revision():
1113
# The tree has lost sync with its branch, there is little
1114
# chance that the user is aware of it but he can still force
1115
# the push with --no-strict
1116
raise errors.OutOfDateTree(
1117
tree, more='Use --no-strict to force the push.')
1119
# Get the stacked_on branch, if any
1120
if stacked_on is not None:
1121
stacked_on = urlutils.normalize_url(stacked_on)
1123
parent_url = br_from.get_parent()
1125
parent = Branch.open(parent_url)
1126
stacked_on = parent.get_public_branch()
1128
# I considered excluding non-http url's here, thus forcing
1129
# 'public' branches only, but that only works for some
1130
# users, so it's best to just depend on the user spotting an
1131
# error by the feedback given to them. RBC 20080227.
1132
stacked_on = parent_url
1134
raise errors.BzrCommandError(
1135
"Could not determine branch to refer to.")
1137
# Get the destination location
705
br_from = Branch.open_containing(directory)[0]
706
stored_loc = br_from.get_push_location()
1138
707
if location is None:
1139
stored_loc = br_from.get_push_location()
1140
708
if stored_loc is None:
1141
raise errors.BzrCommandError(
1142
"No push location known or specified.")
709
raise errors.BzrCommandError("No push location known or specified.")
1144
711
display_url = urlutils.unescape_for_display(stored_loc,
1145
712
self.outf.encoding)
1146
self.outf.write("Using saved push location: %s\n" % display_url)
713
self.outf.write("Using saved location: %s\n" % display_url)
1147
714
location = stored_loc
1149
_show_push_branch(br_from, revision_id, location, self.outf,
1150
verbose=verbose, overwrite=overwrite, remember=remember,
1151
stacked_on=stacked_on, create_prefix=create_prefix,
1152
use_existing_dir=use_existing_dir)
716
to_transport = transport.get_transport(location)
718
br_to = repository_to = dir_to = None
720
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
721
except errors.NotBranchError:
722
pass # Didn't find anything
724
# If we can open a branch, use its direct repository, otherwise see
725
# if there is a repository without a branch.
727
br_to = dir_to.open_branch()
728
except errors.NotBranchError:
729
# Didn't find a branch, can we find a repository?
731
repository_to = dir_to.find_repository()
732
except errors.NoRepositoryPresent:
735
# Found a branch, so we must have found a repository
736
repository_to = br_to.repository
740
# The destination doesn't exist; create it.
741
# XXX: Refactor the create_prefix/no_create_prefix code into a
742
# common helper function
744
to_transport.mkdir('.')
745
except errors.FileExists:
746
if not use_existing_dir:
747
raise errors.BzrCommandError("Target directory %s"
748
" already exists, but does not have a valid .bzr"
749
" directory. Supply --use-existing-dir to push"
750
" there anyway." % location)
751
except errors.NoSuchFile:
752
if not create_prefix:
753
raise errors.BzrCommandError("Parent directory of %s"
755
"\nYou may supply --create-prefix to create all"
756
" leading parent directories."
758
_create_prefix(to_transport)
760
# Now the target directory exists, but doesn't have a .bzr
761
# directory. So we need to create it, along with any work to create
762
# all of the dependent branches, etc.
763
dir_to = br_from.bzrdir.clone_on_transport(to_transport,
764
revision_id=br_from.last_revision())
765
br_to = dir_to.open_branch()
766
# TODO: Some more useful message about what was copied
767
note('Created new branch.')
768
# We successfully created the target, remember it
769
if br_from.get_push_location() is None or remember:
770
br_from.set_push_location(br_to.base)
771
elif repository_to is None:
772
# we have a bzrdir but no branch or repository
773
# XXX: Figure out what to do other than complain.
774
raise errors.BzrCommandError("At %s you have a valid .bzr control"
775
" directory, but not a branch or repository. This is an"
776
" unsupported configuration. Please move the target directory"
777
" out of the way and try again."
780
# We have a repository but no branch, copy the revisions, and then
782
last_revision_id = br_from.last_revision()
783
repository_to.fetch(br_from.repository,
784
revision_id=last_revision_id)
785
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
786
note('Created new branch.')
787
if br_from.get_push_location() is None or remember:
788
br_from.set_push_location(br_to.base)
789
else: # We have a valid to branch
790
# We were able to connect to the remote location, so remember it
791
# we don't need to successfully push because of possible divergence.
792
if br_from.get_push_location() is None or remember:
793
br_from.set_push_location(br_to.base)
794
old_rh = br_to.revision_history()
797
tree_to = dir_to.open_workingtree()
798
except errors.NotLocalUrl:
799
warning("This transport does not update the working "
800
"tree of: %s. See 'bzr help working-trees' for "
801
"more information." % br_to.base)
802
push_result = br_from.push(br_to, overwrite)
803
except errors.NoWorkingTree:
804
push_result = br_from.push(br_to, overwrite)
808
push_result = br_from.push(tree_to.branch, overwrite)
812
except errors.DivergedBranches:
813
raise errors.BzrCommandError('These branches have diverged.'
814
' Try using "merge" and then "push".')
815
if push_result is not None:
816
push_result.report(self.outf)
818
new_rh = br_to.revision_history()
821
from bzrlib.log import show_changed_revisions
822
show_changed_revisions(br_to, old_rh, new_rh,
825
# we probably did a clone rather than a push, so a message was
1155
830
class cmd_branch(Command):
1156
"""Create a new branch that is a copy of an existing branch.
831
"""Create a new copy of a branch.
1158
833
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1159
834
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
2022
1582
raise errors.BzrCommandError(msg)
2025
def _parse_levels(s):
2029
msg = "The levels argument must be an integer."
2030
raise errors.BzrCommandError(msg)
2033
1585
class cmd_log(Command):
2034
"""Show historical log for a branch or subset of a branch.
2036
log is bzr's default tool for exploring the history of a branch.
2037
The branch to use is taken from the first parameter. If no parameters
2038
are given, the branch containing the working directory is logged.
2039
Here are some simple examples::
2041
bzr log log the current branch
2042
bzr log foo.py log a file in its branch
2043
bzr log http://server/branch log a branch on a server
2045
The filtering, ordering and information shown for each revision can
2046
be controlled as explained below. By default, all revisions are
2047
shown sorted (topologically) so that newer revisions appear before
2048
older ones and descendants always appear before ancestors. If displayed,
2049
merged revisions are shown indented under the revision in which they
2054
The log format controls how information about each revision is
2055
displayed. The standard log formats are called ``long``, ``short``
2056
and ``line``. The default is long. See ``bzr help log-formats``
2057
for more details on log formats.
2059
The following options can be used to control what information is
2062
-l N display a maximum of N revisions
2063
-n N display N levels of revisions (0 for all, 1 for collapsed)
2064
-v display a status summary (delta) for each revision
2065
-p display a diff (patch) for each revision
2066
--show-ids display revision-ids (and file-ids), not just revnos
2068
Note that the default number of levels to display is a function of the
2069
log format. If the -n option is not used, the standard log formats show
2070
just the top level (mainline).
2072
Status summaries are shown using status flags like A, M, etc. To see
2073
the changes explained using words like ``added`` and ``modified``
2074
instead, use the -vv option.
2078
To display revisions from oldest to newest, use the --forward option.
2079
In most cases, using this option will have little impact on the total
2080
time taken to produce a log, though --forward does not incrementally
2081
display revisions like --reverse does when it can.
2083
:Revision filtering:
2085
The -r option can be used to specify what revision or range of revisions
2086
to filter against. The various forms are shown below::
2088
-rX display revision X
2089
-rX.. display revision X and later
2090
-r..Y display up to and including revision Y
2091
-rX..Y display from X to Y inclusive
2093
See ``bzr help revisionspec`` for details on how to specify X and Y.
2094
Some common examples are given below::
2096
-r-1 show just the tip
2097
-r-10.. show the last 10 mainline revisions
2098
-rsubmit:.. show what's new on this branch
2099
-rancestor:path.. show changes since the common ancestor of this
2100
branch and the one at location path
2101
-rdate:yesterday.. show changes since yesterday
2103
When logging a range of revisions using -rX..Y, log starts at
2104
revision Y and searches back in history through the primary
2105
("left-hand") parents until it finds X. When logging just the
2106
top level (using -n1), an error is reported if X is not found
2107
along the way. If multi-level logging is used (-n0), X may be
2108
a nested merge revision and the log will be truncated accordingly.
2112
If parameters are given and the first one is not a branch, the log
2113
will be filtered to show only those revisions that changed the
2114
nominated files or directories.
2116
Filenames are interpreted within their historical context. To log a
2117
deleted file, specify a revision range so that the file existed at
2118
the end or start of the range.
2120
Historical context is also important when interpreting pathnames of
2121
renamed files/directories. Consider the following example:
2123
* revision 1: add tutorial.txt
2124
* revision 2: modify tutorial.txt
2125
* revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
2129
* ``bzr log guide.txt`` will log the file added in revision 1
2131
* ``bzr log tutorial.txt`` will log the new file added in revision 3
2133
* ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2134
the original file in revision 2.
2136
* ``bzr log -r2 -p guide.txt`` will display an error message as there
2137
was no file called guide.txt in revision 2.
2139
Renames are always followed by log. By design, there is no need to
2140
explicitly ask for this (and no way to stop logging a file back
2141
until it was last renamed).
2145
The --message option can be used for finding revisions that match a
2146
regular expression in a commit message.
2150
GUI tools and IDEs are often better at exploring history than command
2151
line tools. You may prefer qlog or glog from the QBzr and Bzr-Gtk packages
2152
respectively for example. (TortoiseBzr uses qlog for displaying logs.) See
2153
http://bazaar-vcs.org/BzrPlugins and http://bazaar-vcs.org/IDEIntegration.
2155
Web interfaces are often better at exploring history than command line
2156
tools, particularly for branches on servers. You may prefer Loggerhead
2157
or one of its alternatives. See http://bazaar-vcs.org/WebInterface.
2159
You may find it useful to add the aliases below to ``bazaar.conf``::
2163
top = log -l10 --line
2166
``bzr tip`` will then show the latest revision while ``bzr top``
2167
will show the last 10 mainline revisions. To see the details of a
2168
particular revision X, ``bzr show -rX``.
2170
If you are interested in looking deeper into a particular merge X,
2171
use ``bzr log -n0 -rX``.
2173
``bzr log -v`` on a branch with lots of history is currently
2174
very slow. A fix for this issue is currently under development.
2175
With or without that fix, it is recommended that a revision range
2176
be given when using the -v option.
2178
bzr has a generic full-text matching plugin, bzr-search, that can be
2179
used to find revisions matching user names, commit messages, etc.
2180
Among other features, this plugin can find all revisions containing
2181
a list of words but not others.
2183
When exploring non-mainline history on large projects with deep
2184
history, the performance of log can be greatly improved by installing
2185
the historycache plugin. This plugin buffers historical information
2186
trading disk space for faster speed.
1586
"""Show log of a branch, file, or directory.
1588
By default show the log of the branch containing the working directory.
1590
To request a range of logs, you can use the command -r begin..end
1591
-r revision requests a specific revision, -r ..end or -r begin.. are
1597
bzr log -r -10.. http://server/branch
2188
takes_args = ['file*']
2189
_see_also = ['log-formats', 'revisionspec']
1600
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1602
takes_args = ['location?']
2190
1603
takes_options = [
2191
1604
Option('forward',
2192
1605
help='Show from oldest to newest.'),
2194
custom_help('verbose',
1608
help='Display timezone as local, original, or utc.'),
2195
1611
help='Show files changed in each revision.'),
2199
type=bzrlib.option._parse_revision_str,
2201
help='Show just the specified revision.'
2202
' See also "help revisionspec".'),
2206
help='Number of levels to display - 0 for all, 1 for flat.',
2208
type=_parse_levels),
2209
1615
Option('message',
2210
1616
short_name='m',
2211
1617
help='Show revisions whose message matches this '
2212
1618
'regular expression.',
2214
1620
Option('limit',
2216
1621
help='Limit the output to the first N revisions.',
2218
1623
type=_parse_limit),
2221
help='Show changes made in each revision as a patch.'),
2222
Option('include-merges',
2223
help='Show merged revisions like --levels 0 does.'),
2225
1625
encoding_type = 'replace'
2227
1627
@display_command
2228
def run(self, file_list=None, timezone='original',
1628
def run(self, location=None, timezone='original',
2230
1630
show_ids=False,
2234
1633
log_format=None,
2239
include_merges=False):
2240
from bzrlib.log import (
2242
make_log_request_dict,
2243
_get_info_for_log_files,
1636
from bzrlib.log import show_log
1637
assert message is None or isinstance(message, basestring), \
1638
"invalid message argument %r" % message
2245
1639
direction = (forward and 'forward') or 'reverse'
2250
raise errors.BzrCommandError(
2251
'--levels and --include-merges are mutually exclusive')
2253
if change is not None:
2255
raise errors.RangeInChangeOption()
2256
if revision is not None:
2257
raise errors.BzrCommandError(
2258
'--revision and --change are mutually exclusive')
2263
filter_by_dir = False
2265
# find the file ids to log and check for directory filtering
2266
b, file_info_list, rev1, rev2 = _get_info_for_log_files(revision,
2268
for relpath, file_id, kind in file_info_list:
1644
# find the file id to log:
1646
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1650
tree = b.basis_tree()
1651
file_id = tree.path2id(fp)
2269
1652
if file_id is None:
2270
1653
raise errors.BzrCommandError(
2271
"Path unknown at end or start of revision range: %s" %
2273
# If the relpath is the top of the tree, we log everything
2278
file_ids.append(file_id)
2279
filter_by_dir = filter_by_dir or (
2280
kind in ['directory', 'tree-reference'])
1654
"Path does not have any revision history: %s" %
2283
# FIXME ? log the current subdir only RBC 20060203
1658
# FIXME ? log the current subdir only RBC 20060203
2284
1659
if revision is not None \
2285
1660
and len(revision) > 0 and revision[0].get_branch():
2286
1661
location = revision[0].get_branch()
3610
2629
short_name='d',
3613
Option('preview', help='Instead of merging, show a diff of the'
3615
Option('interactive', help='Select changes interactively.',
3619
def run(self, location=None, revision=None, force=False,
3620
merge_type=None, show_base=False, reprocess=None, remember=False,
2634
def run(self, branch=None, revision=None, force=False, merge_type=None,
2635
show_base=False, reprocess=False, remember=False,
3621
2636
uncommitted=False, pull=False,
3622
2637
directory=None,
2639
from bzrlib.tag import _merge_tags_if_possible
2640
other_revision_id = None
3626
2641
if merge_type is None:
3627
2642
merge_type = _mod_merge.Merge3Merger
3629
2644
if directory is None: directory = u'.'
3630
possible_transports = []
3632
allow_pending = True
3633
verified = 'inapplicable'
2645
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2646
# inventory. Because merge is a mutating operation, it really
2647
# should be a lock_write() for the whole cmd_merge operation.
2648
# However, cmd_merge open's its own tree in _merge_helper, which
2649
# means if we lock here, the later lock_write() will always block.
2650
# Either the merge helper code should be updated to take a tree,
2651
# (What about tree.merge_from_branch?)
3634
2652
tree = WorkingTree.open_containing(directory)[0]
3636
# die as quickly as possible if there are uncommitted changes
3638
basis_tree = tree.revision_tree(tree.last_revision())
3639
except errors.NoSuchRevision:
3640
basis_tree = tree.basis_tree()
3642
if tree.has_changes(basis_tree):
3643
raise errors.UncommittedChanges(tree)
3645
view_info = _get_view_info_for_change_reporter(tree)
3646
2653
change_reporter = delta._ChangeReporter(
3647
unversioned_filter=tree.is_ignored, view_info=view_info)
2654
unversioned_filter=tree.is_ignored)
2656
if branch is not None:
2658
mergeable = bundle.read_mergeable_from_url(
2660
except errors.NotABundle:
2661
pass # Continue on considering this url a Branch
2663
if revision is not None:
2664
raise errors.BzrCommandError(
2665
'Cannot use -r with merge directives or bundles')
2666
other_revision_id = mergeable.install_revisions(
2667
tree.branch.repository)
2668
revision = [RevisionSpec.from_string(
2669
'revid:' + other_revision_id)]
2671
if revision is None \
2672
or len(revision) < 1 or revision[0].needs_branch():
2673
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2675
if revision is None or len(revision) < 1:
2678
other = [branch, None]
2681
other = [branch, -1]
2682
other_branch, path = Branch.open_containing(branch)
2685
raise errors.BzrCommandError('Cannot use --uncommitted and'
2686
' --revision at the same time.')
2687
branch = revision[0].get_branch() or branch
2688
if len(revision) == 1:
2690
if other_revision_id is not None:
2695
other_branch, path = Branch.open_containing(branch)
2696
revno = revision[0].in_history(other_branch).revno
2697
other = [branch, revno]
2699
assert len(revision) == 2
2700
if None in revision:
2701
raise errors.BzrCommandError(
2702
"Merge doesn't permit empty revision specifier.")
2703
base_branch, path = Branch.open_containing(branch)
2704
branch1 = revision[1].get_branch() or branch
2705
other_branch, path1 = Branch.open_containing(branch1)
2706
if revision[0].get_branch() is not None:
2707
# then path was obtained from it, and is None.
2710
base = [branch, revision[0].in_history(base_branch).revno]
2711
other = [branch1, revision[1].in_history(other_branch).revno]
2713
if ((tree.branch.get_parent() is None or remember) and
2714
other_branch is not None):
2715
tree.branch.set_parent(other_branch.base)
2717
# pull tags now... it's a bit inconsistent to do it ahead of copying
2718
# the history but that's done inside the merge code
2719
if other_branch is not None:
2720
_merge_tags_if_possible(other_branch, tree.branch)
2723
interesting_files = [path]
2725
interesting_files = None
2726
pb = ui.ui_factory.nested_progress_bar()
3650
pb = ui.ui_factory.nested_progress_bar()
3651
cleanups.append(pb.finished)
3653
cleanups.append(tree.unlock)
3654
if location is not None:
3656
mergeable = bundle.read_mergeable_from_url(location,
3657
possible_transports=possible_transports)
3658
except errors.NotABundle:
3662
raise errors.BzrCommandError('Cannot use --uncommitted'
3663
' with bundles or merge directives.')
3665
if revision is not None:
3666
raise errors.BzrCommandError(
3667
'Cannot use -r with merge directives or bundles')
3668
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3671
if merger is None and uncommitted:
3672
if revision is not None and len(revision) > 0:
3673
raise errors.BzrCommandError('Cannot use --uncommitted and'
3674
' --revision at the same time.')
3675
merger = self.get_merger_from_uncommitted(tree, location, pb,
3677
allow_pending = False
3680
merger, allow_pending = self._get_merger_from_branch(tree,
3681
location, revision, remember, possible_transports, pb)
3683
merger.merge_type = merge_type
3684
merger.reprocess = reprocess
3685
merger.show_base = show_base
3686
self.sanity_check_merger(merger)
3687
if (merger.base_rev_id == merger.other_rev_id and
3688
merger.other_rev_id is not None):
3689
note('Nothing to do.')
2729
conflict_count = _merge_helper(
2730
other, base, other_rev_id=other_revision_id,
2731
check_clean=(not force),
2732
merge_type=merge_type,
2733
reprocess=reprocess,
2734
show_base=show_base,
2737
pb=pb, file_list=interesting_files,
2738
change_reporter=change_reporter)
2741
if conflict_count != 0:
3692
if merger.interesting_files is not None:
3693
raise errors.BzrCommandError('Cannot pull individual files')
3694
if (merger.base_rev_id == tree.last_revision()):
3695
result = tree.pull(merger.other_branch, False,
3696
merger.other_rev_id)
3697
result.report(self.outf)
3699
merger.check_basis(False)
3701
return self._do_preview(merger, cleanups)
3703
return self._do_interactive(merger, cleanups)
3705
return self._do_merge(merger, change_reporter, allow_pending,
3708
for cleanup in reversed(cleanups):
3711
def _get_preview(self, merger, cleanups):
3712
tree_merger = merger.make_merger()
3713
tt = tree_merger.make_preview_transform()
3714
cleanups.append(tt.finalize)
3715
result_tree = tt.get_preview_tree()
3718
def _do_preview(self, merger, cleanups):
3719
from bzrlib.diff import show_diff_trees
3720
result_tree = self._get_preview(merger, cleanups)
3721
show_diff_trees(merger.this_tree, result_tree, self.outf,
3722
old_label='', new_label='')
3724
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3725
merger.change_reporter = change_reporter
3726
conflict_count = merger.do_merge()
3728
merger.set_pending()
3729
if verified == 'failed':
3730
warning('Preview patch does not match changes')
3731
if conflict_count != 0:
3736
def _do_interactive(self, merger, cleanups):
3737
"""Perform an interactive merge.
3739
This works by generating a preview tree of the merge, then using
3740
Shelver to selectively remove the differences between the working tree
3741
and the preview tree.
3743
from bzrlib import shelf_ui
3744
result_tree = self._get_preview(merger, cleanups)
3745
writer = bzrlib.option.diff_writer_registry.get()
3746
shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
3747
reporter=shelf_ui.ApplyReporter(),
3748
diff_writer=writer(sys.stdout))
3751
def sanity_check_merger(self, merger):
3752
if (merger.show_base and
3753
not merger.merge_type is _mod_merge.Merge3Merger):
3754
raise errors.BzrCommandError("Show-base is not supported for this"
3755
" merge type. %s" % merger.merge_type)
3756
if merger.reprocess is None:
3757
if merger.show_base:
3758
merger.reprocess = False
3760
# Use reprocess if the merger supports it
3761
merger.reprocess = merger.merge_type.supports_reprocess
3762
if merger.reprocess and not merger.merge_type.supports_reprocess:
3763
raise errors.BzrCommandError("Conflict reduction is not supported"
3764
" for merge type %s." %
3766
if merger.reprocess and merger.show_base:
3767
raise errors.BzrCommandError("Cannot do conflict reduction and"
3770
def _get_merger_from_branch(self, tree, location, revision, remember,
3771
possible_transports, pb):
3772
"""Produce a merger from a location, assuming it refers to a branch."""
3773
from bzrlib.tag import _merge_tags_if_possible
3774
# find the branch locations
3775
other_loc, user_location = self._select_branch_location(tree, location,
3777
if revision is not None and len(revision) == 2:
3778
base_loc, _unused = self._select_branch_location(tree,
3779
location, revision, 0)
3781
base_loc = other_loc
3783
other_branch, other_path = Branch.open_containing(other_loc,
3784
possible_transports)
3785
if base_loc == other_loc:
3786
base_branch = other_branch
3788
base_branch, base_path = Branch.open_containing(base_loc,
3789
possible_transports)
3790
# Find the revision ids
3791
other_revision_id = None
3792
base_revision_id = None
3793
if revision is not None:
3794
if len(revision) >= 1:
3795
other_revision_id = revision[-1].as_revision_id(other_branch)
3796
if len(revision) == 2:
3797
base_revision_id = revision[0].as_revision_id(base_branch)
3798
if other_revision_id is None:
3799
other_revision_id = _mod_revision.ensure_null(
3800
other_branch.last_revision())
3801
# Remember where we merge from
3802
if ((remember or tree.branch.get_submit_branch() is None) and
3803
user_location is not None):
3804
tree.branch.set_submit_branch(other_branch.base)
3805
_merge_tags_if_possible(other_branch, tree.branch)
3806
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3807
other_revision_id, base_revision_id, other_branch, base_branch)
3808
if other_path != '':
3809
allow_pending = False
3810
merger.interesting_files = [other_path]
3812
allow_pending = True
3813
return merger, allow_pending
3815
def get_merger_from_uncommitted(self, tree, location, pb, cleanups):
3816
"""Get a merger for uncommitted changes.
3818
:param tree: The tree the merger should apply to.
3819
:param location: The location containing uncommitted changes.
3820
:param pb: The progress bar to use for showing progress.
3821
:param cleanups: A list of operations to perform to clean up the
3822
temporary directories, unfinalized objects, etc.
3824
location = self._select_branch_location(tree, location)[0]
3825
other_tree, other_path = WorkingTree.open_containing(location)
3826
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree, pb)
3827
if other_path != '':
3828
merger.interesting_files = [other_path]
3831
def _select_branch_location(self, tree, user_location, revision=None,
3833
"""Select a branch location, according to possible inputs.
3835
If provided, branches from ``revision`` are preferred. (Both
3836
``revision`` and ``index`` must be supplied.)
3838
Otherwise, the ``location`` parameter is used. If it is None, then the
3839
``submit`` or ``parent`` location is used, and a note is printed.
3841
:param tree: The working tree to select a branch for merging into
3842
:param location: The location entered by the user
3843
:param revision: The revision parameter to the command
3844
:param index: The index to use for the revision parameter. Negative
3845
indices are permitted.
3846
:return: (selected_location, user_location). The default location
3847
will be the user-entered location.
3849
if (revision is not None and index is not None
3850
and revision[index] is not None):
3851
branch = revision[index].get_branch()
3852
if branch is not None:
3853
return branch, branch
3854
if user_location is None:
3855
location = self._get_remembered(tree, 'Merging from')
3857
location = user_location
3858
return location, user_location
3860
def _get_remembered(self, tree, verb_string):
2745
except errors.AmbiguousBase, e:
2746
m = ("sorry, bzr can't determine the right merge base yet\n"
2747
"candidates are:\n "
2748
+ "\n ".join(e.bases)
2750
"please specify an explicit base with -r,\n"
2751
"and (if you want) report this to the bzr developers\n")
2754
# TODO: move up to common parent; this isn't merge-specific anymore.
2755
def _get_remembered_parent(self, tree, supplied_location, verb_string):
3861
2756
"""Use tree.branch's parent if none was supplied.
3863
2758
Report if the remembered location was used.
3865
stored_location = tree.branch.get_submit_branch()
3866
stored_location_type = "submit"
3867
if stored_location is None:
3868
stored_location = tree.branch.get_parent()
3869
stored_location_type = "parent"
2760
if supplied_location is not None:
2761
return supplied_location
2762
stored_location = tree.branch.get_parent()
3870
2763
mutter("%s", stored_location)
3871
2764
if stored_location is None:
3872
2765
raise errors.BzrCommandError("No location specified or remembered")
3873
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
3874
note(u"%s remembered %s location %s", verb_string,
3875
stored_location_type, display_url)
2766
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2767
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
3876
2768
return stored_location
4078
2950
takes_args = ['context?']
4079
2951
aliases = ['s-c']
4082
2954
@display_command
4083
2955
def run(self, context=None):
4084
2956
import shellcomplete
4085
2957
shellcomplete.shellcomplete(context)
2960
class cmd_fetch(Command):
2961
"""Copy in history from another branch but don't merge it.
2963
This is an internal method used for pull and merge.
2966
takes_args = ['from_branch', 'to_branch']
2967
def run(self, from_branch, to_branch):
2968
from bzrlib.fetch import Fetcher
2969
from_b = Branch.open(from_branch)
2970
to_b = Branch.open(to_branch)
2971
Fetcher(to_b, from_b)
4088
2974
class cmd_missing(Command):
4089
2975
"""Show unmerged/unpulled revisions between two branches.
4091
2977
OTHER_BRANCH may be local or remote.
4093
To filter on a range of revisions, you can use the command -r begin..end
4094
-r revision requests a specific revision, -r ..end or -r begin.. are
4099
Determine the missing revisions between this and the branch at the
4100
remembered pull location::
4104
Determine the missing revisions between this and another branch::
4106
bzr missing http://server/branch
4108
Determine the missing revisions up to a specific revision on the other
4111
bzr missing -r ..-10
4113
Determine the missing revisions up to a specific revision on this
4116
bzr missing --my-revision ..-10
4119
2980
_see_also = ['merge', 'pull']
4120
2981
takes_args = ['other_branch?']
4121
2982
takes_options = [
4122
Option('reverse', 'Reverse the order of revisions.'),
4124
'Display changes in the local branch only.'),
4125
Option('this' , 'Same as --mine-only.'),
4126
Option('theirs-only',
4127
'Display changes in the remote branch only.'),
4128
Option('other', 'Same as --theirs-only.'),
4132
custom_help('revision',
4133
help='Filter on other branch revisions (inclusive). '
4134
'See "help revisionspec" for details.'),
4135
Option('my-revision',
4136
type=_parse_revision_str,
4137
help='Filter on local branch revisions (inclusive). '
4138
'See "help revisionspec" for details.'),
4139
Option('include-merges',
4140
'Show all revisions in addition to the mainline ones.'),
2983
Option('reverse', 'Reverse the order of revisions.'),
2985
'Display changes in the local branch only.'),
2986
Option('this' , 'Same as --mine-only.'),
2987
Option('theirs-only',
2988
'Display changes in the remote branch only.'),
2989
Option('other', 'Same as --theirs-only.'),
4142
2994
encoding_type = 'replace'
4144
2996
@display_command
4145
2997
def run(self, other_branch=None, reverse=False, mine_only=False,
4147
log_format=None, long=False, short=False, line=False,
4148
show_ids=False, verbose=False, this=False, other=False,
4149
include_merges=False, revision=None, my_revision=None):
2998
theirs_only=False, log_format=None, long=False, short=False, line=False,
2999
show_ids=False, verbose=False, this=False, other=False):
4150
3000
from bzrlib.missing import find_unmerged, iter_log_revisions
3001
from bzrlib.log import log_formatter
4159
# TODO: We should probably check that we don't have mine-only and
4160
# theirs-only set, but it gets complicated because we also have
4161
# this and other which could be used.
4168
3008
local_branch = Branch.open_containing(u".")[0]
4169
3009
parent = local_branch.get_parent()
4170
3010
if other_branch is None:
4171
3011
other_branch = parent
4172
3012
if other_branch is None:
4173
raise errors.BzrCommandError("No peer location known"
3013
raise errors.BzrCommandError("No peer location known or specified.")
4175
3014
display_url = urlutils.unescape_for_display(parent,
4176
3015
self.outf.encoding)
4177
message("Using saved parent location: "
4178
+ display_url + "\n")
3016
print "Using last location: " + display_url
4180
3018
remote_branch = Branch.open(other_branch)
4181
3019
if remote_branch.base == local_branch.base:
4182
3020
remote_branch = local_branch
4184
local_revid_range = _revision_range_to_revid_range(
4185
_get_revision_range(my_revision, local_branch,
4188
remote_revid_range = _revision_range_to_revid_range(
4189
_get_revision_range(revision,
4190
remote_branch, self.name()))
4192
3021
local_branch.lock_read()
4194
3023
remote_branch.lock_read()
4196
local_extra, remote_extra = find_unmerged(
4197
local_branch, remote_branch, restrict,
4198
backward=not reverse,
4199
include_merges=include_merges,
4200
local_revid_range=local_revid_range,
4201
remote_revid_range=remote_revid_range)
4203
if log_format is None:
4204
registry = log.log_formatter_registry
4205
log_format = registry.get_default(local_branch)
3025
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
3026
if (log_format is None):
3027
log_format = log.log_formatter_registry.get_default(
4206
3029
lf = log_format(to_file=self.outf,
4207
3030
show_ids=show_ids,
4208
3031
show_timezone='original')
3032
if reverse is False:
3033
local_extra.reverse()
3034
remote_extra.reverse()
4211
3035
if local_extra and not theirs_only:
4212
message("You have %d extra revision(s):\n" %
4214
for revision in iter_log_revisions(local_extra,
3036
print "You have %d extra revision(s):" % len(local_extra)
3037
for revision in iter_log_revisions(local_extra,
4215
3038
local_branch.repository,
4217
3040
lf.log_revision(revision)
4218
3041
printed_local = True
4221
3043
printed_local = False
4223
3044
if remote_extra and not mine_only:
4224
3045
if printed_local is True:
4226
message("You are missing %d revision(s):\n" %
4228
for revision in iter_log_revisions(remote_extra,
4229
remote_branch.repository,
3047
print "You are missing %d revision(s):" % len(remote_extra)
3048
for revision in iter_log_revisions(remote_extra,
3049
remote_branch.repository,
4231
3051
lf.log_revision(revision)
3052
if not remote_extra and not local_extra:
3054
print "Branches are up to date."
4232
3056
status_code = 1
4234
if mine_only and not local_extra:
4235
# We checked local, and found nothing extra
4236
message('This branch is up to date.\n')
4237
elif theirs_only and not remote_extra:
4238
# We checked remote, and found nothing extra
4239
message('Other branch is up to date.\n')
4240
elif not (mine_only or theirs_only or local_extra or
4242
# We checked both branches, and neither one had extra
4244
message("Branches are up to date.\n")
4246
3058
remote_branch.unlock()
4913
3626
s.send_email(message)
4916
class cmd_send(Command):
4917
"""Mail or create a merge-directive for submitting changes.
4919
A merge directive provides many things needed for requesting merges:
4921
* A machine-readable description of the merge to perform
4923
* An optional patch that is a preview of the changes requested
4925
* An optional bundle of revision data, so that the changes can be applied
4926
directly from the merge directive, without retrieving data from a
4929
If --no-bundle is specified, then public_branch is needed (and must be
4930
up-to-date), so that the receiver can perform the merge using the
4931
public_branch. The public_branch is always included if known, so that
4932
people can check it later.
4934
The submit branch defaults to the parent, but can be overridden. Both
4935
submit branch and public branch will be remembered if supplied.
4937
If a public_branch is known for the submit_branch, that public submit
4938
branch is used in the merge instructions. This means that a local mirror
4939
can be used as your actual submit branch, once you have set public_branch
4942
Mail is sent using your preferred mail program. This should be transparent
4943
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
4944
If the preferred client can't be found (or used), your editor will be used.
4946
To use a specific mail program, set the mail_client configuration option.
4947
(For Thunderbird 1.5, this works around some bugs.) Supported values for
4948
specific clients are "claws", "evolution", "kmail", "mutt", and
4949
"thunderbird"; generic options are "default", "editor", "emacsclient",
4950
"mapi", and "xdg-email". Plugins may also add supported clients.
4952
If mail is being sent, a to address is required. This can be supplied
4953
either on the commandline, by setting the submit_to configuration
4954
option in the branch itself or the child_submit_to configuration option
4955
in the submit branch.
4957
Two formats are currently supported: "4" uses revision bundle format 4 and
4958
merge directive format 2. It is significantly faster and smaller than
4959
older formats. It is compatible with Bazaar 0.19 and later. It is the
4960
default. "0.9" uses revision bundle format 0.9 and merge directive
4961
format 1. It is compatible with Bazaar 0.12 - 0.18.
4963
The merge directives created by bzr send may be applied using bzr merge or
4964
bzr pull by specifying a file containing a merge directive as the location.
4967
encoding_type = 'exact'
4969
_see_also = ['merge', 'pull']
4971
takes_args = ['submit_branch?', 'public_branch?']
4975
help='Do not include a bundle in the merge directive.'),
4976
Option('no-patch', help='Do not include a preview patch in the merge'
4979
help='Remember submit and public branch.'),
4981
help='Branch to generate the submission from, '
4982
'rather than the one containing the working directory.',
4985
Option('output', short_name='o',
4986
help='Write merge directive to this file; '
4987
'use - for stdout.',
4990
help='Refuse to send if there are uncommitted changes in'
4991
' the working tree, --no-strict disables the check.'),
4992
Option('mail-to', help='Mail the request to this address.',
4996
Option('body', help='Body for the email.', type=unicode),
4997
RegistryOption('format',
4998
help='Use the specified output format.',
4999
lazy_registry=('bzrlib.send', 'format_registry')),
5002
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5003
no_patch=False, revision=None, remember=False, output=None,
5004
format=None, mail_to=None, message=None, body=None,
5005
strict=None, **kwargs):
5006
from bzrlib.send import send
5007
return send(submit_branch, revision, public_branch, remember,
5008
format, no_bundle, no_patch, output,
5009
kwargs.get('from', '.'), mail_to, message, body,
5014
class cmd_bundle_revisions(cmd_send):
5015
"""Create a merge-directive for submitting changes.
5017
A merge directive provides many things needed for requesting merges:
5019
* A machine-readable description of the merge to perform
5021
* An optional patch that is a preview of the changes requested
5023
* An optional bundle of revision data, so that the changes can be applied
5024
directly from the merge directive, without retrieving data from a
5027
If --no-bundle is specified, then public_branch is needed (and must be
5028
up-to-date), so that the receiver can perform the merge using the
5029
public_branch. The public_branch is always included if known, so that
5030
people can check it later.
5032
The submit branch defaults to the parent, but can be overridden. Both
5033
submit branch and public branch will be remembered if supplied.
5035
If a public_branch is known for the submit_branch, that public submit
5036
branch is used in the merge instructions. This means that a local mirror
5037
can be used as your actual submit branch, once you have set public_branch
5040
Two formats are currently supported: "4" uses revision bundle format 4 and
5041
merge directive format 2. It is significantly faster and smaller than
5042
older formats. It is compatible with Bazaar 0.19 and later. It is the
5043
default. "0.9" uses revision bundle format 0.9 and merge directive
5044
format 1. It is compatible with Bazaar 0.12 - 0.18.
5049
help='Do not include a bundle in the merge directive.'),
5050
Option('no-patch', help='Do not include a preview patch in the merge'
5053
help='Remember submit and public branch.'),
5055
help='Branch to generate the submission from, '
5056
'rather than the one containing the working directory.',
5059
Option('output', short_name='o', help='Write directive to this file.',
5062
help='Refuse to bundle revisions if there are uncommitted'
5063
' changes in the working tree, --no-strict disables the check.'),
5065
RegistryOption('format',
5066
help='Use the specified output format.',
5067
lazy_registry=('bzrlib.send', 'format_registry')),
5069
aliases = ['bundle']
5071
_see_also = ['send', 'merge']
5075
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5076
no_patch=False, revision=None, remember=False, output=None,
5077
format=None, strict=None, **kwargs):
5080
from bzrlib.send import send
5081
return send(submit_branch, revision, public_branch, remember,
5082
format, no_bundle, no_patch, output,
5083
kwargs.get('from', '.'), None, None, None,
5084
self.outf, strict=strict)
5087
3629
class cmd_tag(Command):
5088
"""Create, remove or modify a tag naming a revision.
3630
"""Create a tag naming a revision.
5090
3632
Tags give human-meaningful names to revisions. Commands that take a -r
5091
3633
(--revision) option can be given -rtag:X, where X is any previously
5160
3699
short_name='d',
5163
RegistryOption.from_kwargs('sort',
5164
'Sort tags by different criteria.', title='Sorting',
5165
alpha='Sort tags lexicographically (default).',
5166
time='Sort tags chronologically.',
5172
3704
@display_command
5179
3708
branch, relpath = Branch.open_containing(directory)
5181
tags = branch.tags.get_tag_dict().items()
5188
graph = branch.repository.get_graph()
5189
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5190
revid1, revid2 = rev1.rev_id, rev2.rev_id
5191
# only show revisions between revid1 and revid2 (inclusive)
5192
tags = [(tag, revid) for tag, revid in tags if
5193
graph.is_between(revid, revid1, revid2)]
5196
elif sort == 'time':
5198
for tag, revid in tags:
5200
revobj = branch.repository.get_revision(revid)
5201
except errors.NoSuchRevision:
5202
timestamp = sys.maxint # place them at the end
5204
timestamp = revobj.timestamp
5205
timestamps[revid] = timestamp
5206
tags.sort(key=lambda x: timestamps[x[1]])
5208
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5209
for index, (tag, revid) in enumerate(tags):
5211
revno = branch.revision_id_to_dotted_revno(revid)
5212
if isinstance(revno, tuple):
5213
revno = '.'.join(map(str, revno))
5214
except errors.NoSuchRevision:
5215
# Bad tag data/merges can lead to tagged revisions
5216
# which are not in this branch. Fail gracefully ...
5218
tags[index] = (tag, revno)
5221
for tag, revspec in tags:
5222
self.outf.write('%-20s %s\n' % (tag, revspec))
5225
class cmd_reconfigure(Command):
5226
"""Reconfigure the type of a bzr directory.
5228
A target configuration must be specified.
5230
For checkouts, the bind-to location will be auto-detected if not specified.
5231
The order of preference is
5232
1. For a lightweight checkout, the current bound location.
5233
2. For branches that used to be checkouts, the previously-bound location.
5234
3. The push location.
5235
4. The parent location.
5236
If none of these is available, --bind-to must be specified.
5239
_see_also = ['branches', 'checkouts', 'standalone-trees', 'working-trees']
5240
takes_args = ['location?']
5242
RegistryOption.from_kwargs(
5244
title='Target type',
5245
help='The type to reconfigure the directory to.',
5246
value_switches=True, enum_switch=False,
5247
branch='Reconfigure to be an unbound branch with no working tree.',
5248
tree='Reconfigure to be an unbound branch with a working tree.',
5249
checkout='Reconfigure to be a bound branch with a working tree.',
5250
lightweight_checkout='Reconfigure to be a lightweight'
5251
' checkout (with no local history).',
5252
standalone='Reconfigure to be a standalone branch '
5253
'(i.e. stop using shared repository).',
5254
use_shared='Reconfigure to use a shared repository.',
5255
with_trees='Reconfigure repository to create '
5256
'working trees on branches by default.',
5257
with_no_trees='Reconfigure repository to not create '
5258
'working trees on branches by default.'
5260
Option('bind-to', help='Branch to bind checkout to.', type=str),
5262
help='Perform reconfiguration even if local changes'
5264
Option('stacked-on',
5265
help='Reconfigure a branch to be stacked on another branch.',
5269
help='Reconfigure a branch to be unstacked. This '
5270
'may require copying substantial data into it.',
5274
def run(self, location=None, target_type=None, bind_to=None, force=False,
5277
directory = bzrdir.BzrDir.open(location)
5278
if stacked_on and unstacked:
5279
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5280
elif stacked_on is not None:
5281
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5283
reconfigure.ReconfigureUnstacked().apply(directory)
5284
# At the moment you can use --stacked-on and a different
5285
# reconfiguration shape at the same time; there seems no good reason
5287
if target_type is None:
5288
if stacked_on or unstacked:
5291
raise errors.BzrCommandError('No target configuration '
5293
elif target_type == 'branch':
5294
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5295
elif target_type == 'tree':
5296
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5297
elif target_type == 'checkout':
5298
reconfiguration = reconfigure.Reconfigure.to_checkout(
5300
elif target_type == 'lightweight-checkout':
5301
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5303
elif target_type == 'use-shared':
5304
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5305
elif target_type == 'standalone':
5306
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5307
elif target_type == 'with-trees':
5308
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5310
elif target_type == 'with-no-trees':
5311
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5313
reconfiguration.apply(force)
5316
class cmd_switch(Command):
5317
"""Set the branch of a checkout and update.
5319
For lightweight checkouts, this changes the branch being referenced.
5320
For heavyweight checkouts, this checks that there are no local commits
5321
versus the current bound branch, then it makes the local branch a mirror
5322
of the new location and binds to it.
5324
In both cases, the working tree is updated and uncommitted changes
5325
are merged. The user can commit or revert these as they desire.
5327
Pending merges need to be committed or reverted before using switch.
5329
The path to the branch to switch to can be specified relative to the parent
5330
directory of the current branch. For example, if you are currently in a
5331
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
5334
Bound branches use the nickname of its master branch unless it is set
5335
locally, in which case switching will update the the local nickname to be
5339
takes_args = ['to_location']
5340
takes_options = [Option('force',
5341
help='Switch even if local commits will be lost.'),
5342
Option('create-branch', short_name='b',
5343
help='Create the target branch from this one before'
5344
' switching to it.'),
5347
def run(self, to_location, force=False, create_branch=False):
5348
from bzrlib import switch
5350
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5352
branch = control_dir.open_branch()
5353
had_explicit_nick = branch.get_config().has_explicit_nickname()
5354
except errors.NotBranchError:
5356
had_explicit_nick = False
5359
raise errors.BzrCommandError('cannot create branch without'
5361
if '/' not in to_location and '\\' not in to_location:
5362
# This path is meant to be relative to the existing branch
5363
this_url = self._get_branch_location(control_dir)
5364
to_location = urlutils.join(this_url, '..', to_location)
5365
to_branch = branch.bzrdir.sprout(to_location,
5366
possible_transports=[branch.bzrdir.root_transport],
5367
source_branch=branch).open_branch()
5369
# from_branch = control_dir.open_branch()
5370
# except errors.NotBranchError:
5371
# raise BzrCommandError('Cannot create a branch from this'
5372
# ' location when we cannot open this branch')
5373
# from_branch.bzrdir.sprout(
5377
to_branch = Branch.open(to_location)
5378
except errors.NotBranchError:
5379
this_url = self._get_branch_location(control_dir)
5380
to_branch = Branch.open(
5381
urlutils.join(this_url, '..', to_location))
5382
switch.switch(control_dir, to_branch, force)
5383
if had_explicit_nick:
5384
branch = control_dir.open_branch() #get the new branch!
5385
branch.nick = to_branch.nick
5386
note('Switched to branch: %s',
5387
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5389
def _get_branch_location(self, control_dir):
5390
"""Return location of branch for this control dir."""
5392
this_branch = control_dir.open_branch()
5393
# This may be a heavy checkout, where we want the master branch
5394
master_location = this_branch.get_bound_location()
5395
if master_location is not None:
5396
return master_location
5397
# If not, use a local sibling
5398
return this_branch.base
5399
except errors.NotBranchError:
5400
format = control_dir.find_branch_format()
5401
if getattr(format, 'get_reference', None) is not None:
5402
return format.get_reference(control_dir)
5404
return control_dir.root_transport.base
5407
class cmd_view(Command):
5408
"""Manage filtered views.
5410
Views provide a mask over the tree so that users can focus on
5411
a subset of a tree when doing their work. After creating a view,
5412
commands that support a list of files - status, diff, commit, etc -
5413
effectively have that list of files implicitly given each time.
5414
An explicit list of files can still be given but those files
5415
must be within the current view.
5417
In most cases, a view has a short life-span: it is created to make
5418
a selected change and is deleted once that change is committed.
5419
At other times, you may wish to create one or more named views
5420
and switch between them.
5422
To disable the current view without deleting it, you can switch to
5423
the pseudo view called ``off``. This can be useful when you need
5424
to see the whole tree for an operation or two (e.g. merge) but
5425
want to switch back to your view after that.
5428
To define the current view::
5430
bzr view file1 dir1 ...
5432
To list the current view::
5436
To delete the current view::
5440
To disable the current view without deleting it::
5442
bzr view --switch off
5444
To define a named view and switch to it::
5446
bzr view --name view-name file1 dir1 ...
5448
To list a named view::
5450
bzr view --name view-name
5452
To delete a named view::
5454
bzr view --name view-name --delete
5456
To switch to a named view::
5458
bzr view --switch view-name
5460
To list all views defined::
5464
To delete all views::
5466
bzr view --delete --all
5470
takes_args = ['file*']
5473
help='Apply list or delete action to all views.',
5476
help='Delete the view.',
5479
help='Name of the view to define, list or delete.',
5483
help='Name of the view to switch to.',
5488
def run(self, file_list,
5494
tree, file_list = tree_files(file_list, apply_view=False)
5495
current_view, view_dict = tree.views.get_view_info()
5500
raise errors.BzrCommandError(
5501
"Both --delete and a file list specified")
5503
raise errors.BzrCommandError(
5504
"Both --delete and --switch specified")
5506
tree.views.set_view_info(None, {})
5507
self.outf.write("Deleted all views.\n")
5509
raise errors.BzrCommandError("No current view to delete")
5511
tree.views.delete_view(name)
5512
self.outf.write("Deleted '%s' view.\n" % name)
5515
raise errors.BzrCommandError(
5516
"Both --switch and a file list specified")
5518
raise errors.BzrCommandError(
5519
"Both --switch and --all specified")
5520
elif switch == 'off':
5521
if current_view is None:
5522
raise errors.BzrCommandError("No current view to disable")
5523
tree.views.set_view_info(None, view_dict)
5524
self.outf.write("Disabled '%s' view.\n" % (current_view))
5526
tree.views.set_view_info(switch, view_dict)
5527
view_str = views.view_display_str(tree.views.lookup_view())
5528
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
5531
self.outf.write('Views defined:\n')
5532
for view in sorted(view_dict):
5533
if view == current_view:
5537
view_str = views.view_display_str(view_dict[view])
5538
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5540
self.outf.write('No views defined.\n')
5543
# No name given and no current view set
5546
raise errors.BzrCommandError(
5547
"Cannot change the 'off' pseudo view")
5548
tree.views.set_view(name, sorted(file_list))
5549
view_str = views.view_display_str(tree.views.lookup_view())
5550
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
5554
# No name given and no current view set
5555
self.outf.write('No current view.\n')
5557
view_str = views.view_display_str(tree.views.lookup_view(name))
5558
self.outf.write("'%s' view is: %s\n" % (name, view_str))
5561
class cmd_hooks(Command):
5567
for hook_key in sorted(hooks.known_hooks.keys()):
5568
some_hooks = hooks.known_hooks_key_to_object(hook_key)
5569
self.outf.write("%s:\n" % type(some_hooks).__name__)
5570
for hook_name, hook_point in sorted(some_hooks.items()):
5571
self.outf.write(" %s:\n" % (hook_name,))
5572
found_hooks = list(hook_point)
5574
for hook in found_hooks:
5575
self.outf.write(" %s\n" %
5576
(some_hooks.get_hook_name(hook),))
3709
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3710
self.outf.write('%-20s %s\n' % (tag_name, target))
3713
# command-line interpretation helper for merge-related commands
3714
def _merge_helper(other_revision, base_revision,
3715
check_clean=True, ignore_zero=False,
3716
this_dir=None, backup_files=False,
3718
file_list=None, show_base=False, reprocess=False,
3721
change_reporter=None,
3723
"""Merge changes into a tree.
3726
list(path, revno) Base for three-way merge.
3727
If [None, None] then a base will be automatically determined.
3729
list(path, revno) Other revision for three-way merge.
3731
Directory to merge changes into; '.' by default.
3733
If true, this_dir must have no uncommitted changes before the
3735
ignore_zero - If true, suppress the "zero conflicts" message when
3736
there are no conflicts; should be set when doing something we expect
3737
to complete perfectly.
3738
file_list - If supplied, merge only changes to selected files.
3740
All available ancestors of other_revision and base_revision are
3741
automatically pulled into the branch.
3743
The revno may be -1 to indicate the last revision on the branch, which is
3746
This function is intended for use from the command line; programmatic
3747
clients might prefer to call merge.merge_inner(), which has less magic
3750
# Loading it late, so that we don't always have to import bzrlib.merge
3751
if merge_type is None:
3752
merge_type = _mod_merge.Merge3Merger
3753
if this_dir is None:
3755
this_tree = WorkingTree.open_containing(this_dir)[0]
3756
if show_base and not merge_type is _mod_merge.Merge3Merger:
3757
raise errors.BzrCommandError("Show-base is not supported for this merge"
3758
" type. %s" % merge_type)
3759
if reprocess and not merge_type.supports_reprocess:
3760
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3761
" type %s." % merge_type)
3762
if reprocess and show_base:
3763
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3764
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3765
# only want to take out a lock_tree_write() if we don't have to pull
3766
# any ancestry. But merge might fetch ancestry in the middle, in
3767
# which case we would need a lock_write().
3768
# Because we cannot upgrade locks, for now we live with the fact that
3769
# the tree will be locked multiple times during a merge. (Maybe
3770
# read-only some of the time, but it means things will get read
3773
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3774
pb=pb, change_reporter=change_reporter)
3775
merger.pp = ProgressPhase("Merge phase", 5, pb)
3776
merger.pp.next_phase()
3777
merger.check_basis(check_clean)
3778
if other_rev_id is not None:
3779
merger.set_other_revision(other_rev_id, this_tree.branch)
3781
merger.set_other(other_revision)
3782
merger.pp.next_phase()
3783
merger.set_base(base_revision)
3784
if merger.base_rev_id == merger.other_rev_id:
3785
note('Nothing to do.')
3787
if file_list is None:
3788
if pull and merger.base_rev_id == merger.this_rev_id:
3789
# FIXME: deduplicate with pull
3790
result = merger.this_tree.pull(merger.this_branch,
3791
False, merger.other_rev_id)
3792
if result.old_revid == result.new_revid:
3793
note('No revisions to pull.')
5578
self.outf.write(" <no hooks installed>\n")
5581
class cmd_shelve(Command):
5582
"""Temporarily set aside some changes from the current tree.
5584
Shelve allows you to temporarily put changes you've made "on the shelf",
5585
ie. out of the way, until a later time when you can bring them back from
5586
the shelf with the 'unshelve' command. The changes are stored alongside
5587
your working tree, and so they aren't propagated along with your branch nor
5588
will they survive its deletion.
5590
If shelve --list is specified, previously-shelved changes are listed.
5592
Shelve is intended to help separate several sets of changes that have
5593
been inappropriately mingled. If you just want to get rid of all changes
5594
and you don't need to restore them later, use revert. If you want to
5595
shelve all text changes at once, use shelve --all.
5597
If filenames are specified, only the changes to those files will be
5598
shelved. Other files will be left untouched.
5600
If a revision is specified, changes since that revision will be shelved.
5602
You can put multiple items on the shelf, and by default, 'unshelve' will
5603
restore the most recently shelved changes.
5606
takes_args = ['file*']
5610
Option('all', help='Shelve all changes.'),
5612
RegistryOption('writer', 'Method to use for writing diffs.',
5613
bzrlib.option.diff_writer_registry,
5614
value_switches=True, enum_switch=False),
5616
Option('list', help='List shelved changes.'),
5618
help='Destroy removed changes instead of shelving them.'),
5620
_see_also = ['unshelve']
5622
def run(self, revision=None, all=False, file_list=None, message=None,
5623
writer=None, list=False, destroy=False):
5625
return self.run_for_list()
5626
from bzrlib.shelf_ui import Shelver
5628
writer = bzrlib.option.diff_writer_registry.get()
5630
Shelver.from_args(writer(sys.stdout), revision, all, file_list,
5631
message, destroy=destroy).run()
5632
except errors.UserAbort:
5635
def run_for_list(self):
5636
tree = WorkingTree.open_containing('.')[0]
5639
manager = tree.get_shelf_manager()
5640
shelves = manager.active_shelves()
5641
if len(shelves) == 0:
5642
note('No shelved changes.')
3795
note('Now on revision %d.' % result.new_revno)
5644
for shelf_id in reversed(shelves):
5645
message = manager.get_metadata(shelf_id).get('message')
5647
message = '<no message>'
5648
self.outf.write('%3d: %s\n' % (shelf_id, message))
5654
class cmd_unshelve(Command):
5655
"""Restore shelved changes.
5657
By default, the most recently shelved changes are restored. However if you
5658
specify a shelf by id those changes will be restored instead. This works
5659
best when the changes don't depend on each other.
5662
takes_args = ['shelf_id?']
5664
RegistryOption.from_kwargs(
5665
'action', help="The action to perform.",
5666
enum_switch=False, value_switches=True,
5667
apply="Apply changes and remove from the shelf.",
5668
dry_run="Show changes, but do not apply or remove them.",
5669
delete_only="Delete changes without applying them."
5672
_see_also = ['shelve']
5674
def run(self, shelf_id=None, action='apply'):
5675
from bzrlib.shelf_ui import Unshelver
5676
Unshelver.from_args(shelf_id, action).run()
5679
class cmd_clean_tree(Command):
5680
"""Remove unwanted files from working tree.
5682
By default, only unknown files, not ignored files, are deleted. Versioned
5683
files are never deleted.
5685
Another class is 'detritus', which includes files emitted by bzr during
5686
normal operations and selftests. (The value of these files decreases with
5689
If no options are specified, unknown files are deleted. Otherwise, option
5690
flags are respected, and may be combined.
5692
To check what clean-tree will do, use --dry-run.
5694
takes_options = [Option('ignored', help='Delete all ignored files.'),
5695
Option('detritus', help='Delete conflict files, merge'
5696
' backups, and failed selftest dirs.'),
5698
help='Delete files unknown to bzr (default).'),
5699
Option('dry-run', help='Show files to delete instead of'
5701
Option('force', help='Do not prompt before deleting.')]
5702
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5704
from bzrlib.clean_tree import clean_tree
5705
if not (unknown or ignored or detritus):
5709
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5710
dry_run=dry_run, no_prompt=force)
5713
class cmd_reference(Command):
5714
"""list, view and set branch locations for nested trees.
5716
If no arguments are provided, lists the branch locations for nested trees.
5717
If one argument is provided, display the branch location for that tree.
5718
If two arguments are provided, set the branch location for that tree.
5723
takes_args = ['path?', 'location?']
5725
def run(self, path=None, location=None):
5727
if path is not None:
5729
tree, branch, relpath =(
5730
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
5731
if path is not None:
5734
tree = branch.basis_tree()
5736
info = branch._get_all_reference_info().iteritems()
5737
self._display_reference_info(tree, branch, info)
3797
merger.backup_files = backup_files
3798
merger.merge_type = merge_type
3799
merger.set_interesting_files(file_list)
3800
merger.show_base = show_base
3801
merger.reprocess = reprocess
3802
conflicts = merger.do_merge()
3803
if file_list is None:
3804
merger.set_pending()
3810
def _create_prefix(cur_transport):
3811
needed = [cur_transport]
3812
# Recurse upwards until we can create a directory successfully
3814
new_transport = cur_transport.clone('..')
3815
if new_transport.base == cur_transport.base:
3816
raise errors.BzrCommandError(
3817
"Failed to create path prefix for %s."
3818
% cur_transport.base)
3820
new_transport.mkdir('.')
3821
except errors.NoSuchFile:
3822
needed.append(new_transport)
3823
cur_transport = new_transport
5739
file_id = tree.path2id(path)
5741
raise errors.NotVersionedError(path)
5742
if location is None:
5743
info = [(file_id, branch.get_reference_info(file_id))]
5744
self._display_reference_info(tree, branch, info)
5746
branch.set_reference_info(file_id, path, location)
5748
def _display_reference_info(self, tree, branch, info):
5750
for file_id, (path, location) in info:
5752
path = tree.id2path(file_id)
5753
except errors.NoSuchId:
5755
ref_list.append((path, location))
5756
for path, location in sorted(ref_list):
5757
self.outf.write('%s %s\n' % (path, location))
3826
# Now we only need to create child directories
3828
cur_transport = needed.pop()
3829
cur_transport.ensure_base()
3833
merge = _merge_helper
5760
3836
# these get imported and then picked up by the scan for cmd_*
5761
3837
# TODO: Some more consistent way to split command definitions across files;
5762
# we do need to load at least some information about them to know of
3838
# we do need to load at least some information about them to know of
5763
3839
# aliases. ideally we would avoid loading the implementation until the
5764
3840
# details were needed.
5765
3841
from bzrlib.cmd_version_info import cmd_version_info
5766
3842
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5767
from bzrlib.bundle.commands import (
5770
from bzrlib.foreign import cmd_dpush
3843
from bzrlib.bundle.commands import cmd_bundle_revisions
5771
3844
from bzrlib.sign_my_commits import cmd_sign_my_commits
5772
from bzrlib.weave_commands import cmd_versionedfile_list, \
3845
from bzrlib.weave_commands import cmd_versionedfile_list, cmd_weave_join, \
5773
3846
cmd_weave_plan_merge, cmd_weave_merge_text