changeset 13228:d18a748d9c33

merge with stable
author Matt Mackall <mpm@selenic.com>
date Sat, 01 Jan 2011 18:42:04 -0600
parents 1f4721de2ca9 (current diff) 5d1bb1174047 (diff)
children f3058dd05281
files hgext/mq.py mercurial/util.py
diffstat 7 files changed, 257 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/.hgsigs	Thu Dec 23 15:12:24 2010 -0600
+++ b/.hgsigs	Sat Jan 01 18:42:04 2011 -0600
@@ -31,3 +31,4 @@
 333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo=
 4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw=
 6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug=
+e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8=
--- a/.hgtags	Thu Dec 23 15:12:24 2010 -0600
+++ b/.hgtags	Sat Jan 01 18:42:04 2011 -0600
@@ -43,3 +43,4 @@
 333421b9e0f96c7bc788e5667c146a58a9440a55 1.7
 4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1
 6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2
+e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3
--- a/hgext/mq.py	Thu Dec 23 15:12:24 2010 -0600
+++ b/hgext/mq.py	Sat Jan 01 18:42:04 2011 -0600
@@ -2533,7 +2533,7 @@
     backup = 'all'
     if opts.get('backup'):
         backup = 'strip'
-    elif opts.get('no-backup') or opts.get('nobackup'):
+    elif opts.get('no_backup') or opts.get('nobackup'):
         backup = 'none'
 
     cl = repo.changelog
--- a/i18n/pt_BR.po	Thu Dec 23 15:12:24 2010 -0600
+++ b/i18n/pt_BR.po	Sat Jan 01 18:42:04 2011 -0600
@@ -2335,30 +2335,35 @@
 "do Mercurial. Ele usa duas seções ``[patterns]`` e ``[repository]``."
 
 msgid ""
-"The ``[patterns]`` section specifies the line endings used in the\n"
-"working directory. The format is specified by a file pattern. The\n"
-"first match is used, so put more specific patterns first. The\n"
-"available line endings are ``LF``, ``CRLF``, and ``BIN``."
-msgstr ""
-"A seção ``[patterns]`` especifica as quebras de linha usadas no\n"
-"diretório de trabalho. O formato é especificado por um padrão de nomes\n"
+"The ``[patterns]`` section specifies how line endings should be\n"
+"converted between the working copy and the repository. The format is\n"
+"specified by a file pattern. The first match is used, so put more\n"
+"specific patterns first. The available line endings are ``LF``,\n"
+"``CRLF``, and ``BIN``."
+msgstr ""
+"A seção ``[patterns]`` especifica como quebras de linha devem ser\n"
+"convertidas entre o diretório de trabalho e o repositório.\n"
+"O formato é especificado por um padrão de nomes\n"
 "de arquivo. O primeiro padrão que combinar será usado, de modo que\n"
 "padrões mais específicos devem ser especificados primeiro. Os tipos\n"
 "de quebra de linha disponíveis são ``LF``, ``CRLF`` e ``BIN``."
 
 msgid ""
 "Files with the declared format of ``CRLF`` or ``LF`` are always\n"
-"checked out in that format and files declared to be binary (``BIN``)\n"
-"are left unchanged. Additionally, ``native`` is an alias for the\n"
-"platform's default line ending: ``LF`` on Unix (including Mac OS X)\n"
-"and ``CRLF`` on Windows. Note that ``BIN`` (do nothing to line\n"
-"endings) is Mercurial's default behaviour; it is only needed if you\n"
-"need to override a later, more general pattern."
+"checked out and stored in the repository in that format and files\n"
+"declared to be binary (``BIN``) are left unchanged. Additionally,\n"
+"``native`` is an alias for checking out in the platform's default line\n"
+"ending: ``LF`` on Unix (including Mac OS X) and ``CRLF`` on\n"
+"Windows. Note that ``BIN`` (do nothing to line endings) is Mercurial's\n"
+"default behaviour; it is only needed if you need to override a later,\n"
+"more general pattern."
 msgstr ""
 "Arquivos com formato declarado como ``CRLF`` ou ``LF`` são sempre trazidos\n"
-"para o diretório de trabalho no tal formato, e arquivos declarados como\n"
+"para o diretório de trabalho e guardados no repositório no tal formato,\n"
+"e arquivos declarados como\n"
 "binários (``BIN``) não são alterados. Adicionalmente, ``native`` é um\n"
