changeset 23426:19ebd2f88fc7

merge with stable
author Matt Mackall <mpm@selenic.com>
date Mon, 01 Dec 2014 19:34:11 -0600
parents 2d86f4e38c08 (current diff) 2b1ffaaab01f (diff)
children 3778884197f0
files hgext/largefiles/overrides.py mercurial/commands.py mercurial/hook.py mercurial/localrepo.py mercurial/merge.py mercurial/revset.py tests/test-hook.t tests/test-rebase-newancestor.t
diffstat 22 files changed, 325 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/.hgsigs	Fri Nov 28 20:16:15 2014 +0100
+++ b/.hgsigs	Mon Dec 01 19:34:11 2014 -0600
@@ -97,3 +97,4 @@
 7f8d16af8cae246fa5a48e723d48d58b015aed94 0 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
+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
--- a/.hgtags	Fri Nov 28 20:16:15 2014 +0100
+++ b/.hgtags	Mon Dec 01 19:34:11 2014 -0600
@@ -110,3 +110,4 @@
 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc
 ced632394371a36953ce4d394f86278ae51a2aae 3.2
 643c58303fb0ec020907af28b9e486be299ba043 3.2.1
+902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2
--- a/hgext/largefiles/overrides.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/hgext/largefiles/overrides.py	Mon Dec 01 19:34:11 2014 -0600
@@ -437,10 +437,18 @@
             msg = _('remote turned local normal file %s into a largefile\n'
                     'use (l)argefile or keep (n)ormal file?'
                     '$$ &Largefile $$ &Normal file') % lfile
-            if repo.ui.promptchoice(msg, 0) == 0:
+            if (# local has unchanged normal file, pick remote largefile
+                pas and lfile in pas[0] and
+                not pas[0][lfile].cmp(p1[lfile]) or
+                # if remote has unchanged largefile, pick local normal file
+                not (pas and standin in pas[0] and
+                     not pas[0][standin].cmp(p2[standin])) and
+                # else, prompt
+                repo.ui.promptchoice(msg, 0) == 0
+                ): # pick remote largefile
                 actions['r'].append((lfile, None, msg))
                 newglist.append((standin, (p2.flags(standin),), msg))
-            else:
+            else: # keep local normal file
                 actions['r'].append((standin, None, msg))
         elif lfutil.standin(f) in p1 and lfutil.standin(f) not in removes:
             # Case 2: largefile in the working copy, normal file in
@@ -450,7 +458,15 @@
             msg = _('remote turned local largefile %s into a normal file\n'
                     'keep (l)argefile or use (n)ormal file?'
                     '$$ &Largefile $$ &Normal file') % lfile
-            if repo.ui.promptchoice(msg, 0) == 0:
+            if (# if remote has unchanged normal file, pick local largefile
+                pas and f in pas[0] and
+                not pas[0][f].cmp(p2[f]) or
+                # if local has unchanged largefile, pick remote normal file
+                not (pas and standin in pas[0] and
+                     not pas[0][standin].cmp(p1[standin])) and
+                # else, prompt
+                repo.ui.promptchoice(msg, 0) == 0
+                ): # keep local largefile
                 if branchmerge:
                     # largefile can be restored from standin safely
                     actions['r'].append((lfile, None, msg))
@@ -461,7 +477,7 @@
 
                     # linear-merge should treat this largefile as 're-added'
                     actions['a'].append((standin, None, msg))
-            else:
+            else: # pick remote normal file
                 actions['r'].append((standin, None, msg))
                 newglist.append((lfile, (p2.flags(lfile),), msg))
         else:
--- a/hgext/mq.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/hgext/mq.py	Mon Dec 01 19:34:11 2014 -0600
@@ -113,7 +113,6 @@
     '# Branch ',
     '# Node ID ',
     '# Parent  ', # can occur twice for merges - but that is not relevant for mq
-    '', # all lines after headers 'has' this prefix - simplifies the algorithm
     ]
 
 def inserthgheader(lines, header, value):
@@ -127,6 +126,9 @@
     ['# HG changeset patch', '# Date z', '']
     >>> inserthgheader(['# HG changeset patch', '# User y'], '# Date ', 'z')
     ['# HG changeset patch', '# User y', '# Date z']
