changeset 30697:13d94304c8da

merge with stable
author Augie Fackler <augie@google.com>
date Wed, 04 Jan 2017 14:52:59 -0500
parents 667d9c93c412 (current diff) 4a6ecc5d6d3c (diff)
children c3db3bb4699f
files i18n/ja.po mercurial/posix.py tests/test-check-code.t
diffstat 11 files changed, 97 insertions(+), 78 deletions(-) [+]
line wrap: on
line diff
--- a/.hgsigs	Tue Jan 03 13:25:29 2017 +0100
+++ b/.hgsigs	Wed Jan 04 14:52:59 2017 -0500
@@ -136,3 +136,4 @@
 438173c415874f6ac653efc1099dec9c9150e90f 0 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
+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
--- a/.hgtags	Tue Jan 03 13:25:29 2017 +0100
+++ b/.hgtags	Wed Jan 04 14:52:59 2017 -0500
@@ -149,3 +149,4 @@
 438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc
 eab27446995210c334c3d06f1a659e3b9b5da769 4.0
 b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1
+e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2
--- a/i18n/ja.po	Tue Jan 03 13:25:29 2017 +0100
+++ b/i18n/ja.po	Wed Jan 04 14:52:59 2017 -0500
@@ -165,8 +165,8 @@
 msgstr ""
 "Project-Id-Version: Mercurial\n"
 "Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
-"POT-Creation-Date: 2016-10-30 20:25+0900\n"
-"PO-Revision-Date: 2016-11-01 03:50+0900\n"
+"POT-Creation-Date: 2016-12-31 13:29+0900\n"
+"PO-Revision-Date: 2016-12-31 17:09+0900\n"
 "Last-Translator: Japanese translation team <mercurial-ja@googlegroups.com>\n"
 "Language-Team: Japanese\n"
 "Language: ja\n"
@@ -646,6 +646,8 @@
 "This extension checks at commit/amend time if any of the committed files\n"
 "comes from an unrecorded mv."
 msgstr ""
+"本エクステンションは、 Mercurial を介さずに改名されたファイルでも、\n"
+":hg:`commit` の際に自動判定して、 改名扱いにします。"
 
 msgid ""
 "The threshold at which a file is considered a move can be set with the\n"
@@ -653,21 +655,23 @@
 "0\n"
 "(disabled) and 100 (files must be identical), the default is 95."
 msgstr ""
+"改名はファイルの類似度で判定され、 改名判定の閾値は ``automv.similarity``\n"
+"で設定します。 この設定値は 0 (= 判定無効化) から 100 (= 厳密一致時のみ、\n"
+"改名と判定) の間の、 類似度のパーセンテージを表します。 デフォルト値は 95。"
 
 msgid "disable automatic file move detection"
-msgstr ""
-
-#, fuzzy
+msgstr "自動改名判定の無効化"
+
 msgid "automv.similarity must be between 0 and 100"
-msgstr "類似度には0から100の間を指定してください"
-
-#, fuzzy, python-format
+msgstr "automv.similarity には0から100の間を指定してください"
+
+#, python-format
 msgid "detected move of %s as %s (%d%% similar)\n"
-msgstr "%s の削除を %s へのファイル名変更として記録中 (類似度 %d%%)\n"
+msgstr "%s から %s への改名を検出 (類似度 %d%%)\n"
 
 #, python-format
 msgid "detected move of %d files\n"
-msgstr ""
+msgstr "%d ファイルの改名を検出\n"
 
 msgid "log repository events to a blackbox for debugging"
 msgstr "リポジトリにおけるイベントの記録(デバッグ用)"
@@ -4381,9 +4385,8 @@
 "https://facebook.github.io/watchman/ and make sure it is in your PATH."
 msgstr ""
 
-#, fuzzy
 msgid "The following configuration options exist:"
-msgstr "本エクステンションに対しては、以下の設定のみが可能です::"
+msgstr ""
 
 msgid ""
 "    [fsmonitor]\n"
@@ -4465,23 +4468,22 @@
 msgid "unsupported file type (type is %s)"
 msgstr "未サポートのファイル種別(%s)"
 
-#, fuzzy, python-format
+#, python-format
 msgid "warning: unable to write to %s\n"