-"apelido para o tipo de quebra de linha padrão na plataforma: ``LF`` em\n"
+"apelido para trazer o arquivo para o diretório de trabalho\n"
+"no tipo de quebra de linha padrão na plataforma: ``LF`` em\n"
 "Unix (inclusive no Mac OS X) e ``CRLF`` no Windows. Note que ``BIN`` (não\n"
 "fazer nada em relação a quebra de linhas) é o comportamento padrão do\n"
 "Mercurial; em geral só é necessário se você precisar sobrepor um padrão\n"
@@ -2412,6 +2417,17 @@
 "  native = LF"
 
 msgid ""
+".. note::\n"
+"   The rules will first apply when files are touched in the working\n"
+"   copy, e.g. by updating to null and back to tip to touch all files."
+msgstr ""
+".. note::\n"
+"   As regras passarão a ser aplicadas a partir do momento em que os\n"
+"   arquivos forem mexidos na cópia de trabalho, por exemplo após um\n"
+"   update para null e de volta para a revisão atual para mexer em\n"
+"   todos os arquivos."
+
+msgid ""
 "The extension uses an optional ``[eol]`` section in your hgrc file\n"
 "(not the ``.hgeol`` file) for settings that control the overall\n"
 "behavior. There are two settings:"
@@ -10122,12 +10138,15 @@
 msgid ""
 "    Tags are used to name particular revisions of the repository and are\n"
 "    very useful to compare different revisions, to go back to significant\n"
-"    earlier versions or to mark branch points as releases, etc."
+"    earlier versions or to mark branch points as releases, etc. Changing\n"
+"    an existing tag is normally disallowed; use -f/--force to override."
 msgstr ""
 "    Etiquetas são usadas para nomear determinadas revisões do\n"
 "    repositório e são muito úteis para comparar diferentes revisões,\n"
 "    para voltar para versões significativas anteriores ou para marcar\n"
-"    pontos de ramificação para versões de distribuição, etc."
+"    pontos de ramificação para versões de distribuição, etc.\n"
+"    Alterar uma etiqueta existente normalmente não é permitido\n"
+"    use -f/--force para forçar essa alteração."
 
 msgid ""
 "    If no revision is given, the parent of the working directory is\n"
@@ -10139,19 +10158,32 @@
 
 msgid ""
 "    To facilitate version control, distribution, and merging of tags,\n"
-"    they are stored as a file named \".hgtags\" which is managed\n"
-"    similarly to other project files and can be hand-edited if\n"
-"    necessary. The file '.hg/localtags' is used for local tags (not\n"
-"    shared among repositories)."
+"    they are stored as a file named \".hgtags\" which is managed similarly\n"
+"    to other project files and can be hand-edited if necessary. This\n"
+"    also means that tagging creates a new commit. The file\n"
+"    \".hg/localtags\" is used for local tags (not shared among\n"
+"    repositories)."
 msgstr ""
 "    Para facilitar o controle de versão, a distribuição e a\n"
 "    mesclagem de etiquetas, elas são armazenadas em um arquivo\n"
 "    chamado \".hgtags\" que é gerenciado de forma similar a\n"
 "    outros arquivos do projeto, e pode ser editado manualmente se\n"
-"    necessário. O arquivo '.hg/localtags' é usado para etiquetas\n"
+"    necessário. O arquivo \".hg/localtags\" é usado para etiquetas\n"
 "    locais (não compartilhadas entre repositórios)."
 
 msgid ""
+"    Tag commits are usually made at the head of a branch. If the parent\n"
+"    of the working directory is not a branch head, :hg:`tag` aborts; use\n"
+"    -f/--force to force the tag commit to be based on a non-head\n"
+"    changeset."
+msgstr ""
+"    A consolidação de revisões de etiqueta são em geral feitas na\n"
+"    cabeça de um ramo. Se o pai do diretório de trabalho não for a\n"
+"    cabeça de um ramo, :hg:`tag` abortará; use -f/--force para\n"
+"    forçar a consolidação de uma etiqueta a se basear em uma \n"
+"    revisão que não seja uma cabeça de ramo."
+
+msgid ""
 "    Since tag names have priority over branch names during revision\n"
 "    lookup, using an existing branch name as a tag name is discouraged."
 msgstr ""
@@ -10184,6 +10216,12 @@
 msgid "tag '%s' already exists (use -f to force)"
 msgstr "a etiqueta '%s' já existe (use -f para forçar)"
 
+msgid "uncommitted merge"
+msgstr "mesclagem não consolidada pendente"
+
+msgid "not at a branch head (use -f to force)"
+msgstr "não está em uma cabeça de ramo (use -f para forçar)"
+
 msgid "list repository tags"
 msgstr "lista as etiquetas do repositório"
 
