Show More
@@ -1,4 +1,4 b'' | |||||
1 | # bash completion for the Mercurial distributed SCM |
|
1 | # bash completion for the Mercurial distributed SCM -*- sh -*- | |
2 |
|
2 | |||
3 | # Docs: |
|
3 | # Docs: | |
4 | # |
|
4 | # | |
@@ -82,7 +82,7 b' shopt -s extglob' | |||||
82 |
|
82 | |||
83 | _hg_status() |
|
83 | _hg_status() | |
84 | { |
|
84 | { | |
85 |
local files="$(_hg_cmd status -n$1 |
|
85 | local files="$(_hg_cmd status -n$1 "glob:$cur**")" | |
86 | local IFS=$'\n' |
|
86 | local IFS=$'\n' | |
87 | compopt -o filenames 2>/dev/null |
|
87 | compopt -o filenames 2>/dev/null | |
88 | COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur")) |
|
88 | COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur")) | |
@@ -255,7 +255,7 b' shopt -s extglob' | |||||
255 | _hg_status "mar" |
|
255 | _hg_status "mar" | |
256 | ;; |
|
256 | ;; | |
257 | remove) |
|
257 | remove) | |
258 | _hg_status "d" |
|
258 | _hg_status "mcd" | |
259 | ;; |
|
259 | ;; | |
260 | forget) |
|
260 | forget) | |
261 | _hg_status "a" |
|
261 | _hg_status "a" |
@@ -808,8 +808,15 b' def bookmark(ui, repo, mark=None, rev=No' | |||||
808 | scmutil.checknewlabel(repo, mark, 'bookmark') |
|
808 | scmutil.checknewlabel(repo, mark, 'bookmark') | |
809 | return mark |
|
809 | return mark | |
810 |
|
810 | |||
811 | def checkconflict(repo, mark, force=False): |
|
811 | def checkconflict(repo, mark, force=False, target=None): | |
812 | if mark in marks and not force: |
|
812 | if mark in marks and not force: | |
|
813 | if target: | |||
|
814 | anc = repo.changelog.ancestors([repo[target].rev()]) | |||
|
815 | bmctx = repo[marks[mark]] | |||
|
816 | if bmctx.rev() in anc: | |||
|
817 | ui.status(_("moving bookmark '%s' forward from %s\n") % | |||
|
818 | (mark, short(bmctx.node()))) | |||
|
819 | return | |||
813 | raise util.Abort(_("bookmark '%s' already exists " |
|
820 | raise util.Abort(_("bookmark '%s' already exists " | |
814 | "(use -f to force)") % mark) |
|
821 | "(use -f to force)") % mark) | |
815 | if ((mark in repo.branchmap() or mark == repo.dirstate.branch()) |
|
822 | if ((mark in repo.branchmap() or mark == repo.dirstate.branch()) | |
@@ -852,11 +859,11 b' def bookmark(ui, repo, mark=None, rev=No' | |||||
852 | if inactive and mark == repo._bookmarkcurrent: |
|
859 | if inactive and mark == repo._bookmarkcurrent: | |
853 | bookmarks.setcurrent(repo, None) |
|
860 | bookmarks.setcurrent(repo, None) | |
854 | return |
|
861 | return | |
855 | checkconflict(repo, mark, force) |
|
862 | tgt = cur | |
856 | if rev: |
|
863 | if rev: | |
857 |
|
|
864 | tgt = scmutil.revsingle(repo, rev).node() | |
858 | else: |
|
865 | checkconflict(repo, mark, force, tgt) | |
859 |
|
|
866 | marks[mark] = tgt | |
860 | if not inactive and cur == marks[mark]: |
|
867 | if not inactive and cur == marks[mark]: | |
861 | bookmarks.setcurrent(repo, mark) |
|
868 | bookmarks.setcurrent(repo, mark) | |
862 | marks.write() |
|
869 | marks.write() |
@@ -816,6 +816,19 b' def archive(web, req, tmpl):' | |||||
816 | if cnode == key or key == 'tip': |
|
816 | if cnode == key or key == 'tip': | |
817 | arch_version = short(cnode) |
|
817 | arch_version = short(cnode) | |
818 | name = "%s-%s" % (reponame, arch_version) |
|
818 | name = "%s-%s" % (reponame, arch_version) | |
|
819 | ||||
|
820 | ctx = webutil.changectx(web.repo, req) | |||
|
821 | pats = [] | |||
|
822 | file = req.form.get('file', None) | |||
|
823 | if file: | |||
|
824 | file = file[0] | |||
|
825 | patandfile = file.split(':') | |||
|
826 | if len(patandfile) > 1 and patandfile[0].lower() in ('glob', 'relglob', | |||
|
827 | 'path', 'relpath', 're', 'relre', 'set'): | |||
|
828 | msg = 'Archive pattern not allowed: %s' % file | |||
|
829 | raise ErrorResponse(HTTP_FORBIDDEN, msg) | |||
|
830 | pats = ['path:' + file] | |||
|
831 | ||||
819 | mimetype, artype, extension, encoding = web.archive_specs[type_] |
|
832 | mimetype, artype, extension, encoding = web.archive_specs[type_] | |
820 | headers = [ |
|
833 | headers = [ | |
821 | ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension)) |
|
834 | ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension)) | |
@@ -825,9 +838,9 b' def archive(web, req, tmpl):' | |||||
825 | req.headers.extend(headers) |
|
838 | req.headers.extend(headers) | |
826 | req.respond(HTTP_OK, mimetype) |
|
839 | req.respond(HTTP_OK, mimetype) | |
827 |
|
840 | |||
828 | ctx = webutil.changectx(web.repo, req) |
|
841 | matchfn = scmutil.match(ctx, pats, default='path') | |
829 | archival.archive(web.repo, req, cnode, artype, prefix=name, |
|
842 | archival.archive(web.repo, req, cnode, artype, prefix=name, | |
830 |
matchfn= |
|
843 | matchfn=matchfn, | |
831 | subrepos=web.configbool("web", "archivesubrepos")) |
|
844 | subrepos=web.configbool("web", "archivesubrepos")) | |
832 | return [] |
|
845 | return [] | |
833 |
|
846 |
@@ -224,7 +224,7 b' indexarchiveentry = \'<a href="{url|urles' | |||||
224 | index = ../paper/index.tmpl |
|
224 | index = ../paper/index.tmpl | |
225 | archiveentry = ' |
|
225 | archiveentry = ' | |
226 | <li> |
|
226 | <li> | |
227 | <a href="{url|urlescape}archive/{node|short}{extension|urlescape}">{type|escape}</a> |
|
227 | <a href="{url|urlescape}archive/{node|short}{extension|urlescape}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a> | |
228 | </li>' |
|
228 | </li>' | |
229 | notfound = ../paper/notfound.tmpl |
|
229 | notfound = ../paper/notfound.tmpl | |
230 | error = ../paper/error.tmpl |
|
230 | error = ../paper/error.tmpl |
@@ -289,7 +289,7 b" filelogentry = '" | |||||
289 | <td class="link"> |
|
289 | <td class="link"> | |
290 | <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> | <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> | <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> {rename%filelogrename}</td> |
|
290 | <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> | <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> | <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> {rename%filelogrename}</td> | |
291 | </tr>' |
|
291 | </tr>' | |
292 | archiveentry = ' | <a href="{url|urlescape}archive/{node|short}{extension}">{type|escape}</a> ' |
|
292 | archiveentry = ' | <a href="{url|urlescape}archive/{node|short}{extension}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a> ' | |
293 | indexentry = ' |
|
293 | indexentry = ' | |
294 | <tr class="parity{parity}"> |
|
294 | <tr class="parity{parity}"> | |
295 | <td> |
|
295 | <td> |
@@ -245,7 +245,7 b" filelogentry = '" | |||||
245 | {rename%filelogrename} |
|
245 | {rename%filelogrename} | |
246 | </td> |
|
246 | </td> | |
247 | </tr>' |
|
247 | </tr>' | |
248 | archiveentry = '<li><a href="{url|urlescape}archive/{node|short}{extension}">{type|escape}</a></li>' |
|
248 | archiveentry = '<li><a href="{url|urlescape}archive/{node|short}{extension}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a></li>' | |
249 | indexentry = ' |
|
249 | indexentry = ' | |
250 | <tr class="parity{parity}"> |
|
250 | <tr class="parity{parity}"> | |
251 | <td><a href="{url|urlescape}{sessionvars%urlparameter}">{name|escape}</a></td> |
|
251 | <td><a href="{url|urlescape}{sessionvars%urlparameter}">{name|escape}</a></td> |
@@ -232,7 +232,7 b' indexarchiveentry = \'<a href="{url|urles' | |||||
232 | index = index.tmpl |
|
232 | index = index.tmpl | |
233 | archiveentry = ' |
|
233 | archiveentry = ' | |
234 | <li> |
|
234 | <li> | |
235 | <a href="{url|urlescape}archive/{node|short}{extension|urlescape}">{type|escape}</a> |
|
235 | <a href="{url|urlescape}archive/{node|short}{extension|urlescape}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a> | |
236 | </li>' |
|
236 | </li>' | |
237 | notfound = notfound.tmpl |
|
237 | notfound = notfound.tmpl | |
238 | error = error.tmpl |
|
238 | error = error.tmpl |
@@ -69,10 +69,18 b' invalid arch type should give 404' | |||||
69 | > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) |
|
69 | > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) | |
70 | > except ImportError: |
|
70 | > except ImportError: | |
71 | > pass |
|
71 | > pass | |
72 | > node, archive = sys.argv[1:] |
|
72 | > if len(sys.argv) <= 3: | |
73 | > f = urllib2.urlopen('http://127.0.0.1:%s/?cmd=archive;node=%s;type=%s' |
|
73 | > node, archive = sys.argv[1:] | |
74 | > % (os.environ['HGPORT'], node, archive)) |
|
74 | > requeststr = 'cmd=archive;node=%s;type=%s' % (node, archive) | |
75 | > sys.stdout.write(f.read()) |
|
75 | > else: | |
|
76 | > node, archive, file = sys.argv[1:] | |||
|
77 | > requeststr = 'cmd=archive;node=%s;type=%s;file=%s' % (node, archive, file) | |||
|
78 | > try: | |||
|
79 | > f = urllib2.urlopen('http://127.0.0.1:%s/?%s' | |||
|
80 | > % (os.environ['HGPORT'], requeststr)) | |||
|
81 | > sys.stdout.write(f.read()) | |||
|
82 | > except urllib2.HTTPError, e: | |||
|
83 | > sys.stderr.write(str(e) + '\n') | |||
76 | > EOF |
|
84 | > EOF | |
77 | $ python getarchive.py "$TIP" gz | gunzip | tar tf - 2>/dev/null |
|
85 | $ python getarchive.py "$TIP" gz | gunzip | tar tf - 2>/dev/null | |
78 | test-archive-2c0277f05ed4/.hg_archival.txt |
|
86 | test-archive-2c0277f05ed4/.hg_archival.txt | |
@@ -93,6 +101,18 b' invalid arch type should give 404' | |||||
93 | testing: test-archive-2c0277f05ed4/foo OK |
|
101 | testing: test-archive-2c0277f05ed4/foo OK | |
94 | No errors detected in compressed data of archive.zip. |
|
102 | No errors detected in compressed data of archive.zip. | |
95 |
|
103 | |||
|
104 | test that we can download single directories and files | |||
|
105 | ||||
|
106 | $ python getarchive.py "$TIP" gz baz | gunzip | tar tf - 2>/dev/null | |||
|
107 | test-archive-2c0277f05ed4/baz/bletch | |||
|
108 | $ python getarchive.py "$TIP" gz foo | gunzip | tar tf - 2>/dev/null | |||
|
109 | test-archive-2c0277f05ed4/foo | |||
|
110 | ||||
|
111 | test that we reject unsafe patterns | |||
|
112 | ||||
|
113 | $ python getarchive.py "$TIP" gz relre:baz | |||
|
114 | HTTP Error 403: Archive pattern not allowed: relre:baz | |||
|
115 | ||||
96 | $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS |
|
116 | $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS | |
97 |
|
117 | |||
98 | $ hg archive -t tar test.tar |
|
118 | $ hg archive -t tar test.tar |
@@ -239,8 +239,8 b' bookmark with reserved name' | |||||
239 |
|
239 | |||
240 | bookmark with existing name |
|
240 | bookmark with existing name | |
241 |
|
241 | |||
242 |
$ hg bookmark |
|
242 | $ hg bookmark X2 | |
243 |
abort: bookmark ' |
|
243 | abort: bookmark 'X2' already exists (use -f to force) | |
244 | [255] |
|
244 | [255] | |
245 |
|
245 | |||
246 | $ hg bookmark -m Y Z |
|
246 | $ hg bookmark -m Y Z | |
@@ -279,7 +279,13 b' incompatible options' | |||||
279 |
|
279 | |||
280 | force bookmark with existing name |
|
280 | force bookmark with existing name | |
281 |
|
281 | |||
282 |
$ hg bookmark -f |
|
282 | $ hg bookmark -f X2 | |
|
283 | $ hg bookmark -fr1 X2 | |||
|
284 | ||||
|
285 | forward bookmark to descendant without --force | |||
|
286 | ||||
|
287 | $ hg bookmark Z | |||
|
288 | moving bookmark 'Z' forward from f7b1eb17ad24 | |||
283 |
|
289 | |||
284 | list bookmarks |
|
290 | list bookmarks | |
285 |
|
291 |
General Comments 0
You need to be logged in to leave comments.
Login now