-msgstr "警告: %s における .gitmodules の解析に失敗\n"
-
-#, fuzzy, python-format
+msgstr ""
+
+#, python-format
 msgid ""
 "The fsmonitor extension is incompatible with the %s extension and has been "
 "disabled.\n"
-msgstr "eol エクステンションと win32text エクステンションは併用できません\n"
+msgstr ""
 
 #, python-format
 msgid "type '%s' has no property '%s'"
 msgstr ""
 
-#, fuzzy
 msgid "warning: unable to write out fsmonitor state\n"
-msgstr "警告: %s における .gitmodules の解析に失敗\n"
+msgstr ""
 
 msgid "commands to sign and verify changesets"
 msgstr "リビジョンへの署名および検証コマンド"
@@ -5628,9 +5630,8 @@
 "bookmarks were previously located."
 msgstr ""
 
-#, fuzzy
 msgid "journal lock does not support nesting"
-msgstr "指定の連携先には履歴を反映できません"
+msgstr ""
 
 #, python-format
 msgid "journal of %s"
@@ -5644,17 +5645,16 @@
 msgid "got lock after %s seconds\n"
 msgstr "%s 秒遅れでロックを獲得\n"
 
-#, fuzzy, python-format
+#, python-format
 msgid "unsupported journal file version '%s'\n"
-msgstr "未サポートなバンドルファイルバージョンです: %s"
-
-#, fuzzy
+msgstr ""
+
 msgid "not available"
-msgstr "ヘルプはありません"
-
-#, fuzzy, python-format
+msgstr ""
+
+#, python-format
 msgid "unknown journal file version '%s'"
-msgstr "未知のバンドル形式バージョン %s"
+msgstr ""
 
 msgid "show the previous position of bookmarks and the working copy"
 msgstr ""
@@ -5670,15 +5670,11 @@
 "    name, or '.' for the working copy, as well."
 msgstr ""
 
-#, fuzzy
 msgid ""
 "    If `name` starts with `re:`, the remainder of the name is treated as\n"
 "    a regular expression. To match a name that actually starts with `re:`,\n"
 "    use the prefix `literal:`."
 msgstr ""
-"    `name` が `re:` で始まる場合、 残りは正規表現として扱われます。\n"
-"    タグ名そのものが `re:` で始まる場合は、 名前を `literal:`\n"
-"    付きで指定してください。"
 
 msgid ""
 "    By default hg journal only shows the commit hash and the command that "
@@ -5702,17 +5698,15 @@
 msgid "You can't combine --all and filtering on a name"
 msgstr ""
 
-#, fuzzy
 msgid "the working copy and bookmarks"
-msgstr "変更されたブックマークを探索中\n"
-
-#, fuzzy, python-format
+msgstr ""
+
+#, python-format
 msgid "previous locations of %s:\n"
-msgstr "  読み込み元: %s\n"
-
-#, fuzzy
+msgstr ""
+
 msgid "no recorded locations\n"
-msgstr "  読み込み元: %s\n"
+msgstr ""
 
 msgid "expand keywords in tracked files"
 msgstr "構成管理対象ファイル中のキーワード展開"
@@ -13287,8 +13281,8 @@
 msgid "      - clone a remote repository to a new directory named hg/::"
 msgstr "      - 遠隔ホストのリポジトリを、 新規 hg/ ディレクトリ配下に複製::"
 
-msgid "          hg clone http://selenic.com/hg"
-msgstr "          hg clone http://selenic.com/hg"
+msgid "          hg clone https://www.mercurial-scm.org/repo/hg/"
+msgstr "          hg clone https://www.mercurial-scm.org/repo/hg/"
 
 msgid "      - create a lightweight local clone::"
 msgstr "      - 同一ホスト上のリポジトリを軽量複製::"
@@ -13321,8 +13315,8 @@
 msgid "      - clone (and track) a particular named branch::"
 msgstr "      - 特定の名前付きブランチ限定での複製::"
 
-msgid "          hg clone http://selenic.com/hg#stable"
-msgstr "          hg clone http://selenic.com/hg#stable"
+msgid "          hg clone https://www.mercurial-scm.org/repo/hg/#stable"
+msgstr "          hg clone https://www.mercurial-scm.org/repo/hg/#stable"
 
 msgid "    See :hg:`help urls` for details on specifying URLs."
 msgstr "    URL 記述の詳細は :hg:`help urls` を参照してください。"