@@ -11094,8 +11132,8 @@
 msgid "list the changed files of a revision"
 msgstr "lista os arquivos modificados por uma revisão"
 
-msgid "replace existing tag"
-msgstr "substitui etiqueta existente"
+msgid "force tag"
+msgstr "força a mudança da etiqueta"
 
 msgid "make the tag local"
 msgstr "torna a etiqueta local"
@@ -14063,10 +14101,11 @@
 msgstr ":author: String. O autor da revisão, sem modificações."
 
 msgid ""
-":branches: String. The name of the branch on which the changeset was\n"
-"    committed. Will be empty if the branch name was default."
-msgstr ""
-":branches: String. O nome do ramo no qual a revisão foi\n"
+":branches: List of strings. The name of the branch on which the\n"
+"    changeset was committed. Will be empty if the branch name was\n"
+"    default."
+msgstr ""
+":branches: Lista de strings. O nome do ramo no qual a revisão foi\n"
 "    consolidada. Será vazio se o nome do ramo for default."
 
 msgid ":children: List of strings. The children of the changeset."
@@ -15895,6 +15934,10 @@
 msgstr "erro no certificado de %s: %s"
 
 #, python-format
+msgid "warning: %s certificate not verified (check web.cacerts config setting)\n"
+msgstr "aviso: certificado %s não verificado (confira a opção de configuração web.cacerts)\n"
+
+#, python-format
 msgid "command '%s' failed: %s"
 msgstr "falha ao executar o comando '%s' : %s"
 
@@ -16170,6 +16213,8 @@
 msgid "push failed (unexpected response):"
 msgstr "o push falhou (resposta inesperada):"
 
+msgid "replace existing tag"
+msgstr "substitui etiqueta existente"
+
 msgid "- You should use single encoding in one repository."
 msgstr "- Você deve usar uma única codificação em um repositório."
-
--- a/i18n/sv.po	Thu Dec 23 15:12:24 2010 -0600
+++ b/i18n/sv.po	Sat Jan 01 18:42:04 2011 -0600
@@ -13,8 +13,8 @@
 msgstr ""
 "Project-Id-Version: Mercurial\n"
 "Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
-"POT-Creation-Date: 2010-11-01 13:33+0100\n"
-"PO-Revision-Date: 2010-11-01 13:42+0100\n"
+"POT-Creation-Date: 2010-12-19 19:38+0100\n"
+"PO-Revision-Date: 2010-12-19 19:40+0100\n"
 "Last-Translator: Jens Bäckman <jens.backman@gmail.com>\n"
 "Language-Team: Swedish\n"
 "Language: Swedish\n"
@@ -1884,20 +1884,22 @@
 msgstr ""
 
 msgid ""
-"The ``[patterns]`` section specifies the line endings used in the\n"
-"working directory. The format is specified by a file pattern. The\n"
-"first match is used, so put more specific patterns first. The\n"
-"available line endings are ``LF``, ``CRLF``, and ``BIN``."
+"The ``[patterns]`` section specifies how line endings should be\n"
+"converted between the working copy and the repository. The format is\n"
+"specified by a file pattern. The first match is used, so put more\n"
+"specific patterns first. The available line endings are ``LF``,\n"
+"``CRLF``, and ``BIN``."
 msgstr ""
 
 msgid ""
 "Files with the declared format of ``CRLF`` or ``LF`` are always\n"
-"checked out in that format and files declared to be binary (``BIN``)\n"
-"are left unchanged. Additionally, ``native`` is an alias for the\n"
-"platform's default line ending: ``LF`` on Unix (including Mac OS X)\n"
-"and ``CRLF`` on Windows. Note that ``BIN`` (do nothing to line\n"
-"endings) is Mercurial's default behaviour; it is only needed if you\n"
-"need to override a later, more general pattern."
+"checked out and stored in the repository in that format and files\n"
+"declared to be binary (``BIN``) are left unchanged. Additionally,\n"
+"``native`` is an alias for checking out in the platform's default line\n"
+"ending: ``LF`` on Unix (including Mac OS X) and ``CRLF`` on\n"
+"Windows. Note that ``BIN`` (do nothing to line endings) is Mercurial's\n"
+"default behaviour; it is only needed if you need to override a later,\n"
+"more general pattern."
 msgstr ""
 
 msgid ""
@@ -1930,6 +1932,12 @@
 msgstr ""
 
 msgid ""
