##// END OF EJS Templates
merge crew and main
Benoit Boissinot -
r18652:a5e94bee merge default
parent child Browse files
Show More
@@ -677,9 +677,26 b' class dirstate(object):'
677 # step 3: report unseen items in the dmap hash
677 # step 3: report unseen items in the dmap hash
678 if not skipstep3 and not exact:
678 if not skipstep3 and not exact:
679 visit = sorted([f for f in dmap if f not in results and matchfn(f)])
679 visit = sorted([f for f in dmap if f not in results and matchfn(f)])
680 nf = iter(visit).next
680 if unknown:
681 for st in util.statfiles([join(i) for i in visit]):
681 # unknown == True means we walked the full directory tree above.
682 results[nf()] = st
682 # So if a file is not seen it was either a) not matching matchfn
683 # b) ignored, c) missing, or d) under a symlink directory.
684 audit_path = scmutil.pathauditor(self._root)
685
686 for nf in iter(visit):
687 # Report ignored items in the dmap as long as they are not
688 # under a symlink directory.
689 if ignore(nf) and audit_path.check(nf):
690 results[nf] = util.statfiles([join(nf)])[0]
691 else:
692 # It's either missing or under a symlink directory
693 results[nf] = None
694 else:
695 # We may not have walked the full directory tree above,
696 # so stat everything we missed.
697 nf = iter(visit).next
698 for st in util.statfiles([join(i) for i in visit]):
699 results[nf()] = st
683 for s in subrepos:
700 for s in subrepos:
684 del results[s]
701 del results[s]
685 del results['.hg']
702 del results['.hg']
@@ -11,7 +11,7 b' from i18n import _, gettext'
11
11
12 _extensions = {}
12 _extensions = {}
13 _order = []
13 _order = []
14 _ignore = ['hbisect', 'bookmarks', 'parentrevspec']
14 _ignore = ['hbisect', 'bookmarks', 'parentrevspec', 'interhg']
15
15
16 def extensions():
16 def extensions():
17 for name in _order:
17 for name in _order:
@@ -1463,6 +1463,39 b' The full set of options is:'
1463 ``templates``
1463 ``templates``
1464 Where to find the HTML templates. Default is install path.
1464 Where to find the HTML templates. Default is install path.
1465
1465
1466 ``websub``
1467 ----------
1468
1469 Web substitution filter definition. You can use this section to
1470 define a set of regular expression substitution patterns which
1471 let you automatically modify the hgweb server output.
1472
1473 The default hgweb templates only apply these substitution patterns
1474 on the revision description fields. You can apply them anywhere
1475 you want when you create your own templates by adding calls to the
1476 "websub" filter (usually after calling the "escape" filter).
1477
1478 This can be used, for example, to convert issue references to links
1479 to your issue tracker, or to convert "markdown-like" syntax into
1480 HTML (see the examples below).
1481
1482 Each entry in this section names a substitution filter.
1483 The value of each entry defines the substitution expression itself.
1484 The websub expressions follow the old interhg extension syntax,
1485 which in turn imitates the Unix sed replacement syntax::
1486
1487 pattername = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
1488
1489 You can use any separator other than "/". The final "i" is optional
1490 and indicates that the search must be case insensitive.
1491
1492 Examples::
1493
1494 [websub]
1495 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
1496 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
1497 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
1498
1466 ``worker``
1499 ``worker``
1467 ----------
1500 ----------
1468
1501
@@ -8,11 +8,13 b''
8
8
9 import os
9 import os
10 from mercurial import ui, hg, hook, error, encoding, templater, util, repoview
10 from mercurial import ui, hg, hook, error, encoding, templater, util, repoview
11 from mercurial.templatefilters import websub
12 from mercurial.i18n import _
11 from common import get_stat, ErrorResponse, permhooks, caching
13 from common import get_stat, ErrorResponse, permhooks, caching
12 from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST
14 from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST
13 from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR
15 from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR
14 from request import wsgirequest
16 from request import wsgirequest
15 import webcommands, protocol, webutil
17 import webcommands, protocol, webutil, re
16
18
17 perms = {
19 perms = {
18 'changegroup': 'pull',
20 'changegroup': 'pull',
@@ -73,6 +75,7 b' class hgweb(object):'
73 # a repo owner may set web.templates in .hg/hgrc to get any file
75 # a repo owner may set web.templates in .hg/hgrc to get any file
74 # readable by the user running the CGI script
76 # readable by the user running the CGI script
75 self.templatepath = self.config('web', 'templates')
77 self.templatepath = self.config('web', 'templates')
78 self.websubtable = self.loadwebsub()
76
79
77 # The CGI scripts are often run by a user different from the repo owner.
80 # The CGI scripts are often run by a user different from the repo owner.
78 # Trust the settings from the .hg/hgrc files by default.
81 # Trust the settings from the .hg/hgrc files by default.
@@ -258,6 +261,47 b' class hgweb(object):'
258 return ['']
261 return ['']
259 return tmpl('error', error=inst.message)
262 return tmpl('error', error=inst.message)
260
263
264 def loadwebsub(self):
265 websubtable = []
266 websubdefs = self.repo.ui.configitems('websub')
267 # we must maintain interhg backwards compatibility
268 websubdefs += self.repo.ui.configitems('interhg')
269 for key, pattern in websubdefs:
270 # grab the delimiter from the character after the "s"
271 unesc = pattern[1]
272 delim = re.escape(unesc)
273
274 # identify portions of the pattern, taking care to avoid escaped
275 # delimiters. the replace format and flags are optional, but
276 # delimiters are required.
277 match = re.match(
278 r'^s%s(.+)(?:(?<=\\\\)|(?<!\\))%s(.*)%s([ilmsux])*$'
279 % (delim, delim, delim), pattern)
280 if not match:
281 self.repo.ui.warn(_("websub: invalid pattern for %s: %s\n")
282 % (key, pattern))
283 continue
284
285 # we need to unescape the delimiter for regexp and format
286 delim_re = re.compile(r'(?<!\\)\\%s' % delim)
287 regexp = delim_re.sub(unesc, match.group(1))
288 format = delim_re.sub(unesc, match.group(2))
289
290 # the pattern allows for 6 regexp flags, so set them if necessary
291 flagin = match.group(3)
292 flags = 0
293 if flagin:
294 for flag in flagin.upper():
295 flags |= re.__dict__[flag]
296
297 try:
298 regexp = re.compile(regexp, flags)
299 websubtable.append((regexp, format))
300 except re.error:
301 self.repo.ui.warn(_("websub: invalid regexp for %s: %s\n")
302 % (key, regexp))
303 return websubtable
304
261 def templater(self, req):
305 def templater(self, req):
262
306
263 # determine scheme, port and server name
307 # determine scheme, port and server name
@@ -311,9 +355,13 b' class hgweb(object):'
311 or req.env.get('REPO_NAME')
355 or req.env.get('REPO_NAME')
312 or req.url.strip('/') or self.repo.root)
356 or req.url.strip('/') or self.repo.root)
313
357
358 def websubfilter(text):
359 return websub(text, self.websubtable)
360
314 # create the templater
361 # create the templater
315
362
316 tmpl = templater.templater(mapfile,
363 tmpl = templater.templater(mapfile,
364 filters={"websub": websubfilter},
317 defaults={"url": req.url,
365 defaults={"url": req.url,
318 "logourl": logourl,
366 "logourl": logourl,
319 "logoimg": logoimg,
367 "logoimg": logoimg,
@@ -184,6 +184,13 b' class pathauditor(object):'
184 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
184 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
185 self.auditeddir.update(prefixes)
185 self.auditeddir.update(prefixes)
186
186
187 def check(self, path):
188 try:
189 self(path)
190 return True
191 except (OSError, util.Abort):
192 return False
193
187 class abstractvfs(object):
194 class abstractvfs(object):
188 """Abstract base class; cannot be instantiated"""
195 """Abstract base class; cannot be instantiated"""
189
196
@@ -745,21 +752,14 b' def addremove(repo, pats=[], opts={}, dr'
745 ctx = repo[None]
752 ctx = repo[None]
746 walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False)
753 walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False)
747 for abs in sorted(walkresults):
754 for abs in sorted(walkresults):
748 good = True
749 try:
750 audit_path(abs)
751 except (OSError, util.Abort):
752 good = False
753
754 st = walkresults[abs]
755 st = walkresults[abs]
755 dstate = repo.dirstate[abs]
756 dstate = repo.dirstate[abs]
756 if good and dstate == '?':
757 if dstate == '?' and audit_path.check(abs):
757 unknown.append(abs)
758 unknown.append(abs)
758 if repo.ui.verbose or not m.exact(abs):
759 if repo.ui.verbose or not m.exact(abs):
759 rel = m.rel(abs)
760 rel = m.rel(abs)
760 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
761 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
761 elif (dstate != 'r' and
762 elif (dstate != 'r' and (not st or
762 (not good or not st or
763 (stat.S_ISDIR(st.st_mode) and not stat.S_ISLNK(st.st_mode)))):
763 (stat.S_ISDIR(st.st_mode) and not stat.S_ISLNK(st.st_mode)))):
764 deleted.append(abs)
764 deleted.append(abs)
765 if repo.ui.verbose or not m.exact(abs):
765 if repo.ui.verbose or not m.exact(abs):
@@ -391,6 +391,15 b' filters = {'
391 "xmlescape": xmlescape,
391 "xmlescape": xmlescape,
392 }
392 }
393
393
394 def websub(text, websubtable):
395 """:websub: Any text. Only applies to hgweb. Applies the regular
396 expression replacements defined in the websub section.
397 """
398 if websubtable:
399 for regexp, format in websubtable:
400 text = regexp.sub(format, text)
401 return text
402
394 def fillfunc(context, mapping, args):
403 def fillfunc(context, mapping, args):
395 if not (1 <= len(args) <= 2):
404 if not (1 <= len(args) <= 2):
396 raise error.ParseError(_("fill expects one or two arguments"))
405 raise error.ParseError(_("fill expects one or two arguments"))
@@ -8,7 +8,7 b''
8 <i>{author|obfuscate} [{date|rfc822date}] rev {rev}</i><br/>
8 <i>{author|obfuscate} [{date|rfc822date}] rev {rev}</i><br/>
9 </div>
9 </div>
10 <div class="log_body">
10 <div class="log_body">
11 {desc|strip|escape|addbreaks|nonempty}
11 {desc|strip|escape|websub|addbreaks|nonempty}
12 <br/>
12 <br/>
13 <br/>
13 <br/>
14 </div>
14 </div>
@@ -41,7 +41,7 b' changeset |'
41 </table></div>
41 </table></div>
42
42
43 <div class="page_body">
43 <div class="page_body">
44 {desc|strip|escape|addbreaks|nonempty}
44 {desc|strip|escape|websub|addbreaks|nonempty}
45 </div>
45 </div>
46 <div class="list_head"></div>
46 <div class="list_head"></div>
47 <div class="title_text">
47 <div class="title_text">
@@ -56,7 +56,7 b' annotate |'
56 </div>
56 </div>
57
57
58 <div class="page_path">
58 <div class="page_path">
59 {desc|strip|escape|addbreaks|nonempty}
59 {desc|strip|escape|websub|addbreaks|nonempty}
60 </div>
60 </div>
61 <div class="page_body">
61 <div class="page_body">
62 <table>
62 <table>
@@ -56,7 +56,7 b' file |'
56 </div>
56 </div>
57
57
58 <div class="page_path">
58 <div class="page_path">
59 {desc|strip|escape|addbreaks|nonempty}
59 {desc|strip|escape|websub|addbreaks|nonempty}
60 </div>
60 </div>
61
61
62 <div class="page_body">
62 <div class="page_body">
@@ -2,5 +2,5 b''
2 <ul class="changelog-entry">
2 <ul class="changelog-entry">
3 <li class="age">{date|rfc822date}</li>
3 <li class="age">{date|rfc822date}</li>
4 <li>by <span class="name">{author|obfuscate}</span> <span class="revdate">[{date|rfc822date}] rev {rev}</span></li>
4 <li>by <span class="name">{author|obfuscate}</span> <span class="revdate">[{date|rfc822date}] rev {rev}</span></li>
5 <li class="description">{desc|strip|escape|addbreaks|nonempty}</li>
5 <li class="description">{desc|strip|escape|websub|addbreaks|nonempty}</li>
6 </ul>
6 </ul>
@@ -52,7 +52,7 b''
52 {child%changesetchild}
52 {child%changesetchild}
53 </dl>
53 </dl>
54
54
55 <p class="description">{desc|strip|escape|addbreaks|nonempty}</p>
55 <p class="description">{desc|strip|escape|websub|addbreaks|nonempty}</p>
56
56
57 <table>
57 <table>
58 {files}
58 {files}
@@ -57,7 +57,7 b''
57 <dd>{permissions|permissions}</dd>
57 <dd>{permissions|permissions}</dd>
58 </dl>
58 </dl>
59
59
60 <p class="description">{desc|strip|escape|addbreaks|nonempty}</p>
60 <p class="description">{desc|strip|escape|websub|addbreaks|nonempty}</p>
61
61
62 <table class="annotated">
62 <table class="annotated">
63 {annotate%annotateline}
63 {annotate%annotateline}
@@ -57,7 +57,7 b''
57 <dd>{permissions|permissions}</dd>
57 <dd>{permissions|permissions}</dd>
58 </dl>
58 </dl>
59
59
60 <p class="description">{desc|strip|escape|addbreaks|nonempty}</p>
60 <p class="description">{desc|strip|escape|websub|addbreaks|nonempty}</p>
61
61
62 <div class="source">
62 <div class="source">
63 {text%fileline}
63 {text%fileline}
@@ -40,7 +40,7 b''
40 files, or words in the commit message</div>
40 files, or words in the commit message</div>
41 </form>
41 </form>
42
42
43 <div class="description">{desc|strip|escape|nonempty}</div>
43 <div class="description">{desc|strip|escape|websub|nonempty}</div>
44
44
45 <table id="changesetEntry">
45 <table id="changesetEntry">
46 <tr>
46 <tr>
@@ -46,7 +46,7 b''
46 files, or words in the commit message</div>
46 files, or words in the commit message</div>
47 </form>
47 </form>
48
48
49 <div class="description">{desc|strip|escape|nonempty}</div>
49 <div class="description">{desc|strip|escape|websub|nonempty}</div>
50
50
51 <table id="changesetEntry">
51 <table id="changesetEntry">
52 <tr>
52 <tr>
@@ -45,7 +45,7 b''
45 files, or words in the commit message</div>
45 files, or words in the commit message</div>
46 </form>
46 </form>
47
47
48 <div class="description">{desc|strip|escape|nonempty}</div>
48 <div class="description">{desc|strip|escape|websub|nonempty}</div>
49
49
50 <table id="changesetEntry">
50 <table id="changesetEntry">
51 <tr>
51 <tr>
@@ -45,7 +45,7 b''
45 files, or words in the commit message</div>
45 files, or words in the commit message</div>
46 </form>
46 </form>
47
47
48 <div class="description">{desc|strip|escape|nonempty}</div>
48 <div class="description">{desc|strip|escape|websub|nonempty}</div>
49
49
50 <table id="changesetEntry">
50 <table id="changesetEntry">
51 <tr>
51 <tr>
@@ -44,7 +44,7 b''
44 files, or words in the commit message</div>
44 files, or words in the commit message</div>
45 </form>
45 </form>
46
46
47 <div class="description">{desc|strip|escape|nonempty}</div>
47 <div class="description">{desc|strip|escape|websub|nonempty}</div>
48
48
49 <table id="changesetEntry">
49 <table id="changesetEntry">
50 <tr>
50 <tr>
@@ -39,7 +39,7 b''
39 </tr>
39 </tr>
40 <tr>
40 <tr>
41 <th class="description">description:</th>
41 <th class="description">description:</th>
42 <td class="description">{desc|strip|escape|addbreaks|nonempty}</td>
42 <td class="description">{desc|strip|escape|websub|addbreaks|nonempty}</td>
43 </tr>
43 </tr>
44 </table>
44 </table>
45
45
@@ -38,7 +38,7 b''
38 </tr>
38 </tr>
39 <tr>
39 <tr>
40 <td class="metatag">description:</td>
40 <td class="metatag">description:</td>
41 <td>{desc|strip|escape|addbreaks|nonempty}</td>
41 <td>{desc|strip|escape|websub|addbreaks|nonempty}</td>
42 </tr>
42 </tr>
43 </table>
43 </table>
44
44
@@ -36,7 +36,7 b''
36 <td>{permissions|permissions}</td></tr>
36 <td>{permissions|permissions}</td></tr>
37 <tr>
37 <tr>
38 <td class="metatag">description:</td>
38 <td class="metatag">description:</td>
39 <td>{desc|strip|escape|addbreaks|nonempty}</td>
39 <td>{desc|strip|escape|websub|addbreaks|nonempty}</td>
40 </tr>
40 </tr>
41 </table>
41 </table>
42
42
@@ -149,6 +149,10 b' directory moved and symlinked'
149 adding foo/a
149 adding foo/a
150 $ mv foo bar
150 $ mv foo bar
151 $ ln -s bar foo
151 $ ln -s bar foo
152 $ hg status
153 ! foo/a
154 ? bar/a
155 ? foo
152
156
153 now addremove should remove old files
157 now addremove should remove old files
154
158
@@ -5,11 +5,15 b''
5
5
6 $ cat > .hg/hgrc <<EOF
6 $ cat > .hg/hgrc <<EOF
7 > [extensions]
7 > [extensions]
8 > # this is only necessary to check that the mapping from
9 > # interhg to websub works
8 > interhg =
10 > interhg =
9 >
11 >
12 > [websub]
13 > issues = s|Issue(\d+)|<a href="http://bts.example.org/issue\1">Issue\1</a>|
14 >
10 > [interhg]
15 > [interhg]
11 > issues = s|Issue(\d+)|<a href="http://bts.example.org/issue\1">Issue\1</a>|
16 > # check that we maintain some interhg backwards compatibility...
12 >
13 > # yes, 'x' is a weird delimiter...
17 > # yes, 'x' is a weird delimiter...
14 > markbugs = sxbugx<i class="\x">bug</i>x
18 > markbugs = sxbugx<i class="\x">bug</i>x
15 > EOF
19 > EOF
@@ -23,9 +27,8 b''
23
27
24 log
28 log
25
29
26 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '' | grep bts
30 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT "rev/tip" | grep bts
27 <td class="description"><a href="/rev/1b0e7ece6bd6"><a href="http://bts.example.org/issue123">Issue123</a>: fixed the <i class="x">bug</i>!</a><span class="branchhead">default</span> <span class="tag">tip</span> </td>
31 <div class="description"><a href="http://bts.example.org/issue123">Issue123</a>: fixed the <i class="x">bug</i>!</div>
28
29 errors
32 errors
30
33
31 $ cat errors.log
34 $ cat errors.log
General Comments 0
You need to be logged in to leave comments. Login now