@@ -15299,8 +15293,8 @@
 msgid "      - check the most recent revision of a remote repository::"
 msgstr "      - 連携先リポジトリにおける最新リビジョンの確認::"
 
-msgid "          hg id -r tip http://selenic.com/hg/"
-msgstr "          hg id -r tip http://selenic.com/hg/"
+msgid "          hg id -r tip https://www.mercurial-scm.org/repo/hg/"
+msgstr "          hg id -r tip https://www.mercurial-scm.org/repo/hg/"
 
 msgid ""
 "    See :hg:`log` for generating more information about specific revisions,\n"
@@ -15472,8 +15466,10 @@
 msgid "      - import a changeset from an hgweb server::"
 msgstr "      - hgweb サーバからの指定リビジョンの取り込み::"
 
-msgid "          hg import http://www.selenic.com/hg/rev/5ca8c111e9aa"
-msgstr "          hg import http://www.selenic.com/hg/rev/5ca8c111e9aa"
+msgid ""
+"          hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa"
+msgstr ""
+"          hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa"
 
 msgid "      - import all the patches in an Unix-style mbox::"
 msgstr "      - Unix 形式 mbox ファイル中の全パッチの取り込み::"
@@ -16112,14 +16108,14 @@
 "        hg log -r \"p1(REV)+p2(REV)\" or\n"
 "        hg log -r \"max(::p1() and file(FILE))+max(::p2() and file(FILE))\" "
 "or\n"
-"        hg log -r \"max(::p1(REV) and file(FILE))+max(::p2(REV) and file"
-"(FILE))\""
+"        hg log -r \"max(::p1(REV) and file(FILE))+max(::p2(REV) and "
+"file(FILE))\""
 msgstr ""
 "        hg log -r \"p1()+p2()\"\n"
 "        hg log -r \"p1(REV)+p2(REV)\"\n"
 "        hg log -r \"max(::p1() and file(FILE))+max(::p2() and file(FILE))\"\n"
-"        hg log -r \"max(::p1(REV) and file(FILE))+max(::p2(REV) and file"
-"(FILE))\""
+"        hg log -r \"max(::p1(REV) and file(FILE))+max(::p2(REV) and "
+"file(FILE))\""
 
 msgid "    See :hg:`summary` and :hg:`help revsets` for related information."
 msgstr ""
@@ -17402,7 +17398,7 @@
 msgid "uncommitted merge"
 msgstr "マージが未コミットです"
 
-msgid "not at a branch head (use -f to force)"
+msgid "working directory is not at a branch head (use -f to force)"
 msgstr "親リビジョンがブランチのヘッドではありません(強制実行は -f 指定)"
 
 msgid "cannot tag null revision"
@@ -22420,8 +22416,8 @@
 
 msgid ""
 "``width``\n"
-"    If set, the maximum width of the progress information (that is, min"
-"(width,\n"
+"    If set, the maximum width of the progress information (that is, "
+"min(width,\n"
 "    term width) will be used)."
 msgstr ""
 "``width``\n"
@@ -22744,12 +22740,11 @@
 "``templates``\n"
 "-------------"
 
-#, fuzzy
 msgid ""
 "Use the ``[templates]`` section to define template strings.\n"
 "See :hg:`help templates` for details."
 msgstr ""
-"テンプレート文字列の定義は ``[templates]`` セクションで行います。\n"
+"``[templates]`` セクションはテンプレート文字列の定義を行います。\n"
 "詳細は :hg:`help templates` を参照してください。"
 
 msgid ""
@@ -25560,8 +25555,8 @@
 "ラッパースクリプトです。"
 
 msgid ""
-"To be used in ~/.ssh/authorized_keys with the \"command\" option, see sshd"
-"(8):\n"
+"To be used in ~/.ssh/authorized_keys with the \"command\" option, see "
+"sshd(8):\n"
 "command=\"hg-ssh path/to/repo1 /path/to/repo2 ~/repo3 ~user/repo4\" ssh-"
 "dss ...\n"
 "(probably together with these other useful options:\n"