+    >>> inserthgheader(['# HG changeset patch', '# Date x', '# User y'],
+    ...                '# User ', 'z')
+    ['# HG changeset patch', '# Date x', '# User z']
     >>> inserthgheader(['# HG changeset patch', '# Date y'], '# Date ', 'z')
     ['# HG changeset patch', '# Date z']
     >>> inserthgheader(['# HG changeset patch', '', '# Date y'], '# Date ', 'z')
@@ -136,18 +138,21 @@
     """
     start = lines.index('# HG changeset patch') + 1
     newindex = HGHEADERS.index(header)
+    bestpos = len(lines)
     for i in range(start, len(lines)):
         line = lines[i]
+        if not line.startswith('# '):
+            bestpos = min(bestpos, i)
+            break
         for lineindex, h in enumerate(HGHEADERS):
             if line.startswith(h):
-                if lineindex < newindex:
-                    break # next line
                 if lineindex == newindex:
                     lines[i] = header + value
-                else:
-                    lines.insert(i, header + value)
-                return lines
-    lines.append(header + value)
+                    return lines
+                if lineindex > newindex:
+                    bestpos = min(bestpos, i)
+                break # next line
+    lines.insert(bestpos, header + value)
     return lines
 
 def insertplainheader(lines, header, value):
--- a/i18n/ja.po	Fri Nov 28 20:16:15 2014 +0100
+++ b/i18n/ja.po	Mon Dec 01 19:34:11 2014 -0600
@@ -149,8 +149,8 @@
 msgstr ""
 "Project-Id-Version: Mercurial\n"
 "Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
-"POT-Creation-Date: 2014-11-01 17:00+0900\n"
-"PO-Revision-Date: 2014-11-01 17:57+0900\n"
+"POT-Creation-Date: 2014-11-29 14:13+0900\n"
+"PO-Revision-Date: 2014-11-29 14:23+0900\n"
 "Last-Translator: Japanese translation team <mercurial-ja@googlegroups.com>\n"
 "Language-Team: Japanese\n"
 "Language: ja\n"
@@ -12292,6 +12292,9 @@
 msgid "free the working state lock (DANGEROUS)"
 msgstr "作業領域の排他の解放 (危険)"
 
+msgid "[OPTION]..."
+msgstr "[OPTION]..."
+
 msgid "show or modify state of locks"
 msgstr "排他状況の表示又は変更"
 
@@ -12508,9 +12511,6 @@
 msgid "sort by saved mtime"
 msgstr "記録された mtime 情報で整列"
 
-msgid "[OPTION]..."
-msgstr "[OPTION]..."
-
 msgid "show the contents of the current dirstate"
 msgstr "現時点の dirstate 内容の表示"
 
@@ -13857,8 +13857,8 @@
 msgid "[-P] [-f] [[-r] REV]"
 msgstr "[-P] [-f] [[-r] REV]"
 
-msgid "merge working directory with another revision"
-msgstr "作業領域の内容と他のリビジョンのマージ"
+msgid "merge another revision into working directory"
+msgstr "他リビジョンを作業領域にマージ"
 
 msgid ""
 "    The current working directory is updated with all changes made in\n"
@@ -19640,12 +19640,12 @@
 
 msgid ""
 "``reportoldssl``\n"
-"    Warn if an SSL certificate is unable to be due to using Python\n"
+"    Warn if an SSL certificate is unable to be used due to using Python\n"
 "    2.5 or earlier. True or False. Default is True."
 msgstr ""
 "``reportoldssl``\n"
 "    Python 2.5 以前の使用により、 SSL 証明書の処理ができない場合の、\n"
-"    警告表示を指定する真偽値。 デフォルト値: True"
+"    警告表示の有無を指定する真偽値。 デフォルト値: True"
 
 msgid ""
 "``report_untrusted``\n"
--- a/i18n/pt_BR.po	Fri Nov 28 20:16:15 2014 +0100
+++ b/i18n/pt_BR.po	Mon Dec 01 19:34:11 2014 -0600
@@ -12497,6 +12497,9 @@
 msgid "free the working state lock (DANGEROUS)"
 msgstr "libera o lock do working state (PERIGOSO)"
 
+msgid "[OPTION]..."
+msgstr "[OPÇÃO]..."
+
 msgid "show or modify state of locks"
 msgstr "mostra ou modifica o estado dos locks"
 
@@ -12722,9 +12725,6 @@
 msgid "sort by saved mtime"
 msgstr "ordena por mtime armazenado"
 
-msgid "[OPTION]..."
-msgstr "[OPÇÃO]..."
-
 msgid "show the contents of the current dirstate"
 msgstr "mostra o conteúdo do dirstate atual"
 
@@ -14130,8 +14130,8 @@
 msgid "[-P] [-f] [[-r] REV]"
 msgstr "[-P] [-f] [[-r] REV]"
 
-msgid "merge working directory with another revision"
-msgstr "mescla o diretório de trabalho com outra revisão"
+msgid "merge another revision into working directory"
+msgstr "mescla uma outra revisão com o diretório de trabalho"
 
 msgid ""
 "    The current working directory is updated with all changes made in\n"
@@ -20039,7 +20039,7 @@
 
 msgid ""
 "``reportoldssl``\n"
-"    Warn if an SSL certificate is unable to be due to using Python\n"
+"    Warn if an SSL certificate is unable to be used due to using Python\n"
 "    2.5 or earlier. True or False. Default is True."
 msgstr ""
 "``reportoldssl``\n"
--- a/mercurial/commands.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/mercurial/commands.py	Mon Dec 01 19:34:11 2014 -0600
@@ -3201,7 +3201,7 @@
 
           hg files -0 | xargs -0 grep foo
 
-    See :hg:`help pattern` and :hg:`help filesets` for more information
+    See :hg:`help patterns` and :hg:`help filesets` for more information
     on specifying file patterns.
 
     Returns 0 if a match is found, 1 otherwise.
--- a/mercurial/error.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/mercurial/error.py	Mon Dec 01 19:34:11 2014 -0600
@@ -48,6 +48,12 @@
         Exception.__init__(self, *args)
         self.hint = kw.get('hint')
 
+class HookAbort(Abort):
+    """raised when a validation hook fails, aborting an operation
+
+    Exists to allow more specialized catching."""
+    pass
+
 class ConfigError(Abort):
     """Exception raised when parsing config files"""
 
--- a/mercurial/hgweb/server.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/mercurial/hgweb/server.py	Mon Dec 01 19:34:11 2014 -0600
@@ -81,6 +81,7 @@
         except Exception:
             self._start_response("500 Internal Server Error", [])
             self._write("Internal Server Error")
+            self._done()
             tb = "".join(traceback.format_exception(*sys.exc_info()))
             self.log_error("Exception happened during processing "
                            "request '%s':\n%s", self.path, tb)
--- a/mercurial/hook.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/mercurial/hook.py	Mon Dec 01 19:34:11 2014 -0600
@@ -7,7 +7,7 @@
 
 from i18n import _
 import os, sys, time
-import extensions, util, demandimport
+import extensions, util, demandimport, error
 
 def _pythonhook(ui, repo, name, hname, funcname, args, throw):
     '''call python hook. hook is callable object, looked up as
@@ -107,7 +107,7 @@
                name, funcname, duration)
     if r:
         if throw:
-            raise util.Abort(_('%s hook failed') % hname)
+            raise error.HookAbort(_('%s hook failed') % hname)
         ui.warn(_('warning: %s hook failed\n') % hname)
     return r
 
@@ -139,7 +139,7 @@
     if r:
         desc, r = util.explainexit(r)
         if throw:
-            raise util.Abort(_('%s hook %s') % (name, desc))
+            raise error.HookAbort(_('%s hook %s') % (name, desc))
         ui.warn(_('warning: %s hook %s\n') % (name, desc))
     return r
 
--- a/mercurial/localrepo.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/mercurial/localrepo.py	Mon Dec 01 19:34:11 2014 -0600
@@ -1767,8 +1767,14 @@
         return ret
 
     def pushkey(self, namespace, key, old, new):
-        self.hook('prepushkey', throw=True, namespace=namespace, key=key,
-                  old=old, new=new)
+        try:
+            self.hook('prepushkey', throw=True, namespace=namespace, key=key,
+                      old=old, new=new)
+        except error.HookAbort, exc:
+            self.ui.write_err(_("pushkey-abort: %s\n") % exc)
+            if exc.hint:
+                self.ui.write_err(_("(%s)\n") % exc.hint)
+            return False
         self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
         ret = pushkey.push(self, namespace, key, old, new)
         self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
--- a/mercurial/merge.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/mercurial/merge.py	Mon Dec 01 19:34:11 2014 -0600
@@ -602,7 +602,10 @@
 
     # Prompt and create actions. TODO: Move this towards resolve phase.
     for f, args, msg in actions['cd']:
-        if repo.ui.promptchoice(
+        if f in ancestors[0] and not wctx[f].cmp(ancestors[0][f]):
+            # local did change but ended up with same content
+            actions['r'].append((f, None, "prompt same"))
+        elif repo.ui.promptchoice(
             _("local changed %s which remote deleted\n"
               "use (c)hanged version or (d)elete?"
               "$$ &Changed $$ &Delete") % f, 0):
@@ -613,7 +616,10 @@
 
     for f, args, msg in actions['dc']:
         flags, = args
-        if repo.ui.promptchoice(
+        if f in ancestors[0] and not mctx[f].cmp(ancestors[0][f]):
+            # remote did change but ended up with same content
+            pass # don't get = keep local deleted
+        elif repo.ui.promptchoice(
             _("remote changed %s which local deleted\n"
               "use (c)hanged version or leave (d)eleted?"
               "$$ &Changed $$ &Deleted") % f, 0) == 0:
--- a/mercurial/revset.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/mercurial/revset.py	Mon Dec 01 19:34:11 2014 -0600
@@ -2802,7 +2802,7 @@
                 pass
             return self.first()
         if self:
-            return it.next()
+            return it().next()
         return None
 
     def last(self):
@@ -2816,7 +2816,7 @@
                 pass
             return self.first()
         if self:
-            return it.next()
+            return it().next()
         return None
 
 def spanset(repo, start=None, end=None):
--- a/tests/get-with-headers.py	Fri Nov 28 20:16:15 2014 +0100
+++ b/tests/get-with-headers.py	Mon Dec 01 19:34:11 2014 -0600
@@ -43,9 +43,8 @@
             print "%s: %s" % (h, response.getheader(h))
     if not headeronly:
         print
-        if response.status != 500:
-            data = response.read()
-            sys.stdout.write(data)
+        data = response.read()
+        sys.stdout.write(data)
 
         if twice and response.getheader('ETag', None):
             tag = response.getheader('ETag')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/hgweberror.py	Mon Dec 01 19:34:11 2014 -0600
@@ -0,0 +1,17 @@
+# A dummy extension that installs an hgweb command that throws an Exception.
+
+from mercurial.hgweb import webcommands
+
+def raiseerror(web, req, tmpl):
+    '''Dummy web command that raises an uncaught Exception.'''
+
+    # Simulate an error after partial response.
+    if 'partialresponse' in req.form:
+        req.respond(200, 'text/plain')
+        req.write('partial content\n')
+
+    raise AttributeError('I am an uncaught error!')
+
+def extsetup(ui):
+    setattr(webcommands, 'raiseerror', raiseerror)
+    webcommands.__all__.append('raiseerror')
--- a/tests/test-bookmarks-pushpull.t	Fri Nov 28 20:16:15 2014 +0100
+++ b/tests/test-bookmarks-pushpull.t	Mon Dec 01 19:34:11 2014 -0600
@@ -486,4 +486,77 @@
   no changes found
   [1]
 
-  $ cd ..
+
+Check hook preventing push (issue4455)
+======================================
+
+  $ hg bookmarks
+   * @                         0:55482a6fb4b1
+  $ hg log -G
+  @  0:55482a6fb4b1 initial
+  
+  $ hg init ../issue4455-dest
+  $ hg push ../issue4455-dest # changesets only
+  pushing to ../issue4455-dest
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  $ cat >> .hg/hgrc << EOF
+  > [paths]
+  > local=../issue4455-dest/
+  > ssh=ssh://user@dummy/issue4455-dest
+  > http=http://localhost:$HGPORT/
+  > [ui]
+  > ssh=python "$TESTDIR/dummyssh"
+  > EOF
+  $ cat >> ../issue4455-dest/.hg/hgrc << EOF
+  > [hooks]
+  > prepushkey=false
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > EOF
+  $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
+  $ hg -R ../issue4455-dest serve -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
+  $ cat ../issue4455.pid >> $DAEMON_PIDS
+
+Local push
+----------
+
+  $ hg push -B @ local
+  pushing to $TESTTMP/issue4455-dest (glob)
+  searching for changes
+  no changes found
+  pushkey-abort: prepushkey hook exited with status 1
+  exporting bookmark @ failed!
+  [1]
+  $ hg -R ../issue4455-dest/ bookmarks
+  no bookmarks set
+
+Using ssh
+---------
+
+  $ hg push -B @ ssh
+  pushing to ssh://user@dummy/issue4455-dest
+  searching for changes
+  no changes found
+  remote: pushkey-abort: prepushkey hook exited with status 1
+  exporting bookmark @ failed!
+  [1]
+  $ hg -R ../issue4455-dest/ bookmarks
+  no bookmarks set
+
+Using http
+----------
+
+  $ hg push -B @ http
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  remote: pushkey-abort: prepushkey hook exited with status 1
+  exporting bookmark @ failed!
+  [1]
+  $ hg -R ../issue4455-dest/ bookmarks
+  no bookmarks set
--- a/tests/test-hgweb.t	Fri Nov 28 20:16:15 2014 +0100
+++ b/tests/test-hgweb.t	Mon Dec 01 19:34:11 2014 -0600
@@ -579,4 +579,30 @@
 
   $ cat errors.log
 
+Uncaught exceptions result in a logged error and canned HTTP response
+
+  $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
+  $ hg --config extensions.hgweberror=$TESTDIR/hgweberror.py serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ $TESTDIR/get-with-headers.py localhost:$HGPORT 'raiseerror' transfer-encoding content-type
+  500 Internal Server Error
+  transfer-encoding: chunked
+  
+  Internal Server Error (no-eol)
+  [1]
+
+  $ head -1 errors.log
+  .* Exception happened during processing request '/raiseerror': (re)
+
+Uncaught exception after partial content sent
+
+  $ $TESTDIR/get-with-headers.py localhost:$HGPORT 'raiseerror?partialresponse=1' transfer-encoding content-type
+  200 Script output follows
+  transfer-encoding: chunked
+  content-type: text/plain
+  
+  partial content
+  Internal Server Error (no-eol)
+
   $ cd ..
--- a/tests/test-hook.t	Fri Nov 28 20:16:15 2014 +0100
+++ b/tests/test-hook.t	Mon Dec 01 19:34:11 2014 -0600
@@ -228,8 +228,9 @@
   no changes found
   listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
   prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
-  abort: prepushkey hook exited with status 1
-  [255]
+  pushkey-abort: prepushkey hook exited with status 1
+  exporting bookmark baz failed!
+  [1]
   $ cd ../a
 
 test that prelistkeys can prevent listing keys
--- a/tests/test-issue3084.t	Fri Nov 28 20:16:15 2014 +0100
+++ b/tests/test-issue3084.t	Mon Dec 01 19:34:11 2014 -0600
@@ -9,7 +9,19 @@
   $ cd test
   $ echo "root" > root
   $ hg add root
-  $ hg commit -m "Root commit"
+  $ hg commit -m "Root commit" --config extensions.largefiles=!
+
+Ensure that .hg/largefiles isn't created before largefiles are added
+#if unix-permissions
+  $ chmod 555 .hg
+#endif
+  $ hg status
+#if unix-permissions
+  $ chmod 755 .hg
+#endif
+
+  $ test -f .hg/largefiles
+  [1]
 
   $ echo "large" > foo
   $ hg add --large foo
@@ -145,70 +157,88 @@
 
 Systematic testing of merges involving largefiles:
 
-Ancestor: normal  Parent: normal=  Parent: large   result: large
-Ancestor: normal  Parent: normal2  Parent: large   result: ?
-Ancestor: large   Parent: large=   Parent: normal  result: normal
-Ancestor: large   Parent: large2   Parent: normal  result: ?
+Ancestor: normal  Parent: normal-id  Parent: large   result: large
+Ancestor: normal  Parent: normal2    Parent: large   result: ?
+Ancestor: large   Parent: large-id   Parent: normal  result: normal
+Ancestor: large   Parent: large2     Parent: normal  result: ?
 
 All cases should try merging both ways.
-"=" means same file content.
 
 Prepare test repo:
 
   $ hg init merges
   $ cd merges
-  $ touch f1
-  $ hg ci -Aqm "0-root" --config extensions.largefiles=!
 
-Ensure that .hg/largefiles isn't created before largefiles are added
-#if unix-permissions
-  $ chmod 555 .hg
-#endif
-  $ hg status
-#if unix-permissions
-  $ chmod 755 .hg
-#endif
+prepare cases with "normal" ancestor:
 
-  $ test -f .hg/largefiles
-  [1]
-
-ancestor is "normal":
+  $ hg up -qr null
   $ echo normal > f
-  $ hg ci -Aqm "1-normal-ancestor"
+  $ hg ci -Aqm "normal-ancestor"
+  $ hg tag -l "normal-ancestor"
   $ touch f2
-  $ hg ci -Aqm "2-normal-unchanged"
-  $ hg tag -l "normal="
+  $ hg ci -Aqm "normal-id"
+  $ hg tag -l "normal-id"
   $ echo normal2 > f
-  $ hg ci -m "3-normal2"
+  $ hg ci -m "normal2"
   $ hg tag -l "normal2"
-  $ hg up -qr 1
+  $ echo normal > f
+  $ hg ci -Aqm "normal-same"
+  $ hg tag -l "normal-same"
+  $ hg up -qr "normal-ancestor"
   $ hg rm f
   $ echo large > f
   $ hg add --large f
-  $ hg ci -qm "4-normal-to-large"
+  $ hg ci -qm "large"
   $ hg tag -l "large"
 
-  $ hg up -qr null
+prepare cases with "large" ancestor:
 
-ancestor is "large":
+  $ hg up -qr null
   $ echo large > f
   $ hg add --large f
-  $ hg ci -qm "5-large-ancestor"
+  $ hg ci -qm "large-ancestor"
+  $ hg tag -l "large-ancestor"
   $ touch f2
-  $ hg ci -Aqm "6-large-unchanged"
-  $ hg tag -l "large="
+  $ hg ci -Aqm "large-id"
+  $ hg tag -l "large-id"
   $ echo large2 > f
-  $ hg ci -m "7-large2"
+  $ hg ci -m "large2"
   $ hg tag -l "large2"
-  $ hg up -qr 5
+  $ echo large > f
+  $ hg ci -Aqm "large-same"
+  $ hg tag -l "large-same"
+  $ hg up -qr "large-ancestor"
   $ hg rm f
   $ echo normal > f
-  $ hg ci -qAm "8-large-to-normal"
+  $ hg ci -qAm "normal"
   $ hg tag -l "normal"
 
-Ancestor: normal  Parent: normal=  Parent: large   result: large
+  $ hg log -GT '{tags}'
+  @  normal tip
+  |
+  | o  large-same
+  | |
+  | o  large2
+  | |
+  | o  large-id
+  |/
+  o  large-ancestor
+  
+  o  large
+  |
+  | o  normal-same
+  | |
+  | o  normal2
+  | |
+  | o  normal-id
+  |/
+  o  normal-ancestor
+  
 
-  $ hg up -Cqr normal=
+
+Ancestor: normal  Parent: normal-id  Parent: large   result: large
+
+  $ hg up -Cqr normal-id
   $ hg merge -r large
   getting changed largefiles
   1 largefiles updated, 0 removed
@@ -220,7 +250,29 @@
 swap
 
   $ hg up -Cqr large
-  $ hg merge -r normal=
+  $ hg merge -r normal-id
+  getting changed largefiles
+  0 largefiles updated, 0 removed
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ cat f
+  large
+
+Ancestor: normal  Parent: normal-same  Parent: large   result: large
+
+  $ hg up -Cqr normal-same
+  $ hg merge -r large
+  getting changed largefiles
+  1 largefiles updated, 0 removed
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ cat f
+  large
+
+swap
+
+  $ hg up -Cqr large
+  $ hg merge -r normal-same
   getting changed largefiles
   0 largefiles updated, 0 removed
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -307,9 +359,9 @@
   $ cat f
   large
 
-Ancestor: large   Parent: large=   Parent: normal  result: normal
+Ancestor: large   Parent: large-id   Parent: normal  result: normal
 
-  $ hg up -Cqr large=
+  $ hg up -Cqr large-id
   $ hg merge -r normal
   getting changed largefiles
   0 largefiles updated, 0 removed
@@ -321,7 +373,27 @@
 swap
 
   $ hg up -Cqr normal
-  $ hg merge -r large=
+  $ hg merge -r large-id
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ cat f
+  normal
+
+Ancestor: large   Parent: large-same   Parent: normal  result: normal
+
+  $ hg up -Cqr large-same
+  $ hg merge -r normal
+  getting changed largefiles
+  0 largefiles updated, 0 removed
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ cat f
+  normal
+
+swap
+
+  $ hg up -Cqr normal
+  $ hg merge -r large-same
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ cat f
--- a/tests/test-issue619.t	Fri Nov 28 20:16:15 2014 +0100
+++ b/tests/test-issue619.t	Mon Dec 01 19:34:11 2014 -0600
@@ -28,3 +28,9 @@
   abort: merging with a working directory ancestor has no effect
   [255]
 
+Even with strange revset (issue4465)
+
+  $ hg merge ::.
+  abort: merging with a working directory ancestor has no effect
+  [255]
+
--- a/tests/test-rebase-newancestor.t	Fri Nov 28 20:16:15 2014 +0100
+++ b/tests/test-rebase-newancestor.t	Mon Dec 01 19:34:11 2014 -0600
@@ -127,10 +127,10 @@
   $ hg rebase -r 'only(dev,default)' -d default
   remote changed f-default which local deleted
   use (c)hanged version or leave (d)eleted? c
-  local changed f-default which remote deleted
-  use (c)hanged version or (d)elete? c
   saved backup bundle to $TESTTMP/ancestor-merge/.hg/strip-backup/1d1a643d390e-backup.hg (glob)
   $ hg tglog
+  o  6: 'dev: merge default'
+  |
   o  5: 'dev: merge default'
   |
   o  4: 'dev: f-dev stuff'
@@ -151,10 +151,10 @@
   $ hg rebase -r 'children(only(dev,default))' -d default
   remote changed f-default which local deleted
   use (c)hanged version or leave (d)eleted? c
-  local changed f-default which remote deleted
-  use (c)hanged version or (d)elete? c
   saved backup bundle to $TESTTMP/ancestor-merge-2/.hg/strip-backup/ec2c14fb2984-backup.hg (glob)
   $ hg tglog
+  o  7: 'dev: merge default'
+  |
   o  6: 'dev: merge default'
   |
   o  5: 'dev: f-dev stuff'
--- a/tests/test-ssh.t	Fri Nov 28 20:16:15 2014 +0100
+++ b/tests/test-ssh.t	Mon Dec 01 19:34:11 2014 -0600
@@ -392,9 +392,9 @@
   remote: Permission denied
   remote: abort: prechangegroup.hg-ssh hook failed
   remote: Permission denied
-  remote: abort: prepushkey.hg-ssh hook failed
-  abort: unexpected response: empty string
-  [255]
+  remote: pushkey-abort: prepushkey.hg-ssh hook failed
+  updating 6c0482d977a3 to public failed!
+  [1]
 
   $ cd ..