--- a/contrib/zsh_completion Tue Oct 24 13:46:04 2006 -0500
+++ b/contrib/zsh_completion Tue Oct 24 13:42:21 2006 -0700
@@ -14,29 +14,50 @@
local curcontext="$curcontext" state line
typeset -A opt_args
-local subcmds repos tags newFiles addedFiles includeExclude commitMessage
+local repos newFiles addedFiles includeExclude commitMessage
+local ridx _hgroot
+
+# FIXME: why isn't opt_args available?
+[[ -d .hg ]] && _hgroot="$PWD"
+ridx=$words[(i)-R]
+(( $ridx < $#words )) && _hgroot="${words[$ridx+1]}"
-_mq_state () {
+# hg dispatch (borrowed from _cvs)
+(( $+functions[_hg_cmd] )) ||
+_hg_cmd () {
+ _call_program hg hg -R "$_hgroot" "$@"
+}
+
+(( $+functions[_hg_state] )) ||
+_hg_state () {
case "$state" in
+ (tags)
+ compadd $(_hg_cmd tags 2> /dev/null |
+ sed -e 's/[0-9]*:[a-f0-9]*$//; s/ *$//')
+ ;;
(qapplied)
- compadd $(hg qapplied)
+ compadd $(_hg_cmd qapplied)
;;
(qunapplied)
- compadd $(hg qunapplied)
+ compadd $(_hg_cmd 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' \
+(( $+_hg_commands )) ||
+_hg_commands=($(hg -v help | sed -e '1,/^list of commands:/d' \
-e '/^global options:/,$d' -e '/^ [^ ]/!d; s/[,:].*//g;'))
# A lot of commands have these arguments
includeExclude=(
- '*-I-[include names matching the given patterns]:dir:_files -W $(hg root) -/'
- '*--include-[include names matching the given patterns]:dir:_files -W $(hg root) -/'
- '*-X-[exclude names matching the given patterns]:dir:_files -W $(hg root) -/'
- '*--exclude-[exclude names matching the given patterns]:dir:_files -W $(hg root) -/')
+ '*-I-[include names matching the given patterns]:dir:_files -W $(_hg_cmd root) -/'
+ '*--include-[include names matching the given patterns]:dir:_files -W $(_hg_cmd root) -/'
+ '*-X-[exclude names matching the given patterns]:dir:_files -W $(_hg_cmd root) -/'
+ '*--exclude-[exclude names matching the given patterns]:dir:_files -W $(_hg_cmd root) -/')
+
+styleOpts=(
+ '--style[display using template map file]:'
+ '--template[display with template]:')
commitMessage=(
'(-m --message -l --logfile --edit)-e[edit commit message]'
@@ -68,7 +89,7 @@
'*::command:->subcmd' && return 0
if (( CURRENT == 1 )); then
- _wanted commands expl 'hg command' compadd -a subcmds
+ _wanted commands expl 'hg command' compadd -a _hg_commands
return
fi
service="$words[1]"
@@ -77,7 +98,7 @@
case $service in
(add)
- newFiles=(${(ps:\0:)"$(hg status -0un .)"})
+ newFiles=(${(ps:\0:)"$(_hg_cmd status -0un .)"})
_arguments $includeExclude \
'*:file:->unknown'
_wanted files expl 'unknown files' compadd -a newFiles
@@ -89,7 +110,7 @@
;;
(forget)
- addedFiles=(${(ps:\0:)"$(hg status -0an .)"})
+ addedFiles=(${(ps:\0:)"$(_hg_cmd status -0an .)"})
_arguments $includeExclude \
'*:file:->added'
_wanted files expl 'newly added files' compadd -a addedFiles
@@ -128,8 +149,8 @@
(diff)
_arguments $includeExclude \
- '*-r[revision]:revision:($tags)' \
- '*--rev[revision]:revision:($tags)' \
+ '*-r[revision]:revision:->tags' \
+ '*--rev[revision]:revision:->tags' \
'(--text)-a[treat all files as text]' \
'(-a)--text[treat all files as text]' \
'*:file:_files'
@@ -153,10 +174,10 @@
;;
(revert)
- addedFiles=(${(ps:\0:)"$(hg status -0amrn .)"})
+ addedFiles=(${(ps:\0:)"$(_hg_cmd status -0amrn .)"})
_arguments \
- '(--rev)-r[revision to revert to]:revision:($tags)' \
- '(-r)--rev[revision to revert to]:revision:($tags)' \
+ '(--rev)-r[revision to revert to]:revision:->tags' \
+ '(-r)--rev[revision to revert to]:revision:->tags' \
'(--nonrecursive)-n[do not recurse into subdirectories]' \
'(-n)--nonrecursive[do not recurse into subdirectories]' \
'*:file:->modified'
@@ -164,7 +185,7 @@
;;
(commit|ci)
- addedFiles=(${(ps:\0:)"$(hg status -0amrn .)"})
+ addedFiles=(${(ps:\0:)"$(_hg_cmd status -0amrn .)"})
_arguments $includeExclude \
'(--addremove)-A[run addremove during commit]' \
'(-A)--addremove[run addremove during commit]' \
@@ -184,15 +205,15 @@
_arguments $includeExclude \
'(--output)-o[print output to file with formatted name]:filespec:' \
'(-o)--output[print output to file with formatted name]:filespec:' \
- '(--rev)-r[revision]:revision:($tags)' \
- '(-r)--rev[revision]:revision:($tags)' \
+ '(--rev)-r[revision]:revision:->tags' \
+ '(-r)--rev[revision]:revision:->tags' \
'*:file:_files'
;;
(annotate)
_arguments $includeExclude \
- '(--rev)-r[annotate the specified revision]:revision:($tags)' \
- '(-r)--rev[annotate the specified revision]:revision:($tags)' \
+ '(--rev)-r[annotate the specified revision]:revision:->tags' \
+ '(-r)--rev[annotate the specified revision]:revision:->tags' \
'(--text)-a[treat all files as text]' \
'(-a)--text[treat all files as text]' \
'(--user)-u[list the author]' \
@@ -206,8 +227,8 @@
(grep)
_arguments $includeExclude \
- '*-r[search in given revision range]:revision:($tags)' \
- '*--rev[search in given revision range]:revision:($tags)' \
+ '*-r[search in given revision range]:revision:->tags' \
+ '*--rev[search in given revision range]:revision:->tags' \
'--all[print all revisions with matches]' \
'(-print0)-0[end filenames with NUL, for use with xargs]' \
'(-0)--print0[end filenames with NUL, for use with xargs]' \
@@ -224,8 +245,8 @@
(locate)
_arguments $includeExclude \
- '(--rev)-r[search repository as it stood at revision]:revision:($tags)' \
- '(-r)--rev[search repository as it stood at revision]:revision:($tags)' \
+ '(--rev)-r[search repository as it stood at revision]:revision:->tags' \
+ '(-r)--rev[search repository as it stood at revision]:revision:->tags' \
'(--print0)-0[end filenames with NUL, for use with xargs]' \
'(-0)--print0[end filenames with NUL, for use with xargs]' \
'(--fullpath)-f[print complete paths]' \
@@ -234,9 +255,9 @@
;;
(log|history)
- _arguments $includeExclude \
- '*-r[show the specified revision or range]:revision:($tags)' \
- '*--rev[show the specified revision or range]:revision:($tags)' \
+ _arguments $includeExclude $styleOpts \
+ '*-r[show the specified revision or range]:revision:->tags' \
+ '*--rev[show the specified revision or range]:revision:->tags' \
'(--no-merges -M --only-merges)-m[show only merge revisions]' \
'(--no-merges -M -m)--only-merges[show only merge revisions]' \
'(--only-merges -m --no-merges)-M[do not show merge revisions]' \
@@ -258,7 +279,7 @@
'(-C --clean -m)--merge[allow merging of branches]' \
'(-m --merge --clean)-C[overwrite locally modified files]' \
'(-m --merge -C)--clean[overwrite locally modified files]' \
- '*:revision or tag:($tags)'
+ '*:revision or tag:->tags'
;;
(tag)
@@ -271,12 +292,12 @@
'(-d)--date[record datecode as commit date]:date code:' \
'(--user)-u[record user as commiter]:user:' \
'(-u)--user[record user as commiter]:user:' \
- '*:name, then revision:($tags)'
+ '*:name, then revision:->tags'
;;
(clone)
if (( CURRENT == 2 )); then
- repos=( $(hg paths | sed -e 's/^.*= //') )
+ repos=( $(_hg_cmd paths | sed -e 's/^.*= //') )
_arguments \
'(--no-update)-U[do not update the new working directory]' \
'(-U)--no-update[do not update the new working directory]' \
@@ -293,8 +314,8 @@
(rawcommit)
_arguments \
- '(--parent)-p[parent revision]:revision:($tags)' \
- '(-p)--parent[parent revision]:revision:($tags)' \
+ '(--parent)-p[parent revision]:revision:->tags' \
+ '(-p)--parent[parent revision]:revision:->tags' \
'(--date)-d[record datecode as commit date]:date code:' \
'(-d)--date[record datecode as commit date]:date code:' \
'(--user)-u[record user as commiter]:user:' \
@@ -321,7 +342,7 @@
;;
(incoming)
- _arguments \
+ _arguments $styleOpts \
'(--patch)-p[show patch]' \
'(-p)--patch[show patch]' \
'(--no-merges)-M[do not show merge revisions]' \
@@ -337,13 +358,13 @@
'(-p)--strip[directory strip option for patch (default: 1)]:count:' \
'(--force)-f[skip check for outstanding uncommitted changes]' \
'(-f)--force[skip check for outstanding uncommitted changes]' \
- '(--base)-b[base directory to read patches from]:file:_files -W $(hg root) -/' \
- '(-b)--base[base directory to read patches from]:file:_files -W $(hg root) -/' \
+ '(--base)-b[base directory to read patches from]:file:_files -W $(_hg_cmd root) -/' \
+ '(-b)--base[base directory to read patches from]:file:_files -W $(_hg_cmd root) -/' \
'*:patch file:_files'
;;
(pull)
- repos=( $(hg paths | sed -e 's/^.*= //') )
+ repos=( $(_hg_cmd paths | sed -e 's/^.*= //') )
_arguments \
'(--update)-u[update working directory to tip after pull]' \
'(-u)--update[update working directory to tip after pull]' \
@@ -355,7 +376,7 @@
;;
(outgoing)
- _arguments \
+ _arguments $styleOpts \
'(--patch)-p[show patch]' \
'(-p)--patch[show patch]' \
'(--no-merges)-M[do not show merge revisions]' \
@@ -377,7 +398,7 @@
;;
(push)
- repos=( $(hg paths | sed -e 's/^.*= //') )
+ repos=( $(_hg_cmd paths | sed -e 's/^.*= //') )
_arguments \
'(--force)-f[force push]' \
'(-f)--force[force push]' \
@@ -409,11 +430,11 @@
;;
(help)
- _wanted commands expl 'hg command' compadd -a subcmds
+ _wanted commands expl 'hg command' compadd -a _hg_commands
;;
(heads)
- _arguments \
+ _arguments $styleOpts \
'(--branches)-b[find branch info]' \
'(-b)--branches[find branch info]'
;;
@@ -427,15 +448,26 @@
;;
(manifest)
- _arguments '*:revision:($tags)'
+ _arguments '*:revision:->tags'
+ ;;
+
+ (par*)
+ _arguments $styleOpts \
+ '(--rev 1)-r[show parents of the specified rev]:revision:->tags' \
+ '(-r 1)--rev[show parents of the specified rev]:revision:->tags' \
+ '::revision:->tags'
;;
- (parents)
- _arguments '*:revision:($tags)'
+ (identify|recover|root|undo|verify|version|ct|tags)
+ # no arguments for these commands
;;
- (identify|recover|root|undo|view|verify|version|ct|tags)
- # no arguments for these commands
+ # HGK
+ (vi*)
+ _arguments \
+ '(--limit)-l[limit number of changes displayed]:' \
+ '(-l)--limit[limit number of changes displayed]:' \
+ '::revision range:->tags'
;;
# MQ commands
@@ -444,7 +476,6 @@
{-k,--keep}'[keep patch file]' \
{-r,--rev}'[revision]:applied patch:->qapplied' \
'*:unapplied patches:->qunapplied'
- _mq_state
;;
(qnew)
@@ -454,12 +485,10 @@
;;
(qpo*)
- applied=( $(hg qapplied) )
_arguments \
(1){-a,--all}'[pop all patches]' \
{-f,--force}'[forget any local changes]' \
':applied patch:->qapplied'
- _mq_state
;;
(qpu*)
@@ -467,7 +496,6 @@
(1){-a,--all}'[apply all patches]' \
{-f,--force}'[apply if the patch has rejects]' \
':unapplied patch:->qunapplied'
- _mq_state
;;
(qref*)
_arguments $commitMessage $includeExclude \
@@ -479,3 +507,5 @@
_message "unknown hg command completion: $service"
;;
esac
+
+_hg_state
--- a/hgext/mq.py Tue Oct 24 13:46:04 2006 -0500
+++ b/hgext/mq.py Tue Oct 24 13:42:21 2006 -0700
@@ -2003,6 +2003,35 @@
return tagscache
+ def branchtags(self):
+ if self.branchcache != None:
+ return self.branchcache
+
+ q = self.mq
+ if not q.applied:
+ return super(mqrepo, self).branchtags()
+
+ self.branchcache = {} # avoid recursion in changectx
+ cl = self.changelog
+ partial, last, lrev = self._readbranchcache()
+
+ qbase = cl.rev(revlog.bin(q.applied[0].rev))
+ start = lrev + 1
+ if start < qbase:
+ # update the cache (excluding the patches) and save it
+ self._updatebranchcache(partial, lrev+1, qbase)
+ self._writebranchcache(partial, cl.node(qbase-1), qbase-1)
+ start = qbase
+ # if start = qbase, the cache is as updated as it should be.
+ # if start > qbase, the cache includes (part of) the patches.
+ # we might as well use it, but we won't save it.
+
+ # update the cache up to the tip
+ self._updatebranchcache(partial, start, cl.count())
+
+ self.branchcache = partial
+ return self.branchcache
+
if repo.local():
repo.__class__ = mqrepo
repo.mq = queue(ui, repo.join(""))
--- a/mercurial/hgweb/hgweb_mod.py Tue Oct 24 13:46:04 2006 -0500
+++ b/mercurial/hgweb/hgweb_mod.py Tue Oct 24 13:42:21 2006 -0700
@@ -527,6 +527,23 @@
date = t)
parity += 1
+ def heads(**map):
+ parity = 0
+ count = 0
+
+ for node in self.repo.heads():
+ count += 1
+ if count > 10:
+ break;
+
+ ctx = self.repo.changectx(node)
+
+ yield {'parity': self.stripes(parity),
+ 'branch': ctx.branch(),
+ 'node': hex(node),
+ 'date': ctx.date()}
+ parity += 1
+
def changelist(**map):
parity = 0
cl = self.repo.changelog
@@ -560,6 +577,7 @@
self.repo.ui.config("web", "author", "unknown")), # also
lastchange = cl.read(cl.tip())[2],
tags = tagentries,
+ heads = heads,
shortlog = changelist,
node = hex(cl.tip()),
archives=self.archivelist("tip"))
--- a/mercurial/localrepo.py Tue Oct 24 13:46:04 2006 -0500
+++ b/mercurial/localrepo.py Tue Oct 24 13:42:21 2006 -0700
@@ -295,6 +295,18 @@
self.branchcache = {} # avoid recursion in changectx
+ partial, last, lrev = self._readbranchcache()
+
+ tiprev = self.changelog.count() - 1
+ if lrev != tiprev:
+ self._updatebranchcache(partial, lrev+1, tiprev+1)
+ self._writebranchcache(partial, self.changelog.tip(), tiprev)
+
+ self.branchcache = partial
+ return self.branchcache
+
+ def _readbranchcache(self):
+ partial = {}
try:
f = self.opener("branches.cache")
last, lrev = f.readline().rstrip().split(" ", 1)
@@ -303,34 +315,30 @@
self.changelog.node(lrev) == last): # sanity check
for l in f:
node, label = l.rstrip().split(" ", 1)
- self.branchcache[label] = bin(node)
+ partial[label] = bin(node)
else: # invalidate the cache
last, lrev = nullid, -1
f.close()
except IOError:
last, lrev = nullid, -1
+ return partial, last, lrev
- tip = self.changelog.count() - 1
- if lrev != tip:
- for r in xrange(lrev + 1, tip + 1):
- c = self.changectx(r)
- b = c.branch()
- if b:
- self.branchcache[b] = c.node()
- self._writebranchcache()
-
- return self.branchcache
-
- def _writebranchcache(self):
+ def _writebranchcache(self, branches, tip, tiprev):
try:
f = self.opener("branches.cache", "w")
- t = self.changelog.tip()
- f.write("%s %s\n" % (hex(t), self.changelog.count() - 1))
- for label, node in self.branchcache.iteritems():
+ f.write("%s %s\n" % (hex(tip), tiprev))
+ for label, node in branches.iteritems():
f.write("%s %s\n" % (hex(node), label))
except IOError:
pass
+ def _updatebranchcache(self, partial, start, end):
+ for r in xrange(start, end):
+ c = self.changectx(r)
+ b = c.branch()
+ if b:
+ partial[b] = c.node()
+
def lookup(self, key):
if key == '.':
key = self.dirstate.parents()[0]
--- a/templates/gitweb/map Tue Oct 24 13:46:04 2006 -0500
+++ b/templates/gitweb/map Tue Oct 24 13:42:21 2006 -0700
@@ -39,6 +39,7 @@
fileannotatechild = '<tr><td class="metatag">child {rev}:</td><td><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
tags = tags.tmpl
tagentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>#tag|escape#</b></a></td><td class="link"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}log/#node|short#{sessionvars%urlparameter}">changelog</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">manifest</a></td></tr>'
+headentry = '<tr class="parity{parity}"><td class="age"><i>{date|age} ago</i></td><td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{node|short}</td><td>{branch|escape}</td><td class="link"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> | <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> | <a href="{url}file/{node|short}{sessionvars%urlparameter}">manifest</a></td></tr>'
diffblock = '<pre>#lines#</pre>'
changelogtag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
changesettag = '<tr><td>tag</td><td>#tag|escape#</td></tr>'
--- a/templates/gitweb/summary.tmpl Tue Oct 24 13:46:04 2006 -0500
+++ b/templates/gitweb/summary.tmpl Tue Oct 24 13:42:21 2006 -0700
@@ -36,4 +36,12 @@
<tr class="light"><td colspan="3"><a class="list" href="{url}tags{sessionvars%urlparameter}">...</a></td></tr>
</table>
+<div><a class="title"
+href="#">heads</a></div>
+<table cellspacing="0">
+{heads%headentry}
+<tr class="light">
+ <td colspan="3"><a class="list" href="#">...</a></td>
+</tr>
+</table>
#footer#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-caches Tue Oct 24 13:42:21 2006 -0700
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+echo '[extensions]' >> $HGRCPATH
+echo 'hgext.mq=' >> $HGRCPATH
+
+show_branch_cache()
+{
+ branches=.hg/branches.cache
+ hg log -r tip --template 'tip: #rev#\n'
+ if [ -f $branches ]; then
+ sort $branches
+ else
+ echo No $branches
+ fi
+ if [ "$1" = 1 ]; then
+ for b in foo bar; do
+ hg log -r $b --template "branch $b: "'#rev#\n'
+ done
+ fi
+}
+
+hg init a
+cd a
+hg qinit -c
+
+echo '# mq patch on an empty repo'
+hg qnew p1
+show_branch_cache
+
+echo > pfile
+hg add pfile
+hg qrefresh -m 'patch 1'
+show_branch_cache
+
+echo
+echo '# some regular revisions'
+hg qpop
+echo foo > foo
+hg add foo
+echo foo > .hg/branch
+hg ci -m 'branch foo' -d '1000000 0'
+
+echo bar > bar
+hg add bar
+echo bar > .hg/branch
+hg ci -m 'branch bar' -d '1000000 0'
+show_branch_cache
+
+echo
+echo '# add some mq patches'
+hg qpush
+show_branch_cache
+
+hg qnew p2
+echo foo > .hg/branch
+echo foo2 >> foo
+hg qrefresh -m 'patch 2'
+show_branch_cache 1
+
+echo
+echo '# removing the cache'
+rm -f .hg/branches.cache
+show_branch_cache 1
+
+echo
+echo '# importing rev 1 (the cache now ends in one of the patches)'
+hg qimport -r 1 -n p0
+show_branch_cache 1
+hg log -r qbase --template 'qbase: #rev#\n'
+
+echo
+echo '# detect an invalid cache'
+hg qpop -a
+hg qpush -a
+show_branch_cache
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-caches.out Tue Oct 24 13:42:21 2006 -0700
@@ -0,0 +1,53 @@
+# mq patch on an empty repo
+tip: 0
+No .hg/branches.cache
+tip: 0
+No .hg/branches.cache
+
+# some regular revisions
+Patch queue now empty
+tip: 1
+3f910abad313ff802d3a23a7529433872df9b3ae 1
+3f910abad313ff802d3a23a7529433872df9b3ae bar
+9539f35bdc80732cc9a3f84e46508f1ed1ec8cff foo
+
+# add some mq patches
+applying p1
+Now at: p1
+tip: 2
+3f910abad313ff802d3a23a7529433872df9b3ae 1
+3f910abad313ff802d3a23a7529433872df9b3ae bar
+9539f35bdc80732cc9a3f84e46508f1ed1ec8cff foo
+tip: 3
+3f910abad313ff802d3a23a7529433872df9b3ae 1
+3f910abad313ff802d3a23a7529433872df9b3ae bar
+9539f35bdc80732cc9a3f84e46508f1ed1ec8cff foo
+branch foo: 3
+branch bar: 2
+
+# removing the cache
+tip: 3
+3f910abad313ff802d3a23a7529433872df9b3ae 1
+3f910abad313ff802d3a23a7529433872df9b3ae bar
+9539f35bdc80732cc9a3f84e46508f1ed1ec8cff foo
+branch foo: 3
+branch bar: 2
+
+# importing rev 1 (the cache now ends in one of the patches)
+tip: 3
+3f910abad313ff802d3a23a7529433872df9b3ae 1
+3f910abad313ff802d3a23a7529433872df9b3ae bar
+9539f35bdc80732cc9a3f84e46508f1ed1ec8cff foo
+branch foo: 3
+branch bar: 2
+qbase: 1
+
+# detect an invalid cache
+Patch queue now empty
+applying p0
+applying p1
+applying p2
+Now at: p2
+tip: 3
+9539f35bdc80732cc9a3f84e46508f1ed1ec8cff 0
+9539f35bdc80732cc9a3f84e46508f1ed1ec8cff foo