516
1053
location can be accessed.
519
takes_options = ['remember', 'overwrite', 'verbose',
520
Option('create-prefix',
521
help='Create the path leading up to the branch '
522
'if it does not already exist')]
1056
_see_also = ['pull', 'update', 'working-trees']
1057
takes_options = ['remember', 'overwrite', 'verbose', 'revision',
1058
Option('create-prefix',
1059
help='Create the path leading up to the branch '
1060
'if it does not already exist.'),
1062
help='Branch to push from, '
1063
'rather than the one containing the working directory.',
1067
Option('use-existing-dir',
1068
help='By default push will fail if the target'
1069
' directory exists, but does not already'
1070
' have a control directory. This flag will'
1071
' 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.'),
523
1084
takes_args = ['location?']
524
1085
encoding_type = 'replace'
526
1087
def run(self, location=None, remember=False, overwrite=False,
527
create_prefix=False, verbose=False):
528
# FIXME: Way too big! Put this into a function called from the
531
br_from = Branch.open_containing('.')[0]
532
stored_loc = br_from.get_push_location()
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
1093
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
533
1138
if location is None:
1139
stored_loc = br_from.get_push_location()
534
1140
if stored_loc is None:
535
raise BzrCommandError("No push location known or specified.")
1141
raise errors.BzrCommandError(
1142
"No push location known or specified.")
537
1144
display_url = urlutils.unescape_for_display(stored_loc,
538
1145
self.outf.encoding)
539
self.outf.write("Using saved location: %s\n" % display_url)
1146
self.outf.write("Using saved push location: %s\n" % display_url)
540
1147
location = stored_loc
542
to_transport = transport.get_transport(location)
543
location_url = to_transport.base
547
dir_to = bzrdir.BzrDir.open(location_url)
548
br_to = dir_to.open_branch()
549
except NotBranchError:
551
to_transport = to_transport.clone('..')
552
if not create_prefix:
554
relurl = to_transport.relpath(location_url)
555
mutter('creating directory %s => %s', location_url, relurl)
556
to_transport.mkdir(relurl)
558
raise BzrCommandError("Parent directory of %s "
559
"does not exist." % location)
561
current = to_transport.base
562
needed = [(to_transport, to_transport.relpath(location_url))]
565
to_transport, relpath = needed[-1]
566
to_transport.mkdir(relpath)
569
new_transport = to_transport.clone('..')
570
needed.append((new_transport,
571
new_transport.relpath(to_transport.base)))
572
if new_transport.base == to_transport.base:
573
raise BzrCommandError("Could not create "
575
dir_to = br_from.bzrdir.clone(location_url,
576
revision_id=br_from.last_revision())
577
br_to = dir_to.open_branch()
578
count = len(br_to.revision_history())
579
# We successfully created the target, remember it
580
if br_from.get_push_location() is None or remember:
581
br_from.set_push_location(br_to.base)
583
# We were able to connect to the remote location, so remember it
584
# we don't need to successfully push because of possible divergence.
585
if br_from.get_push_location() is None or remember:
586
br_from.set_push_location(br_to.base)
587
old_rh = br_to.revision_history()
590
tree_to = dir_to.open_workingtree()
591
except errors.NotLocalUrl:
592
warning('This transport does not update the working '
593
'tree of: %s' % (br_to.base,))
594
count = br_to.pull(br_from, overwrite)
595
except NoWorkingTree:
596
count = br_to.pull(br_from, overwrite)
598
count = tree_to.pull(br_from, overwrite)
599
except DivergedBranches:
600
raise BzrCommandError("These branches have diverged."
601
" Try a merge then push with overwrite.")
602
note('%d revision(s) pushed.' % (count,))
605
new_rh = br_to.revision_history()
608
from bzrlib.log import show_changed_revisions
609
show_changed_revisions(br_to, old_rh, new_rh,
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)
613
1155
class cmd_branch(Command):
614
"""Create a new copy of a branch.
1156
"""Create a new branch that is a copy of an existing branch.
616
1158
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
617
1159
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1160
If the FROM_LOCATION has no / or path separator embedded, the TO_LOCATION
1161
is derived from the FROM_LOCATION by stripping a leading scheme or drive
1162
identifier, if any. For example, "branch lp:foo-bar" will attempt to
619
1165
To retrieve the branch as of a particular revision, supply the --revision
620
1166
parameter, as in "branch foo/bar -r 5".
622
--basis is to speed up branching from remote branches. When specified, it
623
copies all the file-contents, inventory and revision data from the basis
624
branch before copying anything from the remote branch.
1169
_see_also = ['checkout']
626
1170
takes_args = ['from_location', 'to_location?']
627
takes_options = ['revision', 'basis']
1171
takes_options = ['revision', Option('hardlink',
1172
help='Hard-link working tree files where possible.'),
1174
help="Create a branch without a working-tree."),
1176
help='Create a stacked branch referring to the source branch. '
1177
'The new branch will depend on the availability of the source '
1178
'branch for all operations.'),
1179
Option('standalone',
1180
help='Do not use a shared repository, even if available.'),
1181
Option('use-existing-dir',
1182
help='By default branch will fail if the target'
1183
' directory exists, but does not already'
1184
' have a control directory. This flag will'
1185
' allow branch to proceed.'),
628
1187
aliases = ['get', 'clone']
630
def run(self, from_location, to_location=None, revision=None, basis=None):
633
elif len(revision) > 1:
634
raise BzrCommandError(
635
'bzr branch --revision takes exactly 1 revision value')
637
br_from = Branch.open(from_location)
639
if e.errno == errno.ENOENT:
640
raise BzrCommandError('Source location "%s" does not'
641
' exist.' % to_location)
1189
def run(self, from_location, to_location=None, revision=None,
1190
hardlink=False, stacked=False, standalone=False, no_tree=False,
1191
use_existing_dir=False):
1192
from bzrlib.tag import _merge_tags_if_possible
1194
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1196
if (accelerator_tree is not None and
1197
accelerator_tree.supports_content_filtering()):
1198
accelerator_tree = None
1199
revision = _get_one_revision('branch', revision)
644
1200
br_from.lock_read()
646
if basis is not None:
647
basis_dir = bzrdir.BzrDir.open_containing(basis)[0]
650
if len(revision) == 1 and revision[0] is not None:
651
revision_id = revision[0].in_history(br_from)[1]
1202
if revision is not None:
1203
revision_id = revision.as_revision_id(br_from)
653
1205
# FIXME - wt.last_revision, fallback to branch, fall back to
654
1206
# None or perhaps NULL_REVISION to mean copy nothing
656
1208
revision_id = br_from.last_revision()
657
1209
if to_location is None:
658
to_location = os.path.basename(from_location.rstrip("/\\"))
661
name = os.path.basename(to_location) + '\n'
1210
to_location = urlutils.derive_to_location(from_location)
663
1211
to_transport = transport.get_transport(to_location)
665
1213
to_transport.mkdir('.')
666
1214
except errors.FileExists:
667
raise BzrCommandError('Target directory "%s" already'
668
' exists.' % to_location)
1215
if not use_existing_dir:
1216
raise errors.BzrCommandError('Target directory "%s" '
1217
'already exists.' % to_location)
1220
bzrdir.BzrDir.open_from_transport(to_transport)
1221
except errors.NotBranchError:
1224
raise errors.AlreadyBranchError(to_location)
669
1225
except errors.NoSuchFile:
670
raise BzrCommandError('Parent of "%s" does not exist.' %
1226
raise errors.BzrCommandError('Parent of "%s" does not exist.'
673
1229
# preserve whatever source format we have.
674
dir = br_from.bzrdir.sprout(to_transport.base,
675
revision_id, basis_dir)
1230
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1231
possible_transports=[to_transport],
1232
accelerator_tree=accelerator_tree,
1233
hardlink=hardlink, stacked=stacked,
1234
force_new_repo=standalone,
1235
create_tree_if_local=not no_tree,
1236
source_branch=br_from)
676
1237
branch = dir.open_branch()
677
1238
except errors.NoSuchRevision:
678
1239
to_transport.delete_tree('.')
679
msg = "The branch %s has no revision %s." % (from_location, revision[0])
680
raise BzrCommandError(msg)
681
except errors.UnlistableBranch:
682
osutils.rmtree(to_location)
683
msg = "The branch %s cannot be used as a --basis" % (basis,)
684
raise BzrCommandError(msg)
686
branch.control_files.put_utf8('branch-name', name)
687
note('Branched %d revision(s).' % branch.revno())
1240
msg = "The branch %s has no revision %s." % (from_location,
1242
raise errors.BzrCommandError(msg)
1243
_merge_tags_if_possible(br_from, branch)
1244
# If the source branch is stacked, the new branch may
1245
# be stacked whether we asked for that explicitly or not.
1246
# We therefore need a try/except here and not just 'if stacked:'
1248
note('Created new stacked branch referring to %s.' %
1249
branch.get_stacked_on_url())
1250
except (errors.NotStacked, errors.UnstackableBranchFormat,
1251
errors.UnstackableRepositoryFormat), e:
1252
note('Branched %d revision(s).' % branch.revno())
689
1254
br_from.unlock()
1026
1680
# Just using os.mkdir, since I don't
1027
1681
# believe that we want to create a bunch of
1028
1682
# locations if the user supplies an extended path
1029
# TODO: create-prefix
1031
to_transport.mkdir('.')
1032
except errors.FileExists:
1036
existing_bzrdir = bzrdir.BzrDir.open(location)
1037
except NotBranchError:
1684
to_transport.ensure_base()
1685
except errors.NoSuchFile:
1686
if not create_prefix:
1687
raise errors.BzrCommandError("Parent directory of %s"
1689
"\nYou may supply --create-prefix to create all"
1690
" leading parent directories."
1692
to_transport.create_prefix()
1695
a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
1696
except errors.NotBranchError:
1038
1697
# really a NotBzrDir error...
1039
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1698
create_branch = bzrdir.BzrDir.create_branch_convenience
1699
branch = create_branch(to_transport.base, format=format,
1700
possible_transports=[to_transport])
1701
a_bzrdir = branch.bzrdir
1041
if existing_bzrdir.has_branch():
1703
from bzrlib.transport.local import LocalTransport
1704
if a_bzrdir.has_branch():
1042
1705
if (isinstance(to_transport, LocalTransport)
1043
and not existing_bzrdir.has_workingtree()):
1706
and not a_bzrdir.has_workingtree()):
1044
1707
raise errors.BranchExistsWithoutWorkingTree(location)
1045
1708
raise errors.AlreadyBranchError(location)
1047
existing_bzrdir.create_branch()
1048
existing_bzrdir.create_workingtree()
1709
branch = a_bzrdir.create_branch()
1710
a_bzrdir.create_workingtree()
1711
if append_revisions_only:
1713
branch.set_append_revisions_only(True)
1714
except errors.UpgradeRequired:
1715
raise errors.BzrCommandError('This branch format cannot be set'
1716
' to append-revisions-only. Try --default.')
1718
from bzrlib.info import describe_layout, describe_format
1720
tree = a_bzrdir.open_workingtree(recommend_upgrade=False)
1721
except (errors.NoWorkingTree, errors.NotLocalUrl):
1723
repository = branch.repository
1724
layout = describe_layout(repository, branch, tree).lower()
1725
format = describe_format(a_bzrdir, repository, branch, tree)
1726
self.outf.write("Created a %s (format: %s)\n" % (layout, format))
1727
if repository.is_shared():
1728
#XXX: maybe this can be refactored into transport.path_or_url()
1729
url = repository.bzrdir.root_transport.external_url()
1731
url = urlutils.local_path_from_url(url)
1732
except errors.InvalidURL:
1734
self.outf.write("Using shared repository: %s\n" % url)
1051
1737
class cmd_init_repository(Command):
1052
1738
"""Create a shared repository to hold branches.
1054
New branches created under the repository directory will store their revisions
1055
in the repository, not in the branch directory, if the branch format supports
1061
bzr checkout --lightweight repo/trunk trunk-checkout
1740
New branches created under the repository directory will store their
1741
revisions in the repository, not in the branch directory.
1743
If the --no-trees option is used then the branches in the repository
1744
will not have working trees by default.
1747
Create a shared repositories holding just branches::
1749
bzr init-repo --no-trees repo
1752
Make a lightweight checkout elsewhere::
1754
bzr checkout --lightweight repo/trunk trunk-checkout
1065
takes_args = ["location"]
1066
takes_options = [Option('format',
1067
help='Specify a format for this repository.'
1068
' Current formats are: default, knit,'
1069
' metaweave and weave. Default is knit;'
1070
' metaweave and weave are deprecated',
1071
type=get_format_type),
1073
help='Allows branches in repository to have'
1759
_see_also = ['init', 'branch', 'checkout', 'repositories']
1760
takes_args = ["location"]
1761
takes_options = [RegistryOption('format',
1762
help='Specify a format for this repository. See'
1763
' "bzr help formats" for details.',
1764
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1765
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
1766
value_switches=True, title='Repository format'),
1768
help='Branches in the repository will default to'
1769
' not having a working tree.'),
1075
1771
aliases = ["init-repo"]
1076
def run(self, location, format=None, trees=False):
1773
def run(self, location, format=None, no_trees=False):
1077
1774
if format is None:
1078
format = get_format_type('default')
1775
format = bzrdir.format_registry.make_bzrdir('default')
1080
1777
if location is None:
1083
1780
to_transport = transport.get_transport(location)
1085
to_transport.mkdir('.')
1086
except errors.FileExists:
1781
to_transport.ensure_base()
1089
1783
newdir = format.initialize_on_transport(to_transport)
1090
1784
repo = newdir.create_repository(shared=True)
1091
repo.set_make_working_trees(trees)
1785
repo.set_make_working_trees(not no_trees)
1787
from bzrlib.info import show_bzrdir_info
1788
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
1094
1791
class cmd_diff(Command):
1095
"""Show differences in the working tree or between revisions.
1097
If files are listed, only the changes in those files are listed.
1098
Otherwise, all changes for the tree are listed.
1792
"""Show differences in the working tree, between revisions or branches.
1794
If no arguments are given, all changes for the current tree are listed.
1795
If files are given, only the changes in those files are listed.
1796
Remote and multiple branches can be compared by using the --old and
1797
--new options. If not provided, the default for both is derived from
1798
the first argument, if any, or the current tree if no arguments are
1100
1801
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1101
1802
produces patches suitable for "patch -p1".
1105
Shows the difference in the working tree versus the last commit
1107
Difference between the working tree and revision 1
1109
Difference between revision 2 and revision 1
1110
bzr diff --diff-prefix old/:new/
1111
Same as 'bzr diff' but prefix paths with old/ and new/
1112
bzr diff bzr.mine bzr.dev
1113
Show the differences between the two working trees
1115
Show just the differences for 'foo.c'
1806
2 - unrepresentable changes
1811
Shows the difference in the working tree versus the last commit::
1815
Difference between the working tree and revision 1::
1819
Difference between revision 2 and revision 1::
1823
Difference between revision 2 and revision 1 for branch xxx::
1827
Show just the differences for file NEWS::
1831
Show the differences in working tree xxx for file NEWS::
1835
Show the differences from branch xxx to this working tree:
1839
Show the differences between two branches for file NEWS::
1841
bzr diff --old xxx --new yyy NEWS
1843
Same as 'bzr diff' but prefix paths with old/ and new/::
1845
bzr diff --prefix old/:new/
1117
# TODO: Option to use external diff command; could be GNU diff, wdiff,
1118
# or a graphical diff.
1120
# TODO: Python difflib is not exactly the same as unidiff; should
1121
# either fix it up or prefer to use an external diff.
1123
# TODO: Selected-file diff is inefficient and doesn't show you
1126
# TODO: This probably handles non-Unix newlines poorly.
1847
_see_also = ['status']
1128
1848
takes_args = ['file*']
1129
takes_options = ['revision', 'diff-options', 'prefix']
1850
Option('diff-options', type=str,
1851
help='Pass these options to the external diff program.'),
1852
Option('prefix', type=str,
1854
help='Set prefixes added to old and new filenames, as '
1855
'two values separated by a colon. (eg "old/:new/").'),
1857
help='Branch/tree to compare from.',
1861
help='Branch/tree to compare to.',
1867
help='Use this command to compare files.',
1130
1871
aliases = ['di', 'dif']
1131
1872
encoding_type = 'exact'
1133
1874
@display_command
1134
1875
def run(self, revision=None, file_list=None, diff_options=None,
1136
from bzrlib.diff import diff_cmd_helper, show_diff_trees
1876
prefix=None, old=None, new=None, using=None):
1877
from bzrlib.diff import _get_trees_to_diff, show_diff_trees
1138
1879
if (prefix is None) or (prefix == '0'):
1139
1880
# diff -p0 format
1260
2014
self.outf.write(tree.basedir + '\n')
2017
def _parse_limit(limitstring):
2019
return int(limitstring)
2021
msg = "The limit argument must be an integer."
2022
raise errors.BzrCommandError(msg)
2025
def _parse_levels(s):
2029
msg = "The levels argument must be an integer."
2030
raise errors.BzrCommandError(msg)
1263
2033
class cmd_log(Command):
1264
"""Show log of a branch, file, or directory.
1266
By default show the log of the branch containing the working directory.
1268
To request a range of logs, you can use the command -r begin..end
1269
-r revision requests a specific revision, -r ..end or -r begin.. are
1275
bzr log -r -10.. http://server/branch
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.
1278
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1280
takes_args = ['location?']
1281
takes_options = [Option('forward',
1282
help='show from oldest to newest'),
1285
help='show files changed in each revision'),
1286
'show-ids', 'revision',
1290
help='show revisions whose message matches this regexp',
2188
takes_args = ['file*']
2189
_see_also = ['log-formats', 'revisionspec']
2192
help='Show from oldest to newest.'),
2194
custom_help('verbose',
2195
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),
2211
help='Show revisions whose message matches this '
2212
'regular expression.',
2216
help='Limit the output to the first N revisions.',
2221
help='Show changes made in each revision as a patch.'),
2222
Option('include-merges',
2223
help='Show merged revisions like --levels 0 does.'),
1294
2225
encoding_type = 'replace'
1296
2227
@display_command
1297
def run(self, location=None, timezone='original',
2228
def run(self, file_list=None, timezone='original',
1299
2230
show_ids=False,
1302
2234
log_format=None,
1307
from bzrlib.log import log_formatter, show_log
1308
assert message is None or isinstance(message, basestring), \
1309
"invalid message argument %r" % message
2239
include_merges=False):
2240
from bzrlib.log import (
2242
make_log_request_dict,
2243
_get_info_for_log_files,
1310
2245
direction = (forward and 'forward') or 'reverse'
1315
# find the file id to log:
1317
dir, fp = bzrdir.BzrDir.open_containing(location)
1318
b = dir.open_branch()
1322
inv = dir.open_workingtree().inventory
1323
except (errors.NotBranchError, errors.NotLocalUrl):
1324
# either no tree, or is remote.
1325
inv = b.basis_tree().inventory
1326
file_id = inv.path2id(fp)
1329
# FIXME ? log the current subdir only RBC 20060203
1330
dir, relpath = bzrdir.BzrDir.open_containing('.')
1331
b = dir.open_branch()
1333
if revision is None:
1336
elif len(revision) == 1:
1337
rev1 = rev2 = revision[0].in_history(b).revno
1338
elif len(revision) == 2:
1339
if revision[0].spec is None:
1340
# missing begin-range means first revision
1343
rev1 = revision[0].in_history(b).revno
1345
if revision[1].spec is None:
1346
# missing end-range means last known revision
1349
rev2 = revision[1].in_history(b).revno
1351
raise BzrCommandError('bzr log --revision takes one or two values.')
1353
# By this point, the revision numbers are converted to the +ve
1354
# form if they were supplied in the -ve form, so we can do
1355
# this comparison in relative safety
1357
(rev2, rev1) = (rev1, rev2)
1359
if (log_format == None):
1360
default = b.get_config().log_format()
1361
log_format = get_log_format(long=long, short=short, line=line,
1363
lf = log_formatter(log_format,
1366
show_timezone=timezone)
1372
direction=direction,
1373
start_revision=rev1,
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:
2270
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'])
2283
# FIXME ? log the current subdir only RBC 20060203
2284
if revision is not None \
2285
and len(revision) > 0 and revision[0].get_branch():
2286
location = revision[0].get_branch()
2289
dir, relpath = bzrdir.BzrDir.open_containing(location)
2290
b = dir.open_branch()
2291
rev1, rev2 = _get_revision_range(revision, b, self.name())
2293
# Decide on the type of delta & diff filtering to use
2294
# TODO: add an --all-files option to make this configurable & consistent
2302
diff_type = 'partial'
2308
# Build the log formatter
2309
if log_format is None:
2310
log_format = log.log_formatter_registry.get_default(b)
2311
lf = log_format(show_ids=show_ids, to_file=self.outf,
2312
show_timezone=timezone,
2313
delta_format=get_verbosity_level(),
2315
show_advice=levels is None)
2317
# Choose the algorithm for doing the logging. It's annoying
2318
# having multiple code paths like this but necessary until
2319
# the underlying repository format is faster at generating
2320
# deltas or can provide everything we need from the indices.
2321
# The default algorithm - match-using-deltas - works for
2322
# multiple files and directories and is faster for small
2323
# amounts of history (200 revisions say). However, it's too
2324
# slow for logging a single file in a repository with deep
2325
# history, i.e. > 10K revisions. In the spirit of "do no
2326
# evil when adding features", we continue to use the
2327
# original algorithm - per-file-graph - for the "single
2328
# file that isn't a directory without showing a delta" case.
2329
partial_history = revision and b.repository._format.supports_chks
2330
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2331
or delta_type or partial_history)
2333
# Build the LogRequest and execute it
2334
if len(file_ids) == 0:
2336
rqst = make_log_request_dict(
2337
direction=direction, specific_fileids=file_ids,
2338
start_revision=rev1, end_revision=rev2, limit=limit,
2339
message_search=message, delta_type=delta_type,
2340
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2341
Logger(b, rqst).show(lf)
2346
def _get_revision_range(revisionspec_list, branch, command_name):
2347
"""Take the input of a revision option and turn it into a revision range.
2349
It returns RevisionInfo objects which can be used to obtain the rev_id's
2350
of the desired revisions. It does some user input validations.
2352
if revisionspec_list is None:
2355
elif len(revisionspec_list) == 1:
2356
rev1 = rev2 = revisionspec_list[0].in_history(branch)
2357
elif len(revisionspec_list) == 2:
2358
start_spec = revisionspec_list[0]
2359
end_spec = revisionspec_list[1]
2360
if end_spec.get_branch() != start_spec.get_branch():
2361
# b is taken from revision[0].get_branch(), and
2362
# show_log will use its revision_history. Having
2363
# different branches will lead to weird behaviors.
2364
raise errors.BzrCommandError(
2365
"bzr %s doesn't accept two revisions in different"
2366
" branches." % command_name)
2367
rev1 = start_spec.in_history(branch)
2368
# Avoid loading all of history when we know a missing
2369
# end of range means the last revision ...
2370
if end_spec.spec is None:
2371
last_revno, last_revision_id = branch.last_revision_info()
2372
rev2 = RevisionInfo(branch, last_revno, last_revision_id)
2374
rev2 = end_spec.in_history(branch)
2376
raise errors.BzrCommandError(
2377
'bzr %s --revision takes one or two values.' % command_name)
2381
def _revision_range_to_revid_range(revision_range):
2384
if revision_range[0] is not None:
2385
rev_id1 = revision_range[0].rev_id
2386
if revision_range[1] is not None:
2387
rev_id2 = revision_range[1].rev_id
2388
return rev_id1, rev_id2
1378
2390
def get_log_format(long=False, short=False, line=False, default='long'):
1379
2391
log_format = default
2093
3557
default, use --remember. The value will only be saved if the remote
2094
3558
location can be accessed.
2098
To merge the latest revision from bzr.dev
2099
bzr merge ../bzr.dev
2101
To merge changes up to and including revision 82 from bzr.dev
2102
bzr merge -r 82 ../bzr.dev
2104
To merge the changes introduced by 82, without previous changes:
2105
bzr merge -r 81..82 ../bzr.dev
3560
The results of the merge are placed into the destination working
3561
directory, where they can be reviewed (with bzr diff), tested, and then
3562
committed to record the result of the merge.
2107
3564
merge refuses to run if there are any uncommitted changes, unless
2108
3565
--force is given.
2110
The following merge types are available:
3567
To select only some changes to merge, use "merge -i", which will prompt
3568
you to apply each diff hunk and file change, similar to "shelve".
3571
To merge the latest revision from bzr.dev::
3573
bzr merge ../bzr.dev
3575
To merge changes up to and including revision 82 from bzr.dev::
3577
bzr merge -r 82 ../bzr.dev
3579
To merge the changes introduced by 82, without previous changes::
3581
bzr merge -r 81..82 ../bzr.dev
3583
To apply a merge directive contained in /tmp/merge:
3585
bzr merge /tmp/merge
2112
takes_args = ['branch?']
2113
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2114
Option('show-base', help="Show base revision text in "
2116
Option('uncommitted', help='Apply uncommitted changes'
2117
' from a working copy, instead of branch changes')]
2120
from merge import merge_type_help
2121
from inspect import getdoc
2122
return getdoc(self) + '\n' + merge_type_help()
2124
def run(self, branch=None, revision=None, force=False, merge_type=None,
2125
show_base=False, reprocess=False, remember=False,
3588
encoding_type = 'exact'
3589
_see_also = ['update', 'remerge', 'status-flags', 'send']
3590
takes_args = ['location?']
3595
help='Merge even if the destination tree has uncommitted changes.'),
3599
Option('show-base', help="Show base revision text in "
3601
Option('uncommitted', help='Apply uncommitted changes'
3602
' from a working copy, instead of branch changes.'),
3603
Option('pull', help='If the destination is already'
3604
' completely merged into the source, pull from the'
3605
' source rather than merging. When this happens,'
3606
' you do not need to commit the result.'),
3608
help='Branch to merge into, '
3609
'rather than the one containing the working directory.',
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,
3621
uncommitted=False, pull=False,
2127
3626
if merge_type is None:
2128
merge_type = Merge3Merger
2130
tree = WorkingTree.open_containing(u'.')[0]
2132
if branch is not None:
2134
reader = bundle.read_bundle_from_url(branch)
2136
pass # Continue on considering this url a Branch
2138
conflicts = merge_bundle(reader, tree, not force, merge_type,
2139
reprocess, show_base)
3627
merge_type = _mod_merge.Merge3Merger
3629
if directory is None: directory = u'.'
3630
possible_transports = []
3632
allow_pending = True
3633
verified = 'inapplicable'
3634
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
change_reporter = delta._ChangeReporter(
3647
unversioned_filter=tree.is_ignored, view_info=view_info)
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:
2145
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2147
if revision is None or len(revision) < 1:
2150
other = [branch, None]
2153
other = [branch, -1]
2154
other_branch, path = Branch.open_containing(branch)
2157
raise BzrCommandError('Cannot use --uncommitted and --revision'
2158
' at the same time.')
2159
if len(revision) == 1:
2161
other_branch, path = Branch.open_containing(branch)
2162
revno = revision[0].in_history(other_branch).revno
2163
other = [branch, revno]
2165
assert len(revision) == 2
2166
if None in revision:
2167
raise BzrCommandError(
2168
"Merge doesn't permit that revision specifier.")
2169
other_branch, path = Branch.open_containing(branch)
2171
base = [branch, revision[0].in_history(other_branch).revno]
2172
other = [branch, revision[1].in_history(other_branch).revno]
2174
if tree.branch.get_parent() is None or remember:
2175
tree.branch.set_parent(other_branch.base)
2178
interesting_files = [path]
2180
interesting_files = None
2181
pb = ui.ui_factory.nested_progress_bar()
2184
conflict_count = merge(other, base, check_clean=(not force),
2185
merge_type=merge_type,
2186
reprocess=reprocess,
2187
show_base=show_base,
2188
pb=pb, file_list=interesting_files)
2191
if conflict_count != 0:
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.')
2195
except errors.AmbiguousBase, e:
2196
m = ("sorry, bzr can't determine the right merge base yet\n"
2197
"candidates are:\n "
2198
+ "\n ".join(e.bases)
2200
"please specify an explicit base with -r,\n"
2201
"and (if you want) report this to the bzr developers\n")
2204
# TODO: move up to common parent; this isn't merge-specific anymore.
2205
def _get_remembered_parent(self, tree, supplied_location, verb_string):
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):
2206
3861
"""Use tree.branch's parent if none was supplied.
2208
3863
Report if the remembered location was used.
2210
if supplied_location is not None:
2211
return supplied_location
2212
stored_location = tree.branch.get_parent()
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"
2213
3870
mutter("%s", stored_location)
2214
3871
if stored_location is None:
2215
raise BzrCommandError("No location specified or remembered")
2216
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2217
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
3872
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)
2218
3876
return stored_location
2311
3978
class cmd_revert(Command):
2312
"""Reverse all changes since the last commit.
2314
Only versioned files are affected. Specify filenames to revert only
2315
those files. By default, any files that are changed will be backed up
2316
first. Backup files have a '~' appended to their name.
3979
"""Revert files to a previous revision.
3981
Giving a list of files will revert only those files. Otherwise, all files
3982
will be reverted. If the revision is not specified with '--revision', the
3983
last committed revision is used.
3985
To remove only some changes, without reverting to a prior version, use
3986
merge instead. For example, "merge . --revision -2..-3" will remove the
3987
changes introduced by -2, without affecting the changes introduced by -1.
3988
Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
3990
By default, any files that have been manually changed will be backed up
3991
first. (Files changed only by merge are not backed up.) Backup files have
3992
'.~#~' appended to their name, where # is a number.
3994
When you provide files, you can use their current pathname or the pathname
3995
from the target revision. So you can use revert to "undelete" a file by
3996
name. If you name a directory, all the contents of that directory will be
3999
Any files that have been newly added since that revision will be deleted,
4000
with a backup kept if appropriate. Directories containing unknown files
4001
will not be deleted.
4003
The working tree contains a list of pending merged revisions, which will
4004
be included as parents in the next commit. Normally, revert clears that
4005
list as well as reverting the files. If any files are specified, revert
4006
leaves the pending merge list alone and reverts only the files. Use "bzr
4007
revert ." in the tree root to revert all files but keep the merge record,
4008
and "bzr revert --forget-merges" to clear the pending merge list without
4009
reverting any files.
2318
takes_options = ['revision', 'no-backup']
4012
_see_also = ['cat', 'export']
4015
Option('no-backup', "Do not save backups of reverted files."),
4016
Option('forget-merges',
4017
'Remove pending merge marker, without changing any files.'),
2319
4019
takes_args = ['file*']
2320
aliases = ['merge-revert']
2322
def run(self, revision=None, no_backup=False, file_list=None):
2323
from bzrlib.commands import parse_spec
2324
if file_list is not None:
2325
if len(file_list) == 0:
2326
raise BzrCommandError("No files specified")
4021
def run(self, revision=None, no_backup=False, file_list=None,
4022
forget_merges=None):
2330
4023
tree, file_list = tree_files(file_list)
2331
if revision is None:
2332
# FIXME should be tree.last_revision
2333
rev_id = tree.last_revision()
2334
elif len(revision) != 1:
2335
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
2337
rev_id = revision[0].in_history(tree.branch).rev_id
4027
tree.set_parent_ids(tree.get_parent_ids()[:1])
4029
self._revert_tree_to_revision(tree, revision, file_list, no_backup)
4034
def _revert_tree_to_revision(tree, revision, file_list, no_backup):
4035
rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
2338
4036
pb = ui.ui_factory.nested_progress_bar()
2340
tree.revert(file_list,
2341
tree.branch.repository.revision_tree(rev_id),
4038
tree.revert(file_list, rev_tree, not no_backup, pb,
4039
report_changes=True)
2347
4044
class cmd_assert_fail(Command):
2348
4045
"""Test reporting of assertion failures"""
4046
# intended just for use in testing
2351
assert False, "always fails"
4051
raise AssertionError("always fails")
2354
4054
class cmd_help(Command):
2355
4055
"""Show help on a command or other topic.
2357
For a list of all available commands, say 'bzr help commands'."""
2358
takes_options = [Option('long', 'show help on all commands')]
4058
_see_also = ['topics']
4060
Option('long', 'Show help on all commands.'),
2359
4062
takes_args = ['topic?']
2360
4063
aliases = ['?', '--help', '-?', '-h']
2362
4065
@display_command
2363
4066
def run(self, topic=None, long=False):
2365
4068
if topic is None and long:
2366
4069
topic = "commands"
4070
bzrlib.help.help(topic)
2370
4073
class cmd_shell_complete(Command):
2371
4074
"""Show appropriate completions for context.
2373
For a list of all available commands, say 'bzr shell-complete'."""
4076
For a list of all available commands, say 'bzr shell-complete'.
2374
4078
takes_args = ['context?']
2375
4079
aliases = ['s-c']
2378
4082
@display_command
2379
4083
def run(self, context=None):
2380
4084
import shellcomplete
2381
4085
shellcomplete.shellcomplete(context)
2384
class cmd_fetch(Command):
2385
"""Copy in history from another branch but don't merge it.
2387
This is an internal method used for pull and merge."""
2389
takes_args = ['from_branch', 'to_branch']
2390
def run(self, from_branch, to_branch):
2391
from bzrlib.fetch import Fetcher
2392
from_b = Branch.open(from_branch)
2393
to_b = Branch.open(to_branch)
2394
Fetcher(to_b, from_b)
2397
4088
class cmd_missing(Command):
2398
4089
"""Show unmerged/unpulled revisions between two branches.
2400
OTHER_BRANCH may be local or remote."""
4091
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
_see_also = ['merge', 'pull']
2401
4120
takes_args = ['other_branch?']
2402
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2404
'Display changes in the local branch only'),
2405
Option('theirs-only',
2406
'Display changes in the remote branch only'),
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.'),
2414
4142
encoding_type = 'replace'
2416
4144
@display_command
2417
4145
def run(self, other_branch=None, reverse=False, mine_only=False,
2418
theirs_only=False, log_format=None, long=False, short=False, line=False,
2419
show_ids=False, verbose=False):
2420
from bzrlib.missing import find_unmerged, iter_log_data
2421
from bzrlib.log import log_formatter
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):
4150
from bzrlib.missing import find_unmerged, iter_log_revisions
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.
2422
4168
local_branch = Branch.open_containing(u".")[0]
2423
4169
parent = local_branch.get_parent()
2424
4170
if other_branch is None:
2425
4171
other_branch = parent
2426
4172
if other_branch is None:
2427
raise BzrCommandError("No peer location known or specified.")
2428
print "Using last location: " + local_branch.get_parent()
4173
raise errors.BzrCommandError("No peer location known"
4175
display_url = urlutils.unescape_for_display(parent,
4177
message("Using saved parent location: "
4178
+ display_url + "\n")
2429
4180
remote_branch = Branch.open(other_branch)
2430
4181
if remote_branch.base == local_branch.base:
2431
4182
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()))
2432
4192
local_branch.lock_read()
2434
4194
remote_branch.lock_read()
2436
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2437
if (log_format == None):
2438
default = local_branch.get_config().log_format()
2439
log_format = get_log_format(long=long, short=short,
2440
line=line, default=default)
2441
lf = log_formatter(log_format,
2444
show_timezone='original')
2445
if reverse is False:
2446
local_extra.reverse()
2447
remote_extra.reverse()
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)
4206
lf = log_format(to_file=self.outf,
4208
show_timezone='original')
2448
4211
if local_extra and not theirs_only:
2449
print "You have %d extra revision(s):" % len(local_extra)
2450
for data in iter_log_data(local_extra, local_branch.repository,
4212
message("You have %d extra revision(s):\n" %
4214
for revision in iter_log_revisions(local_extra,
4215
local_branch.repository,
4217
lf.log_revision(revision)
2453
4218
printed_local = True
2455
4221
printed_local = False
2456
4223
if remote_extra and not mine_only:
2457
4224
if printed_local is True:
2459
print "You are missing %d revision(s):" % len(remote_extra)
2460
for data in iter_log_data(remote_extra, remote_branch.repository,
2463
if not remote_extra and not local_extra:
2465
print "Branches are up to date."
4226
message("You are missing %d revision(s):\n" %
4228
for revision in iter_log_revisions(remote_extra,
4229
remote_branch.repository,
4231
lf.log_revision(revision)
2467
4232
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")
2469
4246
remote_branch.unlock()
2748
4664
control.break_lock()
2749
4665
except NotImplementedError:
2754
# command-line interpretation helper for merge-related commands
2755
def merge(other_revision, base_revision,
2756
check_clean=True, ignore_zero=False,
2757
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2758
file_list=None, show_base=False, reprocess=False,
2759
pb=DummyProgress()):
2760
"""Merge changes into a tree.
2763
list(path, revno) Base for three-way merge.
2764
If [None, None] then a base will be automatically determined.
2766
list(path, revno) Other revision for three-way merge.
2768
Directory to merge changes into; '.' by default.
2770
If true, this_dir must have no uncommitted changes before the
2772
ignore_zero - If true, suppress the "zero conflicts" message when
2773
there are no conflicts; should be set when doing something we expect
2774
to complete perfectly.
2775
file_list - If supplied, merge only changes to selected files.
2777
All available ancestors of other_revision and base_revision are
2778
automatically pulled into the branch.
2780
The revno may be -1 to indicate the last revision on the branch, which is
2783
This function is intended for use from the command line; programmatic
2784
clients might prefer to call merge.merge_inner(), which has less magic
2787
from bzrlib.merge import Merger
2788
if this_dir is None:
2790
this_tree = WorkingTree.open_containing(this_dir)[0]
2791
if show_base and not merge_type is Merge3Merger:
2792
raise BzrCommandError("Show-base is not supported for this merge"
2793
" type. %s" % merge_type)
2794
if reprocess and not merge_type.supports_reprocess:
2795
raise BzrCommandError("Conflict reduction is not supported for merge"
2796
" type %s." % merge_type)
2797
if reprocess and show_base:
2798
raise BzrCommandError("Cannot do conflict reduction and show base.")
2800
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2801
merger.pp = ProgressPhase("Merge phase", 5, pb)
2802
merger.pp.next_phase()
2803
merger.check_basis(check_clean)
2804
merger.set_other(other_revision)
2805
merger.pp.next_phase()
2806
merger.set_base(base_revision)
2807
if merger.base_rev_id == merger.other_rev_id:
2808
note('Nothing to do.')
4669
class cmd_wait_until_signalled(Command):
4670
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4672
This just prints a line to signal when it is ready, then blocks on stdin.
4678
sys.stdout.write("running\n")
4680
sys.stdin.readline()
4683
class cmd_serve(Command):
4684
"""Run the bzr server."""
4686
aliases = ['server']
4690
help='Serve on stdin/out for use from inetd or sshd.'),
4691
RegistryOption('protocol',
4692
help="Protocol to serve.",
4693
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
4694
value_switches=True),
4696
help='Listen for connections on nominated port of the form '
4697
'[hostname:]portnumber. Passing 0 as the port number will '
4698
'result in a dynamically allocated port. The default port '
4699
'depends on the protocol.',
4702
help='Serve contents of this directory.',
4704
Option('allow-writes',
4705
help='By default the server is a readonly server. Supplying '
4706
'--allow-writes enables write access to the contents of '
4707
'the served directory and below.'
4711
def get_host_and_port(self, port):
4712
"""Return the host and port to run the smart server on.
4714
If 'port' is None, None will be returned for the host and port.
4716
If 'port' has a colon in it, the string before the colon will be
4717
interpreted as the host.
4719
:param port: A string of the port to run the server on.
4720
:return: A tuple of (host, port), where 'host' is a host name or IP,
4721
and port is an integer TCP/IP port.
4724
if port is not None:
4726
host, port = port.split(':')
4730
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4732
from bzrlib.transport import get_transport, transport_server_registry
4733
if directory is None:
4734
directory = os.getcwd()
4735
if protocol is None:
4736
protocol = transport_server_registry.get()
4737
host, port = self.get_host_and_port(port)
4738
url = urlutils.local_path_to_url(directory)
4739
if not allow_writes:
4740
url = 'readonly+' + url
4741
transport = get_transport(url)
4742
protocol(transport, host, port, inet)
4745
class cmd_join(Command):
4746
"""Combine a tree into its containing tree.
4748
This command requires the target tree to be in a rich-root format.
4750
The TREE argument should be an independent tree, inside another tree, but
4751
not part of it. (Such trees can be produced by "bzr split", but also by
4752
running "bzr branch" with the target inside a tree.)
4754
The result is a combined tree, with the subtree no longer an independant
4755
part. This is marked as a merge of the subtree into the containing tree,
4756
and all history is preserved.
4759
_see_also = ['split']
4760
takes_args = ['tree']
4762
Option('reference', help='Join by reference.', hidden=True),
4765
def run(self, tree, reference=False):
4766
sub_tree = WorkingTree.open(tree)
4767
parent_dir = osutils.dirname(sub_tree.basedir)
4768
containing_tree = WorkingTree.open_containing(parent_dir)[0]
4769
repo = containing_tree.branch.repository
4770
if not repo.supports_rich_root():
4771
raise errors.BzrCommandError(
4772
"Can't join trees because %s doesn't support rich root data.\n"
4773
"You can use bzr upgrade on the repository."
4777
containing_tree.add_reference(sub_tree)
4778
except errors.BadReferenceTarget, e:
4779
# XXX: Would be better to just raise a nicely printable
4780
# exception from the real origin. Also below. mbp 20070306
4781
raise errors.BzrCommandError("Cannot join %s. %s" %
4785
containing_tree.subsume(sub_tree)
4786
except errors.BadSubsumeSource, e:
4787
raise errors.BzrCommandError("Cannot join %s. %s" %
4791
class cmd_split(Command):
4792
"""Split a subdirectory of a tree into a separate tree.
4794
This command will produce a target tree in a format that supports
4795
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
4796
converted into earlier formats like 'dirstate-tags'.
4798
The TREE argument should be a subdirectory of a working tree. That
4799
subdirectory will be converted into an independent tree, with its own
4800
branch. Commits in the top-level tree will not apply to the new subtree.
4803
_see_also = ['join']
4804
takes_args = ['tree']
4806
def run(self, tree):
4807
containing_tree, subdir = WorkingTree.open_containing(tree)
4808
sub_id = containing_tree.path2id(subdir)
4810
raise errors.NotVersionedError(subdir)
4812
containing_tree.extract(sub_id)
4813
except errors.RootNotRich:
4814
raise errors.RichRootUpgradeRequired(containing_tree.branch.base)
4817
class cmd_merge_directive(Command):
4818
"""Generate a merge directive for auto-merge tools.
4820
A directive requests a merge to be performed, and also provides all the
4821
information necessary to do so. This means it must either include a
4822
revision bundle, or the location of a branch containing the desired
4825
A submit branch (the location to merge into) must be supplied the first
4826
time the command is issued. After it has been supplied once, it will
4827
be remembered as the default.
4829
A public branch is optional if a revision bundle is supplied, but required
4830
if --diff or --plain is specified. It will be remembered as the default
4831
after the first use.
4834
takes_args = ['submit_branch?', 'public_branch?']
4838
_see_also = ['send']
4841
RegistryOption.from_kwargs('patch-type',
4842
'The type of patch to include in the directive.',
4844
value_switches=True,
4846
bundle='Bazaar revision bundle (default).',
4847
diff='Normal unified diff.',
4848
plain='No patch, just directive.'),
4849
Option('sign', help='GPG-sign the directive.'), 'revision',
4850
Option('mail-to', type=str,
4851
help='Instead of printing the directive, email to this address.'),
4852
Option('message', type=str, short_name='m',
4853
help='Message to use when committing this merge.')
4856
encoding_type = 'exact'
4858
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
4859
sign=False, revision=None, mail_to=None, message=None):
4860
from bzrlib.revision import ensure_null, NULL_REVISION
4861
include_patch, include_bundle = {
4862
'plain': (False, False),
4863
'diff': (True, False),
4864
'bundle': (True, True),
4866
branch = Branch.open('.')
4867
stored_submit_branch = branch.get_submit_branch()
4868
if submit_branch is None:
4869
submit_branch = stored_submit_branch
4871
if stored_submit_branch is None:
4872
branch.set_submit_branch(submit_branch)
4873
if submit_branch is None:
4874
submit_branch = branch.get_parent()
4875
if submit_branch is None:
4876
raise errors.BzrCommandError('No submit branch specified or known')
4878
stored_public_branch = branch.get_public_branch()
4879
if public_branch is None:
4880
public_branch = stored_public_branch
4881
elif stored_public_branch is None:
4882
branch.set_public_branch(public_branch)
4883
if not include_bundle and public_branch is None:
4884
raise errors.BzrCommandError('No public branch specified or'
4886
base_revision_id = None
4887
if revision is not None:
4888
if len(revision) > 2:
4889
raise errors.BzrCommandError('bzr merge-directive takes '
4890
'at most two one revision identifiers')
4891
revision_id = revision[-1].as_revision_id(branch)
4892
if len(revision) == 2:
4893
base_revision_id = revision[0].as_revision_id(branch)
4895
revision_id = branch.last_revision()
4896
revision_id = ensure_null(revision_id)
4897
if revision_id == NULL_REVISION:
4898
raise errors.BzrCommandError('No revisions to bundle.')
4899
directive = merge_directive.MergeDirective2.from_objects(
4900
branch.repository, revision_id, time.time(),
4901
osutils.local_time_offset(), submit_branch,
4902
public_branch=public_branch, include_patch=include_patch,
4903
include_bundle=include_bundle, message=message,
4904
base_revision_id=base_revision_id)
4907
self.outf.write(directive.to_signed(branch))
4909
self.outf.writelines(directive.to_lines())
4911
message = directive.to_email(mail_to, branch, sign)
4912
s = SMTPConnection(branch.get_config())
4913
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
class cmd_tag(Command):
5088
"""Create, remove or modify a tag naming a revision.
5090
Tags give human-meaningful names to revisions. Commands that take a -r
5091
(--revision) option can be given -rtag:X, where X is any previously
5094
Tags are stored in the branch. Tags are copied from one branch to another
5095
along when you branch, push, pull or merge.
5097
It is an error to give a tag name that already exists unless you pass
5098
--force, in which case the tag is moved to point to the new revision.
5100
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5101
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5104
_see_also = ['commit', 'tags']
5105
takes_args = ['tag_name']
5108
help='Delete this tag rather than placing it.',
5111
help='Branch in which to place the tag.',
5116
help='Replace existing tags.',
5121
def run(self, tag_name,
5127
branch, relpath = Branch.open_containing(directory)
5131
branch.tags.delete_tag(tag_name)
5132
self.outf.write('Deleted tag %s.\n' % tag_name)
5135
if len(revision) != 1:
5136
raise errors.BzrCommandError(
5137
"Tags can only be placed on a single revision, "
5139
revision_id = revision[0].as_revision_id(branch)
5141
revision_id = branch.last_revision()
5142
if (not force) and branch.tags.has_tag(tag_name):
5143
raise errors.TagAlreadyExists(tag_name)
5144
branch.tags.set_tag(tag_name, revision_id)
5145
self.outf.write('Created tag %s.\n' % tag_name)
5150
class cmd_tags(Command):
5153
This command shows a table of tag names and the revisions they reference.
5159
help='Branch whose tags should be displayed.',
5163
RegistryOption.from_kwargs('sort',
5164
'Sort tags by different criteria.', title='Sorting',
5165
alpha='Sort tags lexicographically (default).',
5166
time='Sort tags chronologically.',
5179
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),))
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:
2810
merger.backup_files = backup_files
2811
merger.merge_type = merge_type
2812
merger.set_interesting_files(file_list)
2813
merger.show_base = show_base
2814
merger.reprocess = reprocess
2815
conflicts = merger.do_merge()
2816
if file_list is None:
2817
merger.set_pending()
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.')
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)
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))
2823
5760
# these get imported and then picked up by the scan for cmd_*
2824
5761
# TODO: Some more consistent way to split command definitions across files;
2825
# we do need to load at least some information about them to know of
5762
# we do need to load at least some information about them to know of
2826
5763
# aliases. ideally we would avoid loading the implementation until the
2827
5764
# details were needed.
5765
from bzrlib.cmd_version_info import cmd_version_info
2828
5766
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2829
from bzrlib.bundle.commands import cmd_bundle_revisions
5767
from bzrlib.bundle.commands import (
5770
from bzrlib.foreign import cmd_dpush
2830
5771
from bzrlib.sign_my_commits import cmd_sign_my_commits
2831
from bzrlib.weave_commands import cmd_weave_list, cmd_weave_join, \
5772
from bzrlib.weave_commands import cmd_versionedfile_list, \
2832
5773
cmd_weave_plan_merge, cmd_weave_merge_text