author | Thomas Arendsen Hein <thomas@intevation.de> |
Sat, 30 Sep 2006 09:46:03 +0200 | |
changeset 3203 | 14792adabf80 |
parent 3195 | f8e67b7c57a4 (diff) |
parent 3202 | 9e002614f2eb (current diff) |
child 3204 | a7377a238cec |
--- a/hgext/hgk.py +++ b/hgext/hgk.py @@ -279,8 +279,10 @@ def revlist(ui, repo, *revs, **opts): def view(ui, repo, *etc, **opts): "start interactive history viewer" os.chdir(repo.root) - optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems()]) - os.system(ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc))) + optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v]) + cmd = ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc)) + ui.debug("running %s\n" % cmd) + os.system(cmd) cmdtable = { "view": (view,
--- a/hgext/mq.py +++ b/hgext/mq.py @@ -114,6 +114,9 @@ class queue: comment = l[h:] patch = patch.strip() if patch: + if patch in self.series: + raise util.Abort(_('%s appears more than once in %s') % + (patch, self.join(self.series_path))) self.series.append(patch) self.series_guards.append(self.guard_re.findall(comment)) @@ -800,11 +803,9 @@ class queue: wlock = repo.wlock() patch = self.lookup(patch) if patch and self.isapplied(patch): - self.ui.warn(_("patch %s is already applied\n") % patch) - sys.exit(1) + raise util.Abort(_("patch %s is already applied") % patch) if self.series_end() == len(self.series): - self.ui.warn(_("patch series fully applied\n")) - sys.exit(1) + raise util.Abort(_("patch series fully applied")) if not force: self.check_localchanges(repo) @@ -854,8 +855,7 @@ class queue: if not info: raise util.Abort(_("patch %s is not applied") % patch) if len(self.applied) == 0: - self.ui.warn(_("no patches applied\n")) - sys.exit(1) + raise util.Abort(_("no patches applied")) if not update: parents = repo.dirstate.parents() @@ -1071,25 +1071,38 @@ class queue: self.explain_pushable(i) return unapplied - def qseries(self, repo, missing=None, summary=False): - start = self.series_end(all_patches=True) + def qseries(self, repo, missing=None, start=0, length=0, status=None, + summary=False): + def displayname(patchname): + if summary: + msg = self.readheaders(patchname)[0] + msg = msg and ': ' + msg[0] or ': ' + else: + msg = '' + return '%s%s' % (patchname, msg) + + def pname(i): + if status == 'A': + return self.applied[i].name + else: + return self.series[i] + + unapplied = self.series_end(all_patches=True) + if not length: + length = len(self.series) - start if not missing: - for i in range(len(self.series)): - patch = self.series[i] + for i in range(start, start+length): + pfx = '' + patch = pname(i) if self.ui.verbose: - if i < start: + if i < unapplied: status = 'A' elif self.pushable(i)[0]: status = 'U' else: status = 'G' - self.ui.write('%d %s ' % (i, status)) - if summary: - msg = self.readheaders(patch)[0] - msg = msg and ': ' + msg[0] or ': ' - else: - msg = '' - self.ui.write('%s%s\n' % (patch, msg)) + pfx = '%d %s ' % (i, status) + self.ui.write('%s%s\n' % (pfx, displayname(patch))) else: msng_list = [] for root, dirs, files in os.walk(self.path): @@ -1102,9 +1115,8 @@ class queue: msng_list.append(fl) msng_list.sort() for x in msng_list: - if self.ui.verbose: - self.ui.write("D ") - self.ui.write("%s\n" % x) + pfx = self.ui.verbose and ('D ') or '' + self.ui.write("%s%s\n" % (pfx, displayname(x))) def issaveline(self, l): if l.name == '.hg.patches.save.line': @@ -1136,7 +1148,8 @@ class queue: file_ = se.name if se.rev: applied.append(se) - series.append(file_) + else: + series.append(file_) if datastart == None: self.ui.warn("No saved patch data found\n") return 1 @@ -1227,17 +1240,6 @@ class queue: return next(end + 1) return next(end) - def qapplied(self, repo, patch=None): - if patch and patch not in self.series: - raise util.Abort(_("patch %s is not in series file") % patch) - if not patch: - end = len(self.applied) - else: - end = self.series.index(patch) + 1 - for x in xrange(end): - p = self.appliedname(x) - self.ui.write("%s\n" % p) - def appliedname(self, index): pname = self.applied[index].name if not self.ui.verbose: @@ -1246,36 +1248,6 @@ class queue: p = str(self.series.index(pname)) + " " + pname return p - def top(self, repo): - if len(self.applied): - p = self.appliedname(-1) - self.ui.write(p + '\n') - else: - self.ui.write("No patches applied\n") - return 1 - - def next(self, repo): - end = self.series_end() - if end == len(self.series): - self.ui.write("All patches applied\n") - return 1 - else: - p = self.series[end] - if self.ui.verbose: - self.ui.write("%d " % self.series.index(p)) - self.ui.write(p + '\n') - - def prev(self, repo): - if len(self.applied) > 1: - p = self.appliedname(-2) - self.ui.write(p + '\n') - elif len(self.applied) == 1: - self.ui.write("Only one patch applied\n") - return 1 - else: - self.ui.write("No patches applied\n") - return 1 - def qimport(self, repo, files, patchname=None, rev=None, existing=None, force=None): def checkseries(patchname): @@ -1396,15 +1368,28 @@ def delete(ui, repo, patch, *patches, ** def applied(ui, repo, patch=None, **opts): """print the patches already applied""" - repo.mq.qapplied(repo, patch) - return 0 + q = repo.mq + if patch: + if patch not in q.series: + raise util.Abort(_("patch %s is not in series file") % patch) + end = q.series.index(patch) + 1 + else: + end = len(q.applied) + if not end: + return + + return q.qseries(repo, length=end, status='A', summary=opts.get('summary')) def unapplied(ui, repo, patch=None, **opts): """print the patches not yet applied""" - for i, p in repo.mq.unapplied(repo, patch): - if ui.verbose: - ui.write("%d " % i) - ui.write("%s\n" % p) + q = repo.mq + if patch: + if patch not in q.series: + raise util.Abort(_("patch %s is not in series file") % patch) + start = q.series.index(patch) + 1 + else: + start = q.series_end() + q.qseries(repo, start=start, summary=opts.get('summary')) def qimport(ui, repo, *filename, **opts): """import a patch @@ -1503,15 +1488,36 @@ def series(ui, repo, **opts): def top(ui, repo, **opts): """print the name of the current patch""" - return repo.mq.top(repo) + q = repo.mq + t = len(q.applied) + if t: + return q.qseries(repo, start=t-1, length=1, status='A', + summary=opts.get('summary')) + else: + ui.write("No patches applied\n") + return 1 def next(ui, repo, **opts): """print the name of the next patch""" - return repo.mq.next(repo) + q = repo.mq + end = q.series_end() + if end == len(q.series): + ui.write("All patches applied\n") + return 1 + return q.qseries(repo, start=end, length=1, summary=opts.get('summary')) def prev(ui, repo, **opts): """print the name of the previous patch""" - return repo.mq.prev(repo) + q = repo.mq + l = len(q.applied) + if l == 1: + ui.write("Only one patch applied\n") + return 1 + if not l: + ui.write("No patches applied\n") + return 1 + return q.qseries(repo, start=l-2, length=1, status='A', + summary=opts.get('summary')) def new(ui, repo, patch, **opts): """create a new patch @@ -1988,8 +1994,10 @@ def reposetup(ui, repo): repo.__class__ = mqrepo repo.mq = queue(ui, repo.join("")) +seriesopts = [('s', 'summary', None, _('print first line of patch header'))] + cmdtable = { - "qapplied": (applied, [], 'hg qapplied [PATCH]'), + "qapplied": (applied, [] + seriesopts, 'hg qapplied [-s] [PATCH]'), "qclone": (clone, [('', 'pull', None, _('use pull protocol to copy metadata')), ('U', 'noupdate', None, _('do not update the new working directories')), @@ -2043,8 +2051,8 @@ cmdtable = { ('l', 'logfile', '', _('read the commit message from <file>')), ('f', 'force', None, _('import uncommitted changes into patch'))], 'hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH'), - "qnext": (next, [], 'hg qnext'), - "qprev": (prev, [], 'hg qprev'), + "qnext": (next, [] + seriesopts, 'hg qnext [-s]'), + "qprev": (prev, [] + seriesopts, 'hg qprev [-s]'), "^qpop": (pop, [('a', 'all', None, 'pop all patches'), @@ -2094,8 +2102,7 @@ cmdtable = { 'hg qselect [OPTION...] [GUARD...]'), "qseries": (series, - [('m', 'missing', None, 'print patches not in series'), - ('s', 'summary', None, _('print first line of patch header'))], + [('m', 'missing', None, 'print patches not in series')] + seriesopts, 'hg qseries [-ms]'), "^strip": (strip, @@ -2103,6 +2110,6 @@ cmdtable = { ('b', 'backup', None, 'bundle unrelated changesets'), ('n', 'nobackup', None, 'no backups')], 'hg strip [-f] [-b] [-n] REV'), - "qtop": (top, [], 'hg qtop'), - "qunapplied": (unapplied, [], 'hg qunapplied [PATCH]'), + "qtop": (top, [] + seriesopts, 'hg qtop [-s]'), + "qunapplied": (unapplied, [] + seriesopts, 'hg qunapplied [-s] [PATCH]'), }
--- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -312,7 +312,7 @@ class changeset_printer(object): self.ui = ui self.repo = repo - def show(self, rev=0, changenode=None, brinfo=None): + def show(self, rev=0, changenode=None, brinfo=None, copies=None): '''show a single changeset or file revision''' log = self.repo.changelog if changenode is None: @@ -359,6 +359,9 @@ class changeset_printer(object): self.ui.note("%-12s %s\n" % (key, " ".join(value))) else: self.ui.note(_("files: %s\n") % " ".join(changes[3])) + if copies: + copies = ['%s (%s)' % c for c in copies] + self.ui.note(_("copies: %s\n") % ' '.join(copies)) description = changes[4].strip() if description: @@ -372,21 +375,36 @@ class changeset_printer(object): self.ui.status("\n") def show_changeset(ui, repo, opts): - '''show one changeset. uses template or regular display. caller - can pass in 'style' and 'template' options in opts.''' - + """show one changeset using template or regular display. + + Display format will be the first non-empty hit of: + 1. option 'template' + 2. option 'style' + 3. [ui] setting 'logtemplate' + 4. [ui] setting 'style' + If all of these values are either the unset or the empty string, + regular display via changeset_printer() is done. + """ + # options tmpl = opts.get('template') + mapfile = None if tmpl: tmpl = templater.parsestring(tmpl, quoted=False) else: - tmpl = ui.config('ui', 'logtemplate') - if tmpl: tmpl = templater.parsestring(tmpl) - mapfile = opts.get('style') or ui.config('ui', 'style') + mapfile = opts.get('style') + # ui settings + if not mapfile: + tmpl = ui.config('ui', 'logtemplate') + if tmpl: + tmpl = templater.parsestring(tmpl) + else: + mapfile = ui.config('ui', 'style') + if tmpl or mapfile: if mapfile: - if not os.path.isfile(mapfile): - mapname = templater.templatepath('map-cmdline.' + mapfile) - if not mapname: mapname = templater.templatepath(mapfile) + if not os.path.split(mapfile)[0]: + mapname = (templater.templatepath('map-cmdline.' + mapfile) + or templater.templatepath(mapfile)) if mapname: mapfile = mapname try: t = templater.changeset_templater(ui, repo, mapfile) @@ -574,7 +592,7 @@ def add(ui, repo, *pats, **opts): repo.add(names) def addremove(ui, repo, *pats, **opts): - """add all new files, delete all missing files (DEPRECATED) + """add all new files, delete all missing files Add all new files and remove all missing files from the repository. @@ -612,8 +630,9 @@ def annotate(ui, repo, *pats, **opts): opmap = [['user', lambda x: ui.shortuser(x.user())], ['number', lambda x: str(x.rev())], ['changeset', lambda x: short(x.node())], - ['date', getdate]] - if not opts['user'] and not opts['changeset'] and not opts['date']: + ['date', getdate], ['follow', lambda x: x.path()]] + if (not opts['user'] and not opts['changeset'] and not opts['date'] + and not opts['follow']): opts['number'] = 1 ctx = repo.changectx(opts['rev']) @@ -625,7 +644,7 @@ def annotate(ui, repo, *pats, **opts): ui.write(_("%s: binary file\n") % ((pats and rel) or abs)) continue - lines = fctx.annotate() + lines = fctx.annotate(follow=opts.get('follow')) pieces = [] for o, f in opmap: @@ -760,6 +779,7 @@ def bundle(ui, repo, fname, dest=None, * contents including permissions, rename data, and revision history. """ dest = ui.expandpath(dest or 'default-push', dest or 'default') + setremoteconfig(ui, opts) other = hg.repository(ui, dest) o = repo.findoutgoing(other, force=opts['force']) cg = repo.changegroup(o, 'bundle') @@ -1757,6 +1777,40 @@ def log(ui, repo, *pats, **opts): limit = sys.maxint count = 0 + if opts['copies'] and opts['rev']: + endrev = max([int(i) + for i in cmdutil.revrange(ui, repo, opts['rev'])]) + 1 + else: + endrev = repo.changelog.count() + rcache = {} + ncache = {} + dcache = [] + def getrenamed(fn, rev, man): + '''looks up all renames for a file (up to endrev) the first + time the file is given. It indexes on the changerev and only + parses the manifest if linkrev != changerev. + Returns rename info for fn at changerev rev.''' + if fn not in rcache: + rcache[fn] = {} + ncache[fn] = {} + fl = repo.file(fn) + for i in xrange(fl.count()): + node = fl.node(i) + lr = fl.linkrev(node) + renamed = fl.renamed(node) + rcache[fn][lr] = renamed + if renamed: + ncache[fn][node] = renamed + if lr >= endrev: + break + if rev in rcache[fn]: + return rcache[fn][rev] + if not dcache or dcache[0] != man: + dcache[:] = [man, repo.manifest.readdelta(man)] + if fn in dcache[1]: + return ncache[fn].get(dcache[1][fn]) + return None + displayer = show_changeset(ui, repo, opts) for st, rev, fns in changeiter: if st == 'window': @@ -1788,7 +1842,14 @@ def log(ui, repo, *pats, **opts): if opts['branches']: br = repo.branchlookup([repo.changelog.node(rev)]) - displayer.show(rev, brinfo=br) + copies = [] + if opts.get('copies') and rev: + mf = getchange(rev)[0] + for fn in getchange(rev)[3]: + rename = getrenamed(fn, rev, mf) + if rename: + copies.append((fn, rename[0])) + displayer.show(rev, brinfo=br, copies=copies) if opts['patch']: prev = (parents and parents[0]) or nullid patch.diff(repo, prev, changenode, match=matchfn, fp=du) @@ -2652,32 +2713,60 @@ def verify(ui, repo): # Command options and aliases are listed here, alphabetically +globalopts = [ + ('R', 'repository', '', + _('repository root directory or symbolic path name')), + ('', 'cwd', '', _('change working directory')), + ('y', 'noninteractive', None, + _('do not prompt, assume \'yes\' for any required answers')), + ('q', 'quiet', None, _('suppress output')), + ('v', 'verbose', None, _('enable additional output')), + ('', 'config', [], _('set/override config option')), + ('', 'debug', None, _('enable debugging output')), + ('', 'debugger', None, _('start debugger')), + ('', 'lsprof', None, _('print improved command execution profile')), + ('', 'traceback', None, _('print traceback on exception')), + ('', 'time', None, _('time how long the command takes')), + ('', 'profile', None, _('print command execution profile')), + ('', 'version', None, _('output version information and exit')), + ('h', 'help', None, _('display help and exit')), +] + +dryrunopts = [('n', 'dry-run', None, + _('do not perform actions, just print output'))] + +remoteopts = [ + ('e', 'ssh', '', _('specify ssh command to use')), + ('', 'remotecmd', '', _('specify hg command to run on the remote side')), +] + +walkopts = [ + ('I', 'include', [], _('include names matching the given patterns')), + ('X', 'exclude', [], _('exclude names matching the given patterns')), +] + table = { "^add": (add, - [('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns')), - ('n', 'dry-run', None, _('do not perform actions, just print output'))], + walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')), "addremove": (addremove, - [('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns')), - ('n', 'dry-run', None, - _('do not perform actions, just print output')), - ('s', 'similarity', '', - _('guess renamed files by similarity (0<=s<=1)'))], + walkopts + dryrunopts + + [('s', 'similarity', '', + _('guess renamed files by similarity (0<=s<=100)')), + ] + walkopts + dryrunopts, _('hg addremove [OPTION]... [FILE]...')), "^annotate": (annotate, [('r', 'rev', '', _('annotate the specified revision')), + ('f', 'follow', None, _('follow file copies and renames')), ('a', 'text', None, _('treat all files as text')), ('u', 'user', None, _('list the author')), ('d', 'date', None, _('list the date')), ('n', 'number', None, _('list the revision number (default)')), ('c', 'changeset', None, _('list the changeset')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg annotate [-r REV] [-a] [-u] [-d] [-n] [-c] FILE...')), "archive": (archive, @@ -2685,8 +2774,7 @@ table = { ('p', 'prefix', '', _('directory prefix for files in archive')), ('r', 'rev', '', _('revision to distribute')), ('t', 'type', '', _('type of distribution to create')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg archive [OPTION]... DEST')), "backout": (backout, @@ -2697,20 +2785,19 @@ table = { ('d', 'date', '', _('record datecode as commit date')), ('', 'parent', '', _('parent to choose when backing out merge')), ('u', 'user', '', _('record user as committer')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg backout [OPTION]... REV')), "bundle": (bundle, [('f', 'force', None, - _('run even when remote repository is unrelated'))], + _('run even when remote repository is unrelated')), + ] + remoteopts, _('hg bundle FILE DEST')), "cat": (cat, [('o', 'output', '', _('print output to file with formatted name')), ('r', 'rev', '', _('print the given revision')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg cat [OPTION]... FILE...')), "^clone": (clone, @@ -2720,9 +2807,7 @@ table = { ('', 'pull', None, _('use pull protocol to copy metadata')), ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')), - ('e', 'ssh', '', _('specify ssh command to use')), - ('', 'remotecmd', '', - _('specify hg command to run on the remote side'))], + ] + remoteopts, _('hg clone [OPTION]... SOURCE [DEST]')), "^commit|ci": (commit, @@ -2732,17 +2817,14 @@ table = { ('l', 'logfile', '', _('read the commit message from <file>')), ('d', 'date', '', _('record datecode as commit date')), ('u', 'user', '', _('record user as commiter')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg commit [OPTION]... [FILE]...')), "copy|cp": (copy, [('A', 'after', None, _('record a copy that has already occurred')), ('f', 'force', None, _('forcibly copy over an existing managed file')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns')), - ('n', 'dry-run', None, _('do not perform actions, just print output'))], + ] + walkopts + dryrunopts, _('hg copy [OPTION]... [SOURCE]... DEST')), "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')), "debugcomplete": @@ -2762,10 +2844,7 @@ table = { "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')), "debugrename": (debugrename, [], _('debugrename FILE [REV]')), "debugwalk": - (debugwalk, - [('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], - _('debugwalk [OPTION]... [FILE]...')), + (debugwalk, walkopts, _('debugwalk [OPTION]... [FILE]...')), "^diff": (diff, [('r', 'rev', [], _('revision')), @@ -2773,27 +2852,25 @@ table = { ('p', 'show-function', None, _('show which function each change is in')), ('g', 'git', None, _('use git extended diff format')), + ('', 'nodates', None, _("don't include dates in diff headers")), ('w', 'ignore-all-space', None, _('ignore white space when comparing lines')), ('b', 'ignore-space-change', None, _('ignore changes in the amount of white space')), ('B', 'ignore-blank-lines', None, _('ignore changes whose lines are all blank')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')), "^export": (export, [('o', 'output', '', _('print output to file with formatted name')), ('a', 'text', None, _('treat all files as text')), ('g', 'git', None, _('use git extended diff format')), + ('', 'nodates', None, _("don't include dates in diff headers")), ('', 'switch-parent', None, _('diff against the second parent'))], _('hg export [-a] [-o OUTFILESPEC] REV...')), "debugforget|forget": - (forget, - [('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], - _('hg forget [OPTION]... FILE...')), + (forget, walkopts, _('hg forget [OPTION]... FILE...')), "grep": (grep, [('0', 'print0', None, _('end fields with NUL')), @@ -2806,8 +2883,7 @@ table = { ('n', 'line-number', None, _('print matching line numbers')), ('r', 'rev', [], _('search in given revision range')), ('u', 'user', None, _('print user who committed change')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg grep [OPTION]... PATTERN [FILE]...')), "heads": (heads, @@ -2838,17 +2914,11 @@ table = { ('p', 'patch', None, _('show patch')), ('r', 'rev', [], _('a specific revision up to which you would like to pull')), ('', 'template', '', _('display with template')), - ('e', 'ssh', '', _('specify ssh command to use')), - ('', 'remotecmd', '', - _('specify hg command to run on the remote side'))], + ] + remoteopts, _('hg incoming [-p] [-n] [-M] [-r REV]...' ' [--bundle FILENAME] [SOURCE]')), "^init": - (init, - [('e', 'ssh', '', _('specify ssh command to use')), - ('', 'remotecmd', '', - _('specify hg command to run on the remote side'))], - _('hg init [-e FILE] [--remotecmd FILE] [DEST]')), + (init, remoteopts, _('hg init [-e FILE] [--remotecmd FILE] [DEST]')), "locate": (locate, [('r', 'rev', '', _('search the repository as it stood at rev')), @@ -2856,8 +2926,7 @@ table = { _('end filenames with NUL, for use with xargs')), ('f', 'fullpath', None, _('print complete paths from the filesystem root')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg locate [OPTION]... [PATTERN]...')), "^log|history": (log, @@ -2866,6 +2935,7 @@ table = { _('follow changeset history, or file history across copies and renames')), ('', 'follow-first', None, _('only follow the first parent of merge changesets')), + ('C', 'copies', None, _('show copied files')), ('k', 'keyword', [], _('search for a keyword')), ('l', 'limit', '', _('limit number of changes displayed')), ('r', 'rev', [], _('show the specified revision or range')), @@ -2875,8 +2945,7 @@ table = { ('p', 'patch', None, _('show patch')), ('P', 'prune', [], _('do not display revision or any of its ancestors')), ('', 'template', '', _('display with template')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg log [OPTION]... [FILE]')), "manifest": (manifest, [], _('hg manifest [REV]')), "merge": @@ -2893,9 +2962,7 @@ table = { ('r', 'rev', [], _('a specific revision you would like to push')), ('n', 'newest-first', None, _('show newest record first')), ('', 'template', '', _('display with template')), - ('e', 'ssh', '', _('specify ssh command to use')), - ('', 'remotecmd', '', - _('specify hg command to run on the remote side'))], + ] + remoteopts, _('hg outgoing [-M] [-p] [-n] [-r REV]... [DEST]')), "^parents": (parents, @@ -2908,21 +2975,17 @@ table = { "^pull": (pull, [('u', 'update', None, - _('update the working directory to tip after pull')), - ('e', 'ssh', '', _('specify ssh command to use')), + _('update to new tip if changesets were pulled')), ('f', 'force', None, _('run even when remote repository is unrelated')), ('r', 'rev', [], _('a specific revision up to which you would like to pull')), - ('', 'remotecmd', '', - _('specify hg command to run on the remote side'))], + ] + remoteopts, _('hg pull [-u] [-r REV]... [-e FILE] [--remotecmd FILE] [SOURCE]')), "^push": (push, [('f', 'force', None, _('force push')), - ('e', 'ssh', '', _('specify ssh command to use')), ('r', 'rev', [], _('a specific revision you would like to push')), - ('', 'remotecmd', '', - _('specify hg command to run on the remote side'))], + ] + remoteopts, _('hg push [-f] [-r REV]... [-e FILE] [--remotecmd FILE] [DEST]')), "debugrawcommit|rawcommit": (rawcommit, @@ -2938,26 +3001,21 @@ table = { (remove, [('A', 'after', None, _('record remove that has already occurred')), ('f', 'force', None, _('remove file even if modified')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg remove [OPTION]... FILE...')), "rename|mv": (rename, [('A', 'after', None, _('record a rename that has already occurred')), ('f', 'force', None, _('forcibly copy over an existing managed file')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns')), - ('n', 'dry-run', None, _('do not perform actions, just print output'))], + ] + walkopts + dryrunopts, _('hg rename [OPTION]... SOURCE... DEST')), "^revert": (revert, [('a', 'all', None, _('revert all changes when no arguments given')), ('r', 'rev', '', _('revision to revert to')), ('', 'no-backup', None, _('do not save backup copies of files')), - ('I', 'include', [], _('include names matching given patterns')), - ('X', 'exclude', [], _('exclude names matching given patterns')), - ('n', 'dry-run', None, _('do not perform actions, just print output'))], + ] + walkopts + dryrunopts, _('hg revert [-r REV] [NAME]...')), "rollback": (rollback, [], _('hg rollback')), "root": (root, [], _('hg root')), @@ -2993,8 +3051,7 @@ table = { ('C', 'copies', None, _('show source of copied files')), ('0', 'print0', None, _('end filenames with NUL, for use with xargs')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], + ] + walkopts, _('hg status [OPTION]... [FILE]...')), "tag": (tag, @@ -3015,7 +3072,7 @@ table = { "unbundle": (unbundle, [('u', 'update', None, - _('update the working directory to tip after unbundle'))], + _('update to new tip if changesets were unbundled'))], _('hg unbundle [-u] FILE')), "debugundo|undo": (undo, [], _('hg undo')), "^update|up|checkout|co": @@ -3029,25 +3086,6 @@ table = { "version": (show_version, [], _('hg version')), } -globalopts = [ - ('R', 'repository', '', - _('repository root directory or symbolic path name')), - ('', 'cwd', '', _('change working directory')), - ('y', 'noninteractive', None, - _('do not prompt, assume \'yes\' for any required answers')), - ('q', 'quiet', None, _('suppress output')), - ('v', 'verbose', None, _('enable additional output')), - ('', 'config', [], _('set/override config option')), - ('', 'debug', None, _('enable debugging output')), - ('', 'debugger', None, _('start debugger')), - ('', 'lsprof', None, _('print improved command execution profile')), - ('', 'traceback', None, _('print traceback on exception')), - ('', 'time', None, _('time how long the command takes')), - ('', 'profile', None, _('print command execution profile')), - ('', 'version', None, _('output version information and exit')), - ('h', 'help', None, _('display help and exit')), -] - norepo = ("clone init version help debugancestor debugcomplete debugdata" " debugindex debugindexdot") optionalrepo = ("paths serve debugconfig")
--- a/mercurial/context.py +++ b/mercurial/context.py @@ -5,6 +5,10 @@ # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. +from demandload import * +from node import * +demandload(globals(), 'bdiff') + from node import * from demandload import demandload demandload(globals(), "ancestor util") @@ -183,13 +187,74 @@ class filectx(object): return [ filectx(self._repo, self._path, fileid=x, filelog=self._filelog) for x in c ] - def annotate(self): - getctx = util.cachefunc(lambda x: filectx(self._repo, self._path, - changeid=x, - filelog=self._filelog)) - hist = self._filelog.annotate(self._filenode) + def annotate(self, follow=False): + '''returns a list of tuples of (ctx, line) for each line + in the file, where ctx is the filectx of the node where + that line was last changed''' + + def decorate(text, rev): + return ([rev] * len(text.splitlines()), text) + + def pair(parent, child): + for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]): + child[0][b1:b2] = parent[0][a1:a2] + return child + + getlog = util.cachefunc(lambda x: self._repo.file(x)) + def getctx(path, fileid): + log = path == self._path and self._filelog or getlog(path) + return filectx(self._repo, path, fileid=fileid, filelog=log) + getctx = util.cachefunc(getctx) + + def parents(f): + # we want to reuse filectx objects as much as possible + p = f._path + pl = [ (p, f._filelog.rev(n)) for n in f._filelog.parents(f._filenode) ] + + if follow: + r = f.renamed() + if r: + pl[0] = (r[0], getlog(r[0]).rev(r[1])) - return [(getctx(rev), line) for rev, line in hist] + return [ getctx(p, n) for p, n in pl if n != -1 ] + + # find all ancestors + needed = {self: 1} + visit = [self] + files = [self._path] + while visit: + f = visit.pop(0) + for p in parents(f): + if p not in needed: + needed[p] = 1 + visit.append(p) + if p._path not in files: + files.append(p._path) + else: + # count how many times we'll use this + needed[p] += 1 + + # sort by revision (per file) which is a topological order + visit = [] + files.reverse() + for f in files: + fn = [(n._filerev, n) for n in needed.keys() if n._path == f] + fn.sort() + visit.extend(fn) + hist = {} + + for r, f in visit: + curr = decorate(f.data(), f) + for p in parents(f): + if p != nullid: + curr = pair(hist[p], curr) + # trim the history of unneeded revs + needed[p] -= 1 + if not needed[p]: + del hist[p] + hist[f] = curr + + return zip(hist[f][0], hist[f][1].splitlines(1)) def ancestor(self, fc2): """
--- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -14,7 +14,7 @@ demandload(globals(), "localrepo bundler demandload(globals(), "errno lock os shutil util merge@_merge verify@_verify") def _local(path): - return (os.path.isfile(path and util.drop_scheme('file', path)) and + return (os.path.isfile(util.drop_scheme('file', path)) and bundlerepo or localrepo) schemes = { @@ -51,7 +51,7 @@ def islocal(repo): repo_setup_hooks = [] -def repository(ui, path=None, create=False): +def repository(ui, path='', create=False): """return a repository object for the specified path""" repo = _lookup(path).instance(ui, path, create) for hook in repo_setup_hooks:
--- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -292,9 +292,12 @@ class hgweb(object): files = [] mf = self.repo.manifest.read(changes[0]) + parity = 0 for f in changes[3]: files.append(self.t("filenodelink", - filenode=hex(mf.get(f, nullid)), file=f)) + filenode=hex(mf.get(f, nullid)), file=f, + parity=parity)) + parity = 1 - parity def diff(**map): yield self.diff(p1, n, None) @@ -391,42 +394,27 @@ class hgweb(object): permissions=self.repo.manifest.read(mfn).execf(f)) def fileannotate(self, f, node): - bcache = {} - ncache = {} - fl = self.repo.file(f) - n = fl.lookup(node) - node = hex(n) - changerev = fl.linkrev(n) - - cl = self.repo.changelog - cn = cl.node(changerev) - cs = cl.read(cn) - mfn = cs[0] + fctx = self.repo.filectx(f, fileid=node) + n = fctx.filenode() + fl = fctx.filelog() def annotate(**map): parity = 0 last = None - for r, l in fl.annotate(n): - try: - cnode = ncache[r] - except KeyError: - cnode = ncache[r] = self.repo.changelog.node(r) + for f, l in fctx.annotate(follow=True): + fnode = f.filenode() + name = self.repo.ui.shortuser(f.user()) - try: - name = bcache[r] - except KeyError: - cl = self.repo.changelog.read(cnode) - bcache[r] = name = self.repo.ui.shortuser(cl[1]) - - if last != cnode: + if last != fnode: parity = 1 - parity - last = cnode + last = fnode yield {"parity": parity, - "node": hex(cnode), - "rev": r, + "node": hex(f.node()), + "filenode": hex(fnode), + "rev": f.rev(), "author": name, - "file": f, + "file": f.path(), "line": l} yield self.t("fileannotate", @@ -434,15 +422,15 @@ class hgweb(object): filenode=node, annotate=annotate, path=_up(f), - rev=changerev, - node=hex(cn), - manifest=hex(mfn), - author=cs[1], - date=cs[2], + rev=fctx.rev(), + node=hex(fctx.node()), + manifest=hex(fctx.changectx().changeset()[0]), + author=fctx.user(), + date=fctx.date(), rename=self.renamelink(fl, n), parent=self.siblings(fl.parents(n), fl.rev, file=f), child=self.siblings(fl.children(n), fl.rev, file=f), - permissions=self.repo.manifest.read(mfn).execf(f)) + permissions=fctx.manifest().execf(f)) def manifest(self, mnode, path): man = self.repo.manifest
--- a/mercurial/httprepo.py +++ b/mercurial/httprepo.py @@ -165,7 +165,8 @@ class httprepository(remoterepository): proxyuser, proxypasswd or ''), proxypath, proxyquery, proxyfrag)) handler = urllib2.ProxyHandler({scheme: proxyurl}) - ui.debug(_('proxying through %s\n') % proxyurl) + ui.debug(_('proxying through http://%s:%s\n') % + (proxyhost, proxyport)) # urllib2 takes proxy values from the environment and those # will take precedence if found, so drop them
--- a/mercurial/manifest.py +++ b/mercurial/manifest.py @@ -9,6 +9,7 @@ from revlog import * from i18n import gettext as _ from demandload import * demandload(globals(), "array bisect struct") +demandload(globals(), "mdiff") class manifestdict(dict): def __init__(self, mapping=None, flags=None): @@ -42,16 +43,25 @@ class manifest(revlog): revlog.__init__(self, opener, "00manifest.i", "00manifest.d", defversion) + def parselines(self, lines): + for l in lines.splitlines(1): + yield l.split('\0') + + def readdelta(self, node): + delta = mdiff.patchtext(self.delta(node)) + deltamap = manifestdict() + for f, n in self.parselines(delta): + deltamap.rawset(f, n) + return deltamap + def read(self, node): if node == nullid: return manifestdict() # don't upset local cache if self.mapcache and self.mapcache[0] == node: return self.mapcache[1] text = self.revision(node) self.listcache = array.array('c', text) - lines = text.splitlines(1) mapping = manifestdict() - for l in lines: - (f, n) = l.split('\0') + for f, n in self.parselines(text): mapping.rawset(f, n) self.mapcache = (node, mapping) return mapping
--- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -24,6 +24,7 @@ class diffopts(object): text treats all files as text showfunc enables diff -p output git enables the git extended patch format + nodates removes dates from diff headers ignorews ignores all whitespace changes in the diff ignorewsamount ignores changes in the amount of whitespace ignoreblanklines ignores changes whose lines are all blank''' @@ -33,6 +34,7 @@ class diffopts(object): 'text': False, 'showfunc': True, 'git': False, + 'nodates': False, 'ignorews': False, 'ignorewsamount': False, 'ignoreblanklines': False, @@ -51,7 +53,7 @@ defaultopts = diffopts() def unidiff(a, ad, b, bd, fn, r=None, opts=defaultopts): def datetag(date): - return opts.git and '\n' or '\t%s\n' % date + return (opts.git or opts.nodates) and '\n' or '\t%s\n' % date if not a and not b: return "" epoch = util.datestr((0, 0))
--- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -291,6 +291,8 @@ def diffopts(ui, opts={}): text=opts.get('text'), git=(opts.get('git') or ui.configbool('diff', 'git', None)), + nodates=(opts.get('nodates') or + ui.configbool('diff', 'nodates', None)), showfunc=(opts.get('show_function') or ui.configbool('diff', 'showfunc', None)), ignorews=(opts.get('ignore_all_space') or
--- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -330,7 +330,8 @@ class changeset_templater(object): def __init__(self, ui, repo, mapfile, dest=None): self.t = templater(mapfile, common_filters, cache={'parent': '{rev}:{node|short} ', - 'manifest': '{rev}:{node|short}'}) + 'manifest': '{rev}:{node|short}', + 'filecopy': '{name} ({source})'}) self.ui = ui self.dest = dest self.repo = repo @@ -355,7 +356,7 @@ class changeset_templater(object): self.write(thing, header=True) def show(self, rev=0, changenode=None, brinfo=None, changes=None, - **props): + copies=[], **props): '''show a single changeset or file revision''' log = self.repo.changelog if changenode is None: @@ -472,6 +473,13 @@ class changeset_templater(object): showadds = '' showdels = '' + copies = [{'name': x[0], 'source': x[1]} + for x in copies] + def showcopies(**args): + for x in showlist('file_copy', copies, plural='file_copies', + **args): + yield x + defprops = { 'author': changes[1], 'branches': showbranches, @@ -480,6 +488,7 @@ class changeset_templater(object): 'file_adds': showadds, 'file_dels': showdels, 'files': showfiles, + 'file_copies': showcopies, 'manifest': showmanifest, 'node': hex(changenode), 'parents': showparents,
--- a/mercurial/util.py +++ b/mercurial/util.py @@ -948,6 +948,9 @@ def shortuser(user): f = user.find('<') if f >= 0: user = user[f+1:] + f = user.find(' ') + if f >= 0: + user = user[:f] return user def walkrepos(path):
--- a/mercurial/verify.py +++ b/mercurial/verify.py @@ -102,21 +102,15 @@ def verify(repo): (short(n), short(p))) try: - delta = mdiff.patchtext(repo.manifest.delta(n)) + for f, fn in repo.manifest.readdelta(n).iteritems(): + filenodes.setdefault(f, {})[fn] = 1 except KeyboardInterrupt: repo.ui.warn(_("interrupted")) raise except Exception, inst: - err(_("unpacking manifest %s: %s") % (short(n), inst)) + err(_("reading delta for manifest %s: %s") % (short(n), inst)) continue - try: - ff = [ l.split('\0') for l in delta.splitlines() ] - for f, fn in ff: - filenodes.setdefault(f, {})[bin(fn[:40])] = 1 - except (ValueError, TypeError), inst: - err(_("broken delta in manifest %s: %s") % (short(n), inst)) - repo.ui.status(_("crosschecking files in changesets and manifests\n")) for m, c in neededmanifests.items():
--- a/templates/changeset-gitweb.tmpl +++ b/templates/changeset-gitweb.tmpl @@ -27,10 +27,10 @@ #changesettag# </table></div> -<div class="title_text"> +<div class="page_body"> #desc|strip|escape|addbreaks# </div> - +<div class="list_head"></div> <div class="title_text"> <table cellspacing="0"> #files#
--- a/templates/map +++ b/templates/map @@ -22,7 +22,7 @@ filediff = filediff.tmpl filelog = filelog.tmpl fileline = '<div class="parity#parity#"><span class="lineno">#linenumber#</span>#line|escape#</div>' filelogentry = filelogentry.tmpl -annotateline = '<tr class="parity#parity#"><td class="annotate"><a href="?cs=#node|short#">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>' +annotateline = '<tr class="parity#parity#"><td class="annotate"><a href="?fa=#filenode|short#;file=#file|urlescape#">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>' difflineplus = '<span class="plusline">#line|escape#</span>' difflineminus = '<span class="minusline">#line|escape#</span>' difflineat = '<span class="atline">#line|escape#</span>' @@ -32,11 +32,11 @@ changesetparent = '<tr><th class="parent filerevparent = '<tr><td class="metatag">parent:</td><td><a href="?f=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>' filerename = '<tr><td class="metatag">parent:</td><td><a href="?f=#node|short#;file=#file|urlescape#">#file|escape#@#node|short#</a></td></tr>' filelogrename = '<tr><th>base:</th><td><a href="?f=#node|short#;file=#file|urlescape#">#file|escape#@#node|short#</a></td></tr>' -fileannotateparent = '<tr><td class="metatag">parent:</td><td><a href="?fa=#filenode|short#;file=#file|urlescape#">#node|short#</a></td></tr>' +fileannotateparent = '<tr><td class="metatag">parent:</td><td><a href="?fa=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>' changesetchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="?cs=#node|short#">#node|short#</a></td></tr>' changelogchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="?cs=#node|short#">#node|short#</a></td></tr>' filerevchild = '<tr><td class="metatag">child:</td><td><a href="?f=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>' -fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="?fa=#filenode|short#;file=#file|urlescape#">#node|short#</a></td></tr>' +fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="?fa=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>' tags = tags.tmpl tagentry = '<li class="tagEntry parity#parity#"><tt class="node">#node#</tt> <a href="?cs=#node|short#">#tag|escape#</a></li>' diffblock = '<pre class="parity#parity#">#lines#</pre>'
--- a/templates/map-cmdline.default +++ b/templates/map-cmdline.default @@ -1,12 +1,15 @@ changeset = 'changeset: {rev}:{node|short}\n{tags}{short_parents}user: {author}\ndate: {date|date}\nsummary: {desc|firstline}\n\n' changeset_quiet = '{rev}:{node|short}\n' -changeset_verbose = 'changeset: {rev}:{node}\n{tags}{parents}{manifest}user: {author}\ndate: {date|date}\nfiles: {files}\n{file_adds}{file_dels}description:\n{desc|strip}\n\n\n' +changeset_verbose = 'changeset: {rev}:{node}\n{tags}{parents}{manifest}user: {author}\ndate: {date|date}\nfiles: {files}\n{file_adds}{file_dels}{file_copies}description:\n{desc|strip}\n\n\n' start_file_adds = 'files+: ' file_add = ' {file_add}' end_file_adds = '\n' start_file_dels = 'files-: ' file_del = ' {file_del}' end_file_dels = '\n' +start_file_copies = 'copies: ' +file_copy = ' {name} ({source})' +end_file_copies = '\n' short_parent = 'parent: {rev}:{node|short}\n' parent = 'parent: {rev}:{node}\n' manifest = 'manifest: {rev}:{node}\n'
--- a/templates/map-gitweb +++ b/templates/map-gitweb @@ -8,7 +8,7 @@ error = error-gitweb.tmpl naventry = '<a href="?cmd=changelog;rev=#rev#;style=gitweb">#label|escape#</a> ' navshortentry = '<a href="?cmd=shortlog;rev=#rev#;style=gitweb">#label|escape#</a> ' filedifflink = '<a href="?cmd=filediff;node=#node#;file=#file|urlescape#;style=gitweb">#file|escape#</a> ' -filenodelink = '<tr class="light"><td><a class="list" href="">#file|escape#</a></td><td></td><td class="link"><a href="?cmd=file;filenode=#filenode#;file=#file|urlescape#;style=gitweb">file</a> | <a href="?fa=#filenode|short#;file=#file|urlescape#;style=gitweb">annotate</a> | <!-- FIXME: <a href="?fd=#filenode|short#;file=#file|urlescape#;style=gitweb">diff</a> | --> <a href="?cmd=filelog;filenode=#filenode|short#;file=#file|urlescape#;style=gitweb">revisions</a></td></tr>' +filenodelink = '<tr class="parity#parity#"><td><a class="list" href="">#file|escape#</a></td><td></td><td class="link"><a href="?cmd=file;filenode=#filenode#;file=#file|urlescape#;style=gitweb">file</a> | <a href="?fa=#filenode|short#;file=#file|urlescape#;style=gitweb">annotate</a> | <!-- FIXME: <a href="?fd=#filenode|short#;file=#file|urlescape#;style=gitweb">diff</a> | --> <a href="?cmd=filelog;filenode=#filenode|short#;file=#file|urlescape#;style=gitweb">revisions</a></td></tr>' fileellipses = '...' changelogentry = changelogentry-gitweb.tmpl searchentry = changelogentry-gitweb.tmpl @@ -20,7 +20,7 @@ filerevision = filerevision-gitweb.tmpl fileannotate = fileannotate-gitweb.tmpl filelog = filelog-gitweb.tmpl fileline = '<div style="font-family:monospace" class="parity#parity#"><pre><span class="linenr"> #linenumber#</span> #line|escape#</pre></div>' -annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="?cs=#node|short#;style=gitweb">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>' +annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="?fa=#filenode|short#;file=#file|urlescape#;style=gitweb">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>' difflineplus = '<div style="color:#008800;">#line|escape#</div>' difflineminus = '<div style="color:#cc0000;">#line|escape#</div>' difflineat = '<div style="color:#990099;">#line|escape#</div>'
--- a/templates/template-vars.txt +++ b/templates/template-vars.txt @@ -25,6 +25,7 @@ header the global page header footer the global page footer files a list of file links +file_copies a list of pairs of name, source filenames dirs a set of directory links diff a diff of one or more files annotate an annotated file @@ -36,4 +37,4 @@ Templates and commands: filenodelink - jump to file diff fileellipses - printed after maxfiles changelogentry - an entry in the log - manifest - browse a manifest as a directory tree \ No newline at end of file + manifest - browse a manifest as a directory tree
--- a/tests/README +++ b/tests/README @@ -26,11 +26,9 @@ writing tests: use commit -m "test" -u test -d "1000000 0" -- diff will show the current time +- diff and export may show the current time - use hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" - to strip dates + use -D/--nodates to strip the dates - You can append your own hgrc settings to the file that the environment variable HGRCPATH points to. This file is cleared before running a test.
--- a/tests/test-annotate +++ b/tests/test-annotate @@ -21,3 +21,53 @@ hg annotate -u a echo % annotate -cdnu hg annotate -cdnu a + +cat <<EOF >>a +a +a +EOF +hg ci -ma1 -d '1 0' +hg cp a b +hg ci -mb -d '1 0' +cat <<EOF >> b +b +b +b +EOF +hg ci -mb2 -d '2 0' + +echo % annotate b +hg annotate b +echo % annotate -nf b +hg annotate -nf b + +hg up -C 2 +cat <<EOF >> b +b +c +b +EOF +hg ci -mb2.1 -d '2 0' +hg merge +hg ci -mmergeb -d '3 0' +echo % annotate after merge +hg annotate -nf b + +hg up -C 1 +hg cp a b +cat <<EOF > b +a +z +a +EOF +hg ci -mc -d '3 0' +hg merge +cat <<EOF >> b +b +c +b +EOF +echo d >> b +hg ci -mmerge2 -d '4 0' +echo % annotate after rename merge +hg annotate -nf b
--- a/tests/test-annotate.out +++ b/tests/test-annotate.out @@ -11,3 +11,40 @@ 0: a nobody: a % annotate -cdnu nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a +% annotate b +2: a +2: a +2: a +3: b +3: b +3: b +% annotate -nf b +0 a: a +1 a: a +1 a: a +3 b: b +3 b: b +3 b: b +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +merging b +0 files updated, 1 files merged, 0 files removed, 0 files unresolved +(branch merge, don't forget to commit) +% annotate after merge +0 a: a +1 a: a +1 a: a +3 b: b +4 b: c +3 b: b +0 files updated, 0 files merged, 1 files removed, 0 files unresolved +merging b +0 files updated, 1 files merged, 0 files removed, 0 files unresolved +(branch merge, don't forget to commit) +% annotate after rename merge +0 a: a +6 b: z +1 a: a +3 b: b +4 b: c +3 b: b +7 b: d
--- a/tests/test-command-template +++ b/tests/test-command-template @@ -65,6 +65,10 @@ echo '[ui]' > .hg/hgrc echo 'style = t' >> .hg/hgrc hg log +echo '# issue338' +hg log --style=changelog > changelog +cat changelog + echo "# keys work" for key in author branches date desc file_adds file_dels files \ manifest node parents rev tags; do
--- a/tests/test-command-template.out +++ b/tests/test-command-template.out @@ -76,6 +76,33 @@ 3 2 1 0 +# issue338 +1970-01-16 person <person> + + * c: + no user, no domain + [10e46f2dcbf4] [tip] + +1970-01-14 other <other@place> + + * c: + no person + [97054abb4ab8] + +1970-01-13 A. N. Other <other@place> + + * b: + other 1 other 2 + + other 3 + [b608e9d1a3f0] + +1970-01-12 User Name <user@hostname> + + * a: + line 1 line 2 + [1e4e1b8f71e0] + # keys work author: person author: other@place
--- a/tests/test-diff-ignore-whitespace +++ b/tests/test-diff-ignore-whitespace @@ -3,8 +3,7 @@ # GNU diff is the reference for all of these results. hgdiff() { - hg diff "$@" | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" + hg diff --nodates "$@" } test_added_blank_lines() {
--- a/tests/test-diff-subdir +++ b/tests/test-diff-subdir @@ -14,14 +14,11 @@ echo 1 > alpha/one echo 2 > beta/two echo EVERYTHING -hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --nodates echo BETA ONLY -hg diff beta | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --nodates beta echo INSIDE BETA cd beta -hg diff . | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --nodates .
--- a/tests/test-diffdir +++ b/tests/test-diffdir @@ -7,12 +7,9 @@ hg ci -m "a" -d "1000000 0" echo 123 > b hg add b -hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --nodates -hg diff -r tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --nodates -r tip echo foo > a -hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --nodates
--- a/tests/test-git-export +++ b/tests/test-git-export @@ -8,26 +8,22 @@ hg ci -Amstart -d '0 0' echo new > new hg ci -Amnew -d '0 0' echo '% new file' -hg diff --git -r 0 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --git -r 0 hg cp new copy hg ci -mcopy -d '0 0' echo '% copy' -hg diff --git -r 1:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --git -r 1:tip hg mv copy rename hg ci -mrename -d '0 0' echo '% rename' -hg diff --git -r 2:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --git -r 2:tip hg rm rename hg ci -mdelete -d '0 0' echo '% delete' -hg diff --git -r 3:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --git -r 3:tip cat > src <<EOF 1 @@ -40,17 +36,14 @@ hg ci -Amsrc -d '0 0' chmod +x src hg ci -munexec -d '0 0' echo '% chmod 644' -hg diff --git -r 5:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --git -r 5:tip hg mv src dst chmod -x dst echo a >> dst hg ci -mrenamemod -d '0 0' echo '% rename+mod+chmod' -hg diff --git -r 6:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --git -r 6:tip echo '% nonexistent in tip+chmod' -hg diff --git -r 5:6 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --git -r 5:6
--- a/tests/test-globalopts.out +++ b/tests/test-globalopts.out @@ -115,7 +115,7 @@ Mercurial Distributed SCM list of commands (use "hg help -v" to show aliases and global options): add add the specified files on the next commit - addremove add all new files, delete all missing files (DEPRECATED) + addremove add all new files, delete all missing files annotate show changeset information per file line archive create unversioned archive of a repository revision backout reverse effect of earlier changeset @@ -162,7 +162,7 @@ Mercurial Distributed SCM list of commands (use "hg help -v" to show aliases and global options): add add the specified files on the next commit - addremove add all new files, delete all missing files (DEPRECATED) + addremove add all new files, delete all missing files annotate show changeset information per file line archive create unversioned archive of a repository revision backout reverse effect of earlier changeset
--- a/tests/test-help.out +++ b/tests/test-help.out @@ -39,7 +39,7 @@ Mercurial Distributed SCM list of commands (use "hg help -v" to show aliases and global options): add add the specified files on the next commit - addremove add all new files, delete all missing files (DEPRECATED) + addremove add all new files, delete all missing files annotate show changeset information per file line archive create unversioned archive of a repository revision backout reverse effect of earlier changeset @@ -82,7 +82,7 @@ list of commands (use "hg help -v" to sh verify verify the integrity of the repository version output version and copyright information add add the specified files on the next commit - addremove add all new files, delete all missing files (DEPRECATED) + addremove add all new files, delete all missing files annotate show changeset information per file line archive create unversioned archive of a repository revision backout reverse effect of earlier changeset @@ -179,6 +179,7 @@ options: -a --text treat all files as text -p --show-function show which function each change is in -g --git use git extended diff format + --nodates don't include dates in diff headers -w --ignore-all-space ignore white space when comparing lines -b --ignore-space-change ignore changes in the amount of white space -B --ignore-blank-lines ignore changes whose lines are all blank
--- a/tests/test-log +++ b/tests/test-log @@ -29,6 +29,9 @@ hg log -vf a echo % many renames hg log -vf e +echo % log copies +hg log -vC --template '{rev} {file_copies%filecopy}\n' + # log --follow tests hg init ../follow cd ../follow
--- a/tests/test-log.out +++ b/tests/test-log.out @@ -76,6 +76,12 @@ description: a +% log copies +4 e (dir/b) +3 b (a) +2 dir/b (b) +1 b (a) +0 adding base 1 files updated, 0 files merged, 0 files removed, 0 files unresolved adding b1
--- a/tests/test-merge-revert2 +++ b/tests/test-merge-revert2 @@ -27,8 +27,8 @@ hg id hg update -C 0 echo "changed file1 different" >> file1 HGMERGE=merge hg update -hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" -e "s/\(<<<<<<<\) .*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" -e "s/\(>>>>>>>\) .*/\1/" +#hg diff --nodates | sed -e "s/\(<<<<<<<\) .*/\1/" -e "s/\(>>>>>>>\) .*/\1/" +hg diff --nodates | sed -e "s/\(<<<<<<<\|>>>>>>>\) .*/\1/" hg status hg id hg revert --no-backup --all
--- a/tests/test-remove +++ b/tests/test-remove @@ -13,8 +13,8 @@ hg revert --all rm foo hg remove --after hg commit -m 2 -d "1000000 0" -hg export 0 -hg export 1 +hg export --nodates 0 +hg export --nodates 1 hg log -p -r 0 hg log -p -r 1
--- a/tests/test-remove.out +++ b/tests/test-remove.out @@ -10,8 +10,8 @@ removing foo 1 diff -r 000000000000 -r 8ba83d44753d foo ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/foo Mon Jan 12 13:46:40 1970 +0000 +--- /dev/null ++++ b/foo @@ -0,0 +1,1 @@ +a # HG changeset patch @@ -22,8 +22,8 @@ diff -r 000000000000 -r 8ba83d44753d foo 2 diff -r 8ba83d44753d -r a1fce69c50d9 foo ---- a/foo Mon Jan 12 13:46:40 1970 +0000 -+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +--- a/foo ++++ /dev/null @@ -1,1 +0,0 @@ -a changeset: 0:8ba83d44753d
--- a/tests/test-up-local-change +++ b/tests/test-up-local-change @@ -12,8 +12,7 @@ hg clone . ../r2 cd ../r2 hg up echo abc > a -hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --nodates cd ../r1 echo b > b @@ -34,8 +33,7 @@ hg parents hg --debug up hg parents hg -v history -hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --nodates # create a second head cd ../r1 @@ -53,8 +51,7 @@ hg --debug up || echo failed hg --debug merge || echo failed hg --debug merge -f hg parents -hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ - -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" +hg diff --nodates # test a local add cd ..