@@ -25647,11 +25642,12 @@
 "\"\"\"\"\"\"\"\"\n"
 "ウェブサイト: http://mercurial-scm.org/"
 
-msgid "Source code repository: http://selenic.com/hg"
-msgstr "ソースコードリポジトリ: http://selenic.com/hg"
-
-msgid "Mailing list: http://selenic.com/mailman/listinfo/mercurial"
-msgstr "メーリングリスト: http://selenic.com/mailman/listinfo/mercurial"
+msgid "Source code repository: https://www.mercurial-scm.org/repo/hg"
+msgstr "ソースコードリポジトリ: https://www.mercurial-scm.org/repo/hg"
+
+msgid "Mailing list: https://www.mercurial-scm.org/mailman/listinfo/mercurial/"
+msgstr ""
+"メーリングリスト: https://www.mercurial-scm.org/mailman/listinfo/mercurial/"
 
 msgid ""
 "Copying\n"
@@ -26914,8 +26910,8 @@
 "repository to disable publishing in its configuration file::"
 msgstr ""
 "未完の作業を共有するために、 リビジョンのフェーズを draft のままで\n"
-"push/pull したい場合もあるでしょう。 publishing を無効化するには、\n"
-"サーバ側で以下の設定を行ってください::"
+"push/pull したい場合もあるでしょう。 publishing 処理を無効化するには、\n"
+"各リポジトリで以下の設定を行ってください::"
 
 msgid ""
 "  [phases]\n"
@@ -31784,8 +31780,8 @@
 msgstr ""
 " サブリポジトリ %(s)s の参照先が異なっています (現行側: %(sl)s, 他方側: "
 "%(sr)s)\n"
-"両者のマージ:(m)erge, 現行側%(l)s 参照先:(l)ocal, 他方側%(o)s 参照先:(r)"
-"emote のいずれを採用しますか?$$ &Merge $$ &Local $$ &Remote"
+"両者のマージ:(m)erge, 現行側%(l)s 参照先:(l)ocal, 他方側%(o)s 参照先:"
+"(r)emote のいずれを採用しますか?$$ &Merge $$ &Local $$ &Remote"
 
 #, python-format
 msgid ""
--- a/mercurial/demandimport.py	Tue Jan 03 13:25:29 2017 +0100
+++ b/mercurial/demandimport.py	Wed Jan 04 14:52:59 2017 -0500
@@ -199,8 +199,11 @@
             nonpkg = getattr(mod, '__path__', nothing) is nothing
             if symbol is nothing:
                 if nonpkg:
-                    # do not try relative import, which would raise ValueError
-                    raise ImportError('cannot import name %s' % attr)
+                    # do not try relative import, which would raise ValueError,
+                    # and leave unknown attribute as the default __import__()
+                    # would do. the missing attribute will be detected later
+                    # while processing the import statement.
+                    return
                 mn = '%s.%s' % (mod.__name__, attr)
                 if mn in ignore:
                     importfunc = _origimport