+".. note::\n"
+"   The rules will first apply when files are touched in the working\n"
+"   copy, e.g. by updating to null and back to tip to touch all files."
+msgstr ""
+
+msgid ""
 "The extension uses an optional ``[eol]`` section in your hgrc file\n"
 "(not the ``.hgeol`` file) for settings that control the overall\n"
 "behavior. There are two settings:"
@@ -1951,6 +1959,13 @@
 msgstr ""
 
 msgid ""
+"The ``win32text.forbid*`` hooks provided by the win32text extension\n"
+"have been unified into a single hook named ``eol.hook``. The hook will\n"
+"lookup the expected line endings from the ``.hgeol`` file, which means\n"
+"you must migrate to a ``.hgeol`` file first before using the hook."
+msgstr ""
+
+msgid ""
 "See :hg:`help patterns` for more information about the glob patterns\n"
 "used.\n"
 msgstr ""
@@ -2828,7 +2843,7 @@
 msgid ""
 "The default template mappings (view with :hg:`kwdemo -d`) can be\n"
 "replaced with customized keywords and templates. Again, run\n"
-":hg:`kwdemo` to control the results of your config changes."
+":hg:`kwdemo` to control the results of your configuration changes."
 msgstr ""
 
 msgid ""
@@ -3313,6 +3328,18 @@
 msgid "cannot refresh a revision with children"
 msgstr ""
 
+#, python-format
+msgid "warning: not refreshing %s\n"
+msgstr "varning: uppdaterar inte %s\n"
+
+#, python-format
+msgid "warning: not adding %s\n"
+msgstr "varning: lägger inte till %s\n"
+
+#, python-format
+msgid "warning: not removing %s\n"
+msgstr "varning: tar inte bort %s\n"
+
 msgid ""
 "refresh interrupted while patch was popped! (revert --all, qpush to "
 "recover)\n"
@@ -5057,8 +5084,8 @@
 msgid "changesets"
 msgstr "ändringar"
 
-msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
-msgstr "fixa olösta konflikter med hg resolve, kör sedan hg rebase --continue"
+msgid "unresolved conflicts (see hg resolve, then hg rebase --continue)"
+msgstr "olösta konflikter (se hg resolve, sedan hg rebase --continue)"
 
 #, python-format
 msgid "no changes, revision %d skipped\n"
@@ -5647,11 +5674,13 @@
 msgid "Note that there are some limitations on using this extension:"
 msgstr ""
 
-msgid "- You should use single encoding in one repository."
-msgstr ""
-
-msgid ""
-"\n"
+msgid ""
+"- You should use single encoding in one repository.\n"
+"- If the repository path ends with 0x5c, .hg/hgrc cannot be read.\n"
+"- win32mbcs is not compatible with fixutf8 extention."
+msgstr ""
+
+msgid ""
 "By default, win32mbcs uses encoding.encoding decided by Mercurial.\n"
 "You can specify the encoding by config option::"
 msgstr ""
@@ -8417,7 +8446,7 @@
 
 msgid ""
 "    Start a local HTTP repository browser and pull server. You can use\n"
-"    this for ad-hoc sharing and browing of repositories. It is\n"
+"    this for ad-hoc sharing and browsing of repositories. It is\n"
 "    recommended to use a real web server to serve a repository for\n"
 "    longer periods of time."
 msgstr ""
@@ -8657,12 +8686,14 @@
 msgid ""
 "    Tags are used to name particular revisions of the repository and are\n"
 "    very useful to compare different revisions, to go back to significant\n"
-"    earlier versions or to mark branch points as releases, etc."
+"    earlier versions or to mark branch points as releases, etc. Changing\n"
+"    an existing tag is normally disallowed; use -f/--force to override."
 msgstr ""
 "    Märken används för att namnge specifika revisioner i arkivet och är\n"
 "    väldigt användbara för at jämföra olika revisioner, för att gå\n"
 "    tillbaka till tidigare versioner eller för att markera förgreningar\n"
-"    som releaser, osv."
+"    som releaser, osv. Att ändra ett existerande märke är normalt inte\n"
+"    tillåtet; använd -f/--force för att tvinga."
 
 msgid ""
 "    If no revision is given, the parent of the working directory is\n"
@@ -8673,20 +8704,33 @@
 
 msgid ""
 "    To facilitate version control, distribution, and merging of tags,\n"
