summaryrefslogtreecommitdiff
path: root/bzrlib/tests/test_patches_data/diff
diff options
context:
space:
mode:
Diffstat (limited to 'bzrlib/tests/test_patches_data/diff')
-rw-r--r--bzrlib/tests/test_patches_data/diff1154
1 files changed, 1154 insertions, 0 deletions
diff --git a/bzrlib/tests/test_patches_data/diff b/bzrlib/tests/test_patches_data/diff
new file mode 100644
index 0000000..3ead13c
--- /dev/null
+++ b/bzrlib/tests/test_patches_data/diff
@@ -0,0 +1,1154 @@
+--- orig/commands.py
++++ mod/commands.py
+@@ -19,25 +19,31 @@
+ import arch
+ import arch.util
+ import arch.arch
++
++import pylon.errors
++from pylon.errors import *
++from pylon import errors
++from pylon import util
++from pylon import arch_core
++from pylon import arch_compound
++from pylon import ancillary
++from pylon import misc
++from pylon import paths
++
+ import abacmds
+ import cmdutil
+ import shutil
+ import os
+ import options
+-import paths
+ import time
+ import cmd
+ import readline
+ import re
+ import string
+-import arch_core
+-from errors import *
+-import errors
+ import terminal
+-import ancillary
+-import misc
+ import email
+ import smtplib
++import textwrap
+
+ __docformat__ = "restructuredtext"
+ __doc__ = "Implementation of user (sub) commands"
+@@ -257,7 +263,7 @@
+
+ tree=arch.tree_root()
+ if len(args) == 0:
+- a_spec = cmdutil.comp_revision(tree)
++ a_spec = ancillary.comp_revision(tree)
+ else:
+ a_spec = cmdutil.determine_revision_tree(tree, args[0])
+ cmdutil.ensure_archive_registered(a_spec.archive)
+@@ -284,7 +290,7 @@
+ changeset=options.changeset
+ tmpdir = None
+ else:
+- tmpdir=cmdutil.tmpdir()
++ tmpdir=util.tmpdir()
+ changeset=tmpdir+"/changeset"
+ try:
+ delta=arch.iter_delta(a_spec, b_spec, changeset)
+@@ -304,14 +310,14 @@
+ if status > 1:
+ return
+ if (options.perform_diff):
+- chan = cmdutil.ChangesetMunger(changeset)
++ chan = arch_compound.ChangesetMunger(changeset)
+ chan.read_indices()
+- if isinstance(b_spec, arch.Revision):
+- b_dir = b_spec.library_find()
+- else:
+- b_dir = b_spec
+- a_dir = a_spec.library_find()
+ if options.diffopts is not None:
++ if isinstance(b_spec, arch.Revision):
++ b_dir = b_spec.library_find()
++ else:
++ b_dir = b_spec
++ a_dir = a_spec.library_find()
+ diffopts = options.diffopts.split()
+ cmdutil.show_custom_diffs(chan, diffopts, a_dir, b_dir)
+ else:
+@@ -517,7 +523,7 @@
+ except arch.errors.TreeRootError, e:
+ print e
+ return
+- from_revision=cmdutil.tree_latest(tree)
++ from_revision = arch_compound.tree_latest(tree)
+ if from_revision==to_revision:
+ print "Tree is already up to date with:\n"+str(to_revision)+"."
+ return
+@@ -592,6 +598,9 @@
+
+ if len(args) == 0:
+ args = None
++ if options.version is None:
++ return options, tree.tree_version, args
++
+ revision=cmdutil.determine_revision_arch(tree, options.version)
+ return options, revision.get_version(), args
+
+@@ -601,11 +610,16 @@
+ """
+ tree=arch.tree_root()
+ options, version, files = self.parse_commandline(cmdargs, tree)
++ ancestor = None
+ if options.__dict__.has_key("base") and options.base:
+ base = cmdutil.determine_revision_tree(tree, options.base)
++ ancestor = base
+ else:
+- base = cmdutil.submit_revision(tree)
+-
++ base = ancillary.submit_revision(tree)
++ ancestor = base
++ if ancestor is None:
++ ancestor = arch_compound.tree_latest(tree, version)
++
+ writeversion=version
+ archive=version.archive
+ source=cmdutil.get_mirror_source(archive)
+@@ -625,18 +639,26 @@
+ try:
+ last_revision=tree.iter_logs(version, True).next().revision
+ except StopIteration, e:
+- if cmdutil.prompt("Import from commit"):
+- return do_import(version)
+- else:
+- raise NoVersionLogs(version)
+- if last_revision!=version.iter_revisions(True).next():
++ last_revision = None
++ if ancestor is None:
++ if cmdutil.prompt("Import from commit"):
++ return do_import(version)
++ else:
++ raise NoVersionLogs(version)
++ try:
++ arch_last_revision = version.iter_revisions(True).next()
++ except StopIteration, e:
++ arch_last_revision = None
++
++ if last_revision != arch_last_revision:
++ print "Tree is not up to date with %s" % str(version)
+ if not cmdutil.prompt("Out of date"):
+ raise OutOfDate
+ else:
+ allow_old=True
+
+ try:
+- if not cmdutil.has_changed(version):
++ if not cmdutil.has_changed(ancestor):
+ if not cmdutil.prompt("Empty commit"):
+ raise EmptyCommit
+ except arch.util.ExecProblem, e:
+@@ -645,15 +667,15 @@
+ raise MissingID(e)
+ else:
+ raise
+- log = tree.log_message(create=False)
++ log = tree.log_message(create=False, version=version)
+ if log is None:
+ try:
+ if cmdutil.prompt("Create log"):
+- edit_log(tree)
++ edit_log(tree, version)
+
+ except cmdutil.NoEditorSpecified, e:
+ raise CommandFailed(e)
+- log = tree.log_message(create=False)
++ log = tree.log_message(create=False, version=version)
+ if log is None:
+ raise NoLogMessage
+ if log["Summary"] is None or len(log["Summary"].strip()) == 0:
+@@ -837,23 +859,24 @@
+ if spec is not None:
+ revision = cmdutil.determine_revision_tree(tree, spec)
+ else:
+- revision = cmdutil.comp_revision(tree)
++ revision = ancillary.comp_revision(tree)
+ except cmdutil.CantDetermineRevision, e:
+ raise CommandFailedWrapper(e)
+ munger = None
+
+ if options.file_contents or options.file_perms or options.deletions\
+ or options.additions or options.renames or options.hunk_prompt:
+- munger = cmdutil.MungeOpts()
+- munger.hunk_prompt = options.hunk_prompt
++ munger = arch_compound.MungeOpts()
++ munger.set_hunk_prompt(cmdutil.colorize, cmdutil.user_hunk_confirm,
++ options.hunk_prompt)
+
+ if len(args) > 0 or options.logs or options.pattern_files or \
+ options.control:
+ if munger is None:
+- munger = cmdutil.MungeOpts(True)
++ munger = cmdutil.arch_compound.MungeOpts(True)
+ munger.all_types(True)
+ if len(args) > 0:
+- t_cwd = cmdutil.tree_cwd(tree)
++ t_cwd = arch_compound.tree_cwd(tree)
+ for name in args:
+ if len(t_cwd) > 0:
+ t_cwd += "/"
+@@ -878,7 +901,7 @@
+ if options.pattern_files:
+ munger.add_keep_pattern(options.pattern_files)
+
+- for line in cmdutil.revert(tree, revision, munger,
++ for line in arch_compound.revert(tree, revision, munger,
+ not options.no_output):
+ cmdutil.colorize(line)
+
+@@ -1042,18 +1065,13 @@
+ help_tree_spec()
+ return
+
+-def require_version_exists(version, spec):
+- if not version.exists():
+- raise cmdutil.CantDetermineVersion(spec,
+- "The version %s does not exist." \
+- % version)
+-
+ class Revisions(BaseCommand):
+ """
+ Print a revision name based on a revision specifier
+ """
+ def __init__(self):
+ self.description="Lists revisions"
++ self.cl_revisions = []
+
+ def do_command(self, cmdargs):
+ """
+@@ -1066,224 +1084,68 @@
+ self.tree = arch.tree_root()
+ except arch.errors.TreeRootError:
+ self.tree = None
++ if options.type == "default":
++ options.type = "archive"
+ try:
+- iter = self.get_iterator(options.type, args, options.reverse,
+- options.modified)
++ iter = cmdutil.revision_iterator(self.tree, options.type, args,
++ options.reverse, options.modified,
++ options.shallow)
+ except cmdutil.CantDetermineRevision, e:
+ raise CommandFailedWrapper(e)
+-
++ except cmdutil.CantDetermineVersion, e:
++ raise CommandFailedWrapper(e)
+ if options.skip is not None:
+ iter = cmdutil.iter_skip(iter, int(options.skip))
+
+- for revision in iter:
+- log = None
+- if isinstance(revision, arch.Patchlog):
+- log = revision
+- revision=revision.revision
+- print options.display(revision)
+- if log is None and (options.summary or options.creator or
+- options.date or options.merges):
+- log = revision.patchlog
+- if options.creator:
+- print " %s" % log.creator
+- if options.date:
+- print " %s" % time.strftime('%Y-%m-%d %H:%M:%S %Z', log.date)
+- if options.summary:
+- print " %s" % log.summary
+- if options.merges:
+- showed_title = False
+- for revision in log.merged_patches:
+- if not showed_title:
+- print " Merged:"
+- showed_title = True
+- print " %s" % revision
+-
+- def get_iterator(self, type, args, reverse, modified):
+- if len(args) > 0:
+- spec = args[0]
+- else:
+- spec = None
+- if modified is not None:
+- iter = cmdutil.modified_iter(modified, self.tree)
+- if reverse:
+- return iter
+- else:
+- return cmdutil.iter_reverse(iter)
+- elif type == "archive":
+- if spec is None:
+- if self.tree is None:
+- raise cmdutil.CantDetermineRevision("",
+- "Not in a project tree")
+- version = cmdutil.determine_version_tree(spec, self.tree)
+- else:
+- version = cmdutil.determine_version_arch(spec, self.tree)
+- cmdutil.ensure_archive_registered(version.archive)
+- require_version_exists(version, spec)
+- return version.iter_revisions(reverse)
+- elif type == "cacherevs":
+- if spec is None:
+- if self.tree is None:
+- raise cmdutil.CantDetermineRevision("",
+- "Not in a project tree")
+- version = cmdutil.determine_version_tree(spec, self.tree)
+- else:
+- version = cmdutil.determine_version_arch(spec, self.tree)
+- cmdutil.ensure_archive_registered(version.archive)
+- require_version_exists(version, spec)
+- return cmdutil.iter_cacherevs(version, reverse)
+- elif type == "library":
+- if spec is None:
+- if self.tree is None:
+- raise cmdutil.CantDetermineRevision("",
+- "Not in a project tree")
+- version = cmdutil.determine_version_tree(spec, self.tree)
+- else:
+- version = cmdutil.determine_version_arch(spec, self.tree)
+- return version.iter_library_revisions(reverse)
+- elif type == "logs":
+- if self.tree is None:
+- raise cmdutil.CantDetermineRevision("", "Not in a project tree")
+- return self.tree.iter_logs(cmdutil.determine_version_tree(spec, \
+- self.tree), reverse)
+- elif type == "missing" or type == "skip-present":
+- if self.tree is None:
+- raise cmdutil.CantDetermineRevision("", "Not in a project tree")
+- skip = (type == "skip-present")
+- version = cmdutil.determine_version_tree(spec, self.tree)
+- cmdutil.ensure_archive_registered(version.archive)
+- require_version_exists(version, spec)
+- return cmdutil.iter_missing(self.tree, version, reverse,
+- skip_present=skip)
+-
+- elif type == "present":
+- if self.tree is None:
+- raise cmdutil.CantDetermineRevision("", "Not in a project tree")
+- version = cmdutil.determine_version_tree(spec, self.tree)
+- cmdutil.ensure_archive_registered(version.archive)
+- require_version_exists(version, spec)
+- return cmdutil.iter_present(self.tree, version, reverse)
+-
+- elif type == "new-merges" or type == "direct-merges":
+- if self.tree is None:
+- raise cmdutil.CantDetermineRevision("", "Not in a project tree")
+- version = cmdutil.determine_version_tree(spec, self.tree)
+- cmdutil.ensure_archive_registered(version.archive)
+- require_version_exists(version, spec)
+- iter = cmdutil.iter_new_merges(self.tree, version, reverse)
+- if type == "new-merges":
+- return iter
+- elif type == "direct-merges":
+- return cmdutil.direct_merges(iter)
+-
+- elif type == "missing-from":
+- if self.tree is None:
+- raise cmdutil.CantDetermineRevision("", "Not in a project tree")
+- revision = cmdutil.determine_revision_tree(self.tree, spec)
+- libtree = cmdutil.find_or_make_local_revision(revision)
+- return cmdutil.iter_missing(libtree, self.tree.tree_version,
+- reverse)
+-
+- elif type == "partner-missing":
+- return cmdutil.iter_partner_missing(self.tree, reverse)
+-
+- elif type == "ancestry":
+- revision = cmdutil.determine_revision_tree(self.tree, spec)
+- iter = cmdutil._iter_ancestry(self.tree, revision)
+- if reverse:
+- return iter
+- else:
+- return cmdutil.iter_reverse(iter)
+-
+- elif type == "dependencies" or type == "non-dependencies":
+- nondeps = (type == "non-dependencies")
+- revision = cmdutil.determine_revision_tree(self.tree, spec)
+- anc_iter = cmdutil._iter_ancestry(self.tree, revision)
+- iter_depends = cmdutil.iter_depends(anc_iter, nondeps)
+- if reverse:
+- return iter_depends
+- else:
+- return cmdutil.iter_reverse(iter_depends)
+- elif type == "micro":
+- return cmdutil.iter_micro(self.tree)
+-
+-
++ try:
++ for revision in iter:
++ log = None
++ if isinstance(revision, arch.Patchlog):
++ log = revision
++ revision=revision.revision
++ out = options.display(revision)
++ if out is not None:
++ print out
++ if log is None and (options.summary or options.creator or
++ options.date or options.merges):
++ log = revision.patchlog
++ if options.creator:
++ print " %s" % log.creator
++ if options.date:
++ print " %s" % time.strftime('%Y-%m-%d %H:%M:%S %Z', log.date)
++ if options.summary:
++ print " %s" % log.summary
++ if options.merges:
++ showed_title = False
++ for revision in log.merged_patches:
++ if not showed_title:
++ print " Merged:"
++ showed_title = True
++ print " %s" % revision
++ if len(self.cl_revisions) > 0:
++ print pylon.changelog_for_merge(self.cl_revisions)
++ except pylon.errors.TreeRootNone:
++ raise CommandFailedWrapper(
++ Exception("This option can only be used in a project tree."))
++
++ def changelog_append(self, revision):
++ if isinstance(revision, arch.Revision):
++ revision=arch.Patchlog(revision)
++ self.cl_revisions.append(revision)
++
+ def get_parser(self):
+ """
+ Returns the options parser to use for the "revision" command.
+
+ :rtype: cmdutil.CmdOptionParser
+ """
+- parser=cmdutil.CmdOptionParser("fai revisions [revision]")
++ parser=cmdutil.CmdOptionParser("fai revisions [version/revision]")
+ select = cmdutil.OptionGroup(parser, "Selection options",
+ "Control which revisions are listed. These options"
+ " are mutually exclusive. If more than one is"
+ " specified, the last is used.")
+- select.add_option("", "--archive", action="store_const",
+- const="archive", dest="type", default="archive",
+- help="List all revisions in the archive")
+- select.add_option("", "--cacherevs", action="store_const",
+- const="cacherevs", dest="type",
+- help="List all revisions stored in the archive as "
+- "complete copies")
+- select.add_option("", "--logs", action="store_const",
+- const="logs", dest="type",
+- help="List revisions that have a patchlog in the "
+- "tree")
+- select.add_option("", "--missing", action="store_const",
+- const="missing", dest="type",
+- help="List revisions from the specified version that"
+- " have no patchlog in the tree")
+- select.add_option("", "--skip-present", action="store_const",
+- const="skip-present", dest="type",
+- help="List revisions from the specified version that"
+- " have no patchlogs at all in the tree")
+- select.add_option("", "--present", action="store_const",
+- const="present", dest="type",
+- help="List revisions from the specified version that"
+- " have no patchlog in the tree, but can't be merged")
+- select.add_option("", "--missing-from", action="store_const",
+- const="missing-from", dest="type",
+- help="List revisions from the specified revision "
+- "that have no patchlog for the tree version")
+- select.add_option("", "--partner-missing", action="store_const",
+- const="partner-missing", dest="type",
+- help="List revisions in partner versions that are"
+- " missing")
+- select.add_option("", "--new-merges", action="store_const",
+- const="new-merges", dest="type",
+- help="List revisions that have had patchlogs added"
+- " to the tree since the last commit")
+- select.add_option("", "--direct-merges", action="store_const",
+- const="direct-merges", dest="type",
+- help="List revisions that have been directly added"
+- " to tree since the last commit ")
+- select.add_option("", "--library", action="store_const",
+- const="library", dest="type",
+- help="List revisions in the revision library")
+- select.add_option("", "--ancestry", action="store_const",
+- const="ancestry", dest="type",
+- help="List revisions that are ancestors of the "
+- "current tree version")
+-
+- select.add_option("", "--dependencies", action="store_const",
+- const="dependencies", dest="type",
+- help="List revisions that the given revision "
+- "depends on")
+-
+- select.add_option("", "--non-dependencies", action="store_const",
+- const="non-dependencies", dest="type",
+- help="List revisions that the given revision "
+- "does not depend on")
+-
+- select.add_option("--micro", action="store_const",
+- const="micro", dest="type",
+- help="List partner revisions aimed for this "
+- "micro-branch")
+-
+- select.add_option("", "--modified", dest="modified",
+- help="List tree ancestor revisions that modified a "
+- "given file", metavar="FILE[:LINE]")
+
++ cmdutil.add_revision_iter_options(select)
+ parser.add_option("", "--skip", dest="skip",
+ help="Skip revisions. Positive numbers skip from "
+ "beginning, negative skip from end.",
+@@ -1312,6 +1174,9 @@
+ format.add_option("--cacherev", action="store_const",
+ const=paths.determine_cacherev_path, dest="display",
+ help="Show location of cacherev file")
++ format.add_option("--changelog", action="store_const",
++ const=self.changelog_append, dest="display",
++ help="Show location of cacherev file")
+ parser.add_option_group(format)
+ display = cmdutil.OptionGroup(parser, "Display format options",
+ "These control the display of data")
+@@ -1448,6 +1313,7 @@
+ if os.access(self.history_file, os.R_OK) and \
+ os.path.isfile(self.history_file):
+ readline.read_history_file(self.history_file)
++ self.cwd = os.getcwd()
+
+ def write_history(self):
+ readline.write_history_file(self.history_file)
+@@ -1470,16 +1336,21 @@
+ def set_prompt(self):
+ if self.tree is not None:
+ try:
+- version = " "+self.tree.tree_version.nonarch
++ prompt = pylon.alias_or_version(self.tree.tree_version,
++ self.tree,
++ full=False)
++ if prompt is not None:
++ prompt = " " + prompt
+ except:
+- version = ""
++ prompt = ""
+ else:
+- version = ""
+- self.prompt = "Fai%s> " % version
++ prompt = ""
++ self.prompt = "Fai%s> " % prompt
+
+ def set_title(self, command=None):
+ try:
+- version = self.tree.tree_version.nonarch
++ version = pylon.alias_or_version(self.tree.tree_version, self.tree,
++ full=False)
+ except:
+ version = "[no version]"
+ if command is None:
+@@ -1489,8 +1360,15 @@
+ def do_cd(self, line):
+ if line == "":
+ line = "~"
++ line = os.path.expanduser(line)
++ if os.path.isabs(line):
++ newcwd = line
++ else:
++ newcwd = self.cwd+'/'+line
++ newcwd = os.path.normpath(newcwd)
+ try:
+- os.chdir(os.path.expanduser(line))
++ os.chdir(newcwd)
++ self.cwd = newcwd
+ except Exception, e:
+ print e
+ try:
+@@ -1523,7 +1401,7 @@
+ except cmdutil.CantDetermineRevision, e:
+ print e
+ except Exception, e:
+- print "Unhandled error:\n%s" % cmdutil.exception_str(e)
++ print "Unhandled error:\n%s" % errors.exception_str(e)
+
+ elif suggestions.has_key(args[0]):
+ print suggestions[args[0]]
+@@ -1574,7 +1452,7 @@
+ arg = line.split()[-1]
+ else:
+ arg = ""
+- iter = iter_munged_completions(iter, arg, text)
++ iter = cmdutil.iter_munged_completions(iter, arg, text)
+ except Exception, e:
+ print e
+ return list(iter)
+@@ -1604,10 +1482,11 @@
+ else:
+ arg = ""
+ if arg.startswith("-"):
+- return list(iter_munged_completions(iter, arg, text))
++ return list(cmdutil.iter_munged_completions(iter, arg,
++ text))
+ else:
+- return list(iter_munged_completions(
+- iter_file_completions(arg), arg, text))
++ return list(cmdutil.iter_munged_completions(
++ cmdutil.iter_file_completions(arg), arg, text))
+
+
+ elif cmd == "cd":
+@@ -1615,13 +1494,13 @@
+ arg = args.split()[-1]
+ else:
+ arg = ""
+- iter = iter_dir_completions(arg)
+- iter = iter_munged_completions(iter, arg, text)
++ iter = cmdutil.iter_dir_completions(arg)
++ iter = cmdutil.iter_munged_completions(iter, arg, text)
+ return list(iter)
+ elif len(args)>0:
+ arg = args.split()[-1]
+- return list(iter_munged_completions(iter_file_completions(arg),
+- arg, text))
++ iter = cmdutil.iter_file_completions(arg)
++ return list(cmdutil.iter_munged_completions(iter, arg, text))
+ else:
+ return self.completenames(text, line, begidx, endidx)
+ except Exception, e:
+@@ -1636,44 +1515,8 @@
+ yield entry
+
+
+-def iter_file_completions(arg, only_dirs = False):
+- """Generate an iterator that iterates through filename completions.
+-
+- :param arg: The filename fragment to match
+- :type arg: str
+- :param only_dirs: If true, match only directories
+- :type only_dirs: bool
+- """
+- cwd = os.getcwd()
+- if cwd != "/":
+- extras = [".", ".."]
+- else:
+- extras = []
+- (dir, file) = os.path.split(arg)
+- if dir != "":
+- listingdir = os.path.expanduser(dir)
+- else:
+- listingdir = cwd
+- for file in cmdutil.iter_combine([os.listdir(listingdir), extras]):
+- if dir != "":
+- userfile = dir+'/'+file
+- else:
+- userfile = file
+- if userfile.startswith(arg):
+- if os.path.isdir(listingdir+'/'+file):
+- userfile+='/'
+- yield userfile
+- elif not only_dirs:
+- yield userfile
+-
+-def iter_munged_completions(iter, arg, text):
+- for completion in iter:
+- completion = str(completion)
+- if completion.startswith(arg):
+- yield completion[len(arg)-len(text):]
+-
+ def iter_source_file_completions(tree, arg):
+- treepath = cmdutil.tree_cwd(tree)
++ treepath = arch_compound.tree_cwd(tree)
+ if len(treepath) > 0:
+ dirs = [treepath]
+ else:
+@@ -1701,7 +1544,7 @@
+ :return: An iterator of all matching untagged files
+ :rtype: iterator of str
+ """
+- treepath = cmdutil.tree_cwd(tree)
++ treepath = arch_compound.tree_cwd(tree)
+ if len(treepath) > 0:
+ dirs = [treepath]
+ else:
+@@ -1743,8 +1586,8 @@
+ :param arg: The prefix to match
+ :type arg: str
+ """
+- treepath = cmdutil.tree_cwd(tree)
+- tmpdir = cmdutil.tmpdir()
++ treepath = arch_compound.tree_cwd(tree)
++ tmpdir = util.tmpdir()
+ changeset = tmpdir+"/changeset"
+ completions = []
+ revision = cmdutil.determine_revision_tree(tree)
+@@ -1756,14 +1599,6 @@
+ shutil.rmtree(tmpdir)
+ return completions
+
+-def iter_dir_completions(arg):
+- """Generate an iterator that iterates through directory name completions.
+-
+- :param arg: The directory name fragment to match
+- :type arg: str
+- """
+- return iter_file_completions(arg, True)
+-
+ class Shell(BaseCommand):
+ def __init__(self):
+ self.description = "Runs Fai as a shell"
+@@ -1795,7 +1630,11 @@
+ parser=self.get_parser()
+ (options, args) = parser.parse_args(cmdargs)
+
+- tree = arch.tree_root()
++ try:
++ tree = arch.tree_root()
++ except arch.errors.TreeRootError, e:
++ raise pylon.errors.CommandFailedWrapper(e)
++
+
+ if (len(args) == 0) == (options.untagged == False):
+ raise cmdutil.GetHelp
+@@ -1809,13 +1648,22 @@
+ if options.id_type == "tagline":
+ if method != "tagline":
+ if not cmdutil.prompt("Tagline in other tree"):
+- if method == "explicit":
+- options.id_type == explicit
++ if method == "explicit" or method == "implicit":
++ options.id_type == method
+ else:
+ print "add-id not supported for \"%s\" tagging method"\
+ % method
+ return
+
++ elif options.id_type == "implicit":
++ if method != "implicit":
++ if not cmdutil.prompt("Implicit in other tree"):
++ if method == "explicit" or method == "tagline":
++ options.id_type == method
++ else:
++ print "add-id not supported for \"%s\" tagging method"\
++ % method
++ return
+ elif options.id_type == "explicit":
+ if method != "tagline" and method != explicit:
+ if not prompt("Explicit in other tree"):
+@@ -1824,7 +1672,8 @@
+ return
+
+ if options.id_type == "auto":
+- if method != "tagline" and method != "explicit":
++ if method != "tagline" and method != "explicit" \
++ and method !="implicit":
+ print "add-id not supported for \"%s\" tagging method" % method
+ return
+ else:
+@@ -1852,10 +1701,12 @@
+ previous_files.extend(files)
+ if id_type == "explicit":
+ cmdutil.add_id(files)
+- elif id_type == "tagline":
++ elif id_type == "tagline" or id_type == "implicit":
+ for file in files:
+ try:
+- cmdutil.add_tagline_or_explicit_id(file)
++ implicit = (id_type == "implicit")
++ cmdutil.add_tagline_or_explicit_id(file, False,
++ implicit)
+ except cmdutil.AlreadyTagged:
+ print "\"%s\" already has a tagline." % file
+ except cmdutil.NoCommentSyntax:
+@@ -1888,6 +1739,9 @@
+ parser.add_option("--tagline", action="store_const",
+ const="tagline", dest="id_type",
+ help="Use a tagline id")
++ parser.add_option("--implicit", action="store_const",
++ const="implicit", dest="id_type",
++ help="Use an implicit id (deprecated)")
+ parser.add_option("--untagged", action="store_true",
+ dest="untagged", default=False,
+ help="tag all untagged files")
+@@ -1926,27 +1780,7 @@
+ def get_completer(self, arg, index):
+ if self.tree is None:
+ raise arch.errors.TreeRootError
+- completions = list(ancillary.iter_partners(self.tree,
+- self.tree.tree_version))
+- if len(completions) == 0:
+- completions = list(self.tree.iter_log_versions())
+-
+- aliases = []
+- try:
+- for completion in completions:
+- alias = ancillary.compact_alias(str(completion), self.tree)
+- if alias:
+- aliases.extend(alias)
+-
+- for completion in completions:
+- if completion.archive == self.tree.tree_version.archive:
+- aliases.append(completion.nonarch)
+-
+- except Exception, e:
+- print e
+-
+- completions.extend(aliases)
+- return completions
++ return cmdutil.merge_completions(self.tree, arg, index)
+
+ def do_command(self, cmdargs):
+ """
+@@ -1961,7 +1795,7 @@
+
+ if self.tree is None:
+ raise arch.errors.TreeRootError(os.getcwd())
+- if cmdutil.has_changed(self.tree.tree_version):
++ if cmdutil.has_changed(ancillary.comp_revision(self.tree)):
+ raise UncommittedChanges(self.tree)
+
+ if len(args) > 0:
+@@ -2027,14 +1861,14 @@
+ :type other_revision: `arch.Revision`
+ :return: 0 if the merge was skipped, 1 if it was applied
+ """
+- other_tree = cmdutil.find_or_make_local_revision(other_revision)
++ other_tree = arch_compound.find_or_make_local_revision(other_revision)
+ try:
+ if action == "native-merge":
+- ancestor = cmdutil.merge_ancestor2(self.tree, other_tree,
+- other_revision)
++ ancestor = arch_compound.merge_ancestor2(self.tree, other_tree,
++ other_revision)
+ elif action == "update":
+- ancestor = cmdutil.tree_latest(self.tree,
+- other_revision.version)
++ ancestor = arch_compound.tree_latest(self.tree,
++ other_revision.version)
+ except CantDetermineRevision, e:
+ raise CommandFailedWrapper(e)
+ cmdutil.colorize(arch.Chatter("* Found common ancestor %s" % ancestor))
+@@ -2104,7 +1938,10 @@
+ if self.tree is None:
+ raise arch.errors.TreeRootError
+
+- edit_log(self.tree)
++ try:
++ edit_log(self.tree, self.tree.tree_version)
++ except pylon.errors.NoEditorSpecified, e:
++ raise pylon.errors.CommandFailedWrapper(e)
+
+ def get_parser(self):
+ """
+@@ -2132,7 +1969,7 @@
+ """
+ return
+
+-def edit_log(tree):
++def edit_log(tree, version):
+ """Makes and edits the log for a tree. Does all kinds of fancy things
+ like log templates and merge summaries and log-for-merge
+
+@@ -2141,28 +1978,29 @@
+ """
+ #ensure we have an editor before preparing the log
+ cmdutil.find_editor()
+- log = tree.log_message(create=False)
++ log = tree.log_message(create=False, version=version)
+ log_is_new = False
+ if log is None or cmdutil.prompt("Overwrite log"):
+ if log is not None:
+ os.remove(log.name)
+- log = tree.log_message(create=True)
++ log = tree.log_message(create=True, version=version)
+ log_is_new = True
+ tmplog = log.name
+- template = tree+"/{arch}/=log-template"
+- if not os.path.exists(template):
+- template = os.path.expanduser("~/.arch-params/=log-template")
+- if not os.path.exists(template):
+- template = None
++ template = pylon.log_template_path(tree)
+ if template:
+ shutil.copyfile(template, tmplog)
+-
+- new_merges = list(cmdutil.iter_new_merges(tree,
+- tree.tree_version))
+- log["Summary"] = merge_summary(new_merges, tree.tree_version)
++ comp_version = ancillary.comp_revision(tree).version
++ new_merges = cmdutil.iter_new_merges(tree, comp_version)
++ new_merges = cmdutil.direct_merges(new_merges)
++ log["Summary"] = pylon.merge_summary(new_merges,
++ version)
+ if len(new_merges) > 0:
+ if cmdutil.prompt("Log for merge"):
+- mergestuff = cmdutil.log_for_merge(tree)
++ if cmdutil.prompt("changelog for merge"):
++ mergestuff = "Patches applied:\n"
++ mergestuff += pylon.changelog_for_merge(new_merges)
++ else:
++ mergestuff = cmdutil.log_for_merge(tree, comp_version)
+ log.description += mergestuff
+ log.save()
+ try:
+@@ -2172,29 +2010,6 @@
+ os.remove(log.name)
+ raise
+
+-def merge_summary(new_merges, tree_version):
+- if len(new_merges) == 0:
+- return ""
+- if len(new_merges) == 1:
+- summary = new_merges[0].summary
+- else:
+- summary = "Merge"
+-
+- credits = []
+- for merge in new_merges:
+- if arch.my_id() != merge.creator:
+- name = re.sub("<.*>", "", merge.creator).rstrip(" ");
+- if not name in credits:
+- credits.append(name)
+- else:
+- version = merge.revision.version
+- if version.archive == tree_version.archive:
+- if not version.nonarch in credits:
+- credits.append(version.nonarch)
+- elif not str(version) in credits:
+- credits.append(str(version))
+-
+- return ("%s (%s)") % (summary, ", ".join(credits))
+
+ class MirrorArchive(BaseCommand):
+ """
+@@ -2268,31 +2083,73 @@
+
+ Use "alias" to list available (user and automatic) aliases."""
+
++auto_alias = [
++"acur",
++"The latest revision in the archive of the tree-version. You can specify \
++a different version like so: acur:foo--bar--0 (aliases can be used)",
++"tcur",
++"""(tree current) The latest revision in the tree of the tree-version. \
++You can specify a different version like so: tcur:foo--bar--0 (aliases can be \
++used).""",
++"tprev" ,
++"""(tree previous) The previous revision in the tree of the tree-version. To \
++specify an older revision, use a number, e.g. "tprev:4" """,
++"tanc" ,
++"""(tree ancestor) The ancestor revision of the tree To specify an older \
++revision, use a number, e.g. "tanc:4".""",
++"tdate" ,
++"""(tree date) The latest revision from a given date, e.g. "tdate:July 6".""",
++"tmod" ,
++""" (tree modified) The latest revision to modify a given file, e.g. \
++"tmod:engine.cpp" or "tmod:engine.cpp:16".""",
++"ttag" ,
++"""(tree tag) The revision that was tagged into the current tree revision, \
++according to the tree""",
++"tagcur",
++"""(tag current) The latest revision of the version that the current tree \
++was tagged from.""",
++"mergeanc" ,
++"""The common ancestor of the current tree and the specified revision. \
++Defaults to the first partner-version's latest revision or to tagcur.""",
++]
++
++
++def is_auto_alias(name):
++ """Determine whether a name is an auto alias name
++
++ :param name: the name to check
++ :type name: str
++ :return: True if the name is an auto alias, false if not
++ :rtype: bool
++ """
++ return name in [f for (f, v) in pylon.util.iter_pairs(auto_alias)]
++
++
++def display_def(iter, wrap = 80):
++ """Display a list of definitions
++
++ :param iter: iter of name, definition pairs
++ :type iter: iter of (str, str)
++ :param wrap: The width for text wrapping
++ :type wrap: int
++ """
++ vals = list(iter)
++ maxlen = 0
++ for (key, value) in vals:
++ if len(key) > maxlen:
++ maxlen = len(key)
++ for (key, value) in vals:
++ tw=textwrap.TextWrapper(width=wrap,
++ initial_indent=key.rjust(maxlen)+" : ",
++ subsequent_indent="".rjust(maxlen+3))
++ print tw.fill(value)
++
++
+ def help_aliases(tree):
+- print """Auto-generated aliases
+- acur : The latest revision in the archive of the tree-version. You can specfy
+- a different version like so: acur:foo--bar--0 (aliases can be used)
+- tcur : (tree current) The latest revision in the tree of the tree-version.
+- You can specify a different version like so: tcur:foo--bar--0 (aliases
+- can be used).
+-tprev : (tree previous) The previous revision in the tree of the tree-version.
+- To specify an older revision, use a number, e.g. "tprev:4"
+- tanc : (tree ancestor) The ancestor revision of the tree
+- To specify an older revision, use a number, e.g. "tanc:4"
+-tdate : (tree date) The latest revision from a given date (e.g. "tdate:July 6")
+- tmod : (tree modified) The latest revision to modify a given file
+- (e.g. "tmod:engine.cpp" or "tmod:engine.cpp:16")
+- ttag : (tree tag) The revision that was tagged into the current tree revision,
+- according to the tree.
+-tagcur: (tag current) The latest revision of the version that the current tree
+- was tagged from.
+-mergeanc : The common ancestor of the current tree and the specified revision.
+- Defaults to the first partner-version's latest revision or to tagcur.
+- """
++ print """Auto-generated aliases"""
++ display_def(pylon.util.iter_pairs(auto_alias))
+ print "User aliases"
+- for parts in ancillary.iter_all_alias(tree):
+- print parts[0].rjust(10)+" : "+parts[1]
+-
++ display_def(ancillary.iter_all_alias(tree))
+
+ class Inventory(BaseCommand):
+ """List the status of files in the tree"""
+@@ -2428,6 +2285,11 @@
+ except cmdutil.ForbiddenAliasSyntax, e:
+ raise CommandFailedWrapper(e)
+
++ def no_prefix(self, alias):
++ if alias.startswith("^"):
++ alias = alias[1:]
++ return alias
++
+ def arg_dispatch(self, args, options):
+ """Add, modify, or list aliases, depending on number of arguments
+
+@@ -2438,15 +2300,20 @@
+ if len(args) == 0:
+ help_aliases(self.tree)
+ return
+- elif len(args) == 1:
+- self.print_alias(args[0])
+- elif (len(args)) == 2:
+- self.add(args[0], args[1], options)
+ else:
+- raise cmdutil.GetHelp
++ alias = self.no_prefix(args[0])
++ if len(args) == 1:
++ self.print_alias(alias)
++ elif (len(args)) == 2:
++ self.add(alias, args[1], options)
++ else:
++ raise cmdutil.GetHelp
+
+ def print_alias(self, alias):
+ answer = None
++ if is_auto_alias(alias):
++ raise pylon.errors.IsAutoAlias(alias, "\"%s\" is an auto alias."
++ " Use \"revision\" to expand auto aliases." % alias)
+ for pair in ancillary.iter_all_alias(self.tree):
+ if pair[0] == alias:
+ answer = pair[1]
+@@ -2464,6 +2331,8 @@
+ :type expansion: str
+ :param options: The commandline options
+ """
++ if is_auto_alias(alias):
++ raise IsAutoAlias(alias)
+ newlist = ""
+ written = False
+ new_line = "%s=%s\n" % (alias, cmdutil.expand_alias(expansion,
+@@ -2490,14 +2359,17 @@
+ deleted = False
+ if len(args) != 1:
+ raise cmdutil.GetHelp
++ alias = self.no_prefix(args[0])
++ if is_auto_alias(alias):
++ raise IsAutoAlias(alias)
+ newlist = ""
+ for pair in self.get_iterator(options):
+- if pair[0] != args[0]:
++ if pair[0] != alias:
+ newlist+="%s=%s\n" % (pair[0], pair[1])
+ else:
+ deleted = True
+ if not deleted:
+- raise errors.NoSuchAlias(args[0])
++ raise errors.NoSuchAlias(alias)
+ self.write_aliases(newlist, options)
+
+ def get_alias_file(self, options):
+@@ -2526,7 +2398,7 @@
+ :param options: The commandline options
+ """
+ filename = os.path.expanduser(self.get_alias_file(options))
+- file = cmdutil.NewFileVersion(filename)
++ file = util.NewFileVersion(filename)
+ file.write(newlist)
+ file.commit()
+
+@@ -2588,10 +2460,13 @@
+ :param cmdargs: The commandline arguments
+ :type cmdargs: list of str
+ """
+- cmdutil.find_editor()
+ parser = self.get_parser()
+ (options, args) = parser.parse_args(cmdargs)
+ try:
++ cmdutil.find_editor()
++ except pylon.errors.NoEditorSpecified, e:
++ raise pylon.errors.CommandFailedWrapper(e)
++ try:
+ self.tree=arch.tree_root()
+ except:
+ self.tree=None
+@@ -2655,7 +2530,7 @@
+ target_revision = cmdutil.determine_revision_arch(self.tree,
+ args[0])
+ else:
+- target_revision = cmdutil.tree_latest(self.tree)
++ target_revision = arch_compound.tree_latest(self.tree)
+ if len(args) > 1:
+ merges = [ arch.Patchlog(cmdutil.determine_revision_arch(
+ self.tree, f)) for f in args[1:] ]
+@@ -2711,7 +2586,7 @@
+
+ :param message: The message to send
+ :type message: `email.Message`"""
+- server = smtplib.SMTP()
++ server = smtplib.SMTP("localhost")
+ server.sendmail(message['From'], message['To'], message.as_string())
+ server.quit()
+
+@@ -2763,6 +2638,22 @@
+ 'alias' : Alias,
+ 'request-merge': RequestMerge,
+ }
++
++def my_import(mod_name):
++ module = __import__(mod_name)
++ components = mod_name.split('.')
++ for comp in components[1:]:
++ module = getattr(module, comp)
++ return module
++
++def plugin(mod_name):
++ module = my_import(mod_name)
++ module.add_command(commands)
++
++for file in os.listdir(sys.path[0]+"/command"):
++ if len(file) > 3 and file[-3:] == ".py" and file != "__init__.py":
++ plugin("command."+file[:-3])
++
+ suggestions = {
+ 'apply-delta' : "Try \"apply-changes\".",
+ 'delta' : "To compare two revisions, use \"changes\".",
+@@ -2784,6 +2675,7 @@
+ 'tagline' : "Use add-id. It uses taglines in tagline trees",
+ 'emlog' : "Use elog. It automatically adds log-for-merge text, if any",
+ 'library-revisions' : "Use revisions --library",
+-'file-revert' : "Use revert FILE"
++'file-revert' : "Use revert FILE",
++'join-branch' : "Use replay --logs-only"
+ }
+ # arch-tag: 19d5739d-3708-486c-93ba-deecc3027fc7