##// END OF EJS Templates
merge with stable
Matt Mackall -
r23426:19ebd2f8 merge default
parent child Browse files
Show More
@@ -0,0 +1,17
1 # A dummy extension that installs an hgweb command that throws an Exception.
2
3 from mercurial.hgweb import webcommands
4
5 def raiseerror(web, req, tmpl):
6 '''Dummy web command that raises an uncaught Exception.'''
7
8 # Simulate an error after partial response.
9 if 'partialresponse' in req.form:
10 req.respond(200, 'text/plain')
11 req.write('partial content\n')
12
13 raise AttributeError('I am an uncaught error!')
14
15 def extsetup(ui):
16 setattr(webcommands, 'raiseerror', raiseerror)
17 webcommands.__all__.append('raiseerror')
@@ -97,3 +97,4 f768c888aaa68d12dd7f509dcc7f01c9584357d0
97 7f8d16af8cae246fa5a48e723d48d58b015aed94 0 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
@@ -110,3 +110,4 f768c888aaa68d12dd7f509dcc7f01c9584357d0
110 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc
110 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc
111 ced632394371a36953ce4d394f86278ae51a2aae 3.2
111 ced632394371a36953ce4d394f86278ae51a2aae 3.2
112 643c58303fb0ec020907af28b9e486be299ba043 3.2.1
112 643c58303fb0ec020907af28b9e486be299ba043 3.2.1
113 902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2
@@ -437,10 +437,18 def overridecalculateupdates(origfn, rep
437 msg = _('remote turned local normal file %s into a largefile\n'
437 msg = _('remote turned local normal file %s into a largefile\n'
438 'use (l)argefile or keep (n)ormal file?'
438 'use (l)argefile or keep (n)ormal file?'
439 '$$ &Largefile $$ &Normal file') % lfile
439 '$$ &Largefile $$ &Normal file') % lfile
440 if repo.ui.promptchoice(msg, 0) == 0:
440 if (# local has unchanged normal file, pick remote largefile
441 pas and lfile in pas[0] and
442 not pas[0][lfile].cmp(p1[lfile]) or
443 # if remote has unchanged largefile, pick local normal file
444 not (pas and standin in pas[0] and
445 not pas[0][standin].cmp(p2[standin])) and
446 # else, prompt
447 repo.ui.promptchoice(msg, 0) == 0
448 ): # pick remote largefile
441 actions['r'].append((lfile, None, msg))
449 actions['r'].append((lfile, None, msg))
442 newglist.append((standin, (p2.flags(standin),), msg))
450 newglist.append((standin, (p2.flags(standin),), msg))
443 else:
451 else: # keep local normal file
444 actions['r'].append((standin, None, msg))
452 actions['r'].append((standin, None, msg))
445 elif lfutil.standin(f) in p1 and lfutil.standin(f) not in removes:
453 elif lfutil.standin(f) in p1 and lfutil.standin(f) not in removes:
446 # Case 2: largefile in the working copy, normal file in
454 # Case 2: largefile in the working copy, normal file in
@@ -450,7 +458,15 def overridecalculateupdates(origfn, rep
450 msg = _('remote turned local largefile %s into a normal file\n'
458 msg = _('remote turned local largefile %s into a normal file\n'
451 'keep (l)argefile or use (n)ormal file?'
459 'keep (l)argefile or use (n)ormal file?'
452 '$$ &Largefile $$ &Normal file') % lfile
460 '$$ &Largefile $$ &Normal file') % lfile
453 if repo.ui.promptchoice(msg, 0) == 0:
461 if (# if remote has unchanged normal file, pick local largefile
462 pas and f in pas[0] and
463 not pas[0][f].cmp(p2[f]) or
464 # if local has unchanged largefile, pick remote normal file
465 not (pas and standin in pas[0] and
466 not pas[0][standin].cmp(p1[standin])) and
467 # else, prompt
468 repo.ui.promptchoice(msg, 0) == 0
469 ): # keep local largefile
454 if branchmerge:
470 if branchmerge:
455 # largefile can be restored from standin safely
471 # largefile can be restored from standin safely
456 actions['r'].append((lfile, None, msg))
472 actions['r'].append((lfile, None, msg))
@@ -461,7 +477,7 def overridecalculateupdates(origfn, rep
461
477
462 # linear-merge should treat this largefile as 're-added'
478 # linear-merge should treat this largefile as 're-added'
463 actions['a'].append((standin, None, msg))
479 actions['a'].append((standin, None, msg))
464 else:
480 else: # pick remote normal file
465 actions['r'].append((standin, None, msg))
481 actions['r'].append((standin, None, msg))
466 newglist.append((lfile, (p2.flags(lfile),), msg))
482 newglist.append((lfile, (p2.flags(lfile),), msg))
467 else:
483 else:
@@ -113,7 +113,6 HGHEADERS = [
113 '# Branch ',
113 '# Branch ',
114 '# Node ID ',
114 '# Node ID ',
115 '# Parent ', # can occur twice for merges - but that is not relevant for mq
115 '# Parent ', # can occur twice for merges - but that is not relevant for mq
116 '', # all lines after headers 'has' this prefix - simplifies the algorithm
117 ]
116 ]
118
117
119 def inserthgheader(lines, header, value):
118 def inserthgheader(lines, header, value):
@@ -127,6 +126,9 def inserthgheader(lines, header, value)
127 ['# HG changeset patch', '# Date z', '']
126 ['# HG changeset patch', '# Date z', '']
128 >>> inserthgheader(['# HG changeset patch', '# User y'], '# Date ', 'z')
127 >>> inserthgheader(['# HG changeset patch', '# User y'], '# Date ', 'z')
129 ['# HG changeset patch', '# User y', '# Date z']
128 ['# HG changeset patch', '# User y', '# Date z']
129 >>> inserthgheader(['# HG changeset patch', '# Date x', '# User y'],
130 ... '# User ', 'z')
131 ['# HG changeset patch', '# Date x', '# User z']
130 >>> inserthgheader(['# HG changeset patch', '# Date y'], '# Date ', 'z')
132 >>> inserthgheader(['# HG changeset patch', '# Date y'], '# Date ', 'z')
131 ['# HG changeset patch', '# Date z']
133 ['# HG changeset patch', '# Date z']
132 >>> inserthgheader(['# HG changeset patch', '', '# Date y'], '# Date ', 'z')
134 >>> inserthgheader(['# HG changeset patch', '', '# Date y'], '# Date ', 'z')
@@ -136,18 +138,21 def inserthgheader(lines, header, value)
136 """
138 """
137 start = lines.index('# HG changeset patch') + 1
139 start = lines.index('# HG changeset patch') + 1
138 newindex = HGHEADERS.index(header)
140 newindex = HGHEADERS.index(header)
141 bestpos = len(lines)
139 for i in range(start, len(lines)):
142 for i in range(start, len(lines)):
140 line = lines[i]
143 line = lines[i]
144 if not line.startswith('# '):
145 bestpos = min(bestpos, i)
146 break
141 for lineindex, h in enumerate(HGHEADERS):
147 for lineindex, h in enumerate(HGHEADERS):
142 if line.startswith(h):
148 if line.startswith(h):
143 if lineindex < newindex:
144 break # next line
145 if lineindex == newindex:
149 if lineindex == newindex:
146 lines[i] = header + value
150 lines[i] = header + value
147 else:
148 lines.insert(i, header + value)
149 return lines
151 return lines
150 lines.append(header + value)
152 if lineindex > newindex:
153 bestpos = min(bestpos, i)
154 break # next line
155 lines.insert(bestpos, header + value)
151 return lines
156 return lines
152
157
153 def insertplainheader(lines, header, value):
158 def insertplainheader(lines, header, value):
@@ -149,8 +149,8 msgid ""
149 msgstr ""
149 msgstr ""
150 "Project-Id-Version: Mercurial\n"
150 "Project-Id-Version: Mercurial\n"
151 "Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
151 "Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
152 "POT-Creation-Date: 2014-11-01 17:00+0900\n"
152 "POT-Creation-Date: 2014-11-29 14:13+0900\n"
153 "PO-Revision-Date: 2014-11-01 17:57+0900\n"
153 "PO-Revision-Date: 2014-11-29 14:23+0900\n"
154 "Last-Translator: Japanese translation team <mercurial-ja@googlegroups.com>\n"
154 "Last-Translator: Japanese translation team <mercurial-ja@googlegroups.com>\n"
155 "Language-Team: Japanese\n"
155 "Language-Team: Japanese\n"
156 "Language: ja\n"
156 "Language: ja\n"
@@ -12292,6 +12292,9 msgstr "管理領域の排他の解放 (危険)"
12292 msgid "free the working state lock (DANGEROUS)"
12292 msgid "free the working state lock (DANGEROUS)"
12293 msgstr "作業領域の排他の解放 (危険)"
12293 msgstr "作業領域の排他の解放 (危険)"
12294
12294
12295 msgid "[OPTION]..."
12296 msgstr "[OPTION]..."
12297
12295 msgid "show or modify state of locks"
12298 msgid "show or modify state of locks"
12296 msgstr "排他状況の表示又は変更"
12299 msgstr "排他状況の表示又は変更"
12297
12300
@@ -12508,9 +12511,6 msgstr "記録された mtime 情報の表示抑止"
12508 msgid "sort by saved mtime"
12511 msgid "sort by saved mtime"
12509 msgstr "記録された mtime 情報で整列"
12512 msgstr "記録された mtime 情報で整列"
12510
12513
12511 msgid "[OPTION]..."
12512 msgstr "[OPTION]..."
12513
12514 msgid "show the contents of the current dirstate"
12514 msgid "show the contents of the current dirstate"
12515 msgstr "現時点の dirstate 内容の表示"
12515 msgstr "現時点の dirstate 内容の表示"
12516
12516
@@ -13857,8 +13857,8 msgstr "マージ対象リビジョンの確認(マージ処理は未実施)"
13857 msgid "[-P] [-f] [[-r] REV]"
13857 msgid "[-P] [-f] [[-r] REV]"
13858 msgstr "[-P] [-f] [[-r] REV]"
13858 msgstr "[-P] [-f] [[-r] REV]"
13859
13859
13860 msgid "merge working directory with another revision"
13860 msgid "merge another revision into working directory"
13861 msgstr "作業領域の内容と他のリビジョンのマージ"
13861 msgstr "他リビジョンを作業領域にマージ"
13862
13862
13863 msgid ""
13863 msgid ""
13864 " The current working directory is updated with all changes made in\n"
13864 " The current working directory is updated with all changes made in\n"
@@ -19640,12 +19640,12 msgstr ""
19640
19640
19641 msgid ""
19641 msgid ""
19642 "``reportoldssl``\n"
19642 "``reportoldssl``\n"
19643 " Warn if an SSL certificate is unable to be due to using Python\n"
19643 " Warn if an SSL certificate is unable to be used due to using Python\n"
19644 " 2.5 or earlier. True or False. Default is True."
19644 " 2.5 or earlier. True or False. Default is True."
19645 msgstr ""
19645 msgstr ""
19646 "``reportoldssl``\n"
19646 "``reportoldssl``\n"
19647 " Python 2.5 以前の使用により、 SSL 証明書の処理ができない場合の、\n"
19647 " Python 2.5 以前の使用により、 SSL 証明書の処理ができない場合の、\n"
19648 " 警告表示を指定する真偽値。 デフォルト値: True"
19648 " 警告表示の有無を指定する真偽値。 デフォルト値: True"
19649
19649
19650 msgid ""
19650 msgid ""
19651 "``report_untrusted``\n"
19651 "``report_untrusted``\n"
@@ -12497,6 +12497,9 msgstr "libera o lock do store (PERIGOSO
12497 msgid "free the working state lock (DANGEROUS)"
12497 msgid "free the working state lock (DANGEROUS)"
12498 msgstr "libera o lock do working state (PERIGOSO)"
12498 msgstr "libera o lock do working state (PERIGOSO)"
12499
12499
12500 msgid "[OPTION]..."
12501 msgstr "[OPÇÃO]..."
12502
12500 msgid "show or modify state of locks"
12503 msgid "show or modify state of locks"
12501 msgstr "mostra ou modifica o estado dos locks"
12504 msgstr "mostra ou modifica o estado dos locks"
12502
12505
@@ -12722,9 +12725,6 msgstr "não exibe o mtime armazenado"
12722 msgid "sort by saved mtime"
12725 msgid "sort by saved mtime"
12723 msgstr "ordena por mtime armazenado"
12726 msgstr "ordena por mtime armazenado"
12724
12727
12725 msgid "[OPTION]..."
12726 msgstr "[OPÇÃO]..."
12727
12728 msgid "show the contents of the current dirstate"
12728 msgid "show the contents of the current dirstate"
12729 msgstr "mostra o conteúdo do dirstate atual"
12729 msgstr "mostra o conteúdo do dirstate atual"
12730
12730
@@ -14130,8 +14130,8 msgstr "avalia revisões a serem mescladas (a mesclagem não é executada)"
14130 msgid "[-P] [-f] [[-r] REV]"
14130 msgid "[-P] [-f] [[-r] REV]"
14131 msgstr "[-P] [-f] [[-r] REV]"
14131 msgstr "[-P] [-f] [[-r] REV]"
14132
14132
14133 msgid "merge working directory with another revision"
14133 msgid "merge another revision into working directory"
14134 msgstr "mescla o diretório de trabalho com outra revisão"
14134 msgstr "mescla uma outra revisão com o diretório de trabalho"
14135
14135
14136 msgid ""
14136 msgid ""
14137 " The current working directory is updated with all changes made in\n"
14137 " The current working directory is updated with all changes made in\n"
@@ -20039,7 +20039,7 msgstr ""
20039
20039
20040 msgid ""
20040 msgid ""
20041 "``reportoldssl``\n"
20041 "``reportoldssl``\n"
20042 " Warn if an SSL certificate is unable to be due to using Python\n"
20042 " Warn if an SSL certificate is unable to be used due to using Python\n"
20043 " 2.5 or earlier. True or False. Default is True."
20043 " 2.5 or earlier. True or False. Default is True."
20044 msgstr ""
20044 msgstr ""
20045 "``reportoldssl``\n"
20045 "``reportoldssl``\n"
@@ -3201,7 +3201,7 def files(ui, repo, *pats, **opts):
3201
3201
3202 hg files -0 | xargs -0 grep foo
3202 hg files -0 | xargs -0 grep foo
3203
3203
3204 See :hg:`help pattern` and :hg:`help filesets` for more information
3204 See :hg:`help patterns` and :hg:`help filesets` for more information
3205 on specifying file patterns.
3205 on specifying file patterns.
3206
3206
3207 Returns 0 if a match is found, 1 otherwise.
3207 Returns 0 if a match is found, 1 otherwise.
@@ -48,6 +48,12 class Abort(Exception):
48 Exception.__init__(self, *args)
48 Exception.__init__(self, *args)
49 self.hint = kw.get('hint')
49 self.hint = kw.get('hint')
50
50
51 class HookAbort(Abort):
52 """raised when a validation hook fails, aborting an operation
53
54 Exists to allow more specialized catching."""
55 pass
56
51 class ConfigError(Abort):
57 class ConfigError(Abort):
52 """Exception raised when parsing config files"""
58 """Exception raised when parsing config files"""
53
59
@@ -81,6 +81,7 class _httprequesthandler(BaseHTTPServer
81 except Exception:
81 except Exception:
82 self._start_response("500 Internal Server Error", [])
82 self._start_response("500 Internal Server Error", [])
83 self._write("Internal Server Error")
83 self._write("Internal Server Error")
84 self._done()
84 tb = "".join(traceback.format_exception(*sys.exc_info()))
85 tb = "".join(traceback.format_exception(*sys.exc_info()))
85 self.log_error("Exception happened during processing "
86 self.log_error("Exception happened during processing "
86 "request '%s':\n%s", self.path, tb)
87 "request '%s':\n%s", self.path, tb)
@@ -7,7 +7,7
7
7
8 from i18n import _
8 from i18n import _
9 import os, sys, time
9 import os, sys, time
10 import extensions, util, demandimport
10 import extensions, util, demandimport, error
11
11
12 def _pythonhook(ui, repo, name, hname, funcname, args, throw):
12 def _pythonhook(ui, repo, name, hname, funcname, args, throw):
13 '''call python hook. hook is callable object, looked up as
13 '''call python hook. hook is callable object, looked up as
@@ -107,7 +107,7 def _pythonhook(ui, repo, name, hname, f
107 name, funcname, duration)
107 name, funcname, duration)
108 if r:
108 if r:
109 if throw:
109 if throw:
110 raise util.Abort(_('%s hook failed') % hname)
110 raise error.HookAbort(_('%s hook failed') % hname)
111 ui.warn(_('warning: %s hook failed\n') % hname)
111 ui.warn(_('warning: %s hook failed\n') % hname)
112 return r
112 return r
113
113
@@ -139,7 +139,7 def _exthook(ui, repo, name, cmd, args,
139 if r:
139 if r:
140 desc, r = util.explainexit(r)
140 desc, r = util.explainexit(r)
141 if throw:
141 if throw:
142 raise util.Abort(_('%s hook %s') % (name, desc))
142 raise error.HookAbort(_('%s hook %s') % (name, desc))
143 ui.warn(_('warning: %s hook %s\n') % (name, desc))
143 ui.warn(_('warning: %s hook %s\n') % (name, desc))
144 return r
144 return r
145
145
@@ -1767,8 +1767,14 class localrepository(object):
1767 return ret
1767 return ret
1768
1768
1769 def pushkey(self, namespace, key, old, new):
1769 def pushkey(self, namespace, key, old, new):
1770 try:
1770 self.hook('prepushkey', throw=True, namespace=namespace, key=key,
1771 self.hook('prepushkey', throw=True, namespace=namespace, key=key,
1771 old=old, new=new)
1772 old=old, new=new)
1773 except error.HookAbort, exc:
1774 self.ui.write_err(_("pushkey-abort: %s\n") % exc)
1775 if exc.hint:
1776 self.ui.write_err(_("(%s)\n") % exc.hint)
1777 return False
1772 self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
1778 self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
1773 ret = pushkey.push(self, namespace, key, old, new)
1779 ret = pushkey.push(self, namespace, key, old, new)
1774 self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
1780 self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
@@ -602,7 +602,10 def calculateupdates(repo, wctx, mctx, a
602
602
603 # Prompt and create actions. TODO: Move this towards resolve phase.
603 # Prompt and create actions. TODO: Move this towards resolve phase.
604 for f, args, msg in actions['cd']:
604 for f, args, msg in actions['cd']:
605 if repo.ui.promptchoice(
605 if f in ancestors[0] and not wctx[f].cmp(ancestors[0][f]):
606 # local did change but ended up with same content
607 actions['r'].append((f, None, "prompt same"))
608 elif repo.ui.promptchoice(
606 _("local changed %s which remote deleted\n"
609 _("local changed %s which remote deleted\n"
607 "use (c)hanged version or (d)elete?"
610 "use (c)hanged version or (d)elete?"
608 "$$ &Changed $$ &Delete") % f, 0):
611 "$$ &Changed $$ &Delete") % f, 0):
@@ -613,7 +616,10 def calculateupdates(repo, wctx, mctx, a
613
616
614 for f, args, msg in actions['dc']:
617 for f, args, msg in actions['dc']:
615 flags, = args
618 flags, = args
616 if repo.ui.promptchoice(
619 if f in ancestors[0] and not mctx[f].cmp(ancestors[0][f]):
620 # remote did change but ended up with same content
621 pass # don't get = keep local deleted
622 elif repo.ui.promptchoice(
617 _("remote changed %s which local deleted\n"
623 _("remote changed %s which local deleted\n"
618 "use (c)hanged version or leave (d)eleted?"
624 "use (c)hanged version or leave (d)eleted?"
619 "$$ &Changed $$ &Deleted") % f, 0) == 0:
625 "$$ &Changed $$ &Deleted") % f, 0) == 0:
@@ -2802,7 +2802,7 class generatorset(abstractsmartset):
2802 pass
2802 pass
2803 return self.first()
2803 return self.first()
2804 if self:
2804 if self:
2805 return it.next()
2805 return it().next()
2806 return None
2806 return None
2807
2807
2808 def last(self):
2808 def last(self):
@@ -2816,7 +2816,7 class generatorset(abstractsmartset):
2816 pass
2816 pass
2817 return self.first()
2817 return self.first()
2818 if self:
2818 if self:
2819 return it.next()
2819 return it().next()
2820 return None
2820 return None
2821
2821
2822 def spanset(repo, start=None, end=None):
2822 def spanset(repo, start=None, end=None):
@@ -43,7 +43,6 def request(host, path, show):
43 print "%s: %s" % (h, response.getheader(h))
43 print "%s: %s" % (h, response.getheader(h))
44 if not headeronly:
44 if not headeronly:
45 print
45 print
46 if response.status != 500:
47 data = response.read()
46 data = response.read()
48 sys.stdout.write(data)
47 sys.stdout.write(data)
49
48
@@ -486,4 +486,77 pushing an unchanged bookmark should res
486 no changes found
486 no changes found
487 [1]
487 [1]
488
488
489 $ cd ..
489
490 Check hook preventing push (issue4455)
491 ======================================
492
493 $ hg bookmarks
494 * @ 0:55482a6fb4b1
495 $ hg log -G
496 @ 0:55482a6fb4b1 initial
497
498 $ hg init ../issue4455-dest
499 $ hg push ../issue4455-dest # changesets only
500 pushing to ../issue4455-dest
501 searching for changes
502 adding changesets
503 adding manifests
504 adding file changes
505 added 1 changesets with 1 changes to 1 files
506 $ cat >> .hg/hgrc << EOF
507 > [paths]
508 > local=../issue4455-dest/
509 > ssh=ssh://user@dummy/issue4455-dest
510 > http=http://localhost:$HGPORT/
511 > [ui]
512 > ssh=python "$TESTDIR/dummyssh"
513 > EOF
514 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
515 > [hooks]
516 > prepushkey=false
517 > [web]
518 > push_ssl = false
519 > allow_push = *
520 > EOF
521 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
522 $ hg -R ../issue4455-dest serve -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
523 $ cat ../issue4455.pid >> $DAEMON_PIDS
524
525 Local push
526 ----------
527
528 $ hg push -B @ local
529 pushing to $TESTTMP/issue4455-dest (glob)
530 searching for changes
531 no changes found
532 pushkey-abort: prepushkey hook exited with status 1
533 exporting bookmark @ failed!
534 [1]
535 $ hg -R ../issue4455-dest/ bookmarks
536 no bookmarks set
537
538 Using ssh
539 ---------
540
541 $ hg push -B @ ssh
542 pushing to ssh://user@dummy/issue4455-dest
543 searching for changes
544 no changes found
545 remote: pushkey-abort: prepushkey hook exited with status 1
546 exporting bookmark @ failed!
547 [1]
548 $ hg -R ../issue4455-dest/ bookmarks
549 no bookmarks set
550
551 Using http
552 ----------
553
554 $ hg push -B @ http
555 pushing to http://localhost:$HGPORT/
556 searching for changes
557 no changes found
558 remote: pushkey-abort: prepushkey hook exited with status 1
559 exporting bookmark @ failed!
560 [1]
561 $ hg -R ../issue4455-dest/ bookmarks
562 no bookmarks set
@@ -579,4 +579,30 errors
579
579
580 $ cat errors.log
580 $ cat errors.log
581
581
582 Uncaught exceptions result in a logged error and canned HTTP response
583
584 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
585 $ hg --config extensions.hgweberror=$TESTDIR/hgweberror.py serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
586 $ cat hg.pid >> $DAEMON_PIDS
587
588 $ $TESTDIR/get-with-headers.py localhost:$HGPORT 'raiseerror' transfer-encoding content-type
589 500 Internal Server Error
590 transfer-encoding: chunked
591
592 Internal Server Error (no-eol)
593 [1]
594
595 $ head -1 errors.log
596 .* Exception happened during processing request '/raiseerror': (re)
597
598 Uncaught exception after partial content sent
599
600 $ $TESTDIR/get-with-headers.py localhost:$HGPORT 'raiseerror?partialresponse=1' transfer-encoding content-type
601 200 Script output follows
602 transfer-encoding: chunked
603 content-type: text/plain
604
605 partial content
606 Internal Server Error (no-eol)
607
582 $ cd ..
608 $ cd ..
@@ -228,8 +228,9 test that prepushkey can prevent incomin
228 no changes found
228 no changes found
229 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
229 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
230 prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
230 prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
231 abort: prepushkey hook exited with status 1
231 pushkey-abort: prepushkey hook exited with status 1
232 [255]
232 exporting bookmark baz failed!
233 [1]
233 $ cd ../a
234 $ cd ../a
234
235
235 test that prelistkeys can prevent listing keys
236 test that prelistkeys can prevent listing keys
@@ -9,7 +9,19 Create the repository outside $HOME sinc
9 $ cd test
9 $ cd test
10 $ echo "root" > root
10 $ echo "root" > root
11 $ hg add root
11 $ hg add root
12 $ hg commit -m "Root commit"
12 $ hg commit -m "Root commit" --config extensions.largefiles=!
13
14 Ensure that .hg/largefiles isn't created before largefiles are added
15 #if unix-permissions
16 $ chmod 555 .hg
17 #endif
18 $ hg status
19 #if unix-permissions
20 $ chmod 755 .hg
21 #endif
22
23 $ test -f .hg/largefiles
24 [1]
13
25
14 $ echo "large" > foo
26 $ echo "large" > foo
15 $ hg add --large foo
27 $ hg add --large foo
@@ -145,70 +157,88 Updating from normal to largefile - no r
145
157
146 Systematic testing of merges involving largefiles:
158 Systematic testing of merges involving largefiles:
147
159
148 Ancestor: normal Parent: normal= Parent: large result: large
160 Ancestor: normal Parent: normal-id Parent: large result: large
149 Ancestor: normal Parent: normal2 Parent: large result: ?
161 Ancestor: normal Parent: normal2 Parent: large result: ?
150 Ancestor: large Parent: large= Parent: normal result: normal
162 Ancestor: large Parent: large-id Parent: normal result: normal
151 Ancestor: large Parent: large2 Parent: normal result: ?
163 Ancestor: large Parent: large2 Parent: normal result: ?
152
164
153 All cases should try merging both ways.
165 All cases should try merging both ways.
154 "=" means same file content.
155
166
156 Prepare test repo:
167 Prepare test repo:
157
168
158 $ hg init merges
169 $ hg init merges
159 $ cd merges
170 $ cd merges
160 $ touch f1
161 $ hg ci -Aqm "0-root" --config extensions.largefiles=!
162
171
163 Ensure that .hg/largefiles isn't created before largefiles are added
172 prepare cases with "normal" ancestor:
164 #if unix-permissions
165 $ chmod 555 .hg
166 #endif
167 $ hg status
168 #if unix-permissions
169 $ chmod 755 .hg
170 #endif
171
173
172 $ test -f .hg/largefiles
174 $ hg up -qr null
173 [1]
174
175 ancestor is "normal":
176 $ echo normal > f
175 $ echo normal > f
177 $ hg ci -Aqm "1-normal-ancestor"
176 $ hg ci -Aqm "normal-ancestor"
177 $ hg tag -l "normal-ancestor"
178 $ touch f2
178 $ touch f2
179 $ hg ci -Aqm "2-normal-unchanged"
179 $ hg ci -Aqm "normal-id"
180 $ hg tag -l "normal="
180 $ hg tag -l "normal-id"
181 $ echo normal2 > f
181 $ echo normal2 > f
182 $ hg ci -m "3-normal2"
182 $ hg ci -m "normal2"
183 $ hg tag -l "normal2"
183 $ hg tag -l "normal2"
184 $ hg up -qr 1
184 $ echo normal > f
185 $ hg ci -Aqm "normal-same"
186 $ hg tag -l "normal-same"
187 $ hg up -qr "normal-ancestor"
185 $ hg rm f
188 $ hg rm f
186 $ echo large > f
189 $ echo large > f
187 $ hg add --large f
190 $ hg add --large f
188 $ hg ci -qm "4-normal-to-large"
191 $ hg ci -qm "large"
189 $ hg tag -l "large"
192 $ hg tag -l "large"
190
193
191 $ hg up -qr null
194 prepare cases with "large" ancestor:
192
195
193 ancestor is "large":
196 $ hg up -qr null
194 $ echo large > f
197 $ echo large > f
195 $ hg add --large f
198 $ hg add --large f
196 $ hg ci -qm "5-large-ancestor"
199 $ hg ci -qm "large-ancestor"
200 $ hg tag -l "large-ancestor"
197 $ touch f2
201 $ touch f2
198 $ hg ci -Aqm "6-large-unchanged"
202 $ hg ci -Aqm "large-id"
199 $ hg tag -l "large="
203 $ hg tag -l "large-id"
200 $ echo large2 > f
204 $ echo large2 > f
201 $ hg ci -m "7-large2"
205 $ hg ci -m "large2"
202 $ hg tag -l "large2"
206 $ hg tag -l "large2"
203 $ hg up -qr 5
207 $ echo large > f
208 $ hg ci -Aqm "large-same"
209 $ hg tag -l "large-same"
210 $ hg up -qr "large-ancestor"
204 $ hg rm f
211 $ hg rm f
205 $ echo normal > f
212 $ echo normal > f
206 $ hg ci -qAm "8-large-to-normal"
213 $ hg ci -qAm "normal"
207 $ hg tag -l "normal"
214 $ hg tag -l "normal"
208
215
209 Ancestor: normal Parent: normal= Parent: large result: large
216 $ hg log -GT '{tags}'
217 @ normal tip
218 |
219 | o large-same
220 | |
221 | o large2
222 | |
223 | o large-id
224 |/
225 o large-ancestor
210
226
211 $ hg up -Cqr normal=
227 o large
228 |
229 | o normal-same
230 | |
231 | o normal2
232 | |
233 | o normal-id
234 |/
235 o normal-ancestor
236
237
238
239 Ancestor: normal Parent: normal-id Parent: large result: large
240
241 $ hg up -Cqr normal-id
212 $ hg merge -r large
242 $ hg merge -r large
213 getting changed largefiles
243 getting changed largefiles
214 1 largefiles updated, 0 removed
244 1 largefiles updated, 0 removed
@@ -220,7 +250,29 Ancestor: normal Parent: normal= Paren
220 swap
250 swap
221
251
222 $ hg up -Cqr large
252 $ hg up -Cqr large
223 $ hg merge -r normal=
253 $ hg merge -r normal-id
254 getting changed largefiles
255 0 largefiles updated, 0 removed
256 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 (branch merge, don't forget to commit)
258 $ cat f
259 large
260
261 Ancestor: normal Parent: normal-same Parent: large result: large
262
263 $ hg up -Cqr normal-same
264 $ hg merge -r large
265 getting changed largefiles
266 1 largefiles updated, 0 removed
267 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
268 (branch merge, don't forget to commit)
269 $ cat f
270 large
271
272 swap
273
274 $ hg up -Cqr large
275 $ hg merge -r normal-same
224 getting changed largefiles
276 getting changed largefiles
225 0 largefiles updated, 0 removed
277 0 largefiles updated, 0 removed
226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -307,9 +359,9 swap
307 $ cat f
359 $ cat f
308 large
360 large
309
361
310 Ancestor: large Parent: large= Parent: normal result: normal
362 Ancestor: large Parent: large-id Parent: normal result: normal
311
363
312 $ hg up -Cqr large=
364 $ hg up -Cqr large-id
313 $ hg merge -r normal
365 $ hg merge -r normal
314 getting changed largefiles
366 getting changed largefiles
315 0 largefiles updated, 0 removed
367 0 largefiles updated, 0 removed
@@ -321,7 +373,27 Ancestor: large Parent: large= Paren
321 swap
373 swap
322
374
323 $ hg up -Cqr normal
375 $ hg up -Cqr normal
324 $ hg merge -r large=
376 $ hg merge -r large-id
377 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 (branch merge, don't forget to commit)
379 $ cat f
380 normal
381
382 Ancestor: large Parent: large-same Parent: normal result: normal
383
384 $ hg up -Cqr large-same
385 $ hg merge -r normal
386 getting changed largefiles
387 0 largefiles updated, 0 removed
388 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
389 (branch merge, don't forget to commit)
390 $ cat f
391 normal
392
393 swap
394
395 $ hg up -Cqr normal
396 $ hg merge -r large-same
325 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
397 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
326 (branch merge, don't forget to commit)
398 (branch merge, don't forget to commit)
327 $ cat f
399 $ cat f
@@ -28,3 +28,9 Bogus fast-forward should fail:
28 abort: merging with a working directory ancestor has no effect
28 abort: merging with a working directory ancestor has no effect
29 [255]
29 [255]
30
30
31 Even with strange revset (issue4465)
32
33 $ hg merge ::.
34 abort: merging with a working directory ancestor has no effect
35 [255]
36
@@ -127,10 +127,10 Full rebase all the way back from branch
127 $ hg rebase -r 'only(dev,default)' -d default
127 $ hg rebase -r 'only(dev,default)' -d default
128 remote changed f-default which local deleted
128 remote changed f-default which local deleted
129 use (c)hanged version or leave (d)eleted? c
129 use (c)hanged version or leave (d)eleted? c
130 local changed f-default which remote deleted
131 use (c)hanged version or (d)elete? c
132 saved backup bundle to $TESTTMP/ancestor-merge/.hg/strip-backup/1d1a643d390e-backup.hg (glob)
130 saved backup bundle to $TESTTMP/ancestor-merge/.hg/strip-backup/1d1a643d390e-backup.hg (glob)
133 $ hg tglog
131 $ hg tglog
132 o 6: 'dev: merge default'
133 |
134 o 5: 'dev: merge default'
134 o 5: 'dev: merge default'
135 |
135 |
136 o 4: 'dev: f-dev stuff'
136 o 4: 'dev: f-dev stuff'
@@ -151,10 +151,10 Grafty cherry picking rebasing:
151 $ hg rebase -r 'children(only(dev,default))' -d default
151 $ hg rebase -r 'children(only(dev,default))' -d default
152 remote changed f-default which local deleted
152 remote changed f-default which local deleted
153 use (c)hanged version or leave (d)eleted? c
153 use (c)hanged version or leave (d)eleted? c
154 local changed f-default which remote deleted
155 use (c)hanged version or (d)elete? c
156 saved backup bundle to $TESTTMP/ancestor-merge-2/.hg/strip-backup/ec2c14fb2984-backup.hg (glob)
154 saved backup bundle to $TESTTMP/ancestor-merge-2/.hg/strip-backup/ec2c14fb2984-backup.hg (glob)
157 $ hg tglog
155 $ hg tglog
156 o 7: 'dev: merge default'
157 |
158 o 6: 'dev: merge default'
158 o 6: 'dev: merge default'
159 |
159 |
160 o 5: 'dev: f-dev stuff'
160 o 5: 'dev: f-dev stuff'
@@ -392,9 +392,9 Test hg-ssh in read-only mode:
392 remote: Permission denied
392 remote: Permission denied
393 remote: abort: prechangegroup.hg-ssh hook failed
393 remote: abort: prechangegroup.hg-ssh hook failed
394 remote: Permission denied
394 remote: Permission denied
395 remote: abort: prepushkey.hg-ssh hook failed
395 remote: pushkey-abort: prepushkey.hg-ssh hook failed
396 abort: unexpected response: empty string
396 updating 6c0482d977a3 to public failed!
397 [255]
397 [1]
398
398
399 $ cd ..
399 $ cd ..
400
400
General Comments 0
You need to be logged in to leave comments. Login now