-"    they are stored as a file named \".hgtags\" which is managed\n"
-"    similarly to other project files and can be hand-edited if\n"
-"    necessary. The file '.hg/localtags' is used for local tags (not\n"
-"    shared among repositories)."
+"    they are stored as a file named \".hgtags\" which is managed similarly\n"
+"    to other project files and can be hand-edited if necessary. This\n"
+"    also means that tagging creates a new commit. The file\n"
+"    \".hg/localtags\" is used for local tags (not shared among\n"
+"    repositories)."
 msgstr ""
 "    För att underlätta versionshantering, distribution, och sammanfogning\n"
 "    av märken, lagras de som en fil vid namn \".hgtags\" som hanteras på\n"
 "    samma sätt som andra projektfiler och kan ändras för hand vid behov.\n"
-"    Filen '.hg/localtags' används för lokala märken (ej delad i arkiv)."
+"    Filen \".hg/localtags\" används för lokala märken (ej delad i arkiv)."
+
+msgid ""
+"    Tag commits are usually made at the head of a branch. If the parent\n"
+"    of the working directory is not a branch head, :hg:`tag` aborts; use\n"
+"    -f/--force to force the tag commit to be based on a non-head\n"
+"    changeset."
+msgstr ""
+"    Arkivering av märken görs vanligtvis på huvudet av en gren. Om\n"
+"    föräldern till arbetskatalogen inte är ett grenhuvud, så avbryts\n"
+"    :hg:`tag`; använd -f/--force för att tvinga arkiveringen."
 
 msgid ""
 "    Since tag names have priority over branch names during revision\n"
 "    lookup, using an existing branch name as a tag name is discouraged."
 msgstr ""
+"    Eftersom märkesnamn har prioritet över grennamn vid uppslagning av\n"
+"    revisioner, avråds det att använda existerande grennamn som märkesnamn."
 
 msgid "tag names must be unique"
 msgstr "märkesnamn måste vara unika"
@@ -8713,6 +8757,12 @@
 msgid "tag '%s' already exists (use -f to force)"
 msgstr "märket '%s' existerar redan (använd -f för att tvinga)"
 
+msgid "uncommitted merge"
+msgstr "oarkiverad sammanfogning"
+
+msgid "not at a branch head (use -f to force)"
+msgstr "inte vid ett grenhuvud (använd -f för att tvinga)"
+
 msgid "list repository tags"
 msgstr "lista arkivmärken"
 
@@ -9615,8 +9665,8 @@
 msgid "list the changed files of a revision"
 msgstr "visa de ändrade filerna från en revision"
 
-msgid "replace existing tag"
-msgstr "ersätt existerande märke"
+msgid "force tag"
+msgstr "tvinga märkning"
 
 msgid "make the tag local"
 msgstr "gör märket lokalt"
@@ -12108,7 +12158,7 @@
 msgid ""
 "Paths in the local filesystem can either point to Mercurial\n"
 "repositories or to bundle files (as created by :hg:`bundle` or :hg:`\n"
-"incoming --bundle`)."
+"incoming --bundle`). See also :hg:`help paths`."
 msgstr ""
 
 msgid ""
@@ -12461,6 +12511,10 @@
 msgid "working directory of %s"
 msgstr ""
 
+#, python-format
+msgid "warning: can't find ancestor for '%s' copied from '%s'!\n"
+msgstr "varning: kan inte hitta anfader för '%s', kopierad från '%s'!\n"
+
 msgid "cannot partially commit a merge (do not specify files or patterns)"
 msgstr ""
 
@@ -13295,6 +13349,10 @@
 msgstr ""
 
 #, python-format
+msgid "warning: subrepo spec file %s not found\n"
+msgstr ""
+
+#, python-format
 msgid "subrepo spec file %s not found"
 msgstr ""
 
@@ -13495,6 +13553,13 @@
 msgstr "%s certifikatfel: %s"
 
 #, python-format
+msgid ""
+"warning: %s certificate not verified (check web.cacerts config setting)\n"
+msgstr ""
+"varning: %s-certificatet overifierad (kontrollera inställningen "
+"web.cacerts)\n"
+
+#, python-format
 msgid "command '%s' failed: %s"
 msgstr "kommandot '%s' misslyckades: %s"
 
@@ -13517,17 +13582,28 @@
 msgid "could not symlink to %r: %s"
 msgstr ""
 
+msgid "check your clock"
+msgstr "kontrollera din klocka"
+
+#, python-format
+msgid "negative timestamp: %d"
+msgstr "negativ tidsstämpel: %d"
+
 #, python-format
 msgid "invalid date: %r"
 msgstr "ogiltigt datum: %r"
 
 #, python-format
 msgid "date exceeds 32 bits: %d"
