14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""builtin bzr commands"""
17
# DO NOT change this to cStringIO - it results in control files
19
# FIXIT! (Only deal with byte streams OR unicode at any one layer.)
21
from StringIO import StringIO
26
from bzrlib.branch import Branch, BranchReferenceFormat
27
from bzrlib import (bundle, branch, bzrdir, errors, osutils, ui, config,
29
from bzrlib.bundle import read_bundle_from_url
30
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
26
from bzrlib import BZRDIR
31
27
from bzrlib.commands import Command, display_command
32
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
33
NotBranchError, DivergedBranches, NotConflicted,
34
NoSuchFile, NoWorkingTree, FileInWrongBranch,
35
NotVersionedError, NotABundle)
36
from bzrlib.merge import Merge3Merger
28
from bzrlib.branch import Branch
29
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
30
from bzrlib.errors import DivergedBranches, NoSuchFile, NoWorkingTree
31
import bzrlib.errors as errors
37
32
from bzrlib.option import Option
38
from bzrlib.progress import DummyProgress, ProgressPhase
39
from bzrlib.revision import common_ancestor
40
33
from bzrlib.revisionspec import RevisionSpec
41
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
42
from bzrlib.transport.local import LocalTransport
43
import bzrlib.urlutils as urlutils
35
from bzrlib.trace import mutter, note, log_error, warning
44
36
from bzrlib.workingtree import WorkingTree
47
def tree_files(file_list, default_branch=u'.'):
49
return internal_tree_files(file_list, default_branch)
50
except FileInWrongBranch, e:
51
raise BzrCommandError("%s is not in the same branch as %s" %
52
(e.path, file_list[0]))
55
# XXX: Bad function name; should possibly also be a class method of
56
# WorkingTree rather than a function.
57
def internal_tree_files(file_list, default_branch=u'.'):
58
"""Convert command-line paths to a WorkingTree and relative paths.
60
This is typically used for command-line processors that take one or
61
more filenames, and infer the workingtree that contains them.
63
The filenames given are not required to exist.
65
:param file_list: Filenames to convert.
67
:param default_branch: Fallback tree path to use if file_list is empty or None.
69
:return: workingtree, [relative_paths]
39
def branch_files(file_list, default_branch='.'):
41
Return a branch and list of branch-relative paths.
42
If supplied file_list is empty or None, the branch default will be used,
43
and returned file_list will match the original.
71
45
if file_list is None or len(file_list) == 0:
72
return WorkingTree.open_containing(default_branch)[0], file_list
73
tree = WorkingTree.open_containing(file_list[0])[0]
46
return Branch.open_containing(default_branch)[0], file_list
47
b = Branch.open_containing(file_list[0])[0]
49
# note that if this is a remote branch, we would want
50
# relpath against the transport. RBC 20051018
51
# Most branch ops can't meaningfully operate on files in remote branches;
52
# the above comment was in cmd_status. ADHB 20051026
53
tree = WorkingTree(b.base, b)
75
55
for filename in file_list:
77
57
new_list.append(tree.relpath(filename))
78
except errors.PathNotChild:
79
raise FileInWrongBranch(tree.branch, filename)
83
def get_format_type(typestring):
84
"""Parse and return a format specifier."""
85
if typestring == "weave":
86
return bzrdir.BzrDirFormat6()
87
if typestring == "default":
88
return bzrdir.BzrDirMetaFormat1()
89
if typestring == "metaweave":
90
format = bzrdir.BzrDirMetaFormat1()
91
format.repository_format = repository.RepositoryFormat7()
93
if typestring == "knit":
94
format = bzrdir.BzrDirMetaFormat1()
95
format.repository_format = repository.RepositoryFormatKnit1()
97
msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
98
"metaweave and weave" % typestring
99
raise BzrCommandError(msg)
58
except NotBranchError:
59
raise BzrCommandError("%s is not in the same branch as %s" %
60
(filename, file_list[0]))
102
64
# TODO: Make sure no commands unconditionally use the working directory as a
141
107
that revision, or between two revisions if two are provided.
110
# XXX: FIXME: bzr status should accept a -r option to show changes
111
# relative to a revision, or between revisions
144
113
# TODO: --no-recurse, --recurse options
146
115
takes_args = ['file*']
147
takes_options = ['show-ids', 'revision']
116
takes_options = ['all', 'show-ids']
148
117
aliases = ['st', 'stat']
150
encoding_type = 'replace'
153
def run(self, show_ids=False, file_list=None, revision=None):
154
from bzrlib.status import show_tree_status
156
tree, file_list = tree_files(file_list)
120
def run(self, all=False, show_ids=False, file_list=None, revision=None):
121
b, file_list = branch_files(file_list)
158
show_tree_status(tree, show_ids=show_ids,
159
specific_files=file_list, revision=revision,
123
from bzrlib.status import show_status
124
show_status(b, show_unchanged=all, show_ids=show_ids,
125
specific_files=file_list, revision=revision)
163
128
class cmd_cat_revision(Command):
257
212
Adding a file whose parent directory is not versioned will
258
213
implicitly add the parent, and so on up to the root. This means
259
you should never need to explicitly add a directory, they'll just
214
you should never need to explictly add a directory, they'll just
260
215
get added when you add a file in the directory.
262
--dry-run will show which files would be added, but not actually
265
217
takes_args = ['file*']
266
takes_options = ['no-recurse', 'dry-run', 'verbose']
267
encoding_type = 'replace'
269
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
272
action = bzrlib.add.AddAction(to_file=self.outf,
273
should_print=(not is_quiet()))
275
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
276
action=action, save=not dry_run)
279
for glob in sorted(ignored.keys()):
280
for path in ignored[glob]:
281
self.outf.write("ignored %s matching \"%s\"\n"
285
for glob, paths in ignored.items():
286
match_len += len(paths)
287
self.outf.write("ignored %d file(s).\n" % match_len)
288
self.outf.write("If you wish to add some of these files,"
289
" please add them by name.\n")
218
takes_options = ['no-recurse', 'quiet']
220
def run(self, file_list, no_recurse=False, quiet=False):
221
from bzrlib.add import smart_add, add_reporter_print, add_reporter_null
223
reporter = add_reporter_null
225
reporter = add_reporter_print
226
smart_add(file_list, not no_recurse, reporter)
292
229
class cmd_mkdir(Command):
295
232
This is equivalent to creating the directory and then adding it.
298
234
takes_args = ['dir+']
299
encoding_type = 'replace'
301
236
def run(self, dir_list):
302
239
for d in dir_list:
304
wt, dd = WorkingTree.open_containing(d)
306
self.outf.write('added %s\n' % d)
242
b = Branch.open_containing(d)[0]
309
247
class cmd_relpath(Command):
310
248
"""Show path of a file relative to root"""
312
249
takes_args = ['filename']
316
253
def run(self, filename):
317
# TODO: jam 20050106 Can relpath return a munged path if
318
# sys.stdout encoding cannot represent it?
319
tree, relpath = WorkingTree.open_containing(filename)
320
self.outf.write(relpath)
321
self.outf.write('\n')
254
branch, relpath = Branch.open_containing(filename)
324
258
class cmd_inventory(Command):
325
"""Show inventory of the current working copy or a revision.
327
It is possible to limit the output to a particular entry
328
type using the --kind option. For example; --kind file.
331
takes_options = ['revision', 'show-ids', 'kind']
259
"""Show inventory of the current working copy or a revision."""
260
takes_options = ['revision', 'show-ids']
334
def run(self, revision=None, show_ids=False, kind=None):
335
if kind and kind not in ['file', 'directory', 'symlink']:
336
raise BzrCommandError('invalid kind specified')
337
tree = WorkingTree.open_containing(u'.')[0]
263
def run(self, revision=None, show_ids=False):
264
b = Branch.open_containing('.')[0]
338
265
if revision is None:
339
inv = tree.read_working_inventory()
266
inv = b.working_tree().read_working_inventory()
341
268
if len(revision) > 1:
342
269
raise BzrCommandError('bzr inventory --revision takes'
343
270
' exactly one revision identifier')
344
inv = tree.branch.repository.get_revision_inventory(
345
revision[0].in_history(tree.branch).rev_id)
271
inv = b.get_revision_inventory(revision[0].in_history(b).rev_id)
347
273
for path, entry in inv.entries():
348
if kind and kind != entry.kind:
351
self.outf.write('%-50s %s\n' % (path, entry.file_id))
275
print '%-50s %s' % (path, entry.file_id)
353
self.outf.write(path)
354
self.outf.write('\n')
280
class cmd_move(Command):
281
"""Move files to a different directory.
286
The destination must be a versioned directory in the same branch.
288
takes_args = ['source$', 'dest']
289
def run(self, source_list, dest):
290
b, source_list = branch_files(source_list)
292
# TODO: glob expansion on windows?
293
tree = WorkingTree(b.base, b)
294
b.move(source_list, tree.relpath(dest))
297
class cmd_rename(Command):
298
"""Change the name of an entry.
301
bzr rename frob.c frobber.c
302
bzr rename src/frob.c lib/frob.c
304
It is an error if the destination name exists.
306
See also the 'move' command, which moves files into a different
307
directory without changing their name.
309
# TODO: Some way to rename multiple files without invoking
310
# bzr for each one?"""
311
takes_args = ['from_name', 'to_name']
313
def run(self, from_name, to_name):
314
b, (from_name, to_name) = branch_files((from_name, to_name))
315
b.rename_one(from_name, to_name)
357
318
class cmd_mv(Command):
368
329
Files cannot be moved between branches.
371
331
takes_args = ['names*']
372
aliases = ['move', 'rename']
373
encoding_type = 'replace'
375
332
def run(self, names_list):
376
333
if len(names_list) < 2:
377
334
raise BzrCommandError("missing file argument")
378
tree, rel_names = tree_files(names_list)
335
b, rel_names = branch_files(names_list)
380
337
if os.path.isdir(names_list[-1]):
381
338
# move into existing directory
382
for pair in tree.move(rel_names[:-1], rel_names[-1]):
383
self.outf.write("%s => %s\n" % pair)
339
for pair in b.move(rel_names[:-1], rel_names[-1]):
340
print "%s => %s" % pair
385
342
if len(names_list) != 2:
386
343
raise BzrCommandError('to mv multiple files the destination '
387
344
'must be a versioned directory')
388
tree.rename_one(rel_names[0], rel_names[1])
389
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
345
b.rename_one(rel_names[0], rel_names[1])
346
print "%s => %s" % (rel_names[0], rel_names[1])
392
349
class cmd_pull(Command):
393
"""Turn this branch into a mirror of another branch.
350
"""Pull any changes from another branch into the current one.
352
If there is no default location set, the first pull will set it. After
353
that, you can omit the location to use the default. To change the
354
default, use --remember.
395
356
This command only works on branches that have not diverged. Branches are
396
considered diverged if the destination branch's most recent commit is one
397
that has not been merged (directly or indirectly) into the parent.
357
considered diverged if both branches have had commits without first
358
pulling from the other.
399
If branches have diverged, you can use 'bzr merge' to integrate the changes
360
If branches have diverged, you can use 'bzr merge' to pull the text changes
400
361
from one into the other. Once one branch has merged, the other should
401
362
be able to pull it again.
403
364
If you want to forget your local changes and just update your branch to
404
match the remote one, use pull --overwrite.
406
If there is no default location set, the first pull will set it. After
407
that, you can omit the location to use the default. To change the
408
default, use --remember. The value will only be saved if the remote
409
location can be accessed.
365
match the remote one, use --overwrite.
412
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
367
takes_options = ['remember', 'overwrite']
413
368
takes_args = ['location?']
414
encoding_type = 'replace'
416
def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
417
# FIXME: too much stuff is in the command class
419
tree_to = WorkingTree.open_containing(u'.')[0]
420
branch_to = tree_to.branch
421
except NoWorkingTree:
423
branch_to = Branch.open_containing(u'.')[0]
426
if location is not None:
428
reader = bundle.read_bundle_from_url(location)
430
pass # Continue on considering this url a Branch
432
stored_loc = branch_to.get_parent()
370
def run(self, location=None, remember=False, overwrite=False):
371
from bzrlib.merge import merge
372
from shutil import rmtree
375
br_to = Branch.open_containing('.')[0]
376
stored_loc = br_to.get_parent()
433
377
if location is None:
434
378
if stored_loc is None:
435
379
raise BzrCommandError("No pull location known or specified.")
437
display_url = urlutils.unescape_for_display(stored_loc,
439
self.outf.write("Using saved location: %s\n" % display_url)
381
print "Using saved location: %s" % stored_loc
440
382
location = stored_loc
443
if reader is not None:
444
install_bundle(branch_to.repository, reader)
445
branch_from = branch_to
447
branch_from = Branch.open(location)
449
if branch_to.get_parent() is None or remember:
450
branch_to.set_parent(branch_from.base)
454
if reader is not None:
455
rev_id = reader.target
456
elif len(revision) == 1:
457
rev_id = revision[0].in_history(branch_from).rev_id
459
raise BzrCommandError('bzr pull --revision takes one value.')
461
old_rh = branch_to.revision_history()
462
if tree_to is not None:
463
count = tree_to.pull(branch_from, overwrite, rev_id)
465
count = branch_to.pull(branch_from, overwrite, rev_id)
466
note('%d revision(s) pulled.' % (count,))
469
new_rh = branch_to.revision_history()
472
from bzrlib.log import show_changed_revisions
473
show_changed_revisions(branch_to, old_rh, new_rh,
383
br_from = Branch.open(location)
385
br_to.working_tree().pull(br_from, overwrite)
386
except DivergedBranches:
387
raise BzrCommandError("These branches have diverged."
389
if br_to.get_parent() is None or remember:
390
br_to.set_parent(location)
477
393
class cmd_push(Command):
478
"""Update a mirror of this branch.
480
The target branch will not have its working tree populated because this
481
is both expensive, and is not supported on remote file systems.
483
Some smart servers or protocols *may* put the working tree in place in
394
"""Push this branch into another branch.
396
The remote branch will not have its working tree populated because this
397
is both expensive, and may not be supported on the remote file system.
399
Some smart servers or protocols *may* put the working tree in place.
401
If there is no default push location set, the first push will set it.
402
After that, you can omit the location to use the default. To change the
403
default, use --remember.
486
405
This command only works on branches that have not diverged. Branches are
487
considered diverged if the destination branch's most recent commit is one
488
that has not been merged (directly or indirectly) by the source branch.
406
considered diverged if the branch being pushed to is not an older version
490
409
If branches have diverged, you can use 'bzr push --overwrite' to replace
491
the other branch completely, discarding its unmerged changes.
410
the other branch completely.
493
412
If you want to ensure you have the different changes in the other branch,
494
do a merge (see bzr help merge) from the other branch, and commit that.
495
After that you will be able to do a push without '--overwrite'.
497
If there is no default push location set, the first push will set it.
498
After that, you can omit the location to use the default. To change the
499
default, use --remember. The value will only be saved if the remote
500
location can be accessed.
413
do a merge (see bzr help merge) from the other branch, and commit that
414
before doing a 'push --overwrite'.
503
takes_options = ['remember', 'overwrite', 'verbose',
416
takes_options = ['remember', 'overwrite',
504
417
Option('create-prefix',
505
418
help='Create the path leading up to the branch '
506
419
'if it does not already exist')]
507
420
takes_args = ['location?']
508
encoding_type = 'replace'
510
422
def run(self, location=None, remember=False, overwrite=False,
511
create_prefix=False, verbose=False):
512
# FIXME: Way too big! Put this into a function called from the
423
create_prefix=False):
425
from shutil import rmtree
514
426
from bzrlib.transport import get_transport
516
428
br_from = Branch.open_containing('.')[0]
555
457
needed.append((new_transport,
556
458
new_transport.relpath(transport.base)))
557
459
if new_transport.base == transport.base:
558
raise BzrCommandError("Could not create "
460
raise BzrCommandError("Could not creeate "
560
dir_to = br_from.bzrdir.clone(location_url,
561
revision_id=br_from.last_revision())
562
br_to = dir_to.open_branch()
563
count = len(br_to.revision_history())
564
# We successfully created the target, remember it
565
if br_from.get_push_location() is None or remember:
566
br_from.set_push_location(br_to.base)
568
# We were able to connect to the remote location, so remember it
569
# we don't need to successfully push because of possible divergence.
570
if br_from.get_push_location() is None or remember:
571
br_from.set_push_location(br_to.base)
572
old_rh = br_to.revision_history()
575
tree_to = dir_to.open_workingtree()
576
except errors.NotLocalUrl:
577
warning('This transport does not update the working '
578
'tree of: %s' % (br_to.base,))
579
count = br_to.pull(br_from, overwrite)
580
except NoWorkingTree:
581
count = br_to.pull(br_from, overwrite)
583
count = tree_to.pull(br_from, overwrite)
584
except DivergedBranches:
585
raise BzrCommandError("These branches have diverged."
586
" Try a merge then push with overwrite.")
587
note('%d revision(s) pushed.' % (count,))
590
new_rh = br_to.revision_history()
593
from bzrlib.log import show_changed_revisions
594
show_changed_revisions(br_to, old_rh, new_rh,
464
br_to = Branch.initialize(location)
466
br_to.pull(br_from, overwrite)
467
except DivergedBranches:
468
raise BzrCommandError("These branches have diverged."
469
" Try a merge then push with overwrite.")
470
if br_from.get_push_location() is None or remember:
471
br_from.set_push_location(location)
598
474
class cmd_branch(Command):
630
511
br_from.lock_read()
632
513
if basis is not None:
633
basis_dir = bzrdir.BzrDir.open_containing(basis)[0]
514
basis_branch = Branch.open_containing(basis)[0]
636
517
if len(revision) == 1 and revision[0] is not None:
637
518
revision_id = revision[0].in_history(br_from)[1]
639
# FIXME - wt.last_revision, fallback to branch, fall back to
640
# None or perhaps NULL_REVISION to mean copy nothing
642
revision_id = br_from.last_revision()
643
521
if to_location is None:
644
522
to_location = os.path.basename(from_location.rstrip("/\\"))
647
525
name = os.path.basename(to_location) + '\n'
649
to_transport = get_transport(to_location)
651
to_transport.mkdir('.')
652
except errors.FileExists:
653
raise BzrCommandError('Target directory "%s" already'
654
' exists.' % to_location)
655
except errors.NoSuchFile:
656
raise BzrCommandError('Parent of "%s" does not exist.' %
659
# preserve whatever source format we have.
660
dir = br_from.bzrdir.sprout(to_transport.base,
661
revision_id, basis_dir)
662
branch = dir.open_branch()
663
except errors.NoSuchRevision:
664
to_transport.delete_tree('.')
527
os.mkdir(to_location)
529
if e.errno == errno.EEXIST:
530
raise BzrCommandError('Target directory "%s" already'
531
' exists.' % to_location)
532
if e.errno == errno.ENOENT:
533
raise BzrCommandError('Parent of "%s" does not exist.' %
538
copy_branch(br_from, to_location, revision_id, basis_branch)
539
except bzrlib.errors.NoSuchRevision:
665
541
msg = "The branch %s has no revision %s." % (from_location, revision[0])
666
542
raise BzrCommandError(msg)
667
except errors.UnlistableBranch:
668
osutils.rmtree(to_location)
543
except bzrlib.errors.UnlistableBranch:
669
545
msg = "The branch %s cannot be used as a --basis" % (basis,)
670
546
raise BzrCommandError(msg)
547
branch = Branch.open(to_location)
672
branch.control_files.put_utf8('branch-name', name)
673
note('Branched %d revision(s).' % branch.revno())
549
name = StringIO(name)
550
branch.put_controlfile('branch-name', name)
678
class cmd_checkout(Command):
679
"""Create a new checkout of an existing branch.
681
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
682
the branch found in '.'. This is useful if you have removed the working tree
683
or if it was never created - i.e. if you pushed the branch to its current
686
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
687
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
689
To retrieve the branch as of a particular revision, supply the --revision
690
parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
691
out of date [so you cannot commit] but it may be useful (i.e. to examine old
694
--basis is to speed up checking out from remote branches. When specified, it
695
uses the inventory and file contents from the basis branch in preference to the
696
branch being checked out.
698
takes_args = ['branch_location?', 'to_location?']
699
takes_options = ['revision', # , 'basis']
700
Option('lightweight',
701
help="perform a lightweight checkout. Lightweight "
702
"checkouts depend on access to the branch for "
703
"every operation. Normal checkouts can perform "
704
"common operations like diff and status without "
705
"such access, and also support local commits."
710
def run(self, branch_location=None, to_location=None, revision=None, basis=None,
714
elif len(revision) > 1:
715
raise BzrCommandError(
716
'bzr checkout --revision takes exactly 1 revision value')
717
if branch_location is None:
718
branch_location = osutils.getcwd()
719
to_location = branch_location
720
source = Branch.open(branch_location)
721
if len(revision) == 1 and revision[0] is not None:
722
revision_id = revision[0].in_history(source)[1]
725
if to_location is None:
726
to_location = os.path.basename(branch_location.rstrip("/\\"))
727
# if the source and to_location are the same,
728
# and there is no working tree,
729
# then reconstitute a branch
730
if (osutils.abspath(to_location) ==
731
osutils.abspath(branch_location)):
733
source.bzrdir.open_workingtree()
734
except errors.NoWorkingTree:
735
source.bzrdir.create_workingtree()
738
os.mkdir(to_location)
740
if e.errno == errno.EEXIST:
741
raise BzrCommandError('Target directory "%s" already'
742
' exists.' % to_location)
743
if e.errno == errno.ENOENT:
744
raise BzrCommandError('Parent of "%s" does not exist.' %
748
old_format = bzrdir.BzrDirFormat.get_default_format()
749
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
752
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
753
branch.BranchReferenceFormat().initialize(checkout, source)
755
checkout_branch = bzrdir.BzrDir.create_branch_convenience(
756
to_location, force_new_tree=False)
757
checkout = checkout_branch.bzrdir
758
checkout_branch.bind(source)
759
if revision_id is not None:
760
rh = checkout_branch.revision_history()
761
checkout_branch.set_revision_history(rh[:rh.index(revision_id) + 1])
762
checkout.create_workingtree(revision_id)
764
bzrdir.BzrDirFormat.set_default_format(old_format)
767
557
class cmd_renames(Command):
773
563
takes_args = ['dir?']
776
def run(self, dir=u'.'):
777
from bzrlib.tree import find_renames
778
tree = WorkingTree.open_containing(dir)[0]
779
old_inv = tree.basis_tree().inventory
780
new_inv = tree.read_working_inventory()
781
renames = list(find_renames(old_inv, new_inv))
566
def run(self, dir='.'):
567
b = Branch.open_containing(dir)[0]
568
old_inv = b.basis_tree().inventory
569
new_inv = b.working_tree().read_working_inventory()
571
renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
783
573
for old_name, new_name in renames:
784
self.outf.write("%s => %s\n" % (old_name, new_name))
787
class cmd_update(Command):
788
"""Update a tree to have the latest code committed to its branch.
790
This will perform a merge into the working tree, and may generate
791
conflicts. If you have any local changes, you will still
792
need to commit them after the update for the update to be complete.
794
If you want to discard your local changes, you can just do a
795
'bzr revert' instead of 'bzr commit' after the update.
797
takes_args = ['dir?']
799
def run(self, dir='.'):
800
tree = WorkingTree.open_containing(dir)[0]
803
if tree.last_revision() == tree.branch.last_revision():
804
# may be up to date, check master too.
805
master = tree.branch.get_master_branch()
806
if master is None or master.last_revision == tree.last_revision():
807
note("Tree is up to date.")
809
conflicts = tree.update()
810
note('Updated to revision %d.' %
811
(tree.branch.revision_id_to_revno(tree.last_revision()),))
574
print "%s => %s" % (old_name, new_name)
820
577
class cmd_info(Command):
821
"""Show information about a working tree, branch or repository.
823
This command will show all known locations and formats associated to the
824
tree, branch or repository. Statistical information is included with
827
Branches and working trees will also report any missing revisions.
829
takes_args = ['location?']
830
takes_options = ['verbose']
578
"""Show statistical information about a branch."""
579
takes_args = ['branch?']
833
def run(self, location=None, verbose=False):
834
from bzrlib.info import show_bzrdir_info
835
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
582
def run(self, branch=None):
584
b = Branch.open_containing(branch)[0]
839
588
class cmd_remove(Command):
842
591
This makes bzr stop tracking changes to a versioned file. It does
843
592
not delete the working copy.
845
You can specify one or more files, and/or --new. If you specify --new,
846
only 'added' files will be removed. If you specify both, then new files
847
in the specified directories will be removed. If the directories are
848
also new, they will also be removed.
850
takes_args = ['file*']
851
takes_options = ['verbose', Option('new', help='remove newly-added files')]
594
takes_args = ['file+']
595
takes_options = ['verbose']
853
encoding_type = 'replace'
855
def run(self, file_list, verbose=False, new=False):
856
tree, file_list = tree_files(file_list)
858
if file_list is None:
859
raise BzrCommandError('Specify one or more files to remove, or'
862
from bzrlib.delta import compare_trees
863
added = [compare_trees(tree.basis_tree(), tree,
864
specific_files=file_list).added]
865
file_list = sorted([f[0] for f in added[0]], reverse=True)
866
if len(file_list) == 0:
867
raise BzrCommandError('No matching files.')
868
tree.remove(file_list, verbose=verbose, to_file=self.outf)
598
def run(self, file_list, verbose=False):
599
b, file_list = branch_files(file_list)
600
tree = b.working_tree()
601
tree.remove(file_list, verbose=verbose)
871
604
class cmd_file_id(Command):
875
608
same through all revisions where the file exists, even when it is
876
609
moved or renamed.
880
612
takes_args = ['filename']
883
614
def run(self, filename):
884
tree, relpath = WorkingTree.open_containing(filename)
885
i = tree.inventory.path2id(relpath)
615
b, relpath = Branch.open_containing(filename)
616
i = b.inventory.path2id(relpath)
887
618
raise BzrError("%r is not a versioned file" % filename)
889
self.outf.write(i + '\n')
892
623
class cmd_file_path(Command):
893
624
"""Print path of file_ids to a file or directory.
895
626
This prints one line for each directory down to the target,
896
starting at the branch root.
627
starting at the branch root."""
900
629
takes_args = ['filename']
903
631
def run(self, filename):
904
tree, relpath = WorkingTree.open_containing(filename)
632
b, relpath = Branch.open_containing(filename)
906
634
fid = inv.path2id(relpath)
908
636
raise BzrError("%r is not a versioned file" % filename)
909
637
for fip in inv.get_idpath(fid):
910
self.outf.write(fip + '\n')
913
class cmd_reconcile(Command):
914
"""Reconcile bzr metadata in a branch.
916
This can correct data mismatches that may have been caused by
917
previous ghost operations or bzr upgrades. You should only
918
need to run this command if 'bzr check' or a bzr developer
919
advises you to run it.
921
If a second branch is provided, cross-branch reconciliation is
922
also attempted, which will check that data like the tree root
923
id which was not present in very early bzr versions is represented
924
correctly in both branches.
926
At the same time it is run it may recompress data resulting in
927
a potential saving in disk space or performance gain.
929
The branch *MUST* be on a listable system such as local disk or sftp.
931
takes_args = ['branch?']
933
def run(self, branch="."):
934
from bzrlib.reconcile import reconcile
935
dir = bzrdir.BzrDir.open(branch)
939
641
class cmd_revision_history(Command):
940
"""Display the list of revision ids on a branch."""
941
takes_args = ['location?']
642
"""Display list of revision ids on this branch."""
946
def run(self, location="."):
947
branch = Branch.open_containing(location)[0]
948
for revid in branch.revision_history():
949
self.outf.write(revid)
950
self.outf.write('\n')
646
for patchid in Branch.open_containing('.')[0].revision_history():
953
650
class cmd_ancestry(Command):
954
651
"""List all revisions merged into this branch."""
955
takes_args = ['location?']
960
def run(self, location="."):
962
wt = WorkingTree.open_containing(location)[0]
963
except errors.NoWorkingTree:
964
b = Branch.open(location)
965
last_revision = b.last_revision()
968
last_revision = wt.last_revision()
970
revision_ids = b.repository.get_ancestry(last_revision)
971
assert revision_ids[0] == None
973
for revision_id in revision_ids:
974
self.outf.write(revision_id + '\n')
655
b = Branch.open_containing('.')[0]
656
for revision_id in b.get_ancestry(b.last_revision()):
660
class cmd_directories(Command):
661
"""Display list of versioned directories in this branch."""
664
for name, ie in (Branch.open_containing('.')[0].working_tree().
665
read_working_inventory().directories()):
977
672
class cmd_init(Command):
1017
695
# locations if the user supplies an extended path
1018
696
if not os.path.exists(location):
1019
697
os.mkdir(location)
1021
existing_bzrdir = bzrdir.BzrDir.open(location)
1022
except NotBranchError:
1023
# really a NotBzrDir error...
1024
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1026
if existing_bzrdir.has_branch():
1027
if existing_bzrdir.has_workingtree():
1028
raise errors.AlreadyBranchError(location)
1030
raise errors.BranchExistsWithoutWorkingTree(location)
1032
existing_bzrdir.create_branch()
1033
existing_bzrdir.create_workingtree()
1036
class cmd_init_repository(Command):
1037
"""Create a shared repository to hold branches.
1039
New branches created under the repository directory will store their revisions
1040
in the repository, not in the branch directory, if the branch format supports
1046
bzr checkout --lightweight repo/trunk trunk-checkout
1050
takes_args = ["location"]
1051
takes_options = [Option('format',
1052
help='Specify a format for this repository.'
1053
' Current formats are: default, knit,'
1054
' metaweave and weave. Default is knit;'
1055
' metaweave and weave are deprecated',
1056
type=get_format_type),
1058
help='Allows branches in repository to have'
1060
aliases = ["init-repo"]
1061
def run(self, location, format=None, trees=False):
1062
from bzrlib.transport import get_transport
1064
format = get_format_type('default')
1065
transport = get_transport(location)
1066
if not transport.has('.'):
1068
newdir = format.initialize_on_transport(transport)
1069
repo = newdir.create_repository(shared=True)
1070
repo.set_make_working_trees(trees)
698
Branch.initialize(location)
1073
701
class cmd_diff(Command):
1076
704
If files are listed, only the changes in those files are listed.
1077
705
Otherwise, all changes for the tree are listed.
1079
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1080
produces patches suitable for "patch -p1".
1086
bzr diff --diff-prefix old/:new/
1087
bzr diff bzr.mine bzr.dev
712
# TODO: Allow diff across branches.
1090
713
# TODO: Option to use external diff command; could be GNU diff, wdiff,
1091
714
# or a graphical diff.
1093
716
# TODO: Python difflib is not exactly the same as unidiff; should
1094
717
# either fix it up or prefer to use an external diff.
719
# TODO: If a directory is given, diff everything under that.
1096
721
# TODO: Selected-file diff is inefficient and doesn't show you
1097
722
# deleted files.
1099
724
# TODO: This probably handles non-Unix newlines poorly.
1101
726
takes_args = ['file*']
1102
takes_options = ['revision', 'diff-options', 'prefix']
727
takes_options = ['revision', 'diff-options']
1103
728
aliases = ['di', 'dif']
1104
encoding_type = 'exact'
1106
730
@display_command
1107
def run(self, revision=None, file_list=None, diff_options=None,
1109
from bzrlib.diff import diff_cmd_helper, show_diff_trees
1111
if (prefix is None) or (prefix == '0'):
1119
if not ':' in prefix:
1120
raise BzrError("--diff-prefix expects two values separated by a colon")
1121
old_label, new_label = prefix.split(":")
731
def run(self, revision=None, file_list=None, diff_options=None):
732
from bzrlib.diff import show_diff
1124
tree1, file_list = internal_tree_files(file_list)
1128
except FileInWrongBranch:
1129
if len(file_list) != 2:
1130
raise BzrCommandError("Files are in different branches")
1132
tree1, file1 = WorkingTree.open_containing(file_list[0])
1133
tree2, file2 = WorkingTree.open_containing(file_list[1])
1134
if file1 != "" or file2 != "":
1135
# FIXME diff those two files. rbc 20051123
1136
raise BzrCommandError("Files are in different branches")
734
b, file_list = branch_files(file_list)
1138
735
if revision is not None:
1139
if tree2 is not None:
1140
raise BzrCommandError("Can't specify -r with two branches")
1141
if (len(revision) == 1) or (revision[1].spec is None):
1142
return diff_cmd_helper(tree1, file_list, diff_options,
1144
old_label=old_label, new_label=new_label)
736
if len(revision) == 1:
737
return show_diff(b, revision[0], specific_files=file_list,
738
external_diff_options=diff_options)
1145
739
elif len(revision) == 2:
1146
return diff_cmd_helper(tree1, file_list, diff_options,
1147
revision[0], revision[1],
1148
old_label=old_label, new_label=new_label)
740
return show_diff(b, revision[0], specific_files=file_list,
741
external_diff_options=diff_options,
742
revision2=revision[1])
1150
744
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
1152
if tree2 is not None:
1153
return show_diff_trees(tree1, tree2, sys.stdout,
1154
specific_files=file_list,
1155
external_diff_options=diff_options,
1156
old_label=old_label, new_label=new_label)
1158
return diff_cmd_helper(tree1, file_list, diff_options,
1159
old_label=old_label, new_label=new_label)
746
return show_diff(b, None, specific_files=file_list,
747
external_diff_options=diff_options)
1162
750
class cmd_deleted(Command):
1223
812
@display_command
1224
813
def run(self, filename=None):
1225
814
"""Print the branch root."""
1226
tree = WorkingTree.open_containing(filename)[0]
1227
self.outf.write(tree.basedir + '\n')
815
b = Branch.open_containing(filename)[0]
1230
819
class cmd_log(Command):
1231
"""Show log of a branch, file, or directory.
1233
By default show the log of the branch containing the working directory.
820
"""Show log of this branch.
1235
822
To request a range of logs, you can use the command -r begin..end
1236
823
-r revision requests a specific revision, -r ..end or -r begin.. are
1242
bzr log -r -10.. http://server/branch
1245
827
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1247
takes_args = ['location?']
829
takes_args = ['filename?']
1248
830
takes_options = [Option('forward',
1249
831
help='show from oldest to newest'),
1252
help='show files changed in each revision'),
832
'timezone', 'verbose',
1253
833
'show-ids', 'revision',
834
Option('line', help='format with one line per revision'),
1256
836
Option('message',
1257
837
help='show revisions whose message matches this regexp',
839
Option('short', help='use moderately short format'),
1261
encoding_type = 'replace'
1263
841
@display_command
1264
def run(self, location=None, timezone='original',
842
def run(self, filename=None, timezone='original',
1274
851
from bzrlib.log import log_formatter, show_log
1275
853
assert message is None or isinstance(message, basestring), \
1276
854
"invalid message argument %r" % message
1277
855
direction = (forward and 'forward') or 'reverse'
1282
# find the file id to log:
1284
dir, fp = bzrdir.BzrDir.open_containing(location)
1285
b = dir.open_branch()
858
b, fp = Branch.open_containing(filename)
1289
inv = dir.open_workingtree().inventory
1290
except (errors.NotBranchError, errors.NotLocalUrl):
1291
# either no tree, or is remote.
1292
inv = b.basis_tree().inventory
861
inv = b.working_tree().read_working_inventory()
862
except NoWorkingTree:
863
inv = b.get_inventory(b.last_revision())
1293
864
file_id = inv.path2id(fp)
866
file_id = None # points to branch root
1296
# FIXME ? log the current subdir only RBC 20060203
1297
dir, relpath = bzrdir.BzrDir.open_containing('.')
1298
b = dir.open_branch()
868
b, relpath = Branch.open_containing('.')
1300
871
if revision is None:
1537
1096
is found exports to a directory (equivalent to --format=dir).
1539
1098
Root may be the top directory for tar, tgz and tbz2 formats. If none
1540
is given, the top directory will be the root name of the file.
1542
Note: export of tree with non-ascii filenames to zip is not supported.
1544
Supported formats Autodetected by extension
1545
----------------- -------------------------
1548
tbz2 .tar.bz2, .tbz2
1099
is given, the top directory will be the root name of the file."""
1100
# TODO: list known exporters
1552
1101
takes_args = ['dest']
1553
1102
takes_options = ['revision', 'format', 'root']
1554
1103
def run(self, dest, revision=None, format=None, root=None):
1556
from bzrlib.export import export
1557
tree = WorkingTree.open_containing(u'.')[0]
1105
b = Branch.open_containing('.')[0]
1559
1106
if revision is None:
1560
# should be tree.last_revision FIXME
1561
1107
rev_id = b.last_revision()
1563
1109
if len(revision) != 1:
1564
1110
raise BzrError('bzr export --revision takes exactly 1 argument')
1565
1111
rev_id = revision[0].in_history(b).rev_id
1566
t = b.repository.revision_tree(rev_id)
1568
export(t, dest, format, root)
1569
except errors.NoSuchExportFormat, e:
1570
raise BzrCommandError('Unsupported export format: %s' % e.format)
1112
t = b.revision_tree(rev_id)
1113
arg_root, ext = os.path.splitext(os.path.basename(dest))
1114
if ext in ('.gz', '.bz2'):
1115
new_root, new_ext = os.path.splitext(arg_root)
1116
if new_ext == '.tar':
1122
if ext in (".tar",):
1124
elif ext in (".tar.gz", ".tgz"):
1126
elif ext in (".tar.bz2", ".tbz2"):
1130
t.export(dest, format, root)
1573
1133
class cmd_cat(Command):
1637
1187
Option('strict',
1638
1188
help="refuse to commit if there are unknown "
1639
1189
"files in the working tree."),
1641
help="perform a local only commit in a bound "
1642
"branch. Such commits are not pushed to "
1643
"the master branch until a normal commit "
1647
1191
aliases = ['ci', 'checkin']
1649
1193
def run(self, message=None, file=None, verbose=True, selected_list=None,
1650
unchanged=False, strict=False, local=False):
1651
from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
1194
unchanged=False, strict=False):
1652
1195
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
1653
1196
StrictCommitFailed)
1654
from bzrlib.msgeditor import edit_commit_message, \
1655
make_commit_message_template
1656
from tempfile import TemporaryFile
1658
# TODO: Need a blackbox test for invoking the external editor; may be
1659
# slightly problematic to run this cross-platform.
1661
# TODO: do more checks that the commit will succeed before
1662
# spending the user's valuable time typing a commit message.
1664
# TODO: if the commit *does* happen to fail, then save the commit
1665
# message to a temporary file where it can be recovered
1666
tree, selected_list = tree_files(selected_list)
1667
if selected_list == ['']:
1668
# workaround - commit of root of tree should be exactly the same
1669
# as just default commit in that tree, and succeed even though
1670
# selected-file merge commit is not done yet
1673
if local and not tree.branch.get_bound_location():
1674
raise errors.LocalRequiresBoundBranch()
1197
from bzrlib.msgeditor import edit_commit_message
1198
from bzrlib.status import show_status
1199
from cStringIO import StringIO
1201
b, selected_list = branch_files(selected_list)
1675
1202
if message is None and not file:
1676
template = make_commit_message_template(tree, selected_list)
1677
message = edit_commit_message(template)
1203
catcher = StringIO()
1204
show_status(b, specific_files=selected_list,
1206
message = edit_commit_message(catcher.getvalue())
1678
1208
if message is None:
1679
1209
raise BzrCommandError("please specify a commit message"
1680
1210
" with either --message or --file")
1682
1212
raise BzrCommandError("please specify either --message or --file")
1685
1216
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1687
1218
if message == "":
1688
raise BzrCommandError("empty commit message specified")
1691
reporter = ReportCommitToLog()
1693
reporter = NullCommitReporter()
1219
raise BzrCommandError("empty commit message specified")
1696
tree.commit(message, specific_files=selected_list,
1697
allow_pointless=unchanged, strict=strict, local=local,
1222
b.working_tree().commit(message, specific_files=selected_list,
1223
allow_pointless=unchanged, strict=strict)
1699
1224
except PointlessCommit:
1700
1225
# FIXME: This should really happen before the file is read in;
1701
1226
# perhaps prepare the commit; get the message; then actually commit
1702
raise BzrCommandError("no changes to commit."
1703
" use --unchanged to commit anyhow")
1227
raise BzrCommandError("no changes to commit",
1228
["use --unchanged to commit anyhow"])
1704
1229
except ConflictsInTree:
1705
1230
raise BzrCommandError("Conflicts detected in working tree. "
1706
1231
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1707
1232
except StrictCommitFailed:
1708
1233
raise BzrCommandError("Commit refused because there are unknown "
1709
1234
"files in the working tree.")
1710
except errors.BoundBranchOutOfDate, e:
1711
raise BzrCommandError(str(e)
1712
+ ' Either unbind, update, or'
1713
' pass --local to commit.')
1235
except errors.CannotInstallRevisions, e:
1236
raise BzrCommandError(e.msg)
1716
1239
class cmd_check(Command):
1817
1310
This creates temporary test directories in the working directory,
1818
1311
but not existing data is affected. These directories are deleted
1819
1312
if the tests pass, or left behind to help in debugging if they
1820
fail and --keep-output is specified.
1822
1315
If arguments are given, they are regular expressions that say
1823
1316
which tests should run.
1825
If the global option '--no-plugins' is given, plugins are not loaded
1826
before running the selftests. This has two effects: features provided or
1827
modified by plugins will not be tested, and tests provided by plugins will
1832
bzr --no-plugins selftest -v
1834
1318
# TODO: --list should give a list of all available tests
1836
# NB: this is used from the class without creating an instance, which is
1837
# why it does not have a self parameter.
1838
def get_transport_type(typestring):
1839
"""Parse and return a transport specifier."""
1840
if typestring == "sftp":
1841
from bzrlib.transport.sftp import SFTPAbsoluteServer
1842
return SFTPAbsoluteServer
1843
if typestring == "memory":
1844
from bzrlib.transport.memory import MemoryServer
1846
if typestring == "fakenfs":
1847
from bzrlib.transport.fakenfs import FakeNFSServer
1848
return FakeNFSServer
1849
msg = "No known transport type %s. Supported types are: sftp\n" %\
1851
raise BzrCommandError(msg)
1854
1320
takes_args = ['testspecs*']
1855
takes_options = ['verbose',
1321
takes_options = ['verbose',
1856
1322
Option('one', help='stop when one test fails'),
1857
Option('keep-output',
1858
help='keep output directories when tests fail'),
1860
help='Use a different transport by default '
1861
'throughout the test suite.',
1862
type=get_transport_type),
1863
Option('benchmark', help='run the bzr bencharks.'),
1864
Option('lsprof-timed',
1865
help='generate lsprof output for benchmarked'
1866
' sections of code.'),
1869
def run(self, testspecs_list=None, verbose=None, one=False,
1870
keep_output=False, transport=None, benchmark=None,
1325
def run(self, testspecs_list=None, verbose=False, one=False):
1872
1326
import bzrlib.ui
1873
from bzrlib.tests import selftest
1874
import bzrlib.benchmarks as benchmarks
1327
from bzrlib.selftest import selftest
1875
1328
# we don't want progress meters from the tests to go to the
1876
1329
# real output; and we don't want log messages cluttering up
1877
1330
# the real logs.
1878
save_ui = ui.ui_factory
1879
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1880
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
1882
info('running tests...')
1331
save_ui = bzrlib.ui.ui_factory
1332
bzrlib.trace.info('running tests...')
1884
ui.ui_factory = ui.SilentUIFactory()
1334
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1885
1335
if testspecs_list is not None:
1886
1336
pattern = '|'.join(testspecs_list)
1890
test_suite_factory = benchmarks.test_suite
1894
test_suite_factory = None
1897
1339
result = selftest(verbose=verbose,
1898
1340
pattern=pattern,
1899
stop_on_failure=one,
1900
keep_output=keep_output,
1901
transport=transport,
1902
test_suite_factory=test_suite_factory,
1903
lsprof_timed=lsprof_timed)
1341
stop_on_failure=one)
1905
info('tests passed')
1343
bzrlib.trace.info('tests passed')
1907
info('tests failed')
1345
bzrlib.trace.info('tests failed')
1908
1346
return int(not result)
1910
ui.ui_factory = save_ui
1913
def _get_bzr_branch():
1914
"""If bzr is run from a branch, return Branch or None"""
1915
from os.path import dirname
1918
branch = Branch.open(dirname(osutils.abspath(dirname(__file__))))
1920
except errors.BzrError:
1348
bzrlib.ui.ui_factory = save_ui
1924
1351
def show_version():
1926
1352
print "bzr (bazaar-ng) %s" % bzrlib.__version__
1927
1353
# is bzrlib itself in a branch?
1928
branch = _get_bzr_branch()
1930
rh = branch.revision_history()
1932
print " bzr checkout, revision %d" % (revno,)
1933
print " nick: %s" % (branch.nick,)
1935
print " revid: %s" % (rh[-1],)
1936
print "Using python interpreter:", sys.executable
1938
print "Using python standard library:", os.path.dirname(site.__file__)
1939
print "Using bzrlib:",
1940
if len(bzrlib.__path__) > 1:
1941
# print repr, which is a good enough way of making it clear it's
1942
# more than one element (eg ['/foo/bar', '/foo/bzr'])
1943
print repr(bzrlib.__path__)
1945
print bzrlib.__path__[0]
1354
bzrrev = bzrlib.get_bzr_revision()
1356
print " (bzr checkout, revision %d {%s})" % bzrrev
1948
1357
print bzrlib.__copyright__
1949
print "http://bazaar-vcs.org/"
1358
print "http://bazaar-ng.org/"
1951
1360
print "bzr comes with ABSOLUTELY NO WARRANTY. bzr is free software, and"
1952
1361
print "you may use, modify and redistribute it under the terms of the GNU"
1988
1397
last1 = branch1.last_revision()
1989
1398
last2 = branch2.last_revision()
1991
source = MultipleRevisionSources(branch1.repository,
1400
source = MultipleRevisionSources(branch1, branch2)
1994
1402
base_rev_id = common_ancestor(last1, last2, source)
1996
1404
print 'merge base is revision %s' % base_rev_id
1408
if base_revno is None:
1409
raise bzrlib.errors.UnrelatedBranches()
1411
print ' r%-6d in %s' % (base_revno, branch)
1413
other_revno = branch2.revision_id_to_revno(base_revid)
1415
print ' r%-6d in %s' % (other_revno, other)
1999
1419
class cmd_merge(Command):
2000
1420
"""Perform a three-way merge.
2002
The branch is the branch you will merge from. By default, it will merge
2003
the latest revision. If you specify a revision, that revision will be
2004
merged. If you specify two revisions, the first will be used as a BASE,
2005
and the second one as OTHER. Revision numbers are always relative to the
1422
The branch is the branch you will merge from. By default, it will
1423
merge the latest revision. If you specify a revision, that
1424
revision will be merged. If you specify two revisions, the first
1425
will be used as a BASE, and the second one as OTHER. Revision
1426
numbers are always relative to the specified branch.
2008
By default, bzr will try to merge in all new work from the other
1428
By default bzr will try to merge in all new work from the other
2009
1429
branch, automatically determining an appropriate base. If this
2010
1430
fails, you may need to give an explicit base.
2012
Merge will do its best to combine the changes in two branches, but there
2013
are some kinds of problems only a human can fix. When it encounters those,
2014
it will mark a conflict. A conflict means that you need to fix something,
2015
before you should commit.
2017
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
2019
If there is no default branch set, the first merge will set it. After
2020
that, you can omit the branch to use the default. To change the
2021
default, use --remember. The value will only be saved if the remote
2022
location can be accessed.
2026
1434
To merge the latest revision from bzr.dev
2035
1443
merge refuses to run if there are any uncommitted changes, unless
2036
1444
--force is given.
2038
The following merge types are available:
2040
1446
takes_args = ['branch?']
2041
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
1447
takes_options = ['revision', 'force', 'merge-type', 'reprocess',
2042
1448
Option('show-base', help="Show base revision text in "
2046
from merge import merge_type_help
2047
from inspect import getdoc
2048
return getdoc(self) + '\n' + merge_type_help()
2050
1451
def run(self, branch=None, revision=None, force=False, merge_type=None,
2051
show_base=False, reprocess=False, remember=False):
1452
show_base=False, reprocess=False):
1453
from bzrlib.merge import merge
1454
from bzrlib.merge_core import ApplyMerge3
2052
1455
if merge_type is None:
2053
merge_type = Merge3Merger
2055
tree = WorkingTree.open_containing(u'.')[0]
2057
if branch is not None:
2059
reader = bundle.read_bundle_from_url(branch)
2061
pass # Continue on considering this url a Branch
1456
merge_type = ApplyMerge3
1458
branch = Branch.open_containing('.')[0].get_parent()
1460
raise BzrCommandError("No merge location known or specified.")
2063
conflicts = merge_bundle(reader, tree, not force, merge_type,
2064
reprocess, show_base)
2070
branch = self._get_remembered_parent(tree, branch, 'Merging from')
1462
print "Using saved location: %s" % branch
2072
1463
if revision is None or len(revision) < 1:
2073
1464
base = [None, None]
2074
1465
other = [branch, -1]
2075
other_branch, path = Branch.open_containing(branch)
2077
1467
if len(revision) == 1:
2078
1468
base = [None, None]
2079
other_branch, path = Branch.open_containing(branch)
1469
other_branch = Branch.open_containing(branch)[0]
2080
1470
revno = revision[0].in_history(other_branch).revno
2081
1471
other = [branch, revno]
2119
1496
"and (if you want) report this to the bzr developers\n")
2122
# TODO: move up to common parent; this isn't merge-specific anymore.
2123
def _get_remembered_parent(self, tree, supplied_location, verb_string):
2124
"""Use tree.branch's parent if none was supplied.
2126
Report if the remembered location was used.
2128
if supplied_location is not None:
2129
return supplied_location
2130
stored_location = tree.branch.get_parent()
2131
mutter("%s", stored_location)
2132
if stored_location is None:
2133
raise BzrCommandError("No location specified or remembered")
2134
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2135
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
2136
return stored_location
2139
class cmd_remerge(Command):
2142
Use this if you want to try a different merge technique while resolving
2143
conflicts. Some merge techniques are better than others, and remerge
2144
lets you try different ones on different files.
2146
The options for remerge have the same meaning and defaults as the ones for
2147
merge. The difference is that remerge can (only) be run when there is a
2148
pending merge, and it lets you specify particular files.
2151
$ bzr remerge --show-base
2152
Re-do the merge of all conflicted files, and show the base text in
2153
conflict regions, in addition to the usual THIS and OTHER texts.
2155
$ bzr remerge --merge-type weave --reprocess foobar
2156
Re-do the merge of "foobar", using the weave merge algorithm, with
2157
additional processing to reduce the size of conflict regions.
2159
The following merge types are available:"""
2160
takes_args = ['file*']
2161
takes_options = ['merge-type', 'reprocess',
2162
Option('show-base', help="Show base revision text in "
2166
from merge import merge_type_help
2167
from inspect import getdoc
2168
return getdoc(self) + '\n' + merge_type_help()
2170
def run(self, file_list=None, merge_type=None, show_base=False,
2172
from bzrlib.merge import merge_inner, transform_tree
2173
if merge_type is None:
2174
merge_type = Merge3Merger
2175
tree, file_list = tree_files(file_list)
2178
pending_merges = tree.pending_merges()
2179
if len(pending_merges) != 1:
2180
raise BzrCommandError("Sorry, remerge only works after normal"
2181
" merges. Not cherrypicking or"
2183
repository = tree.branch.repository
2184
base_revision = common_ancestor(tree.branch.last_revision(),
2185
pending_merges[0], repository)
2186
base_tree = repository.revision_tree(base_revision)
2187
other_tree = repository.revision_tree(pending_merges[0])
2188
interesting_ids = None
2189
if file_list is not None:
2190
interesting_ids = set()
2191
for filename in file_list:
2192
file_id = tree.path2id(filename)
2194
raise NotVersionedError(filename)
2195
interesting_ids.add(file_id)
2196
if tree.kind(file_id) != "directory":
2199
for name, ie in tree.inventory.iter_entries(file_id):
2200
interesting_ids.add(ie.file_id)
2201
transform_tree(tree, tree.basis_tree(), interesting_ids)
2202
if file_list is None:
2203
restore_files = list(tree.iter_conflicts())
2205
restore_files = file_list
2206
for filename in restore_files:
2208
restore(tree.abspath(filename))
2209
except NotConflicted:
2211
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2213
interesting_ids = interesting_ids,
2214
other_rev_id=pending_merges[0],
2215
merge_type=merge_type,
2216
show_base=show_base,
2217
reprocess=reprocess)
2225
1500
class cmd_revert(Command):
2226
1501
"""Reverse all changes since the last commit.
2303
1574
takes_args = ['from_branch', 'to_branch']
2304
1575
def run(self, from_branch, to_branch):
2305
1576
from bzrlib.fetch import Fetcher
1577
from bzrlib.branch import Branch
2306
1578
from_b = Branch.open(from_branch)
2307
1579
to_b = Branch.open(to_branch)
2308
Fetcher(to_b, from_b)
1584
Fetcher(to_b, from_b)
2311
1591
class cmd_missing(Command):
2312
"""Show unmerged/unpulled revisions between two branches.
2314
OTHER_BRANCH may be local or remote."""
2315
takes_args = ['other_branch?']
2316
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2318
'Display changes in the local branch only'),
2319
Option('theirs-only',
2320
'Display changes in the remote branch only'),
2328
encoding_type = 'replace'
1592
"""What is missing in this branch relative to other branch.
1594
# TODO: rewrite this in terms of ancestry so that it shows only
1597
takes_args = ['remote?']
1598
aliases = ['mis', 'miss']
1599
# We don't have to add quiet to the list, because
1600
# unknown options are parsed as booleans
1601
takes_options = ['verbose', 'quiet']
2330
1603
@display_command
2331
def run(self, other_branch=None, reverse=False, mine_only=False,
2332
theirs_only=False, log_format=None, long=False, short=False, line=False,
2333
show_ids=False, verbose=False):
2334
from bzrlib.missing import find_unmerged, iter_log_data
2335
from bzrlib.log import log_formatter
2336
local_branch = Branch.open_containing(u".")[0]
2337
parent = local_branch.get_parent()
2338
if other_branch is None:
2339
other_branch = parent
2340
if other_branch is None:
1604
def run(self, remote=None, verbose=False, quiet=False):
1605
from bzrlib.errors import BzrCommandError
1606
from bzrlib.missing import show_missing
1608
if verbose and quiet:
1609
raise BzrCommandError('Cannot pass both quiet and verbose')
1611
b = Branch.open_containing('.')[0]
1612
parent = b.get_parent()
2341
1615
raise BzrCommandError("No missing location known or specified.")
2342
print "Using last location: " + local_branch.get_parent()
2343
remote_branch = Branch.open(other_branch)
2344
if remote_branch.base == local_branch.base:
2345
remote_branch = local_branch
2346
local_branch.lock_read()
2348
remote_branch.lock_read()
2350
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2351
if (log_format == None):
2352
default = local_branch.get_config().log_format()
2353
log_format = get_log_format(long=long, short=short,
2354
line=line, default=default)
2355
lf = log_formatter(log_format,
2358
show_timezone='original')
2359
if reverse is False:
2360
local_extra.reverse()
2361
remote_extra.reverse()
2362
if local_extra and not theirs_only:
2363
print "You have %d extra revision(s):" % len(local_extra)
2364
for data in iter_log_data(local_extra, local_branch.repository,
2367
printed_local = True
2369
printed_local = False
2370
if remote_extra and not mine_only:
2371
if printed_local is True:
2373
print "You are missing %d revision(s):" % len(remote_extra)
2374
for data in iter_log_data(remote_extra, remote_branch.repository,
2377
if not remote_extra and not local_extra:
2379
print "Branches are up to date."
2383
remote_branch.unlock()
2385
local_branch.unlock()
2386
if not status_code and parent is None and other_branch is not None:
2387
local_branch.lock_write()
2389
# handle race conditions - a parent might be set while we run.
2390
if local_branch.get_parent() is None:
2391
local_branch.set_parent(remote_branch.base)
2393
local_branch.unlock()
1618
print "Using last location: %s" % parent
1620
elif parent is None:
1621
# We only update parent if it did not exist, missing
1622
# should not change the parent
1623
b.set_parent(remote)
1624
br_remote = Branch.open_containing(remote)[0]
1625
return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
2397
1628
class cmd_plugins(Command):
2453
1678
shown only at the top, unless the --all option is given.
2455
1680
# TODO: annotate directories; showing when each file was last changed
1681
# TODO: annotate a previous version of a file
2456
1682
# TODO: if the working copy is modified, show annotations on that
2457
1683
# with new uncommitted lines marked
2458
aliases = ['ann', 'blame', 'praise']
1684
aliases = ['blame', 'praise']
2459
1685
takes_args = ['filename']
2460
1686
takes_options = [Option('all', help='show annotations on all lines'),
2461
1687
Option('long', help='show date in annotations'),
2465
1690
@display_command
2466
def run(self, filename, all=False, long=False, revision=None):
1691
def run(self, filename, all=False, long=False):
2467
1692
from bzrlib.annotate import annotate_file
2468
tree, relpath = WorkingTree.open_containing(filename)
2469
branch = tree.branch
1693
b, relpath = Branch.open_containing(filename)
2472
if revision is None:
2473
revision_id = branch.last_revision()
2474
elif len(revision) != 1:
2475
raise BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2477
revision_id = revision[0].in_history(branch).rev_id
1696
tree = WorkingTree(b.base, b)
1697
tree = b.revision_tree(b.last_revision())
2478
1698
file_id = tree.inventory.path2id(relpath)
2479
tree = branch.repository.revision_tree(revision_id)
2480
1699
file_version = tree.inventory[file_id].revision
2481
annotate_file(branch, file_version, file_id, long, all, sys.stdout)
1700
annotate_file(b, file_version, file_id, long, all, sys.stdout)
2486
1705
class cmd_re_sign(Command):
2488
1707
# TODO be able to replace existing ones.
2490
1709
hidden = True # is this right ?
2491
takes_args = ['revision_id*']
1710
takes_args = ['revision_id?']
2492
1711
takes_options = ['revision']
2494
def run(self, revision_id_list=None, revision=None):
1713
def run(self, revision_id=None, revision=None):
1714
import bzrlib.config as config
2495
1715
import bzrlib.gpg as gpg
2496
if revision_id_list is not None and revision is not None:
1716
if revision_id is not None and revision is not None:
2497
1717
raise BzrCommandError('You can only supply one of revision_id or --revision')
2498
if revision_id_list is None and revision is None:
1718
if revision_id is None and revision is None:
2499
1719
raise BzrCommandError('You must supply either --revision or a revision_id')
2500
b = WorkingTree.open_containing(u'.')[0].branch
2501
gpg_strategy = gpg.GPGStrategy(b.get_config())
2502
if revision_id_list is not None:
2503
for revision_id in revision_id_list:
2504
b.repository.sign_revision(revision_id, gpg_strategy)
1720
b = Branch.open_containing('.')[0]
1721
gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
1722
if revision_id is not None:
1723
b.sign_revision(revision_id, gpg_strategy)
2505
1724
elif revision is not None:
2506
1725
if len(revision) == 1:
2507
1726
revno, rev_id = revision[0].in_history(b)
2508
b.repository.sign_revision(rev_id, gpg_strategy)
1727
b.sign_revision(rev_id, gpg_strategy)
2509
1728
elif len(revision) == 2:
2510
1729
# are they both on rh- if so we can walk between them
2511
1730
# might be nice to have a range helper for arbitrary
2517
1736
if from_revno is None or to_revno is None:
2518
1737
raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
2519
1738
for revno in range(from_revno, to_revno + 1):
2520
b.repository.sign_revision(b.get_rev_id(revno),
1739
b.sign_revision(b.get_rev_id(revno), gpg_strategy)
2523
1741
raise BzrCommandError('Please supply either one revision, or a range.')
2526
1743
class cmd_bind(Command):
2527
"""Bind the current branch to a master branch.
1744
"""Bind the current branch to its parent.
2529
After binding, commits must succeed on the master branch
2530
before they are executed on the local one.
1746
After binding, commits must succeed on the parent branch
1747
before they can be done on the local one.
2533
takes_args = ['location']
1750
takes_args = ['location?']
2534
1751
takes_options = []
2536
1753
def run(self, location=None):
2537
b, relpath = Branch.open_containing(u'.')
1754
b, relpath = Branch.open_containing('.')
1755
if location is None:
1756
location = b.get_bound_location()
1757
if location is None:
1758
location = b.get_parent()
1759
if location is None:
1760
raise BzrCommandError('Branch has no parent,'
1761
' you must supply a bind location.')
2538
1762
b_other = Branch.open(location)
2540
1764
b.bind(b_other)
2542
1766
raise BzrCommandError('These branches have diverged.'
2543
1767
' Try merging, and then bind again.')
2546
1769
class cmd_unbind(Command):
2547
"""Unbind the current branch from its master branch.
1770
"""Bind the current branch to its parent.
2549
1772
After unbinding, the local branch is considered independent.
2550
All subsequent commits will be local.
2553
1775
takes_args = []
2554
1776
takes_options = []
2557
b, relpath = Branch.open_containing(u'.')
2559
raise BzrCommandError('Local branch is not bound')
2562
class cmd_uncommit(Command):
2563
"""Remove the last committed revision.
2565
--verbose will print out what is being removed.
2566
--dry-run will go through all the motions, but not actually
2569
In the future, uncommit will create a revision bundle, which can then
2573
# TODO: jam 20060108 Add an option to allow uncommit to remove
2574
# unreferenced information in 'branch-as-repository' branches.
2575
# TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
2576
# information in shared branches as well.
2577
takes_options = ['verbose', 'revision',
2578
Option('dry-run', help='Don\'t actually make changes'),
2579
Option('force', help='Say yes to all questions.')]
2580
takes_args = ['location?']
2583
def run(self, location=None,
2584
dry_run=False, verbose=False,
2585
revision=None, force=False):
2586
from bzrlib.log import log_formatter
2588
from bzrlib.uncommit import uncommit
2590
if location is None:
2592
control, relpath = bzrdir.BzrDir.open_containing(location)
2594
tree = control.open_workingtree()
2596
except (errors.NoWorkingTree, errors.NotLocalUrl):
2598
b = control.open_branch()
2600
if revision is None:
2602
rev_id = b.last_revision()
2604
revno, rev_id = revision[0].in_history(b)
2606
print 'No revisions to uncommit.'
2608
for r in range(revno, b.revno()+1):
2609
rev_id = b.get_rev_id(r)
2610
lf = log_formatter('short', to_file=sys.stdout,show_timezone='original')
2611
lf.show(r, b.repository.get_revision(rev_id), None)
2614
print 'Dry-run, pretending to remove the above revisions.'
2616
val = raw_input('Press <enter> to continue')
2618
print 'The above revision(s) will be removed.'
2620
val = raw_input('Are you sure [y/N]? ')
2621
if val.lower() not in ('y', 'yes'):
2625
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
2629
class cmd_break_lock(Command):
2630
"""Break a dead lock on a repository, branch or working directory.
2632
CAUTION: Locks should only be broken when you are sure that the process
2633
holding the lock has been stopped.
2635
You can get information on what locks are open via the 'bzr info' command.
2640
takes_args = ['location?']
2642
def run(self, location=None, show=False):
2643
if location is None:
2645
control, relpath = bzrdir.BzrDir.open_containing(location)
2647
control.break_lock()
2648
except NotImplementedError:
2653
# command-line interpretation helper for merge-related commands
2654
def merge(other_revision, base_revision,
2655
check_clean=True, ignore_zero=False,
2656
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2657
file_list=None, show_base=False, reprocess=False,
2658
pb=DummyProgress()):
2659
"""Merge changes into a tree.
2662
list(path, revno) Base for three-way merge.
2663
If [None, None] then a base will be automatically determined.
2665
list(path, revno) Other revision for three-way merge.
2667
Directory to merge changes into; '.' by default.
2669
If true, this_dir must have no uncommitted changes before the
2671
ignore_zero - If true, suppress the "zero conflicts" message when
2672
there are no conflicts; should be set when doing something we expect
2673
to complete perfectly.
2674
file_list - If supplied, merge only changes to selected files.
2676
All available ancestors of other_revision and base_revision are
2677
automatically pulled into the branch.
2679
The revno may be -1 to indicate the last revision on the branch, which is
2682
This function is intended for use from the command line; programmatic
2683
clients might prefer to call merge.merge_inner(), which has less magic
2686
from bzrlib.merge import Merger
2687
if this_dir is None:
2689
this_tree = WorkingTree.open_containing(this_dir)[0]
2690
if show_base and not merge_type is Merge3Merger:
2691
raise BzrCommandError("Show-base is not supported for this merge"
2692
" type. %s" % merge_type)
2693
if reprocess and not merge_type.supports_reprocess:
2694
raise BzrCommandError("Conflict reduction is not supported for merge"
2695
" type %s." % merge_type)
2696
if reprocess and show_base:
2697
raise BzrCommandError("Cannot do conflict reduction and show base.")
2699
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2700
merger.pp = ProgressPhase("Merge phase", 5, pb)
2701
merger.pp.next_phase()
2702
merger.check_basis(check_clean)
2703
merger.set_other(other_revision)
2704
merger.pp.next_phase()
2705
merger.set_base(base_revision)
2706
if merger.base_rev_id == merger.other_rev_id:
2707
note('Nothing to do.')
2709
merger.backup_files = backup_files
2710
merger.merge_type = merge_type
2711
merger.set_interesting_files(file_list)
2712
merger.show_base = show_base
2713
merger.reprocess = reprocess
2714
conflicts = merger.do_merge()
2715
if file_list is None:
2716
merger.set_pending()
1779
b, relpath = Branch.open_containing('.')
2722
1782
# these get imported and then picked up by the scan for cmd_*
2723
1783
# TODO: Some more consistent way to split command definitions across files;
2724
1784
# we do need to load at least some information about them to know of
2725
# aliases. ideally we would avoid loading the implementation until the
2726
# details were needed.
2727
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2728
from bzrlib.bundle.commands import cmd_bundle_revisions
2729
from bzrlib.sign_my_commits import cmd_sign_my_commits
2730
from bzrlib.weave_commands import cmd_weave_list, cmd_weave_join, \
2731
cmd_weave_plan_merge, cmd_weave_merge_text
1786
from bzrlib.conflicts import cmd_resolve, cmd_conflicts