diff --git a/contrib/bash_completion b/contrib/bash_completion index f0b16dde4d..6d8d762d85 100644 --- a/contrib/bash_completion +++ b/contrib/bash_completion @@ -1,4 +1,4 @@ -# bash completion for the Mercurial distributed SCM +# bash completion for the Mercurial distributed SCM -*- sh -*- # Docs: # @@ -82,7 +82,7 @@ _hg_repos() _hg_status() { - local files="$(_hg_cmd status -n$1 .)" + local files="$(_hg_cmd status -n$1 "glob:$cur**")" local IFS=$'\n' compopt -o filenames 2>/dev/null COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur")) @@ -255,7 +255,7 @@ _hg_command_specific() _hg_status "mar" ;; remove) - _hg_status "d" + _hg_status "mcd" ;; forget) _hg_status "a" diff --git a/mercurial/commands.py b/mercurial/commands.py index cf6fd8f66c..3943cf1397 100644 --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -808,8 +808,15 @@ def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, scmutil.checknewlabel(repo, mark, 'bookmark') return mark - def checkconflict(repo, mark, force=False): + def checkconflict(repo, mark, force=False, target=None): if mark in marks and not force: + if target: + anc = repo.changelog.ancestors([repo[target].rev()]) + bmctx = repo[marks[mark]] + if bmctx.rev() in anc: + ui.status(_("moving bookmark '%s' forward from %s\n") % + (mark, short(bmctx.node()))) + return raise util.Abort(_("bookmark '%s' already exists " "(use -f to force)") % mark) if ((mark in repo.branchmap() or mark == repo.dirstate.branch()) @@ -852,11 +859,11 @@ def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, if inactive and mark == repo._bookmarkcurrent: bookmarks.setcurrent(repo, None) return - checkconflict(repo, mark, force) + tgt = cur if rev: - marks[mark] = scmutil.revsingle(repo, rev).node() - else: - marks[mark] = cur + tgt = scmutil.revsingle(repo, rev).node() + checkconflict(repo, mark, force, tgt) + marks[mark] = tgt if not inactive and cur == marks[mark]: bookmarks.setcurrent(repo, mark) marks.write() diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py index 8073c173ab..b763408319 100644 --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -816,6 +816,19 @@ def archive(web, req, tmpl): if cnode == key or key == 'tip': arch_version = short(cnode) name = "%s-%s" % (reponame, arch_version) + + ctx = webutil.changectx(web.repo, req) + pats = [] + file = req.form.get('file', None) + if file: + file = file[0] + patandfile = file.split(':') + if len(patandfile) > 1 and patandfile[0].lower() in ('glob', 'relglob', + 'path', 'relpath', 're', 'relre', 'set'): + msg = 'Archive pattern not allowed: %s' % file + raise ErrorResponse(HTTP_FORBIDDEN, msg) + pats = ['path:' + file] + mimetype, artype, extension, encoding = web.archive_specs[type_] headers = [ ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension)) @@ -825,9 +838,9 @@ def archive(web, req, tmpl): req.headers.extend(headers) req.respond(HTTP_OK, mimetype) - ctx = webutil.changectx(web.repo, req) + matchfn = scmutil.match(ctx, pats, default='path') archival.archive(web.repo, req, cnode, artype, prefix=name, - matchfn=scmutil.match(ctx, []), + matchfn=matchfn, subrepos=web.configbool("web", "archivesubrepos")) return [] diff --git a/mercurial/templates/coal/map b/mercurial/templates/coal/map index e324888907..99f64bbf25 100644 --- a/mercurial/templates/coal/map +++ b/mercurial/templates/coal/map @@ -224,7 +224,7 @@ indexarchiveentry = '{type|escape} + {type|escape} ' notfound = ../paper/notfound.tmpl error = ../paper/error.tmpl diff --git a/mercurial/templates/gitweb/map b/mercurial/templates/gitweb/map index f4b80624d3..f789d67d31 100644 --- a/mercurial/templates/gitweb/map +++ b/mercurial/templates/gitweb/map @@ -289,7 +289,7 @@ filelogentry = '