# HG changeset patch # User Matt Mackall # Date 1161715564 18000 # Node ID ceaa3fefc10c5d4a6684d4720b6c9e776b817f1f # Parent ff06fe0703ef0a4c6261dcc819d476ca01a0a930# Parent c3345b0f2fcdb3bb8cf3a6bf572159ec7e190a90 Merge with crew diff --git a/contrib/bash_completion b/contrib/bash_completion --- a/contrib/bash_completion +++ b/contrib/bash_completion @@ -8,9 +8,9 @@ # # Mercurial allows you to define additional commands through extensions. # Bash should be able to automatically figure out the name of these new -# commands and their options. If you also want to tell it how to -# complete non-option arguments, see below for how to define an -# _hg_cmd_foo function. +# commands and their options. See below for how to define _hg_opt_foo +# and _hg_cmd_foo functions to fine-tune the completion for option and +# non-option arguments, respectively. # # # Notes about completion for specific commands: @@ -34,7 +34,10 @@ # # If it exists, the function _hg_cmd_foo will be called without # arguments to generate the completion candidates for the hg command -# "foo". +# "foo". If the command receives some arguments that aren't options +# even though they start with a "-", you can define a function called +# _hg_opt_foo to generate the completion candidates. If _hg_opt_foo +# doesn't return 0, regular completion for options is attempted. # # In addition to the regular completion variables provided by bash, # the following variables are also set: @@ -109,6 +112,7 @@ shopt -s extglob # global options that receive an argument local global_args='--cwd|-R|--repository' local hg="$1" + local canonical=0 COMPREPLY=() cur="$2" @@ -128,6 +132,10 @@ shopt -s extglob done if [[ "$cur" == -* ]]; then + if [ "$(type -t "_hg_opt_$cmd")" = function ] && "_hg_opt_$cmd"; then + return + fi + opts=$("$hg" debugcomplete --options "$cmd" 2>/dev/null) COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur")) @@ -153,7 +161,6 @@ shopt -s extglob # try to generate completion candidates for whatever command the user typed local help - local canonical=0 if _hg_command_specific; then return fi @@ -193,7 +200,13 @@ shopt -s extglob help) _hg_commands ;; - export|manifest|update) + export) + if _hg_ext_mq_patchlist qapplied && [ "${COMPREPLY[*]}" ]; then + return 0 + fi + _hg_tags + ;; + manifest|update) _hg_tags ;; pull|push|outgoing|incoming) @@ -251,8 +264,13 @@ complete -o bashdefault -o default -F _h # mq _hg_ext_mq_patchlist() { - local patches=$("$hg" $1 2>/dev/null) - COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur")) + local patches + patches=$("$hg" $1 2>/dev/null) + if [ $? -eq 0 ] && [ "$patches" ]; then + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur")) + return 0 + fi + return 1 } _hg_ext_mq_queues() @@ -288,7 +306,11 @@ complete -o bashdefault -o default -F _h _hg_cmd_qdelete() { - _hg_ext_mq_patchlist qunapplied + local qcmd=qunapplied + if [[ "$prev" = @(-r|--rev) ]]; then + qcmd=qapplied + fi + _hg_ext_mq_patchlist $qcmd } _hg_cmd_qsave() @@ -313,9 +335,76 @@ complete -o bashdefault -o default -F _h COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur")) } -_hg_cmd_export() +_hg_cmd_qfold() +{ + _hg_ext_mq_patchlist qunapplied +} + +_hg_cmd_qrename() +{ + _hg_ext_mq_patchlist qseries +} + +_hg_cmd_qheader() +{ + _hg_ext_mq_patchlist qseries +} + +_hg_cmd_qclone() +{ + local count=$(_hg_count_non_option) + if [ $count = 1 ]; then + _hg_paths + fi + _hg_repos +} + +_hg_ext_mq_guards() +{ + "$hg" qselect --series 2>/dev/null | sed -e 's/^.//' +} + +_hg_cmd_qselect() { - _hg_ext_mq_patchlist qapplied + local guards=$(_hg_ext_mq_guards) + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$guards' -- "$cur")) +} + +_hg_cmd_qguard() +{ + local prefix='' + + if [[ "$cur" == +* ]]; then + prefix=+ + elif [[ "$cur" == -* ]]; then + prefix=- + fi + local ncur=${cur#[-+]} + + if ! [ "$prefix" ]; then + _hg_ext_mq_patchlist qseries + return + fi + + local guards=$(_hg_ext_mq_guards) + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -P $prefix -W '$guards' -- "$ncur")) +} + +_hg_opt_qguard() +{ + local i + for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != -* ]]; then + if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then + _hg_cmd_qguard + return 0 + fi + elif [ "${COMP_WORDS[i]}" = -- ]; then + _hg_cmd_qguard + return 0 + fi + done + return 1 } @@ -354,7 +443,7 @@ complete -o bashdefault -o default -F _h _hg_cmd_email() { case "$prev" in - -c|--cc|-t|--to|-f|--from) + -c|--cc|-t|--to|-f|--from|--bcc) # we need an e-mail address. let the user provide a function # to get them if [ "$(type -t _hg_emails)" = function ]; then diff --git a/contrib/zsh_completion b/contrib/zsh_completion --- a/contrib/zsh_completion +++ b/contrib/zsh_completion @@ -14,7 +14,18 @@ local curcontext="$curcontext" state line typeset -A opt_args -local subcmds repos tags newFiles addedFiles includeExclude +local subcmds repos tags newFiles addedFiles includeExclude commitMessage + +_mq_state () { + case "$state" in + (qapplied) + compadd $(hg qapplied) + ;; + (qunapplied) + compadd $(hg qunapplied) + ;; + esac +} tags=($(hg tags 2> /dev/null | sed -e 's/[0-9]*:[a-f0-9]\{40\}$//; s/ *$//')) subcmds=($(hg -v help | sed -e '1,/^list of commands:/d' \ @@ -27,6 +38,14 @@ includeExclude=( '*-X-[exclude names matching the given patterns]:dir:_files -W $(hg root) -/' '*--exclude-[exclude names matching the given patterns]:dir:_files -W $(hg root) -/') +commitMessage=( + '(-m --message -l --logfile --edit)-e[edit commit message]' + '(-m --message -l --logfile -e)--edit[edit commit message]' + '(-e --edit -l --logfile --message)-m[use as commit message]:message:' + '(-e --edit -l --logfile -m)--message[use as commit message]:message:' + '(-e --edit -m --message --logfile)-l[read the commit message from ]:log file:_files' + '(-e --edit -m --message -l)--logfile[read the commit message from ]:log file:_files') + if [[ $service == "hg" ]]; then _arguments -C -A "-*" \ '(--repository)-R[repository root directory]:root:_files -/' \ @@ -419,6 +438,43 @@ case $service in # no arguments for these commands ;; + # MQ commands + (qdel*|qrm|qrem*) + _arguments \ + {-k,--keep}'[keep patch file]' \ + {-r,--rev}'[revision]:applied patch:->qapplied' \ + '*:unapplied patches:->qunapplied' + _mq_state + ;; + + (qnew) + _arguments $commitMessage \ + {-f,--force}'[import uncommitted changes into patch]' \ + ':patch name:' + ;; + + (qpo*) + applied=( $(hg qapplied) ) + _arguments \ + (1){-a,--all}'[pop all patches]' \ + {-f,--force}'[forget any local changes]' \ + ':applied patch:->qapplied' + _mq_state + ;; + + (qpu*) + _arguments \ + (1){-a,--all}'[apply all patches]' \ + {-f,--force}'[apply if the patch has rejects]' \ + ':unapplied patch:->qunapplied' + _mq_state + ;; + (qref*) + _arguments $commitMessage $includeExclude \ + {-g,--git}'[use git extended diff format]' \ + {-s,--short}'[short refresh]' + ;; + (*) _message "unknown hg command completion: $service" ;; diff --git a/doc/hgrc.5.txt b/doc/hgrc.5.txt --- a/doc/hgrc.5.txt +++ b/doc/hgrc.5.txt @@ -401,9 +401,8 @@ ui:: username;; The committer of a changeset created when running "commit". Typically a person's name and email address, e.g. "Fred Widget - ". Default is $EMAIL or username@hostname, unless - username is set to an empty string, which enforces specifying the - username manually. + ". Default is $EMAIL. If no default is found, or the + configured username is empty, it has to be specified manually. verbose;; Increase the amount of output printed. True or False. Default is False. diff --git a/hgext/hgk.py b/hgext/hgk.py --- a/hgext/hgk.py +++ b/hgext/hgk.py @@ -177,7 +177,7 @@ def revtree(args, repo, full="tree", max if len(ar) == 0: return 1 mask = 0 - for i in range(len(ar)): + for i in xrange(len(ar)): if sha in reachable[i]: mask |= 1 << i @@ -190,7 +190,7 @@ def revtree(args, repo, full="tree", max # figure out which commits they are asking for and which ones they # want us to stop on - for i in range(len(args)): + for i in xrange(len(args)): if args[i].startswith('^'): s = repo.lookup(args[i][1:]) stop_sha1.append(s) @@ -199,7 +199,7 @@ def revtree(args, repo, full="tree", max want_sha1.append(repo.lookup(args[i])) # calculate the graph for the supplied commits - for i in range(len(want_sha1)): + for i in xrange(len(want_sha1)): reachable.append({}); n = want_sha1[i]; visit = [n]; diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -408,14 +408,15 @@ class queue: def patch(self, repo, patchfile): '''Apply patchfile to the working directory. patchfile: file name of patch''' + files = {} try: - (files, fuzz) = patch.patch(patchfile, self.ui, strip=1, - cwd=repo.root) + fuzz = patch.patch(patchfile, self.ui, strip=1, cwd=repo.root, + files=files) except Exception, inst: self.ui.note(str(inst) + '\n') if not self.ui.verbose: self.ui.warn("patch failed, unable to continue (try -v)\n") - return (False, [], False) + return (False, files, False) return (True, files, fuzz) @@ -592,7 +593,7 @@ class queue: if stop in chlog.nodemap: stoprev = chlog.rev(stop) - for r in range(chlog.count() - 1, -1, -1): + for r in xrange(chlog.count() - 1, -1, -1): n = chlog.node(r) if n not in p: h.append(n) @@ -954,7 +955,7 @@ class queue: if comments: # Remove existing message. ci = 0 - for mi in range(len(message)): + for mi in xrange(len(message)): while message[mi] != comments[ci]: ci += 1 del comments[ci] @@ -1035,7 +1036,7 @@ class queue: # if the patch excludes a modified file, mark that file with mtime=0 # so status can see it. mm = [] - for i in range(len(m)-1, -1, -1): + for i in xrange(len(m)-1, -1, -1): if not matchfn(m[i]): mm.append(m[i]) del m[i] @@ -1103,7 +1104,7 @@ class queue: if not length: length = len(self.series) - start if not missing: - for i in range(start, start+length): + for i in xrange(start, start+length): pfx = '' patch = pname(i) if self.ui.verbose: diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py --- a/hgext/patchbomb.py +++ b/hgext/patchbomb.py @@ -195,7 +195,7 @@ def patchbomb(ui, repo, *revs, **opts): ui.write(_('This patch series consists of %d patches.\n\n') % len(patches)) - for p, i in zip(patches, range(len(patches))): + for p, i in zip(patches, xrange(len(patches))): jumbo.extend(p) msgs.append(makepatch(p, i + 1, len(patches))) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -219,7 +219,7 @@ def walkchangerevs(ui, repo, pats, opts) rev = repo.changelog.rev(repo.lookup(rev)) ff = followfilter() stop = min(revs[0], revs[-1]) - for x in range(rev, stop-1, -1): + for x in xrange(rev, stop-1, -1): if ff.match(x) and wanted.has_key(x): del wanted[x] @@ -326,7 +326,8 @@ class changeset_printer(object): changes = log.read(changenode) date = util.datestr(changes[2]) - branch = changes[5].get("branch") + extra = changes[5] + branch = extra.get("branch") hexfunc = self.ui.debugflag and hex or short @@ -360,12 +361,19 @@ class changeset_printer(object): files): if value: self.ui.note("%-12s %s\n" % (key, " ".join(value))) - else: + elif changes[3]: 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)) + if extra and self.ui.debugflag: + extraitems = extra.items() + extraitems.sort() + for key, value in extraitems: + self.ui.debug(_("extra: %s=%s\n") + % (key, value.encode('string_escape'))) + description = changes[4].strip() if description: if self.ui.verbose: @@ -1237,7 +1245,7 @@ def debugindex(ui, file_): r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0) ui.write(" rev offset length base linkrev" + " nodeid p1 p2\n") - for i in range(r.count()): + for i in xrange(r.count()): node = r.node(i) pp = r.parents(node) ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % ( @@ -1248,7 +1256,7 @@ def debugindexdot(ui, file_): """dump an index DAG as a .dot file""" r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0) ui.write("digraph G {\n") - for i in range(r.count()): + for i in xrange(r.count()): node = r.node(i) pp = r.parents(node) ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i)) @@ -1435,15 +1443,15 @@ def grep(ui, repo, pattern, *pats, **opt sm = difflib.SequenceMatcher(None, a, b) for tag, alo, ahi, blo, bhi in sm.get_opcodes(): if tag == 'insert': - for i in range(blo, bhi): + for i in xrange(blo, bhi): yield ('+', b[i]) elif tag == 'delete': - for i in range(alo, ahi): + for i in xrange(alo, ahi): yield ('-', a[i]) elif tag == 'replace': - for i in range(alo, ahi): + for i in xrange(alo, ahi): yield ('-', a[i]) - for i in range(blo, bhi): + for i in xrange(blo, bhi): yield ('+', b[i]) prev = {} @@ -1648,8 +1656,12 @@ def import_(ui, repo, patch1, *patches, message = None ui.debug(_('message:\n%s\n') % message) - files, fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root) - files = patch.updatedir(ui, repo, files, wlock=wlock) + files = {} + try: + fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root, + files=files) + finally: + files = patch.updatedir(ui, repo, files, wlock=wlock) repo.commit(files, message, user, date, wlock=wlock, lock=lock) finally: os.unlink(tmpname) @@ -2091,11 +2103,11 @@ def pull(ui, repo, source="default", **o Use an extra slash at the start of a path to specify an absolute path: ssh://example.com//tmp/repository - Mercurial doesn't use its own compression via SSH; the right thing - to do is to configure it in your ~/.ssh/ssh_config, e.g.: + to do is to configure it in your ~/.ssh/config, e.g.: Host *.mylocalnetwork.example.com - Compression off + Compression no Host * - Compression on + Compression yes Alternatively specify "ssh -C" as your ssh command in your hgrc or with the --ssh command line option. """ @@ -2538,6 +2550,9 @@ def status(ui, repo, *pats, **opts): files that match are shown. Files that are clean or ignored, are not listed unless -c (clean), -i (ignored) or -A is given. + If one revision is given, it is used as the base revision. + If two revisions are given, the difference between them is shown. + The codes used to show the status of files are: M = modified A = added @@ -2550,12 +2565,14 @@ def status(ui, repo, *pats, **opts): """ all = opts['all'] + node1, node2 = cmdutil.revpair(ui, repo, opts.get('rev')) files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) cwd = (pats and repo.getcwd()) or '' modified, added, removed, deleted, unknown, ignored, clean = [ [util.pathto(cwd, x) for x in n] - for n in repo.status(files=files, match=matchfn, + for n in repo.status(node1=node1, node2=node2, files=files, + match=matchfn, list_ignored=all or opts['ignored'], list_clean=all or opts['clean'])] @@ -3101,6 +3118,7 @@ table = { ('C', 'copies', None, _('show source of copied files')), ('0', 'print0', None, _('end filenames with NUL, for use with xargs')), + ('', 'rev', [], _('show difference from revision')), ] + walkopts, _('hg status [OPTION]... [FILE]...')), "tag": diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -191,7 +191,7 @@ class hgweb(object): parity = (start - end) & 1 cl = self.repo.changelog l = [] # build a list in forward order for efficiency - for i in range(start, end): + for i in xrange(start, end): ctx = self.repo.changectx(i) n = ctx.node() @@ -234,9 +234,9 @@ class hgweb(object): qw = query.lower().split() def revgen(): - for i in range(cl.count() - 1, 0, -100): + for i in xrange(cl.count() - 1, 0, -100): l = [] - for j in range(max(0, i - 100), i): + for j in xrange(max(0, i - 100), i): ctx = self.repo.changectx(j) l.append(ctx) l.reverse() @@ -322,7 +322,7 @@ class hgweb(object): l = [] parity = (count - 1) & 1 - for i in range(start, end): + for i in xrange(start, end): ctx = fctx.filectx(i) n = fl.node(i) @@ -531,7 +531,7 @@ class hgweb(object): parity = 0 cl = self.repo.changelog l = [] # build a list in forward order for efficiency - for i in range(start, end): + for i in xrange(start, end): n = cl.node(i) changes = cl.read(n) hn = hex(n) @@ -629,9 +629,10 @@ class hgweb(object): yield '' def footer(**map): - yield self.t("footer", - motd=self.repo.ui.config("web", "motd", ""), - **map) + yield self.t("footer", **map) + + def motd(**map): + yield self.repo.ui.config("web", "motd", "") def expand_form(form): shortcuts = { @@ -762,6 +763,7 @@ class hgweb(object): "repo": self.reponame, "header": header, "footer": footer, + "motd": motd, "rawfileheader": rawfileheader, "sessionvars": sessionvars }) diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py --- a/mercurial/hgweb/hgwebdir_mod.py +++ b/mercurial/hgweb/hgwebdir_mod.py @@ -67,7 +67,10 @@ class hgwebdir(object): yield header_file.read() def footer(**map): - yield tmpl("footer", motd=self.motd, **map) + yield tmpl("footer", **map) + + def motd(**map): + yield self.motd url = req.env['REQUEST_URI'].split('?')[0] if not url.endswith('/'): @@ -80,6 +83,7 @@ class hgwebdir(object): tmpl = templater.templater(mapfile, templater.common_filters, defaults={"header": header, "footer": footer, + "motd": motd, "url": url}) def archivelist(ui, nodeid, url): diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1137,7 +1137,7 @@ class localrepository(repo.repository): reqcnt += 1 self.ui.debug(_("request %d: %s\n") % (reqcnt, " ".join(map(short, r)))) - for p in range(0, len(r), 10): + for p in xrange(0, len(r), 10): for b in remote.branches(r[p:p+10]): self.ui.debug(_("received %s:%s\n") % (short(b[0]), short(b[1]))) @@ -1757,7 +1757,7 @@ class localrepository(repo.repository): self.hook("changegroup", node=hex(self.changelog.node(cor+1)), source=srctype, url=url) - for i in range(cor + 1, cnr + 1): + for i in xrange(cor + 1, cnr + 1): self.hook("incoming", node=hex(self.changelog.node(i)), source=srctype, url=url) diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -220,7 +220,7 @@ def dogitpatch(patchname, gitpatches, cw tmpfp = os.fdopen(fd, 'w') try: - for i in range(len(gitpatches)): + for i in xrange(len(gitpatches)): p = gitpatches[i] if not p.copymod and not p.binary: continue @@ -266,14 +266,13 @@ def dogitpatch(patchname, gitpatches, cw tmpfp.close() return patchname -def patch(patchname, ui, strip=1, cwd=None): +def patch(patchname, ui, strip=1, cwd=None, files={}): """apply the patch to the working directory. a list of patched files is returned""" # helper function def __patch(patchname): """patch and updates the files and fuzz variables""" - files = {} fuzz = False patcher = util.find_in_path('gpatch', os.environ.get('PATH', ''), @@ -308,25 +307,24 @@ def patch(patchname, ui, strip=1, cwd=No if code: raise util.Abort(_("patch command failed: %s") % util.explain_exit(code)[0]) - return files, fuzz + return fuzz (dopatch, gitpatches) = readgitpatch(patchname) + for gp in gitpatches: + files[gp.path] = (gp.op, gp) - files, fuzz = {}, False + fuzz = False if dopatch: if dopatch in ('filter', 'binary'): patchname = dogitpatch(patchname, gitpatches, cwd=cwd) try: if dopatch != 'binary': - files, fuzz = __patch(patchname) + fuzz = __patch(patchname) finally: if dopatch == 'filter': os.unlink(patchname) - for gp in gitpatches: - files[gp.path] = (gp.op, gp) - - return (files, fuzz) + return fuzz def diffopts(ui, opts={}): return mdiff.diffopts( diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -737,13 +737,9 @@ class revlog(object): c = [] p = self.rev(node) for r in range(p + 1, self.count()): - n = self.node(r) - for pn in self.parents(n): - if pn == node: - c.append(n) - continue - elif pn == nullid: - continue + for pr in self.parentrevs(r): + if pr == p: + c.append(self.node(r)) return c def _match(self, id): diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -310,6 +310,7 @@ common_filters = { "strip": lambda x: x.strip(), "urlescape": lambda x: urllib.quote(x), "user": lambda x: util.shortuser(x), + "stringescape": lambda x: x.encode('string_escape'), } def templatepath(name=None): @@ -431,14 +432,15 @@ class changeset_templater(object): if endname in self.t: yield self.t(endname, **args) - if brinfo: - def showbranches(**args): - if changenode in brinfo: - for x in showlist('branch', brinfo[changenode], - plural='branches', **args): - yield x - else: - showbranches = '' + def showbranches(**args): + branch = changes[5].get("branch") + if branch: + yield showlist('branch', [branch], plural='branches', **args) + # add old style branches if requested + if brinfo and changenode in brinfo: + for x in showlist('branch', brinfo[changenode], + plural='branches', **args): + yield x if self.ui.debugflag: def showmanifest(**args): @@ -463,6 +465,14 @@ class changeset_templater(object): for x in showlist('tag', self.repo.nodetags(changenode), **args): yield x + def showextras(**args): + extras = changes[5].items() + extras.sort() + for key, value in extras: + args = args.copy() + args.update(dict(key=key, value=value)) + yield self.t('extra', **args) + if self.ui.debugflag: files = self.repo.status(log.parents(changenode)[0], changenode)[:3] def showfiles(**args): @@ -498,6 +508,7 @@ class changeset_templater(object): 'parents': showparents, 'rev': rev, 'tags': showtags, + 'extras': showextras, } props = props.copy() props.update(defprops) diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -111,7 +111,8 @@ class ui(object): try: cdata.read(filename) except ConfigParser.ParsingError, inst: - raise util.Abort(_("failed to parse %s\n%s") % (f, inst)) + raise util.Abort(_("failed to parse %s\n%s") % (filename, + inst)) for section in sections: if not cdata.has_section(section): @@ -226,21 +227,21 @@ class ui(object): Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL and stop searching if one of these is set. - Abort if found username is an empty string to force specifying - the commit user elsewhere, e.g. with line option or repo hgrc. - If not found, use ($LOGNAME or $USER or $LNAME or - $USERNAME) +"@full.hostname". + Abort if no username is found, to force specifying the commit user + with line option or repo hgrc. """ user = os.environ.get("HGUSER") if user is None: user = self.config("ui", "username") if user is None: user = os.environ.get("EMAIL") - if user is None: - try: - user = '%s@%s' % (util.getuser(), socket.getfqdn()) - except KeyError: - raise util.Abort(_("Please specify a username.")) + if not user: + self.status(_("Please choose a commit username to be recorded " + "in the changelog via\ncommand line option " + '(-u "First Last "), in the\n' + "configuration files (hgrc), or by setting the " + "EMAIL environment variable.\n\n")) + raise util.Abort(_("No commit username specified!")) return user def shortuser(self, user): diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -519,20 +519,6 @@ def is_win_9x(): except AttributeError: return os.name == 'nt' and 'command' in os.environ.get('comspec', '') -getuser_fallback = None - -def getuser(): - '''return name of current user''' - try: - return getpass.getuser() - except ImportError: - # import of pwd will fail on windows - try fallback - if getuser_fallback: - return getuser_fallback() - # raised if win32api not available - raise Abort(_('user name not available - set USERNAME ' - 'environment variable')) - # Platform specific variants if os.name == 'nt': demandload(globals(), "msvcrt") diff --git a/mercurial/util_win32.py b/mercurial/util_win32.py --- a/mercurial/util_win32.py +++ b/mercurial/util_win32.py @@ -297,5 +297,3 @@ class posixfile_nt(object): win32file.SetEndOfFile(self.handle) except pywintypes.error, err: raise WinIOError(err) - -getuser_fallback = win32api.GetUserName diff --git a/mercurial/verify.py b/mercurial/verify.py --- a/mercurial/verify.py +++ b/mercurial/verify.py @@ -48,7 +48,7 @@ def verify(repo): repo.ui.status(_("checking changesets\n")) checksize(repo.changelog, "changelog") - for i in range(repo.changelog.count()): + for i in xrange(repo.changelog.count()): changesets += 1 n = repo.changelog.node(i) l = repo.changelog.linkrev(n) @@ -81,7 +81,7 @@ def verify(repo): checkversion(repo.manifest, "manifest") checksize(repo.manifest, "manifest") - for i in range(repo.manifest.count()): + for i in xrange(repo.manifest.count()): n = repo.manifest.node(i) l = repo.manifest.linkrev(n) @@ -142,7 +142,7 @@ def verify(repo): nodes = {nullid: 1} seen = {} - for i in range(fl.count()): + for i in xrange(fl.count()): revisions += 1 n = fl.node(i) diff --git a/templates/gitweb/changeset.tmpl b/templates/gitweb/changeset.tmpl --- a/templates/gitweb/changeset.tmpl +++ b/templates/gitweb/changeset.tmpl @@ -1,5 +1,5 @@ #header# -#repo|escape#: Changeset +{repo|escape}: changeset {rev}:{node|short} @@ -20,7 +20,7 @@ - + #parent%changesetparent# #child%changesetchild# diff --git a/templates/gitweb/fileannotate.tmpl b/templates/gitweb/fileannotate.tmpl --- a/templates/gitweb/fileannotate.tmpl +++ b/templates/gitweb/fileannotate.tmpl @@ -1,5 +1,5 @@ #header# -#repo|escape#: Annotate +{repo|escape}: {file|escape}@{node|short} (annotated) diff --git a/templates/gitweb/filerevision.tmpl b/templates/gitweb/filerevision.tmpl --- a/templates/gitweb/filerevision.tmpl +++ b/templates/gitweb/filerevision.tmpl @@ -1,5 +1,5 @@ #header# -#repo|escape#: File revision +{repo|escape}: {file|escape}@{node|short} diff --git a/templates/gitweb/footer.tmpl b/templates/gitweb/footer.tmpl --- a/templates/gitweb/footer.tmpl +++ b/templates/gitweb/footer.tmpl @@ -1,6 +1,8 @@ diff --git a/templates/gitweb/index.tmpl b/templates/gitweb/index.tmpl --- a/templates/gitweb/index.tmpl +++ b/templates/gitweb/index.tmpl @@ -18,6 +18,7 @@ #entries%indexentry#
author#author|obfuscate#
#date|date# (#date|age# ago)
changeset#node|short#
changeset {rev}{node|short}
manifest#node|short#
diff --git a/templates/gitweb/map b/templates/gitweb/map --- a/templates/gitweb/map +++ b/templates/gitweb/map @@ -28,15 +28,15 @@ difflineminus = '
#line|escape#
' diffline = '
#line|escape#
' changelogparent = 'parent #rev#:#node|short#' -changesetparent = 'parent#node|short#' -filerevparent = 'parent:{rename%filerename}{node|short}' +changesetparent = 'parent {rev}{node|short}' +filerevparent = 'parent {rev}:{rename%filerename}{node|short}' filerename = '{file|escape}@' filelogrename = '| base' -fileannotateparent = 'parent:{rename%filerename}{node|short}' +fileannotateparent = 'parent {rev}:{rename%filerename}{node|short}' changelogchild = 'child #rev#:#node|short#' -changesetchild = 'child#node|short#' -filerevchild = 'child:#node|short#' -fileannotatechild = 'child:#node|short#' +changesetchild = 'child {rev}{node|short}' +filerevchild = 'child {rev}:{node|short}' +fileannotatechild = 'child {rev}:{node|short}' tags = tags.tmpl tagentry = '#date|age# ago#tag|escape#changeset | changelog | manifest' diffblock = '
#lines#
' diff --git a/templates/map-cmdline.default b/templates/map-cmdline.default --- a/templates/map-cmdline.default +++ b/templates/map-cmdline.default @@ -1,6 +1,10 @@ -changeset = 'changeset: {rev}:{node|short}\n{tags}{short_parents}user: {author}\ndate: {date|date}\nsummary: {desc|firstline}\n\n' +changeset = 'changeset: {rev}:{node|short}\n{branches}{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}{file_copies}description:\n{desc|strip}\n\n\n' +changeset_verbose = 'changeset: {rev}:{node|short}\n{branches}{tags}{parents}{manifest}user: {author}\ndate: {date|date}\n{files}{file_adds}{file_dels}{file_copies}description:\n{desc|strip}\n\n\n' +changeset_debug = 'changeset: {rev}:{node}\n{branches}{tags}{parents}{manifest}user: {author}\ndate: {date|date}\n{files}{file_adds}{file_dels}{file_copies}{extras}description:\n{desc|strip}\n\n\n' +start_files = 'files: ' +file = ' {file}' +end_files = '\n' start_file_adds = 'files+: ' file_add = ' {file_add}' end_file_adds = '\n' @@ -13,4 +17,6 @@ end_file_copies = '\n' short_parent = 'parent: {rev}:{node|short}\n' parent = 'parent: {rev}:{node}\n' manifest = 'manifest: {rev}:{node}\n' +branch = 'branch: {branch}\n' tag = 'tag: {tag}\n' +extra = 'extra: {key}={value|stringescape}\n' diff --git a/templates/static/style-gitweb.css b/templates/static/style-gitweb.css --- a/templates/static/style-gitweb.css +++ b/templates/static/style-gitweb.css @@ -7,7 +7,7 @@ div.page_header a:hover { color:#880000; div.page_nav { padding:8px; } div.page_nav a:visited { color:#0000cc; } div.page_path { padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px} -div.page_footer { height:17px; padding:4px 8px; background-color: #d9d8d1; } +div.page_footer { padding:4px 8px; background-color: #d9d8d1; } div.page_footer_text { float:left; color:#555555; font-style:italic; } div.page_body { padding:8px; } div.title, a.title { diff --git a/tests/test-acl b/tests/test-acl --- a/tests/test-acl +++ b/tests/test-acl @@ -9,7 +9,7 @@ do_push() echo 'hgrc = """' sed -e 1,2d b/.hg/hgrc echo '"""' - if [ -e acl.config ]; then + if test -f acl.config; then echo 'acl.config = """' cat acl.config echo '"""' diff --git a/tests/test-bad-pull b/tests/test-bad-pull --- a/tests/test-bad-pull +++ b/tests/test-bad-pull @@ -2,7 +2,7 @@ hg clone http://localhost:20059/ copy echo $? -test -e copy || echo copy: No such file or directory +test -d copy || echo copy: No such file or directory cat > dumb.py <> c hg commit -m 'no user, no domain' -d '1300000 0' -u 'person' +echo foo > .hg/branch +hg commit -m 'new branch' -d '1400000 0' -u 'person' # make sure user/global hgrc does not affect tests echo '[ui]' > .hg/hgrc @@ -24,12 +26,15 @@ echo 'logtemplate =' >> .hg/hgrc echo 'style =' >> .hg/hgrc echo '# default style is like normal output' +echo '# normal' hg log > log.out hg log --style default > style.out diff log.out style.out +echo '# verbose' hg log -v > log.out hg log -v --style default > style.out diff log.out style.out +echo '# debug' hg log --debug > log.out hg log --debug --style default > style.out diff log.out style.out diff --git a/tests/test-command-template.out b/tests/test-command-template.out --- a/tests/test-command-template.out +++ b/tests/test-command-template.out @@ -1,28 +1,12 @@ # default style is like normal output -1c1 -< changeset: 3:10e46f2dcbf4 ---- -> changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -10c10 -< changeset: 2:97054abb4ab8 ---- -> changeset: 2:97054abb4ab824450e9164180baf491ae0078465 -18c18 -< changeset: 1:b608e9d1a3f0 ---- -> changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -29c29 -< changeset: 0:1e4e1b8f71e0 ---- -> changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -18a19 -> files: -29a31 -> files: -43a46 -> files: +# normal +# verbose +# debug # compact style works -3[tip] 10e46f2dcbf4 1970-01-16 01:06 +0000 person +4[tip] 32a18f097fcc 1970-01-17 04:53 +0000 person + new branch + +3 10e46f2dcbf4 1970-01-16 01:06 +0000 person no user, no domain 2 97054abb4ab8 1970-01-14 21:20 +0000 other @@ -34,7 +18,10 @@ 1 b608e9d1a3f0 1970-01-13 17:33 +000 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user line 1 -3[tip] 10e46f2dcbf4 1970-01-16 01:06 +0000 person +4[tip] 32a18f097fcc 1970-01-17 04:53 +0000 person + new branch + +3 10e46f2dcbf4 1970-01-16 01:06 +0000 person no user, no domain 2 97054abb4ab8 1970-01-14 21:20 +0000 other @@ -46,7 +33,10 @@ 1 b608e9d1a3f0 1970-01-13 17:33 +000 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user line 1 -3[tip]:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person +4[tip]:3,-1 32a18f097fcc 1970-01-17 04:53 +0000 person + new branch + +3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person no user, no domain 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other @@ -67,21 +57,28 @@ abort: ./t: no key named 'changeset' # error if include fails abort: template file ./q: Permission denied # include works +4 3 2 1 0 # ui.style works +4 3 2 1 0 # issue338 +1970-01-17 person + + * new branch + [32a18f097fcc] [tip] + 1970-01-16 person * c: no user, no domain - [10e46f2dcbf4] [tip] + [10e46f2dcbf4] 1970-01-14 other @@ -105,41 +102,51 @@ 1970-01-12 User Name # keys work author: person +author: person author: other@place author: A. N. Other author: User Name author--verbose: person +author--verbose: person author--verbose: other@place author--verbose: A. N. Other author--verbose: User Name author--debug: person +author--debug: person author--debug: other@place author--debug: A. N. Other author--debug: User Name +branches: foo branches: branches: branches: branches: +branches--verbose: foo branches--verbose: branches--verbose: branches--verbose: branches--verbose: +branches--debug: foo branches--debug: branches--debug: branches--debug: branches--debug: +date: 1400000.00 date: 1300000.00 date: 1200000.00 date: 1100000.00 date: 1000000.00 +date--verbose: 1400000.00 date--verbose: 1300000.00 date--verbose: 1200000.00 date--verbose: 1100000.00 date--verbose: 1000000.00 +date--debug: 1400000.00 date--debug: 1300000.00 date--debug: 1200000.00 date--debug: 1100000.00 date--debug: 1000000.00 +desc: new branch desc: no user, no domain desc: no person desc: other 1 @@ -148,6 +155,7 @@ other 2 other 3 desc: line 1 line 2 +desc--verbose: new branch desc--verbose: no user, no domain desc--verbose: no person desc--verbose: other 1 @@ -156,6 +164,7 @@ other 2 other 3 desc--verbose: line 1 line 2 +desc--debug: new branch desc--debug: no user, no domain desc--debug: no person desc--debug: other 1 @@ -168,10 +177,13 @@ file_adds: file_adds: file_adds: file_adds: +file_adds: file_adds--verbose: file_adds--verbose: file_adds--verbose: file_adds--verbose: +file_adds--verbose: +file_adds--debug: file_adds--debug: file_adds--debug: c file_adds--debug: b @@ -180,6 +192,8 @@ file_dels: file_dels: file_dels: file_dels: +file_dels: +file_dels--verbose: file_dels--verbose: file_dels--verbose: file_dels--verbose: @@ -188,14 +202,18 @@ file_dels--debug: file_dels--debug: file_dels--debug: file_dels--debug: +file_dels--debug: +files: files: c files: c files: b files: a +files--verbose: files--verbose: c files--verbose: c files--verbose: b files--verbose: a +files--debug: files--debug: c files--debug: files--debug: @@ -204,22 +222,28 @@ manifest: manifest: manifest: manifest: +manifest: manifest--verbose: manifest--verbose: manifest--verbose: manifest--verbose: +manifest--verbose: +manifest--debug: 4:90ae8dda64e1 manifest--debug: 3:cb5a1327723b manifest--debug: 2:6e0e82995c35 manifest--debug: 1:4e8d705b1e53 manifest--debug: 0:a0c8bcbbb45c +node: 32a18f097fcccf76ef282f62f8a85b3adf8d13c4 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47 node: 97054abb4ab824450e9164180baf491ae0078465 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965 node: 1e4e1b8f71e05681d422154f5421e385fec3454f +node--verbose: 32a18f097fcccf76ef282f62f8a85b3adf8d13c4 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47 node--verbose: 97054abb4ab824450e9164180baf491ae0078465 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f +node--debug: 32a18f097fcccf76ef282f62f8a85b3adf8d13c4 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47 node--debug: 97054abb4ab824450e9164180baf491ae0078465 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965 @@ -228,22 +252,28 @@ parents: parents: parents: parents: +parents: parents--verbose: parents--verbose: parents--verbose: parents--verbose: +parents--verbose: +parents--debug: 3:10e46f2dcbf4 -1:000000000000 parents--debug: 2:97054abb4ab8 -1:000000000000 parents--debug: 1:b608e9d1a3f0 -1:000000000000 parents--debug: 0:1e4e1b8f71e0 -1:000000000000 parents--debug: -1:000000000000 -1:000000000000 +rev: 4 rev: 3 rev: 2 rev: 1 rev: 0 +rev--verbose: 4 rev--verbose: 3 rev--verbose: 2 rev--verbose: 1 rev--verbose: 0 +rev--debug: 4 rev--debug: 3 rev--debug: 2 rev--debug: 1 @@ -252,43 +282,54 @@ tags: tip tags: tags: tags: +tags: tags--verbose: tip tags--verbose: tags--verbose: tags--verbose: +tags--verbose: tags--debug: tip tags--debug: tags--debug: tags--debug: +tags--debug: # filters work + place place hostname person +person other A. N. Other User Name person +person other other user +Sat Jan 17 04:53:20 1970 +0000 Fri Jan 16 01:06:40 1970 +0000 Wed Jan 14 21:20:00 1970 +0000 Tue Jan 13 17:33:20 1970 +0000 Mon Jan 12 13:46:40 1970 +0000 +1970-01-17 04:53 +0000 1970-01-16 01:06 +0000 1970-01-14 21:20 +0000 1970-01-13 17:33 +0000 1970-01-12 13:46 +0000 +Sat, 17 Jan 1970 04:53:20 +0000 Fri, 16 Jan 1970 01:06:40 +0000 Wed, 14 Jan 1970 21:20:00 +0000 Tue, 13 Jan 1970 17:33:20 +0000 Mon, 12 Jan 1970 13:46:40 +0000 +new branch no user, no domain no person other 1 line 1 +32a18f097fcc 10e46f2dcbf4 97054abb4ab8 b608e9d1a3f0 diff --git a/tests/test-committer b/tests/test-committer --- a/tests/test-committer +++ b/tests/test-committer @@ -10,3 +10,17 @@ touch asdf hg add asdf hg commit -d '1000000 0' -m commit-1 hg tip + +unset EMAIL +echo 1 > asdf +hg commit -d '1000000 0' -m commit-1 +hg commit -d '1000000 0' -u "foo@bar.com" -m commit-1 +hg tip +echo "[ui]" >> .hg/hgrc +echo "username = foobar " >> .hg/hgrc +echo 12 > asdf +hg commit -d '1000000 0' -m commit-1 +hg tip +echo 1 > asdf +hg commit -d '1000000 0' -u "foo@bar.com" -m commit-1 +hg tip diff --git a/tests/test-committer.out b/tests/test-committer.out --- a/tests/test-committer.out +++ b/tests/test-committer.out @@ -4,3 +4,28 @@ user: My Name "), in the +configuration files (hgrc), or by setting the EMAIL environment variable. + +abort: No commit username specified! +transaction abort! +rollback completed +changeset: 1:2becd0bae6e6 +tag: tip +user: foo@bar.com +date: Mon Jan 12 13:46:40 1970 +0000 +summary: commit-1 + +changeset: 2:7a0176714f78 +tag: tip +user: foobar +date: Mon Jan 12 13:46:40 1970 +0000 +summary: commit-1 + +changeset: 3:f9b58c5a6352 +tag: tip +user: foo@bar.com +date: Mon Jan 12 13:46:40 1970 +0000 +summary: commit-1 + diff --git a/tests/test-empty-dir b/tests/test-empty-dir --- a/tests/test-empty-dir +++ b/tests/test-empty-dir @@ -11,6 +11,6 @@ hg commit -m "second" -d "1000000 0" sub cat sub/b hg co 0 cat sub/b 2>/dev/null || echo "sub/b not present" -test -e sub || echo "sub not present" +test -d sub || echo "sub not present" true diff --git a/tests/test-help.out b/tests/test-help.out --- a/tests/test-help.out +++ b/tests/test-help.out @@ -195,6 +195,9 @@ show changed files in the working direct files that match are shown. Files that are clean or ignored, are not listed unless -c (clean), -i (ignored) or -A is given. + If one revision is given, it is used as the base revision. + If two revisions are given, the difference between them is shown. + The codes used to show the status of files are: M = modified A = added @@ -220,6 +223,7 @@ options: -n --no-status hide status prefix -C --copies show source of copied files -0 --print0 end filenames with NUL, for use with xargs + --rev show difference from revision -I --include include names matching the given patterns -X --exclude exclude names matching the given patterns hg status [OPTION]... [FILE]... diff --git a/tests/test-mq b/tests/test-mq --- a/tests/test-mq +++ b/tests/test-mq @@ -165,11 +165,13 @@ cd .. hg qrefresh hg qnew -mbar bar echo foo > foo -hg add foo +echo bar > bar +hg add foo bar hg qrefresh hg qpop -a echo bar > foo hg qpush -a +hg st cat >>$HGRCPATH <