--- a/mercurial/posix.py	Tue Jan 03 13:25:29 2017 +0100
+++ b/mercurial/posix.py	Wed Jan 04 14:52:59 2017 -0500
@@ -607,7 +607,14 @@
 
     In unsupported cases, it will raise a NotImplementedError"""
     try:
-        res = select.select(fds, fds, fds)
+        while True:
+            try:
+                res = select.select(fds, fds, fds)
+                break
+            except select.error as inst:
+                if inst.args[0] == errno.EINTR:
+                    continue
+                raise
     except ValueError: # out of range file descriptor
         raise NotImplementedError()
     return sorted(list(set(sum(res, []))))
--- a/mercurial/templates/rss/filelogentry.tmpl	Tue Jan 03 13:25:29 2017 +0100
+++ b/mercurial/templates/rss/filelogentry.tmpl	Wed Jan 04 14:52:59 2017 -0500
@@ -1,6 +1,6 @@
 <item>
     <title>{desc|strip|firstline|strip|escape}</title>
-    <link>{urlbase}{url|urlescape}log{node|short}/{file|urlescape}</link>
+    <link>{urlbase}{url|urlescape}log/{node|short}/{file|urlescape}</link>
     <description><![CDATA[{desc|strip|escape|websub|addbreaks|nonempty}]]></description>
     <author>{author|obfuscate}</author>
     <pubDate>{date|rfc822date}</pubDate>
--- a/tests/test-check-code.t	Tue Jan 03 13:25:29 2017 +0100
+++ b/tests/test-check-code.t	Wed Jan 04 14:52:59 2017 -0500
@@ -10,7 +10,7 @@
   $ hg locate -X contrib/python-zstandard -X hgext/fsmonitor/pywatchman |
   > sed 's-\\-/-g' | xargs "$check_code" --warnings --per-file=0 || false
   Skipping i18n/polib.py it has no-che?k-code (glob)
-  mercurial/demandimport.py:309:
+  mercurial/demandimport.py:312:
    >     if os.environ.get('HGDEMANDIMPORT') != 'disable':
    use encoding.environ instead (py3)
   mercurial/encoding.py:54:
--- a/tests/test-demandimport.py	Tue Jan 03 13:25:29 2017 +0100
+++ b/tests/test-demandimport.py	Wed Jan 04 14:52:59 2017 -0500
@@ -70,7 +70,16 @@
     print('no demandmod should be created for attribute of non-package '
           'module:\ncontextlib.unknownattr =', f(unknownattr))
 except ImportError as inst:
-    print('contextlib.unknownattr = ImportError: %s' % inst)
+    print('contextlib.unknownattr = ImportError: %s'
+          % rsub(r"'", '', str(inst)))
+
+# Unlike the import statement, __import__() function should not raise
+# ImportError even if fromlist has an unknown item
+# (see Python/import.c:import_module_level() and ensure_fromlist())
+contextlibimp = __import__('contextlib', globals(), locals(), ['unknownattr'])
+print("__import__('contextlib', ..., ['unknownattr']) =", f(contextlibimp))
+print("hasattr(contextlibimp, 'unknownattr') =",
+      util.safehasattr(contextlibimp, 'unknownattr'))
 
 demandimport.disable()
 os.environ['HGDEMANDIMPORT'] = 'disable'
--- a/tests/test-demandimport.py.out	Tue Jan 03 13:25:29 2017 +0100
+++ b/tests/test-demandimport.py.out	Wed Jan 04 14:52:59 2017 -0500
@@ -18,4 +18,6 @@
 re = <proxied module 'sys'>
 contextlib = <unloaded module 'contextlib'>
 contextlib.unknownattr = ImportError: cannot import name unknownattr
+__import__('contextlib', ..., ['unknownattr']) = <module 'contextlib' from '?'>
+hasattr(contextlibimp, 'unknownattr') = False
 node = <module 'mercurial.node' from '?'>
--- a/tests/test-hgweb-commands.t	Tue Jan 03 13:25:29 2017 +0100
+++ b/tests/test-hgweb-commands.t	Wed Jan 04 14:52:59 2017 -0500
@@ -686,7 +686,7 @@
       <description>foo revision history</description>
       <item>
       <title>base</title>
-      <link>http://*:$HGPORT/log2ef0ac749a14/foo</link> (glob)
+      <link>http://*:$HGPORT/log/2ef0ac749a14/foo</link> (glob)
       <description><![CDATA[base(websub)]]></description>
       <author>&#116;&#101;&#115;&#116;</author>
       <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
--- a/tests/test-hgweb-filelog.t	Tue Jan 03 13:25:29 2017 +0100
+++ b/tests/test-hgweb-filelog.t	Wed Jan 04 14:52:59 2017 -0500
@@ -783,14 +783,14 @@
       <description>a revision history</description>
       <item>
       <title>second a</title>
-      <link>http://*:$HGPORT/log3f41bc784e7e/a</link> (glob)
+      <link>http://*:$HGPORT/log/3f41bc784e7e/a</link> (glob)
       <description><![CDATA[second a]]></description>
       <author>&#116;&#101;&#115;&#116;</author>
       <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
   </item>
   <item>
       <title>first a</title>
-      <link>http://*:$HGPORT/log5ed941583260/a</link> (glob)
+      <link>http://*:$HGPORT/log/5ed941583260/a</link> (glob)
       <description><![CDATA[first a]]></description>
       <author>&#116;&#101;&#115;&#116;</author>
       <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>