-msgstr ""
+msgstr "datum överskrider 32 bitar: %d"
+
+#, python-format
+msgid "negative date value: %d"
+msgstr "negativt datumvärde: %d"
 
 #, python-format
 msgid "impossible time zone offset: %d"
-msgstr ""
+msgstr "omöjlig tidzonsoffset: %d"
 
 #, python-format
 msgid "invalid day spec: %s"
@@ -13535,43 +13611,43 @@
 
 #, python-format
 msgid "%.0f GB"
-msgstr ""
+msgstr "%.0f GB"
 
 #, python-format
 msgid "%.1f GB"
-msgstr ""
+msgstr "%.1f GB"
 
 #, python-format
 msgid "%.2f GB"
-msgstr ""
+msgstr "%.2f GB"
 
 #, python-format
 msgid "%.0f MB"
-msgstr ""
+msgstr "%.0f MB"
 
 #, python-format
 msgid "%.1f MB"
-msgstr ""
+msgstr "%.1f MB"
 
 #, python-format
 msgid "%.2f MB"
-msgstr ""
+msgstr "%.2f MB"
 
 #, python-format
 msgid "%.0f KB"
-msgstr ""
+msgstr "%.0f KB"
 
 #, python-format
 msgid "%.1f KB"
-msgstr ""
+msgstr "%.1f KB"
 
 #, python-format
 msgid "%.2f KB"
-msgstr ""
+msgstr "%.2f KB"
 
 #, python-format
 msgid "%.0f bytes"
-msgstr ""
+msgstr "%.0f bytes"
 
 #, python-format
 msgid "no port number associated with service '%s'"
--- a/mercurial/util.py	Thu Dec 23 15:12:24 2010 -0600
+++ b/mercurial/util.py	Sat Jan 01 18:42:04 2011 -0600
@@ -1244,12 +1244,23 @@
         r = None
     return author[author.find('<') + 1:r]
 
+def _ellipsis(text, maxlength):
+    if len(text) <= maxlength:
+        return text, False
+    else:
+        return "%s..." % (text[:maxlength - 3]), True
+
 def ellipsis(text, maxlength=400):
     """Trim string to at most maxlength (default: 400) characters."""
-    if len(text) <= maxlength:
-        return text
-    else:
-        return "%s..." % (text[:maxlength - 3])
+    try:
+        # use unicode not to split at intermediate multi-byte sequence
+        utext, truncated = _ellipsis(text.decode(encoding.encoding),
+                                     maxlength)
+        if not truncated:
+            return text
+        return utext.encode(encoding.encoding)
+    except (UnicodeDecodeError, UnicodeEncodeError):
+        return _ellipsis(text, maxlength)[0]
 
 def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
     '''yield every hg repository under path, recursively.'''
--- a/tests/test-notify.t	Thu Dec 23 15:12:24 2010 -0600
+++ b/tests/test-notify.t	Sat Jan 01 18:42:04 2011 -0600
@@ -302,3 +302,49 @@
   changeset 22c88b85aa27 in b
   description: merge
   (run 'hg update' to get a working copy)
+
+truncate multi-byte subject
+
+  $ cat <<EOF >> $HGRCPATH
+  > [notify]
+  > maxsubject = 4
+  > EOF
+  $ echo a >> a/a
+  $ hg --cwd a --encoding utf-8 commit -A -d '0 0' \
+  >   -m `python -c 'print "\xc3\xa0\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4"'`
+  $ hg --traceback --cwd b --encoding utf-8 pull ../a | \
+  >   python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
+  pulling from ../a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: 8bit
+  X-Test: foo
+  Date: * (glob)
+  Subject: \xc3\xa0... (esc)
+  From: test@test.com
+  X-Hg-Notification: changeset 4a47f01c1356
+  Message-Id: <*> (glob)
+  To: baz@test.com, foo@bar
+  
+  changeset 4a47f01c1356 in b
+  description: \xc3\xa0\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4 (esc)
+  diffstat:
+  
+   a |  1 +
+   1 files changed, 1 insertions(+), 0 deletions(-)
+  
+  diffs (7 lines):
+  
+  diff -r 22c88b85aa27 -r 4a47f01c1356 a
+  --- a/a	Thu Jan 01 00:00:03 1970 +0000
+  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,2 +1,3 @@
+   a
+   a
+  +a
+  (run 'hg update' to get a working copy)