summaryrefslogtreecommitdiff
path: root/sys/src/cmd/hg
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-05-03 11:25:13 +0000
committercinap_lenrek <cinap_lenrek@localhost>2011-05-03 11:25:13 +0000
commit458120dd40db6b4df55a4e96b650e16798ef06a0 (patch)
tree8f82685be24fef97e715c6f5ca4c68d34d5074ee /sys/src/cmd/hg
parent3a742c699f6806c1145aea5149bf15de15a0afd7 (diff)
add hg and python
Diffstat (limited to 'sys/src/cmd/hg')
-rw-r--r--sys/src/cmd/hg/CONTRIBUTORS41
-rw-r--r--sys/src/cmd/hg/COPYING340
-rw-r--r--sys/src/cmd/hg/Makefile103
-rw-r--r--sys/src/cmd/hg/README10
-rw-r--r--sys/src/cmd/hg/README.Plan95
-rw-r--r--sys/src/cmd/hg/contrib/bash_completion532
-rwxr-xr-xsys/src/cmd/hg/contrib/buildrpm72
-rwxr-xr-xsys/src/cmd/hg/contrib/convert-repo27
-rw-r--r--sys/src/cmd/hg/contrib/dumprevlog25
-rw-r--r--sys/src/cmd/hg/contrib/git-viz/git-cat-file5
-rw-r--r--sys/src/cmd/hg/contrib/git-viz/git-diff-tree5
-rw-r--r--sys/src/cmd/hg/contrib/git-viz/git-rev-list5
-rw-r--r--sys/src/cmd/hg/contrib/git-viz/git-rev-tree5
-rw-r--r--sys/src/cmd/hg/contrib/git-viz/hg-viz26
-rwxr-xr-xsys/src/cmd/hg/contrib/hg-relink128
-rwxr-xr-xsys/src/cmd/hg/contrib/hg-ssh52
-rwxr-xr-xsys/src/cmd/hg/contrib/hgdiff105
-rwxr-xr-xsys/src/cmd/hg/contrib/hgk4001
-rw-r--r--sys/src/cmd/hg/contrib/hgsh/Makefile13
-rw-r--r--sys/src/cmd/hg/contrib/hgsh/hgsh.c439
-rw-r--r--sys/src/cmd/hg/contrib/hgwebdir.fcgi62
-rw-r--r--sys/src/cmd/hg/contrib/hgwebdir.wsgi51
-rw-r--r--sys/src/cmd/hg/contrib/logo-droplets.svg624
-rw-r--r--sys/src/cmd/hg/contrib/macosx/Readme.html37
-rw-r--r--sys/src/cmd/hg/contrib/macosx/Welcome.html20
-rw-r--r--sys/src/cmd/hg/contrib/macosx/macosx-build.txt11
-rw-r--r--sys/src/cmd/hg/contrib/mercurial.el1294
-rwxr-xr-xsys/src/cmd/hg/contrib/mercurial.spec86
-rw-r--r--sys/src/cmd/hg/contrib/mergetools.hgrc63
-rw-r--r--sys/src/cmd/hg/contrib/mq.el418
-rw-r--r--sys/src/cmd/hg/contrib/perf.py131
-rw-r--r--sys/src/cmd/hg/contrib/python-hook-examples.py22
-rwxr-xr-xsys/src/cmd/hg/contrib/rewrite-log23
-rw-r--r--sys/src/cmd/hg/contrib/sample.hgrc133
-rwxr-xr-xsys/src/cmd/hg/contrib/simplemerge67
-rw-r--r--sys/src/cmd/hg/contrib/tcsh_completion49
-rwxr-xr-xsys/src/cmd/hg/contrib/tcsh_completion_build.sh73
-rwxr-xr-xsys/src/cmd/hg/contrib/tmplrewrite.py23
-rw-r--r--sys/src/cmd/hg/contrib/undumprevlog37
-rw-r--r--sys/src/cmd/hg/contrib/vim/HGAnnotate.vim27
-rw-r--r--sys/src/cmd/hg/contrib/vim/hg-menu.vim93
-rw-r--r--sys/src/cmd/hg/contrib/vim/hgcommand.vim1703
-rw-r--r--sys/src/cmd/hg/contrib/vim/patchreview.txt97
-rw-r--r--sys/src/cmd/hg/contrib/vim/patchreview.vim332
-rw-r--r--sys/src/cmd/hg/contrib/win32/ReadMe.html163
-rw-r--r--sys/src/cmd/hg/contrib/win32/hg.bat12
-rw-r--r--sys/src/cmd/hg/contrib/win32/mercurial.icobin0 -> 2238 bytes
-rw-r--r--sys/src/cmd/hg/contrib/win32/mercurial.ini124
-rw-r--r--sys/src/cmd/hg/contrib/win32/mercurial.iss103
-rw-r--r--sys/src/cmd/hg/contrib/win32/postinstall.txt9
-rw-r--r--sys/src/cmd/hg/contrib/win32/win32-build.txt114
-rw-r--r--sys/src/cmd/hg/contrib/zsh_completion946
-rw-r--r--sys/src/cmd/hg/doc/Makefile48
-rw-r--r--sys/src/cmd/hg/doc/README17
-rw-r--r--sys/src/cmd/hg/doc/common.txt8
-rw-r--r--sys/src/cmd/hg/doc/gendoc.py115
-rw-r--r--sys/src/cmd/hg/doc/hg.1.txt96
-rw-r--r--sys/src/cmd/hg/doc/hgignore.5.txt111
-rw-r--r--sys/src/cmd/hg/doc/hgrc.5.txt934
-rw-r--r--sys/src/cmd/hg/doc/ja/Makefile21
-rw-r--r--sys/src/cmd/hg/doc/ja/docbook.ja.conf583
-rw-r--r--sys/src/cmd/hg/doc/ja/docbook.ja.xsl23
-rw-r--r--sys/src/cmd/hg/doc/ja/hg.1.ja.txt867
-rw-r--r--sys/src/cmd/hg/doc/ja/hgrc.5.ja.txt204
-rwxr-xr-xsys/src/cmd/hg/hg31
-rw-r--r--sys/src/cmd/hg/hg.proto14
-rwxr-xr-xsys/src/cmd/hg/hgeditor56
-rw-r--r--sys/src/cmd/hg/hgext/__init__.py1
-rw-r--r--sys/src/cmd/hg/hgext/acl.py107
-rw-r--r--sys/src/cmd/hg/hgext/bookmarks.py340
-rw-r--r--sys/src/cmd/hg/hgext/bugzilla.py439
-rw-r--r--sys/src/cmd/hg/hgext/children.py44
-rw-r--r--sys/src/cmd/hg/hgext/churn.py174
-rw-r--r--sys/src/cmd/hg/hgext/color.py286
-rw-r--r--sys/src/cmd/hg/hgext/convert/__init__.py296
-rw-r--r--sys/src/cmd/hg/hgext/convert/bzr.py259
-rw-r--r--sys/src/cmd/hg/hgext/convert/common.py389
-rw-r--r--sys/src/cmd/hg/hgext/convert/convcmd.py396
-rw-r--r--sys/src/cmd/hg/hgext/convert/cvs.py372
-rw-r--r--sys/src/cmd/hg/hgext/convert/cvsps.py831
-rw-r--r--sys/src/cmd/hg/hgext/convert/darcs.py135
-rw-r--r--sys/src/cmd/hg/hgext/convert/filemap.py359
-rw-r--r--sys/src/cmd/hg/hgext/convert/git.py152
-rw-r--r--sys/src/cmd/hg/hgext/convert/gnuarch.py342
-rw-r--r--sys/src/cmd/hg/hgext/convert/hg.py363
-rw-r--r--sys/src/cmd/hg/hgext/convert/monotone.py217
-rw-r--r--sys/src/cmd/hg/hgext/convert/p4.py205
-rw-r--r--sys/src/cmd/hg/hgext/convert/subversion.py1136
-rw-r--r--sys/src/cmd/hg/hgext/convert/transport.py128
-rw-r--r--sys/src/cmd/hg/hgext/extdiff.py228
-rw-r--r--sys/src/cmd/hg/hgext/fetch.py148
-rw-r--r--sys/src/cmd/hg/hgext/gpg.py284
-rw-r--r--sys/src/cmd/hg/hgext/graphlog.py378
-rw-r--r--sys/src/cmd/hg/hgext/hgcia.py246
-rw-r--r--sys/src/cmd/hg/hgext/hgk.py347
-rw-r--r--sys/src/cmd/hg/hgext/highlight/__init__.py60
-rw-r--r--sys/src/cmd/hg/hgext/highlight/highlight.py60
-rw-r--r--sys/src/cmd/hg/hgext/inotify/__init__.py109
-rw-r--r--sys/src/cmd/hg/hgext/inotify/client.py160
-rw-r--r--sys/src/cmd/hg/hgext/inotify/common.py51
-rw-r--r--sys/src/cmd/hg/hgext/inotify/linux/__init__.py41
-rw-r--r--sys/src/cmd/hg/hgext/inotify/linux/_inotify.c608
-rw-r--r--sys/src/cmd/hg/hgext/inotify/linux/watcher.py335
-rw-r--r--sys/src/cmd/hg/hgext/inotify/server.py874
-rw-r--r--sys/src/cmd/hg/hgext/interhg.py80
-rw-r--r--sys/src/cmd/hg/hgext/keyword.py555
-rw-r--r--sys/src/cmd/hg/hgext/mq.py2653
-rw-r--r--sys/src/cmd/hg/hgext/notify.py298
-rw-r--r--sys/src/cmd/hg/hgext/pager.py64
-rw-r--r--sys/src/cmd/hg/hgext/parentrevspec.py96
-rw-r--r--sys/src/cmd/hg/hgext/patchbomb.py513
-rw-r--r--sys/src/cmd/hg/hgext/purge.py111
-rw-r--r--sys/src/cmd/hg/hgext/rebase.py471
-rw-r--r--sys/src/cmd/hg/hgext/record.py551
-rw-r--r--sys/src/cmd/hg/hgext/share.py30
-rw-r--r--sys/src/cmd/hg/hgext/transplant.py606
-rw-r--r--sys/src/cmd/hg/hgext/win32mbcs.py147
-rw-r--r--sys/src/cmd/hg/hgext/win32text.py158
-rw-r--r--sys/src/cmd/hg/hgext/zeroconf/Zeroconf.py1573
-rw-r--r--sys/src/cmd/hg/hgext/zeroconf/__init__.py159
-rw-r--r--sys/src/cmd/hg/hgweb.cgi28
-rw-r--r--sys/src/cmd/hg/hgwebdir.cgi67
-rw-r--r--sys/src/cmd/hg/i18n/da.po9275
-rw-r--r--sys/src/cmd/hg/i18n/de.po9685
-rw-r--r--sys/src/cmd/hg/i18n/el.po8779
-rw-r--r--sys/src/cmd/hg/i18n/fr.po9171
-rwxr-xr-xsys/src/cmd/hg/i18n/hggettext123
-rw-r--r--sys/src/cmd/hg/i18n/it.po9510
-rw-r--r--sys/src/cmd/hg/i18n/ja.po10605
-rw-r--r--sys/src/cmd/hg/i18n/pt_BR.po11609
-rw-r--r--sys/src/cmd/hg/i18n/zh_CN.po9165
-rw-r--r--sys/src/cmd/hg/i18n/zh_TW.po9255
-rw-r--r--sys/src/cmd/hg/mercurial/__init__.py0
-rw-r--r--sys/src/cmd/hg/mercurial/__init__.pycbin0 -> 110 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/ancestor.py85
-rw-r--r--sys/src/cmd/hg/mercurial/archival.py226
-rw-r--r--sys/src/cmd/hg/mercurial/base85.c155
-rw-r--r--sys/src/cmd/hg/mercurial/bdiff.c401
-rw-r--r--sys/src/cmd/hg/mercurial/bundlerepo.py303
-rw-r--r--sys/src/cmd/hg/mercurial/byterange.py468
-rw-r--r--sys/src/cmd/hg/mercurial/changegroup.py140
-rw-r--r--sys/src/cmd/hg/mercurial/changelog.py228
-rw-r--r--sys/src/cmd/hg/mercurial/cmdutil.py1254
-rw-r--r--sys/src/cmd/hg/mercurial/commands.py3565
-rw-r--r--sys/src/cmd/hg/mercurial/commands.pycbin0 -> 124515 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/config.py137
-rw-r--r--sys/src/cmd/hg/mercurial/config.pycbin0 -> 5736 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/context.py818
-rw-r--r--sys/src/cmd/hg/mercurial/copies.py233
-rw-r--r--sys/src/cmd/hg/mercurial/demandimport.py139
-rw-r--r--sys/src/cmd/hg/mercurial/demandimport.pycbin0 -> 4500 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/diffhelpers.c156
-rw-r--r--sys/src/cmd/hg/mercurial/dirstate.py601
-rw-r--r--sys/src/cmd/hg/mercurial/dispatch.py501
-rw-r--r--sys/src/cmd/hg/mercurial/dispatch.pycbin0 -> 16165 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/encoding.py75
-rw-r--r--sys/src/cmd/hg/mercurial/encoding.pycbin0 -> 2892 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/error.py72
-rw-r--r--sys/src/cmd/hg/mercurial/error.pycbin0 -> 3986 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/extensions.py178
-rw-r--r--sys/src/cmd/hg/mercurial/extensions.pycbin0 -> 5555 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/fancyopts.py110
-rw-r--r--sys/src/cmd/hg/mercurial/fancyopts.pycbin0 -> 2621 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/filelog.py68
-rw-r--r--sys/src/cmd/hg/mercurial/filemerge.py231
-rw-r--r--sys/src/cmd/hg/mercurial/graphmod.py119
-rw-r--r--sys/src/cmd/hg/mercurial/hbisect.py145
-rw-r--r--sys/src/cmd/hg/mercurial/help.py527
-rw-r--r--sys/src/cmd/hg/mercurial/hg.py367
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/__init__.py16
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/__init__.pycbin0 -> 499 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/common.py105
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/hgweb_mod.py315
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/hgwebdir_mod.py333
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/protocol.py206
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/request.py134
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/server.py298
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/webcommands.py690
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/webutil.py218
-rw-r--r--sys/src/cmd/hg/mercurial/hgweb/wsgicgi.py70
-rw-r--r--sys/src/cmd/hg/mercurial/hook.py135
-rw-r--r--sys/src/cmd/hg/mercurial/httprepo.py258
-rw-r--r--sys/src/cmd/hg/mercurial/i18n.py52
-rw-r--r--sys/src/cmd/hg/mercurial/i18n.pycbin0 -> 1216 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/ignore.py103
-rw-r--r--sys/src/cmd/hg/mercurial/keepalive.py671
-rw-r--r--sys/src/cmd/hg/mercurial/localrepo.py2156
-rw-r--r--sys/src/cmd/hg/mercurial/lock.py137
-rw-r--r--sys/src/cmd/hg/mercurial/lock.pycbin0 -> 3987 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/lsprof.py113
-rw-r--r--sys/src/cmd/hg/mercurial/lsprofcalltree.py86
-rw-r--r--sys/src/cmd/hg/mercurial/mail.py190
-rw-r--r--sys/src/cmd/hg/mercurial/manifest.py201
-rw-r--r--sys/src/cmd/hg/mercurial/match.py249
-rw-r--r--sys/src/cmd/hg/mercurial/mdiff.py269
-rw-r--r--sys/src/cmd/hg/mercurial/merge.py481
-rw-r--r--sys/src/cmd/hg/mercurial/minirst.py343
-rw-r--r--sys/src/cmd/hg/mercurial/mpatch.c444
-rw-r--r--sys/src/cmd/hg/mercurial/node.py18
-rw-r--r--sys/src/cmd/hg/mercurial/node.pycbin0 -> 417 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/osutil.c534
-rw-r--r--sys/src/cmd/hg/mercurial/parsers.c435
-rw-r--r--sys/src/cmd/hg/mercurial/patch.py1454
-rw-r--r--sys/src/cmd/hg/mercurial/posix.py252
-rw-r--r--sys/src/cmd/hg/mercurial/posix.pycbin0 -> 9261 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/pure/base85.py74
-rw-r--r--sys/src/cmd/hg/mercurial/pure/bdiff.py76
-rw-r--r--sys/src/cmd/hg/mercurial/pure/diffhelpers.py56
-rw-r--r--sys/src/cmd/hg/mercurial/pure/mpatch.py116
-rw-r--r--sys/src/cmd/hg/mercurial/pure/osutil.py52
-rw-r--r--sys/src/cmd/hg/mercurial/pure/parsers.py90
-rw-r--r--sys/src/cmd/hg/mercurial/repair.py145
-rw-r--r--sys/src/cmd/hg/mercurial/repo.py43
-rw-r--r--sys/src/cmd/hg/mercurial/revlog.py1376
-rw-r--r--sys/src/cmd/hg/mercurial/simplemerge.py451
-rw-r--r--sys/src/cmd/hg/mercurial/sshrepo.py260
-rw-r--r--sys/src/cmd/hg/mercurial/sshserver.py225
-rw-r--r--sys/src/cmd/hg/mercurial/statichttprepo.py134
-rw-r--r--sys/src/cmd/hg/mercurial/store.py333
-rw-r--r--sys/src/cmd/hg/mercurial/streamclone.py67
-rw-r--r--sys/src/cmd/hg/mercurial/strutil.py34
-rw-r--r--sys/src/cmd/hg/mercurial/subrepo.py197
-rw-r--r--sys/src/cmd/hg/mercurial/tags.py338
-rw-r--r--sys/src/cmd/hg/mercurial/templatefilters.py211
-rw-r--r--sys/src/cmd/hg/mercurial/templater.py245
-rw-r--r--sys/src/cmd/hg/mercurial/transaction.py165
-rw-r--r--sys/src/cmd/hg/mercurial/ui.py381
-rw-r--r--sys/src/cmd/hg/mercurial/ui.pycbin0 -> 14752 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/url.py533
-rw-r--r--sys/src/cmd/hg/mercurial/util.py1284
-rw-r--r--sys/src/cmd/hg/mercurial/util.pycbin0 -> 42141 bytes
-rw-r--r--sys/src/cmd/hg/mercurial/verify.py258
-rw-r--r--sys/src/cmd/hg/mercurial/win32.py144
-rw-r--r--sys/src/cmd/hg/mercurial/windows.py292
-rw-r--r--sys/src/cmd/hg/mkfile17
-rw-r--r--sys/src/cmd/hg/setup.py273
-rw-r--r--sys/src/cmd/hg/templates/atom/changelog.tmpl10
-rw-r--r--sys/src/cmd/hg/templates/atom/changelogentry.tmpl16
-rw-r--r--sys/src/cmd/hg/templates/atom/error.tmpl17
-rw-r--r--sys/src/cmd/hg/templates/atom/filelog.tmpl8
-rw-r--r--sys/src/cmd/hg/templates/atom/header.tmpl2
-rw-r--r--sys/src/cmd/hg/templates/atom/map11
-rw-r--r--sys/src/cmd/hg/templates/atom/tagentry.tmpl8
-rw-r--r--sys/src/cmd/hg/templates/atom/tags.tmpl11
-rw-r--r--sys/src/cmd/hg/templates/coal/header.tmpl6
-rw-r--r--sys/src/cmd/hg/templates/coal/map191
-rw-r--r--sys/src/cmd/hg/templates/gitweb/branches.tmpl30
-rw-r--r--sys/src/cmd/hg/templates/gitweb/changelog.tmpl39
-rw-r--r--sys/src/cmd/hg/templates/gitweb/changelogentry.tmpl14
-rw-r--r--sys/src/cmd/hg/templates/gitweb/changeset.tmpl50
-rw-r--r--sys/src/cmd/hg/templates/gitweb/error.tmpl25
-rw-r--r--sys/src/cmd/hg/templates/gitweb/fileannotate.tmpl61
-rw-r--r--sys/src/cmd/hg/templates/gitweb/filediff.tmpl47
-rw-r--r--sys/src/cmd/hg/templates/gitweb/filelog.tmpl40
-rw-r--r--sys/src/cmd/hg/templates/gitweb/filerevision.tmpl60
-rw-r--r--sys/src/cmd/hg/templates/gitweb/footer.tmpl11
-rw-r--r--sys/src/cmd/hg/templates/gitweb/graph.tmpl121
-rw-r--r--sys/src/cmd/hg/templates/gitweb/header.tmpl8
-rw-r--r--sys/src/cmd/hg/templates/gitweb/index.tmpl26
-rw-r--r--sys/src/cmd/hg/templates/gitweb/manifest.tmpl38
-rw-r--r--sys/src/cmd/hg/templates/gitweb/map248
-rw-r--r--sys/src/cmd/hg/templates/gitweb/notfound.tmpl18
-rw-r--r--sys/src/cmd/hg/templates/gitweb/search.tmpl36
-rw-r--r--sys/src/cmd/hg/templates/gitweb/shortlog.tmpl41
-rw-r--r--sys/src/cmd/hg/templates/gitweb/summary.tmpl58
-rw-r--r--sys/src/cmd/hg/templates/gitweb/tags.tmpl30
-rw-r--r--sys/src/cmd/hg/templates/map-cmdline.changelog14
-rw-r--r--sys/src/cmd/hg/templates/map-cmdline.compact9
-rw-r--r--sys/src/cmd/hg/templates/map-cmdline.default24
-rw-r--r--sys/src/cmd/hg/templates/monoblue/branches.tmpl36
-rw-r--r--sys/src/cmd/hg/templates/monoblue/changelog.tmpl40
-rw-r--r--sys/src/cmd/hg/templates/monoblue/changelogentry.tmpl6
-rw-r--r--sys/src/cmd/hg/templates/monoblue/changeset.tmpl63
-rw-r--r--sys/src/cmd/hg/templates/monoblue/error.tmpl34
-rw-r--r--sys/src/cmd/hg/templates/monoblue/fileannotate.tmpl63
-rw-r--r--sys/src/cmd/hg/templates/monoblue/filediff.tmpl54
-rw-r--r--sys/src/cmd/hg/templates/monoblue/filelog.tmpl49
-rw-r--r--sys/src/cmd/hg/templates/monoblue/filerevision.tmpl63
-rw-r--r--sys/src/cmd/hg/templates/monoblue/footer.tmpl22
-rw-r--r--sys/src/cmd/hg/templates/monoblue/graph.tmpl118
-rw-r--r--sys/src/cmd/hg/templates/monoblue/header.tmpl6
-rw-r--r--sys/src/cmd/hg/templates/monoblue/index.tmpl39
-rw-r--r--sys/src/cmd/hg/templates/monoblue/manifest.tmpl51
-rw-r--r--sys/src/cmd/hg/templates/monoblue/map214
-rw-r--r--sys/src/cmd/hg/templates/monoblue/notfound.tmpl35
-rw-r--r--sys/src/cmd/hg/templates/monoblue/search.tmpl34
-rw-r--r--sys/src/cmd/hg/templates/monoblue/shortlog.tmpl41
-rw-r--r--sys/src/cmd/hg/templates/monoblue/summary.tmpl66
-rw-r--r--sys/src/cmd/hg/templates/monoblue/tags.tmpl36
-rw-r--r--sys/src/cmd/hg/templates/paper/branches.tmpl45
-rw-r--r--sys/src/cmd/hg/templates/paper/changeset.tmpl71
-rw-r--r--sys/src/cmd/hg/templates/paper/error.tmpl43
-rw-r--r--sys/src/cmd/hg/templates/paper/fileannotate.tmpl77
-rw-r--r--sys/src/cmd/hg/templates/paper/filediff.tmpl72
-rw-r--r--sys/src/cmd/hg/templates/paper/filelog.tmpl60
-rw-r--r--sys/src/cmd/hg/templates/paper/filelogentry.tmpl5
-rw-r--r--sys/src/cmd/hg/templates/paper/filerevision.tmpl72
-rw-r--r--sys/src/cmd/hg/templates/paper/footer.tmpl4
-rw-r--r--sys/src/cmd/hg/templates/paper/graph.tmpl132
-rw-r--r--sys/src/cmd/hg/templates/paper/header.tmpl6
-rw-r--r--sys/src/cmd/hg/templates/paper/index.tmpl26
-rw-r--r--sys/src/cmd/hg/templates/paper/manifest.tmpl54
-rw-r--r--sys/src/cmd/hg/templates/paper/map191
-rw-r--r--sys/src/cmd/hg/templates/paper/notfound.tmpl12
-rw-r--r--sys/src/cmd/hg/templates/paper/search.tmpl43
-rw-r--r--sys/src/cmd/hg/templates/paper/shortlog.tmpl57
-rw-r--r--sys/src/cmd/hg/templates/paper/shortlogentry.tmpl5
-rw-r--r--sys/src/cmd/hg/templates/paper/tags.tmpl45
-rw-r--r--sys/src/cmd/hg/templates/raw/changeset.tmpl9
-rw-r--r--sys/src/cmd/hg/templates/raw/error.tmpl2
-rw-r--r--sys/src/cmd/hg/templates/raw/fileannotate.tmpl5
-rw-r--r--sys/src/cmd/hg/templates/raw/filediff.tmpl5
-rw-r--r--sys/src/cmd/hg/templates/raw/index.tmpl2
-rw-r--r--sys/src/cmd/hg/templates/raw/manifest.tmpl3
-rw-r--r--sys/src/cmd/hg/templates/raw/map23
-rw-r--r--sys/src/cmd/hg/templates/raw/notfound.tmpl2
-rw-r--r--sys/src/cmd/hg/templates/rss/changelog.tmpl6
-rw-r--r--sys/src/cmd/hg/templates/rss/changelogentry.tmpl7
-rw-r--r--sys/src/cmd/hg/templates/rss/error.tmpl10
-rw-r--r--sys/src/cmd/hg/templates/rss/filelog.tmpl6
-rw-r--r--sys/src/cmd/hg/templates/rss/filelogentry.tmpl7
-rw-r--r--sys/src/cmd/hg/templates/rss/header.tmpl5
-rw-r--r--sys/src/cmd/hg/templates/rss/map10
-rw-r--r--sys/src/cmd/hg/templates/rss/tagentry.tmpl6
-rw-r--r--sys/src/cmd/hg/templates/rss/tags.tmpl6
-rw-r--r--sys/src/cmd/hg/templates/spartan/branches.tmpl26
-rw-r--r--sys/src/cmd/hg/templates/spartan/changelog.tmpl43
-rw-r--r--sys/src/cmd/hg/templates/spartan/changelogentry.tmpl25
-rw-r--r--sys/src/cmd/hg/templates/spartan/changeset.tmpl51
-rw-r--r--sys/src/cmd/hg/templates/spartan/error.tmpl15
-rw-r--r--sys/src/cmd/hg/templates/spartan/fileannotate.tmpl48
-rw-r--r--sys/src/cmd/hg/templates/spartan/filediff.tmpl36
-rw-r--r--sys/src/cmd/hg/templates/spartan/filelog.tmpl28
-rw-r--r--sys/src/cmd/hg/templates/spartan/filelogentry.tmpl25
-rw-r--r--sys/src/cmd/hg/templates/spartan/filerevision.tmpl46
-rw-r--r--sys/src/cmd/hg/templates/spartan/footer.tmpl8
-rw-r--r--sys/src/cmd/hg/templates/spartan/graph.tmpl96
-rw-r--r--sys/src/cmd/hg/templates/spartan/header.tmpl6
-rw-r--r--sys/src/cmd/hg/templates/spartan/index.tmpl19
-rw-r--r--sys/src/cmd/hg/templates/spartan/manifest.tmpl28
-rw-r--r--sys/src/cmd/hg/templates/spartan/map178
-rw-r--r--sys/src/cmd/hg/templates/spartan/notfound.tmpl12
-rw-r--r--sys/src/cmd/hg/templates/spartan/search.tmpl36
-rw-r--r--sys/src/cmd/hg/templates/spartan/shortlog.tmpl43
-rw-r--r--sys/src/cmd/hg/templates/spartan/shortlogentry.tmpl7
-rw-r--r--sys/src/cmd/hg/templates/spartan/tags.tmpl26
-rw-r--r--sys/src/cmd/hg/templates/static/background.pngbin0 -> 603 bytes
-rw-r--r--sys/src/cmd/hg/templates/static/coal-file.pngbin0 -> 273 bytes
-rw-r--r--sys/src/cmd/hg/templates/static/coal-folder.pngbin0 -> 284 bytes
-rw-r--r--sys/src/cmd/hg/templates/static/excanvas.js19
-rw-r--r--sys/src/cmd/hg/templates/static/graph.js137
-rw-r--r--sys/src/cmd/hg/templates/static/hgicon.pngbin0 -> 792 bytes
-rw-r--r--sys/src/cmd/hg/templates/static/hglogo.pngbin0 -> 4123 bytes
-rw-r--r--sys/src/cmd/hg/templates/static/style-coal.css265
-rw-r--r--sys/src/cmd/hg/templates/static/style-gitweb.css123
-rw-r--r--sys/src/cmd/hg/templates/static/style-monoblue.css472
-rw-r--r--sys/src/cmd/hg/templates/static/style-paper.css254
-rw-r--r--sys/src/cmd/hg/templates/static/style.css105
-rw-r--r--sys/src/cmd/hg/templates/template-vars.txt37
359 files changed, 158135 insertions, 0 deletions
diff --git a/sys/src/cmd/hg/CONTRIBUTORS b/sys/src/cmd/hg/CONTRIBUTORS
new file mode 100644
index 000000000..81f8143d1
--- /dev/null
+++ b/sys/src/cmd/hg/CONTRIBUTORS
@@ -0,0 +1,41 @@
+[This file is here for historical purposes, all recent contributors
+should appear in the changelog directly]
+
+Andrea Arcangeli <andrea at suse.de>
+Thomas Arendsen Hein <thomas at intevation.de>
+Goffredo Baroncelli <kreijack at libero.it>
+Muli Ben-Yehuda <mulix at mulix.org>
+Mikael Berthe <mikael at lilotux.net>
+Benoit Boissinot <bboissin at gmail.com>
+Brendan Cully <brendan at kublai.com>
+Vincent Danjean <vdanjean.ml at free.fr>
+Jake Edge <jake at edge2.net>
+Michael Fetterman <michael.fetterman at intel.com>
+Edouard Gomez <ed.gomez at free.fr>
+Eric Hopper <hopper at omnifarious.org>
+Alecs King <alecsk at gmail.com>
+Volker Kleinfeld <Volker.Kleinfeld at gmx.de>
+Vadim Lebedev <vadim at mbdsys.com>
+Christopher Li <hg at chrisli.org>
+Chris Mason <mason at suse.com>
+Colin McMillen <mcmillen at cs.cmu.edu>
+Wojciech Milkowski <wmilkowski at interia.pl>
+Chad Netzer <chad.netzer at gmail.com>
+Bryan O'Sullivan <bos at serpentine.com>
+Vicent Seguí Pascual <vseguip at gmail.com>
+Sean Perry <shaleh at speakeasy.net>
+Nguyen Anh Quynh <aquynh at gmail.com>
+Ollivier Robert <roberto at keltia.freenix.fr>
+Alexander Schremmer <alex at alexanderweb.de>
+Arun Sharma <arun at sharma-home.net>
+Josef "Jeff" Sipek <jeffpc at optonline.net>
+Kevin Smith <yarcs at qualitycode.com>
+TK Soh <teekaysoh at yahoo.com>
+Radoslaw Szkodzinski <astralstorm at gorzow.mm.pl>
+Samuel Tardieu <sam at rfc1149.net>
+K Thananchayan <thananck at yahoo.com>
+Andrew Thompson <andrewkt at aktzero.com>
+Michael S. Tsirkin <mst at mellanox.co.il>
+Rafael Villar Burke <pachi at mmn-arquitectos.com>
+Tristan Wibberley <tristan at wibberley.org>
+Mark Williamson <mark.williamson at cl.cam.ac.uk>
diff --git a/sys/src/cmd/hg/COPYING b/sys/src/cmd/hg/COPYING
new file mode 100644
index 000000000..d60c31a97
--- /dev/null
+++ b/sys/src/cmd/hg/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/sys/src/cmd/hg/Makefile b/sys/src/cmd/hg/Makefile
new file mode 100644
index 000000000..2a4600490
--- /dev/null
+++ b/sys/src/cmd/hg/Makefile
@@ -0,0 +1,103 @@
+PREFIX=/usr/local
+export PREFIX
+PYTHON=python
+PURE=
+PYTHON_FILES:=$(shell find mercurial hgext doc -name '*.py')
+
+help:
+ @echo 'Commonly used make targets:'
+ @echo ' all - build program and documentation'
+ @echo ' install - install program and man pages to PREFIX ($(PREFIX))'
+ @echo ' install-home - install with setup.py install --home=HOME ($(HOME))'
+ @echo ' local - build for inplace usage'
+ @echo ' tests - run all tests in the automatic test suite'
+ @echo ' test-foo - run only specified tests (e.g. test-merge1)'
+ @echo ' dist - run all tests and create a source tarball in dist/'
+ @echo ' clean - remove files created by other targets'
+ @echo ' (except installed files or dist source tarball)'
+ @echo ' update-pot - update i18n/hg.pot'
+ @echo
+ @echo 'Example for a system-wide installation under /usr/local:'
+ @echo ' make all && su -c "make install" && hg version'
+ @echo
+ @echo 'Example for a local installation (usable in this directory):'
+ @echo ' make local && ./hg version'
+
+all: build doc
+
+local:
+ $(PYTHON) setup.py $(PURE) build_py -c -d . build_ext -i build_mo
+ $(PYTHON) hg version
+
+build:
+ $(PYTHON) setup.py $(PURE) build
+
+doc:
+ $(MAKE) -C doc
+
+clean:
+ -$(PYTHON) setup.py clean --all # ignore errors from this command
+ find . -name '*.py[cdo]' -exec rm -f '{}' ';'
+ rm -f MANIFEST mercurial/__version__.py mercurial/*.so tests/*.err
+ rm -rf locale
+ $(MAKE) -C doc clean
+
+install: install-bin install-doc
+
+install-bin: build
+ $(PYTHON) setup.py $(PURE) install --prefix="$(PREFIX)" --force
+
+install-doc: doc
+ cd doc && $(MAKE) $(MFLAGS) install
+
+install-home: install-home-bin install-home-doc
+
+install-home-bin: build
+ $(PYTHON) setup.py $(PURE) install --home="$(HOME)" --force
+
+install-home-doc: doc
+ cd doc && $(MAKE) $(MFLAGS) PREFIX="$(HOME)" install
+
+MANIFEST-doc:
+ $(MAKE) -C doc MANIFEST
+
+MANIFEST: MANIFEST-doc
+ hg manifest > MANIFEST
+ echo mercurial/__version__.py >> MANIFEST
+ cat doc/MANIFEST >> MANIFEST
+
+dist: tests dist-notests
+
+dist-notests: doc MANIFEST
+ TAR_OPTIONS="--owner=root --group=root --mode=u+w,go-w,a+rX-s" $(PYTHON) setup.py -q sdist
+
+tests:
+ cd tests && $(PYTHON) run-tests.py $(TESTFLAGS)
+
+test-%:
+ cd tests && $(PYTHON) run-tests.py $(TESTFLAGS) $@
+
+update-pot: i18n/hg.pot
+
+i18n/hg.pot: $(PYTHON_FILES)
+ $(PYTHON) i18n/hggettext mercurial/commands.py \
+ hgext/*.py hgext/*/__init__.py > i18n/hg.pot
+ # All strings marked for translation in Mercurial contain
+ # ASCII characters only. But some files contain string
+ # literals like this '\037\213'. xgettext thinks it has to
+ # parse them even though they are not marked for translation.
+ # Extracting with an explicit encoding of ISO-8859-1 will make
+ # xgettext "parse" and ignore them.
+ echo $^ | xargs \
+ xgettext --package-name "Mercurial" \
+ --msgid-bugs-address "<mercurial-devel@selenic.com>" \
+ --copyright-holder "Matt Mackall <mpm@selenic.com> and others" \
+ --from-code ISO-8859-1 --join --sort-by-file \
+ -d hg -p i18n -o hg.pot
+
+%.po: i18n/hg.pot
+ msgmerge --no-location --update $@ $^
+
+.PHONY: help all local build doc clean install install-bin install-doc \
+ install-home install-home-bin install-home-doc dist dist-notests tests \
+ update-pot
diff --git a/sys/src/cmd/hg/README b/sys/src/cmd/hg/README
new file mode 100644
index 000000000..d67e780a6
--- /dev/null
+++ b/sys/src/cmd/hg/README
@@ -0,0 +1,10 @@
+Basic install:
+
+ $ make # see install targets
+ $ make install # do a system-wide install
+ $ hg debuginstall # sanity-check setup
+ $ hg # see help
+
+See http://mercurial.selenic.com/ for detailed installation
+instructions, platform-specific notes, and Mercurial user information.
+
diff --git a/sys/src/cmd/hg/README.Plan9 b/sys/src/cmd/hg/README.Plan9
new file mode 100644
index 000000000..4ed1d16b5
--- /dev/null
+++ b/sys/src/cmd/hg/README.Plan9
@@ -0,0 +1,5 @@
+Mercurial (cloned in 20090826)
+
+Federico G. Benavento
+August 2009
+benavento@gmail.com
diff --git a/sys/src/cmd/hg/contrib/bash_completion b/sys/src/cmd/hg/contrib/bash_completion
new file mode 100644
index 000000000..28f1d0b41
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/bash_completion
@@ -0,0 +1,532 @@
+# bash completion for the Mercurial distributed SCM
+
+# Docs:
+#
+# If you source this file from your .bashrc, bash should be able to
+# complete a command line that uses hg with all the available commands
+# and options and sometimes even arguments.
+#
+# Mercurial allows you to define additional commands through extensions.
+# Bash should be able to automatically figure out the name of these new
+# commands and their options. See below for how to define _hg_opt_foo
+# and _hg_cmd_foo functions to fine-tune the completion for option and
+# non-option arguments, respectively.
+#
+#
+# Notes about completion for specific commands:
+#
+# - the completion function for the email command from the patchbomb
+# extension will try to call _hg_emails to get a list of e-mail
+# addresses. It's up to the user to define this function. For
+# example, put the addresses of the lists that you usually patchbomb
+# in ~/.patchbomb-to and the addresses that you usually use to send
+# the patchbombs in ~/.patchbomb-from and use something like this:
+#
+# _hg_emails()
+# {
+# if [ -r ~/.patchbomb-$1 ]; then
+# cat ~/.patchbomb-$1
+# fi
+# }
+#
+#
+# Writing completion functions for additional commands:
+#
+# If it exists, the function _hg_cmd_foo will be called without
+# arguments to generate the completion candidates for the hg command
+# "foo". If the command receives some arguments that aren't options
+# even though they start with a "-", you can define a function called
+# _hg_opt_foo to generate the completion candidates. If _hg_opt_foo
+# doesn't return 0, regular completion for options is attempted.
+#
+# In addition to the regular completion variables provided by bash,
+# the following variables are also set:
+# - $hg - the hg program being used (e.g. /usr/bin/hg)
+# - $cmd - the name of the hg command being completed
+# - $cmd_index - the index of $cmd in $COMP_WORDS
+# - $cur - the current argument being completed
+# - $prev - the argument before $cur
+# - $global_args - "|"-separated list of global options that accept
+# an argument (e.g. '--cwd|-R|--repository')
+# - $canonical - 1 if we canonicalized $cmd before calling the function
+# 0 otherwise
+#
+
+shopt -s extglob
+
+_hg_commands()
+{
+ local commands
+ commands="$("$hg" debugcomplete "$cur" 2>/dev/null)" || commands=""
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$commands' -- "$cur"))
+}
+
+_hg_paths()
+{
+ local paths="$("$hg" paths 2>/dev/null | sed -e 's/ = .*$//')"
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$paths' -- "$cur"))
+}
+
+_hg_repos()
+{
+ local i
+ for i in $(compgen -d -- "$cur"); do
+ test ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i")
+ done
+}
+
+_hg_status()
+{
+ local files="$("$hg" status -n$1 . 2>/dev/null)"
+ local IFS=$'\n'
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
+}
+
+_hg_tags()
+{
+ local tags="$("$hg" tags -q 2>/dev/null)"
+ local IFS=$'\n'
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$tags' -- "$cur"))
+}
+
+_hg_branches()
+{
+ local branches="$("$hg" branches -q 2>/dev/null)"
+ local IFS=$'\n'
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$branches' -- "$cur"))
+}
+
+# this is "kind of" ugly...
+_hg_count_non_option()
+{
+ local i count=0
+ local filters="$1"
+
+ for ((i=1; $i<=$COMP_CWORD; i++)); do
+ if [[ "${COMP_WORDS[i]}" != -* ]]; then
+ if [[ ${COMP_WORDS[i-1]} == @($filters|$global_args) ]]; then
+ continue
+ fi
+ count=$(($count + 1))
+ fi
+ done
+
+ echo $(($count - 1))
+}
+
+_hg()
+{
+ local cur prev cmd cmd_index opts i
+ # global options that receive an argument
+ local global_args='--cwd|-R|--repository'
+ local hg="$1"
+ local canonical=0
+
+ COMPREPLY=()
+ cur="$2"
+ prev="$3"
+
+ # searching for the command
+ # (first non-option argument that doesn't follow a global option that
+ # receives an argument)
+ for ((i=1; $i<=$COMP_CWORD; i++)); do
+ if [[ ${COMP_WORDS[i]} != -* ]]; then
+ if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
+ cmd="${COMP_WORDS[i]}"
+ cmd_index=$i
+ break
+ fi
+ fi
+ done
+
+ if [[ "$cur" == -* ]]; then
+ if [ "$(type -t "_hg_opt_$cmd")" = function ] && "_hg_opt_$cmd"; then
+ return
+ fi
+
+ opts=$("$hg" debugcomplete --options "$cmd" 2>/dev/null)
+
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur"))
+ return
+ fi
+
+ # global options
+ case "$prev" in
+ -R|--repository)
+ _hg_paths
+ _hg_repos
+ return
+ ;;
+ --cwd)
+ # Stick with default bash completion
+ return
+ ;;
+ esac
+
+ if [ -z "$cmd" ] || [ $COMP_CWORD -eq $i ]; then
+ _hg_commands
+ return
+ fi
+
+ # try to generate completion candidates for whatever command the user typed
+ local help
+ if _hg_command_specific; then
+ return
+ fi
+
+ # canonicalize the command name and try again
+ help=$("$hg" help "$cmd" 2>/dev/null)
+ if [ $? -ne 0 ]; then
+ # Probably either the command doesn't exist or it's ambiguous
+ return
+ fi
+ cmd=${help#hg }
+ cmd=${cmd%%[$' \n']*}
+ canonical=1
+ _hg_command_specific
+}
+
+_hg_command_specific()
+{
+ if [ "$(type -t "_hg_cmd_$cmd")" = function ]; then
+ "_hg_cmd_$cmd"
+ return 0
+ fi
+
+ if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" == --rev ]; then
+ if [ $canonical = 1 ]; then
+ _hg_tags
+ _hg_branches
+ return 0
+ elif [[ status != "$cmd"* ]]; then
+ _hg_tags
+ _hg_branches
+ return 0
+ else
+ return 1
+ fi
+ fi
+
+ case "$cmd" in
+ help)
+ _hg_commands
+ ;;
+ export)
+ if _hg_ext_mq_patchlist qapplied && [ "${COMPREPLY[*]}" ]; then
+ return 0
+ fi
+ _hg_tags
+ _hg_branches
+ ;;
+ manifest|update)
+ _hg_tags
+ _hg_branches
+ ;;
+ pull|push|outgoing|incoming)
+ _hg_paths
+ _hg_repos
+ ;;
+ paths)
+ _hg_paths
+ ;;
+ add)
+ _hg_status "u"
+ ;;
+ merge)
+ _hg_tags
+ _hg_branches
+ ;;
+ commit)
+ _hg_status "mar"
+ ;;
+ remove)
+ _hg_status "d"
+ ;;
+ forget)
+ _hg_status "a"
+ ;;
+ diff)
+ _hg_status "mar"
+ ;;
+ revert)
+ _hg_status "mard"
+ ;;
+ clone)
+ local count=$(_hg_count_non_option)
+ if [ $count = 1 ]; then
+ _hg_paths
+ fi
+ _hg_repos
+ ;;
+ debugindex|debugindexdot)
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.i" -- "$cur"))
+ ;;
+ debugdata)
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.d" -- "$cur"))
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+
+ return 0
+}
+
+complete -o bashdefault -o default -F _hg hg 2>/dev/null \
+ || complete -o default -F _hg hg
+
+
+# Completion for commands provided by extensions
+
+# mq
+_hg_ext_mq_patchlist()
+{
+ local patches
+ patches=$("$hg" $1 2>/dev/null)
+ if [ $? -eq 0 ] && [ "$patches" ]; then
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur"))
+ return 0
+ fi
+ return 1
+}
+
+_hg_ext_mq_queues()
+{
+ local root=$("$hg" root 2>/dev/null)
+ local n
+ for n in $(cd "$root"/.hg && compgen -d -- "$cur"); do
+ # I think we're usually not interested in the regular "patches" queue
+ # so just filter it.
+ if [ "$n" != patches ] && [ -e "$root/.hg/$n/series" ]; then
+ COMPREPLY=(${COMPREPLY[@]:-} "$n")
+ fi
+ done
+}
+
+_hg_cmd_qpop()
+{
+ if [[ "$prev" = @(-n|--name) ]]; then
+ _hg_ext_mq_queues
+ return
+ fi
+ _hg_ext_mq_patchlist qapplied
+}
+
+_hg_cmd_qpush()
+{
+ if [[ "$prev" = @(-n|--name) ]]; then
+ _hg_ext_mq_queues
+ return
+ fi
+ _hg_ext_mq_patchlist qunapplied
+}
+
+_hg_cmd_qgoto()
+{
+ if [[ "$prev" = @(-n|--name) ]]; then
+ _hg_ext_mq_queues
+ return
+ fi
+ _hg_ext_mq_patchlist qseries
+}
+
+_hg_cmd_qdelete()
+{
+ local qcmd=qunapplied
+ if [[ "$prev" = @(-r|--rev) ]]; then
+ qcmd=qapplied
+ fi
+ _hg_ext_mq_patchlist $qcmd
+}
+
+_hg_cmd_qsave()
+{
+ if [[ "$prev" = @(-n|--name) ]]; then
+ _hg_ext_mq_queues
+ return
+ fi
+}
+
+_hg_cmd_strip()
+{
+ _hg_tags
+ _hg_branches
+}
+
+_hg_cmd_qcommit()
+{
+ local root=$("$hg" root 2>/dev/null)
+ # this is run in a sub-shell, so we can't use _hg_status
+ local files=$(cd "$root/.hg/patches" 2>/dev/null &&
+ "$hg" status -nmar 2>/dev/null)
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
+}
+
+_hg_cmd_qfold()
+{
+ _hg_ext_mq_patchlist qunapplied
+}
+
+_hg_cmd_qrename()
+{
+ _hg_ext_mq_patchlist qseries
+}
+
+_hg_cmd_qheader()
+{
+ _hg_ext_mq_patchlist qseries
+}
+
+_hg_cmd_qclone()
+{
+ local count=$(_hg_count_non_option)
+ if [ $count = 1 ]; then
+ _hg_paths
+ fi
+ _hg_repos
+}
+
+_hg_ext_mq_guards()
+{
+ "$hg" qselect --series 2>/dev/null | sed -e 's/^.//'
+}
+
+_hg_cmd_qselect()
+{
+ local guards=$(_hg_ext_mq_guards)
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$guards' -- "$cur"))
+}
+
+_hg_cmd_qguard()
+{
+ local prefix=''
+
+ if [[ "$cur" == +* ]]; then
+ prefix=+
+ elif [[ "$cur" == -* ]]; then
+ prefix=-
+ fi
+ local ncur=${cur#[-+]}
+
+ if ! [ "$prefix" ]; then
+ _hg_ext_mq_patchlist qseries
+ return
+ fi
+
+ local guards=$(_hg_ext_mq_guards)
+ COMPREPLY=(${COMPREPLY[@]:-} $(compgen -P $prefix -W '$guards' -- "$ncur"))
+}
+
+_hg_opt_qguard()
+{
+ local i
+ for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
+ if [[ ${COMP_WORDS[i]} != -* ]]; then
+ if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
+ _hg_cmd_qguard
+ return 0
+ fi
+ elif [ "${COMP_WORDS[i]}" = -- ]; then
+ _hg_cmd_qguard
+ return 0
+ fi
+ done
+ return 1
+}
+
+
+# hbisect
+_hg_cmd_bisect()
+{
+ local i subcmd
+
+ # find the sub-command
+ for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
+ if [[ ${COMP_WORDS[i]} != -* ]]; then
+ if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
+ subcmd="${COMP_WORDS[i]}"
+ break
+ fi
+ fi
+ done
+
+ if [ -z "$subcmd" ] || [ $COMP_CWORD -eq $i ] || [ "$subcmd" = help ]; then
+ COMPREPLY=(${COMPREPLY[@]:-}
+ $(compgen -W 'bad good help init next reset' -- "$cur"))
+ return
+ fi
+
+ case "$subcmd" in
+ good|bad)
+ _hg_tags
+ _hg_branches
+ ;;
+ esac
+
+ return
+}
+
+
+# patchbomb
+_hg_cmd_email()
+{
+ case "$prev" in
+ -c|--cc|-t|--to|-f|--from|--bcc)
+ # we need an e-mail address. let the user provide a function
+ # to get them
+ if [ "$(type -t _hg_emails)" = function ]; then
+ local arg=to
+ if [[ "$prev" == @(-f|--from) ]]; then
+ arg=from
+ fi
+ local addresses=$(_hg_emails $arg)
+ COMPREPLY=(${COMPREPLY[@]:-}
+ $(compgen -W '$addresses' -- "$cur"))
+ fi
+ return
+ ;;
+ -m|--mbox)
+ # fallback to standard filename completion
+ return
+ ;;
+ -s|--subject)
+ # free form string
+ return
+ ;;
+ esac
+
+ _hg_tags
+ _hg_branches
+ return
+}
+
+
+# gpg
+_hg_cmd_sign()
+{
+ _hg_tags
+ _hg_branches
+}
+
+
+# transplant
+_hg_cmd_transplant()
+{
+ case "$prev" in
+ -s|--source)
+ _hg_paths
+ _hg_repos
+ return
+ ;;
+ --filter)
+ # standard filename completion
+ return
+ ;;
+ esac
+
+ # all other transplant options values and command parameters are revisions
+ _hg_tags
+ _hg_branches
+ return
+}
+
diff --git a/sys/src/cmd/hg/contrib/buildrpm b/sys/src/cmd/hg/contrib/buildrpm
new file mode 100755
index 000000000..641ddbfac
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/buildrpm
@@ -0,0 +1,72 @@
+#!/bin/sh
+#
+# Build a Mercurial RPM in place.
+#
+# Bryan O'Sullivan <bos@serpentine.com>
+#
+# Tested on
+# - Fedora 10
+# - Fedora 11
+# - Centos 5.3 (with Fedora EPEL repo for asciidoc)
+
+HG="`dirname $0`/../hg"
+PYTHONPATH="`dirname $0`/../mercurial/pure"
+export PYTHONPATH
+
+root="`$HG root 2>/dev/null`"
+specfile=contrib/mercurial.spec
+
+if [ -z "$root" ]; then
+ echo 'You are not inside a Mercurial repository!' 1>&2
+ exit 1
+fi
+
+rpmdir=/tmp/"`basename $root | sed 's/ /_/'`"-rpm # FIXME: Insecure /tmp handling
+
+cd "$root"
+rm -rf $rpmdir
+mkdir -p $rpmdir/RPMS
+$HG clone "$root" $rpmdir/BUILD
+
+if [ ! -f $specfile ]; then
+ echo "Cannot find $specfile!" 1>&2
+ exit 1
+fi
+
+tmpspec=/tmp/`basename "$specfile"`.$$ # FIXME: Insecure /tmp handling
+# Use the most recent tag as the version.
+version=`$HG tags | python -c 'import sys; print [l for l in sys.stdin.readlines() if l[0].isdigit()][0].split()[0]'`
+# Compute the release number as the difference in revision numbers
+# between the tip and the most recent tag.
+release=`$HG tags | python -c 'import sys; l = sys.stdin.readlines(); print int(l[0].split()[1].split(":")[0]) - int([x for x in l if x[0].isdigit()][0].split()[1].split(":")[0])'`
+tip=`$HG -q tip`
+
+# Beat up the spec file
+sed -e 's,^Source:.*,Source: /dev/null,' \
+ -e "s,^Version:.*,Version: $version," \
+ -e "s,^Release:.*,Release: $release," \
+ -e "s,^%prep.*,Changeset: $tip\n\0," \
+ -e 's,^%setup.*,,' \
+ $specfile > $tmpspec
+
+cat <<EOF >> $tmpspec
+%changelog
+* `LANG=en_US date +'%a %b %d %Y'` `$HG showconfig ui.username` $version-$release
+- Automatically built via $0
+
+EOF
+$HG log \
+ --template '* {date|rfc822date} {author}\n- {desc|firstline}\n\n' \
+ .hgtags \
+ | sed -e 's/^\(\* [MTWFS][a-z][a-z]\), \([0-3][0-9]\) \([A-Z][a-z][a-z]\) /\1 \3 \2 /' \
+ -e '/^\* [MTWFS][a-z][a-z] /{s/ [012][0-9]:[0-9][0-9]:[0-9][0-9] [+-][0-9]\{4\}//}' \
+ >> $tmpspec
+
+rpmbuild --define "_topdir $rpmdir" -bb $tmpspec
+if [ $? = 0 ]; then
+ rm -rf $tmpspec $rpmdir/BUILD
+ mv $rpmdir/RPMS/*/* $rpmdir && rm -r $rpmdir/RPMS
+ echo
+ echo "Packages are in $rpmdir:"
+ ls -l $rpmdir/*.rpm
+fi
diff --git a/sys/src/cmd/hg/contrib/convert-repo b/sys/src/cmd/hg/contrib/convert-repo
new file mode 100755
index 000000000..4113f40c0
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/convert-repo
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Wrapper script around the convert.py hgext extension
+# for foreign SCM conversion to mercurial format.
+#
+
+import sys
+from mercurial import ui, fancyopts
+from hgext import convert
+
+# Options extracted from the cmdtable
+func, options, help = convert.cmdtable['convert']
+
+# An ui instance
+u = ui.ui()
+
+opts = {}
+args = []
+try:
+ args = list(fancyopts.fancyopts(sys.argv[1:], options, opts))
+ args += [None]*(3 - len(args))
+ src, dest, revmapfile = args
+except (fancyopts.getopt.GetoptError, ValueError), inst:
+ u.warn('Usage:\n%s\n' % help)
+ sys.exit(-1)
+
+convert.convert(u, src, dest, revmapfile, **opts)
diff --git a/sys/src/cmd/hg/contrib/dumprevlog b/sys/src/cmd/hg/contrib/dumprevlog
new file mode 100644
index 000000000..caf287d49
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/dumprevlog
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# Dump revlogs as raw data stream
+# $ find .hg/store/ -name "*.i" | xargs dumprevlog > repo.dump
+
+import sys
+from mercurial import revlog, node, util
+
+for fp in (sys.stdin, sys.stdout, sys.stderr):
+ util.set_binary(fp)
+
+for f in sys.argv[1:]:
+ binopen = lambda fn: open(fn, 'rb')
+ r = revlog.revlog(binopen, f)
+ print "file:", f
+ for i in r:
+ n = r.node(i)
+ p = r.parents(n)
+ d = r.revision(n)
+ print "node:", node.hex(n)
+ print "linkrev:", r.linkrev(i)
+ print "parents:", node.hex(p[0]), node.hex(p[1])
+ print "length:", len(d)
+ print "-start-"
+ print d
+ print "-end-"
diff --git a/sys/src/cmd/hg/contrib/git-viz/git-cat-file b/sys/src/cmd/hg/contrib/git-viz/git-cat-file
new file mode 100644
index 000000000..ee4a0aed6
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/git-viz/git-cat-file
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+op=`basename $0 | sed -e 's/^git-//'`
+exec hgit $op "$@"
+
diff --git a/sys/src/cmd/hg/contrib/git-viz/git-diff-tree b/sys/src/cmd/hg/contrib/git-viz/git-diff-tree
new file mode 100644
index 000000000..ee4a0aed6
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/git-viz/git-diff-tree
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+op=`basename $0 | sed -e 's/^git-//'`
+exec hgit $op "$@"
+
diff --git a/sys/src/cmd/hg/contrib/git-viz/git-rev-list b/sys/src/cmd/hg/contrib/git-viz/git-rev-list
new file mode 100644
index 000000000..ee4a0aed6
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/git-viz/git-rev-list
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+op=`basename $0 | sed -e 's/^git-//'`
+exec hgit $op "$@"
+
diff --git a/sys/src/cmd/hg/contrib/git-viz/git-rev-tree b/sys/src/cmd/hg/contrib/git-viz/git-rev-tree
new file mode 100644
index 000000000..ee4a0aed6
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/git-viz/git-rev-tree
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+op=`basename $0 | sed -e 's/^git-//'`
+exec hgit $op "$@"
+
diff --git a/sys/src/cmd/hg/contrib/git-viz/hg-viz b/sys/src/cmd/hg/contrib/git-viz/hg-viz
new file mode 100644
index 000000000..81bd57b45
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/git-viz/hg-viz
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+set -e
+
+if test x"$1" != x ; then
+ cd $1
+fi
+
+if [ ! -d ".hg" ]; then
+ echo "${1:-.} is not a mercurial repository" 1>&2
+ echo "Aborting" 1>&2
+ exit 1
+fi
+if [ ! -d ".git" ]; then
+ mkdir -v ".git"
+fi
+if [ -e ".git/HEAD" ]; then
+ if [ ! -e ".git/HEAD.hg-viz-save" ]; then
+ mv -v ".git/HEAD" ".git/HEAD.hg-viz-save"
+ else
+ rm -vf ".git/HEAD"
+ fi
+fi
+hg history | head -1 | awk -F: '{print $3}' > .git/HEAD
+git-viz
+
diff --git a/sys/src/cmd/hg/contrib/hg-relink b/sys/src/cmd/hg/contrib/hg-relink
new file mode 100755
index 000000000..266e7edfc
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/hg-relink
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2007 Brendan Cully <brendan@kublai.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os, sys
+
+class ConfigError(Exception): pass
+
+def usage():
+ print """relink <source> <destination>
+ Recreate hard links between source and destination repositories"""
+
+class Config:
+ def __init__(self, args):
+ if len(args) != 3:
+ raise ConfigError("wrong number of arguments")
+ self.src = os.path.abspath(args[1])
+ self.dst = os.path.abspath(args[2])
+ for d in (self.src, self.dst):
+ if not os.path.exists(os.path.join(d, '.hg')):
+ raise ConfigError("%s: not a mercurial repository" % d)
+
+def collect(src):
+ seplen = len(os.path.sep)
+ candidates = []
+ for dirpath, dirnames, filenames in os.walk(src):
+ relpath = dirpath[len(src) + seplen:]
+ for filename in filenames:
+ if not filename.endswith('.i'):
+ continue
+ st = os.stat(os.path.join(dirpath, filename))
+ candidates.append((os.path.join(relpath, filename), st))
+
+ return candidates
+
+def prune(candidates, dst):
+ def getdatafile(path):
+ if not path.endswith('.i'):
+ return None, None
+ df = path[:-1] + 'd'
+ try:
+ st = os.stat(df)
+ except OSError:
+ return None, None
+ return df, st
+
+ def linkfilter(dst, st):
+ try:
+ ts = os.stat(dst)
+ except OSError:
+ # Destination doesn't have this file?
+ return False
+ if st.st_ino == ts.st_ino:
+ return False
+ if st.st_dev != ts.st_dev:
+ # No point in continuing
+ raise Exception('Source and destination are on different devices')
+ if st.st_size != ts.st_size:
+ # TODO: compare revlog heads
+ return False
+ return st
+
+ targets = []
+ for fn, st in candidates:
+ tgt = os.path.join(dst, fn)
+ ts = linkfilter(tgt, st)
+ if not ts:
+ continue
+ targets.append((fn, ts.st_size))
+ df, ts = getdatafile(tgt)
+ if df:
+ targets.append((fn[:-1] + 'd', ts.st_size))
+
+ return targets
+
+def relink(src, dst, files):
+ def relinkfile(src, dst):
+ bak = dst + '.bak'
+ os.rename(dst, bak)
+ try:
+ os.link(src, dst)
+ except OSError:
+ os.rename(bak, dst)
+ raise
+ os.remove(bak)
+
+ CHUNKLEN = 65536
+ relinked = 0
+ savedbytes = 0
+
+ for f, sz in files:
+ source = os.path.join(src, f)
+ tgt = os.path.join(dst, f)
+ sfp = file(source)
+ dfp = file(tgt)
+ sin = sfp.read(CHUNKLEN)
+ while sin:
+ din = dfp.read(CHUNKLEN)
+ if sin != din:
+ break
+ sin = sfp.read(CHUNKLEN)
+ if sin:
+ continue
+ try:
+ relinkfile(source, tgt)
+ print 'Relinked %s' % f
+ relinked += 1
+ savedbytes += sz
+ except OSError, inst:
+ print '%s: %s' % (tgt, str(inst))
+
+ print 'Relinked %d files (%d bytes reclaimed)' % (relinked, savedbytes)
+
+try:
+ cfg = Config(sys.argv)
+except ConfigError, inst:
+ print str(inst)
+ usage()
+ sys.exit(1)
+
+src = os.path.join(cfg.src, '.hg')
+dst = os.path.join(cfg.dst, '.hg')
+candidates = collect(src)
+targets = prune(candidates, dst)
+relink(src, dst, targets)
diff --git a/sys/src/cmd/hg/contrib/hg-ssh b/sys/src/cmd/hg/contrib/hg-ssh
new file mode 100755
index 000000000..64a6e4c02
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/hg-ssh
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+#
+# Copyright 2005-2007 by Intevation GmbH <intevation@intevation.de>
+#
+# Author(s):
+# Thomas Arendsen Hein <thomas@intevation.de>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+"""
+hg-ssh - a wrapper for ssh access to a limited set of mercurial repos
+
+To be used in ~/.ssh/authorized_keys with the "command" option, see sshd(8):
+command="hg-ssh path/to/repo1 /path/to/repo2 ~/repo3 ~user/repo4" ssh-dss ...
+(probably together with these other useful options:
+ no-port-forwarding,no-X11-forwarding,no-agent-forwarding)
+
+This allows pull/push over ssh to to the repositories given as arguments.
+
+If all your repositories are subdirectories of a common directory, you can
+allow shorter paths with:
+command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2"
+
+You can use pattern matching of your normal shell, e.g.:
+command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}"
+"""
+
+# enable importing on demand to reduce startup time
+from mercurial import demandimport; demandimport.enable()
+
+from mercurial import dispatch
+
+import sys, os
+
+cwd = os.getcwd()
+allowed_paths = [os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
+ for path in sys.argv[1:]]
+orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?')
+
+if orig_cmd.startswith('hg -R ') and orig_cmd.endswith(' serve --stdio'):
+ path = orig_cmd[6:-14]
+ repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
+ if repo in allowed_paths:
+ dispatch.dispatch(['-R', repo, 'serve', '--stdio'])
+ else:
+ sys.stderr.write("Illegal repository %r\n" % repo)
+ sys.exit(-1)
+else:
+ sys.stderr.write("Illegal command %r\n" % orig_cmd)
+ sys.exit(-1)
+
diff --git a/sys/src/cmd/hg/contrib/hgdiff b/sys/src/cmd/hg/contrib/hgdiff
new file mode 100755
index 000000000..c7b9aaf34
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/hgdiff
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+
+import os, sys, struct, stat
+import difflib
+import re
+from optparse import OptionParser
+from mercurial.bdiff import bdiff, blocks
+from mercurial.mdiff import bunidiff, diffopts
+
+VERSION="0.3"
+usage = "usage: %prog [options] file1 file2"
+parser = OptionParser(usage=usage)
+
+parser.add_option("-d", "--difflib", action="store_true", default=False)
+parser.add_option('-x', '--count', default=1)
+parser.add_option('-c', '--context', type="int", default=3)
+parser.add_option('-p', '--show-c-function', action="store_true", default=False)
+parser.add_option('-w', '--ignore-all-space', action="store_true",
+ default=False)
+
+(options, args) = parser.parse_args()
+
+if not args:
+ parser.print_help()
+ sys.exit(1)
+
+# simple utility function to put all the
+# files from a directory tree into a dict
+def buildlist(names, top):
+ tlen = len(top)
+ for root, dirs, files in os.walk(top):
+ l = root[tlen + 1:]
+ for x in files:
+ p = os.path.join(root, x)
+ st = os.lstat(p)
+ if stat.S_ISREG(st.st_mode):
+ names[os.path.join(l, x)] = (st.st_dev, st.st_ino)
+
+def diff_files(file1, file2):
+ if file1 is None:
+ b = file(file2).read().splitlines(True)
+ l1 = "--- %s\n" % (file2)
+ l2 = "+++ %s\n" % (file2)
+ l3 = "@@ -0,0 +1,%d @@\n" % len(b)
+ l = [l1, l2, l3] + ["+" + e for e in b]
+ elif file2 is None:
+ a = file(file1).read().splitlines(True)
+ l1 = "--- %s\n" % (file1)
+ l2 = "+++ %s\n" % (file1)
+ l3 = "@@ -1,%d +0,0 @@\n" % len(a)
+ l = [l1, l2, l3] + ["-" + e for e in a]
+ else:
+ t1 = file(file1).read()
+ t2 = file(file2).read()
+ l1 = t1.splitlines(True)
+ l2 = t2.splitlines(True)
+ if options.difflib:
+ l = difflib.unified_diff(l1, l2, file1, file2)
+ else:
+ l = bunidiff(t1, t2, l1, l2, file1, file2,
+ diffopts(context=options.context,
+ showfunc=options.show_c_function,
+ ignorews=options.ignore_all_space))
+ for x in l:
+ if x[-1] != '\n':
+ x += "\n\ No newline at end of file\n"
+ print x,
+
+file1 = args[0]
+file2 = args[1]
+
+if os.path.isfile(file1) and os.path.isfile(file2):
+ diff_files(file1, file2)
+elif os.path.isdir(file1):
+ if not os.path.isdir(file2):
+ sys.stderr.write("file types don't match\n")
+ sys.exit(1)
+
+ d1 = {}
+ d2 = {}
+
+ buildlist(d1, file1)
+ buildlist(d2, file2)
+ keys = d1.keys()
+ keys.sort()
+ for x in keys:
+ if x not in d2:
+ f2 = None
+ else:
+ f2 = os.path.join(file2, x)
+ st1 = d1[x]
+ st2 = d2[x]
+ del d2[x]
+ if st1[0] == st2[0] and st1[1] == st2[1]:
+ sys.stderr.write("%s is a hard link\n" % x)
+ continue
+ x = os.path.join(file1, x)
+ diff_files(x, f2)
+ keys = d2.keys()
+ keys.sort()
+ for x in keys:
+ f1 = None
+ x = os.path.join(file2, x)
+ diff_files(f1, x)
+
diff --git a/sys/src/cmd/hg/contrib/hgk b/sys/src/cmd/hg/contrib/hgk
new file mode 100755
index 000000000..2031eafbf
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/hgk
@@ -0,0 +1,4001 @@
+#!/usr/bin/env wish
+
+# Copyright (C) 2005 Paul Mackerras. All rights reserved.
+# This program is free software; it may be used, copied, modified
+# and distributed under the terms of the GNU General Public Licence,
+# either version 2, or (at your option) any later version.
+#
+# See hgk.py for extension usage and configuration.
+
+
+# Modified version of Tip 171:
+# http://www.tcl.tk/cgi-bin/tct/tip/171.html
+#
+# The in_mousewheel global was added to fix strange reentrancy issues.
+# The whole snipped is activated only under windows, mouse wheel
+# bindings working already under MacOSX and Linux.
+
+if {[tk windowingsystem] eq "win32"} {
+
+set mw_classes [list Text Listbox Table TreeCtrl]
+ foreach class $mw_classes { bind $class <MouseWheel> {} }
+
+set in_mousewheel 0
+
+proc ::tk::MouseWheel {wFired X Y D {shifted 0}} {
+ global in_mousewheel
+ if { $in_mousewheel != 0 } { return }
+ # Set event to check based on call
+ set evt "<[expr {$shifted?{Shift-}:{}}]MouseWheel>"
+ # do not double-fire in case the class already has a binding
+ if {[bind [winfo class $wFired] $evt] ne ""} { return }
+ # obtain the window the mouse is over
+ set w [winfo containing $X $Y]
+ # if we are outside the app, try and scroll the focus widget
+ if {![winfo exists $w]} { catch {set w [focus]} }
+ if {[winfo exists $w]} {
+
+ if {[bind $w $evt] ne ""} {
+ # Awkward ... this widget has a MouseWheel binding, but to
+ # trigger successfully in it, we must give it focus.
+ catch {focus} old
+ if {$w ne $old} { focus $w }
+ set in_mousewheel 1
+ event generate $w $evt -rootx $X -rooty $Y -delta $D
+ set in_mousewheel 0
+ if {$w ne $old} { focus $old }
+ return
+ }
+
+ # aqua and x11/win32 have different delta handling
+ if {[tk windowingsystem] ne "aqua"} {
+ set delta [expr {- ($D / 30)}]
+ } else {
+ set delta [expr {- ($D)}]
+ }
+ # scrollbars have different call conventions
+ if {[string match "*Scrollbar" [winfo class $w]]} {
+ catch {tk::ScrollByUnits $w \
+ [string index [$w cget -orient] 0] $delta}
+ } else {
+ set cmd [list $w [expr {$shifted ? "xview" : "yview"}] \
+ scroll $delta units]
+ # Walking up to find the proper widget (handles cases like
+ # embedded widgets in a canvas)
+ while {[catch $cmd] && [winfo toplevel $w] ne $w} {
+ set w [winfo parent $w]
+ }
+ }
+ }
+}
+
+bind all <MouseWheel> [list ::tk::MouseWheel %W %X %Y %D 0]
+
+# end of win32 section
+}
+
+
+# Unify right mouse button handling.
+# See "mouse buttons on macintosh" thread on comp.lang.tcl
+if {[tk windowingsystem] eq "aqua"} {
+ event add <<B3>> <Control-ButtonPress-1>
+ event add <<B3>> <Button-2>
+} else {
+ event add <<B3>> <Button-3>
+}
+
+proc gitdir {} {
+ global env
+ if {[info exists env(GIT_DIR)]} {
+ return $env(GIT_DIR)
+ } else {
+ return ".hg"
+ }
+}
+
+proc getcommits {rargs} {
+ global commits commfd phase canv mainfont env
+ global startmsecs nextupdate ncmupdate
+ global ctext maincursor textcursor leftover
+
+ # check that we can find a .git directory somewhere...
+ set gitdir [gitdir]
+ if {![file isdirectory $gitdir]} {
+ error_popup "Cannot find the git directory \"$gitdir\"."
+ exit 1
+ }
+ set commits {}
+ set phase getcommits
+ set startmsecs [clock clicks -milliseconds]
+ set nextupdate [expr $startmsecs + 100]
+ set ncmupdate 1
+ set limit 0
+ set revargs {}
+ for {set i 0} {$i < [llength $rargs]} {incr i} {
+ set opt [lindex $rargs $i]
+ if {$opt == "--limit"} {
+ incr i
+ set limit [lindex $rargs $i]
+ } else {
+ lappend revargs $opt
+ }
+ }
+ if [catch {
+ set parse_args [concat --default HEAD $revargs]
+ set parse_temp [eval exec {$env(HG)} --config ui.report_untrusted=false debug-rev-parse $parse_args]
+ regsub -all "\r\n" $parse_temp "\n" parse_temp
+ set parsed_args [split $parse_temp "\n"]
+ } err] {
+ # if git-rev-parse failed for some reason...
+ if {$rargs == {}} {
+ set revargs HEAD
+ }
+ set parsed_args $revargs
+ }
+ if {$limit > 0} {
+ set parsed_args [concat -n $limit $parsed_args]
+ }
+ if [catch {
+ set commfd [open "|{$env(HG)} --config ui.report_untrusted=false debug-rev-list --header --topo-order --parents $parsed_args" r]
+ } err] {
+ puts stderr "Error executing hg debug-rev-list: $err"
+ exit 1
+ }
+ set leftover {}
+ fconfigure $commfd -blocking 0 -translation lf
+ fileevent $commfd readable [list getcommitlines $commfd]
+ $canv delete all
+ $canv create text 3 3 -anchor nw -text "Reading commits..." \
+ -font $mainfont -tags textitems
+ . config -cursor watch
+ settextcursor watch
+}
+
+proc getcommitlines {commfd} {
+ global commits parents cdate children
+ global commitlisted phase commitinfo nextupdate
+ global stopped redisplaying leftover
+
+ set stuff [read $commfd]
+ if {$stuff == {}} {
+ if {![eof $commfd]} return
+ # set it blocking so we wait for the process to terminate
+ fconfigure $commfd -blocking 1
+ if {![catch {close $commfd} err]} {
+ after idle finishcommits
+ return
+ }
+ if {[string range $err 0 4] == "usage"} {
+ set err \
+{Gitk: error reading commits: bad arguments to git-rev-list.
+(Note: arguments to gitk are passed to git-rev-list
+to allow selection of commits to be displayed.)}
+ } else {
+ set err "Error reading commits: $err"
+ }
+ error_popup $err
+ exit 1
+ }
+ set start 0
+ while 1 {
+ set i [string first "\0" $stuff $start]
+ if {$i < 0} {
+ append leftover [string range $stuff $start end]
+ return
+ }
+ set cmit [string range $stuff $start [expr {$i - 1}]]
+ if {$start == 0} {
+ set cmit "$leftover$cmit"
+ set leftover {}
+ }
+ set start [expr {$i + 1}]
+ regsub -all "\r\n" $cmit "\n" cmit
+ set j [string first "\n" $cmit]
+ set ok 0
+ if {$j >= 0} {
+ set ids [string range $cmit 0 [expr {$j - 1}]]
+ set ok 1
+ foreach id $ids {
+ if {![regexp {^[0-9a-f]{12}$} $id]} {
+ set ok 0
+ break
+ }
+ }
+ }
+ if {!$ok} {
+ set shortcmit $cmit
+ if {[string length $shortcmit] > 80} {
+ set shortcmit "[string range $shortcmit 0 80]..."
+ }
+ error_popup "Can't parse hg debug-rev-list output: {$shortcmit}"
+ exit 1
+ }
+ set id [lindex $ids 0]
+ set olds [lrange $ids 1 end]
+ set cmit [string range $cmit [expr {$j + 1}] end]
+ lappend commits $id
+ set commitlisted($id) 1
+ parsecommit $id $cmit 1 [lrange $ids 1 end]
+ drawcommit $id
+ if {[clock clicks -milliseconds] >= $nextupdate} {
+ doupdate 1
+ }
+ while {$redisplaying} {
+ set redisplaying 0
+ if {$stopped == 1} {
+ set stopped 0
+ set phase "getcommits"
+ foreach id $commits {
+ drawcommit $id
+ if {$stopped} break
+ if {[clock clicks -milliseconds] >= $nextupdate} {
+ doupdate 1
+ }
+ }
+ }
+ }
+ }
+}
+
+proc doupdate {reading} {
+ global commfd nextupdate numcommits ncmupdate
+
+ if {$reading} {
+ fileevent $commfd readable {}
+ }
+ update
+ set nextupdate [expr {[clock clicks -milliseconds] + 100}]
+ if {$numcommits < 100} {
+ set ncmupdate [expr {$numcommits + 1}]
+ } elseif {$numcommits < 10000} {
+ set ncmupdate [expr {$numcommits + 10}]
+ } else {
+ set ncmupdate [expr {$numcommits + 100}]
+ }
+ if {$reading} {
+ fileevent $commfd readable [list getcommitlines $commfd]
+ }
+}
+
+proc readcommit {id} {
+ global env
+ if [catch {set contents [exec $env(HG) --config ui.report_untrusted=false debug-cat-file commit $id]}] return
+ parsecommit $id $contents 0 {}
+}
+
+proc parsecommit {id contents listed olds} {
+ global commitinfo children nchildren parents nparents cdate ncleft
+ global firstparents
+
+ set inhdr 1
+ set comment {}
+ set headline {}
+ set auname {}
+ set audate {}
+ set comname {}
+ set comdate {}
+ set rev {}
+ set branch {}
+ if {![info exists nchildren($id)]} {
+ set children($id) {}
+ set nchildren($id) 0
+ set ncleft($id) 0
+ }
+ set parents($id) $olds
+ set nparents($id) [llength $olds]
+ foreach p $olds {
+ if {![info exists nchildren($p)]} {
+ set children($p) [list $id]
+ set nchildren($p) 1
+ set ncleft($p) 1
+ } elseif {[lsearch -exact $children($p) $id] < 0} {
+ lappend children($p) $id
+ incr nchildren($p)
+ incr ncleft($p)
+ }
+ }
+ regsub -all "\r\n" $contents "\n" contents
+ foreach line [split $contents "\n"] {
+ if {$inhdr} {
+ set line [split $line]
+ if {$line == {}} {
+ set inhdr 0
+ } else {
+ set tag [lindex $line 0]
+ if {$tag == "author"} {
+ set x [expr {[llength $line] - 2}]
+ set audate [lindex $line $x]
+ set auname [join [lrange $line 1 [expr {$x - 1}]]]
+ } elseif {$tag == "committer"} {
+ set x [expr {[llength $line] - 2}]
+ set comdate [lindex $line $x]
+ set comname [join [lrange $line 1 [expr {$x - 1}]]]
+ } elseif {$tag == "revision"} {
+ set rev [lindex $line 1]
+ } elseif {$tag == "branch"} {
+ set branch [join [lrange $line 1 end]]
+ }
+ }
+ } else {
+ if {$comment == {}} {
+ set headline [string trim $line]
+ } else {
+ append comment "\n"
+ }
+ if {!$listed} {
+ # git-rev-list indents the comment by 4 spaces;
+ # if we got this via git-cat-file, add the indentation
+ append comment " "
+ }
+ append comment $line
+ }
+ }
+ if {$audate != {}} {
+ set audate [clock format $audate -format "%Y-%m-%d %H:%M:%S"]
+ }
+ if {$comdate != {}} {
+ set cdate($id) $comdate
+ set comdate [clock format $comdate -format "%Y-%m-%d %H:%M:%S"]
+ }
+ set commitinfo($id) [list $headline $auname $audate \
+ $comname $comdate $comment $rev $branch]
+
+ if {[info exists firstparents]} {
+ set i [lsearch $firstparents $id]
+ if {$i != -1} {
+ # remove the parent from firstparents, possible building
+ # an empty list
+ set firstparents [concat \
+ [lrange $firstparents 0 [expr $i - 1]] \
+ [lrange $firstparents [expr $i + 1] end]]
+ if {$firstparents eq {}} {
+ # we have found all parents of the first changeset
+ # which means that we can safely select the first line
+ after idle {
+ selectline 0 0
+ }
+ }
+ }
+ } else {
+ # this is the first changeset, save the parents
+ set firstparents $olds
+ if {$firstparents eq {}} {
+ # a repository with a single changeset
+ after idle {
+ selectline 0 0
+ }
+ }
+ }
+}
+
+proc readrefs {} {
+ global tagids idtags headids idheads tagcontents env curid
+
+ set status [catch {exec $env(HG) --config ui.report_untrusted=false id} curid]
+ if { $status != 0 } {
+ puts $::errorInfo
+ if { ![string equal $::errorCode NONE] } {
+ exit 2
+ }
+ }
+ regexp -- {[[:xdigit:]]+} $curid curid
+
+ set status [catch {exec $env(HG) --config ui.report_untrusted=false tags} tags]
+ if { $status != 0 } {
+ puts $::errorInfo
+ if { ![string equal $::errorCode NONE] } {
+ exit 2
+ }
+ }
+ regsub -all "\r\n" $tags "\n" tags
+
+ set lines [split $tags "\n"]
+ foreach f $lines {
+ regexp {(\S+)$} $f full
+ regsub {\s+(\S+)$} $f "" direct
+ set sha [split $full ':']
+ set tag [lindex $sha 1]
+ lappend tagids($direct) $tag
+ lappend idtags($tag) $direct
+ }
+
+ set status [catch {exec $env(HG) --config ui.report_untrusted=false heads} heads]
+ if { $status != 0 } {
+ puts $::errorInfo
+ if { ![string equal $::errorCode NONE] } {
+ exit 2
+ }
+ }
+ regsub -all "\r\n" $heads "\n" heads
+
+ set lines [split $heads "\n"]
+ foreach f $lines {
+ set match ""
+ regexp {changeset:\s+(\S+):(\S+)$} $f match id sha
+ if {$match != ""} {
+ lappend idheads($sha) $id
+ }
+ }
+
+}
+
+proc readotherrefs {base dname excl} {
+ global otherrefids idotherrefs
+
+ set git [gitdir]
+ set files [glob -nocomplain -types f [file join $git $base *]]
+ foreach f $files {
+ catch {
+ set fd [open $f r]
+ set line [read $fd 40]
+ if {[regexp {^[0-9a-f]{12}} $line id]} {
+ set name "$dname[file tail $f]"
+ set otherrefids($name) $id
+ lappend idotherrefs($id) $name
+ }
+ close $fd
+ }
+ }
+ set dirs [glob -nocomplain -types d [file join $git $base *]]
+ foreach d $dirs {
+ set dir [file tail $d]
+ if {[lsearch -exact $excl $dir] >= 0} continue
+ readotherrefs [file join $base $dir] "$dname$dir/" {}
+ }
+}
+
+proc allcansmousewheel {delta} {
+ set delta [expr -5*(int($delta)/abs($delta))]
+ allcanvs yview scroll $delta units
+}
+
+proc error_popup msg {
+ set w .error
+ toplevel $w
+ wm transient $w .
+ message $w.m -text $msg -justify center -aspect 400
+ pack $w.m -side top -fill x -padx 20 -pady 20
+ button $w.ok -text OK -command "destroy $w"
+ pack $w.ok -side bottom -fill x
+ bind $w <Visibility> "grab $w; focus $w"
+ tkwait window $w
+}
+
+proc makewindow {} {
+ global canv canv2 canv3 linespc charspc ctext cflist textfont
+ global findtype findtypemenu findloc findstring fstring geometry
+ global entries sha1entry sha1string sha1but
+ global maincursor textcursor curtextcursor
+ global rowctxmenu gaudydiff mergemax
+ global hgvdiff bgcolor fgcolor diffremcolor diffaddcolor diffmerge1color
+ global diffmerge2color hunksepcolor
+
+ menu .bar
+ .bar add cascade -label "File" -menu .bar.file
+ menu .bar.file
+ .bar.file add command -label "Reread references" -command rereadrefs
+ .bar.file add command -label "Quit" -command doquit
+ menu .bar.help
+ .bar add cascade -label "Help" -menu .bar.help
+ .bar.help add command -label "About gitk" -command about
+ . configure -menu .bar
+
+ if {![info exists geometry(canv1)]} {
+ set geometry(canv1) [expr 45 * $charspc]
+ set geometry(canv2) [expr 30 * $charspc]
+ set geometry(canv3) [expr 15 * $charspc]
+ set geometry(canvh) [expr 25 * $linespc + 4]
+ set geometry(ctextw) 80
+ set geometry(ctexth) 30
+ set geometry(cflistw) 30
+ }
+ panedwindow .ctop -orient vertical
+ if {[info exists geometry(width)]} {
+ .ctop conf -width $geometry(width) -height $geometry(height)
+ set texth [expr {$geometry(height) - $geometry(canvh) - 56}]
+ set geometry(ctexth) [expr {($texth - 8) /
+ [font metrics $textfont -linespace]}]
+ }
+ frame .ctop.top
+ frame .ctop.top.bar
+ pack .ctop.top.bar -side bottom -fill x
+ set cscroll .ctop.top.csb
+ scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
+ pack $cscroll -side right -fill y
+ panedwindow .ctop.top.clist -orient horizontal -sashpad 0 -handlesize 4
+ pack .ctop.top.clist -side top -fill both -expand 1
+ .ctop add .ctop.top
+ set canv .ctop.top.clist.canv
+ canvas $canv -height $geometry(canvh) -width $geometry(canv1) \
+ -bg $bgcolor -bd 0 \
+ -yscrollincr $linespc -yscrollcommand "$cscroll set" -selectbackground grey
+ .ctop.top.clist add $canv
+ set canv2 .ctop.top.clist.canv2
+ canvas $canv2 -height $geometry(canvh) -width $geometry(canv2) \
+ -bg $bgcolor -bd 0 -yscrollincr $linespc -selectbackground grey
+ .ctop.top.clist add $canv2
+ set canv3 .ctop.top.clist.canv3
+ canvas $canv3 -height $geometry(canvh) -width $geometry(canv3) \
+ -bg $bgcolor -bd 0 -yscrollincr $linespc -selectbackground grey
+ .ctop.top.clist add $canv3
+ bind .ctop.top.clist <Configure> {resizeclistpanes %W %w}
+
+ set sha1entry .ctop.top.bar.sha1
+ set entries $sha1entry
+ set sha1but .ctop.top.bar.sha1label
+ button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
+ -command gotocommit -width 8
+ $sha1but conf -disabledforeground [$sha1but cget -foreground]
+ pack .ctop.top.bar.sha1label -side left
+ entry $sha1entry -width 40 -font $textfont -textvariable sha1string
+ trace add variable sha1string write sha1change
+ pack $sha1entry -side left -pady 2
+
+ image create bitmap bm-left -data {
+ #define left_width 16
+ #define left_height 16
+ static unsigned char left_bits[] = {
+ 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
+ 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
+ 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
+ }
+ image create bitmap bm-right -data {
+ #define right_width 16
+ #define right_height 16
+ static unsigned char right_bits[] = {
+ 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
+ 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
+ 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
+ }
+ button .ctop.top.bar.leftbut -image bm-left -command goback \
+ -state disabled -width 26
+ pack .ctop.top.bar.leftbut -side left -fill y
+ button .ctop.top.bar.rightbut -image bm-right -command goforw \
+ -state disabled -width 26
+ pack .ctop.top.bar.rightbut -side left -fill y
+
+ button .ctop.top.bar.findbut -text "Find" -command dofind
+ pack .ctop.top.bar.findbut -side left
+ set findstring {}
+ set fstring .ctop.top.bar.findstring
+ lappend entries $fstring
+ entry $fstring -width 30 -font $textfont -textvariable findstring
+ pack $fstring -side left -expand 1 -fill x
+ set findtype Exact
+ set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \
+ findtype Exact IgnCase Regexp]
+ set findloc "All fields"
+ tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \
+ Comments Author Committer Files Pickaxe
+ pack .ctop.top.bar.findloc -side right
+ pack .ctop.top.bar.findtype -side right
+ # for making sure type==Exact whenever loc==Pickaxe
+ trace add variable findloc write findlocchange
+
+ panedwindow .ctop.cdet -orient horizontal
+ .ctop add .ctop.cdet
+ frame .ctop.cdet.left
+ set ctext .ctop.cdet.left.ctext
+ text $ctext -fg $fgcolor -bg $bgcolor -state disabled -font $textfont \
+ -width $geometry(ctextw) -height $geometry(ctexth) \
+ -yscrollcommand ".ctop.cdet.left.sb set" \
+ -xscrollcommand ".ctop.cdet.left.hb set" -wrap none
+ scrollbar .ctop.cdet.left.sb -command "$ctext yview"
+ scrollbar .ctop.cdet.left.hb -orient horizontal -command "$ctext xview"
+ pack .ctop.cdet.left.sb -side right -fill y
+ pack .ctop.cdet.left.hb -side bottom -fill x
+ pack $ctext -side left -fill both -expand 1
+ .ctop.cdet add .ctop.cdet.left
+
+ $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
+ if {$gaudydiff} {
+ $ctext tag conf hunksep -back blue -fore white
+ $ctext tag conf d0 -back "#ff8080"
+ $ctext tag conf d1 -back green
+ } else {
+ $ctext tag conf hunksep -fore $hunksepcolor
+ $ctext tag conf d0 -fore $diffremcolor
+ $ctext tag conf d1 -fore $diffaddcolor
+
+ # The mX colours seem to be used in merge changesets, where m0
+ # is first parent, m1 is second parent and so on. Git can have
+ # several parents, Hg cannot, so I think the m2..mmax would be
+ # unused.
+ $ctext tag conf m0 -fore $diffmerge1color
+ $ctext tag conf m1 -fore $diffmerge2color
+ $ctext tag conf m2 -fore green
+ $ctext tag conf m3 -fore purple
+ $ctext tag conf m4 -fore brown
+ $ctext tag conf mmax -fore darkgrey
+ set mergemax 5
+ $ctext tag conf mresult -font [concat $textfont bold]
+ $ctext tag conf msep -font [concat $textfont bold]
+ $ctext tag conf found -back yellow
+ }
+
+ frame .ctop.cdet.right
+ set cflist .ctop.cdet.right.cfiles
+ listbox $cflist -fg $fgcolor -bg $bgcolor \
+ -selectmode extended -width $geometry(cflistw) \
+ -yscrollcommand ".ctop.cdet.right.sb set"
+ scrollbar .ctop.cdet.right.sb -command "$cflist yview"
+ pack .ctop.cdet.right.sb -side right -fill y
+ pack $cflist -side left -fill both -expand 1
+ .ctop.cdet add .ctop.cdet.right
+ bind .ctop.cdet <Configure> {resizecdetpanes %W %w}
+
+ pack .ctop -side top -fill both -expand 1
+
+ bindall <1> {selcanvline %W %x %y}
+ #bindall <B1-Motion> {selcanvline %W %x %y}
+ bindall <MouseWheel> "allcansmousewheel %D"
+ bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
+ bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
+ bindall <2> "allcanvs scan mark 0 %y"
+ bindall <B2-Motion> "allcanvs scan dragto 0 %y"
+ bind . <Key-Up> "selnextline -1"
+ bind . <Key-Down> "selnextline 1"
+ bind . <Key-Prior> "allcanvs yview scroll -1 pages"
+ bind . <Key-Next> "allcanvs yview scroll 1 pages"
+ bindkey <Key-Delete> "$ctext yview scroll -1 pages"
+ bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
+ bindkey <Key-space> "$ctext yview scroll 1 pages"
+ bindkey p "selnextline -1"
+ bindkey n "selnextline 1"
+ bindkey b "$ctext yview scroll -1 pages"
+ bindkey d "$ctext yview scroll 18 units"
+ bindkey u "$ctext yview scroll -18 units"
+ bindkey / {findnext 1}
+ bindkey <Key-Return> {findnext 0}
+ bindkey ? findprev
+ bindkey f nextfile
+ bind . <Control-q> doquit
+ bind . <Control-w> doquit
+ bind . <Control-f> dofind
+ bind . <Control-g> {findnext 0}
+ bind . <Control-r> findprev
+ bind . <Control-equal> {incrfont 1}
+ bind . <Control-KP_Add> {incrfont 1}
+ bind . <Control-minus> {incrfont -1}
+ bind . <Control-KP_Subtract> {incrfont -1}
+ bind $cflist <<ListboxSelect>> listboxsel
+ bind . <Destroy> {savestuff %W}
+ bind . <Button-1> "click %W"
+ bind $fstring <Key-Return> dofind
+ bind $sha1entry <Key-Return> gotocommit
+ bind $sha1entry <<PasteSelection>> clearsha1
+
+ set maincursor [. cget -cursor]
+ set textcursor [$ctext cget -cursor]
+ set curtextcursor $textcursor
+
+ set rowctxmenu .rowctxmenu
+ menu $rowctxmenu -tearoff 0
+ $rowctxmenu add command -label "Diff this -> selected" \
+ -command {diffvssel 0}
+ $rowctxmenu add command -label "Diff selected -> this" \
+ -command {diffvssel 1}
+ $rowctxmenu add command -label "Make patch" -command mkpatch
+ $rowctxmenu add command -label "Create tag" -command mktag
+ $rowctxmenu add command -label "Write commit to file" -command writecommit
+ if { $hgvdiff ne "" } {
+ $rowctxmenu add command -label "Visual diff with parent" \
+ -command {vdiff 1}
+ $rowctxmenu add command -label "Visual diff with selected" \
+ -command {vdiff 0}
+ }
+}
+
+# when we make a key binding for the toplevel, make sure
+# it doesn't get triggered when that key is pressed in the
+# find string entry widget.
+proc bindkey {ev script} {
+ global entries
+ bind . $ev $script
+ set escript [bind Entry $ev]
+ if {$escript == {}} {
+ set escript [bind Entry <Key>]
+ }
+ foreach e $entries {
+ bind $e $ev "$escript; break"
+ }
+}
+
+# set the focus back to the toplevel for any click outside
+# the entry widgets
+proc click {w} {
+ global entries
+ foreach e $entries {
+ if {$w == $e} return
+ }
+ focus .
+}
+
+proc savestuff {w} {
+ global canv canv2 canv3 ctext cflist mainfont textfont
+ global stuffsaved findmergefiles gaudydiff maxgraphpct
+ global maxwidth authorcolors curidfont bgcolor fgcolor
+ global diffremcolor diffaddcolor hunksepcolor
+ global diffmerge1color diffmerge2color
+
+ if {$stuffsaved} return
+ if {![winfo viewable .]} return
+ catch {
+ set f [open "~/.hgk-new" w]
+ puts $f [list set mainfont $mainfont]
+ puts $f [list set curidfont $curidfont]
+ puts $f [list set textfont $textfont]
+ puts $f [list set findmergefiles $findmergefiles]
+ puts $f [list set gaudydiff $gaudydiff]
+ puts $f [list set maxgraphpct $maxgraphpct]
+ puts $f [list set maxwidth $maxwidth]
+ puts $f "set geometry(width) [winfo width .ctop]"
+ puts $f "set geometry(height) [winfo height .ctop]"
+ puts $f "set geometry(canv1) [expr [winfo width $canv]-2]"
+ puts $f "set geometry(canv2) [expr [winfo width $canv2]-2]"
+ puts $f "set geometry(canv3) [expr [winfo width $canv3]-2]"
+ puts $f "set geometry(canvh) [expr [winfo height $canv]-2]"
+ set wid [expr {([winfo width $ctext] - 8) \
+ / [font measure $textfont "0"]}]
+ puts $f "set geometry(ctextw) $wid"
+ set wid [expr {([winfo width $cflist] - 11) \
+ / [font measure [$cflist cget -font] "0"]}]
+ puts $f "set geometry(cflistw) $wid"
+ puts $f "#"
+ puts $f "# authorcolors format:"
+ puts $f "#"
+ puts $f "# zero or more sublists of"
+ puts $f "#"
+ puts $f "# { regex color }"
+ puts $f "#"
+ puts $f "# followed by a list of colors"
+ puts $f "#"
+ puts $f "# If the commit author matches a regex in a sublist,"
+ puts $f "# the commit will be colored by that color"
+ puts $f "# otherwise the next unused entry from the list of colors"
+ puts $f "# will be assigned to this commit and also all other commits"
+ puts $f "# of the same author. When the list of colors is exhausted,"
+ puts $f "# the last entry will be reused."
+ puts $f "#"
+ puts $f "set authorcolors {$authorcolors}"
+ puts $f "#"
+ puts $f "# The background color in the text windows"
+ puts $f "set bgcolor $bgcolor"
+ puts $f "#"
+ puts $f "# The text color used in the diff and file list view"
+ puts $f "set fgcolor $fgcolor"
+ puts $f "#"
+ puts $f "# Color to display + lines in diffs"
+ puts $f "set diffaddcolor $diffaddcolor"
+ puts $f "#"
+ puts $f "# Color to display - lines in diffs"
+ puts $f "set diffremcolor $diffremcolor"
+ puts $f "#"
+ puts $f "# Merge diffs: Color to signal lines from first parent"
+ puts $f "set diffmerge1color $diffmerge1color"
+ puts $f "#"
+ puts $f "# Merge diffs: Color to signal lines from second parent"
+ puts $f "set diffmerge2color $diffmerge2color"
+ puts $f "#"
+ puts $f "# Hunkseparator (@@ -lineno,lines +lineno,lines @@) color"
+ puts $f "set hunksepcolor $hunksepcolor"
+ close $f
+ file rename -force "~/.hgk-new" "~/.hgk"
+ }
+ set stuffsaved 1
+}
+
+proc resizeclistpanes {win w} {
+ global oldwidth
+ if [info exists oldwidth($win)] {
+ set s0 [$win sash coord 0]
+ set s1 [$win sash coord 1]
+ if {$w < 60} {
+ set sash0 [expr {int($w/2 - 2)}]
+ set sash1 [expr {int($w*5/6 - 2)}]
+ } else {
+ set factor [expr {1.0 * $w / $oldwidth($win)}]
+ set sash0 [expr {int($factor * [lindex $s0 0])}]
+ set sash1 [expr {int($factor * [lindex $s1 0])}]
+ if {$sash0 < 30} {
+ set sash0 30
+ }
+ if {$sash1 < $sash0 + 20} {
+ set sash1 [expr $sash0 + 20]
+ }
+ if {$sash1 > $w - 10} {
+ set sash1 [expr $w - 10]
+ if {$sash0 > $sash1 - 20} {
+ set sash0 [expr $sash1 - 20]
+ }
+ }
+ }
+ $win sash place 0 $sash0 [lindex $s0 1]
+ $win sash place 1 $sash1 [lindex $s1 1]
+ }
+ set oldwidth($win) $w
+}
+
+proc resizecdetpanes {win w} {
+ global oldwidth
+ if [info exists oldwidth($win)] {
+ set s0 [$win sash coord 0]
+ if {$w < 60} {
+ set sash0 [expr {int($w*3/4 - 2)}]
+ } else {
+ set factor [expr {1.0 * $w / $oldwidth($win)}]
+ set sash0 [expr {int($factor * [lindex $s0 0])}]
+ if {$sash0 < 45} {
+ set sash0 45
+ }
+ if {$sash0 > $w - 15} {
+ set sash0 [expr $w - 15]
+ }
+ }
+ $win sash place 0 $sash0 [lindex $s0 1]
+ }
+ set oldwidth($win) $w
+}
+
+proc allcanvs args {
+ global canv canv2 canv3
+ eval $canv $args
+ eval $canv2 $args
+ eval $canv3 $args
+}
+
+proc bindall {event action} {
+ global canv canv2 canv3
+ bind $canv $event $action
+ bind $canv2 $event $action
+ bind $canv3 $event $action
+}
+
+proc about {} {
+ set w .about
+ if {[winfo exists $w]} {
+ raise $w
+ return
+ }
+ toplevel $w
+ wm title $w "About gitk"
+ message $w.m -text {
+Gitk version 1.2
+
+Copyright © 2005 Paul Mackerras
+
+Use and redistribute under the terms of the GNU General Public License} \
+ -justify center -aspect 400
+ pack $w.m -side top -fill x -padx 20 -pady 20
+ button $w.ok -text Close -command "destroy $w"
+ pack $w.ok -side bottom
+}
+
+set aunextcolor 0
+proc assignauthorcolor {name} {
+ global authorcolors aucolormap aunextcolor
+ if [info exists aucolormap($name)] return
+
+ set randomcolors {black}
+ for {set i 0} {$i < [llength $authorcolors]} {incr i} {
+ set col [lindex $authorcolors $i]
+ if {[llength $col] > 1} {
+ set re [lindex $col 0]
+ set c [lindex $col 1]
+ if {[regexp -- $re $name]} {
+ set aucolormap($name) $c
+ return
+ }
+ } else {
+ set randomcolors [lrange $authorcolors $i end]
+ break
+ }
+ }
+
+ set ncolors [llength $randomcolors]
+ set c [lindex $randomcolors $aunextcolor]
+ if {[incr aunextcolor] >= $ncolors} {
+ incr aunextcolor -1
+ }
+ set aucolormap($name) $c
+}
+
+proc assigncolor {id} {
+ global commitinfo colormap commcolors colors nextcolor
+ global parents nparents children nchildren
+ global cornercrossings crossings
+
+ if [info exists colormap($id)] return
+ set ncolors [llength $colors]
+ if {$nparents($id) <= 1 && $nchildren($id) == 1} {
+ set child [lindex $children($id) 0]
+ if {[info exists colormap($child)]
+ && $nparents($child) == 1} {
+ set colormap($id) $colormap($child)
+ return
+ }
+ }
+ set badcolors {}
+ if {[info exists cornercrossings($id)]} {
+ foreach x $cornercrossings($id) {
+ if {[info exists colormap($x)]
+ && [lsearch -exact $badcolors $colormap($x)] < 0} {
+ lappend badcolors $colormap($x)
+ }
+ }
+ if {[llength $badcolors] >= $ncolors} {
+ set badcolors {}
+ }
+ }
+ set origbad $badcolors
+ if {[llength $badcolors] < $ncolors - 1} {
+ if {[info exists crossings($id)]} {
+ foreach x $crossings($id) {
+ if {[info exists colormap($x)]
+ && [lsearch -exact $badcolors $colormap($x)] < 0} {
+ lappend badcolors $colormap($x)
+ }
+ }
+ if {[llength $badcolors] >= $ncolors} {
+ set badcolors $origbad
+ }
+ }
+ set origbad $badcolors
+ }
+ if {[llength $badcolors] < $ncolors - 1} {
+ foreach child $children($id) {
+ if {[info exists colormap($child)]
+ && [lsearch -exact $badcolors $colormap($child)] < 0} {
+ lappend badcolors $colormap($child)
+ }
+ if {[info exists parents($child)]} {
+ foreach p $parents($child) {
+ if {[info exists colormap($p)]
+ && [lsearch -exact $badcolors $colormap($p)] < 0} {
+ lappend badcolors $colormap($p)
+ }
+ }
+ }
+ }
+ if {[llength $badcolors] >= $ncolors} {
+ set badcolors $origbad
+ }
+ }
+ for {set i 0} {$i <= $ncolors} {incr i} {
+ set c [lindex $colors $nextcolor]
+ if {[incr nextcolor] >= $ncolors} {
+ set nextcolor 0
+ }
+ if {[lsearch -exact $badcolors $c]} break
+ }
+ set colormap($id) $c
+}
+
+proc initgraph {} {
+ global canvy canvy0 lineno numcommits nextcolor linespc
+ global mainline mainlinearrow sidelines
+ global nchildren ncleft
+ global displist nhyperspace
+
+ allcanvs delete all
+ set nextcolor 0
+ set canvy $canvy0
+ set lineno -1
+ set numcommits 0
+ catch {unset mainline}
+ catch {unset mainlinearrow}
+ catch {unset sidelines}
+ foreach id [array names nchildren] {
+ set ncleft($id) $nchildren($id)
+ }
+ set displist {}
+ set nhyperspace 0
+}
+
+proc bindline {t id} {
+ global canv
+
+ $canv bind $t <Enter> "lineenter %x %y $id"
+ $canv bind $t <Motion> "linemotion %x %y $id"
+ $canv bind $t <Leave> "lineleave $id"
+ $canv bind $t <Button-1> "lineclick %x %y $id 1"
+}
+
+proc drawlines {id xtra} {
+ global mainline mainlinearrow sidelines lthickness colormap canv
+
+ $canv delete lines.$id
+ if {[info exists mainline($id)]} {
+ set t [$canv create line $mainline($id) \
+ -width [expr {($xtra + 1) * $lthickness}] \
+ -fill $colormap($id) -tags lines.$id \
+ -arrow $mainlinearrow($id)]
+ $canv lower $t
+ bindline $t $id
+ }
+ if {[info exists sidelines($id)]} {
+ foreach ls $sidelines($id) {
+ set coords [lindex $ls 0]
+ set thick [lindex $ls 1]
+ set arrow [lindex $ls 2]
+ set t [$canv create line $coords -fill $colormap($id) \
+ -width [expr {($thick + $xtra) * $lthickness}] \
+ -arrow $arrow -tags lines.$id]
+ $canv lower $t
+ bindline $t $id
+ }
+ }
+}
+
+# level here is an index in displist
+proc drawcommitline {level} {
+ global parents children nparents displist
+ global canv canv2 canv3 mainfont namefont canvy linespc
+ global lineid linehtag linentag linedtag commitinfo
+ global colormap numcommits currentparents dupparents
+ global idtags idline idheads idotherrefs
+ global lineno lthickness mainline mainlinearrow sidelines
+ global commitlisted rowtextx idpos lastuse displist
+ global oldnlines olddlevel olddisplist
+ global aucolormap curid curidfont
+
+ incr numcommits
+ incr lineno
+ set id [lindex $displist $level]
+ set lastuse($id) $lineno
+ set lineid($lineno) $id
+ set idline($id) $lineno
+ set ofill [expr {[info exists commitlisted($id)]? "blue": "white"}]
+ if {![info exists commitinfo($id)]} {
+ readcommit $id
+ if {![info exists commitinfo($id)]} {
+ set commitinfo($id) {"No commit information available"}
+ set nparents($id) 0
+ }
+ }
+ assigncolor $id
+ set currentparents {}
+ set dupparents {}
+ if {[info exists commitlisted($id)] && [info exists parents($id)]} {
+ foreach p $parents($id) {
+ if {[lsearch -exact $currentparents $p] < 0} {
+ lappend currentparents $p
+ } else {
+ # remember that this parent was listed twice
+ lappend dupparents $p
+ }
+ }
+ }
+ set x [xcoord $level $level $lineno]
+ set y1 $canvy
+ set canvy [expr $canvy + $linespc]
+ allcanvs conf -scrollregion \
+ [list 0 0 0 [expr $y1 + 0.5 * $linespc + 2]]
+ if {[info exists mainline($id)]} {
+ lappend mainline($id) $x $y1
+ if {$mainlinearrow($id) ne "none"} {
+ set mainline($id) [trimdiagstart $mainline($id)]
+ }
+ }
+ drawlines $id 0
+ set orad [expr {$linespc / 3}]
+ set t [$canv create oval [expr $x - $orad] [expr $y1 - $orad] \
+ [expr $x + $orad - 1] [expr $y1 + $orad - 1] \
+ -fill $ofill -outline black -width 1]
+ $canv raise $t
+ $canv bind $t <1> {selcanvline {} %x %y}
+ set xt [xcoord [llength $displist] $level $lineno]
+ if {[llength $currentparents] > 2} {
+ set xt [expr {$xt + ([llength $currentparents] - 2) * $linespc}]
+ }
+ set rowtextx($lineno) $xt
+ set idpos($id) [list $x $xt $y1]
+ if {[info exists idtags($id)] || [info exists idheads($id)]
+ || [info exists idotherrefs($id)]} {
+ set xt [drawtags $id $x $xt $y1]
+ }
+ set headline [lindex $commitinfo($id) 0]
+ set name [lindex $commitinfo($id) 1]
+ assignauthorcolor $name
+ set fg $aucolormap($name)
+ if {$id == $curid} {
+ set fn $curidfont
+ } else {
+ set fn $mainfont
+ }
+
+ set date [lindex $commitinfo($id) 2]
+ set linehtag($lineno) [$canv create text $xt $y1 -anchor w \
+ -text $headline -font $fn \
+ -fill $fg]
+ $canv bind $linehtag($lineno) <<B3>> "rowmenu %X %Y $id"
+ set linentag($lineno) [$canv2 create text 3 $y1 -anchor w \
+ -text $name -font $namefont \
+ -fill $fg]
+ set linedtag($lineno) [$canv3 create text 3 $y1 -anchor w \
+ -text $date -font $mainfont \
+ -fill $fg]
+
+ set olddlevel $level
+ set olddisplist $displist
+ set oldnlines [llength $displist]
+}
+
+proc drawtags {id x xt y1} {
+ global idtags idheads idotherrefs commitinfo
+ global linespc lthickness
+ global canv mainfont idline rowtextx
+
+ set marks {}
+ set ntags 0
+ set nheads 0
+ if {[info exists idtags($id)]} {
+ set marks $idtags($id)
+ set ntags [llength $marks]
+ }
+ if {[info exists idheads($id)]} {
+ set headmark [lindex $commitinfo($id) 7]
+ if {$headmark ne "default"} {
+ lappend marks $headmark
+ set nheads 1
+ }
+ }
+ if {[info exists idotherrefs($id)]} {
+ set marks [concat $marks $idotherrefs($id)]
+ }
+ if {$marks eq {}} {
+ return $xt
+ }
+
+ set delta [expr {int(0.5 * ($linespc - $lthickness))}]
+ set yt [expr $y1 - 0.5 * $linespc]
+ set yb [expr $yt + $linespc - 1]
+ set xvals {}
+ set wvals {}
+ foreach tag $marks {
+ set wid [font measure $mainfont $tag]
+ lappend xvals $xt
+ lappend wvals $wid
+ set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
+ }
+ set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
+ -width $lthickness -fill black -tags tag.$id]
+ $canv lower $t
+ foreach tag $marks x $xvals wid $wvals {
+ set xl [expr $x + $delta]
+ set xr [expr $x + $delta + $wid + $lthickness]
+ if {[incr ntags -1] >= 0} {
+ # draw a tag
+ set t [$canv create polygon $x [expr $yt + $delta] $xl $yt \
+ $xr $yt $xr $yb $xl $yb $x [expr $yb - $delta] \
+ -width 1 -outline black -fill yellow -tags tag.$id]
+ $canv bind $t <1> [list showtag $tag 1]
+ set rowtextx($idline($id)) [expr {$xr + $linespc}]
+ } else {
+ # draw a head or other ref
+ if {[incr nheads -1] >= 0} {
+ set col green
+ } else {
+ set col "#ddddff"
+ }
+ set xl [expr $xl - $delta/2]
+ $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
+ -width 1 -outline black -fill $col -tags tag.$id
+ }
+ set t [$canv create text $xl $y1 -anchor w -text $tag \
+ -font $mainfont -tags tag.$id]
+ if {$ntags >= 0} {
+ $canv bind $t <1> [list showtag $tag 1]
+ }
+ }
+ return $xt
+}
+
+proc notecrossings {id lo hi corner} {
+ global olddisplist crossings cornercrossings
+
+ for {set i $lo} {[incr i] < $hi} {} {
+ set p [lindex $olddisplist $i]
+ if {$p == {}} continue
+ if {$i == $corner} {
+ if {![info exists cornercrossings($id)]
+ || [lsearch -exact $cornercrossings($id) $p] < 0} {
+ lappend cornercrossings($id) $p
+ }
+ if {![info exists cornercrossings($p)]
+ || [lsearch -exact $cornercrossings($p) $id] < 0} {
+ lappend cornercrossings($p) $id
+ }
+ } else {
+ if {![info exists crossings($id)]
+ || [lsearch -exact $crossings($id) $p] < 0} {
+ lappend crossings($id) $p
+ }
+ if {![info exists crossings($p)]
+ || [lsearch -exact $crossings($p) $id] < 0} {
+ lappend crossings($p) $id
+ }
+ }
+ }
+}
+
+proc xcoord {i level ln} {
+ global canvx0 xspc1 xspc2
+
+ set x [expr {$canvx0 + $i * $xspc1($ln)}]
+ if {$i > 0 && $i == $level} {
+ set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
+ } elseif {$i > $level} {
+ set x [expr {$x + $xspc2 - $xspc1($ln)}]
+ }
+ return $x
+}
+
+# it seems Tk can't draw arrows on the end of diagonal line segments...
+proc trimdiagend {line} {
+ while {[llength $line] > 4} {
+ set x1 [lindex $line end-3]
+ set y1 [lindex $line end-2]
+ set x2 [lindex $line end-1]
+ set y2 [lindex $line end]
+ if {($x1 == $x2) != ($y1 == $y2)} break
+ set line [lreplace $line end-1 end]
+ }
+ return $line
+}
+
+proc trimdiagstart {line} {
+ while {[llength $line] > 4} {
+ set x1 [lindex $line 0]
+ set y1 [lindex $line 1]
+ set x2 [lindex $line 2]
+ set y2 [lindex $line 3]
+ if {($x1 == $x2) != ($y1 == $y2)} break
+ set line [lreplace $line 0 1]
+ }
+ return $line
+}
+
+proc drawslants {id needonscreen nohs} {
+ global canv mainline mainlinearrow sidelines
+ global canvx0 canvy xspc1 xspc2 lthickness
+ global currentparents dupparents
+ global lthickness linespc canvy colormap lineno geometry
+ global maxgraphpct maxwidth
+ global displist onscreen lastuse
+ global parents commitlisted
+ global oldnlines olddlevel olddisplist
+ global nhyperspace numcommits nnewparents
+
+ if {$lineno < 0} {
+ lappend displist $id
+ set onscreen($id) 1
+ return 0
+ }
+
+ set y1 [expr {$canvy - $linespc}]
+ set y2 $canvy
+
+ # work out what we need to get back on screen
+ set reins {}
+ if {$onscreen($id) < 0} {
+ # next to do isn't displayed, better get it on screen...
+ lappend reins [list $id 0]
+ }
+ # make sure all the previous commits's parents are on the screen
+ foreach p $currentparents {
+ if {$onscreen($p) < 0} {
+ lappend reins [list $p 0]
+ }
+ }
+ # bring back anything requested by caller
+ if {$needonscreen ne {}} {
+ lappend reins $needonscreen
+ }
+
+ # try the shortcut
+ if {$currentparents == $id && $onscreen($id) == 0 && $reins eq {}} {
+ set dlevel $olddlevel
+ set x [xcoord $dlevel $dlevel $lineno]
+ set mainline($id) [list $x $y1]
+ set mainlinearrow($id) none
+ set lastuse($id) $lineno
+ set displist [lreplace $displist $dlevel $dlevel $id]
+ set onscreen($id) 1
+ set xspc1([expr {$lineno + 1}]) $xspc1($lineno)
+ return $dlevel
+ }
+
+ # update displist
+ set displist [lreplace $displist $olddlevel $olddlevel]
+ set j $olddlevel
+ foreach p $currentparents {
+ set lastuse($p) $lineno
+ if {$onscreen($p) == 0} {
+ set displist [linsert $displist $j $p]
+ set onscreen($p) 1
+ incr j
+ }
+ }
+ if {$onscreen($id) == 0} {
+ lappend displist $id
+ set onscreen($id) 1
+ }
+
+ # remove the null entry if present
+ set nullentry [lsearch -exact $displist {}]
+ if {$nullentry >= 0} {
+ set displist [lreplace $displist $nullentry $nullentry]
+ }
+
+ # bring back the ones we need now (if we did it earlier
+ # it would change displist and invalidate olddlevel)
+ foreach pi $reins {
+ # test again in case of duplicates in reins
+ set p [lindex $pi 0]
+ if {$onscreen($p) < 0} {
+ set onscreen($p) 1
+ set lastuse($p) $lineno
+ set displist [linsert $displist [lindex $pi 1] $p]
+ incr nhyperspace -1
+ }
+ }
+
+ set lastuse($id) $lineno
+
+ # see if we need to make any lines jump off into hyperspace
+ set displ [llength $displist]
+ if {$displ > $maxwidth} {
+ set ages {}
+ foreach x $displist {
+ lappend ages [list $lastuse($x) $x]
+ }
+ set ages [lsort -integer -index 0 $ages]
+ set k 0
+ while {$displ > $maxwidth} {
+ set use [lindex $ages $k 0]
+ set victim [lindex $ages $k 1]
+ if {$use >= $lineno - 5} break
+ incr k
+ if {[lsearch -exact $nohs $victim] >= 0} continue
+ set i [lsearch -exact $displist $victim]
+ set displist [lreplace $displist $i $i]
+ set onscreen($victim) -1
+ incr nhyperspace
+ incr displ -1
+ if {$i < $nullentry} {
+ incr nullentry -1
+ }
+ set x [lindex $mainline($victim) end-1]
+ lappend mainline($victim) $x $y1
+ set line [trimdiagend $mainline($victim)]
+ set arrow "last"
+ if {$mainlinearrow($victim) ne "none"} {
+ set line [trimdiagstart $line]
+ set arrow "both"
+ }
+ lappend sidelines($victim) [list $line 1 $arrow]
+ unset mainline($victim)
+ }
+ }
+
+ set dlevel [lsearch -exact $displist $id]
+
+ # If we are reducing, put in a null entry
+ if {$displ < $oldnlines} {
+ # does the next line look like a merge?
+ # i.e. does it have > 1 new parent?
+ if {$nnewparents($id) > 1} {
+ set i [expr {$dlevel + 1}]
+ } elseif {$nnewparents([lindex $olddisplist $olddlevel]) == 0} {
+ set i $olddlevel
+ if {$nullentry >= 0 && $nullentry < $i} {
+ incr i -1
+ }
+ } elseif {$nullentry >= 0} {
+ set i $nullentry
+ while {$i < $displ
+ && [lindex $olddisplist $i] == [lindex $displist $i]} {
+ incr i
+ }
+ } else {
+ set i $olddlevel
+ if {$dlevel >= $i} {
+ incr i
+ }
+ }
+ if {$i < $displ} {
+ set displist [linsert $displist $i {}]
+ incr displ
+ if {$dlevel >= $i} {
+ incr dlevel
+ }
+ }
+ }
+
+ # decide on the line spacing for the next line
+ set lj [expr {$lineno + 1}]
+ set maxw [expr {$maxgraphpct * $geometry(canv1) / 100}]
+ if {$displ <= 1 || $canvx0 + $displ * $xspc2 <= $maxw} {
+ set xspc1($lj) $xspc2
+ } else {
+ set xspc1($lj) [expr {($maxw - $canvx0 - $xspc2) / ($displ - 1)}]
+ if {$xspc1($lj) < $lthickness} {
+ set xspc1($lj) $lthickness
+ }
+ }
+
+ foreach idi $reins {
+ set id [lindex $idi 0]
+ set j [lsearch -exact $displist $id]
+ set xj [xcoord $j $dlevel $lj]
+ set mainline($id) [list $xj $y2]
+ set mainlinearrow($id) first
+ }
+
+ set i -1
+ foreach id $olddisplist {
+ incr i
+ if {$id == {}} continue
+ if {$onscreen($id) <= 0} continue
+ set xi [xcoord $i $olddlevel $lineno]
+ if {$i == $olddlevel} {
+ foreach p $currentparents {
+ set j [lsearch -exact $displist $p]
+ set coords [list $xi $y1]
+ set xj [xcoord $j $dlevel $lj]
+ if {$xj < $xi - $linespc} {
+ lappend coords [expr {$xj + $linespc}] $y1
+ notecrossings $p $j $i [expr {$j + 1}]
+ } elseif {$xj > $xi + $linespc} {
+ lappend coords [expr {$xj - $linespc}] $y1
+ notecrossings $p $i $j [expr {$j - 1}]
+ }
+ if {[lsearch -exact $dupparents $p] >= 0} {
+ # draw a double-width line to indicate the doubled parent
+ lappend coords $xj $y2
+ lappend sidelines($p) [list $coords 2 none]
+ if {![info exists mainline($p)]} {
+ set mainline($p) [list $xj $y2]
+ set mainlinearrow($p) none
+ }
+ } else {
+ # normal case, no parent duplicated
+ set yb $y2
+ set dx [expr {abs($xi - $xj)}]
+ if {0 && $dx < $linespc} {
+ set yb [expr {$y1 + $dx}]
+ }
+ if {![info exists mainline($p)]} {
+ if {$xi != $xj} {
+ lappend coords $xj $yb
+ }
+ set mainline($p) $coords
+ set mainlinearrow($p) none
+ } else {
+ lappend coords $xj $yb
+ if {$yb < $y2} {
+ lappend coords $xj $y2
+ }
+ lappend sidelines($p) [list $coords 1 none]
+ }
+ }
+ }
+ } else {
+ set j $i
+ if {[lindex $displist $i] != $id} {
+ set j [lsearch -exact $displist $id]
+ }
+ if {$j != $i || $xspc1($lineno) != $xspc1($lj)
+ || ($olddlevel < $i && $i < $dlevel)
+ || ($dlevel < $i && $i < $olddlevel)} {
+ set xj [xcoord $j $dlevel $lj]
+ lappend mainline($id) $xi $y1 $xj $y2
+ }
+ }
+ }
+ return $dlevel
+}
+
+# search for x in a list of lists
+proc llsearch {llist x} {
+ set i 0
+ foreach l $llist {
+ if {$l == $x || [lsearch -exact $l $x] >= 0} {
+ return $i
+ }
+ incr i
+ }
+ return -1
+}
+
+proc drawmore {reading} {
+ global displayorder numcommits ncmupdate nextupdate
+ global stopped nhyperspace parents commitlisted
+ global maxwidth onscreen displist currentparents olddlevel
+
+ set n [llength $displayorder]
+ while {$numcommits < $n} {
+ set id [lindex $displayorder $numcommits]
+ set ctxend [expr {$numcommits + 10}]
+ if {!$reading && $ctxend > $n} {
+ set ctxend $n
+ }
+ set dlist {}
+ if {$numcommits > 0} {
+ set dlist [lreplace $displist $olddlevel $olddlevel]
+ set i $olddlevel
+ foreach p $currentparents {
+ if {$onscreen($p) == 0} {
+ set dlist [linsert $dlist $i $p]
+ incr i
+ }
+ }
+ }
+ set nohs {}
+ set reins {}
+ set isfat [expr {[llength $dlist] > $maxwidth}]
+ if {$nhyperspace > 0 || $isfat} {
+ if {$ctxend > $n} break
+ # work out what to bring back and
+ # what we want to don't want to send into hyperspace
+ set room 1
+ for {set k $numcommits} {$k < $ctxend} {incr k} {
+ set x [lindex $displayorder $k]
+ set i [llsearch $dlist $x]
+ if {$i < 0} {
+ set i [llength $dlist]
+ lappend dlist $x
+ }
+ if {[lsearch -exact $nohs $x] < 0} {
+ lappend nohs $x
+ }
+ if {$reins eq {} && $onscreen($x) < 0 && $room} {
+ set reins [list $x $i]
+ }
+ set newp {}
+ if {[info exists commitlisted($x)]} {
+ set right 0
+ foreach p $parents($x) {
+ if {[llsearch $dlist $p] < 0} {
+ lappend newp $p
+ if {[lsearch -exact $nohs $p] < 0} {
+ lappend nohs $p
+ }
+ if {$reins eq {} && $onscreen($p) < 0 && $room} {
+ set reins [list $p [expr {$i + $right}]]
+ }
+ }
+ set right 1
+ }
+ }
+ set l [lindex $dlist $i]
+ if {[llength $l] == 1} {
+ set l $newp
+ } else {
+ set j [lsearch -exact $l $x]
+ set l [concat [lreplace $l $j $j] $newp]
+ }
+ set dlist [lreplace $dlist $i $i $l]
+ if {$room && $isfat && [llength $newp] <= 1} {
+ set room 0
+ }
+ }
+ }
+
+ set dlevel [drawslants $id $reins $nohs]
+ drawcommitline $dlevel
+ if {[clock clicks -milliseconds] >= $nextupdate
+ && $numcommits >= $ncmupdate} {
+ doupdate $reading
+ if {$stopped} break
+ }
+ }
+}
+
+# level here is an index in todo
+proc updatetodo {level noshortcut} {
+ global ncleft todo nnewparents
+ global commitlisted parents onscreen
+
+ set id [lindex $todo $level]
+ set olds {}
+ if {[info exists commitlisted($id)]} {
+ foreach p $parents($id) {
+ if {[lsearch -exact $olds $p] < 0} {
+ lappend olds $p
+ }
+ }
+ }
+ if {!$noshortcut && [llength $olds] == 1} {
+ set p [lindex $olds 0]
+ if {$ncleft($p) == 1 && [lsearch -exact $todo $p] < 0} {
+ set ncleft($p) 0
+ set todo [lreplace $todo $level $level $p]
+ set onscreen($p) 0
+ set nnewparents($id) 1
+ return 0
+ }
+ }
+
+ set todo [lreplace $todo $level $level]
+ set i $level
+ set n 0
+ foreach p $olds {
+ incr ncleft($p) -1
+ set k [lsearch -exact $todo $p]
+ if {$k < 0} {
+ set todo [linsert $todo $i $p]
+ set onscreen($p) 0
+ incr i
+ incr n
+ }
+ }
+ set nnewparents($id) $n
+
+ return 1
+}
+
+proc decidenext {{noread 0}} {
+ global ncleft todo
+ global datemode cdate
+ global commitinfo
+
+ # choose which one to do next time around
+ set todol [llength $todo]
+ set level -1
+ set latest {}
+ for {set k $todol} {[incr k -1] >= 0} {} {
+ set p [lindex $todo $k]
+ if {$ncleft($p) == 0} {
+ if {$datemode} {
+ if {![info exists commitinfo($p)]} {
+ if {$noread} {
+ return {}
+ }
+ readcommit $p
+ }
+ if {$latest == {} || $cdate($p) > $latest} {
+ set level $k
+ set latest $cdate($p)
+ }
+ } else {
+ set level $k
+ break
+ }
+ }
+ }
+ if {$level < 0} {
+ if {$todo != {}} {
+ puts "ERROR: none of the pending commits can be done yet:"
+ foreach p $todo {
+ puts " $p ($ncleft($p))"
+ }
+ }
+ return -1
+ }
+
+ return $level
+}
+
+proc drawcommit {id} {
+ global phase todo nchildren datemode nextupdate
+ global numcommits ncmupdate displayorder todo onscreen
+
+ if {$phase != "incrdraw"} {
+ set phase incrdraw
+ set displayorder {}
+ set todo {}
+ initgraph
+ }
+ if {$nchildren($id) == 0} {
+ lappend todo $id
+ set onscreen($id) 0
+ }
+ set level [decidenext 1]
+ if {$level == {} || $id != [lindex $todo $level]} {
+ return
+ }
+ while 1 {
+ lappend displayorder [lindex $todo $level]
+ if {[updatetodo $level $datemode]} {
+ set level [decidenext 1]
+ if {$level == {}} break
+ }
+ set id [lindex $todo $level]
+ if {![info exists commitlisted($id)]} {
+ break
+ }
+ }
+ drawmore 1
+}
+
+proc finishcommits {} {
+ global phase
+ global canv mainfont ctext maincursor textcursor
+
+ if {$phase != "incrdraw"} {
+ $canv delete all
+ $canv create text 3 3 -anchor nw -text "No commits selected" \
+ -font $mainfont -tags textitems
+ set phase {}
+ } else {
+ drawrest
+ }
+ . config -cursor $maincursor
+ settextcursor $textcursor
+}
+
+# Don't change the text pane cursor if it is currently the hand cursor,
+# showing that we are over a sha1 ID link.
+proc settextcursor {c} {
+ global ctext curtextcursor
+
+ if {[$ctext cget -cursor] == $curtextcursor} {
+ $ctext config -cursor $c
+ }
+ set curtextcursor $c
+}
+
+proc drawgraph {} {
+ global nextupdate startmsecs ncmupdate
+ global displayorder onscreen
+
+ if {$displayorder == {}} return
+ set startmsecs [clock clicks -milliseconds]
+ set nextupdate [expr $startmsecs + 100]
+ set ncmupdate 1
+ initgraph
+ foreach id $displayorder {
+ set onscreen($id) 0
+ }
+ drawmore 0
+}
+
+proc drawrest {} {
+ global phase stopped redisplaying selectedline
+ global datemode todo displayorder
+ global numcommits ncmupdate
+ global nextupdate startmsecs
+
+ set level [decidenext]
+ if {$level >= 0} {
+ set phase drawgraph
+ while 1 {
+ lappend displayorder [lindex $todo $level]
+ set hard [updatetodo $level $datemode]
+ if {$hard} {
+ set level [decidenext]
+ if {$level < 0} break
+ }
+ }
+ drawmore 0
+ }
+ set phase {}
+ set drawmsecs [expr [clock clicks -milliseconds] - $startmsecs]
+ #puts "overall $drawmsecs ms for $numcommits commits"
+ if {$redisplaying} {
+ if {$stopped == 0 && [info exists selectedline]} {
+ selectline $selectedline 0
+ }
+ if {$stopped == 1} {
+ set stopped 0
+ after idle drawgraph
+ } else {
+ set redisplaying 0
+ }
+ }
+}
+
+proc findmatches {f} {
+ global findtype foundstring foundstrlen
+ if {$findtype == "Regexp"} {
+ set matches [regexp -indices -all -inline $foundstring $f]
+ } else {
+ if {$findtype == "IgnCase"} {
+ set str [string tolower $f]
+ } else {
+ set str $f
+ }
+ set matches {}
+ set i 0
+ while {[set j [string first $foundstring $str $i]] >= 0} {
+ lappend matches [list $j [expr $j+$foundstrlen-1]]
+ set i [expr $j + $foundstrlen]
+ }
+ }
+ return $matches
+}
+
+proc dofind {} {
+ global findtype findloc findstring markedmatches commitinfo
+ global numcommits lineid linehtag linentag linedtag
+ global mainfont namefont canv canv2 canv3 selectedline
+ global matchinglines foundstring foundstrlen
+
+ stopfindproc
+ unmarkmatches
+ focus .
+ set matchinglines {}
+ if {$findloc == "Pickaxe"} {
+ findpatches
+ return
+ }
+ if {$findtype == "IgnCase"} {
+ set foundstring [string tolower $findstring]
+ } else {
+ set foundstring $findstring
+ }
+ set foundstrlen [string length $findstring]
+ if {$foundstrlen == 0} return
+ if {$findloc == "Files"} {
+ findfiles
+ return
+ }
+ if {![info exists selectedline]} {
+ set oldsel -1
+ } else {
+ set oldsel $selectedline
+ }
+ set didsel 0
+ set fldtypes {Headline Author Date Committer CDate Comment}
+ for {set l 0} {$l < $numcommits} {incr l} {
+ set id $lineid($l)
+ set info $commitinfo($id)
+ set doesmatch 0
+ foreach f $info ty $fldtypes {
+ if {$findloc != "All fields" && $findloc != $ty} {
+ continue
+ }
+ set matches [findmatches $f]
+ if {$matches == {}} continue
+ set doesmatch 1
+ if {$ty == "Headline"} {
+ markmatches $canv $l $f $linehtag($l) $matches $mainfont
+ } elseif {$ty == "Author"} {
+ markmatches $canv2 $l $f $linentag($l) $matches $namefont
+ } elseif {$ty == "Date"} {
+ markmatches $canv3 $l $f $linedtag($l) $matches $mainfont
+ }
+ }
+ if {$doesmatch} {
+ lappend matchinglines $l
+ if {!$didsel && $l > $oldsel} {
+ findselectline $l
+ set didsel 1
+ }
+ }
+ }
+ if {$matchinglines == {}} {
+ bell
+ } elseif {!$didsel} {
+ findselectline [lindex $matchinglines 0]
+ }
+}
+
+proc findselectline {l} {
+ global findloc commentend ctext
+ selectline $l 1
+ if {$findloc == "All fields" || $findloc == "Comments"} {
+ # highlight the matches in the comments
+ set f [$ctext get 1.0 $commentend]
+ set matches [findmatches $f]
+ foreach match $matches {
+ set start [lindex $match 0]
+ set end [expr [lindex $match 1] + 1]
+ $ctext tag add found "1.0 + $start c" "1.0 + $end c"
+ }
+ }
+}
+
+proc findnext {restart} {
+ global matchinglines selectedline
+ if {![info exists matchinglines]} {
+ if {$restart} {
+ dofind
+ }
+ return
+ }
+ if {![info exists selectedline]} return
+ foreach l $matchinglines {
+ if {$l > $selectedline} {
+ findselectline $l
+ return
+ }
+ }
+ bell
+}
+
+proc findprev {} {
+ global matchinglines selectedline
+ if {![info exists matchinglines]} {
+ dofind
+ return
+ }
+ if {![info exists selectedline]} return
+ set prev {}
+ foreach l $matchinglines {
+ if {$l >= $selectedline} break
+ set prev $l
+ }
+ if {$prev != {}} {
+ findselectline $prev
+ } else {
+ bell
+ }
+}
+
+proc findlocchange {name ix op} {
+ global findloc findtype findtypemenu
+ if {$findloc == "Pickaxe"} {
+ set findtype Exact
+ set state disabled
+ } else {
+ set state normal
+ }
+ $findtypemenu entryconf 1 -state $state
+ $findtypemenu entryconf 2 -state $state
+}
+
+proc stopfindproc {{done 0}} {
+ global findprocpid findprocfile findids
+ global ctext findoldcursor phase maincursor textcursor
+ global findinprogress
+
+ catch {unset findids}
+ if {[info exists findprocpid]} {
+ if {!$done} {
+ catch {exec kill $findprocpid}
+ }
+ catch {close $findprocfile}
+ unset findprocpid
+ }
+ if {[info exists findinprogress]} {
+ unset findinprogress
+ if {$phase != "incrdraw"} {
+ . config -cursor $maincursor
+ settextcursor $textcursor
+ }
+ }
+}
+
+proc findpatches {} {
+ global findstring selectedline numcommits
+ global findprocpid findprocfile
+ global finddidsel ctext lineid findinprogress
+ global findinsertpos
+ global env
+
+ if {$numcommits == 0} return
+
+ # make a list of all the ids to search, starting at the one
+ # after the selected line (if any)
+ if {[info exists selectedline]} {
+ set l $selectedline
+ } else {
+ set l -1
+ }
+ set inputids {}
+ for {set i 0} {$i < $numcommits} {incr i} {
+ if {[incr l] >= $numcommits} {
+ set l 0
+ }
+ append inputids $lineid($l) "\n"
+ }
+
+ if {[catch {
+ set f [open [list | $env(HG) --config ui.report_untrusted=false debug-diff-tree --stdin -s -r -S$findstring << $inputids] r]
+ } err]} {
+ error_popup "Error starting search process: $err"
+ return
+ }
+
+ set findinsertpos end
+ set findprocfile $f
+ set findprocpid [pid $f]
+ fconfigure $f -blocking 0
+ fileevent $f readable readfindproc
+ set finddidsel 0
+ . config -cursor watch
+ settextcursor watch
+ set findinprogress 1
+}
+
+proc readfindproc {} {
+ global findprocfile finddidsel
+ global idline matchinglines findinsertpos
+
+ set n [gets $findprocfile line]
+ if {$n < 0} {
+ if {[eof $findprocfile]} {
+ stopfindproc 1
+ if {!$finddidsel} {
+ bell
+ }
+ }
+ return
+ }
+ if {![regexp {^[0-9a-f]{12}} $line id]} {
+ error_popup "Can't parse git-diff-tree output: $line"
+ stopfindproc
+ return
+ }
+ if {![info exists idline($id)]} {
+ puts stderr "spurious id: $id"
+ return
+ }
+ set l $idline($id)
+ insertmatch $l $id
+}
+
+proc insertmatch {l id} {
+ global matchinglines findinsertpos finddidsel
+
+ if {$findinsertpos == "end"} {
+ if {$matchinglines != {} && $l < [lindex $matchinglines 0]} {
+ set matchinglines [linsert $matchinglines 0 $l]
+ set findinsertpos 1
+ } else {
+ lappend matchinglines $l
+ }
+ } else {
+ set matchinglines [linsert $matchinglines $findinsertpos $l]
+ incr findinsertpos
+ }
+ markheadline $l $id
+ if {!$finddidsel} {
+ findselectline $l
+ set finddidsel 1
+ }
+}
+
+proc findfiles {} {
+ global selectedline numcommits lineid ctext
+ global ffileline finddidsel parents nparents
+ global findinprogress findstartline findinsertpos
+ global treediffs fdiffids fdiffsneeded fdiffpos
+ global findmergefiles
+ global env
+
+ if {$numcommits == 0} return
+
+ if {[info exists selectedline]} {
+ set l [expr {$selectedline + 1}]
+ } else {
+ set l 0
+ }
+ set ffileline $l
+ set findstartline $l
+ set diffsneeded {}
+ set fdiffsneeded {}
+ while 1 {
+ set id $lineid($l)
+ if {$findmergefiles || $nparents($id) == 1} {
+ foreach p $parents($id) {
+ if {![info exists treediffs([list $id $p])]} {
+ append diffsneeded "$id $p\n"
+ lappend fdiffsneeded [list $id $p]
+ }
+ }
+ }
+ if {[incr l] >= $numcommits} {
+ set l 0
+ }
+ if {$l == $findstartline} break
+ }
+
+ # start off a git-diff-tree process if needed
+ if {$diffsneeded ne {}} {
+ if {[catch {
+ set df [open [list | $env(HG) --config ui.report_untrusted=false debug-diff-tree -r --stdin << $diffsneeded] r]
+ } err ]} {
+ error_popup "Error starting search process: $err"
+ return
+ }
+ catch {unset fdiffids}
+ set fdiffpos 0
+ fconfigure $df -blocking 0
+ fileevent $df readable [list readfilediffs $df]
+ }
+
+ set finddidsel 0
+ set findinsertpos end
+ set id $lineid($l)
+ set p [lindex $parents($id) 0]
+ . config -cursor watch
+ settextcursor watch
+ set findinprogress 1
+ findcont [list $id $p]
+ update
+}
+
+proc readfilediffs {df} {
+ global findids fdiffids fdiffs
+
+ set n [gets $df line]
+ if {$n < 0} {
+ if {[eof $df]} {
+ donefilediff
+ if {[catch {close $df} err]} {
+ stopfindproc
+ bell
+ error_popup "Error in hg debug-diff-tree: $err"
+ } elseif {[info exists findids]} {
+ set ids $findids
+ stopfindproc
+ bell
+ error_popup "Couldn't find diffs for {$ids}"
+ }
+ }
+ return
+ }
+ if {[regexp {^([0-9a-f]{12}) \(from ([0-9a-f]{12})\)} $line match id p]} {
+ # start of a new string of diffs
+ donefilediff
+ set fdiffids [list $id $p]
+ set fdiffs {}
+ } elseif {[string match ":*" $line]} {
+ lappend fdiffs [lindex $line 5]
+ }
+}
+
+proc donefilediff {} {
+ global fdiffids fdiffs treediffs findids
+ global fdiffsneeded fdiffpos
+
+ if {[info exists fdiffids]} {
+ while {[lindex $fdiffsneeded $fdiffpos] ne $fdiffids
+ && $fdiffpos < [llength $fdiffsneeded]} {
+ # git-diff-tree doesn't output anything for a commit
+ # which doesn't change anything
+ set nullids [lindex $fdiffsneeded $fdiffpos]
+ set treediffs($nullids) {}
+ if {[info exists findids] && $nullids eq $findids} {
+ unset findids
+ findcont $nullids
+ }
+ incr fdiffpos
+ }
+ incr fdiffpos
+
+ if {![info exists treediffs($fdiffids)]} {
+ set treediffs($fdiffids) $fdiffs
+ }
+ if {[info exists findids] && $fdiffids eq $findids} {
+ unset findids
+ findcont $fdiffids
+ }
+ }
+}
+
+proc findcont {ids} {
+ global findids treediffs parents nparents
+ global ffileline findstartline finddidsel
+ global lineid numcommits matchinglines findinprogress
+ global findmergefiles
+
+ set id [lindex $ids 0]
+ set p [lindex $ids 1]
+ set pi [lsearch -exact $parents($id) $p]
+ set l $ffileline
+ while 1 {
+ if {$findmergefiles || $nparents($id) == 1} {
+ if {![info exists treediffs($ids)]} {
+ set findids $ids
+ set ffileline $l
+ return
+ }
+ set doesmatch 0
+ foreach f $treediffs($ids) {
+ set x [findmatches $f]
+ if {$x != {}} {
+ set doesmatch 1
+ break
+ }
+ }
+ if {$doesmatch} {
+ insertmatch $l $id
+ set pi $nparents($id)
+ }
+ } else {
+ set pi $nparents($id)
+ }
+ if {[incr pi] >= $nparents($id)} {
+ set pi 0
+ if {[incr l] >= $numcommits} {
+ set l 0
+ }
+ if {$l == $findstartline} break
+ set id $lineid($l)
+ }
+ set p [lindex $parents($id) $pi]
+ set ids [list $id $p]
+ }
+ stopfindproc
+ if {!$finddidsel} {
+ bell
+ }
+}
+
+# mark a commit as matching by putting a yellow background
+# behind the headline
+proc markheadline {l id} {
+ global canv mainfont linehtag commitinfo
+
+ set bbox [$canv bbox $linehtag($l)]
+ set t [$canv create rect $bbox -outline {} -tags matches -fill yellow]
+ $canv lower $t
+}
+
+# mark the bits of a headline, author or date that match a find string
+proc markmatches {canv l str tag matches font} {
+ set bbox [$canv bbox $tag]
+ set x0 [lindex $bbox 0]
+ set y0 [lindex $bbox 1]
+ set y1 [lindex $bbox 3]
+ foreach match $matches {
+ set start [lindex $match 0]
+ set end [lindex $match 1]
+ if {$start > $end} continue
+ set xoff [font measure $font [string range $str 0 [expr $start-1]]]
+ set xlen [font measure $font [string range $str 0 [expr $end]]]
+ set t [$canv create rect [expr $x0+$xoff] $y0 [expr $x0+$xlen+2] $y1 \
+ -outline {} -tags matches -fill yellow]
+ $canv lower $t
+ }
+}
+
+proc unmarkmatches {} {
+ global matchinglines findids
+ allcanvs delete matches
+ catch {unset matchinglines}
+ catch {unset findids}
+}
+
+proc selcanvline {w x y} {
+ global canv canvy0 ctext linespc
+ global lineid linehtag linentag linedtag rowtextx
+ set ymax [lindex [$canv cget -scrollregion] 3]
+ if {$ymax == {}} return
+ set yfrac [lindex [$canv yview] 0]
+ set y [expr {$y + $yfrac * $ymax}]
+ set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
+ if {$l < 0} {
+ set l 0
+ }
+ if {$w eq $canv} {
+ if {![info exists rowtextx($l)] || $x < $rowtextx($l)} return
+ }
+ unmarkmatches
+ selectline $l 1
+}
+
+proc commit_descriptor {p} {
+ global commitinfo
+ set l "..."
+ if {[info exists commitinfo($p)]} {
+ set l [lindex $commitinfo($p) 0]
+ set r [lindex $commitinfo($p) 6]
+ }
+ return "$r:$p ($l)"
+}
+
+# append some text to the ctext widget, and make any SHA1 ID
+# that we know about be a clickable link.
+proc appendwithlinks {text} {
+ global ctext idline linknum
+
+ set start [$ctext index "end - 1c"]
+ $ctext insert end $text
+ $ctext insert end "\n"
+ set links [regexp -indices -all -inline {[0-9a-f]{12}} $text]
+ foreach l $links {
+ set s [lindex $l 0]
+ set e [lindex $l 1]
+ set linkid [string range $text $s $e]
+ if {![info exists idline($linkid)]} continue
+ incr e
+ $ctext tag add link "$start + $s c" "$start + $e c"
+ $ctext tag add link$linknum "$start + $s c" "$start + $e c"
+ $ctext tag bind link$linknum <1> [list selectline $idline($linkid) 1]
+ incr linknum
+ }
+ $ctext tag conf link -foreground blue -underline 1
+ $ctext tag bind link <Enter> { %W configure -cursor hand2 }
+ $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
+}
+
+proc selectline {l isnew} {
+ global canv canv2 canv3 ctext commitinfo selectedline
+ global lineid linehtag linentag linedtag
+ global canvy0 linespc parents nparents children
+ global cflist currentid sha1entry
+ global commentend idtags idline linknum
+
+ $canv delete hover
+ normalline
+ if {![info exists lineid($l)] || ![info exists linehtag($l)]} return
+ $canv delete secsel
+ set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
+ -tags secsel -fill [$canv cget -selectbackground]]
+ $canv lower $t
+ $canv2 delete secsel
+ set t [eval $canv2 create rect [$canv2 bbox $linentag($l)] -outline {{}} \
+ -tags secsel -fill [$canv2 cget -selectbackground]]
+ $canv2 lower $t
+ $canv3 delete secsel
+ set t [eval $canv3 create rect [$canv3 bbox $linedtag($l)] -outline {{}} \
+ -tags secsel -fill [$canv3 cget -selectbackground]]
+ $canv3 lower $t
+ set y [expr {$canvy0 + $l * $linespc}]
+ set ymax [lindex [$canv cget -scrollregion] 3]
+ set ytop [expr {$y - $linespc - 1}]
+ set ybot [expr {$y + $linespc + 1}]
+ set wnow [$canv yview]
+ set wtop [expr [lindex $wnow 0] * $ymax]
+ set wbot [expr [lindex $wnow 1] * $ymax]
+ set wh [expr {$wbot - $wtop}]
+ set newtop $wtop
+ if {$ytop < $wtop} {
+ if {$ybot < $wtop} {
+ set newtop [expr {$y - $wh / 2.0}]
+ } else {
+ set newtop $ytop
+ if {$newtop > $wtop - $linespc} {
+ set newtop [expr {$wtop - $linespc}]
+ }
+ }
+ } elseif {$ybot > $wbot} {
+ if {$ytop > $wbot} {
+ set newtop [expr {$y - $wh / 2.0}]
+ } else {
+ set newtop [expr {$ybot - $wh}]
+ if {$newtop < $wtop + $linespc} {
+ set newtop [expr {$wtop + $linespc}]
+ }
+ }
+ }
+ if {$newtop != $wtop} {
+ if {$newtop < 0} {
+ set newtop 0
+ }
+ allcanvs yview moveto [expr $newtop * 1.0 / $ymax]
+ }
+
+ if {$isnew} {
+ addtohistory [list selectline $l 0]
+ }
+
+ set selectedline $l
+
+ set id $lineid($l)
+ set currentid $id
+ $sha1entry delete 0 end
+ $sha1entry insert 0 $id
+ $sha1entry selection from 0
+ $sha1entry selection to end
+
+ $ctext conf -state normal
+ $ctext delete 0.0 end
+ set linknum 0
+ $ctext mark set fmark.0 0.0
+ $ctext mark gravity fmark.0 left
+ set info $commitinfo($id)
+ $ctext insert end "Revision: [lindex $info 6]\n"
+ if {[llength [lindex $info 7]] > 0} {
+ $ctext insert end "Branch: [lindex $info 7]\n"
+ }
+ $ctext insert end "Author: [lindex $info 1] [lindex $info 2]\n"
+ $ctext insert end "Committer: [lindex $info 3] [lindex $info 4]\n"
+ if {[info exists idtags($id)]} {
+ $ctext insert end "Tags:"
+ foreach tag $idtags($id) {
+ $ctext insert end " $tag"
+ }
+ $ctext insert end "\n"
+ }
+
+ set comment {}
+ if {[info exists parents($id)]} {
+ foreach p $parents($id) {
+ append comment "Parent: [commit_descriptor $p]\n"
+ }
+ }
+ if {[info exists children($id)]} {
+ foreach c $children($id) {
+ append comment "Child: [commit_descriptor $c]\n"
+ }
+ }
+ append comment "\n"
+ append comment [lindex $info 5]
+
+ # make anything that looks like a SHA1 ID be a clickable link
+ appendwithlinks $comment
+
+ $ctext tag delete Comments
+ $ctext tag remove found 1.0 end
+ $ctext conf -state disabled
+ set commentend [$ctext index "end - 1c"]
+
+ $cflist delete 0 end
+ $cflist insert end "Comments"
+ if {$nparents($id) <= 1} {
+ set parent "null"
+ if {$nparents($id) == 1} {
+ set parent $parents($id)
+ }
+ startdiff [concat $id $parent]
+ } elseif {$nparents($id) > 1} {
+ mergediff $id
+ }
+}
+
+proc selnextline {dir} {
+ global selectedline
+ if {![info exists selectedline]} return
+ set l [expr $selectedline + $dir]
+ unmarkmatches
+ selectline $l 1
+}
+
+proc unselectline {} {
+ global selectedline
+
+ catch {unset selectedline}
+ allcanvs delete secsel
+}
+
+proc addtohistory {cmd} {
+ global history historyindex
+
+ if {$historyindex > 0
+ && [lindex $history [expr {$historyindex - 1}]] == $cmd} {
+ return
+ }
+
+ if {$historyindex < [llength $history]} {
+ set history [lreplace $history $historyindex end $cmd]
+ } else {
+ lappend history $cmd
+ }
+ incr historyindex
+ if {$historyindex > 1} {
+ .ctop.top.bar.leftbut conf -state normal
+ } else {
+ .ctop.top.bar.leftbut conf -state disabled
+ }
+ .ctop.top.bar.rightbut conf -state disabled
+}
+
+proc goback {} {
+ global history historyindex
+
+ if {$historyindex > 1} {
+ incr historyindex -1
+ set cmd [lindex $history [expr {$historyindex - 1}]]
+ eval $cmd
+ .ctop.top.bar.rightbut conf -state normal
+ }
+ if {$historyindex <= 1} {
+ .ctop.top.bar.leftbut conf -state disabled
+ }
+}
+
+proc goforw {} {
+ global history historyindex
+
+ if {$historyindex < [llength $history]} {
+ set cmd [lindex $history $historyindex]
+ incr historyindex
+ eval $cmd
+ .ctop.top.bar.leftbut conf -state normal
+ }
+ if {$historyindex >= [llength $history]} {
+ .ctop.top.bar.rightbut conf -state disabled
+ }
+}
+
+proc mergediff {id} {
+ global parents diffmergeid diffmergegca mergefilelist diffpindex
+
+ set diffmergeid $id
+ set diffpindex -1
+ set diffmergegca [findgca $parents($id)]
+ if {[info exists mergefilelist($id)]} {
+ if {$mergefilelist($id) ne {}} {
+ showmergediff
+ }
+ } else {
+ contmergediff {}
+ }
+}
+
+proc findgca {ids} {
+ global env
+ set gca {}
+ foreach id $ids {
+ if {$gca eq {}} {
+ set gca $id
+ } else {
+ if {[catch {
+ set gca [exec $env(HG) --config ui.report_untrusted=false debug-merge-base $gca $id]
+ } err]} {
+ return {}
+ }
+ }
+ }
+ return $gca
+}
+
+proc contmergediff {ids} {
+ global diffmergeid diffpindex parents nparents diffmergegca
+ global treediffs mergefilelist diffids treepending
+
+ # diff the child against each of the parents, and diff
+ # each of the parents against the GCA.
+ while 1 {
+ if {[lindex $ids 0] == $diffmergeid && $diffmergegca ne {}} {
+ set ids [list [lindex $ids 1] $diffmergegca]
+ } else {
+ if {[incr diffpindex] >= $nparents($diffmergeid)} break
+ set p [lindex $parents($diffmergeid) $diffpindex]
+ set ids [list $diffmergeid $p]
+ }
+ if {![info exists treediffs($ids)]} {
+ set diffids $ids
+ if {![info exists treepending]} {
+ gettreediffs $ids
+ }
+ return
+ }
+ }
+
+ # If a file in some parent is different from the child and also
+ # different from the GCA, then it's interesting.
+ # If we don't have a GCA, then a file is interesting if it is
+ # different from the child in all the parents.
+ if {$diffmergegca ne {}} {
+ set files {}
+ foreach p $parents($diffmergeid) {
+ set gcadiffs $treediffs([list $p $diffmergegca])
+ foreach f $treediffs([list $diffmergeid $p]) {
+ if {[lsearch -exact $files $f] < 0
+ && [lsearch -exact $gcadiffs $f] >= 0} {
+ lappend files $f
+ }
+ }
+ }
+ set files [lsort $files]
+ } else {
+ set p [lindex $parents($diffmergeid) 0]
+ set files $treediffs([list $diffmergeid $p])
+ for {set i 1} {$i < $nparents($diffmergeid) && $files ne {}} {incr i} {
+ set p [lindex $parents($diffmergeid) $i]
+ set df $treediffs([list $diffmergeid $p])
+ set nf {}
+ foreach f $files {
+ if {[lsearch -exact $df $f] >= 0} {
+ lappend nf $f
+ }
+ }
+ set files $nf
+ }
+ }
+
+ set mergefilelist($diffmergeid) $files
+ if {$files ne {}} {
+ showmergediff
+ }
+}
+
+proc showmergediff {} {
+ global cflist diffmergeid mergefilelist parents
+ global diffopts diffinhunk currentfile currenthunk filelines
+ global diffblocked groupfilelast mergefds groupfilenum grouphunks
+ global env
+
+ set files $mergefilelist($diffmergeid)
+ foreach f $files {
+ $cflist insert end $f
+ }
+ set env(GIT_DIFF_OPTS) $diffopts
+ set flist {}
+ catch {unset currentfile}
+ catch {unset currenthunk}
+ catch {unset filelines}
+ catch {unset groupfilenum}
+ catch {unset grouphunks}
+ set groupfilelast -1
+ foreach p $parents($diffmergeid) {
+ set cmd [list | $env(HG) --config ui.report_untrusted=false debug-diff-tree -p $p $diffmergeid]
+ set cmd [concat $cmd $mergefilelist($diffmergeid)]
+ if {[catch {set f [open $cmd r]} err]} {
+ error_popup "Error getting diffs: $err"
+ foreach f $flist {
+ catch {close $f}
+ }
+ return
+ }
+ lappend flist $f
+ set ids [list $diffmergeid $p]
+ set mergefds($ids) $f
+ set diffinhunk($ids) 0
+ set diffblocked($ids) 0
+ fconfigure $f -blocking 0
+ fileevent $f readable [list getmergediffline $f $ids $diffmergeid]
+ }
+}
+
+proc getmergediffline {f ids id} {
+ global diffmergeid diffinhunk diffoldlines diffnewlines
+ global currentfile currenthunk
+ global diffoldstart diffnewstart diffoldlno diffnewlno
+ global diffblocked mergefilelist
+ global noldlines nnewlines difflcounts filelines
+
+ set n [gets $f line]
+ if {$n < 0} {
+ if {![eof $f]} return
+ }
+
+ if {!([info exists diffmergeid] && $diffmergeid == $id)} {
+ if {$n < 0} {
+ close $f
+ }
+ return
+ }
+
+ if {$diffinhunk($ids) != 0} {
+ set fi $currentfile($ids)
+ if {$n > 0 && [regexp {^[-+ \\]} $line match]} {
+ # continuing an existing hunk
+ set line [string range $line 1 end]
+ set p [lindex $ids 1]
+ if {$match eq "-" || $match eq " "} {
+ set filelines($p,$fi,$diffoldlno($ids)) $line
+ incr diffoldlno($ids)
+ }
+ if {$match eq "+" || $match eq " "} {
+ set filelines($id,$fi,$diffnewlno($ids)) $line
+ incr diffnewlno($ids)
+ }
+ if {$match eq " "} {
+ if {$diffinhunk($ids) == 2} {
+ lappend difflcounts($ids) \
+ [list $noldlines($ids) $nnewlines($ids)]
+ set noldlines($ids) 0
+ set diffinhunk($ids) 1
+ }
+ incr noldlines($ids)
+ } elseif {$match eq "-" || $match eq "+"} {
+ if {$diffinhunk($ids) == 1} {
+ lappend difflcounts($ids) [list $noldlines($ids)]
+ set noldlines($ids) 0
+ set nnewlines($ids) 0
+ set diffinhunk($ids) 2
+ }
+ if {$match eq "-"} {
+ incr noldlines($ids)
+ } else {
+ incr nnewlines($ids)
+ }
+ }
+ # and if it's \ No newline at end of line, then what?
+ return
+ }
+ # end of a hunk
+ if {$diffinhunk($ids) == 1 && $noldlines($ids) != 0} {
+ lappend difflcounts($ids) [list $noldlines($ids)]
+ } elseif {$diffinhunk($ids) == 2
+ && ($noldlines($ids) != 0 || $nnewlines($ids) != 0)} {
+ lappend difflcounts($ids) [list $noldlines($ids) $nnewlines($ids)]
+ }
+ set currenthunk($ids) [list $currentfile($ids) \
+ $diffoldstart($ids) $diffnewstart($ids) \
+ $diffoldlno($ids) $diffnewlno($ids) \
+ $difflcounts($ids)]
+ set diffinhunk($ids) 0
+ # -1 = need to block, 0 = unblocked, 1 = is blocked
+ set diffblocked($ids) -1
+ processhunks
+ if {$diffblocked($ids) == -1} {
+ fileevent $f readable {}
+ set diffblocked($ids) 1
+ }
+ }
+
+ if {$n < 0} {
+ # eof
+ if {!$diffblocked($ids)} {
+ close $f
+ set currentfile($ids) [llength $mergefilelist($diffmergeid)]
+ set currenthunk($ids) [list $currentfile($ids) 0 0 0 0 {}]
+ processhunks
+ }
+ } elseif {[regexp {^diff --git a/(.*) b/} $line match fname]} {
+ # start of a new file
+ set currentfile($ids) \
+ [lsearch -exact $mergefilelist($diffmergeid) $fname]
+ } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
+ $line match f1l f1c f2l f2c rest]} {
+ if {[info exists currentfile($ids)] && $currentfile($ids) >= 0} {
+ # start of a new hunk
+ if {$f1l == 0 && $f1c == 0} {
+ set f1l 1
+ }
+ if {$f2l == 0 && $f2c == 0} {
+ set f2l 1
+ }
+ set diffinhunk($ids) 1
+ set diffoldstart($ids) $f1l
+ set diffnewstart($ids) $f2l
+ set diffoldlno($ids) $f1l
+ set diffnewlno($ids) $f2l
+ set difflcounts($ids) {}
+ set noldlines($ids) 0
+ set nnewlines($ids) 0
+ }
+ }
+}
+
+proc processhunks {} {
+ global diffmergeid parents nparents currenthunk
+ global mergefilelist diffblocked mergefds
+ global grouphunks grouplinestart grouplineend groupfilenum
+
+ set nfiles [llength $mergefilelist($diffmergeid)]
+ while 1 {
+ set fi $nfiles
+ set lno 0
+ # look for the earliest hunk
+ foreach p $parents($diffmergeid) {
+ set ids [list $diffmergeid $p]
+ if {![info exists currenthunk($ids)]} return
+ set i [lindex $currenthunk($ids) 0]
+ set l [lindex $currenthunk($ids) 2]
+ if {$i < $fi || ($i == $fi && $l < $lno)} {
+ set fi $i
+ set lno $l
+ set pi $p
+ }
+ }
+
+ if {$fi < $nfiles} {
+ set ids [list $diffmergeid $pi]
+ set hunk $currenthunk($ids)
+ unset currenthunk($ids)
+ if {$diffblocked($ids) > 0} {
+ fileevent $mergefds($ids) readable \
+ [list getmergediffline $mergefds($ids) $ids $diffmergeid]
+ }
+ set diffblocked($ids) 0
+
+ if {[info exists groupfilenum] && $groupfilenum == $fi
+ && $lno <= $grouplineend} {
+ # add this hunk to the pending group
+ lappend grouphunks($pi) $hunk
+ set endln [lindex $hunk 4]
+ if {$endln > $grouplineend} {
+ set grouplineend $endln
+ }
+ continue
+ }
+ }
+
+ # succeeding stuff doesn't belong in this group, so
+ # process the group now
+ if {[info exists groupfilenum]} {
+ processgroup
+ unset groupfilenum
+ unset grouphunks
+ }
+
+ if {$fi >= $nfiles} break
+
+ # start a new group
+ set groupfilenum $fi
+ set grouphunks($pi) [list $hunk]
+ set grouplinestart $lno
+ set grouplineend [lindex $hunk 4]
+ }
+}
+
+proc processgroup {} {
+ global groupfilelast groupfilenum difffilestart
+ global mergefilelist diffmergeid ctext filelines
+ global parents diffmergeid diffoffset
+ global grouphunks grouplinestart grouplineend nparents
+ global mergemax
+
+ $ctext conf -state normal
+ set id $diffmergeid
+ set f $groupfilenum
+ if {$groupfilelast != $f} {
+ $ctext insert end "\n"
+ set here [$ctext index "end - 1c"]
+ set difffilestart($f) $here
+ set mark fmark.[expr {$f + 1}]
+ $ctext mark set $mark $here
+ $ctext mark gravity $mark left
+ set header [lindex $mergefilelist($id) $f]
+ set l [expr {(78 - [string length $header]) / 2}]
+ set pad [string range "----------------------------------------" 1 $l]
+ $ctext insert end "$pad $header $pad\n" filesep
+ set groupfilelast $f
+ foreach p $parents($id) {
+ set diffoffset($p) 0
+ }
+ }
+
+ $ctext insert end "@@" msep
+ set nlines [expr {$grouplineend - $grouplinestart}]
+ set events {}
+ set pnum 0
+ foreach p $parents($id) {
+ set startline [expr {$grouplinestart + $diffoffset($p)}]
+ set ol $startline
+ set nl $grouplinestart
+ if {[info exists grouphunks($p)]} {
+ foreach h $grouphunks($p) {
+ set l [lindex $h 2]
+ if {$nl < $l} {
+ for {} {$nl < $l} {incr nl} {
+ set filelines($p,$f,$ol) $filelines($id,$f,$nl)
+ incr ol
+ }
+ }
+ foreach chunk [lindex $h 5] {
+ if {[llength $chunk] == 2} {
+ set olc [lindex $chunk 0]
+ set nlc [lindex $chunk 1]
+ set nnl [expr {$nl + $nlc}]
+ lappend events [list $nl $nnl $pnum $olc $nlc]
+ incr ol $olc
+ set nl $nnl
+ } else {
+ incr ol [lindex $chunk 0]
+ incr nl [lindex $chunk 0]
+ }
+ }
+ }
+ }
+ if {$nl < $grouplineend} {
+ for {} {$nl < $grouplineend} {incr nl} {
+ set filelines($p,$f,$ol) $filelines($id,$f,$nl)
+ incr ol
+ }
+ }
+ set nlines [expr {$ol - $startline}]
+ $ctext insert end " -$startline,$nlines" msep
+ incr pnum
+ }
+
+ set nlines [expr {$grouplineend - $grouplinestart}]
+ $ctext insert end " +$grouplinestart,$nlines @@\n" msep
+
+ set events [lsort -integer -index 0 $events]
+ set nevents [llength $events]
+ set nmerge $nparents($diffmergeid)
+ set l $grouplinestart
+ for {set i 0} {$i < $nevents} {set i $j} {
+ set nl [lindex $events $i 0]
+ while {$l < $nl} {
+ $ctext insert end " $filelines($id,$f,$l)\n"
+ incr l
+ }
+ set e [lindex $events $i]
+ set enl [lindex $e 1]
+ set j $i
+ set active {}
+ while 1 {
+ set pnum [lindex $e 2]
+ set olc [lindex $e 3]
+ set nlc [lindex $e 4]
+ if {![info exists delta($pnum)]} {
+ set delta($pnum) [expr {$olc - $nlc}]
+ lappend active $pnum
+ } else {
+ incr delta($pnum) [expr {$olc - $nlc}]
+ }
+ if {[incr j] >= $nevents} break
+ set e [lindex $events $j]
+ if {[lindex $e 0] >= $enl} break
+ if {[lindex $e 1] > $enl} {
+ set enl [lindex $e 1]
+ }
+ }
+ set nlc [expr {$enl - $l}]
+ set ncol mresult
+ set bestpn -1
+ if {[llength $active] == $nmerge - 1} {
+ # no diff for one of the parents, i.e. it's identical
+ for {set pnum 0} {$pnum < $nmerge} {incr pnum} {
+ if {![info exists delta($pnum)]} {
+ if {$pnum < $mergemax} {
+ lappend ncol m$pnum
+ } else {
+ lappend ncol mmax
+ }
+ break
+ }
+ }
+ } elseif {[llength $active] == $nmerge} {
+ # all parents are different, see if one is very similar
+ set bestsim 30
+ for {set pnum 0} {$pnum < $nmerge} {incr pnum} {
+ set sim [similarity $pnum $l $nlc $f \
+ [lrange $events $i [expr {$j-1}]]]
+ if {$sim > $bestsim} {
+ set bestsim $sim
+ set bestpn $pnum
+ }
+ }
+ if {$bestpn >= 0} {
+ lappend ncol m$bestpn
+ }
+ }
+ set pnum -1
+ foreach p $parents($id) {
+ incr pnum
+ if {![info exists delta($pnum)] || $pnum == $bestpn} continue
+ set olc [expr {$nlc + $delta($pnum)}]
+ set ol [expr {$l + $diffoffset($p)}]
+ incr diffoffset($p) $delta($pnum)
+ unset delta($pnum)
+ for {} {$olc > 0} {incr olc -1} {
+ $ctext insert end "-$filelines($p,$f,$ol)\n" m$pnum
+ incr ol
+ }
+ }
+ set endl [expr {$l + $nlc}]
+ if {$bestpn >= 0} {
+ # show this pretty much as a normal diff
+ set p [lindex $parents($id) $bestpn]
+ set ol [expr {$l + $diffoffset($p)}]
+ incr diffoffset($p) $delta($bestpn)
+ unset delta($bestpn)
+ for {set k $i} {$k < $j} {incr k} {
+ set e [lindex $events $k]
+ if {[lindex $e 2] != $bestpn} continue
+ set nl [lindex $e 0]
+ set ol [expr {$ol + $nl - $l}]
+ for {} {$l < $nl} {incr l} {
+ $ctext insert end "+$filelines($id,$f,$l)\n" $ncol
+ }
+ set c [lindex $e 3]
+ for {} {$c > 0} {incr c -1} {
+ $ctext insert end "-$filelines($p,$f,$ol)\n" m$bestpn
+ incr ol
+ }
+ set nl [lindex $e 1]
+ for {} {$l < $nl} {incr l} {
+ $ctext insert end "+$filelines($id,$f,$l)\n" mresult
+ }
+ }
+ }
+ for {} {$l < $endl} {incr l} {
+ $ctext insert end "+$filelines($id,$f,$l)\n" $ncol
+ }
+ }
+ while {$l < $grouplineend} {
+ $ctext insert end " $filelines($id,$f,$l)\n"
+ incr l
+ }
+ $ctext conf -state disabled
+}
+
+proc similarity {pnum l nlc f events} {
+ global diffmergeid parents diffoffset filelines
+
+ set id $diffmergeid
+ set p [lindex $parents($id) $pnum]
+ set ol [expr {$l + $diffoffset($p)}]
+ set endl [expr {$l + $nlc}]
+ set same 0
+ set diff 0
+ foreach e $events {
+ if {[lindex $e 2] != $pnum} continue
+ set nl [lindex $e 0]
+ set ol [expr {$ol + $nl - $l}]
+ for {} {$l < $nl} {incr l} {
+ incr same [string length $filelines($id,$f,$l)]
+ incr same
+ }
+ set oc [lindex $e 3]
+ for {} {$oc > 0} {incr oc -1} {
+ incr diff [string length $filelines($p,$f,$ol)]
+ incr diff
+ incr ol
+ }
+ set nl [lindex $e 1]
+ for {} {$l < $nl} {incr l} {
+ incr diff [string length $filelines($id,$f,$l)]
+ incr diff
+ }
+ }
+ for {} {$l < $endl} {incr l} {
+ incr same [string length $filelines($id,$f,$l)]
+ incr same
+ }
+ if {$same == 0} {
+ return 0
+ }
+ return [expr {200 * $same / (2 * $same + $diff)}]
+}
+
+proc startdiff {ids} {
+ global treediffs diffids treepending diffmergeid
+
+ set diffids $ids
+ catch {unset diffmergeid}
+ if {![info exists treediffs($ids)]} {
+ if {![info exists treepending]} {
+ gettreediffs $ids
+ }
+ } else {
+ addtocflist $ids
+ }
+}
+
+proc addtocflist {ids} {
+ global treediffs cflist
+ foreach f $treediffs($ids) {
+ $cflist insert end $f
+ }
+ getblobdiffs $ids
+}
+
+proc gettreediffs {ids} {
+ global treediff parents treepending env
+ set treepending $ids
+ set treediff {}
+ set id [lindex $ids 0]
+ set p [lindex $ids 1]
+ if [catch {set gdtf [open "|{$env(HG)} --config ui.report_untrusted=false debug-diff-tree -r $p $id" r]}] return
+ fconfigure $gdtf -blocking 0
+ fileevent $gdtf readable [list gettreediffline $gdtf $ids]
+}
+
+proc gettreediffline {gdtf ids} {
+ global treediff treediffs treepending diffids diffmergeid
+
+ set n [gets $gdtf line]
+ if {$n < 0} {
+ if {![eof $gdtf]} return
+ close $gdtf
+ set treediffs($ids) $treediff
+ unset treepending
+ if {$ids != $diffids} {
+ gettreediffs $diffids
+ } else {
+ if {[info exists diffmergeid]} {
+ contmergediff $ids
+ } else {
+ addtocflist $ids
+ }
+ }
+ return
+ }
+ set tab1 [expr [string first "\t" $line] + 1]
+ set tab2 [expr [string first "\t" $line $tab1] - 1]
+ set file [string range $line $tab1 $tab2]
+ lappend treediff $file
+}
+
+proc getblobdiffs {ids} {
+ global diffopts blobdifffd diffids env curdifftag curtagstart
+ global difffilestart nextupdate diffinhdr treediffs
+
+ set id [lindex $ids 0]
+ set p [lindex $ids 1]
+ set env(GIT_DIFF_OPTS) $diffopts
+ set cmd [list | $env(HG) --config ui.report_untrusted=false debug-diff-tree -r -p -C $p $id]
+ if {[catch {set bdf [open $cmd r]} err]} {
+ puts "error getting diffs: $err"
+ return
+ }
+ set diffinhdr 0
+ fconfigure $bdf -blocking 0
+ set blobdifffd($ids) $bdf
+ set curdifftag Comments
+ set curtagstart 0.0
+ catch {unset difffilestart}
+ fileevent $bdf readable [list getblobdiffline $bdf $diffids]
+ set nextupdate [expr {[clock clicks -milliseconds] + 100}]
+}
+
+proc getblobdiffline {bdf ids} {
+ global diffids blobdifffd ctext curdifftag curtagstart
+ global diffnexthead diffnextnote difffilestart
+ global nextupdate diffinhdr treediffs
+ global gaudydiff
+
+ set n [gets $bdf line]
+ if {$n < 0} {
+ if {[eof $bdf]} {
+ close $bdf
+ if {$ids == $diffids && $bdf == $blobdifffd($ids)} {
+ $ctext tag add $curdifftag $curtagstart end
+ }
+ }
+ return
+ }
+ if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
+ return
+ }
+ regsub -all "\r" $line "" line
+ $ctext conf -state normal
+ if {[regexp {^diff --git a/(.*) b/(.*)} $line match fname newname]} {
+ # start of a new file
+ $ctext insert end "\n"
+ $ctext tag add $curdifftag $curtagstart end
+ set curtagstart [$ctext index "end - 1c"]
+ set header $newname
+ set here [$ctext index "end - 1c"]
+ set i [lsearch -exact $treediffs($diffids) $fname]
+ if {$i >= 0} {
+ set difffilestart($i) $here
+ incr i
+ $ctext mark set fmark.$i $here
+ $ctext mark gravity fmark.$i left
+ }
+ if {$newname != $fname} {
+ set i [lsearch -exact $treediffs($diffids) $newname]
+ if {$i >= 0} {
+ set difffilestart($i) $here
+ incr i
+ $ctext mark set fmark.$i $here
+ $ctext mark gravity fmark.$i left
+ }
+ }
+ set curdifftag "f:$fname"
+ $ctext tag delete $curdifftag
+ set l [expr {(78 - [string length $header]) / 2}]
+ set pad [string range "----------------------------------------" 1 $l]
+ $ctext insert end "$pad $header $pad\n" filesep
+ set diffinhdr 1
+ } elseif {[regexp {^(---|\+\+\+)} $line]} {
+ set diffinhdr 0
+ } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
+ $line match f1l f1c f2l f2c rest]} {
+ if {$gaudydiff} {
+ $ctext insert end "\t" hunksep
+ $ctext insert end " $f1l " d0 " $f2l " d1
+ $ctext insert end " $rest \n" hunksep
+ } else {
+ $ctext insert end "$line\n" hunksep
+ }
+ set diffinhdr 0
+ } else {
+ set x [string range $line 0 0]
+ if {$x == "-" || $x == "+"} {
+ set tag [expr {$x == "+"}]
+ if {$gaudydiff} {
+ set line [string range $line 1 end]
+ }
+ $ctext insert end "$line\n" d$tag
+ } elseif {$x == " "} {
+ if {$gaudydiff} {
+ set line [string range $line 1 end]
+ }
+ $ctext insert end "$line\n"
+ } elseif {$diffinhdr || $x == "\\"} {
+ # e.g. "\ No newline at end of file"
+ $ctext insert end "$line\n" filesep
+ } elseif {$line != ""} {
+ # Something else we don't recognize
+ if {$curdifftag != "Comments"} {
+ $ctext insert end "\n"
+ $ctext tag add $curdifftag $curtagstart end
+ set curtagstart [$ctext index "end - 1c"]
+ set curdifftag Comments
+ }
+ $ctext insert end "$line\n" filesep
+ }
+ }
+ $ctext conf -state disabled
+ if {[clock clicks -milliseconds] >= $nextupdate} {
+ incr nextupdate 100
+ fileevent $bdf readable {}
+ update
+ fileevent $bdf readable "getblobdiffline $bdf {$ids}"
+ }
+}
+
+proc nextfile {} {
+ global difffilestart ctext
+ set here [$ctext index @0,0]
+ for {set i 0} {[info exists difffilestart($i)]} {incr i} {
+ if {[$ctext compare $difffilestart($i) > $here]} {
+ if {![info exists pos]
+ || [$ctext compare $difffilestart($i) < $pos]} {
+ set pos $difffilestart($i)
+ }
+ }
+ }
+ if {[info exists pos]} {
+ $ctext yview $pos
+ }
+}
+
+proc listboxsel {} {
+ global ctext cflist currentid
+ if {![info exists currentid]} return
+ set sel [lsort [$cflist curselection]]
+ if {$sel eq {}} return
+ set first [lindex $sel 0]
+ catch {$ctext yview fmark.$first}
+}
+
+proc setcoords {} {
+ global linespc charspc canvx0 canvy0 mainfont
+ global xspc1 xspc2 lthickness
+
+ set linespc [font metrics $mainfont -linespace]
+ set charspc [font measure $mainfont "m"]
+ set canvy0 [expr 3 + 0.5 * $linespc]
+ set canvx0 [expr 3 + 0.5 * $linespc]
+ set lthickness [expr {int($linespc / 9) + 1}]
+ set xspc1(0) $linespc
+ set xspc2 $linespc
+}
+
+proc redisplay {} {
+ global stopped redisplaying phase
+ if {$stopped > 1} return
+ if {$phase == "getcommits"} return
+ set redisplaying 1
+ if {$phase == "drawgraph" || $phase == "incrdraw"} {
+ set stopped 1
+ } else {
+ drawgraph
+ }
+}
+
+proc incrfont {inc} {
+ global mainfont namefont textfont ctext canv phase
+ global stopped entries curidfont
+ unmarkmatches
+ set mainfont [lreplace $mainfont 1 1 [expr {[lindex $mainfont 1] + $inc}]]
+ set curidfont [lreplace $curidfont 1 1 [expr {[lindex $curidfont 1] + $inc}]]
+ set namefont [lreplace $namefont 1 1 [expr {[lindex $namefont 1] + $inc}]]
+ set textfont [lreplace $textfont 1 1 [expr {[lindex $textfont 1] + $inc}]]
+ setcoords
+ $ctext conf -font $textfont
+ $ctext tag conf filesep -font [concat $textfont bold]
+ foreach e $entries {
+ $e conf -font $mainfont
+ }
+ if {$phase == "getcommits"} {
+ $canv itemconf textitems -font $mainfont
+ }
+ redisplay
+}
+
+proc clearsha1 {} {
+ global sha1entry sha1string
+ if {[string length $sha1string] == 40} {
+ $sha1entry delete 0 end
+ }
+}
+
+proc sha1change {n1 n2 op} {
+ global sha1string currentid sha1but
+ if {$sha1string == {}
+ || ([info exists currentid] && $sha1string == $currentid)} {
+ set state disabled
+ } else {
+ set state normal
+ }
+ if {[$sha1but cget -state] == $state} return
+ if {$state == "normal"} {
+ $sha1but conf -state normal -relief raised -text "Goto: "
+ } else {
+ $sha1but conf -state disabled -relief flat -text "SHA1 ID: "
+ }
+}
+
+proc gotocommit {} {
+ global sha1string currentid idline tagids
+ global lineid numcommits
+
+ if {$sha1string == {}
+ || ([info exists currentid] && $sha1string == $currentid)} return
+ if {[info exists tagids($sha1string)]} {
+ set id $tagids($sha1string)
+ } else {
+ set id [string tolower $sha1string]
+ if {[regexp {^[0-9a-f]{4,39}$} $id]} {
+ set matches {}
+ for {set l 0} {$l < $numcommits} {incr l} {
+ if {[string match $id* $lineid($l)]} {
+ lappend matches $lineid($l)
+ }
+ }
+ if {$matches ne {}} {
+ if {[llength $matches] > 1} {
+ error_popup "Short SHA1 id $id is ambiguous"
+ return
+ }
+ set id [lindex $matches 0]
+ }
+ }
+ }
+ if {[info exists idline($id)]} {
+ selectline $idline($id) 1
+ return
+ }
+ if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
+ set type "SHA1 id"
+ } else {
+ set type "Tag"
+ }
+ error_popup "$type $sha1string is not known"
+}
+
+proc lineenter {x y id} {
+ global hoverx hovery hoverid hovertimer
+ global commitinfo canv
+
+ if {![info exists commitinfo($id)]} return
+ set hoverx $x
+ set hovery $y
+ set hoverid $id
+ if {[info exists hovertimer]} {
+ after cancel $hovertimer
+ }
+ set hovertimer [after 500 linehover]
+ $canv delete hover
+}
+
+proc linemotion {x y id} {
+ global hoverx hovery hoverid hovertimer
+
+ if {[info exists hoverid] && $id == $hoverid} {
+ set hoverx $x
+ set hovery $y
+ if {[info exists hovertimer]} {
+ after cancel $hovertimer
+ }
+ set hovertimer [after 500 linehover]
+ }
+}
+
+proc lineleave {id} {
+ global hoverid hovertimer canv
+
+ if {[info exists hoverid] && $id == $hoverid} {
+ $canv delete hover
+ if {[info exists hovertimer]} {
+ after cancel $hovertimer
+ unset hovertimer
+ }
+ unset hoverid
+ }
+}
+
+proc linehover {} {
+ global hoverx hovery hoverid hovertimer
+ global canv linespc lthickness
+ global commitinfo mainfont
+
+ set text [lindex $commitinfo($hoverid) 0]
+ set ymax [lindex [$canv cget -scrollregion] 3]
+ if {$ymax == {}} return
+ set yfrac [lindex [$canv yview] 0]
+ set x [expr {$hoverx + 2 * $linespc}]
+ set y [expr {$hovery + $yfrac * $ymax - $linespc / 2}]
+ set x0 [expr {$x - 2 * $lthickness}]
+ set y0 [expr {$y - 2 * $lthickness}]
+ set x1 [expr {$x + [font measure $mainfont $text] + 2 * $lthickness}]
+ set y1 [expr {$y + $linespc + 2 * $lthickness}]
+ set t [$canv create rectangle $x0 $y0 $x1 $y1 \
+ -fill \#ffff80 -outline black -width 1 -tags hover]
+ $canv raise $t
+ set t [$canv create text $x $y -anchor nw -text $text -tags hover]
+ $canv raise $t
+}
+
+proc clickisonarrow {id y} {
+ global mainline mainlinearrow sidelines lthickness
+
+ set thresh [expr {2 * $lthickness + 6}]
+ if {[info exists mainline($id)]} {
+ if {$mainlinearrow($id) ne "none"} {
+ if {abs([lindex $mainline($id) 1] - $y) < $thresh} {
+ return "up"
+ }
+ }
+ }
+ if {[info exists sidelines($id)]} {
+ foreach ls $sidelines($id) {
+ set coords [lindex $ls 0]
+ set arrow [lindex $ls 2]
+ if {$arrow eq "first" || $arrow eq "both"} {
+ if {abs([lindex $coords 1] - $y) < $thresh} {
+ return "up"
+ }
+ }
+ if {$arrow eq "last" || $arrow eq "both"} {
+ if {abs([lindex $coords end] - $y) < $thresh} {
+ return "down"
+ }
+ }
+ }
+ }
+ return {}
+}
+
+proc arrowjump {id dirn y} {
+ global mainline sidelines canv
+
+ set yt {}
+ if {$dirn eq "down"} {
+ if {[info exists mainline($id)]} {
+ set y1 [lindex $mainline($id) 1]
+ if {$y1 > $y} {
+ set yt $y1
+ }
+ }
+ if {[info exists sidelines($id)]} {
+ foreach ls $sidelines($id) {
+ set y1 [lindex $ls 0 1]
+ if {$y1 > $y && ($yt eq {} || $y1 < $yt)} {
+ set yt $y1
+ }
+ }
+ }
+ } else {
+ if {[info exists sidelines($id)]} {
+ foreach ls $sidelines($id) {
+ set y1 [lindex $ls 0 end]
+ if {$y1 < $y && ($yt eq {} || $y1 > $yt)} {
+ set yt $y1
+ }
+ }
+ }
+ }
+ if {$yt eq {}} return
+ set ymax [lindex [$canv cget -scrollregion] 3]
+ if {$ymax eq {} || $ymax <= 0} return
+ set view [$canv yview]
+ set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
+ set yfrac [expr {$yt / $ymax - $yspan / 2}]
+ if {$yfrac < 0} {
+ set yfrac 0
+ }
+ $canv yview moveto $yfrac
+}
+
+proc lineclick {x y id isnew} {
+ global ctext commitinfo children cflist canv thickerline
+
+ unmarkmatches
+ unselectline
+ normalline
+ $canv delete hover
+ # draw this line thicker than normal
+ drawlines $id 1
+ set thickerline $id
+ if {$isnew} {
+ set ymax [lindex [$canv cget -scrollregion] 3]
+ if {$ymax eq {}} return
+ set yfrac [lindex [$canv yview] 0]
+ set y [expr {$y + $yfrac * $ymax}]
+ }
+ set dirn [clickisonarrow $id $y]
+ if {$dirn ne {}} {
+ arrowjump $id $dirn $y
+ return
+ }
+
+ if {$isnew} {
+ addtohistory [list lineclick $x $y $id 0]
+ }
+ # fill the details pane with info about this line
+ $ctext conf -state normal
+ $ctext delete 0.0 end
+ $ctext tag conf link -foreground blue -underline 1
+ $ctext tag bind link <Enter> { %W configure -cursor hand2 }
+ $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
+ $ctext insert end "Parent:\t"
+ $ctext insert end $id [list link link0]
+ $ctext tag bind link0 <1> [list selbyid $id]
+ set info $commitinfo($id)
+ $ctext insert end "\n\t[lindex $info 0]\n"
+ $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
+ $ctext insert end "\tDate:\t[lindex $info 2]\n"
+ if {[info exists children($id)]} {
+ $ctext insert end "\nChildren:"
+ set i 0
+ foreach child $children($id) {
+ incr i
+ set info $commitinfo($child)
+ $ctext insert end "\n\t"
+ $ctext insert end $child [list link link$i]
+ $ctext tag bind link$i <1> [list selbyid $child]
+ $ctext insert end "\n\t[lindex $info 0]"
+ $ctext insert end "\n\tAuthor:\t[lindex $info 1]"
+ $ctext insert end "\n\tDate:\t[lindex $info 2]\n"
+ }
+ }
+ $ctext conf -state disabled
+
+ $cflist delete 0 end
+}
+
+proc normalline {} {
+ global thickerline
+ if {[info exists thickerline]} {
+ drawlines $thickerline 0
+ unset thickerline
+ }
+}
+
+proc selbyid {id} {
+ global idline
+ if {[info exists idline($id)]} {
+ selectline $idline($id) 1
+ }
+}
+
+proc mstime {} {
+ global startmstime
+ if {![info exists startmstime]} {
+ set startmstime [clock clicks -milliseconds]
+ }
+ return [format "%.3f" [expr {([clock click -milliseconds] - $startmstime) / 1000.0}]]
+}
+
+proc rowmenu {x y id} {
+ global rowctxmenu idline selectedline rowmenuid hgvdiff
+
+ if {![info exists selectedline] || $idline($id) eq $selectedline} {
+ set state disabled
+ } else {
+ set state normal
+ }
+ $rowctxmenu entryconfigure 0 -state $state
+ $rowctxmenu entryconfigure 1 -state $state
+ $rowctxmenu entryconfigure 2 -state $state
+ if { $hgvdiff ne "" } {
+ $rowctxmenu entryconfigure 6 -state $state
+ }
+ set rowmenuid $id
+ tk_popup $rowctxmenu $x $y
+}
+
+proc diffvssel {dirn} {
+ global rowmenuid selectedline lineid
+
+ if {![info exists selectedline]} return
+ if {$dirn} {
+ set oldid $lineid($selectedline)
+ set newid $rowmenuid
+ } else {
+ set oldid $rowmenuid
+ set newid $lineid($selectedline)
+ }
+ addtohistory [list doseldiff $oldid $newid]
+ doseldiff $oldid $newid
+}
+
+proc doseldiff {oldid newid} {
+ global ctext cflist
+ global commitinfo
+
+ $ctext conf -state normal
+ $ctext delete 0.0 end
+ $ctext mark set fmark.0 0.0
+ $ctext mark gravity fmark.0 left
+ $cflist delete 0 end
+ $cflist insert end "Top"
+ $ctext insert end "From "
+ $ctext tag conf link -foreground blue -underline 1
+ $ctext tag bind link <Enter> { %W configure -cursor hand2 }
+ $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
+ $ctext tag bind link0 <1> [list selbyid $oldid]
+ $ctext insert end $oldid [list link link0]
+ $ctext insert end "\n "
+ $ctext insert end [lindex $commitinfo($oldid) 0]
+ $ctext insert end "\n\nTo "
+ $ctext tag bind link1 <1> [list selbyid $newid]
+ $ctext insert end $newid [list link link1]
+ $ctext insert end "\n "
+ $ctext insert end [lindex $commitinfo($newid) 0]
+ $ctext insert end "\n"
+ $ctext conf -state disabled
+ $ctext tag delete Comments
+ $ctext tag remove found 1.0 end
+ startdiff [list $newid $oldid]
+}
+
+proc mkpatch {} {
+ global rowmenuid currentid commitinfo patchtop patchnum
+
+ if {![info exists currentid]} return
+ set oldid $currentid
+ set oldhead [lindex $commitinfo($oldid) 0]
+ set newid $rowmenuid
+ set newhead [lindex $commitinfo($newid) 0]
+ set top .patch
+ set patchtop $top
+ catch {destroy $top}
+ toplevel $top
+ label $top.title -text "Generate patch"
+ grid $top.title - -pady 10
+ label $top.from -text "From:"
+ entry $top.fromsha1 -width 40 -relief flat
+ $top.fromsha1 insert 0 $oldid
+ $top.fromsha1 conf -state readonly
+ grid $top.from $top.fromsha1 -sticky w
+ entry $top.fromhead -width 60 -relief flat
+ $top.fromhead insert 0 $oldhead
+ $top.fromhead conf -state readonly
+ grid x $top.fromhead -sticky w
+ label $top.to -text "To:"
+ entry $top.tosha1 -width 40 -relief flat
+ $top.tosha1 insert 0 $newid
+ $top.tosha1 conf -state readonly
+ grid $top.to $top.tosha1 -sticky w
+ entry $top.tohead -width 60 -relief flat
+ $top.tohead insert 0 $newhead
+ $top.tohead conf -state readonly
+ grid x $top.tohead -sticky w
+ button $top.rev -text "Reverse" -command mkpatchrev -padx 5
+ grid $top.rev x -pady 10
+ label $top.flab -text "Output file:"
+ entry $top.fname -width 60
+ $top.fname insert 0 [file normalize "patch$patchnum.patch"]
+ incr patchnum
+ grid $top.flab $top.fname -sticky w
+ frame $top.buts
+ button $top.buts.gen -text "Generate" -command mkpatchgo
+ button $top.buts.can -text "Cancel" -command mkpatchcan
+ grid $top.buts.gen $top.buts.can
+ grid columnconfigure $top.buts 0 -weight 1 -uniform a
+ grid columnconfigure $top.buts 1 -weight 1 -uniform a
+ grid $top.buts - -pady 10 -sticky ew
+ focus $top.fname
+}
+
+proc mkpatchrev {} {
+ global patchtop
+
+ set oldid [$patchtop.fromsha1 get]
+ set oldhead [$patchtop.fromhead get]
+ set newid [$patchtop.tosha1 get]
+ set newhead [$patchtop.tohead get]
+ foreach e [list fromsha1 fromhead tosha1 tohead] \
+ v [list $newid $newhead $oldid $oldhead] {
+ $patchtop.$e conf -state normal
+ $patchtop.$e delete 0 end
+ $patchtop.$e insert 0 $v
+ $patchtop.$e conf -state readonly
+ }
+}
+
+proc mkpatchgo {} {
+ global patchtop env
+
+ set oldid [$patchtop.fromsha1 get]
+ set newid [$patchtop.tosha1 get]
+ set fname [$patchtop.fname get]
+ if {[catch {exec $env(HG) --config ui.report_untrusted=false debug-diff-tree -p $oldid $newid >$fname &} err]} {
+ error_popup "Error creating patch: $err"
+ }
+ catch {destroy $patchtop}
+ unset patchtop
+}
+
+proc mkpatchcan {} {
+ global patchtop
+
+ catch {destroy $patchtop}
+ unset patchtop
+}
+
+proc mktag {} {
+ global rowmenuid mktagtop commitinfo
+
+ set top .maketag
+ set mktagtop $top
+ catch {destroy $top}
+ toplevel $top
+ label $top.title -text "Create tag"
+ grid $top.title - -pady 10
+ label $top.id -text "ID:"
+ entry $top.sha1 -width 40 -relief flat
+ $top.sha1 insert 0 $rowmenuid
+ $top.sha1 conf -state readonly
+ grid $top.id $top.sha1 -sticky w
+ entry $top.head -width 60 -relief flat
+ $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
+ $top.head conf -state readonly
+ grid x $top.head -sticky w
+ label $top.tlab -text "Tag name:"
+ entry $top.tag -width 60
+ grid $top.tlab $top.tag -sticky w
+ frame $top.buts
+ button $top.buts.gen -text "Create" -command mktaggo
+ button $top.buts.can -text "Cancel" -command mktagcan
+ grid $top.buts.gen $top.buts.can
+ grid columnconfigure $top.buts 0 -weight 1 -uniform a
+ grid columnconfigure $top.buts 1 -weight 1 -uniform a
+ grid $top.buts - -pady 10 -sticky ew
+ focus $top.tag
+}
+
+proc domktag {} {
+ global mktagtop env tagids idtags
+
+ set id [$mktagtop.sha1 get]
+ set tag [$mktagtop.tag get]
+ if {$tag == {}} {
+ error_popup "No tag name specified"
+ return
+ }
+ if {[info exists tagids($tag)]} {
+ error_popup "Tag \"$tag\" already exists"
+ return
+ }
+ if {[catch {
+ set out [exec $env(HG) --config ui.report_untrusted=false tag -r $id $tag]
+ } err]} {
+ error_popup "Error creating tag: $err"
+ return
+ }
+
+ set tagids($tag) $id
+ lappend idtags($id) $tag
+ redrawtags $id
+}
+
+proc redrawtags {id} {
+ global canv linehtag idline idpos selectedline
+
+ if {![info exists idline($id)]} return
+ $canv delete tag.$id
+ set xt [eval drawtags $id $idpos($id)]
+ $canv coords $linehtag($idline($id)) $xt [lindex $idpos($id) 2]
+ if {[info exists selectedline] && $selectedline == $idline($id)} {
+ selectline $selectedline 0
+ }
+}
+
+proc mktagcan {} {
+ global mktagtop
+
+ catch {destroy $mktagtop}
+ unset mktagtop
+}
+
+proc mktaggo {} {
+ domktag
+ mktagcan
+}
+
+proc writecommit {} {
+ global rowmenuid wrcomtop commitinfo wrcomcmd
+
+ set top .writecommit
+ set wrcomtop $top
+ catch {destroy $top}
+ toplevel $top
+ label $top.title -text "Write commit to file"
+ grid $top.title - -pady 10
+ label $top.id -text "ID:"
+ entry $top.sha1 -width 40 -relief flat
+ $top.sha1 insert 0 $rowmenuid
+ $top.sha1 conf -state readonly
+ grid $top.id $top.sha1 -sticky w
+ entry $top.head -width 60 -relief flat
+ $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
+ $top.head conf -state readonly
+ grid x $top.head -sticky w
+ label $top.clab -text "Command:"
+ entry $top.cmd -width 60 -textvariable wrcomcmd
+ grid $top.clab $top.cmd -sticky w -pady 10
+ label $top.flab -text "Output file:"
+ entry $top.fname -width 60
+ $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"]
+ grid $top.flab $top.fname -sticky w
+ frame $top.buts
+ button $top.buts.gen -text "Write" -command wrcomgo
+ button $top.buts.can -text "Cancel" -command wrcomcan
+ grid $top.buts.gen $top.buts.can
+ grid columnconfigure $top.buts 0 -weight 1 -uniform a
+ grid columnconfigure $top.buts 1 -weight 1 -uniform a
+ grid $top.buts - -pady 10 -sticky ew
+ focus $top.fname
+}
+
+proc wrcomgo {} {
+ global wrcomtop
+
+ set id [$wrcomtop.sha1 get]
+ set cmd "echo $id | [$wrcomtop.cmd get]"
+ set fname [$wrcomtop.fname get]
+ if {[catch {exec sh -c $cmd > $fname &} err]} {
+ error_popup "Error writing commit: $err"
+ }
+ catch {destroy $wrcomtop}
+ unset wrcomtop
+}
+
+proc wrcomcan {} {
+ global wrcomtop
+
+ catch {destroy $wrcomtop}
+ unset wrcomtop
+}
+
+proc listrefs {id} {
+ global idtags idheads idotherrefs
+
+ set x {}
+ if {[info exists idtags($id)]} {
+ set x $idtags($id)
+ }
+ set y {}
+ if {[info exists idheads($id)]} {
+ set y $idheads($id)
+ }
+ set z {}
+ if {[info exists idotherrefs($id)]} {
+ set z $idotherrefs($id)
+ }
+ return [list $x $y $z]
+}
+
+proc rereadrefs {} {
+ global idtags idheads idotherrefs
+ global tagids headids otherrefids
+
+ set refids [concat [array names idtags] \
+ [array names idheads] [array names idotherrefs]]
+ foreach id $refids {
+ if {![info exists ref($id)]} {
+ set ref($id) [listrefs $id]
+ }
+ }
+ foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
+ catch {unset $v}
+ }
+ readrefs
+ set refids [lsort -unique [concat $refids [array names idtags] \
+ [array names idheads] [array names idotherrefs]]]
+ foreach id $refids {
+ set v [listrefs $id]
+ if {![info exists ref($id)] || $ref($id) != $v} {
+ redrawtags $id
+ }
+ }
+}
+
+proc vdiff {withparent} {
+ global env rowmenuid selectedline lineid hgvdiff
+
+ if {![info exists rowmenuid]} return
+ set curid $rowmenuid
+
+ if {$withparent} {
+ set parents [exec $env(HG) --config ui.report_untrusted=false parents --rev $curid --template "{node}\n"]
+ set firstparent [lindex [split $parents "\n"] 0]
+ set otherid $firstparent
+ } else {
+ if {![info exists selectedline]} return
+ set otherid $lineid($selectedline)
+ }
+ set range "$otherid:$curid"
+ if {[catch {exec $env(HG) --config ui.report_untrusted=false $hgvdiff -r $range} err]} {
+ # Ignore errors, this is just visualization
+ }
+}
+
+proc showtag {tag isnew} {
+ global ctext cflist tagcontents tagids linknum
+
+ if {$isnew} {
+ addtohistory [list showtag $tag 0]
+ }
+ $ctext conf -state normal
+ $ctext delete 0.0 end
+ set linknum 0
+ if {[info exists tagcontents($tag)]} {
+ set text $tagcontents($tag)
+ } else {
+ set text "Tag: $tag\nId: $tagids($tag)"
+ }
+ appendwithlinks $text
+ $ctext conf -state disabled
+ $cflist delete 0 end
+}
+
+proc doquit {} {
+ global stopped
+ set stopped 100
+ destroy .
+}
+
+proc getconfig {} {
+ global env
+
+ set lines [exec $env(HG) debug-config]
+ regsub -all "\r\n" $lines "\n" config
+ set config {}
+ foreach line [split $lines "\n"] {
+ regsub "^(k|v)=" $line "" line
+ lappend config $line
+ }
+ return $config
+}
+
+# defaults...
+set datemode 0
+set boldnames 0
+set diffopts "-U 5 -p"
+set wrcomcmd "\"\$HG\" --config ui.report_untrusted=false debug-diff-tree --stdin -p --pretty"
+
+set mainfont {Helvetica 9}
+set curidfont {}
+set textfont {Courier 9}
+set findmergefiles 0
+set gaudydiff 0
+set maxgraphpct 50
+set maxwidth 16
+
+set colors {green red blue magenta darkgrey brown orange}
+set authorcolors {
+ black blue deeppink mediumorchid blue burlywood4 goldenrod slateblue red2 navy dimgrey
+}
+set bgcolor white
+
+# This color should probably be some system color (provided by tk),
+# but as the bgcolor has always been set to white, I choose to ignore
+set fgcolor black
+set diffaddcolor "#00a000"
+set diffremcolor red
+set diffmerge1color red
+set diffmerge2color blue
+set hunksepcolor blue
+
+catch {source ~/.hgk}
+
+if {$curidfont == ""} { # initialize late based on current mainfont
+ set curidfont "$mainfont bold italic underline"
+}
+
+set namefont $mainfont
+if {$boldnames} {
+ lappend namefont bold
+}
+
+set revtreeargs {}
+foreach arg $argv {
+ switch -regexp -- $arg {
+ "^$" { }
+ "^-b" { set boldnames 1 }
+ "^-d" { set datemode 1 }
+ default {
+ lappend revtreeargs $arg
+ }
+ }
+}
+
+set history {}
+set historyindex 0
+
+set stopped 0
+set redisplaying 0
+set stuffsaved 0
+set patchnum 0
+
+array set config [getconfig]
+set hgvdiff $config(vdiff)
+setcoords
+makewindow
+readrefs
+set hgroot [exec $env(HG) root]
+wm title . "hgk $hgroot"
+getcommits $revtreeargs
diff --git a/sys/src/cmd/hg/contrib/hgsh/Makefile b/sys/src/cmd/hg/contrib/hgsh/Makefile
new file mode 100644
index 000000000..966158f54
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/hgsh/Makefile
@@ -0,0 +1,13 @@
+CC := gcc
+CFLAGS := -g -O2 -Wall -Werror
+
+prefix ?= /usr/bin
+
+hgsh: hgsh.o
+ $(CC) -o $@ $<
+
+install: hgsh
+ install -m755 hgsh $(prefix)
+
+clean:
+ rm -f *.o hgsh
diff --git a/sys/src/cmd/hg/contrib/hgsh/hgsh.c b/sys/src/cmd/hg/contrib/hgsh/hgsh.c
new file mode 100644
index 000000000..a6ce0063a
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/hgsh/hgsh.c
@@ -0,0 +1,439 @@
+/*
+ * hgsh.c - restricted login shell for mercurial
+ *
+ * Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+ *
+ * This software may be used and distributed according to the terms of the
+ * GNU General Public License, incorporated herein by reference.
+ *
+ * this program is login shell for dedicated mercurial user account. it
+ * only allows few actions:
+ *
+ * 1. run hg in server mode on specific repository. no other hg commands
+ * are allowed. we try to verify that repo to be accessed exists under
+ * given top-level directory.
+ *
+ * 2. (optional) forward ssh connection from firewall/gateway machine to
+ * "real" mercurial host, to let users outside intranet pull and push
+ * changes through firewall.
+ *
+ * 3. (optional) run normal shell, to allow to "su" to mercurial user, use
+ * "sudo" to run programs as that user, or run cron jobs as that user.
+ *
+ * only tested on linux yet. patches for non-linux systems welcome.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* for asprintf */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+/*
+ * user config.
+ *
+ * if you see a hostname below, just use first part of hostname. example,
+ * if you have host named foo.bar.com, use "foo".
+ */
+
+/*
+ * HG_GATEWAY: hostname of gateway/firewall machine that people outside your
+ * intranet ssh into if they need to ssh to other machines. if you do not
+ * have such machine, set to NULL.
+ */
+#ifndef HG_GATEWAY
+#define HG_GATEWAY "gateway"
+#endif
+
+/*
+ * HG_HOST: hostname of mercurial server. if any machine is allowed, set to
+ * NULL.
+ */
+#ifndef HG_HOST
+#define HG_HOST "mercurial"
+#endif
+
+/*
+ * HG_USER: username to log in from HG_GATEWAY to HG_HOST. if gateway and
+ * host username are same, set to NULL.
+ */
+#ifndef HG_USER
+#define HG_USER "hg"
+#endif
+
+/*
+ * HG_ROOT: root of tree full of mercurial repos. if you do not want to
+ * validate location of repo when someone is try to access, set to NULL.
+ */
+#ifndef HG_ROOT
+#define HG_ROOT "/home/hg/repos"
+#endif
+
+/*
+ * HG: path to the mercurial executable to run.
+ */
+#ifndef HG
+#define HG "/home/hg/bin/hg"
+#endif
+
+/*
+ * HG_SHELL: shell to use for actions like "sudo" and "su" access to
+ * mercurial user, and cron jobs. if you want to make these things
+ * impossible, set to NULL.
+ */
+#ifndef HG_SHELL
+#define HG_SHELL NULL
+// #define HG_SHELL "/bin/bash"
+#endif
+
+/*
+ * HG_HELP: some way for users to get support if they have problem. if they
+ * should not get helpful message, set to NULL.
+ */
+#ifndef HG_HELP
+#define HG_HELP "please contact support@example.com for help."
+#endif
+
+/*
+ * SSH: path to ssh executable to run, if forwarding from HG_GATEWAY to
+ * HG_HOST. if you want to use rsh instead (why?), you need to modify
+ * arguments it is called with. see forward_through_gateway.
+ */
+#ifndef SSH
+#define SSH "/usr/bin/ssh"
+#endif
+
+/*
+ * tell whether to print command that is to be executed. useful for
+ * debugging. should not interfere with mercurial operation, since
+ * mercurial only cares about stdin and stdout, and this prints to stderr.
+ */
+static const int debug = 0;
+
+static void print_cmdline(int argc, char **argv)
+{
+ FILE *fp = stderr;
+ int i;
+
+ fputs("command: ", fp);
+
+ for (i = 0; i < argc; i++) {
+ char *spc = strpbrk(argv[i], " \t\r\n");
+ if (spc) {
+ fputc('\'', fp);
+ }
+ fputs(argv[i], fp);
+ if (spc) {
+ fputc('\'', fp);
+ }
+ if (i < argc - 1) {
+ fputc(' ', fp);
+ }
+ }
+ fputc('\n', fp);
+ fflush(fp);
+}
+
+static void usage(const char *reason, int exitcode)
+{
+ char *hg_help = HG_HELP;
+
+ if (reason) {
+ fprintf(stderr, "*** Error: %s.\n", reason);
+ }
+ fprintf(stderr, "*** This program has been invoked incorrectly.\n");
+ if (hg_help) {
+ fprintf(stderr, "*** %s\n", hg_help);
+ }
+ exit(exitcode ? exitcode : EX_USAGE);
+}
+
+/*
+ * run on gateway host to make another ssh connection, to "real" mercurial
+ * server. it sends its command line unmodified to far end.
+ *
+ * never called if HG_GATEWAY is NULL.
+ */
+static void forward_through_gateway(int argc, char **argv)
+{
+ char *ssh = SSH;
+ char *hg_host = HG_HOST;
+ char *hg_user = HG_USER;
+ char **nargv = alloca((10 + argc) * sizeof(char *));
+ int i = 0, j;
+
+ nargv[i++] = ssh;
+ nargv[i++] = "-q";
+ nargv[i++] = "-T";
+ nargv[i++] = "-x";
+ if (hg_user) {
+ nargv[i++] = "-l";
+ nargv[i++] = hg_user;
+ }
+ nargv[i++] = hg_host;
+
+ /*
+ * sshd called us with added "-c", because it thinks we are a shell.
+ * drop it if we find it.
+ */
+ j = 1;
+ if (j < argc && strcmp(argv[j], "-c") == 0) {
+ j++;
+ }
+
+ for (; j < argc; i++, j++) {
+ nargv[i] = argv[j];
+ }
+ nargv[i] = NULL;
+
+ if (debug) {
+ print_cmdline(i, nargv);
+ }
+
+ execv(ssh, nargv);
+ perror(ssh);
+ exit(EX_UNAVAILABLE);
+}
+
+/*
+ * run shell. let administrator "su" to mercurial user's account to do
+ * administrative works.
+ *
+ * never called if HG_SHELL is NULL.
+ */
+static void run_shell(int argc, char **argv)
+{
+ char *hg_shell = HG_SHELL;
+ char **nargv;
+ char *c;
+ int i;
+
+ nargv = alloca((argc + 3) * sizeof(char *));
+ c = strrchr(hg_shell, '/');
+
+ /* tell "real" shell it is login shell, if needed. */
+
+ if (argv[0][0] == '-' && c) {
+ nargv[0] = strdup(c);
+ if (nargv[0] == NULL) {
+ perror("malloc");
+ exit(EX_OSERR);
+ }
+ nargv[0][0] = '-';
+ } else {
+ nargv[0] = hg_shell;
+ }
+
+ for (i = 1; i < argc; i++) {
+ nargv[i] = argv[i];
+ }
+ nargv[i] = NULL;
+
+ if (debug) {
+ print_cmdline(i, nargv);
+ }
+
+ execv(hg_shell, nargv);
+ perror(hg_shell);
+ exit(EX_OSFILE);
+}
+
+enum cmdline {
+ hg_init,
+ hg_serve,
+};
+
+
+/*
+ * attempt to verify that a directory is really a hg repo, by testing
+ * for the existence of a subdirectory.
+ */
+static int validate_repo(const char *repo_root, const char *subdir)
+{
+ char *abs_path;
+ struct stat st;
+ int ret;
+
+ if (asprintf(&abs_path, "%s.hg/%s", repo_root, subdir) == -1) {
+ ret = -1;
+ goto bail;
+ }
+
+ /* verify that we really are looking at valid repo. */
+
+ if (stat(abs_path, &st) == -1) {
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+
+bail:
+ return ret;
+}
+
+/*
+ * paranoid wrapper, runs hg executable in server mode.
+ */
+static void serve_data(int argc, char **argv)
+{
+ char *hg_root = HG_ROOT;
+ char *repo, *repo_root;
+ enum cmdline cmd;
+ char *nargv[6];
+ size_t repolen;
+ int i;
+
+ /*
+ * check argv for looking okay. we should be invoked with argv
+ * resembling like this:
+ *
+ * hgsh
+ * -c
+ * hg -R some/path serve --stdio
+ *
+ * the "-c" is added by sshd, because it thinks we are login shell.
+ */
+
+ if (argc != 3) {
+ goto badargs;
+ }
+
+ if (strcmp(argv[1], "-c") != 0) {
+ goto badargs;
+ }
+
+ if (sscanf(argv[2], "hg init %as", &repo) == 1) {
+ cmd = hg_init;
+ }
+ else if (sscanf(argv[2], "hg -R %as serve --stdio", &repo) == 1) {
+ cmd = hg_serve;
+ } else {
+ goto badargs;
+ }
+
+ repolen = repo ? strlen(repo) : 0;
+
+ if (repolen == 0) {
+ goto badargs;
+ }
+
+ if (hg_root) {
+ if (asprintf(&repo_root, "%s/%s/", hg_root, repo) == -1) {
+ goto badargs;
+ }
+
+ /*
+ * attempt to stop break out from inside the repository tree. could
+ * do something more clever here, because e.g. we could traverse a
+ * symlink that looks safe, but really breaks us out of tree.
+ */
+
+ if (strstr(repo_root, "/../") != NULL) {
+ goto badargs;
+ }
+
+ /* only hg init expects no repo. */
+
+ if (cmd != hg_init) {
+ int valid;
+
+ valid = validate_repo(repo_root, "data");
+
+ if (valid == -1) {
+ goto badargs;
+ }
+
+ if (valid == 0) {
+ valid = validate_repo(repo_root, "store");
+
+ if (valid == -1) {
+ goto badargs;
+ }
+ }
+
+ if (valid == 0) {
+ perror(repo);
+ exit(EX_DATAERR);
+ }
+ }
+
+ if (chdir(hg_root) == -1) {
+ perror(hg_root);
+ exit(EX_SOFTWARE);
+ }
+ }
+
+ i = 0;
+
+ switch (cmd) {
+ case hg_serve:
+ nargv[i++] = HG;
+ nargv[i++] = "-R";
+ nargv[i++] = repo;
+ nargv[i++] = "serve";
+ nargv[i++] = "--stdio";
+ break;
+ case hg_init:
+ nargv[i++] = HG;
+ nargv[i++] = "init";
+ nargv[i++] = repo;
+ break;
+ }
+
+ nargv[i] = NULL;
+
+ if (debug) {
+ print_cmdline(i, nargv);
+ }
+
+ execv(HG, nargv);
+ perror(HG);
+ exit(EX_UNAVAILABLE);
+
+badargs:
+ /* print useless error message. */
+
+ usage("invalid arguments", EX_DATAERR);
+}
+
+int main(int argc, char **argv)
+{
+ char host[1024];
+ char *c;
+
+ if (gethostname(host, sizeof(host)) == -1) {
+ perror("gethostname");
+ exit(EX_OSERR);
+ }
+
+ if ((c = strchr(host, '.')) != NULL) {
+ *c = '\0';
+ }
+
+ if (getenv("SSH_CLIENT")) {
+ char *hg_gateway = HG_GATEWAY;
+ char *hg_host = HG_HOST;
+
+ if (hg_gateway && strcmp(host, hg_gateway) == 0) {
+ forward_through_gateway(argc, argv);
+ }
+
+ if (hg_host && strcmp(host, hg_host) != 0) {
+ usage("invoked on unexpected host", EX_USAGE);
+ }
+
+ serve_data(argc, argv);
+ } else if (HG_SHELL) {
+ run_shell(argc, argv);
+ } else {
+ usage("invalid arguments", EX_DATAERR);
+ }
+
+ return 0;
+}
diff --git a/sys/src/cmd/hg/contrib/hgwebdir.fcgi b/sys/src/cmd/hg/contrib/hgwebdir.fcgi
new file mode 100644
index 000000000..e014b98cb
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/hgwebdir.fcgi
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+#
+# An example CGI script to export multiple hgweb repos, edit as necessary
+
+# adjust python path if not a system-wide install:
+#import sys
+#sys.path.insert(0, "/path/to/python/lib")
+
+# enable demandloading to reduce startup time
+from mercurial import demandimport; demandimport.enable()
+
+# Uncomment to send python tracebacks to the browser if an error occurs:
+#import cgitb
+#cgitb.enable()
+
+# If you'd like to serve pages with UTF-8 instead of your default
+# locale charset, you can do so by uncommenting the following lines.
+# Note that this will cause your .hgrc files to be interpreted in
+# UTF-8 and all your repo files to be displayed using UTF-8.
+#
+#import os
+#os.environ["HGENCODING"] = "UTF-8"
+
+from mercurial.hgweb.hgwebdir_mod import hgwebdir
+from flup.server.fcgi import WSGIServer
+
+# The config file looks like this. You can have paths to individual
+# repos, collections of repos in a directory tree, or both.
+#
+# [paths]
+# virtual/path1 = /real/path1
+# virtual/path2 = /real/path2
+# virtual/root = /real/root/*
+# / = /real/root2/*
+#
+# [collections]
+# /prefix/to/strip/off = /root/of/tree/full/of/repos
+#
+# paths example:
+#
+# * First two lines mount one repository into one virtual path, like
+# '/real/path1' into 'virtual/path1'.
+#
+# * The third entry tells every mercurial repository found in
+# '/real/root', recursively, should be mounted in 'virtual/root'. This
+# format is preferred over the [collections] one, using absolute paths
+# as configuration keys is not supported on every platform (including
+# Windows).
+#
+# * The last entry is a special case mounting all repositories in
+# '/real/root2' in the root of the virtual directory.
+#
+# collections example: say directory tree /foo contains repos /foo/bar,
+# /foo/quux/baz. Give this config section:
+# [collections]
+# /foo = /foo
+# Then repos will list as bar and quux/baz.
+#
+# Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
+# or use a dictionary with entries like 'virtual/path': '/real/path'
+
+WSGIServer(hgwebdir('hgweb.config')).run()
diff --git a/sys/src/cmd/hg/contrib/hgwebdir.wsgi b/sys/src/cmd/hg/contrib/hgwebdir.wsgi
new file mode 100644
index 000000000..64e09b2de
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/hgwebdir.wsgi
@@ -0,0 +1,51 @@
+# An example WSGI (use with mod_wsgi) script to export multiple hgweb repos
+
+# adjust python path if not a system-wide install:
+#import sys
+#sys.path.insert(0, "/path/to/python/lib")
+
+# enable demandloading to reduce startup time
+from mercurial import demandimport; demandimport.enable()
+from mercurial.hgweb.hgwebdir_mod import hgwebdir
+
+# If you'd like to serve pages with UTF-8 instead of your default
+# locale charset, you can do so by uncommenting the following lines.
+# Note that this will cause your .hgrc files to be interpreted in
+# UTF-8 and all your repo files to be displayed using UTF-8.
+#
+#import os
+#os.environ["HGENCODING"] = "UTF-8"
+
+# The config file looks like this. You can have paths to individual
+# repos, collections of repos in a directory tree, or both.
+#
+# [paths]
+# virtual/path1 = /real/path1
+# virtual/path2 = /real/path2
+# virtual/root = /real/root/*
+# / = /real/root2/*
+#
+# paths example:
+#
+# * First two lines mount one repository into one virtual path, like
+# '/real/path1' into 'virtual/path1'.
+#
+# * The third entry tells every mercurial repository found in
+# '/real/root', recursively, should be mounted in 'virtual/root'. This
+# format is preferred over the [collections] one, using absolute paths
+# as configuration keys is not supported on every platform (including
+# Windows).
+#
+# * The last entry is a special case mounting all repositories in
+# '/real/root2' in the root of the virtual directory.
+#
+# collections example: say directory tree /foo contains repos /foo/bar,
+# /foo/quux/baz. Give this config section:
+# [collections]
+# /foo = /foo
+# Then repos will list as bar and quux/baz.
+#
+# Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
+# or use a dictionary with entries like 'virtual/path': '/real/path'
+
+application = hgwebdir('hgweb.config')
diff --git a/sys/src/cmd/hg/contrib/logo-droplets.svg b/sys/src/cmd/hg/contrib/logo-droplets.svg
new file mode 100644
index 000000000..01f412b36
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/logo-droplets.svg
@@ -0,0 +1,624 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="100"
+ height="120"
+ viewBox="0 0 124.766 152.099"
+ id="Layer_1"
+ xml:space="preserve"
+ sodipodi:version="0.32"
+ inkscape:version="0.45.1"
+ sodipodi:docname="logo-droplets.svg"
+ sodipodi:docbase="/home/oxymoron/waste/selenic/public_html/hg-logo"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
+ id="metadata6845"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title>Mercurial &quot;droplets&quot; logo</dc:title><dc:creator><cc:Agent><dc:title>Cali Mastny and Matt Mackall</dc:title></cc:Agent></dc:creator><cc:license
+ rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /><dc:date>Feb 12 2008</dc:date></cc:Work><cc:License
+ rdf:about="http://creativecommons.org/licenses/GPL/2.0/"><cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" /><cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" /><cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" /><cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" /><cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" /><cc:requires
+ rdf:resource="http://web.resource.org/cc/SourceCode" /></cc:License></rdf:RDF></metadata><sodipodi:namedview
+ inkscape:window-height="576"
+ inkscape:window-width="746"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ inkscape:zoom="2.3216673"
+ inkscape:cx="4.1210694"
+ inkscape:cy="65.759396"
+ inkscape:window-x="377"
+ inkscape:window-y="398"
+ inkscape:current-layer="Layer_1"
+ width="100px"
+ height="120px"
+ units="px" /><defs
+ id="defs261" />
+<pattern
+ overflow="visible"
+ viewBox="2.125 -70.896 69 69"
+ id="Polka_Dot_Pattern"
+ patternUnits="userSpaceOnUse"
+ height="69"
+ width="69"
+ y="736.415"
+ x="-316">
+ <g
+ id="g4">
+ <polygon
+ id="polygon6"
+ points="71.125,-1.896 2.125,-1.896 2.125,-70.896 71.125,-70.896 "
+ fill="none" />
+ <polygon
+ id="polygon8"
+ points="71.125,-1.896 2.125,-1.896 2.125,-70.896 71.125,-70.896 "
+ fill="#F7BC60" />
+ <g
+ id="g10">
+ <path
+ id="path12"
+ d="M61.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path14"
+ d="M54.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path16"
+ d="M46.439-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path18"
+ d="M38.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path20"
+ d="M31.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path22"
+ d="M23.439-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path24"
+ d="M15.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path26"
+ d="M8.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path28"
+ d="M0.439-71.653c0.018,0.072,0.008,0.127-0.026,0.19C0.361-71.362,0.3-71.4,0.248-71.335 c-0.051,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ <g
+ id="g30">
+ <path
+ id="path32"
+ d="M69.439-71.653c0.018,0.072,0.008,0.127-0.026,0.19c-0.052,0.101-0.113,0.062-0.165,0.128 c-0.051,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ <path
+ id="path34"
+ d="M0.495-71.653c0.018,0.072,0.008,0.127-0.026,0.19c-0.052,0.101-0.113,0.062-0.165,0.128 c-0.051,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224C0.5-71.68,0.503-71.744,0.51-71.626 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <g
+ id="g36">
+ <g
+ id="g38">
+ <path
+ id="path40"
+ d="M69.439-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path42"
+ d="M61.778-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path44"
+ d="M54.118-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path46"
+ d="M46.458-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path48"
+ d="M38.797-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path50"
+ d="M31.137-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path52"
+ d="M23.477-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path54"
+ d="M15.816-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path56"
+ d="M8.156-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path58"
+ d="M0.495-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143C2-61.45,2.217-61.397,2.391-61.46c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ <g
+ id="g60">
+ <path
+ id="path62"
+ d="M69.439-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path64"
+ d="M61.778-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path66"
+ d="M54.118-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path68"
+ d="M46.458-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path70"
+ d="M38.797-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path72"
+ d="M31.137-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path74"
+ d="M23.477-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path76"
+ d="M15.816-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path78"
+ d="M8.156-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path80"
+ d="M0.495-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-56.374,0.503-56.438,0.51-56.32 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ <g
+ id="g82">
+ <path
+ id="path84"
+ d="M69.439-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path86"
+ d="M61.778-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path88"
+ d="M54.118-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path90"
+ d="M46.458-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path92"
+ d="M38.797-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path94"
+ d="M31.137-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path96"
+ d="M23.477-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path98"
+ d="M15.816-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path100"
+ d="M8.156-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path102"
+ d="M0.495-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ <g
+ id="g104">
+ <path
+ id="path106"
+ d="M69.439-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path108"
+ d="M61.778-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path110"
+ d="M54.118-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path112"
+ d="M46.458-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path114"
+ d="M38.797-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path116"
+ d="M31.137-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path118"
+ d="M23.477-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path120"
+ d="M15.816-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path122"
+ d="M8.156-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 C8.15-41.004,8.149-41.02,8.14-41.04"
+ fill="#FFFFFF" />
+ <path
+ id="path124"
+ d="M0.495-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ <g
+ id="g126">
+ <path
+ id="path128"
+ d="M69.439-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path130"
+ d="M61.778-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path132"
+ d="M54.118-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path134"
+ d="M46.458-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path136"
+ d="M38.797-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path138"
+ d="M31.137-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path140"
+ d="M23.477-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path142"
+ d="M15.816-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path144"
+ d="M8.156-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path146"
+ d="M0.495-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-33.416,0.503-33.48,0.51-33.362 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ <g
+ id="g148">
+ <path
+ id="path150"
+ d="M69.439-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path152"
+ d="M61.778-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path154"
+ d="M54.118-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path156"
+ d="M46.458-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path158"
+ d="M38.797-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path160"
+ d="M31.137-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path162"
+ d="M23.477-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path164"
+ d="M15.816-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path166"
+ d="M8.156-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path168"
+ d="M0.495-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ <g
+ id="g170">
+ <path
+ id="path172"
+ d="M69.439-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path174"
+ d="M61.778-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path176"
+ d="M54.118-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path178"
+ d="M46.458-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path180"
+ d="M38.797-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path182"
+ d="M31.137-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path184"
+ d="M23.477-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path186"
+ d="M15.816-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path188"
+ d="M8.156-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path190"
+ d="M0.495-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-18.11,0.503-18.175,0.51-18.057 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ <g
+ id="g192">
+ <path
+ id="path194"
+ d="M69.439-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362C69-9.692,69.159-9.523,69.154-9.4c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path196"
+ d="M61.778-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path198"
+ d="M54.118-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path200"
+ d="M46.458-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path202"
+ d="M38.797-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path204"
+ d="M31.137-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path206"
+ d="M23.477-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path208"
+ d="M15.816-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053C17.933-7.969,17.839-8.227,18-8.34 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path210"
+ d="M8.156-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 C7.915-10.05,7.866-9.836,7.886-9.75C7.717-9.692,7.876-9.523,7.871-9.4C7.868-9.351,7.83-9.295,7.826-9.239 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C9.114-7.652,9.321-7.799,9.48-7.837c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path212"
+ d="M0.495-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 C0.254-10.05,0.205-9.836,0.225-9.75C0.056-9.692,0.215-9.523,0.21-9.4c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37C0.33-8.671,0.501-8.456,0.668-8.325c0.19,0.148,0.365,0.572,0.608,0.631 C1.454-7.652,1.66-7.799,1.819-7.837C2-7.88,2.217-7.827,2.391-7.89c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46C3.477-8.933,3.471-8.995,3.5-9.071 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ </g>
+ </g>
+ <g
+ id="g214">
+ <path
+ id="path216"
+ d="M69.439-2.778c0.018,0.072,0.008,0.127-0.026,0.19C69.361-2.487,69.3-2.525,69.248-2.46 c-0.051,0.062-0.099,0.276-0.079,0.362C69-2.04,69.159-1.871,69.154-1.748c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C70.397,0,70.604-0.146,70.763-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path218"
+ d="M61.778-2.778c0.018,0.072,0.007,0.127-0.026,0.19C61.7-2.487,61.64-2.525,61.587-2.46 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C62.737,0,62.943-0.146,63.103-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C61.915-3.117,61.78-3.02,61.781-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path220"
+ d="M54.118-2.778c0.018,0.072,0.007,0.127-0.026,0.19C54.04-2.487,53.98-2.525,53.927-2.46 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C55.077,0,55.283-0.146,55.442-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C54.255-3.117,54.12-3.02,54.121-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path222"
+ d="M46.458-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C47.416,0,47.623-0.146,47.782-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C46.594-3.117,46.459-3.02,46.46-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path224"
+ d="M38.797-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C39.756,0,39.962-0.146,40.122-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C38.934-3.117,38.799-3.02,38.8-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path226"
+ d="M31.137-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C32.095,0,32.302-0.146,32.461-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224C31.273-3.117,31.139-3.02,31.14-2.92c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path228"
+ d="M23.477-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C24.435,0,24.642-0.146,24.801-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 c-0.021,0.011-0.021-0.005-0.03-0.025"
+ fill="#FFFFFF" />
+ <path
+ id="path230"
+ d="M15.816-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C16.774,0,16.981-0.146,17.14-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207 c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169 C15.81-2.74,15.809-2.756,15.8-2.776"
+ fill="#FFFFFF" />
+ <path
+ id="path232"
+ d="M8.156-2.778c0.018,0.072,0.007,0.127-0.026,0.19C8.077-2.487,8.018-2.525,7.965-2.46 c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35C7.868-1.698,7.83-1.643,7.826-1.587 c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631 C9.114,0,9.321-0.146,9.48-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221 c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789C8.954-3.54,8.847-3.448,8.692-3.367 c-0.17,0.088-0.139,0.166-0.318,0.224C8.292-3.117,8.158-3.02,8.159-2.92C8.16-2.805,8.164-2.869,8.17-2.751 C8.15-2.74,8.149-2.756,8.14-2.776"
+ fill="#FFFFFF" />
+ <path
+ id="path234"
+ d="M0.495-2.778c0.018,0.072,0.008,0.127-0.026,0.19C0.417-2.487,0.356-2.525,0.304-2.46 C0.253-2.397,0.205-2.184,0.225-2.098C0.056-2.04,0.215-1.871,0.21-1.748c-0.002,0.05-0.041,0.105-0.045,0.161 c-0.01,0.119,0.017,0.266,0.068,0.37C0.33-1.019,0.501-0.804,0.668-0.673c0.19,0.148,0.365,0.572,0.608,0.631 C1.454,0,1.66-0.146,1.819-0.185C2-0.228,2.217-0.175,2.391-0.237c0.222-0.079,0.127-0.337,0.288-0.45 c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46C3.477-1.28,3.471-1.343,3.5-1.419 c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337 c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789C1.293-3.54,1.187-3.448,1.031-3.367 c-0.17,0.088-0.139,0.166-0.318,0.224C0.632-3.117,0.498-3.02,0.498-2.92C0.5-2.805,0.503-2.869,0.51-2.751 C0.489-2.74,0.488-2.756,0.479-2.776"
+ fill="#FFFFFF" />
+ </g>
+ </g>
+</pattern>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.97552931;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect6847"
+ width="124.77364"
+ height="150.12347"
+ x="0.31690097"
+ y="0.98776293" /><path
+ d="M 9.8480335,124.60683 C 11.62496,123.82337 13.513211,123.43203 15.327243,123.43203 C 17.067063,123.43203 18.177759,123.85879 18.806894,124.74937 C 20.139374,123.8596 21.953416,123.43203 23.360116,123.43203 C 27.581053,123.43203 27.728648,125.14068 27.728648,130.16028 L 27.728648,141.26547 C 27.728648,141.76382 27.802857,141.76382 25.692811,141.76382 L 25.692811,129.94606 C 25.692811,126.31544 25.618592,125.21154 23.213365,125.21154 C 22.139794,125.21154 21.029108,125.4603 19.844204,126.24379 L 19.844204,141.5142 C 19.807099,141.65677 19.732887,141.69215 19.474821,141.72758 C 19.436863,141.72758 19.400602,141.763 19.362653,141.763 L 17.807522,141.763 L 17.807522,129.94606 C 17.807522,126.45791 17.807522,125.17607 15.29098,125.17607 C 14.2174,125.17607 13.143818,125.38944 11.884705,125.99501 L 11.884705,141.26547 C 11.884705,141.76382 11.958925,141.76382 9.8488776,141.76382 L 9.8488776,124.60683 M 37.680118,123.43203 C 34.533596,123.43203 31.053954,124.32176 31.053954,133.8263 C 31.053954,141.15915 33.607611,142.29771 37.125192,142.29771 C 39.826435,142.29771 42.159131,141.40799 42.159131,140.98039 C 42.159131,140.44659 42.084921,139.62768 41.900221,139.16468 C 40.75243,139.94814 39.123081,140.37486 37.309893,140.37486 C 34.829612,140.37486 33.164001,139.66309 33.126052,134.14592 C 34.755402,134.14592 38.902128,134.11044 41.97444,133.50498 C 42.233351,132.33022 42.343821,130.62155 42.343821,129.12711 C 42.343821,125.56743 40.900016,123.43203 37.680118,123.43203 M 37.494584,125.21154 C 39.715955,125.21154 40.307995,126.67048 40.3451,129.51849 C 40.3451,130.26565 40.307995,131.15541 40.19667,132.00972 C 38.123729,132.50815 34.60612,132.50815 33.125209,132.50815 C 33.385806,126.0304 35.606333,125.21154 37.494584,125.21154 M 45.565397,124.99816 C 47.304384,123.85879 48.897464,123.43203 50.525969,123.43203 C 52.34,123.43203 53.191776,123.93046 53.191776,124.53602 C 53.191776,124.89187 53.079617,125.49742 52.894917,125.85331 C 52.376261,125.56823 51.785075,125.31945 50.821131,125.31945 C 49.637079,125.31945 48.526385,125.63909 47.638339,126.42255 L 47.638339,141.26632 C 47.638339,141.7647 47.675453,141.7647 45.565397,141.7647 L 45.565397,124.99816 M 64.254794,124.60683 C 64.254794,124.14383 62.700508,123.43203 61.145377,123.43203 C 58.145598,123.43203 54.481256,124.4643 54.481256,133.25617 C 54.481256,141.58507 56.70347,142.3331 60.589608,142.3331 C 62.514121,142.3331 64.254794,141.30089 64.254794,140.73161 C 64.254794,140.4111 64.181418,139.91269 63.99504,139.48515 C 63.217475,140.05441 62.033423,140.58905 60.775152,140.58905 C 58.11018,140.58905 56.55504,139.84185 56.55504,133.3633 C 56.55504,126.20837 59.108698,125.21154 61.330069,125.21154 C 62.58834,125.21154 63.291694,125.56743 63.99504,126.0304 C 64.181418,125.60367 64.254794,124.99816 64.254794,124.60683 M 78.435657,141.15915 C 76.806308,141.97803 74.659991,142.29851 72.808845,142.29851 C 68.070088,142.29851 67.366733,140.30571 67.366733,135.57114 L 67.366733,124.42971 C 67.366733,123.96757 67.330471,123.96757 69.440527,123.96757 L 69.440527,135.7854 C 69.440527,139.34513 69.958338,140.55538 72.734626,140.55538 C 73.808215,140.55538 75.289126,140.34199 76.399811,139.70105 L 76.399811,124.43056 C 76.399811,123.96839 76.325602,123.96839 78.435657,123.96839 L 78.435657,141.15915 M 82.657438,124.99816 C 84.396406,123.85879 85.98865,123.43203 87.617156,123.43203 C 89.431178,123.43203 90.282962,123.93046 90.282962,124.53602 C 90.282962,124.89187 90.171639,125.49742 89.986938,125.85331 C 89.468283,125.56823 88.876272,125.31945 87.913163,125.31945 C 86.729111,125.31945 85.618415,125.63909 84.729535,126.42255 L 84.729535,141.26632 C 84.729535,141.7647 84.767484,141.7647 82.657438,141.7647 L 82.657438,124.99816 M 95.036045,123.9659 C 93.406714,123.9659 92.926008,123.9659 92.926008,124.92729 L 92.926008,141.76382 C 94.99895,141.76382 95.036045,141.76382 95.036045,141.26547 L 95.036045,123.9659 M 92.851787,117.70149 C 92.851787,118.87629 93.222023,119.30304 93.961631,119.33843 C 94.813415,119.33843 95.220746,118.73376 95.220746,117.66526 C 95.257851,116.56214 94.960991,116.06374 94.11006,116.06374 C 93.296243,116.06374 92.888893,116.66926 92.851787,117.70149 M 98.547748,124.99816 C 98.547748,124.60683 98.62196,124.39264 98.770389,124.28635 C 99.473743,123.89502 102.17666,123.43203 105.24898,123.43203 C 107.58166,123.43203 109.06174,124.53602 109.06174,127.73899 L 109.06174,130.05231 C 109.06174,136.38835 108.87704,141.12293 108.87704,141.12293 C 108.02528,141.58507 106.43387,142.29771 103.84143,142.29771 C 101.17646,142.3331 98.511478,142.0843 98.511478,136.81596 C 98.511478,131.7972 101.25067,131.01375 103.98986,131.01375 C 105.02633,131.01375 106.24834,131.12082 107.06301,131.4413 C 107.06301,131.4413 107.06301,129.12711 107.06301,128.13033 C 107.06301,125.81704 105.87895,125.31862 104.47141,125.31862 C 102.58399,125.31862 99.956127,125.67451 98.808337,126.20837 C 98.585707,125.81704 98.547748,125.21154 98.547748,124.99816 M 107.06216,132.9011 C 106.35882,132.65147 105.35945,132.54522 104.65609,132.54522 C 102.54604,132.54522 100.62069,132.97198 100.62069,136.88763 C 100.62069,140.55363 102.21293,140.58991 104.10032,140.58991 C 105.28522,140.58991 106.47014,140.26946 106.87663,139.84271 C 106.87747,139.84185 107.06216,135.57029 107.06216,132.9011 M 114.91792,141.26547 C 114.91792,141.76382 114.95503,141.76382 112.88124,141.76382 L 112.88124,116.56214 C 112.88124,115.60073 113.28857,115.60073 114.91792,115.60073 L 114.91792,141.26547"
+ style="fill:#010101;stroke-width:2.02999997;stroke-miterlimit:4;stroke-dasharray:none"
+ id="text2611" /><g
+ transform="matrix(0.9351326,0,0,0.9351326,150.39508,-1.251766)"
+ id="g4503"
+ style="opacity:1"><path
+ d="M -45.749655,92.691592 C -25.709638,59.370739 -49.98206,5.3291313 -94.363693,10.819389 C -134.46337,15.776665 -135.10949,57.983708 -99.76917,68.010455 C -69.186498,76.695132 -93.451029,96.093536 -92.742037,109.01138 C -92.030055,121.92728 -66.155038,126.61324 -45.749655,92.691592 z "
+ style="fill:#1b1a1b"
+ id="path2339" /><circle
+ cx="33.728001"
+ cy="85.363998"
+ r="15.414"
+ transform="matrix(1.0917947,-0.2858168,0.2858168,1.0917947,-180.30817,13.494135)"
+ style="fill:#1b1a1b"
+ id="circle2341"
+ sodipodi:cx="33.728001"
+ sodipodi:cy="85.363998"
+ sodipodi:rx="15.414"
+ sodipodi:ry="15.414" /><path
+ d="M -140.06215,48.935849 C -146.31997,49.541603 -150.90082,55.100456 -150.29507,61.358275 C -149.68817,67.620461 -144.12955,72.20487 -137.87064,71.59883 C -131.61373,70.985148 -127.02904,65.427621 -127.63726,59.169282 C -128.24543,52.915596 -133.80324,48.329809 -140.06215,48.935849 z "
+ style="fill:#1b1a1b"
+ id="path2343" /><path
+ d="M -44.99294,91.339709 C -24.951831,58.018571 -49.224253,3.976963 -93.605885,9.4672202 C -133.70556,14.424496 -134.35249,56.632918 -99.012168,66.659664 C -68.429497,75.344341 -92.694028,94.742745 -91.984749,107.66168 C -91.271961,120.5762 -65.398322,125.26135 -44.99294,91.339709 z "
+ style="fill:#bfbfbf"
+ id="path2561" /><path
+ d="M -86.84228,112.75985 C -88.056751,110.79004 -86.19955,108.60176 -84.290569,108.76815 C -81.251858,109.03428 -74.635637,108.73252 -69.415044,105.77341 C -56.372412,98.379694 -36.300952,62.803704 -46.395841,40.365295 C -50.915249,30.320886 -53.115898,27.444964 -57.770162,22.531645 C -58.719625,21.529587 -58.174556,21.584053 -57.531623,21.923221 C -55.014762,23.244092 -50.592026,28.36035 -46.055478,36.687677 C -38.390628,50.757116 -38.788117,67.483141 -41.638835,77.975343 C -43.624548,85.27439 -50.464117,101.78644 -60.480639,108.92577 C -70.5197,116.0815 -82.266433,120.18559 -86.84228,112.75985 z "
+ style="fill:#000000"
+ id="path2563" /><path
+ d="M -95.930347,66.591355 C -102.76341,64.562985 -111.57238,61.738267 -116.66758,55.073789 C -120.42371,50.15984 -122.3305,44.796759 -122.81745,41.755703 C -122.99069,40.670602 -123.13785,39.765332 -122.82526,39.515509 C -122.68064,39.399486 -120.02045,45.412302 -116.04367,50.451645 C -112.06769,55.492366 -106.51047,58.440379 -101.88092,59.511496 C -97.763206,60.46345 -89.233623,62.555175 -86.347769,65.013729 C -83.380949,67.540918 -83.133309,73.00119 -84.131664,73.617197 C -85.138469,74.236583 -87.180025,69.187603 -95.930347,66.591355 z "
+ style="fill:#000000"
+ id="path2565" /><path
+ d="M -81.840812,113.72311 C -81.972699,115.28707 -80.176315,115.59377 -77.75828,115.23141 C -74.658947,114.76654 -72.037923,114.41754 -68.470623,112.62971 C -63.63582,110.20674 -58.742752,106.74072 -55.159223,102.06476 C -44.467444,88.115271 -40.681354,71.610444 -41.264404,69.236185 C -41.459242,71.196944 -44.040349,81.489071 -49.943268,90.767882 C -57.52457,102.68631 -63.022197,109.03464 -75.701416,112.1124 C -79.230011,112.96964 -81.668137,111.66432 -81.840812,113.72311 z "
+ style="fill:#ffffff"
+ id="path2567" /><path
+ d="M -109.96233,59.479354 C -108.51822,60.704238 -105.55938,62.336389 -99.737455,64.245644 C -92.705873,66.551032 -89.282274,68.550326 -87.848506,69.508429 C -86.329222,70.525809 -85.366279,72.795951 -85.27115,70.779631 C -85.17194,68.761076 -86.416123,67.025373 -89.192166,66.104839 C -91.070345,65.481234 -94.229847,63.996111 -97.258539,63.398373 C -99.204694,63.014221 -102.37098,62.251845 -105.08636,61.420426 C -106.57454,60.963046 -108.09089,60.161888 -109.96233,59.479354 z "
+ style="fill:#ffffff"
+ id="path2569" /><circle
+ cx="34.681"
+ cy="84.375"
+ r="15.414"
+ transform="matrix(1.0917947,-0.2858168,0.2858168,1.0917947,-180.30817,13.494135)"
+ style="fill:#bfbfbf"
+ id="circle2577"
+ sodipodi:cx="34.681"
+ sodipodi:cy="84.375"
+ sodipodi:rx="15.414"
+ sodipodi:ry="15.414" /><path
+ d="M -128.68413,108.37945 C -115.15301,120.91784 -94.786007,103.69471 -103.75445,88.482597 C -104.76154,86.774656 -106.06907,85.474351 -105.63906,86.782721 C -102.77288,95.529828 -105.42141,102.44941 -110.3632,106.01451 C -115.20857,109.5112 -121.86847,110.09622 -127.20028,107.33186 C -128.76601,106.5203 -129.41538,107.70291 -128.68413,108.37945 z "
+ style="fill:#000000"
+ id="path2579" /><path
+ d="M -118.06686,110.95477 C -116.34413,110.59244 -106.32442,107.99742 -103.97055,99.756195 C -103.23743,97.186709 -103.1058,97.702893 -103.31295,99.095232 C -104.37035,106.20143 -111.08741,111.44338 -116.80312,111.63773 C -117.963,111.75704 -119.48484,111.25131 -118.06686,110.95477 z "
+ style="fill:#ffffff"
+ id="path2585" /><path
+ d="M -139.30435,47.583681 C -145.56216,48.189435 -150.14301,53.748288 -149.53726,60.006106 C -148.93065,66.2672 -143.37174,70.852702 -137.11392,70.246948 C -130.85592,69.632979 -126.27151,64.074361 -126.88083,57.816308 C -127.48791,51.562336 -133.04544,46.977641 -139.30435,47.583681 z "
+ style="fill:#bfbfbf"
+ id="path2589" /><path
+ d="M -144.46878,67.571208 C -144.39939,68.375508 -143.29781,69.408789 -141.56718,69.883196 C -140.08038,70.290771 -136.24758,71.332594 -131.32372,68.224839 C -126.39986,65.117084 -125.8321,56.804464 -128.07041,54.35955 C -128.76326,53.121154 -129.66426,52.21957 -128.94737,54.195974 C -127.13695,59.186468 -130.65487,63.854586 -133.68917,66.0162 C -136.72238,68.177528 -140.56932,67.154692 -142.14014,66.675779 C -143.71095,66.196867 -144.53929,66.740369 -144.46878,67.571208 z "
+ style="fill:#000000"
+ id="path2591" /><path
+ d="M -138.11472,68.687851 C -137.66344,68.281557 -135.37889,68.447629 -133.31622,67.338341 C -131.25464,66.229338 -128.80419,63.798254 -128.36692,60.343756 C -128.10933,58.315237 -128.03197,58.824631 -127.92942,59.929403 C -128.24939,65.67243 -133.53086,68.844638 -136.55132,69.263202 C -137.36636,69.376239 -138.8007,69.307247 -138.11472,68.687851 z "
+ style="fill:#ffffff"
+ id="path2597" /><path
+ d="M -47.767489,69.693822 C -39.234739,45.099506 -57.090457,7.9576459 -93.212919,12.425552 C -125.85191,16.461012 -126.37823,50.814524 -97.613495,58.976486 C -65.031338,63.908526 -84.650966,88.487524 -87.434101,100.88229 C -89.929232,111.99304 -61.102889,113.82164 -47.767489,69.693822 z "
+ style="fill:#999999"
+ id="path2561_1_" /><path
+ d="M -70.093288,88.904346 C -78.920045,87.812046 -91.622267,107.74061 -79.645446,105.40671 C -67.670523,103.07448 -91.622267,107.74061 -79.645446,105.40671 C -73.888849,104.55302 -69.119803,102.52058 -64.850547,97.64761 C -59.283982,91.295233 -50.968477,77.5735 -48.563483,68.707586 C -46.537563,61.232354 -47.555881,49.650767 -49.644305,60.532553 C -51.786232,71.700167 -61.266532,89.996647 -70.093288,88.904346 z "
+ style="fill:#f3f3f3"
+ id="path2571" /><path
+ d="M -129.3854,104.84502 C -127.34184,104.87935 -126.10573,105.16706 -124.03635,106.61908 C -119.94568,108.31891 -112.42648,107.24179 -108.9543,102.67081 C -105.48212,98.099823 -105.36811,91.801741 -106.69103,87.996073 C -109.92728,78.682039 -123.67593,78.846722 -129.81795,86.579362 C -136.46216,95.2146 -131.42897,104.81069 -129.3854,104.84502 z "
+ style="fill:#999999"
+ id="path2581" /><path
+ d="M -147.63565,61.683628 C -147.22833,62.966318 -146.18754,64.837882 -143.9897,65.149887 C -141.05481,65.566524 -140.45479,66.892551 -136.9892,66.204631 C -133.52361,65.516711 -130.89674,62.676625 -129.84557,59.535064 C -128.64212,55.188187 -130.44406,52.944024 -133.15599,50.940416 C -135.86791,48.936808 -141.83359,49.152263 -145.3938,52.39768 C -147.92393,54.702631 -148.62733,58.560726 -147.63565,61.683628 z "
+ style="fill:#999999"
+ id="path2593_2_" /><path
+ d="M -136.11009,64.55822 C -133.44721,63.861113 -129.92545,60.232613 -131.67381,57.462279 C -133.83086,54.048798 -139.84051,56.970651 -140.04374,60.77103 C -140.24777,64.572786 -138.93238,65.297057 -136.11009,64.55822 z "
+ style="fill:#f3f3f3"
+ id="path256" /><path
+ d="M -116.11512,105.50904 C -113.8431,104.91425 -106.88259,102.0818 -108.18994,91.962983 C -108.85161,86.83742 -111.64725,98.324328 -116.82409,100.04237 C -124.66721,102.64507 -123.78607,107.51719 -116.11512,105.50904 z "
+ style="fill:#f3f3f3"
+ id="path258" /></g>
+</svg> \ No newline at end of file
diff --git a/sys/src/cmd/hg/contrib/macosx/Readme.html b/sys/src/cmd/hg/contrib/macosx/Readme.html
new file mode 100644
index 000000000..eaeec76b7
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/macosx/Readme.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!-- This is the second screen displayed during the install. -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <title></title>
+ <style type="text/css">
+ p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
+ p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+ p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+ p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #000fed}
+ span.s1 {text-decoration: underline}
+ span.s2 {font: 12.0px Courier}
+ </style>
+</head>
+<body>
+<p class="p1"><b>Before you install</b></p>
+<p class="p2"><br></p>
+<p class="p3">This is an OS X 10.5 version of Mercurial that depends on the default Python 2.5 installation.</p>
+<p class="p2"><br></p>
+<p class="p1"><b>After you install</b></p>
+<p class="p2"><br></p>
+<p class="p3">This package installs the <span class="s2">hg</span> executable in <span class="s2">/usr/local/bin</span> and the Mercurial files in <span class="s2">/Library/Python/2.5/site-packages/mercurial.</span></p>
+<p class="p2"><br></p>
+<p class="p1"><b>Documentation</b></p>
+<p class="p2"><br></p>
+<p class="p3">Visit the <a href="http://mercurial.selenic.com/">Mercurial web site and wiki</a></p>
+<p class="p2"><br></p>
+<p class="p3">There's also a free book, <a href="http://hgbook.red-bean.com/">Distributed revision control with Mercurial</a></p>
+<p class="p2"><br></p>
+<p class="p1"><b>Reporting problems</b></p>
+<p class="p2"><br></p>
+<p class="p3">If you run into any problems, please file a bug online:</p>
+<p class="p3"><a href="http://mercurial.selenic.com/bts/">http://mercurial.selenic.com/bts/</a></p>
+</body>
+</html>
diff --git a/sys/src/cmd/hg/contrib/macosx/Welcome.html b/sys/src/cmd/hg/contrib/macosx/Welcome.html
new file mode 100644
index 000000000..61ebabc72
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/macosx/Welcome.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!-- This is the second screen displayed during the install. -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <title></title>
+ <style type="text/css">
+ p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
+ p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+ </style>
+</head>
+<body>
+<p class="p1">This is a prepackaged release of <a href="http://mercurial.selenic.com/">Mercurial</a> for Mac OS X.</p>
+<p class="p2"><br></p>
+<br>
+<p>
+Please be sure to read the latest <a href="http://mercurial.selenic.com/wiki/WhatsNew">release notes</a>.</p>
+</body>
+</html>
diff --git a/sys/src/cmd/hg/contrib/macosx/macosx-build.txt b/sys/src/cmd/hg/contrib/macosx/macosx-build.txt
new file mode 100644
index 000000000..f67ca5332
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/macosx/macosx-build.txt
@@ -0,0 +1,11 @@
+to build a new macosx binary package:
+
+install macpython from http://www.python.org/download/mac
+
+install py2app from http://pythonmac.org/packages/
+
+make sure /usr/local/bin is in your path
+
+run bdist_mpkg in top-level hg directory
+
+find packaged stuff in dist directory
diff --git a/sys/src/cmd/hg/contrib/mercurial.el b/sys/src/cmd/hg/contrib/mercurial.el
new file mode 100644
index 000000000..182fc18c4
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/mercurial.el
@@ -0,0 +1,1294 @@
+;;; mercurial.el --- Emacs support for the Mercurial distributed SCM
+
+;; Copyright (C) 2005, 2006 Bryan O'Sullivan
+
+;; Author: Bryan O'Sullivan <bos@serpentine.com>
+
+;; mercurial.el is free software; you can redistribute it and/or
+;; modify it under the terms of version 2 of the GNU General Public
+;; License as published by the Free Software Foundation.
+
+;; mercurial.el is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with mercurial.el, GNU Emacs, or XEmacs; see the file COPYING
+;; (`C-h C-l'). If not, write to the Free Software Foundation, Inc.,
+;; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; mercurial.el builds upon Emacs's VC mode to provide flexible
+;; integration with the Mercurial distributed SCM tool.
+
+;; To get going as quickly as possible, load mercurial.el into Emacs and
+;; type `C-c h h'; this runs hg-help-overview, which prints a helpful
+;; usage overview.
+
+;; Much of the inspiration for mercurial.el comes from Rajesh
+;; Vaidheeswarran's excellent p4.el, which does an admirably thorough
+;; job for the commercial Perforce SCM product. In fact, substantial
+;; chunks of code are adapted from p4.el.
+
+;; This code has been developed under XEmacs 21.5, and may not work as
+;; well under GNU Emacs (albeit tested under 21.4). Patches to
+;; enhance the portability of this code, fix bugs, and add features
+;; are most welcome.
+
+;; As of version 22.3, GNU Emacs's VC mode has direct support for
+;; Mercurial, so this package may not prove as useful there.
+
+;; Please send problem reports and suggestions to bos@serpentine.com.
+
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'diff-mode)
+(require 'easymenu)
+(require 'executable)
+(require 'vc)
+
+(defmacro hg-feature-cond (&rest clauses)
+ "Test CLAUSES for feature at compile time.
+Each clause is (FEATURE BODY...)."
+ (dolist (x clauses)
+ (let ((feature (car x))
+ (body (cdr x)))
+ (when (or (eq feature t)
+ (featurep feature))
+ (return (cons 'progn body))))))
+
+
+;;; XEmacs has view-less, while GNU Emacs has view. Joy.
+
+(hg-feature-cond
+ (xemacs (require 'view-less))
+ (t (require 'view)))
+
+
+;;; Variables accessible through the custom system.
+
+(defgroup mercurial nil
+ "Mercurial distributed SCM."
+ :group 'tools)
+
+(defcustom hg-binary
+ (or (executable-find "hg")
+ (dolist (path '("~/bin/hg" "/usr/bin/hg" "/usr/local/bin/hg"))
+ (when (file-executable-p path)
+ (return path))))
+ "The path to Mercurial's hg executable."
+ :type '(file :must-match t)
+ :group 'mercurial)
+
+(defcustom hg-mode-hook nil
+ "Hook run when a buffer enters hg-mode."
+ :type 'sexp
+ :group 'mercurial)
+
+(defcustom hg-commit-mode-hook nil
+ "Hook run when a buffer is created to prepare a commit."
+ :type 'sexp
+ :group 'mercurial)
+
+(defcustom hg-pre-commit-hook nil
+ "Hook run before a commit is performed.
+If you want to prevent the commit from proceeding, raise an error."
+ :type 'sexp
+ :group 'mercurial)
+
+(defcustom hg-log-mode-hook nil
+ "Hook run after a buffer is filled with log information."
+ :type 'sexp
+ :group 'mercurial)
+
+(defcustom hg-global-prefix "\C-ch"
+ "The global prefix for Mercurial keymap bindings."
+ :type 'sexp
+ :group 'mercurial)
+
+(defcustom hg-commit-allow-empty-message nil
+ "Whether to allow changes to be committed with empty descriptions."
+ :type 'boolean
+ :group 'mercurial)
+
+(defcustom hg-commit-allow-empty-file-list nil
+ "Whether to allow changes to be committed without any modified files."
+ :type 'boolean
+ :group 'mercurial)
+
+(defcustom hg-rev-completion-limit 100
+ "The maximum number of revisions that hg-read-rev will offer to complete.
+This affects memory usage and performance when prompting for revisions
+in a repository with a lot of history."
+ :type 'integer
+ :group 'mercurial)
+
+(defcustom hg-log-limit 50
+ "The maximum number of revisions that hg-log will display."
+ :type 'integer
+ :group 'mercurial)
+
+(defcustom hg-update-modeline t
+ "Whether to update the modeline with the status of a file after every save.
+Set this to nil on platforms with poor process management, such as Windows."
+ :type 'boolean
+ :group 'mercurial)
+
+(defcustom hg-incoming-repository "default"
+ "The repository from which changes are pulled from by default.
+This should be a symbolic repository name, since it is used for all
+repository-related commands."
+ :type 'string
+ :group 'mercurial)
+
+(defcustom hg-outgoing-repository "default-push"
+ "The repository to which changes are pushed to by default.
+This should be a symbolic repository name, since it is used for all
+repository-related commands."
+ :type 'string
+ :group 'mercurial)
+
+
+;;; Other variables.
+
+(defvar hg-mode nil
+ "Is this file managed by Mercurial?")
+(make-variable-buffer-local 'hg-mode)
+(put 'hg-mode 'permanent-local t)
+
+(defvar hg-status nil)
+(make-variable-buffer-local 'hg-status)
+(put 'hg-status 'permanent-local t)
+
+(defvar hg-prev-buffer nil)
+(make-variable-buffer-local 'hg-prev-buffer)
+(put 'hg-prev-buffer 'permanent-local t)
+
+(defvar hg-root nil)
+(make-variable-buffer-local 'hg-root)
+(put 'hg-root 'permanent-local t)
+
+(defvar hg-view-mode nil)
+(make-variable-buffer-local 'hg-view-mode)
+(put 'hg-view-mode 'permanent-local t)
+
+(defvar hg-view-file-name nil)
+(make-variable-buffer-local 'hg-view-file-name)
+(put 'hg-view-file-name 'permanent-local t)
+
+(defvar hg-output-buffer-name "*Hg*"
+ "The name to use for Mercurial output buffers.")
+
+(defvar hg-file-history nil)
+(defvar hg-repo-history nil)
+(defvar hg-rev-history nil)
+(defvar hg-repo-completion-table nil) ; shut up warnings
+
+
+;;; Random constants.
+
+(defconst hg-commit-message-start
+ "--- Enter your commit message. Type `C-c C-c' to commit. ---\n")
+
+(defconst hg-commit-message-end
+ "--- Files in bold will be committed. Click to toggle selection. ---\n")
+
+(defconst hg-state-alist
+ '((?M . modified)
+ (?A . added)
+ (?R . removed)
+ (?! . deleted)
+ (?C . normal)
+ (?I . ignored)
+ (?? . nil)))
+
+;;; hg-mode keymap.
+
+(defvar hg-prefix-map
+ (let ((map (make-sparse-keymap)))
+ (hg-feature-cond (xemacs (set-keymap-name map 'hg-prefix-map))) ; XEmacs
+ (set-keymap-parent map vc-prefix-map)
+ (define-key map "=" 'hg-diff)
+ (define-key map "c" 'hg-undo)
+ (define-key map "g" 'hg-annotate)
+ (define-key map "i" 'hg-add)
+ (define-key map "l" 'hg-log)
+ (define-key map "n" 'hg-commit-start)
+ ;; (define-key map "r" 'hg-update)
+ (define-key map "u" 'hg-revert-buffer)
+ (define-key map "~" 'hg-version-other-window)
+ map)
+ "This keymap overrides some default vc-mode bindings.")
+
+(defvar hg-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-xv" hg-prefix-map)
+ map))
+
+(add-minor-mode 'hg-mode 'hg-mode hg-mode-map)
+
+
+;;; Global keymap.
+
+(defvar hg-global-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "," 'hg-incoming)
+ (define-key map "." 'hg-outgoing)
+ (define-key map "<" 'hg-pull)
+ (define-key map "=" 'hg-diff-repo)
+ (define-key map ">" 'hg-push)
+ (define-key map "?" 'hg-help-overview)
+ (define-key map "A" 'hg-addremove)
+ (define-key map "U" 'hg-revert)
+ (define-key map "a" 'hg-add)
+ (define-key map "c" 'hg-commit-start)
+ (define-key map "f" 'hg-forget)
+ (define-key map "h" 'hg-help-overview)
+ (define-key map "i" 'hg-init)
+ (define-key map "l" 'hg-log-repo)
+ (define-key map "r" 'hg-root)
+ (define-key map "s" 'hg-status)
+ (define-key map "u" 'hg-update)
+ map))
+
+(global-set-key hg-global-prefix hg-global-map)
+
+;;; View mode keymap.
+
+(defvar hg-view-mode-map
+ (let ((map (make-sparse-keymap)))
+ (hg-feature-cond (xemacs (set-keymap-name map 'hg-view-mode-map))) ; XEmacs
+ (define-key map (hg-feature-cond (xemacs [button2])
+ (t [mouse-2]))
+ 'hg-buffer-mouse-clicked)
+ map))
+
+(add-minor-mode 'hg-view-mode "" hg-view-mode-map)
+
+
+;;; Commit mode keymaps.
+
+(defvar hg-commit-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-c\C-c" 'hg-commit-finish)
+ (define-key map "\C-c\C-k" 'hg-commit-kill)
+ (define-key map "\C-xv=" 'hg-diff-repo)
+ map))
+
+(defvar hg-commit-mode-file-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (hg-feature-cond (xemacs [button2])
+ (t [mouse-2]))
+ 'hg-commit-mouse-clicked)
+ (define-key map " " 'hg-commit-toggle-file)
+ (define-key map "\r" 'hg-commit-toggle-file)
+ map))
+
+
+;;; Convenience functions.
+
+(defsubst hg-binary ()
+ (if hg-binary
+ hg-binary
+ (error "No `hg' executable found!")))
+
+(defsubst hg-replace-in-string (str regexp newtext &optional literal)
+ "Replace all matches in STR for REGEXP with NEWTEXT string.
+Return the new string. Optional LITERAL non-nil means do a literal
+replacement.
+
+This function bridges yet another pointless impedance gap between
+XEmacs and GNU Emacs."
+ (hg-feature-cond
+ (xemacs (replace-in-string str regexp newtext literal))
+ (t (replace-regexp-in-string regexp newtext str nil literal))))
+
+(defsubst hg-strip (str)
+ "Strip leading and trailing blank lines from a string."
+ (hg-replace-in-string (hg-replace-in-string str "[\r\n][ \t\r\n]*\\'" "")
+ "\\`[ \t\r\n]*[\r\n]" ""))
+
+(defsubst hg-chomp (str)
+ "Strip trailing newlines from a string."
+ (hg-replace-in-string str "[\r\n]+\\'" ""))
+
+(defun hg-run-command (command &rest args)
+ "Run the shell command COMMAND, returning (EXIT-CODE . COMMAND-OUTPUT).
+The list ARGS contains a list of arguments to pass to the command."
+ (let* (exit-code
+ (output
+ (with-output-to-string
+ (with-current-buffer
+ standard-output
+ (setq exit-code
+ (apply 'call-process command nil t nil args))))))
+ (cons exit-code output)))
+
+(defun hg-run (command &rest args)
+ "Run the Mercurial command COMMAND, returning (EXIT-CODE . COMMAND-OUTPUT)."
+ (apply 'hg-run-command (hg-binary) command args))
+
+(defun hg-run0 (command &rest args)
+ "Run the Mercurial command COMMAND, returning its output.
+If the command does not exit with a zero status code, raise an error."
+ (let ((res (apply 'hg-run-command (hg-binary) command args)))
+ (if (not (eq (car res) 0))
+ (error "Mercurial command failed %s - exit code %s"
+ (cons command args)
+ (car res))
+ (cdr res))))
+
+(defmacro hg-do-across-repo (path &rest body)
+ (let ((root-name (make-symbol "root-"))
+ (buf-name (make-symbol "buf-")))
+ `(let ((,root-name (hg-root ,path)))
+ (save-excursion
+ (dolist (,buf-name (buffer-list))
+ (set-buffer ,buf-name)
+ (when (and hg-status (equal (hg-root buffer-file-name) ,root-name))
+ ,@body))))))
+
+(put 'hg-do-across-repo 'lisp-indent-function 1)
+
+(defun hg-sync-buffers (path)
+ "Sync buffers visiting PATH with their on-disk copies.
+If PATH is not being visited, but is under the repository root, sync
+all buffers visiting files in the repository."
+ (let ((buf (find-buffer-visiting path)))
+ (if buf
+ (with-current-buffer buf
+ (vc-buffer-sync))
+ (hg-do-across-repo path
+ (vc-buffer-sync)))))
+
+(defun hg-buffer-commands (pnt)
+ "Use the properties of a character to do something sensible."
+ (interactive "d")
+ (let ((rev (get-char-property pnt 'rev))
+ (file (get-char-property pnt 'file)))
+ (cond
+ (file
+ (find-file-other-window file))
+ (rev
+ (hg-diff hg-view-file-name rev rev))
+ ((message "I don't know how to do that yet")))))
+
+(defsubst hg-event-point (event)
+ "Return the character position of the mouse event EVENT."
+ (hg-feature-cond (xemacs (event-point event))
+ (t (posn-point (event-start event)))))
+
+(defsubst hg-event-window (event)
+ "Return the window over which mouse event EVENT occurred."
+ (hg-feature-cond (xemacs (event-window event))
+ (t (posn-window (event-start event)))))
+
+(defun hg-buffer-mouse-clicked (event)
+ "Translate the mouse clicks in a HG log buffer to character events.
+These are then handed off to `hg-buffer-commands'.
+
+Handle frickin' frackin' gratuitous event-related incompatibilities."
+ (interactive "e")
+ (select-window (hg-event-window event))
+ (hg-buffer-commands (hg-event-point event)))
+
+(defsubst hg-abbrev-file-name (file)
+ "Portable wrapper around abbreviate-file-name."
+ (hg-feature-cond (xemacs (abbreviate-file-name file t))
+ (t (abbreviate-file-name file))))
+
+(defun hg-read-file-name (&optional prompt default)
+ "Read a file or directory name, or a pattern, to use with a command."
+ (save-excursion
+ (while hg-prev-buffer
+ (set-buffer hg-prev-buffer))
+ (let ((path (or default
+ (buffer-file-name)
+ (expand-file-name default-directory))))
+ (if (or (not path) current-prefix-arg)
+ (expand-file-name
+ (eval (list* 'read-file-name
+ (format "File, directory or pattern%s: "
+ (or prompt ""))
+ (and path (file-name-directory path))
+ nil nil
+ (and path (file-name-nondirectory path))
+ (hg-feature-cond
+ (xemacs (cons (quote 'hg-file-history) nil))
+ (t nil)))))
+ path))))
+
+(defun hg-read-number (&optional prompt default)
+ "Read a integer value."
+ (save-excursion
+ (if (or (not default) current-prefix-arg)
+ (string-to-number
+ (eval (list* 'read-string
+ (or prompt "")
+ (if default (cons (format "%d" default) nil) nil))))
+ default)))
+
+(defun hg-read-config ()
+ "Return an alist of (key . value) pairs of Mercurial config data.
+Each key is of the form (section . name)."
+ (let (items)
+ (dolist (line (split-string (hg-chomp (hg-run0 "debugconfig")) "\n") items)
+ (string-match "^\\([^=]*\\)=\\(.*\\)" line)
+ (let* ((left (substring line (match-beginning 1) (match-end 1)))
+ (right (substring line (match-beginning 2) (match-end 2)))
+ (key (split-string left "\\."))
+ (value (hg-replace-in-string right "\\\\n" "\n" t)))
+ (setq items (cons (cons (cons (car key) (cadr key)) value) items))))))
+
+(defun hg-config-section (section config)
+ "Return an alist of (name . value) pairs for SECTION of CONFIG."
+ (let (items)
+ (dolist (item config items)
+ (when (equal (caar item) section)
+ (setq items (cons (cons (cdar item) (cdr item)) items))))))
+
+(defun hg-string-starts-with (sub str)
+ "Indicate whether string STR starts with the substring or character SUB."
+ (if (not (stringp sub))
+ (and (> (length str) 0) (equal (elt str 0) sub))
+ (let ((sub-len (length sub)))
+ (and (<= sub-len (length str))
+ (string= sub (substring str 0 sub-len))))))
+
+(defun hg-complete-repo (string predicate all)
+ "Attempt to complete a repository name.
+We complete on either symbolic names from Mercurial's config or real
+directory names from the file system. We do not penalise URLs."
+ (or (if all
+ (all-completions string hg-repo-completion-table predicate)
+ (try-completion string hg-repo-completion-table predicate))
+ (let* ((str (expand-file-name string))
+ (dir (file-name-directory str))
+ (file (file-name-nondirectory str)))
+ (if all
+ (let (completions)
+ (dolist (name (delete "./" (file-name-all-completions file dir))
+ completions)
+ (let ((path (concat dir name)))
+ (when (file-directory-p path)
+ (setq completions (cons name completions))))))
+ (let ((comp (file-name-completion file dir)))
+ (if comp
+ (hg-abbrev-file-name (concat dir comp))))))))
+
+(defun hg-read-repo-name (&optional prompt initial-contents default)
+ "Read the location of a repository."
+ (save-excursion
+ (while hg-prev-buffer
+ (set-buffer hg-prev-buffer))
+ (let (hg-repo-completion-table)
+ (if current-prefix-arg
+ (progn
+ (dolist (path (hg-config-section "paths" (hg-read-config)))
+ (setq hg-repo-completion-table
+ (cons (cons (car path) t) hg-repo-completion-table))
+ (unless (hg-string-starts-with (hg-feature-cond
+ (xemacs directory-sep-char)
+ (t ?/))
+ (cdr path))
+ (setq hg-repo-completion-table
+ (cons (cons (cdr path) t) hg-repo-completion-table))))
+ (completing-read (format "Repository%s: " (or prompt ""))
+ 'hg-complete-repo
+ nil
+ nil
+ initial-contents
+ 'hg-repo-history
+ default))
+ default))))
+
+(defun hg-read-rev (&optional prompt default)
+ "Read a revision or tag, offering completions."
+ (save-excursion
+ (while hg-prev-buffer
+ (set-buffer hg-prev-buffer))
+ (let ((rev (or default "tip")))
+ (if current-prefix-arg
+ (let ((revs (split-string
+ (hg-chomp
+ (hg-run0 "-q" "log" "-l"
+ (format "%d" hg-rev-completion-limit)))
+ "[\n:]")))
+ (dolist (line (split-string (hg-chomp (hg-run0 "tags")) "\n"))
+ (setq revs (cons (car (split-string line "\\s-")) revs)))
+ (completing-read (format "Revision%s (%s): "
+ (or prompt "")
+ (or default "tip"))
+ (mapcar (lambda (x) (cons x x)) revs)
+ nil
+ nil
+ nil
+ 'hg-rev-history
+ (or default "tip")))
+ rev))))
+
+(defun hg-parents-for-mode-line (root)
+ "Format the parents of the working directory for the mode line."
+ (let ((parents (split-string (hg-chomp
+ (hg-run0 "--cwd" root "parents" "--template"
+ "{rev}\n")) "\n")))
+ (mapconcat 'identity parents "+")))
+
+(defun hg-buffers-visiting-repo (&optional path)
+ "Return a list of buffers visiting the repository containing PATH."
+ (let ((root-name (hg-root (or path (buffer-file-name))))
+ bufs)
+ (save-excursion
+ (dolist (buf (buffer-list) bufs)
+ (set-buffer buf)
+ (let ((name (buffer-file-name)))
+ (when (and hg-status name (equal (hg-root name) root-name))
+ (setq bufs (cons buf bufs))))))))
+
+(defun hg-update-mode-lines (path)
+ "Update the mode lines of all buffers visiting the same repository as PATH."
+ (let* ((root (hg-root path))
+ (parents (hg-parents-for-mode-line root)))
+ (save-excursion
+ (dolist (info (hg-path-status
+ root
+ (mapcar
+ (function
+ (lambda (buf)
+ (substring (buffer-file-name buf) (length root))))
+ (hg-buffers-visiting-repo root))))
+ (let* ((name (car info))
+ (status (cdr info))
+ (buf (find-buffer-visiting (concat root name))))
+ (when buf
+ (set-buffer buf)
+ (hg-mode-line-internal status parents)))))))
+
+
+;;; View mode bits.
+
+(defun hg-exit-view-mode (buf)
+ "Exit from hg-view-mode.
+We delete the current window if entering hg-view-mode split the
+current frame."
+ (when (and (eq buf (current-buffer))
+ (> (length (window-list)) 1))
+ (delete-window))
+ (when (buffer-live-p buf)
+ (kill-buffer buf)))
+
+(defun hg-view-mode (prev-buffer &optional file-name)
+ (goto-char (point-min))
+ (set-buffer-modified-p nil)
+ (toggle-read-only t)
+ (hg-feature-cond (xemacs (view-minor-mode prev-buffer 'hg-exit-view-mode))
+ (t (view-mode-enter nil 'hg-exit-view-mode)))
+ (setq hg-view-mode t)
+ (setq truncate-lines t)
+ (when file-name
+ (setq hg-view-file-name
+ (hg-abbrev-file-name file-name))))
+
+(defun hg-file-status (file)
+ "Return status of FILE, or nil if FILE does not exist or is unmanaged."
+ (let* ((s (hg-run "status" file))
+ (exit (car s))
+ (output (cdr s)))
+ (if (= exit 0)
+ (let ((state (and (>= (length output) 2)
+ (= (aref output 1) ? )
+ (assq (aref output 0) hg-state-alist))))
+ (if state
+ (cdr state)
+ 'normal)))))
+
+(defun hg-path-status (root paths)
+ "Return status of PATHS in repo ROOT as an alist.
+Each entry is a pair (FILE-NAME . STATUS)."
+ (let ((s (apply 'hg-run "--cwd" root "status" "-marduc" paths))
+ result)
+ (dolist (entry (split-string (hg-chomp (cdr s)) "\n") (nreverse result))
+ (let (state name)
+ (cond ((= (aref entry 1) ? )
+ (setq state (assq (aref entry 0) hg-state-alist)
+ name (substring entry 2)))
+ ((string-match "\\(.*\\): " entry)
+ (setq name (match-string 1 entry))))
+ (setq result (cons (cons name state) result))))))
+
+(defmacro hg-view-output (args &rest body)
+ "Execute BODY in a clean buffer, then quickly display that buffer.
+If the buffer contains one line, its contents are displayed in the
+minibuffer. Otherwise, the buffer is displayed in view-mode.
+ARGS is of the form (BUFFER-NAME &optional FILE), where BUFFER-NAME is
+the name of the buffer to create, and FILE is the name of the file
+being viewed."
+ (let ((prev-buf (make-symbol "prev-buf-"))
+ (v-b-name (car args))
+ (v-m-rest (cdr args)))
+ `(let ((view-buf-name ,v-b-name)
+ (,prev-buf (current-buffer)))
+ (get-buffer-create view-buf-name)
+ (kill-buffer view-buf-name)
+ (get-buffer-create view-buf-name)
+ (set-buffer view-buf-name)
+ (save-excursion
+ ,@body)
+ (case (count-lines (point-min) (point-max))
+ ((0)
+ (kill-buffer view-buf-name)
+ (message "(No output)"))
+ ((1)
+ (let ((msg (hg-chomp (buffer-substring (point-min) (point-max)))))
+ (kill-buffer view-buf-name)
+ (message "%s" msg)))
+ (t
+ (pop-to-buffer view-buf-name)
+ (setq hg-prev-buffer ,prev-buf)
+ (hg-view-mode ,prev-buf ,@v-m-rest))))))
+
+(put 'hg-view-output 'lisp-indent-function 1)
+
+;;; Context save and restore across revert and other operations.
+
+(defun hg-position-context (pos)
+ "Return information to help find the given position again."
+ (let* ((end (min (point-max) (+ pos 98))))
+ (list pos
+ (buffer-substring (max (point-min) (- pos 2)) end)
+ (- end pos))))
+
+(defun hg-buffer-context ()
+ "Return information to help restore a user's editing context.
+This is useful across reverts and merges, where a context is likely
+to have moved a little, but not really changed."
+ (let ((point-context (hg-position-context (point)))
+ (mark-context (let ((mark (mark-marker)))
+ (and mark
+ ;; make sure active mark
+ (marker-buffer mark)
+ (marker-position mark)
+ (hg-position-context mark)))))
+ (list point-context mark-context)))
+
+(defun hg-find-context (ctx)
+ "Attempt to find a context in the given buffer.
+Always returns a valid, hopefully sane, position."
+ (let ((pos (nth 0 ctx))
+ (str (nth 1 ctx))
+ (fixup (nth 2 ctx)))
+ (save-excursion
+ (goto-char (max (point-min) (- pos 15000)))
+ (if (and (not (equal str ""))
+ (search-forward str nil t))
+ (- (point) fixup)
+ (max pos (point-min))))))
+
+(defun hg-restore-context (ctx)
+ "Attempt to restore the user's editing context."
+ (let ((point-context (nth 0 ctx))
+ (mark-context (nth 1 ctx)))
+ (goto-char (hg-find-context point-context))
+ (when mark-context
+ (set-mark (hg-find-context mark-context)))))
+
+
+;;; Hooks.
+
+(defun hg-mode-line-internal (status parents)
+ (setq hg-status status
+ hg-mode (and status (concat " Hg:"
+ parents
+ (cdr (assq status
+ '((normal . "")
+ (removed . "r")
+ (added . "a")
+ (deleted . "!")
+ (modified . "m"))))))))
+
+(defun hg-mode-line (&optional force)
+ "Update the modeline with the current status of a file.
+An update occurs if optional argument FORCE is non-nil,
+hg-update-modeline is non-nil, or we have not yet checked the state of
+the file."
+ (let ((root (hg-root)))
+ (when (and root (or force hg-update-modeline (not hg-mode)))
+ (let ((status (hg-file-status buffer-file-name))
+ (parents (hg-parents-for-mode-line root)))
+ (hg-mode-line-internal status parents)
+ status))))
+
+(defun hg-mode (&optional toggle)
+ "Minor mode for Mercurial distributed SCM integration.
+
+The Mercurial mode user interface is based on that of VC mode, so if
+you're already familiar with VC, the same keybindings and functions
+will generally work.
+
+Below is a list of many common SCM tasks. In the list, `G/L\'
+indicates whether a key binding is global (G) to a repository or
+local (L) to a file. Many commands take a prefix argument.
+
+SCM Task G/L Key Binding Command Name
+-------- --- ----------- ------------
+Help overview (what you are reading) G C-c h h hg-help-overview
+
+Tell Mercurial to manage a file G C-c h a hg-add
+Commit changes to current file only L C-x v n hg-commit-start
+Undo changes to file since commit L C-x v u hg-revert-buffer
+
+Diff file vs last checkin L C-x v = hg-diff
+
+View file change history L C-x v l hg-log
+View annotated file L C-x v a hg-annotate
+
+Diff repo vs last checkin G C-c h = hg-diff-repo
+View status of files in repo G C-c h s hg-status
+Commit all changes G C-c h c hg-commit-start
+
+Undo all changes since last commit G C-c h U hg-revert
+View repo change history G C-c h l hg-log-repo
+
+See changes that can be pulled G C-c h , hg-incoming
+Pull changes G C-c h < hg-pull
+Update working directory after pull G C-c h u hg-update
+See changes that can be pushed G C-c h . hg-outgoing
+Push changes G C-c h > hg-push"
+ (unless vc-make-backup-files
+ (set (make-local-variable 'backup-inhibited) t))
+ (run-hooks 'hg-mode-hook))
+
+(defun hg-find-file-hook ()
+ (ignore-errors
+ (when (hg-mode-line)
+ (hg-mode))))
+
+(add-hook 'find-file-hooks 'hg-find-file-hook)
+
+(defun hg-after-save-hook ()
+ (ignore-errors
+ (let ((old-status hg-status))
+ (hg-mode-line)
+ (if (and (not old-status) hg-status)
+ (hg-mode)))))
+
+(add-hook 'after-save-hook 'hg-after-save-hook)
+
+
+;;; User interface functions.
+
+(defun hg-help-overview ()
+ "This is an overview of the Mercurial SCM mode for Emacs.
+
+You can find the source code, license (GPL v2), and credits for this
+code by typing `M-x find-library mercurial RET'."
+ (interactive)
+ (hg-view-output ("Mercurial Help Overview")
+ (insert (documentation 'hg-help-overview))
+ (let ((pos (point)))
+ (insert (documentation 'hg-mode))
+ (goto-char pos)
+ (end-of-line 1)
+ (delete-region pos (point)))
+ (let ((hg-root-dir (hg-root)))
+ (if (not hg-root-dir)
+ (error "error: %s: directory is not part of a Mercurial repository."
+ default-directory)
+ (cd hg-root-dir)))))
+
+(defun hg-fix-paths ()
+ "Fix paths reported by some Mercurial commands."
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward " \\.\\.." nil t)
+ (replace-match " " nil nil))))
+
+(defun hg-add (path)
+ "Add PATH to the Mercurial repository on the next commit.
+With a prefix argument, prompt for the path to add."
+ (interactive (list (hg-read-file-name " to add")))
+ (let ((buf (current-buffer))
+ (update (equal buffer-file-name path)))
+ (hg-view-output (hg-output-buffer-name)
+ (apply 'call-process (hg-binary) nil t nil (list "add" path))
+ (hg-fix-paths)
+ (goto-char (point-min))
+ (cd (hg-root path)))
+ (when update
+ (unless vc-make-backup-files
+ (set (make-local-variable 'backup-inhibited) t))
+ (with-current-buffer buf
+ (hg-mode-line)))))
+
+(defun hg-addremove ()
+ (interactive)
+ (error "not implemented"))
+
+(defun hg-annotate ()
+ (interactive)
+ (error "not implemented"))
+
+(defun hg-commit-toggle-file (pos)
+ "Toggle whether or not the file at POS will be committed."
+ (interactive "d")
+ (save-excursion
+ (goto-char pos)
+ (let (face
+ (inhibit-read-only t)
+ bol)
+ (beginning-of-line)
+ (setq bol (+ (point) 4))
+ (setq face (get-text-property bol 'face))
+ (end-of-line)
+ (if (eq face 'bold)
+ (progn
+ (remove-text-properties bol (point) '(face nil))
+ (message "%s will not be committed"
+ (buffer-substring bol (point))))
+ (add-text-properties bol (point) '(face bold))
+ (message "%s will be committed"
+ (buffer-substring bol (point)))))))
+
+(defun hg-commit-mouse-clicked (event)
+ "Toggle whether or not the file at POS will be committed."
+ (interactive "@e")
+ (hg-commit-toggle-file (hg-event-point event)))
+
+(defun hg-commit-kill ()
+ "Kill the commit currently being prepared."
+ (interactive)
+ (when (or (not (buffer-modified-p)) (y-or-n-p "Really kill this commit? "))
+ (let ((buf hg-prev-buffer))
+ (kill-buffer nil)
+ (switch-to-buffer buf))))
+
+(defun hg-commit-finish ()
+ "Finish preparing a commit, and perform the actual commit.
+The hook hg-pre-commit-hook is run before anything else is done. If
+the commit message is empty and hg-commit-allow-empty-message is nil,
+an error is raised. If the list of files to commit is empty and
+hg-commit-allow-empty-file-list is nil, an error is raised."
+ (interactive)
+ (let ((root hg-root))
+ (save-excursion
+ (run-hooks 'hg-pre-commit-hook)
+ (goto-char (point-min))
+ (search-forward hg-commit-message-start)
+ (let (message files)
+ (let ((start (point)))
+ (goto-char (point-max))
+ (search-backward hg-commit-message-end)
+ (setq message (hg-strip (buffer-substring start (point)))))
+ (when (and (= (length message) 0)
+ (not hg-commit-allow-empty-message))
+ (error "Cannot proceed - commit message is empty"))
+ (forward-line 1)
+ (beginning-of-line)
+ (while (< (point) (point-max))
+ (let ((pos (+ (point) 4)))
+ (end-of-line)
+ (when (eq (get-text-property pos 'face) 'bold)
+ (end-of-line)
+ (setq files (cons (buffer-substring pos (point)) files))))
+ (forward-line 1))
+ (when (and (= (length files) 0)
+ (not hg-commit-allow-empty-file-list))
+ (error "Cannot proceed - no files to commit"))
+ (setq message (concat message "\n"))
+ (apply 'hg-run0 "--cwd" hg-root "commit" "-m" message files))
+ (let ((buf hg-prev-buffer))
+ (kill-buffer nil)
+ (switch-to-buffer buf))
+ (hg-update-mode-lines root))))
+
+(defun hg-commit-mode ()
+ "Mode for describing a commit of changes to a Mercurial repository.
+This involves two actions: describing the changes with a commit
+message, and choosing the files to commit.
+
+To describe the commit, simply type some text in the designated area.
+
+By default, all modified, added and removed files are selected for
+committing. Files that will be committed are displayed in bold face\;
+those that will not are displayed in normal face.
+
+To toggle whether a file will be committed, move the cursor over a
+particular file and hit space or return. Alternatively, middle click
+on the file.
+
+Key bindings
+------------
+\\[hg-commit-finish] proceed with commit
+\\[hg-commit-kill] kill commit
+
+\\[hg-diff-repo] view diff of pending changes"
+ (interactive)
+ (use-local-map hg-commit-mode-map)
+ (set-syntax-table text-mode-syntax-table)
+ (setq local-abbrev-table text-mode-abbrev-table
+ major-mode 'hg-commit-mode
+ mode-name "Hg-Commit")
+ (set-buffer-modified-p nil)
+ (setq buffer-undo-list nil)
+ (run-hooks 'text-mode-hook 'hg-commit-mode-hook))
+
+(defun hg-commit-start ()
+ "Prepare a commit of changes to the repository containing the current file."
+ (interactive)
+ (while hg-prev-buffer
+ (set-buffer hg-prev-buffer))
+ (let ((root (hg-root))
+ (prev-buffer (current-buffer))
+ modified-files)
+ (unless root
+ (error "Cannot commit outside a repository!"))
+ (hg-sync-buffers root)
+ (setq modified-files (hg-chomp (hg-run0 "--cwd" root "status" "-arm")))
+ (when (and (= (length modified-files) 0)
+ (not hg-commit-allow-empty-file-list))
+ (error "No pending changes to commit"))
+ (let* ((buf-name (format "*Mercurial: Commit %s*" root)))
+ (pop-to-buffer (get-buffer-create buf-name))
+ (when (= (point-min) (point-max))
+ (set (make-local-variable 'hg-root) root)
+ (setq hg-prev-buffer prev-buffer)
+ (insert "\n")
+ (let ((bol (point)))
+ (insert hg-commit-message-end)
+ (add-text-properties bol (point) '(face bold-italic)))
+ (let ((file-area (point)))
+ (insert modified-files)
+ (goto-char file-area)
+ (while (< (point) (point-max))
+ (let ((bol (point)))
+ (forward-char 1)
+ (insert " ")
+ (end-of-line)
+ (add-text-properties (+ bol 4) (point)
+ '(face bold mouse-face highlight)))
+ (forward-line 1))
+ (goto-char file-area)
+ (add-text-properties (point) (point-max)
+ `(keymap ,hg-commit-mode-file-map))
+ (goto-char (point-min))
+ (insert hg-commit-message-start)
+ (add-text-properties (point-min) (point) '(face bold-italic))
+ (insert "\n\n")
+ (forward-line -1)
+ (save-excursion
+ (goto-char (point-max))
+ (search-backward hg-commit-message-end)
+ (add-text-properties (match-beginning 0) (point-max)
+ '(read-only t))
+ (goto-char (point-min))
+ (search-forward hg-commit-message-start)
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(read-only t)))
+ (hg-commit-mode)
+ (cd root))))))
+
+(defun hg-diff (path &optional rev1 rev2)
+ "Show the differences between REV1 and REV2 of PATH.
+When called interactively, the default behaviour is to treat REV1 as
+the \"parent\" revision, REV2 as the current edited version of the file, and
+PATH as the file edited in the current buffer.
+With a prefix argument, prompt for all of these."
+ (interactive (list (hg-read-file-name " to diff")
+ (let ((rev1 (hg-read-rev " to start with" 'parent)))
+ (and (not (eq rev1 'parent)) rev1))
+ (let ((rev2 (hg-read-rev " to end with" 'working-dir)))
+ (and (not (eq rev2 'working-dir)) rev2))))
+ (hg-sync-buffers path)
+ (let ((a-path (hg-abbrev-file-name path))
+ ;; none revision is specified explicitly
+ (none (and (not rev1) (not rev2)))
+ ;; only one revision is specified explicitly
+ (one (or (and (or (equal rev1 rev2) (not rev2)) rev1)
+ (and (not rev1) rev2)))
+ diff)
+ (hg-view-output ((cond
+ (none
+ (format "Mercurial: Diff against parent of %s" a-path))
+ (one
+ (format "Mercurial: Diff of rev %s of %s" one a-path))
+ (t
+ (format "Mercurial: Diff from rev %s to %s of %s"
+ rev1 rev2 a-path))))
+ (cond
+ (none
+ (call-process (hg-binary) nil t nil "diff" path))
+ (one
+ (call-process (hg-binary) nil t nil "diff" "-r" one path))
+ (t
+ (call-process (hg-binary) nil t nil "diff" "-r" rev1 "-r" rev2 path)))
+ (diff-mode)
+ (setq diff (not (= (point-min) (point-max))))
+ (font-lock-fontify-buffer)
+ (cd (hg-root path)))
+ diff))
+
+(defun hg-diff-repo (path &optional rev1 rev2)
+ "Show the differences between REV1 and REV2 of repository containing PATH.
+When called interactively, the default behaviour is to treat REV1 as
+the \"parent\" revision, REV2 as the current edited version of the file, and
+PATH as the `hg-root' of the current buffer.
+With a prefix argument, prompt for all of these."
+ (interactive (list (hg-read-file-name " to diff")
+ (let ((rev1 (hg-read-rev " to start with" 'parent)))
+ (and (not (eq rev1 'parent)) rev1))
+ (let ((rev2 (hg-read-rev " to end with" 'working-dir)))
+ (and (not (eq rev2 'working-dir)) rev2))))
+ (hg-diff (hg-root path) rev1 rev2))
+
+(defun hg-forget (path)
+ "Lose track of PATH, which has been added, but not yet committed.
+This will prevent the file from being incorporated into the Mercurial
+repository on the next commit.
+With a prefix argument, prompt for the path to forget."
+ (interactive (list (hg-read-file-name " to forget")))
+ (let ((buf (current-buffer))
+ (update (equal buffer-file-name path)))
+ (hg-view-output (hg-output-buffer-name)
+ (apply 'call-process (hg-binary) nil t nil (list "forget" path))
+ ;; "hg forget" shows pathes relative NOT TO ROOT BUT TO REPOSITORY
+ (hg-fix-paths)
+ (goto-char (point-min))
+ (cd (hg-root path)))
+ (when update
+ (with-current-buffer buf
+ (when (local-variable-p 'backup-inhibited)
+ (kill-local-variable 'backup-inhibited))
+ (hg-mode-line)))))
+
+(defun hg-incoming (&optional repo)
+ "Display changesets present in REPO that are not present locally."
+ (interactive (list (hg-read-repo-name " where changes would come from")))
+ (hg-view-output ((format "Mercurial: Incoming from %s to %s"
+ (hg-abbrev-file-name (hg-root))
+ (hg-abbrev-file-name
+ (or repo hg-incoming-repository))))
+ (call-process (hg-binary) nil t nil "incoming"
+ (or repo hg-incoming-repository))
+ (hg-log-mode)
+ (cd (hg-root))))
+
+(defun hg-init ()
+ (interactive)
+ (error "not implemented"))
+
+(defun hg-log-mode ()
+ "Mode for viewing a Mercurial change log."
+ (goto-char (point-min))
+ (when (looking-at "^searching for changes.*$")
+ (delete-region (match-beginning 0) (match-end 0)))
+ (run-hooks 'hg-log-mode-hook))
+
+(defun hg-log (path &optional rev1 rev2 log-limit)
+ "Display the revision history of PATH.
+History is displayed between REV1 and REV2.
+Number of displayed changesets is limited to LOG-LIMIT.
+REV1 defaults to the tip, while REV2 defaults to 0.
+LOG-LIMIT defaults to `hg-log-limit'.
+With a prefix argument, prompt for each parameter."
+ (interactive (list (hg-read-file-name " to log")
+ (hg-read-rev " to start with"
+ "tip")
+ (hg-read-rev " to end with"
+ "0")
+ (hg-read-number "Output limited to: "
+ hg-log-limit)))
+ (let ((a-path (hg-abbrev-file-name path))
+ (r1 (or rev1 "tip"))
+ (r2 (or rev2 "0"))
+ (limit (format "%d" (or log-limit hg-log-limit))))
+ (hg-view-output ((if (equal r1 r2)
+ (format "Mercurial: Log of rev %s of %s" rev1 a-path)
+ (format
+ "Mercurial: at most %s log(s) from rev %s to %s of %s"
+ limit r1 r2 a-path)))
+ (eval (list* 'call-process (hg-binary) nil t nil
+ "log"
+ "-r" (format "%s:%s" r1 r2)
+ "-l" limit
+ (if (> (length path) (length (hg-root path)))
+ (cons path nil)
+ nil)))
+ (hg-log-mode)
+ (cd (hg-root path)))))
+
+(defun hg-log-repo (path &optional rev1 rev2 log-limit)
+ "Display the revision history of the repository containing PATH.
+History is displayed between REV1 and REV2.
+Number of displayed changesets is limited to LOG-LIMIT,
+REV1 defaults to the tip, while REV2 defaults to 0.
+LOG-LIMIT defaults to `hg-log-limit'.
+With a prefix argument, prompt for each parameter."
+ (interactive (list (hg-read-file-name " to log")
+ (hg-read-rev " to start with"
+ "tip")
+ (hg-read-rev " to end with"
+ "0")
+ (hg-read-number "Output limited to: "
+ hg-log-limit)))
+ (hg-log (hg-root path) rev1 rev2 log-limit))
+
+(defun hg-outgoing (&optional repo)
+ "Display changesets present locally that are not present in REPO."
+ (interactive (list (hg-read-repo-name " where changes would go to" nil
+ hg-outgoing-repository)))
+ (hg-view-output ((format "Mercurial: Outgoing from %s to %s"
+ (hg-abbrev-file-name (hg-root))
+ (hg-abbrev-file-name
+ (or repo hg-outgoing-repository))))
+ (call-process (hg-binary) nil t nil "outgoing"
+ (or repo hg-outgoing-repository))
+ (hg-log-mode)
+ (cd (hg-root))))
+
+(defun hg-pull (&optional repo)
+ "Pull changes from repository REPO.
+This does not update the working directory."
+ (interactive (list (hg-read-repo-name " to pull from")))
+ (hg-view-output ((format "Mercurial: Pull to %s from %s"
+ (hg-abbrev-file-name (hg-root))
+ (hg-abbrev-file-name
+ (or repo hg-incoming-repository))))
+ (call-process (hg-binary) nil t nil "pull"
+ (or repo hg-incoming-repository))
+ (cd (hg-root))))
+
+(defun hg-push (&optional repo)
+ "Push changes to repository REPO."
+ (interactive (list (hg-read-repo-name " to push to")))
+ (hg-view-output ((format "Mercurial: Push from %s to %s"
+ (hg-abbrev-file-name (hg-root))
+ (hg-abbrev-file-name
+ (or repo hg-outgoing-repository))))
+ (call-process (hg-binary) nil t nil "push"
+ (or repo hg-outgoing-repository))
+ (cd (hg-root))))
+
+(defun hg-revert-buffer-internal ()
+ (let ((ctx (hg-buffer-context)))
+ (message "Reverting %s..." buffer-file-name)
+ (hg-run0 "revert" buffer-file-name)
+ (revert-buffer t t t)
+ (hg-restore-context ctx)
+ (hg-mode-line)
+ (message "Reverting %s...done" buffer-file-name)))
+
+(defun hg-revert-buffer ()
+ "Revert current buffer's file back to the latest committed version.
+If the file has not changed, nothing happens. Otherwise, this
+displays a diff and asks for confirmation before reverting."
+ (interactive)
+ (let ((vc-suppress-confirm nil)
+ (obuf (current-buffer))
+ diff)
+ (vc-buffer-sync)
+ (unwind-protect
+ (setq diff (hg-diff buffer-file-name))
+ (when diff
+ (unless (yes-or-no-p "Discard changes? ")
+ (error "Revert cancelled")))
+ (when diff
+ (let ((buf (current-buffer)))
+ (delete-window (selected-window))
+ (kill-buffer buf))))
+ (set-buffer obuf)
+ (when diff
+ (hg-revert-buffer-internal))))
+
+(defun hg-root (&optional path)
+ "Return the root of the repository that contains the given path.
+If the path is outside a repository, return nil.
+When called interactively, the root is printed. A prefix argument
+prompts for a path to check."
+ (interactive (list (hg-read-file-name)))
+ (if (or path (not hg-root))
+ (let ((root (do ((prev nil dir)
+ (dir (file-name-directory
+ (or
+ path
+ buffer-file-name
+ (expand-file-name default-directory)))
+ (file-name-directory (directory-file-name dir))))
+ ((equal prev dir))
+ (when (file-directory-p (concat dir ".hg"))
+ (return dir)))))
+ (when (interactive-p)
+ (if root
+ (message "The root of this repository is `%s'." root)
+ (message "The path `%s' is not in a Mercurial repository."
+ (hg-abbrev-file-name path))))
+ root)
+ hg-root))
+
+(defun hg-cwd (&optional path)
+ "Return the current directory of PATH within the repository."
+ (do ((stack nil (cons (file-name-nondirectory
+ (directory-file-name dir))
+ stack))
+ (prev nil dir)
+ (dir (file-name-directory (or path buffer-file-name
+ (expand-file-name default-directory)))
+ (file-name-directory (directory-file-name dir))))
+ ((equal prev dir))
+ (when (file-directory-p (concat dir ".hg"))
+ (let ((cwd (mapconcat 'identity stack "/")))
+ (unless (equal cwd "")
+ (return (file-name-as-directory cwd)))))))
+
+(defun hg-status (path)
+ "Print revision control status of a file or directory.
+With prefix argument, prompt for the path to give status for.
+Names are displayed relative to the repository root."
+ (interactive (list (hg-read-file-name " for status" (hg-root))))
+ (let ((root (hg-root)))
+ (hg-view-output ((format "Mercurial: Status of %s in %s"
+ (let ((name (substring (expand-file-name path)
+ (length root))))
+ (if (> (length name) 0)
+ name
+ "*"))
+ (hg-abbrev-file-name root)))
+ (apply 'call-process (hg-binary) nil t nil
+ (list "--cwd" root "status" path))
+ (cd (hg-root path)))))
+
+(defun hg-undo ()
+ (interactive)
+ (error "not implemented"))
+
+(defun hg-update ()
+ (interactive)
+ (error "not implemented"))
+
+(defun hg-version-other-window (rev)
+ "Visit version REV of the current file in another window.
+If the current file is named `F', the version is named `F.~REV~'.
+If `F.~REV~' already exists, use it instead of checking it out again."
+ (interactive "sVersion to visit (default is workfile version): ")
+ (let* ((file buffer-file-name)
+ (version (if (string-equal rev "")
+ "tip"
+ rev))
+ (automatic-backup (vc-version-backup-file-name file version))
+ (manual-backup (vc-version-backup-file-name file version 'manual)))
+ (unless (file-exists-p manual-backup)
+ (if (file-exists-p automatic-backup)
+ (rename-file automatic-backup manual-backup nil)
+ (hg-run0 "-q" "cat" "-r" version "-o" manual-backup file)))
+ (find-file-other-window manual-backup)))
+
+
+(provide 'mercurial)
+
+
+;;; Local Variables:
+;;; prompt-to-byte-compile: nil
+;;; end:
diff --git a/sys/src/cmd/hg/contrib/mercurial.spec b/sys/src/cmd/hg/contrib/mercurial.spec
new file mode 100755
index 000000000..3762f5a8e
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/mercurial.spec
@@ -0,0 +1,86 @@
+Summary: Mercurial -- a distributed SCM
+Name: mercurial
+Version: snapshot
+Release: 0
+License: GPLv2
+Group: Development/Tools
+URL: http://mercurial.selenic.com/
+Source0: http://mercurial.selenic.com/release/%{name}-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+
+# From the README:
+#
+# Note: some distributions fails to include bits of distutils by
+# default, you'll need python-dev to install. You'll also need a C
+# compiler and a 3-way merge tool like merge, tkdiff, or kdiff3.
+#
+# python-devel provides an adequate python-dev. The merge tool is a
+# run-time dependency.
+#
+BuildRequires: python >= 2.4, python-devel, make, gcc, asciidoc, xmlto
+Provides: hg = %{version}-%{release}
+
+%define pythonver %(python -c 'import sys;print ".".join(map(str, sys.version_info[:2]))')
+%define emacs_lispdir %{_datadir}/emacs/site-lisp
+
+%description
+Mercurial is a fast, lightweight source control management system designed
+for efficient handling of very large distributed projects.
+
+%prep
+%setup -q
+
+%build
+make all
+
+%install
+rm -rf $RPM_BUILD_ROOT
+python setup.py install --root $RPM_BUILD_ROOT --prefix %{_prefix}
+make install-doc DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir}
+
+install contrib/hgk $RPM_BUILD_ROOT%{_bindir}
+install contrib/convert-repo $RPM_BUILD_ROOT%{_bindir}/mercurial-convert-repo
+install contrib/hg-ssh $RPM_BUILD_ROOT%{_bindir}
+install contrib/git-viz/{hg-viz,git-rev-tree} $RPM_BUILD_ROOT%{_bindir}
+
+bash_completion_dir=$RPM_BUILD_ROOT%{_sysconfdir}/bash_completion.d
+mkdir -p $bash_completion_dir
+install -m 644 contrib/bash_completion $bash_completion_dir/mercurial.sh
+
+zsh_completion_dir=$RPM_BUILD_ROOT%{_datadir}/zsh/site-functions
+mkdir -p $zsh_completion_dir
+install -m 644 contrib/zsh_completion $zsh_completion_dir/_mercurial
+
+mkdir -p $RPM_BUILD_ROOT%{emacs_lispdir}
+install contrib/mercurial.el $RPM_BUILD_ROOT%{emacs_lispdir}
+
+mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/mercurial/hgrc.d
+install contrib/mergetools.hgrc $RPM_BUILD_ROOT%{_sysconfdir}/mercurial/hgrc.d/mergetools.rc
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root,-)
+%doc CONTRIBUTORS COPYING doc/README doc/hg*.txt doc/hg*.html doc/ja *.cgi contrib/*.fcgi
+%doc %attr(644,root,root) %{_mandir}/man?/hg*.gz
+%doc %attr(644,root,root) contrib/*.svg contrib/sample.hgrc
+%{_sysconfdir}/bash_completion.d/mercurial.sh
+%{_datadir}/zsh/site-functions/_mercurial
+%{_datadir}/emacs/site-lisp/mercurial.el
+%{_bindir}/hg
+%{_bindir}/hgk
+%{_bindir}/hg-ssh
+%{_bindir}/hg-viz
+%{_bindir}/git-rev-tree
+%{_bindir}/mercurial-convert-repo
+%dir %{_sysconfdir}/bash_completion.d/
+%dir %{_datadir}/zsh/site-functions/
+%dir %{_sysconfdir}/mercurial
+%dir %{_sysconfdir}/mercurial/hgrc.d
+%config(noreplace) %{_sysconfdir}/mercurial/hgrc.d/mergetools.rc
+%if "%{?pythonver}" != "2.4"
+%{_libdir}/python%{pythonver}/site-packages/%{name}-*-py%{pythonver}.egg-info
+%endif
+%{_libdir}/python%{pythonver}/site-packages/%{name}
+%{_libdir}/python%{pythonver}/site-packages/hgext
diff --git a/sys/src/cmd/hg/contrib/mergetools.hgrc b/sys/src/cmd/hg/contrib/mergetools.hgrc
new file mode 100644
index 000000000..6c90ab732
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/mergetools.hgrc
@@ -0,0 +1,63 @@
+# Some default global settings for common merge tools
+
+[merge-tools]
+kdiff3.args=--auto --L1 base --L2 local --L3 other $base $local $other -o $output
+kdiff3.regkey=Software\KDiff3
+kdiff3.regappend=\kdiff3.exe
+kdiff3.fixeol=True
+kdiff3.gui=True
+
+gvimdiff.args=--nofork -d -g -O $local $other $base
+gvimdiff.regkey=Software\Vim\GVim
+gvimdiff.regname=path
+gvimdiff.priority=-9
+
+merge.checkconflicts=True
+merge.priority=-10
+
+gpyfm.gui=True
+
+meld.gui=True
+
+tkdiff.args=$local $other -a $base -o $output
+tkdiff.gui=True
+tkdiff.priority=-8
+
+xxdiff.args=--show-merged-pane --exit-with-merge-status --title1 local --title2 base --title3 other --merged-filename $output --merge $local $base $other
+xxdiff.gui=True
+xxdiff.priority=-8
+
+diffmerge.args=--nosplash --merge --title1=base --title2=local --title3=other $base $local $other
+diffmerge.checkchanged=True
+diffmerge.gui=True
+
+p4merge.args=$base $local $other $output
+p4merge.regkey=Software\Perforce\Environment
+p4merge.regname=P4INSTROOT
+p4merge.regappend=\p4merge.exe
+p4merge.gui=True
+p4merge.priority=-8
+
+tortoisemerge.args=/base:$base /mine:$local /theirs:$other /merged:$output
+tortoisemerge.regkey=Software\TortoiseSVN
+tortoisemerge.checkchanged=True
+tortoisemerge.gui=True
+
+ecmerge.args=$base $local $other --mode=merge3 --title0=base --title1=local --title2=other --to=$output
+ecmerge.regkey=Software\Elli\xc3\xa9 Computing\Merge
+ecmerge.gui=True
+
+filemerge.executable=/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge
+filemerge.args=-left $other -right $local -ancestor $base -merge $output
+filemerge.gui=True
+
+beyondcompare3.args=$local $other $base $output /ro /lefttitle=local /centertitle=base /righttitle=other /automerge /reviewconflicts /solo
+beyondcompare3.regkey=Software\Scooter Software\Beyond Compare 3
+beyondcompare3.regname=ExePath
+beyondcompare3.gui=True
+
+winmerge.args=/e /u /dl local /dr other /wr $local $other $output
+winmerge.regkey=Software\Thingamahoochie\WinMerge
+winmerge.regname=Executable
+winmerge.checkchanged=True
+winmerge.gui=True
diff --git a/sys/src/cmd/hg/contrib/mq.el b/sys/src/cmd/hg/contrib/mq.el
new file mode 100644
index 000000000..f3d9df4e4
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/mq.el
@@ -0,0 +1,418 @@
+;;; mq.el --- Emacs support for Mercurial Queues
+
+;; Copyright (C) 2006 Bryan O'Sullivan
+
+;; Author: Bryan O'Sullivan <bos@serpentine.com>
+
+;; mq.el is free software; you can redistribute it and/or modify it
+;; under the terms of version 2 of the GNU General Public License as
+;; published by the Free Software Foundation.
+
+;; mq.el is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with mq.el, GNU Emacs, or XEmacs; see the file COPYING (`C-h
+;; C-l'). If not, write to the Free Software Foundation, Inc., 59
+;; Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+(eval-when-compile (require 'cl))
+(require 'mercurial)
+
+
+(defcustom mq-mode-hook nil
+ "Hook run when a buffer enters mq-mode."
+ :type 'sexp
+ :group 'mercurial)
+
+(defcustom mq-global-prefix "\C-cq"
+ "The global prefix for Mercurial Queues keymap bindings."
+ :type 'sexp
+ :group 'mercurial)
+
+(defcustom mq-edit-mode-hook nil
+ "Hook run after a buffer is populated to edit a patch description."
+ :type 'sexp
+ :group 'mercurial)
+
+(defcustom mq-edit-finish-hook nil
+ "Hook run before a patch description is finished up with."
+ :type 'sexp
+ :group 'mercurial)
+
+(defcustom mq-signoff-address nil
+ "Address with which to sign off on a patch."
+ :type 'string
+ :group 'mercurial)
+
+
+;;; Internal variables.
+
+(defvar mq-mode nil
+ "Is this file managed by MQ?")
+(make-variable-buffer-local 'mq-mode)
+(put 'mq-mode 'permanent-local t)
+
+(defvar mq-patch-history nil)
+
+(defvar mq-top-patch '(nil))
+
+(defvar mq-prev-buffer nil)
+(make-variable-buffer-local 'mq-prev-buffer)
+(put 'mq-prev-buffer 'permanent-local t)
+
+(defvar mq-top nil)
+(make-variable-buffer-local 'mq-top)
+(put 'mq-top 'permanent-local t)
+
+;;; Global keymap.
+
+(defvar mq-global-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "." 'mq-push)
+ (define-key map ">" 'mq-push-all)
+ (define-key map "," 'mq-pop)
+ (define-key map "<" 'mq-pop-all)
+ (define-key map "=" 'mq-diff)
+ (define-key map "r" 'mq-refresh)
+ (define-key map "e" 'mq-refresh-edit)
+ (define-key map "i" 'mq-new)
+ (define-key map "n" 'mq-next)
+ (define-key map "o" 'mq-signoff)
+ (define-key map "p" 'mq-previous)
+ (define-key map "s" 'mq-edit-series)
+ (define-key map "t" 'mq-top)
+ map))
+
+(global-set-key mq-global-prefix mq-global-map)
+
+(add-minor-mode 'mq-mode 'mq-mode)
+
+
+;;; Refresh edit mode keymap.
+
+(defvar mq-edit-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-c\C-c" 'mq-edit-finish)
+ (define-key map "\C-c\C-k" 'mq-edit-kill)
+ (define-key map "\C-c\C-s" 'mq-signoff)
+ map))
+
+
+;;; Helper functions.
+
+(defun mq-read-patch-name (&optional source prompt force)
+ "Read a patch name to use with a command.
+May return nil, meaning \"use the default\"."
+ (let ((patches (split-string
+ (hg-chomp (hg-run0 (or source "qseries"))) "\n")))
+ (when force
+ (completing-read (format "Patch%s: " (or prompt ""))
+ (mapcar (lambda (x) (cons x x)) patches)
+ nil
+ nil
+ nil
+ 'mq-patch-history))))
+
+(defun mq-refresh-buffers (root)
+ (save-excursion
+ (dolist (buf (hg-buffers-visiting-repo root))
+ (when (not (verify-visited-file-modtime buf))
+ (set-buffer buf)
+ (let ((ctx (hg-buffer-context)))
+ (message "Refreshing %s..." (buffer-name))
+ (revert-buffer t t t)
+ (hg-restore-context ctx)
+ (message "Refreshing %s...done" (buffer-name))))))
+ (hg-update-mode-lines root)
+ (mq-update-mode-lines root))
+
+(defun mq-last-line ()
+ (goto-char (point-max))
+ (beginning-of-line)
+ (when (looking-at "^$")
+ (forward-line -1))
+ (let ((bol (point)))
+ (end-of-line)
+ (let ((line (buffer-substring bol (point))))
+ (when (> (length line) 0)
+ line))))
+
+(defun mq-push (&optional patch)
+ "Push patches until PATCH is reached.
+If PATCH is nil, push at most one patch."
+ (interactive (list (mq-read-patch-name "qunapplied" " to push"
+ current-prefix-arg)))
+ (let ((root (hg-root))
+ (prev-buf (current-buffer))
+ last-line ok)
+ (unless root
+ (error "Cannot push outside a repository!"))
+ (hg-sync-buffers root)
+ (let ((buf-name (format "MQ: Push %s" (or patch "next patch"))))
+ (kill-buffer (get-buffer-create buf-name))
+ (split-window-vertically)
+ (other-window 1)
+ (switch-to-buffer (get-buffer-create buf-name))
+ (cd root)
+ (message "Pushing...")
+ (setq ok (= 0 (apply 'call-process (hg-binary) nil t t "qpush"
+ (if patch (list patch))))
+ last-line (mq-last-line))
+ (let ((lines (count-lines (point-min) (point-max))))
+ (if (or (<= lines 1)
+ (and (equal lines 2) (string-match "Now at:" last-line)))
+ (progn
+ (kill-buffer (current-buffer))
+ (delete-window))
+ (hg-view-mode prev-buf))))
+ (mq-refresh-buffers root)
+ (sit-for 0)
+ (when last-line
+ (if ok
+ (message "Pushing... %s" last-line)
+ (error "Pushing... %s" last-line)))))
+
+(defun mq-push-all ()
+ "Push patches until all are applied."
+ (interactive)
+ (mq-push "-a"))
+
+(defun mq-pop (&optional patch)
+ "Pop patches until PATCH is reached.
+If PATCH is nil, pop at most one patch."
+ (interactive (list (mq-read-patch-name "qapplied" " to pop to"
+ current-prefix-arg)))
+ (let ((root (hg-root))
+ last-line ok)
+ (unless root
+ (error "Cannot pop outside a repository!"))
+ (hg-sync-buffers root)
+ (set-buffer (generate-new-buffer "qpop"))
+ (cd root)
+ (message "Popping...")
+ (setq ok (= 0 (apply 'call-process (hg-binary) nil t t "qpop"
+ (if patch (list patch))))
+ last-line (mq-last-line))
+ (kill-buffer (current-buffer))
+ (mq-refresh-buffers root)
+ (sit-for 0)
+ (when last-line
+ (if ok
+ (message "Popping... %s" last-line)
+ (error "Popping... %s" last-line)))))
+
+(defun mq-pop-all ()
+ "Push patches until none are applied."
+ (interactive)
+ (mq-pop "-a"))
+
+(defun mq-refresh-internal (root &rest args)
+ (hg-sync-buffers root)
+ (let ((patch (mq-patch-info "qtop")))
+ (message "Refreshing %s..." patch)
+ (let ((ret (apply 'hg-run "qrefresh" args)))
+ (if (equal (car ret) 0)
+ (message "Refreshing %s... done." patch)
+ (error "Refreshing %s... %s" patch (hg-chomp (cdr ret)))))))
+
+(defun mq-refresh (&optional git)
+ "Refresh the topmost applied patch.
+With a prefix argument, generate a git-compatible patch."
+ (interactive "P")
+ (let ((root (hg-root)))
+ (unless root
+ (error "Cannot refresh outside of a repository!"))
+ (apply 'mq-refresh-internal root (if git '("--git")))))
+
+(defun mq-patch-info (cmd &optional msg)
+ (let* ((ret (hg-run cmd))
+ (info (hg-chomp (cdr ret))))
+ (if (equal (car ret) 0)
+ (if msg
+ (message "%s patch: %s" msg info)
+ info)
+ (error "%s" info))))
+
+(defun mq-top ()
+ "Print the name of the topmost applied patch."
+ (interactive)
+ (mq-patch-info "qtop" "Top"))
+
+(defun mq-next ()
+ "Print the name of the next patch to be pushed."
+ (interactive)
+ (mq-patch-info "qnext" "Next"))
+
+(defun mq-previous ()
+ "Print the name of the first patch below the topmost applied patch.
+This would become the active patch if popped to."
+ (interactive)
+ (mq-patch-info "qprev" "Previous"))
+
+(defun mq-edit-finish ()
+ "Finish editing the description of this patch, and refresh the patch."
+ (interactive)
+ (unless (equal (mq-patch-info "qtop") mq-top)
+ (error "Topmost patch has changed!"))
+ (hg-sync-buffers hg-root)
+ (run-hooks 'mq-edit-finish-hook)
+ (mq-refresh-internal hg-root "-m" (buffer-substring (point-min) (point-max)))
+ (let ((buf mq-prev-buffer))
+ (kill-buffer nil)
+ (switch-to-buffer buf)))
+
+(defun mq-edit-kill ()
+ "Kill the edit currently being prepared."
+ (interactive)
+ (when (or (not (buffer-modified-p)) (y-or-n-p "Really kill this edit? "))
+ (let ((buf mq-prev-buffer))
+ (kill-buffer nil)
+ (switch-to-buffer buf))))
+
+(defun mq-get-top (root)
+ (let ((entry (assoc root mq-top-patch)))
+ (if entry
+ (cdr entry))))
+
+(defun mq-set-top (root patch)
+ (let ((entry (assoc root mq-top-patch)))
+ (if entry
+ (if patch
+ (setcdr entry patch)
+ (setq mq-top-patch (delq entry mq-top-patch)))
+ (setq mq-top-patch (cons (cons root patch) mq-top-patch)))))
+
+(defun mq-update-mode-lines (root)
+ (let ((cwd default-directory))
+ (cd root)
+ (condition-case nil
+ (mq-set-top root (mq-patch-info "qtop"))
+ (error (mq-set-top root nil)))
+ (cd cwd))
+ (let ((patch (mq-get-top root)))
+ (save-excursion
+ (dolist (buf (hg-buffers-visiting-repo root))
+ (set-buffer buf)
+ (if mq-mode
+ (setq mq-mode (or (and patch (concat " MQ:" patch)) " MQ")))))))
+
+(defun mq-mode (&optional arg)
+ "Minor mode for Mercurial repositories with an MQ patch queue"
+ (interactive "i")
+ (cond ((hg-root)
+ (setq mq-mode (if (null arg) (not mq-mode)
+ arg))
+ (mq-update-mode-lines (hg-root))))
+ (run-hooks 'mq-mode-hook))
+
+(defun mq-edit-mode ()
+ "Mode for editing the description of a patch.
+
+Key bindings
+------------
+\\[mq-edit-finish] use this description
+\\[mq-edit-kill] abandon this description"
+ (interactive)
+ (use-local-map mq-edit-mode-map)
+ (set-syntax-table text-mode-syntax-table)
+ (setq local-abbrev-table text-mode-abbrev-table
+ major-mode 'mq-edit-mode
+ mode-name "MQ-Edit")
+ (set-buffer-modified-p nil)
+ (setq buffer-undo-list nil)
+ (run-hooks 'text-mode-hook 'mq-edit-mode-hook))
+
+(defun mq-refresh-edit ()
+ "Refresh the topmost applied patch, editing the patch description."
+ (interactive)
+ (while mq-prev-buffer
+ (set-buffer mq-prev-buffer))
+ (let ((root (hg-root))
+ (prev-buffer (current-buffer))
+ (patch (mq-patch-info "qtop")))
+ (hg-sync-buffers root)
+ (let ((buf-name (format "*MQ: Edit description of %s*" patch)))
+ (switch-to-buffer (get-buffer-create buf-name))
+ (when (= (point-min) (point-max))
+ (set (make-local-variable 'hg-root) root)
+ (set (make-local-variable 'mq-top) patch)
+ (setq mq-prev-buffer prev-buffer)
+ (insert (hg-run0 "qheader"))
+ (goto-char (point-min)))
+ (mq-edit-mode)
+ (cd root)))
+ (message "Type `C-c C-c' to finish editing and refresh the patch."))
+
+(defun mq-new (name)
+ "Create a new empty patch named NAME.
+The patch is applied on top of the current topmost patch.
+With a prefix argument, forcibly create the patch even if the working
+directory is modified."
+ (interactive (list (mq-read-patch-name "qseries" " to create" t)))
+ (message "Creating patch...")
+ (let ((ret (if current-prefix-arg
+ (hg-run "qnew" "-f" name)
+ (hg-run "qnew" name))))
+ (if (equal (car ret) 0)
+ (progn
+ (hg-update-mode-lines (buffer-file-name))
+ (message "Creating patch... done."))
+ (error "Creating patch... %s" (hg-chomp (cdr ret))))))
+
+(defun mq-edit-series ()
+ "Edit the MQ series file directly."
+ (interactive)
+ (let ((root (hg-root)))
+ (unless root
+ (error "Not in an MQ repository!"))
+ (find-file (concat root ".hg/patches/series"))))
+
+(defun mq-diff (&optional git)
+ "Display a diff of the topmost applied patch.
+With a prefix argument, display a git-compatible diff."
+ (interactive "P")
+ (hg-view-output ((format "MQ: Diff of %s" (mq-patch-info "qtop")))
+ (if git
+ (call-process (hg-binary) nil t nil "qdiff" "--git")
+ (call-process (hg-binary) nil t nil "qdiff"))
+ (diff-mode)
+ (font-lock-fontify-buffer)))
+
+(defun mq-signoff ()
+ "Sign off on the current patch, in the style used by the Linux kernel.
+If the variable mq-signoff-address is non-nil, it will be used, otherwise
+the value of the ui.username item from your hgrc will be used."
+ (interactive)
+ (let ((was-editing (eq major-mode 'mq-edit-mode))
+ signed)
+ (unless was-editing
+ (mq-refresh-edit))
+ (save-excursion
+ (let* ((user (or mq-signoff-address
+ (hg-run0 "debugconfig" "ui.username")))
+ (signoff (concat "Signed-off-by: " user)))
+ (if (search-forward signoff nil t)
+ (message "You have already signed off on this patch.")
+ (goto-char (point-max))
+ (let ((case-fold-search t))
+ (if (re-search-backward "^Signed-off-by: " nil t)
+ (forward-line 1)
+ (insert "\n")))
+ (insert signoff)
+ (message "%s" signoff)
+ (setq signed t))))
+ (unless was-editing
+ (if signed
+ (mq-edit-finish)
+ (mq-edit-kill)))))
+
+
+(provide 'mq)
+
+
+;;; Local Variables:
+;;; prompt-to-byte-compile: nil
+;;; end:
diff --git a/sys/src/cmd/hg/contrib/perf.py b/sys/src/cmd/hg/contrib/perf.py
new file mode 100644
index 000000000..3da83d60c
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/perf.py
@@ -0,0 +1,131 @@
+# perf.py - performance test routines
+'''helper extension to measure performance'''
+
+from mercurial import cmdutil, match, commands
+import time, os, sys
+
+def timer(func):
+ results = []
+ begin = time.time()
+ count = 0
+ while 1:
+ ostart = os.times()
+ cstart = time.time()
+ r = func()
+ cstop = time.time()
+ ostop = os.times()
+ count += 1
+ a, b = ostart, ostop
+ results.append((cstop - cstart, b[0] - a[0], b[1]-a[1]))
+ if cstop - begin > 3 and count >= 100:
+ break
+ if cstop - begin > 10 and count >= 3:
+ break
+ if r:
+ sys.stderr.write("! result: %s\n" % r)
+ m = min(results)
+ sys.stderr.write("! wall %f comb %f user %f sys %f (best of %d)\n"
+ % (m[0], m[1] + m[2], m[1], m[2], count))
+
+def perfwalk(ui, repo, *pats):
+ try:
+ m = cmdutil.match(repo, pats, {})
+ timer(lambda: len(list(repo.dirstate.walk(m, True, False))))
+ except:
+ try:
+ m = cmdutil.match(repo, pats, {})
+ timer(lambda: len([b for a,b,c in repo.dirstate.statwalk([], m)]))
+ except:
+ timer(lambda: len(list(cmdutil.walk(repo, pats, {}))))
+
+def perfstatus(ui, repo, *pats):
+ #m = match.always(repo.root, repo.getcwd())
+ #timer(lambda: sum(map(len, repo.dirstate.status(m, False, False, False))))
+ timer(lambda: sum(map(len, repo.status())))
+
+def perfheads(ui, repo):
+ timer(lambda: len(repo.changelog.heads()))
+
+def perftags(ui, repo):
+ import mercurial.changelog, mercurial.manifest
+ def t():
+ repo.changelog = mercurial.changelog.changelog(repo.sopener)
+ repo.manifest = mercurial.manifest.manifest(repo.sopener)
+ repo._tags = None
+ return len(repo.tags())
+ timer(t)
+
+def perfdirstate(ui, repo):
+ "a" in repo.dirstate
+ def d():
+ repo.dirstate.invalidate()
+ "a" in repo.dirstate
+ timer(d)
+
+def perfdirstatedirs(ui, repo):
+ "a" in repo.dirstate
+ def d():
+ "a" in repo.dirstate._dirs
+ del repo.dirstate._dirs
+ timer(d)
+
+def perfmanifest(ui, repo):
+ def d():
+ t = repo.manifest.tip()
+ m = repo.manifest.read(t)
+ repo.manifest.mapcache = None
+ repo.manifest._cache = None
+ timer(d)
+
+def perfindex(ui, repo):
+ import mercurial.changelog
+ def d():
+ t = repo.changelog.tip()
+ repo.changelog = mercurial.changelog.changelog(repo.sopener)
+ repo.changelog._loadindexmap()
+ timer(d)
+
+def perfstartup(ui, repo):
+ cmd = sys.argv[0]
+ def d():
+ os.system("HGRCPATH= %s version -q > /dev/null" % cmd)
+ timer(d)
+
+def perfparents(ui, repo):
+ nl = [repo.changelog.node(i) for i in xrange(1000)]
+ def d():
+ for n in nl:
+ repo.changelog.parents(n)
+ timer(d)
+
+def perflookup(ui, repo, rev):
+ timer(lambda: len(repo.lookup(rev)))
+
+def perflog(ui, repo):
+ ui.pushbuffer()
+ timer(lambda: commands.log(ui, repo, rev=[], date='', user=''))
+ ui.popbuffer()
+
+def perftemplating(ui, repo):
+ ui.pushbuffer()
+ timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
+ template='{date|shortdate} [{rev}:{node|short}]'
+ ' {author|person}: {desc|firstline}\n'))
+ ui.popbuffer()
+
+cmdtable = {
+ 'perflookup': (perflookup, []),
+ 'perfparents': (perfparents, []),
+ 'perfstartup': (perfstartup, []),
+ 'perfstatus': (perfstatus, []),
+ 'perfwalk': (perfwalk, []),
+ 'perfmanifest': (perfmanifest, []),
+ 'perfindex': (perfindex, []),
+ 'perfheads': (perfheads, []),
+ 'perftags': (perftags, []),
+ 'perfdirstate': (perfdirstate, []),
+ 'perfdirstatedirs': (perfdirstate, []),
+ 'perflog': (perflog, []),
+ 'perftemplating': (perftemplating, []),
+}
+
diff --git a/sys/src/cmd/hg/contrib/python-hook-examples.py b/sys/src/cmd/hg/contrib/python-hook-examples.py
new file mode 100644
index 000000000..54fb7d348
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/python-hook-examples.py
@@ -0,0 +1,22 @@
+'''
+Examples of useful python hooks for Mercurial.
+'''
+from mercurial import patch, util
+
+def diffstat(ui, repo, **kwargs):
+ '''Example usage:
+
+ [hooks]
+ commit.diffstat = python:/path/to/this/file.py:diffstat
+ changegroup.diffstat = python:/path/to/this/file.py:diffstat
+ '''
+ if kwargs.get('parent2'):
+ return
+ node = kwargs['node']
+ first = repo[node].parents()[0].node()
+ if 'url' in kwargs:
+ last = repo['tip'].node()
+ else:
+ last = node
+ diff = patch.diff(repo, first, last)
+ ui.write(patch.diffstat(util.iterlines(diff)))
diff --git a/sys/src/cmd/hg/contrib/rewrite-log b/sys/src/cmd/hg/contrib/rewrite-log
new file mode 100755
index 000000000..885a32017
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/rewrite-log
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+import sys, os
+from mercurial import revlog, transaction, node, util
+
+f = sys.argv[1]
+
+r1 = revlog.revlog(util.opener(os.getcwd(), audit=False), f + ".i", f + ".d")
+r2 = revlog.revlog(util.opener(os.getcwd(), audit=False), f + ".i2", f + ".d2")
+
+tr = transaction.transaction(sys.stderr.write, open, "journal")
+
+for i in xrange(r1.count()):
+ n = r1.node(i)
+ p1, p2 = r1.parents(n)
+ l = r1.linkrev(n)
+ t = r1.revision(n)
+ n2 = r2.addrevision(t, tr, l, p1, p2)
+tr.close()
+
+os.rename(f + ".i", f + ".i.old")
+os.rename(f + ".d", f + ".d.old")
+os.rename(f + ".i2", f + ".i")
+os.rename(f + ".d2", f + ".d")
diff --git a/sys/src/cmd/hg/contrib/sample.hgrc b/sys/src/cmd/hg/contrib/sample.hgrc
new file mode 100644
index 000000000..6a0d403dc
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/sample.hgrc
@@ -0,0 +1,133 @@
+### --- User interface
+
+[ui]
+
+### show changed files and be a bit more verbose if True
+
+# verbose = True
+
+### username data to appear in comits
+### it usually takes the form: Joe User <joe.user@host.com>
+
+# username = Joe User <j.user@example.com>
+
+### --- Extensions
+
+[extensions]
+
+### each extension has its own 'extension_name=path' line
+### the default python library path is used when path is left blank
+### the hgext dir is used when 'hgext.extension_name=' is written
+
+### acl - Access control lists
+### hg help acl
+
+# hgext.acl =
+
+### bisect - binary search changesets to detect bugs
+### hg help bisect
+
+# hgext.hbisect =
+
+### bugzilla - update bugzilla bugs when changesets mention them
+### hg help bugzilla
+
+# hgext.bugzilla =
+
+### extdiff - Use external diff application instead of builtin one
+
+# hgext.extdiff =
+
+### gpg - GPG checks and signing
+### hg help gpg
+
+# hgext.gpg =
+
+### graphlog - ASCII graph log
+### hg help glog
+
+# hgext.graphlog =
+
+### hgk - GUI repository browser
+### hg help view
+
+# hgext.hgk =
+
+### mq - Mercurial patch queues
+### hg help mq
+
+# hgext.mq =
+
+### notify - Template driven e-mail notifications
+### hg help notify
+
+# hgext.notify =
+
+### patchbomb - send changesets as a series of patch emails
+### hg help email
+
+# hgext.patchbomb =
+
+### churn - create a graph showing who changed the most lines
+### hg help churn
+
+# hgext.churn = /home/user/hg/hg/contrib/churn.py
+
+### win32text - line ending conversion filters for the Windows platform
+
+# hgext.win32text =
+
+### --- hgk additional configuration
+
+[hgk]
+
+### set executable path
+
+# path = /home/user/hg/hg/contrib/hgk
+
+### --- Hook to Mercurial actions - See hgrc man page for avaliable hooks
+
+[hooks]
+
+### Example notify hooks (load hgext.notify extension before use)
+
+# incoming.notify = python:hgext.notify.hook
+# changegroup.notify = python:hgext.notify.hook
+
+### Email configuration for the notify and patchbomb extensions
+
+[email]
+
+### Your email address
+
+# from = user@example.com
+
+### Method to send email - smtp or /usr/sbin/sendmail or other program name
+
+# method = smtp
+
+### smtp server to send email to
+
+[smtp]
+
+# host = mail
+# port = 25
+# tls = false
+# username = user
+# password = blivet
+# local_hostname = myhost
+
+### --- Email notification hook for server
+
+[notify]
+### multiple sources can be specified as a whitespace or comma separated list
+
+# sources = serve push pull bundle
+
+### set this to False when you're ready for mail to start sending
+
+# test = True
+
+### path to config file with names of subscribers
+
+# config = /path/to/subscription/file
diff --git a/sys/src/cmd/hg/contrib/simplemerge b/sys/src/cmd/hg/contrib/simplemerge
new file mode 100755
index 000000000..3a0897f5a
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/simplemerge
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+
+from mercurial import demandimport
+demandimport.enable()
+
+import os, sys
+from mercurial.i18n import _
+from mercurial import simplemerge, fancyopts, util, ui
+
+options = [('L', 'label', [], _('labels to use on conflict markers')),
+ ('a', 'text', None, _('treat all files as text')),
+ ('p', 'print', None,
+ _('print results instead of overwriting LOCAL')),
+ ('', 'no-minimal', None,
+ _('do not try to minimize conflict regions')),
+ ('h', 'help', None, _('display help and exit')),
+ ('q', 'quiet', None, _('suppress output'))]
+
+usage = _('''simplemerge [OPTS] LOCAL BASE OTHER
+
+ Simple three-way file merge utility with a minimal feature set.
+
+ Apply to LOCAL the changes necessary to go from BASE to OTHER.
+
+ By default, LOCAL is overwritten with the results of this operation.
+''')
+
+class ParseError(Exception):
+ """Exception raised on errors in parsing the command line."""
+
+def showhelp():
+ sys.stdout.write(usage)
+ sys.stdout.write('\noptions:\n')
+
+ out_opts = []
+ for shortopt, longopt, default, desc in options:
+ out_opts.append(('%2s%s' % (shortopt and '-%s' % shortopt,
+ longopt and ' --%s' % longopt),
+ '%s' % desc))
+ opts_len = max([len(opt[0]) for opt in out_opts])
+ for first, second in out_opts:
+ sys.stdout.write(' %-*s %s\n' % (opts_len, first, second))
+
+try:
+ for fp in (sys.stdin, sys.stdout, sys.stderr):
+ util.set_binary(fp)
+
+ opts = {}
+ try:
+ args = fancyopts.fancyopts(sys.argv[1:], options, opts)
+ except fancyopts.getopt.GetoptError, e:
+ raise ParseError(e)
+ if opts['help']:
+ showhelp()
+ sys.exit(0)
+ if len(args) != 3:
+ raise ParseError(_('wrong number of arguments'))
+ sys.exit(simplemerge.simplemerge(ui.ui(), *args, **opts))
+except ParseError, e:
+ sys.stdout.write("%s: %s\n" % (sys.argv[0], e))
+ showhelp()
+ sys.exit(1)
+except util.Abort, e:
+ sys.stderr.write("abort: %s\n" % e)
+ sys.exit(255)
+except KeyboardInterrupt:
+ sys.exit(255)
diff --git a/sys/src/cmd/hg/contrib/tcsh_completion b/sys/src/cmd/hg/contrib/tcsh_completion
new file mode 100644
index 000000000..cf4133d54
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/tcsh_completion
@@ -0,0 +1,49 @@
+#
+# tcsh completion for Mercurial
+#
+# This file has been auto-generated by tcsh_completion_build.sh for
+# Mercurial Distributed SCM (version 1.1.2)
+#
+# Copyright (C) 2005 TK Soh.
+#
+# This is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+
+complete hg \
+ 'n/--cwd/d/' 'n/-R/d/' 'n/--repository/d/' \
+ 'C/-/( -R --repository \
+ --cwd \
+ -y --noninteractive \
+ -q --quiet \
+ -v --verbose \
+ --config \
+ --debug \
+ --debugger \
+ --encoding \
+ --encodingmode \
+ --lsprof \
+ --traceback \
+ --time \
+ --profile \
+ --version \
+ -h --help)/' \
+ 'p/1/(add addremove annotate blame archive \
+ backout bisect branch branches bundle \
+ cat clone commit ci copy \
+ cp debugancestor debugcheckstate debugcomplete debugdata \
+ debugdate debugfsinfo debugindex debugindexdot debuginstall \
+ debugrawcommit rawcommit debugrebuildstate debugrename debugsetparents \
+ debugstate debugwalk diff export grep \
+ heads help identify id import \
+ patch incoming in init locate \
+ log history manifest merge outgoing \
+ out parents paths pull push \
+ recover remove rm rename mv \
+ resolve revert rollback root serve \
+ showconfig debugconfig status st tag \
+ tags tip unbundle update up \
+ checkout co verify version)/'
+
diff --git a/sys/src/cmd/hg/contrib/tcsh_completion_build.sh b/sys/src/cmd/hg/contrib/tcsh_completion_build.sh
new file mode 100755
index 000000000..8b83f30e1
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/tcsh_completion_build.sh
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+#
+# tcsh_completion_build.sh - script to generate tcsh completion
+#
+#
+# Copyright (C) 2005 TK Soh.
+#
+# This is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+#
+# Description
+# -----------
+# This script generates a tcsh source file to support completion
+# of Mercurial commands and options.
+#
+# Instruction:
+# -----------
+# Run this script to generate the tcsh source file, and source
+# the file to add command completion support for Mercurial.
+#
+# tcsh% tcsh_completion.sh FILE
+# tcsh% source FILE
+#
+# If FILE is not specified, tcsh_completion will be generated.
+#
+# Bugs:
+# ----
+# 1. command specific options are not supported
+# 2. hg commands must be specified immediately after 'hg'.
+#
+
+tcsh_file=${1-tcsh_completion}
+
+hg_commands=`hg --debug help | \
+ sed -e '1,/^list of commands:/d' \
+ -e '/^enabled extensions:/,$d' \
+ -e '/^ [^ ]/!d; s/[,:]//g;' | \
+ xargs -n5 | \
+ sed -e '$!s/$/ \\\\/g; 2,$s/^ */ /g'`
+
+hg_global_options=`hg -v help | \
+ sed -e '1,/global/d;/^ *-/!d; s/ [^- ].*//' | \
+ sed -e 's/ *$//; $!s/$/ \\\\/g; 2,$s/^ */ /g'`
+
+hg_version=`hg version | sed -e '1q'`
+
+script_name=`basename $0`
+
+cat > $tcsh_file <<END
+#
+# tcsh completion for Mercurial
+#
+# This file has been auto-generated by $script_name for
+# $hg_version
+#
+# Copyright (C) 2005 TK Soh.
+#
+# This is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+
+complete hg \\
+ 'n/--cwd/d/' 'n/-R/d/' 'n/--repository/d/' \\
+ 'C/-/($hg_global_options)/' \\
+ 'p/1/($hg_commands)/'
+
+END
diff --git a/sys/src/cmd/hg/contrib/tmplrewrite.py b/sys/src/cmd/hg/contrib/tmplrewrite.py
new file mode 100755
index 000000000..eb1600328
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/tmplrewrite.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+import sys, os, re
+
+IGNORE = ['.css', '.py']
+oldre = re.compile('#([\w\|%]+)#')
+
+def rewrite(fn):
+ f = open(fn)
+ new = open(fn + '.new', 'wb')
+ for ln in f:
+ new.write(oldre.sub('{\\1}', ln))
+ new.close()
+ f.close()
+ os.rename(new.name, f.name)
+
+if __name__ == '__main__':
+ if len(sys.argv) < 2:
+ print 'usage: python tmplrewrite.py [file [file [file]]]'
+ for fn in sys.argv[1:]:
+ if os.path.splitext(fn) in IGNORE:
+ continue
+ print 'rewriting %s...' % fn
+ rewrite(fn)
diff --git a/sys/src/cmd/hg/contrib/undumprevlog b/sys/src/cmd/hg/contrib/undumprevlog
new file mode 100644
index 000000000..dd796b83c
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/undumprevlog
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# Undump a dump from dumprevlog
+# $ hg init
+# $ undumprevlog < repo.dump
+
+import sys
+from mercurial import revlog, node, util, transaction
+
+for fp in (sys.stdin, sys.stdout, sys.stderr):
+ util.set_binary(fp)
+
+opener = util.opener('.', False)
+tr = transaction.transaction(sys.stderr.write, opener, "undump.journal")
+while 1:
+ l = sys.stdin.readline()
+ if not l:
+ break
+ if l.startswith("file:"):
+ f = l[6:-1]
+ r = revlog.revlog(opener, f)
+ print f
+ elif l.startswith("node:"):
+ n = node.bin(l[6:-1])
+ elif l.startswith("linkrev:"):
+ lr = int(l[9:-1])
+ elif l.startswith("parents:"):
+ p = l[9:-1].split()
+ p1 = node.bin(p[0])
+ p2 = node.bin(p[1])
+ elif l.startswith("length:"):
+ length = int(l[8:-1])
+ sys.stdin.readline() # start marker
+ d = sys.stdin.read(length)
+ sys.stdin.readline() # end marker
+ r.addrevision(d, tr, lr, p1, p2)
+
+tr.close()
diff --git a/sys/src/cmd/hg/contrib/vim/HGAnnotate.vim b/sys/src/cmd/hg/contrib/vim/HGAnnotate.vim
new file mode 100644
index 000000000..5b5ab957e
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/vim/HGAnnotate.vim
@@ -0,0 +1,27 @@
+" $Id: CVSAnnotate.vim,v 1.5 2002/10/01 21:34:02 rhiestan Exp $
+" Vim syntax file
+" Language: CVS annotate output
+" Maintainer: Bob Hiestand <bob@hiestandfamily.org>
+" Last Change: $Date: 2002/10/01 21:34:02 $
+" Remark: Used by the cvscommand plugin. Originally written by Mathieu
+" Clabaut
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+syn match cvsDate /\S\S\S \S\+ \d\+ \d\+:\d\+:\d\+ \d\+ [+-]\?\d\+/ contained
+syn match cvsName /^\s*\S\+ / contained nextgroup=cvsVer
+syn match cvsVer /\d\+ / contained nextgroup=cvsDate
+syn region cvsHead start="^" end=":" contains=cvsVer,cvsName,cvsDate
+
+if !exists("did_cvsannotate_syntax_inits")
+let did_cvsannotate_syntax_inits = 1
+hi link cvsText String
+hi link cvsDate Comment
+hi link cvsName Type
+hi link cvsVer Statement
+endif
+
+let b:current_syntax="CVSAnnotate"
diff --git a/sys/src/cmd/hg/contrib/vim/hg-menu.vim b/sys/src/cmd/hg/contrib/vim/hg-menu.vim
new file mode 100644
index 000000000..1664ecb10
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/vim/hg-menu.vim
@@ -0,0 +1,93 @@
+" vim600: set foldmethod=marker:
+" =============================================================================
+" Name Of File: hg-menu.vim
+" Description: Interface to Mercurial Version Control.
+" Author: Steve Borho (modified Jeff Lanzarotta's RCS script)
+" Date: Wednesday, October 5, 2005
+" Version: 0.1.0
+" Copyright: None.
+" Usage: These command and gui menu displays useful hg functions
+" Configuration: Your hg executable must be in your path.
+" =============================================================================
+
+" Section: Init {{{1
+if exists("loaded_hg_menu")
+ finish
+endif
+let loaded_hg_menu = 1
+
+" Section: Menu Options {{{1
+if has("gui")
+" amenu H&G.Commit\ File<Tab>,ci :!hg commit %<CR>:e!<CR>
+" amenu H&G.Commit\ All<Tab>,call :!hg commit<CR>:e!<CR>
+" amenu H&G.-SEP1- <nul>
+ amenu H&G.Add<Tab>\\add :!hg add %<CR><CR>
+ amenu H&G.Forget\ Add<Tab>\\fgt :!hg forget %<CR><CR>
+ amenu H&G.Show\ Differences<Tab>\\diff :call ShowResults("FileDiff", "hg\ diff")<CR><CR>
+ amenu H&G.Revert\ to\ Last\ Version<Tab>\\revert :!hg revert %<CR>:e!<CR>
+ amenu H&G.Show\ History<Tab>\\log :call ShowResults("FileLog", "hg\ log")<CR><CR>
+ amenu H&G.Annotate<Tab>\\an :call ShowResults("annotate", "hg\ annotate")<CR><CR>
+ amenu H&G.-SEP1- <nul>
+ amenu H&G.Repo\ Status<Tab>\\stat :call ShowResults("RepoStatus", "hg\ status")<CR><CR>
+ amenu H&G.Pull<Tab>\\pull :!hg pull<CR>:e!<CR>
+ amenu H&G.Update<Tab>\\upd :!hg update<CR>:e!<CR>
+endif
+
+" Section: Mappings {{{1
+if(v:version >= 600)
+ " The default Leader is \ 'backslash'
+ map <Leader>add :!hg add %<CR><CR>
+ map <Leader>fgt :!hg forget %<CR><CR>
+ map <Leader>diff :call ShowResults("FileDiff", "hg\ diff")<CR><CR>
+ map <Leader>revert :!hg revert %<CR>:e!<CR>
+ map <Leader>log :call ShowResults("FileLog", "hg\ log")<CR><CR>
+ map <Leader>an :call ShowResults("annotate", "hg\ annotate")<CR><CR>
+ map <Leader>stat :call ShowResults("RepoStatus", "hg\ status")<CR><CR>
+ map <Leader>upd :!hg update<CR>:e!<CR>
+ map <Leader>pull :!hg pull<CR>:e!<CR>
+else
+ " pre 6.0, the default Leader was a comma
+ map ,add :!hg add %<CR><CR>
+ map ,fgt :!hg forget %<CR><CR>
+ map ,diff :call ShowResults("FileDiff", "hg\ diff")<CR><CR>
+ map ,revert :!hg revert<CR>:e!<CR>
+ map ,log :call ShowResults("FileLog", "hg\ log")<CR><CR>
+ map ,an :call ShowResults("annotate", "hg\ annotate")<CR><CR>
+ map ,stat :call ShowResults("RepoStatus", "hg\ status")<CR><CR>
+ map ,upd :!hg update<CR>:e!<CR>
+ map ,pull :!hg pull<CR>:e!<CR>
+endif
+
+" Section: Functions {{{1
+" Show the log results of the current file with a revision control system.
+function! ShowResults(bufferName, cmdName)
+ " Modify the shortmess option:
+ " A don't give the "ATTENTION" message when an existing swap file is
+ " found.
+ set shortmess+=A
+
+ " Get the name of the current buffer.
+ let currentBuffer = bufname("%")
+
+ " If a buffer with the name rlog exists, delete it.
+ if bufexists(a:bufferName)
+ execute 'bd! ' a:bufferName
+ endif
+
+ " Create a new buffer.
+ execute 'new ' a:bufferName
+
+ " Execute the command.
+ execute 'r!' a:cmdName ' ' currentBuffer
+
+ " Make is so that the file can't be edited.
+ setlocal nomodified
+ setlocal nomodifiable
+ setlocal readonly
+
+ " Go to the beginning of the buffer.
+ execute "normal 1G"
+
+ " Restore the shortmess option.
+ set shortmess-=A
+endfunction
diff --git a/sys/src/cmd/hg/contrib/vim/hgcommand.vim b/sys/src/cmd/hg/contrib/vim/hgcommand.vim
new file mode 100644
index 000000000..9cbb579c9
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/vim/hgcommand.vim
@@ -0,0 +1,1703 @@
+" vim600: set foldmethod=marker:
+"
+" Vim plugin to assist in working with HG-controlled files.
+"
+" Last Change: 2006/02/22
+" Version: 1.77
+" Maintainer: Mathieu Clabaut <mathieu.clabaut@gmail.com>
+" License: This file is placed in the public domain.
+" Credits:
+" Bob Hiestand <bob.hiestand@gmail.com> for the fabulous
+" cvscommand.vim from which this script was directly created by
+" means of sed commands and minor tweaks.
+" Note:
+" For Vim7 the use of Bob Hiestand's vcscommand.vim
+" <http://www.vim.org/scripts/script.php?script_id=90>
+" in conjunction with Vladmir Marek's Hg backend
+" <http://www.vim.org/scripts/script.php?script_id=1898>
+" is recommended.
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Section: Documentation
+"----------------------------
+"
+" Documentation should be available by ":help hgcommand" command, once the
+" script has been copied in you .vim/plugin directory.
+"
+" You still can read the documentation at the end of this file. Locate it by
+" searching the "hgcommand-contents" string (and set ft=help to have
+" appropriate syntaxic coloration).
+
+" Section: Plugin header {{{1
+
+" loaded_hgcommand is set to 1 when the initialization begins, and 2 when it
+" completes. This allows various actions to only be taken by functions after
+" system initialization.
+
+if exists("g:loaded_hgcommand")
+ finish
+endif
+let g:loaded_hgcommand = 1
+
+" store 'compatible' settings
+let s:save_cpo = &cpo
+set cpo&vim
+
+" run checks
+let s:script_name = expand("<sfile>:t:r")
+
+function! s:HGCleanupOnFailure(err)
+ echohl WarningMsg
+ echomsg s:script_name . ":" a:err "Plugin not loaded"
+ echohl None
+ let g:loaded_hgcommand = "no"
+ unlet s:save_cpo s:script_name
+endfunction
+
+if v:version < 602
+ call <SID>HGCleanupOnFailure("VIM 6.2 or later required.")
+ finish
+endif
+
+if !exists("*system")
+ call <SID>HGCleanupOnFailure("builtin system() function required.")
+ finish
+endif
+
+let s:script_version = "v0.2"
+
+" Section: Event group setup {{{1
+
+augroup HGCommand
+augroup END
+
+" Section: Plugin initialization {{{1
+silent do HGCommand User HGPluginInit
+
+" Section: Script variable initialization {{{1
+
+let s:HGCommandEditFileRunning = 0
+unlet! s:vimDiffRestoreCmd
+unlet! s:vimDiffSourceBuffer
+unlet! s:vimDiffBufferCount
+unlet! s:vimDiffScratchList
+
+" Section: Utility functions {{{1
+
+" Function: s:HGResolveLink() {{{2
+" Fully resolve the given file name to remove shortcuts or symbolic links.
+
+function! s:HGResolveLink(fileName)
+ let resolved = resolve(a:fileName)
+ if resolved != a:fileName
+ let resolved = <SID>HGResolveLink(resolved)
+ endif
+ return resolved
+endfunction
+
+" Function: s:HGChangeToCurrentFileDir() {{{2
+" Go to the directory in which the current HG-controlled file is located.
+" If this is a HG command buffer, first switch to the original file.
+
+function! s:HGChangeToCurrentFileDir(fileName)
+ let oldCwd=getcwd()
+ let fileName=<SID>HGResolveLink(a:fileName)
+ let newCwd=fnamemodify(fileName, ':h')
+ if strlen(newCwd) > 0
+ execute 'cd' escape(newCwd, ' ')
+ endif
+ return oldCwd
+endfunction
+
+" Function: <SID>HGGetOption(name, default) {{{2
+" Grab a user-specified option to override the default provided. Options are
+" searched in the window, buffer, then global spaces.
+
+function! s:HGGetOption(name, default)
+ if exists("s:" . a:name . "Override")
+ execute "return s:".a:name."Override"
+ elseif exists("w:" . a:name)
+ execute "return w:".a:name
+ elseif exists("b:" . a:name)
+ execute "return b:".a:name
+ elseif exists("g:" . a:name)
+ execute "return g:".a:name
+ else
+ return a:default
+ endif
+endfunction
+
+" Function: s:HGEditFile(name, origBuffNR) {{{2
+" Wrapper around the 'edit' command to provide some helpful error text if the
+" current buffer can't be abandoned. If name is provided, it is used;
+" otherwise, a nameless scratch buffer is used.
+" Returns: 0 if successful, -1 if an error occurs.
+
+function! s:HGEditFile(name, origBuffNR)
+ "Name parameter will be pasted into expression.
+ let name = escape(a:name, ' *?\')
+
+ let editCommand = <SID>HGGetOption('HGCommandEdit', 'edit')
+ if editCommand != 'edit'
+ if <SID>HGGetOption('HGCommandSplit', 'horizontal') == 'horizontal'
+ if name == ""
+ let editCommand = 'rightbelow new'
+ else
+ let editCommand = 'rightbelow split ' . name
+ endif
+ else
+ if name == ""
+ let editCommand = 'vert rightbelow new'
+ else
+ let editCommand = 'vert rightbelow split ' . name
+ endif
+ endif
+ else
+ if name == ""
+ let editCommand = 'enew'
+ else
+ let editCommand = 'edit ' . name
+ endif
+ endif
+
+ " Protect against useless buffer set-up
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1
+ try
+ execute editCommand
+ finally
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1
+ endtry
+
+ let b:HGOrigBuffNR=a:origBuffNR
+ let b:HGCommandEdit='split'
+endfunction
+
+" Function: s:HGCreateCommandBuffer(cmd, cmdName, statusText, filename) {{{2
+" Creates a new scratch buffer and captures the output from execution of the
+" given command. The name of the scratch buffer is returned.
+
+function! s:HGCreateCommandBuffer(cmd, cmdName, statusText, origBuffNR)
+ let fileName=bufname(a:origBuffNR)
+
+ let resultBufferName=''
+
+ if <SID>HGGetOption("HGCommandNameResultBuffers", 0)
+ let nameMarker = <SID>HGGetOption("HGCommandNameMarker", '_')
+ if strlen(a:statusText) > 0
+ let bufName=a:cmdName . ' -- ' . a:statusText
+ else
+ let bufName=a:cmdName
+ endif
+ let bufName=fileName . ' ' . nameMarker . bufName . nameMarker
+ let counter=0
+ let resultBufferName = bufName
+ while buflisted(resultBufferName)
+ let counter=counter + 1
+ let resultBufferName=bufName . ' (' . counter . ')'
+ endwhile
+ endif
+
+ let hgCommand = <SID>HGGetOption("HGCommandHGExec", "hg") . " " . a:cmd
+ "echomsg "DBG :".hgCommand
+ let hgOut = system(hgCommand)
+ " HACK: diff command does not return proper error codes
+ if v:shell_error && a:cmdName != 'hgdiff'
+ if strlen(hgOut) == 0
+ echoerr "HG command failed"
+ else
+ echoerr "HG command failed: " . hgOut
+ endif
+ return -1
+ endif
+ if strlen(hgOut) == 0
+ " Handle case of no output. In this case, it is important to check the
+ " file status, especially since hg edit/unedit may change the attributes
+ " of the file with no visible output.
+
+ echomsg "No output from HG command"
+ checktime
+ return -1
+ endif
+
+ if <SID>HGEditFile(resultBufferName, a:origBuffNR) == -1
+ return -1
+ endif
+
+ set buftype=nofile
+ set noswapfile
+ set filetype=
+
+ if <SID>HGGetOption("HGCommandDeleteOnHide", 0)
+ set bufhidden=delete
+ endif
+
+ silent 0put=hgOut
+
+ " The last command left a blank line at the end of the buffer. If the
+ " last line is folded (a side effect of the 'put') then the attempt to
+ " remove the blank line will kill the last fold.
+ "
+ " This could be fixed by explicitly detecting whether the last line is
+ " within a fold, but I prefer to simply unfold the result buffer altogether.
+
+ if has("folding")
+ setlocal nofoldenable
+ endif
+
+ $d
+ 1
+
+ " Define the environment and execute user-defined hooks.
+
+ let b:HGSourceFile=fileName
+ let b:HGCommand=a:cmdName
+ if a:statusText != ""
+ let b:HGStatusText=a:statusText
+ endif
+
+ silent do HGCommand User HGBufferCreated
+ return bufnr("%")
+endfunction
+
+" Function: s:HGBufferCheck(hgBuffer) {{{2
+" Attempts to locate the original file to which HG operations were applied
+" for a given buffer.
+
+function! s:HGBufferCheck(hgBuffer)
+ let origBuffer = getbufvar(a:hgBuffer, "HGOrigBuffNR")
+ if origBuffer
+ if bufexists(origBuffer)
+ return origBuffer
+ else
+ " Original buffer no longer exists.
+ return -1
+ endif
+ else
+ " No original buffer
+ return a:hgBuffer
+ endif
+endfunction
+
+" Function: s:HGCurrentBufferCheck() {{{2
+" Attempts to locate the original file to which HG operations were applied
+" for the current buffer.
+
+function! s:HGCurrentBufferCheck()
+ return <SID>HGBufferCheck(bufnr("%"))
+endfunction
+
+" Function: s:HGToggleDeleteOnHide() {{{2
+" Toggles on and off the delete-on-hide behavior of HG buffers
+
+function! s:HGToggleDeleteOnHide()
+ if exists("g:HGCommandDeleteOnHide")
+ unlet g:HGCommandDeleteOnHide
+ else
+ let g:HGCommandDeleteOnHide=1
+ endif
+endfunction
+
+" Function: s:HGDoCommand(hgcmd, cmdName, statusText) {{{2
+" General skeleton for HG function execution.
+" Returns: name of the new command buffer containing the command results
+
+function! s:HGDoCommand(cmd, cmdName, statusText)
+ let hgBufferCheck=<SID>HGCurrentBufferCheck()
+ if hgBufferCheck == -1
+ echo "Original buffer no longer exists, aborting."
+ return -1
+ endif
+
+ let fileName=bufname(hgBufferCheck)
+ if isdirectory(fileName)
+ let fileName=fileName . "/" . getline(".")
+ endif
+ let realFileName = fnamemodify(<SID>HGResolveLink(fileName), ':t')
+ let oldCwd=<SID>HGChangeToCurrentFileDir(fileName)
+ try
+ " TODO
+ "if !filereadable('HG/Root')
+ "throw fileName . ' is not a HG-controlled file.'
+ "endif
+ let fullCmd = a:cmd . ' "' . realFileName . '"'
+ "echomsg "DEBUG".fullCmd
+ let resultBuffer=<SID>HGCreateCommandBuffer(fullCmd, a:cmdName, a:statusText, hgBufferCheck)
+ return resultBuffer
+ catch
+ echoerr v:exception
+ return -1
+ finally
+ execute 'cd' escape(oldCwd, ' ')
+ endtry
+endfunction
+
+
+" Function: s:HGGetStatusVars(revision, branch, repository) {{{2
+"
+" Obtains a HG revision number and branch name. The 'revisionVar',
+" 'branchVar'and 'repositoryVar' arguments, if non-empty, contain the names of variables to hold
+" the corresponding results.
+"
+" Returns: string to be exec'd that sets the multiple return values.
+
+function! s:HGGetStatusVars(revisionVar, branchVar, repositoryVar)
+ let hgBufferCheck=<SID>HGCurrentBufferCheck()
+ "echomsg "DBG : in HGGetStatusVars"
+ if hgBufferCheck == -1
+ return ""
+ endif
+ let fileName=bufname(hgBufferCheck)
+ let fileNameWithoutLink=<SID>HGResolveLink(fileName)
+ let realFileName = fnamemodify(fileNameWithoutLink, ':t')
+ let oldCwd=<SID>HGChangeToCurrentFileDir(realFileName)
+ try
+ let hgCommand = <SID>HGGetOption("HGCommandHGExec", "hg") . " root "
+ let roottext=system(hgCommand)
+ " Suppress ending null char ! Does it work in window ?
+ let roottext=substitute(roottext,'^.*/\([^/\n\r]*\)\n\_.*$','\1','')
+ if match(getcwd()."/".fileNameWithoutLink, roottext) == -1
+ return ""
+ endif
+ let returnExpression = ""
+ if a:repositoryVar != ""
+ let returnExpression=returnExpression . " | let " . a:repositoryVar . "='" . roottext . "'"
+ endif
+ let hgCommand = <SID>HGGetOption("HGCommandHGExec", "hg") . " status -mardui " . realFileName
+ let statustext=system(hgCommand)
+ if(v:shell_error)
+ return ""
+ endif
+ if match(statustext, '^[?I]') >= 0
+ let revision="NEW"
+ elseif match(statustext, '^[R]') >= 0
+ let revision="REMOVED"
+ elseif match(statustext, '^[D]') >= 0
+ let revision="DELETED"
+ elseif match(statustext, '^[A]') >= 0
+ let revision="ADDED"
+ else
+ " The file is tracked, we can try to get is revision number
+ let hgCommand = <SID>HGGetOption("HGCommandHGExec", "hg") . " parents "
+ let statustext=system(hgCommand)
+ if(v:shell_error)
+ return ""
+ endif
+ let revision=substitute(statustext, '^changeset:\s*\(\d\+\):.*\_$\_.*$', '\1', "")
+
+ if a:branchVar != "" && match(statustext, '^\_.*\_^branch:') >= 0
+ let branch=substitute(statustext, '^\_.*\_^branch:\s*\(\S\+\)\n\_.*$', '\1', "")
+ let returnExpression=returnExpression . " | let " . a:branchVar . "='" . branch . "'"
+ endif
+ endif
+ if (exists('revision'))
+ let returnExpression = "let " . a:revisionVar . "='" . revision . "' " . returnExpression
+ endif
+
+ return returnExpression
+ finally
+ execute 'cd' escape(oldCwd, ' ')
+ endtry
+endfunction
+
+" Function: s:HGSetupBuffer() {{{2
+" Attempts to set the b:HGBranch, b:HGRevision and b:HGRepository variables.
+
+function! s:HGSetupBuffer(...)
+ if (exists("b:HGBufferSetup") && b:HGBufferSetup && !exists('a:1'))
+ " This buffer is already set up.
+ return
+ endif
+
+ if !<SID>HGGetOption("HGCommandEnableBufferSetup", 0)
+ \ || @% == ""
+ \ || s:HGCommandEditFileRunning > 0
+ \ || exists("b:HGOrigBuffNR")
+ unlet! b:HGRevision
+ unlet! b:HGBranch
+ unlet! b:HGRepository
+ return
+ endif
+
+ if !filereadable(expand("%"))
+ return -1
+ endif
+
+ let revision=""
+ let branch=""
+ let repository=""
+
+ exec <SID>HGGetStatusVars('revision', 'branch', 'repository')
+ "echomsg "DBG ".revision."#".branch."#".repository
+ if revision != ""
+ let b:HGRevision=revision
+ else
+ unlet! b:HGRevision
+ endif
+ if branch != ""
+ let b:HGBranch=branch
+ else
+ unlet! b:HGBranch
+ endif
+ if repository != ""
+ let b:HGRepository=repository
+ else
+ unlet! b:HGRepository
+ endif
+ silent do HGCommand User HGBufferSetup
+ let b:HGBufferSetup=1
+endfunction
+
+" Function: s:HGMarkOrigBufferForSetup(hgbuffer) {{{2
+" Resets the buffer setup state of the original buffer for a given HG buffer.
+" Returns: The HG buffer number in a passthrough mode.
+
+function! s:HGMarkOrigBufferForSetup(hgBuffer)
+ checktime
+ if a:hgBuffer != -1
+ let origBuffer = <SID>HGBufferCheck(a:hgBuffer)
+ "This should never not work, but I'm paranoid
+ if origBuffer != a:hgBuffer
+ call setbufvar(origBuffer, "HGBufferSetup", 0)
+ endif
+ else
+ "We are presumably in the original buffer
+ let b:HGBufferSetup = 0
+ "We do the setup now as now event will be triggered allowing it later.
+ call <SID>HGSetupBuffer()
+ endif
+ return a:hgBuffer
+endfunction
+
+" Function: s:HGOverrideOption(option, [value]) {{{2
+" Provides a temporary override for the given HG option. If no value is
+" passed, the override is disabled.
+
+function! s:HGOverrideOption(option, ...)
+ if a:0 == 0
+ unlet! s:{a:option}Override
+ else
+ let s:{a:option}Override = a:1
+ endif
+endfunction
+
+" Function: s:HGWipeoutCommandBuffers() {{{2
+" Clears all current HG buffers of the specified type for a given source.
+
+function! s:HGWipeoutCommandBuffers(originalBuffer, hgCommand)
+ let buffer = 1
+ while buffer <= bufnr('$')
+ if getbufvar(buffer, 'HGOrigBuffNR') == a:originalBuffer
+ if getbufvar(buffer, 'HGCommand') == a:hgCommand
+ execute 'bw' buffer
+ endif
+ endif
+ let buffer = buffer + 1
+ endwhile
+endfunction
+
+" Function: s:HGInstallDocumentation(full_name, revision) {{{2
+" Install help documentation.
+" Arguments:
+" full_name: Full name of this vim plugin script, including path name.
+" revision: Revision of the vim script. #version# mark in the document file
+" will be replaced with this string with 'v' prefix.
+" Return:
+" 1 if new document installed, 0 otherwise.
+" Note: Cleaned and generalized by guo-peng Wen
+"'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+" Helper function to make mkdir as portable as possible
+function! s:HGFlexiMkdir(dir)
+ if exists("*mkdir") " we can use Vim's own mkdir()
+ call mkdir(a:dir)
+ elseif !exists("+shellslash")
+ call system("mkdir -p '".a:dir."'")
+ else " M$
+ let l:ssl = &shellslash
+ try
+ set shellslash
+ " no single quotes?
+ call system('mkdir "'.a:dir.'"')
+ finally
+ let &shellslash = l:ssl
+ endtry
+ endif
+endfunction
+
+function! s:HGInstallDocumentation(full_name)
+ " Figure out document path based on full name of this script:
+ let l:vim_doc_path = fnamemodify(a:full_name, ":h:h") . "/doc"
+ if filewritable(l:vim_doc_path) != 2
+ echomsg s:script_name . ": Trying to update docs at" l:vim_doc_path
+ silent! call <SID>HGFlexiMkdir(l:vim_doc_path)
+ if filewritable(l:vim_doc_path) != 2
+ " Try first item in 'runtimepath':
+ let l:vim_doc_path =
+ \ substitute(&runtimepath, '^\([^,]*\).*', '\1/doc', 'e')
+ if filewritable(l:vim_doc_path) != 2
+ echomsg s:script_name . ": Trying to update docs at" l:vim_doc_path
+ silent! call <SID>HGFlexiMkdir(l:vim_doc_path)
+ if filewritable(l:vim_doc_path) != 2
+ " Put a warning:
+ echomsg "Unable to open documentation directory"
+ echomsg " type `:help add-local-help' for more information."
+ return 0
+ endif
+ endif
+ endif
+ endif
+
+ " Full name of documentation file:
+ let l:doc_file =
+ \ l:vim_doc_path . "/" . s:script_name . ".txt"
+ " Bail out if document file is still up to date:
+ if filereadable(l:doc_file) &&
+ \ getftime(a:full_name) < getftime(l:doc_file)
+ return 0
+ endif
+
+ " temporary global settings
+ let l:lz = &lazyredraw
+ let l:hls = &hlsearch
+ set lazyredraw nohlsearch
+ " Create a new buffer & read in the plugin file (me):
+ 1 new
+ setlocal noswapfile modifiable nomodeline
+ if has("folding")
+ setlocal nofoldenable
+ endif
+ silent execute "read" escape(a:full_name, " ")
+ let l:doc_buf = bufnr("%")
+
+ 1
+ " Delete from first line to a line starts with
+ " === START_DOC
+ silent 1,/^=\{3,}\s\+START_DOC\C/ delete _
+ " Delete from a line starts with
+ " === END_DOC
+ " to the end of the documents:
+ silent /^=\{3,}\s\+END_DOC\C/,$ delete _
+
+ " Add modeline for help doc: the modeline string is mangled intentionally
+ " to avoid it be recognized by VIM:
+ call append(line("$"), "")
+ call append(line("$"), " v" . "im:tw=78:ts=8:ft=help:norl:")
+
+ " Replace revision:
+ silent execute "normal :1s/#version#/" . s:script_version . "/\<CR>"
+ " Save the help document and wipe out buffer:
+ silent execute "wq!" escape(l:doc_file, " ") "| bw" l:doc_buf
+ " Build help tags:
+ silent execute "helptags" l:vim_doc_path
+
+ let &hlsearch = l:hls
+ let &lazyredraw = l:lz
+ return 1
+endfunction
+
+" Section: Public functions {{{1
+
+" Function: HGGetRevision() {{{2
+" Global function for retrieving the current buffer's HG revision number.
+" Returns: Revision number or an empty string if an error occurs.
+
+function! HGGetRevision()
+ let revision=""
+ exec <SID>HGGetStatusVars('revision', '', '')
+ return revision
+endfunction
+
+" Function: HGDisableBufferSetup() {{{2
+" Global function for deactivating the buffer autovariables.
+
+function! HGDisableBufferSetup()
+ let g:HGCommandEnableBufferSetup=0
+ silent! augroup! HGCommandPlugin
+endfunction
+
+" Function: HGEnableBufferSetup() {{{2
+" Global function for activating the buffer autovariables.
+
+function! HGEnableBufferSetup()
+ let g:HGCommandEnableBufferSetup=1
+ augroup HGCommandPlugin
+ au!
+ au BufEnter * call <SID>HGSetupBuffer()
+ au BufWritePost * call <SID>HGSetupBuffer()
+ " Force resetting up buffer on external file change (HG update)
+ au FileChangedShell * call <SID>HGSetupBuffer(1)
+ augroup END
+
+ " Only auto-load if the plugin is fully loaded. This gives other plugins a
+ " chance to run.
+ if g:loaded_hgcommand == 2
+ call <SID>HGSetupBuffer()
+ endif
+endfunction
+
+" Function: HGGetStatusLine() {{{2
+" Default (sample) status line entry for HG files. This is only useful if
+" HG-managed buffer mode is on (see the HGCommandEnableBufferSetup variable
+" for how to do this).
+
+function! HGGetStatusLine()
+ if exists('b:HGSourceFile')
+ " This is a result buffer
+ let value='[' . b:HGCommand . ' ' . b:HGSourceFile
+ if exists('b:HGStatusText')
+ let value=value . ' ' . b:HGStatusText
+ endif
+ let value = value . ']'
+ return value
+ endif
+
+ if exists('b:HGRevision')
+ \ && b:HGRevision != ''
+ \ && exists('b:HGRepository')
+ \ && b:HGRepository != ''
+ \ && exists('g:HGCommandEnableBufferSetup')
+ \ && g:HGCommandEnableBufferSetup
+ if !exists('b:HGBranch')
+ let l:branch=''
+ else
+ let l:branch=b:HGBranch
+ endif
+ return '[HG ' . b:HGRepository . '/' . l:branch .'/' . b:HGRevision . ']'
+ else
+ return ''
+ endif
+endfunction
+
+" Section: HG command functions {{{1
+
+" Function: s:HGAdd() {{{2
+function! s:HGAdd()
+ return <SID>HGMarkOrigBufferForSetup(<SID>HGDoCommand('add', 'hgadd', ''))
+endfunction
+
+" Function: s:HGAnnotate(...) {{{2
+function! s:HGAnnotate(...)
+ if a:0 == 0
+ if &filetype == "HGAnnotate"
+ " This is a HGAnnotate buffer. Perform annotation of the version
+ " indicated by the current line.
+ let revision = substitute(getline("."),'\(^[0-9]*\):.*','\1','')
+ if <SID>HGGetOption('HGCommandAnnotateParent', 0) != 0 && revision > 0
+ let revision = revision - 1
+ endif
+ else
+ let revision=HGGetRevision()
+ if revision == ""
+ echoerr "Unable to obtain HG version information."
+ return -1
+ endif
+ endif
+ else
+ let revision=a:1
+ endif
+
+ if revision == "NEW"
+ echo "No annotatation available for new file."
+ return -1
+ endif
+
+ let resultBuffer=<SID>HGDoCommand('annotate -ndu -r ' . revision, 'hgannotate', revision)
+ "echomsg "DBG: ".resultBuffer
+ if resultBuffer != -1
+ set filetype=HGAnnotate
+ endif
+
+ return resultBuffer
+endfunction
+
+" Function: s:HGCommit() {{{2
+function! s:HGCommit(...)
+ " Handle the commit message being specified. If a message is supplied, it
+ " is used; if bang is supplied, an empty message is used; otherwise, the
+ " user is provided a buffer from which to edit the commit message.
+ if a:2 != "" || a:1 == "!"
+ return <SID>HGMarkOrigBufferForSetup(<SID>HGDoCommand('commit -m "' . a:2 . '"', 'hgcommit', ''))
+ endif
+
+ let hgBufferCheck=<SID>HGCurrentBufferCheck()
+ if hgBufferCheck == -1
+ echo "Original buffer no longer exists, aborting."
+ return -1
+ endif
+
+ " Protect against windows' backslashes in paths. They confuse exec'd
+ " commands.
+
+ let shellSlashBak = &shellslash
+ try
+ set shellslash
+
+ let messageFileName = tempname()
+
+ let fileName=bufname(hgBufferCheck)
+ let realFilePath=<SID>HGResolveLink(fileName)
+ let newCwd=fnamemodify(realFilePath, ':h')
+ if strlen(newCwd) == 0
+ " Account for autochdir being in effect, which will make this blank, but
+ " we know we'll be in the current directory for the original file.
+ let newCwd = getcwd()
+ endif
+
+ let realFileName=fnamemodify(realFilePath, ':t')
+
+ if <SID>HGEditFile(messageFileName, hgBufferCheck) == -1
+ return
+ endif
+
+ " Protect against case and backslash issues in Windows.
+ let autoPattern = '\c' . messageFileName
+
+ " Ensure existance of group
+ augroup HGCommit
+ augroup END
+
+ execute 'au HGCommit BufDelete' autoPattern 'call delete("' . messageFileName . '")'
+ execute 'au HGCommit BufDelete' autoPattern 'au! HGCommit * ' autoPattern
+
+ " Create a commit mapping. The mapping must clear all autocommands in case
+ " it is invoked when HGCommandCommitOnWrite is active, as well as to not
+ " invoke the buffer deletion autocommand.
+
+ execute 'nnoremap <silent> <buffer> <Plug>HGCommit '.
+ \ ':au! HGCommit * ' . autoPattern . '<CR>'.
+ \ ':g/^HG:/d<CR>'.
+ \ ':update<CR>'.
+ \ ':call <SID>HGFinishCommit("' . messageFileName . '",' .
+ \ '"' . newCwd . '",' .
+ \ '"' . realFileName . '",' .
+ \ hgBufferCheck . ')<CR>'
+
+ silent 0put ='HG: ----------------------------------------------------------------------'
+ silent put =\"HG: Enter Log. Lines beginning with `HG:' are removed automatically\"
+ silent put ='HG: Type <leader>cc (or your own <Plug>HGCommit mapping)'
+
+ if <SID>HGGetOption('HGCommandCommitOnWrite', 1) == 1
+ execute 'au HGCommit BufWritePre' autoPattern 'g/^HG:/d'
+ execute 'au HGCommit BufWritePost' autoPattern 'call <SID>HGFinishCommit("' . messageFileName . '", "' . newCwd . '", "' . realFileName . '", ' . hgBufferCheck . ') | au! * ' autoPattern
+ silent put ='HG: or write this buffer'
+ endif
+
+ silent put ='HG: to finish this commit operation'
+ silent put ='HG: ----------------------------------------------------------------------'
+ $
+ let b:HGSourceFile=fileName
+ let b:HGCommand='HGCommit'
+ set filetype=hg
+ finally
+ let &shellslash = shellSlashBak
+ endtry
+
+endfunction
+
+" Function: s:HGDiff(...) {{{2
+function! s:HGDiff(...)
+ if a:0 == 1
+ let revOptions = '-r' . a:1
+ let caption = a:1 . ' -> current'
+ elseif a:0 == 2
+ let revOptions = '-r' . a:1 . ' -r' . a:2
+ let caption = a:1 . ' -> ' . a:2
+ else
+ let revOptions = ''
+ let caption = ''
+ endif
+
+ let hgdiffopt=<SID>HGGetOption('HGCommandDiffOpt', 'w')
+
+ if hgdiffopt == ""
+ let diffoptionstring=""
+ else
+ let diffoptionstring=" -" . hgdiffopt . " "
+ endif
+
+ let resultBuffer = <SID>HGDoCommand('diff ' . diffoptionstring . revOptions , 'hgdiff', caption)
+ if resultBuffer != -1
+ set filetype=diff
+ endif
+ return resultBuffer
+endfunction
+
+
+" Function: s:HGGotoOriginal(["!]) {{{2
+function! s:HGGotoOriginal(...)
+ let origBuffNR = <SID>HGCurrentBufferCheck()
+ if origBuffNR > 0
+ let origWinNR = bufwinnr(origBuffNR)
+ if origWinNR == -1
+ execute 'buffer' origBuffNR
+ else
+ execute origWinNR . 'wincmd w'
+ endif
+ if a:0 == 1
+ if a:1 == "!"
+ let buffnr = 1
+ let buffmaxnr = bufnr("$")
+ while buffnr <= buffmaxnr
+ if getbufvar(buffnr, "HGOrigBuffNR") == origBuffNR
+ execute "bw" buffnr
+ endif
+ let buffnr = buffnr + 1
+ endwhile
+ endif
+ endif
+ endif
+endfunction
+
+" Function: s:HGFinishCommit(messageFile, targetDir, targetFile) {{{2
+function! s:HGFinishCommit(messageFile, targetDir, targetFile, origBuffNR)
+ if filereadable(a:messageFile)
+ let oldCwd=getcwd()
+ if strlen(a:targetDir) > 0
+ execute 'cd' escape(a:targetDir, ' ')
+ endif
+ let resultBuffer=<SID>HGCreateCommandBuffer('commit -l "' . a:messageFile . '" "'. a:targetFile . '"', 'hgcommit', '', a:origBuffNR)
+ execute 'cd' escape(oldCwd, ' ')
+ execute 'bw' escape(a:messageFile, ' *?\')
+ silent execute 'call delete("' . a:messageFile . '")'
+ return <SID>HGMarkOrigBufferForSetup(resultBuffer)
+ else
+ echoerr "Can't read message file; no commit is possible."
+ return -1
+ endif
+endfunction
+
+" Function: s:HGLog() {{{2
+function! s:HGLog(...)
+ if a:0 == 0
+ let versionOption = ""
+ let caption = ''
+ else
+ let versionOption=" -r" . a:1
+ let caption = a:1
+ endif
+
+ let resultBuffer=<SID>HGDoCommand('log' . versionOption, 'hglog', caption)
+ if resultBuffer != ""
+ set filetype=rcslog
+ endif
+ return resultBuffer
+endfunction
+
+" Function: s:HGRevert() {{{2
+function! s:HGRevert()
+ return <SID>HGMarkOrigBufferForSetup(<SID>HGDoCommand('revert', 'hgrevert', ''))
+endfunction
+
+" Function: s:HGReview(...) {{{2
+function! s:HGReview(...)
+ if a:0 == 0
+ let versiontag=""
+ if <SID>HGGetOption('HGCommandInteractive', 0)
+ let versiontag=input('Revision: ')
+ endif
+ if versiontag == ""
+ let versiontag="(current)"
+ let versionOption=""
+ else
+ let versionOption=" -r " . versiontag . " "
+ endif
+ else
+ let versiontag=a:1
+ let versionOption=" -r " . versiontag . " "
+ endif
+
+ let resultBuffer = <SID>HGDoCommand('cat' . versionOption, 'hgreview', versiontag)
+ if resultBuffer > 0
+ let &filetype=getbufvar(b:HGOrigBuffNR, '&filetype')
+ endif
+
+ return resultBuffer
+endfunction
+
+" Function: s:HGStatus() {{{2
+function! s:HGStatus()
+ return <SID>HGDoCommand('status', 'hgstatus', '')
+endfunction
+
+
+" Function: s:HGUpdate() {{{2
+function! s:HGUpdate()
+ return <SID>HGMarkOrigBufferForSetup(<SID>HGDoCommand('update', 'update', ''))
+endfunction
+
+" Function: s:HGVimDiff(...) {{{2
+function! s:HGVimDiff(...)
+ let originalBuffer = <SID>HGCurrentBufferCheck()
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1
+ try
+ " If there's already a VimDiff'ed window, restore it.
+ " There may only be one HGVimDiff original window at a time.
+
+ if exists("s:vimDiffSourceBuffer") && s:vimDiffSourceBuffer != originalBuffer
+ " Clear the existing vimdiff setup by removing the result buffers.
+ call <SID>HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff')
+ endif
+
+ " Split and diff
+ if(a:0 == 2)
+ " Reset the vimdiff system, as 2 explicit versions were provided.
+ if exists('s:vimDiffSourceBuffer')
+ call <SID>HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff')
+ endif
+ let resultBuffer = <SID>HGReview(a:1)
+ if resultBuffer < 0
+ echomsg "Can't open HG revision " . a:1
+ return resultBuffer
+ endif
+ let b:HGCommand = 'vimdiff'
+ diffthis
+ let s:vimDiffBufferCount = 1
+ let s:vimDiffScratchList = '{'. resultBuffer . '}'
+ " If no split method is defined, cheat, and set it to vertical.
+ try
+ call <SID>HGOverrideOption('HGCommandSplit', <SID>HGGetOption('HGCommandDiffSplit', <SID>HGGetOption('HGCommandSplit', 'vertical')))
+ let resultBuffer=<SID>HGReview(a:2)
+ finally
+ call <SID>HGOverrideOption('HGCommandSplit')
+ endtry
+ if resultBuffer < 0
+ echomsg "Can't open HG revision " . a:1
+ return resultBuffer
+ endif
+ let b:HGCommand = 'vimdiff'
+ diffthis
+ let s:vimDiffBufferCount = 2
+ let s:vimDiffScratchList = s:vimDiffScratchList . '{'. resultBuffer . '}'
+ else
+ " Add new buffer
+ try
+ " Force splitting behavior, otherwise why use vimdiff?
+ call <SID>HGOverrideOption("HGCommandEdit", "split")
+ call <SID>HGOverrideOption("HGCommandSplit", <SID>HGGetOption('HGCommandDiffSplit', <SID>HGGetOption('HGCommandSplit', 'vertical')))
+ if(a:0 == 0)
+ let resultBuffer=<SID>HGReview()
+ else
+ let resultBuffer=<SID>HGReview(a:1)
+ endif
+ finally
+ call <SID>HGOverrideOption("HGCommandEdit")
+ call <SID>HGOverrideOption("HGCommandSplit")
+ endtry
+ if resultBuffer < 0
+ echomsg "Can't open current HG revision"
+ return resultBuffer
+ endif
+ let b:HGCommand = 'vimdiff'
+ diffthis
+
+ if !exists('s:vimDiffBufferCount')
+ " New instance of vimdiff.
+ let s:vimDiffBufferCount = 2
+ let s:vimDiffScratchList = '{' . resultBuffer . '}'
+
+ " This could have been invoked on a HG result buffer, not the
+ " original buffer.
+ wincmd W
+ execute 'buffer' originalBuffer
+ " Store info for later original buffer restore
+ let s:vimDiffRestoreCmd =
+ \ "call setbufvar(".originalBuffer.", \"&diff\", ".getbufvar(originalBuffer, '&diff').")"
+ \ . "|call setbufvar(".originalBuffer.", \"&foldcolumn\", ".getbufvar(originalBuffer, '&foldcolumn').")"
+ \ . "|call setbufvar(".originalBuffer.", \"&foldenable\", ".getbufvar(originalBuffer, '&foldenable').")"
+ \ . "|call setbufvar(".originalBuffer.", \"&foldmethod\", '".getbufvar(originalBuffer, '&foldmethod')."')"
+ \ . "|call setbufvar(".originalBuffer.", \"&scrollbind\", ".getbufvar(originalBuffer, '&scrollbind').")"
+ \ . "|call setbufvar(".originalBuffer.", \"&wrap\", ".getbufvar(originalBuffer, '&wrap').")"
+ \ . "|if &foldmethod=='manual'|execute 'normal! zE'|endif"
+ diffthis
+ wincmd w
+ else
+ " Adding a window to an existing vimdiff
+ let s:vimDiffBufferCount = s:vimDiffBufferCount + 1
+ let s:vimDiffScratchList = s:vimDiffScratchList . '{' . resultBuffer . '}'
+ endif
+ endif
+
+ let s:vimDiffSourceBuffer = originalBuffer
+
+ " Avoid executing the modeline in the current buffer after the autocommand.
+
+ let currentBuffer = bufnr('%')
+ let saveModeline = getbufvar(currentBuffer, '&modeline')
+ try
+ call setbufvar(currentBuffer, '&modeline', 0)
+ silent do HGCommand User HGVimDiffFinish
+ finally
+ call setbufvar(currentBuffer, '&modeline', saveModeline)
+ endtry
+ return resultBuffer
+ finally
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1
+ endtry
+endfunction
+
+" Section: Command definitions {{{1
+" Section: Primary commands {{{2
+com! HGAdd call <SID>HGAdd()
+com! -nargs=? HGAnnotate call <SID>HGAnnotate(<f-args>)
+com! -bang -nargs=? HGCommit call <SID>HGCommit(<q-bang>, <q-args>)
+com! -nargs=* HGDiff call <SID>HGDiff(<f-args>)
+com! -bang HGGotoOriginal call <SID>HGGotoOriginal(<q-bang>)
+com! -nargs=? HGLog call <SID>HGLog(<f-args>)
+com! HGRevert call <SID>HGRevert()
+com! -nargs=? HGReview call <SID>HGReview(<f-args>)
+com! HGStatus call <SID>HGStatus()
+com! HGUpdate call <SID>HGUpdate()
+com! -nargs=* HGVimDiff call <SID>HGVimDiff(<f-args>)
+
+" Section: HG buffer management commands {{{2
+com! HGDisableBufferSetup call HGDisableBufferSetup()
+com! HGEnableBufferSetup call HGEnableBufferSetup()
+
+" Allow reloading hgcommand.vim
+com! HGReload unlet! g:loaded_hgcommand | runtime plugin/hgcommand.vim
+
+" Section: Plugin command mappings {{{1
+nnoremap <silent> <Plug>HGAdd :HGAdd<CR>
+nnoremap <silent> <Plug>HGAnnotate :HGAnnotate<CR>
+nnoremap <silent> <Plug>HGCommit :HGCommit<CR>
+nnoremap <silent> <Plug>HGDiff :HGDiff<CR>
+nnoremap <silent> <Plug>HGGotoOriginal :HGGotoOriginal<CR>
+nnoremap <silent> <Plug>HGClearAndGotoOriginal :HGGotoOriginal!<CR>
+nnoremap <silent> <Plug>HGLog :HGLog<CR>
+nnoremap <silent> <Plug>HGRevert :HGRevert<CR>
+nnoremap <silent> <Plug>HGReview :HGReview<CR>
+nnoremap <silent> <Plug>HGStatus :HGStatus<CR>
+nnoremap <silent> <Plug>HGUpdate :HGUpdate<CR>
+nnoremap <silent> <Plug>HGVimDiff :HGVimDiff<CR>
+
+" Section: Default mappings {{{1
+if !hasmapto('<Plug>HGAdd')
+ nmap <unique> <Leader>hga <Plug>HGAdd
+endif
+if !hasmapto('<Plug>HGAnnotate')
+ nmap <unique> <Leader>hgn <Plug>HGAnnotate
+endif
+if !hasmapto('<Plug>HGClearAndGotoOriginal')
+ nmap <unique> <Leader>hgG <Plug>HGClearAndGotoOriginal
+endif
+if !hasmapto('<Plug>HGCommit')
+ nmap <unique> <Leader>hgc <Plug>HGCommit
+endif
+if !hasmapto('<Plug>HGDiff')
+ nmap <unique> <Leader>hgd <Plug>HGDiff
+endif
+if !hasmapto('<Plug>HGGotoOriginal')
+ nmap <unique> <Leader>hgg <Plug>HGGotoOriginal
+endif
+if !hasmapto('<Plug>HGLog')
+ nmap <unique> <Leader>hgl <Plug>HGLog
+endif
+if !hasmapto('<Plug>HGRevert')
+ nmap <unique> <Leader>hgq <Plug>HGRevert
+endif
+if !hasmapto('<Plug>HGReview')
+ nmap <unique> <Leader>hgr <Plug>HGReview
+endif
+if !hasmapto('<Plug>HGStatus')
+ nmap <unique> <Leader>hgs <Plug>HGStatus
+endif
+if !hasmapto('<Plug>HGUpdate')
+ nmap <unique> <Leader>hgu <Plug>HGUpdate
+endif
+if !hasmapto('<Plug>HGVimDiff')
+ nmap <unique> <Leader>hgv <Plug>HGVimDiff
+endif
+
+" Section: Menu items {{{1
+silent! aunmenu Plugin.HG
+amenu <silent> &Plugin.HG.&Add <Plug>HGAdd
+amenu <silent> &Plugin.HG.A&nnotate <Plug>HGAnnotate
+amenu <silent> &Plugin.HG.&Commit <Plug>HGCommit
+amenu <silent> &Plugin.HG.&Diff <Plug>HGDiff
+amenu <silent> &Plugin.HG.&Log <Plug>HGLog
+amenu <silent> &Plugin.HG.Revert <Plug>HGRevert
+amenu <silent> &Plugin.HG.&Review <Plug>HGReview
+amenu <silent> &Plugin.HG.&Status <Plug>HGStatus
+amenu <silent> &Plugin.HG.&Update <Plug>HGUpdate
+amenu <silent> &Plugin.HG.&VimDiff <Plug>HGVimDiff
+
+" Section: Autocommands to restore vimdiff state {{{1
+function! s:HGVimDiffRestore(vimDiffBuff)
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1
+ try
+ if exists("s:vimDiffSourceBuffer")
+ if a:vimDiffBuff == s:vimDiffSourceBuffer
+ " Original file is being removed.
+ unlet! s:vimDiffSourceBuffer
+ unlet! s:vimDiffBufferCount
+ unlet! s:vimDiffRestoreCmd
+ unlet! s:vimDiffScratchList
+ elseif match(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}') >= 0
+ let s:vimDiffScratchList = substitute(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}', '', '')
+ let s:vimDiffBufferCount = s:vimDiffBufferCount - 1
+ if s:vimDiffBufferCount == 1 && exists('s:vimDiffRestoreCmd')
+ " All scratch buffers are gone, reset the original.
+ " Only restore if the source buffer is still in Diff mode
+
+ let sourceWinNR=bufwinnr(s:vimDiffSourceBuffer)
+ if sourceWinNR != -1
+ " The buffer is visible in at least one window
+ let currentWinNR = winnr()
+ while winbufnr(sourceWinNR) != -1
+ if winbufnr(sourceWinNR) == s:vimDiffSourceBuffer
+ execute sourceWinNR . 'wincmd w'
+ if getwinvar('', "&diff")
+ execute s:vimDiffRestoreCmd
+ endif
+ endif
+ let sourceWinNR = sourceWinNR + 1
+ endwhile
+ execute currentWinNR . 'wincmd w'
+ else
+ " The buffer is hidden. It must be visible in order to set the
+ " diff option.
+ let currentBufNR = bufnr('')
+ execute "hide buffer" s:vimDiffSourceBuffer
+ if getwinvar('', "&diff")
+ execute s:vimDiffRestoreCmd
+ endif
+ execute "hide buffer" currentBufNR
+ endif
+
+ unlet s:vimDiffRestoreCmd
+ unlet s:vimDiffSourceBuffer
+ unlet s:vimDiffBufferCount
+ unlet s:vimDiffScratchList
+ elseif s:vimDiffBufferCount == 0
+ " All buffers are gone.
+ unlet s:vimDiffSourceBuffer
+ unlet s:vimDiffBufferCount
+ unlet s:vimDiffScratchList
+ endif
+ endif
+ endif
+ finally
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1
+ endtry
+endfunction
+
+augroup HGVimDiffRestore
+ au!
+ au BufUnload * call <SID>HGVimDiffRestore(expand("<abuf>"))
+augroup END
+
+" Section: Optional activation of buffer management {{{1
+
+if s:HGGetOption('HGCommandEnableBufferSetup', 1)
+ call HGEnableBufferSetup()
+endif
+
+" Section: Doc installation {{{1
+
+if <SID>HGInstallDocumentation(expand("<sfile>:p"))
+ echomsg s:script_name s:script_version . ": updated documentation"
+endif
+
+" Section: Plugin completion {{{1
+
+" delete one-time vars and functions
+delfunction <SID>HGInstallDocumentation
+delfunction <SID>HGFlexiMkdir
+delfunction <SID>HGCleanupOnFailure
+unlet s:script_version s:script_name
+
+let g:loaded_hgcommand=2
+silent do HGCommand User HGPluginFinish
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+" vim:se expandtab sts=2 sw=2:
+finish
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Section: Documentation content {{{1
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+=== START_DOC
+*hgcommand.txt* Mercurial vim integration #version#
+
+
+ HGCOMMAND REFERENCE MANUAL~
+
+
+Author: Mathieu Clabaut <mathieu.clabaut@gmail.com>
+Credits: Bob Hiestand <bob.hiestand@gmail.com>
+Mercurial: http://mercurial.selenic.com/
+ Mercurial (noted Hg) is a fast, lightweight Source Control Management
+ system designed for efficient handling of very large distributed projects.
+
+==============================================================================
+1. Contents *hgcommand-contents*
+
+ Installation : |hgcommand-install|
+ HGCommand Intro : |hgcommand|
+ HGCommand Manual : |hgcommand-manual|
+ Customization : |hgcommand-customize|
+ Bugs : |hgcommand-bugs|
+
+==============================================================================
+2. HGCommand Installation *hgcommand-install*
+
+ In order to install the plugin, place the hgcommand.vim file into a plugin'
+ directory in your runtime path (please see |add-global-plugin| and
+ |'runtimepath'|.
+
+ HGCommand may be customized by setting variables, creating maps, and
+ specifying event handlers. Please see |hgcommand-customize| for more
+ details.
+
+ *hgcommand-auto-help*
+ The help file is automagically generated when the |hgcommand| script is
+ loaded for the first time.
+
+==============================================================================
+
+3. HGCommand Intro *hgcommand*
+ *hgcommand-intro*
+
+ The HGCommand plugin provides global ex commands for manipulating
+ HG-controlled source files. In general, each command operates on the
+ current buffer and accomplishes a separate hg function, such as update,
+ commit, log, and others (please see |hgcommand-commands| for a list of all
+ available commands). The results of each operation are displayed in a
+ scratch buffer. Several buffer variables are defined for those scratch
+ buffers (please see |hgcommand-buffer-variables|).
+
+ The notion of "current file" means either the current buffer, or, in the
+ case of a directory buffer, the file on the current line within the buffer.
+
+ For convenience, any HGCommand invoked on a HGCommand scratch buffer acts
+ as though it was invoked on the original file and splits the screen so that
+ the output appears in a new window.
+
+ Many of the commands accept revisions as arguments. By default, most
+ operate on the most recent revision on the current branch if no revision is
+ specified (though see |HGCommandInteractive| to prompt instead).
+
+ Each HGCommand is mapped to a key sequence starting with the <Leader>
+ keystroke. The default mappings may be overridden by supplying different
+ mappings before the plugin is loaded, such as in the vimrc, in the standard
+ fashion for plugin mappings. For examples, please see
+ |hgcommand-mappings-override|.
+
+ The HGCommand plugin may be configured in several ways. For more details,
+ please see |hgcommand-customize|.
+
+==============================================================================
+4. HGCommand Manual *hgcommand-manual*
+
+4.1 HGCommand commands *hgcommand-commands*
+
+ HGCommand defines the following commands:
+
+ |:HGAdd|
+ |:HGAnnotate|
+ |:HGCommit|
+ |:HGDiff|
+ |:HGGotoOriginal|
+ |:HGLog|
+ |:HGRevert|
+ |:HGReview|
+ |:HGStatus|
+ |:HGUpdate|
+ |:HGVimDiff|
+
+:HGAdd *:HGAdd*
+
+ This command performs "hg add" on the current file. Please note, this does
+ not commit the newly-added file.
+
+:HGAnnotate *:HGAnnotate*
+
+ This command performs "hg annotate" on the current file. If an argument is
+ given, the argument is used as a revision number to display. If not given
+ an argument, it uses the most recent version of the file on the current
+ branch. Additionally, if the current buffer is a HGAnnotate buffer
+ already, the version number on the current line is used.
+
+ If the |HGCommandAnnotateParent| variable is set to a non-zero value, the
+ version previous to the one on the current line is used instead. This
+ allows one to navigate back to examine the previous version of a line.
+
+ The filetype of the HGCommand scratch buffer is set to 'HGAnnotate', to
+ take advantage of the bundled syntax file.
+
+
+:HGCommit[!] *:HGCommit*
+
+ If called with arguments, this performs "hg commit" using the arguments as
+ the log message.
+
+ If '!' is used with no arguments, an empty log message is committed.
+
+ If called with no arguments, this is a two-step command. The first step
+ opens a buffer to accept a log message. When that buffer is written, it is
+ automatically closed and the file is committed using the information from
+ that log message. The commit can be abandoned if the log message buffer is
+ deleted or wiped before being written.
+
+ Alternatively, the mapping that is used to invoke :HGCommit (by default
+ <Leader>hgc) can be used in the log message buffer to immediately commit.
+ This is useful if the |HGCommandCommitOnWrite| variable is set to 0 to
+ disable the normal commit-on-write behavior.
+
+:HGDiff *:HGDiff*
+
+ With no arguments, this performs "hg diff" on the current file against the
+ current repository version.
+
+ With one argument, "hg diff" is performed on the current file against the
+ specified revision.
+
+ With two arguments, hg diff is performed between the specified revisions of
+ the current file.
+
+ This command uses the 'HGCommandDiffOpt' variable to specify diff options.
+ If that variable does not exist, then 'wbBc' is assumed. If you wish to
+ have no options, then set it to the empty string.
+
+
+:HGGotoOriginal *:HGGotoOriginal*
+
+ This command returns the current window to the source buffer, if the
+ current buffer is a HG command output buffer.
+
+:HGGotoOriginal!
+
+ Like ":HGGotoOriginal" but also executes :bufwipeout on all HG command
+ output buffers for the source buffer.
+
+:HGLog *:HGLog*
+
+ Performs "hg log" on the current file.
+
+ If an argument is given, it is passed as an argument to the "-r" option of
+ "hg log".
+
+:HGRevert *:HGRevert*
+
+ Replaces the current file with the most recent version from the repository
+ in order to wipe out any undesired changes.
+
+:HGReview *:HGReview*
+
+ Retrieves a particular version of the current file. If no argument is
+ given, the most recent version of the file on the current branch is
+ retrieved. Otherwise, the specified version is retrieved.
+
+:HGStatus *:HGStatus*
+
+ Performs "hg status" on the current file.
+
+:HGUpdate *:HGUpdate*
+
+ Performs "hg update" on the current file. This intentionally does not
+ automatically reload the current buffer, though vim should prompt the user
+ to do so if the underlying file is altered by this command.
+
+:HGVimDiff *:HGVimDiff*
+
+ With no arguments, this prompts the user for a revision and then uses
+ vimdiff to display the differences between the current file and the
+ specified revision. If no revision is specified, the most recent version
+ of the file on the current branch is used.
+
+ With one argument, that argument is used as the revision as above. With
+ two arguments, the differences between the two revisions is displayed using
+ vimdiff.
+
+ With either zero or one argument, the original buffer is used to perform
+ the vimdiff. When the other buffer is closed, the original buffer will be
+ returned to normal mode.
+
+ Once vimdiff mode is started using the above methods, additional vimdiff
+ buffers may be added by passing a single version argument to the command.
+ There may be up to 4 vimdiff buffers total.
+
+ Using the 2-argument form of the command resets the vimdiff to only those 2
+ versions. Additionally, invoking the command on a different file will
+ close the previous vimdiff buffers.
+
+
+4.2 Mappings *hgcommand-mappings*
+
+ By default, a mapping is defined for each command. These mappings execute
+ the default (no-argument) form of each command.
+
+ <Leader>hga HGAdd
+ <Leader>hgn HGAnnotate
+ <Leader>hgc HGCommit
+ <Leader>hgd HGDiff
+ <Leader>hgg HGGotoOriginal
+ <Leader>hgG HGGotoOriginal!
+ <Leader>hgl HGLog
+ <Leader>hgr HGReview
+ <Leader>hgs HGStatus
+ <Leader>hgu HGUpdate
+ <Leader>hgv HGVimDiff
+
+ *hgcommand-mappings-override*
+
+ The default mappings can be overriden by user-provided instead by mapping
+ to <Plug>CommandName. This is especially useful when these mappings
+ collide with other existing mappings (vim will warn of this during plugin
+ initialization, but will not clobber the existing mappings).
+
+ For instance, to override the default mapping for :HGAdd to set it to
+ '\add', add the following to the vimrc: >
+
+ nmap \add <Plug>HGAdd
+<
+4.3 Automatic buffer variables *hgcommand-buffer-variables*
+
+ Several buffer variables are defined in each HGCommand result buffer.
+ These may be useful for additional customization in callbacks defined in
+ the event handlers (please see |hgcommand-events|).
+
+ The following variables are automatically defined:
+
+b:hgOrigBuffNR *b:hgOrigBuffNR*
+
+ This variable is set to the buffer number of the source file.
+
+b:hgcmd *b:hgcmd*
+
+ This variable is set to the name of the hg command that created the result
+ buffer.
+==============================================================================
+
+5. Configuration and customization *hgcommand-customize*
+ *hgcommand-config*
+
+ The HGCommand plugin can be configured in two ways: by setting
+ configuration variables (see |hgcommand-options|) or by defining HGCommand
+ event handlers (see |hgcommand-events|). Additionally, the HGCommand
+ plugin provides several option for naming the HG result buffers (see
+ |hgcommand-naming|) and supported a customized status line (see
+ |hgcommand-statusline| and |hgcommand-buffer-management|).
+
+5.1 HGCommand configuration variables *hgcommand-options*
+
+ Several variables affect the plugin's behavior. These variables are
+ checked at time of execution, and may be defined at the window, buffer, or
+ global level and are checked in that order of precedence.
+
+
+ The following variables are available:
+
+ |HGCommandAnnotateParent|
+ |HGCommandCommitOnWrite|
+ |HGCommandHGExec|
+ |HGCommandDeleteOnHide|
+ |HGCommandDiffOpt|
+ |HGCommandDiffSplit|
+ |HGCommandEdit|
+ |HGCommandEnableBufferSetup|
+ |HGCommandInteractive|
+ |HGCommandNameMarker|
+ |HGCommandNameResultBuffers|
+ |HGCommandSplit|
+
+HGCommandAnnotateParent *HGCommandAnnotateParent*
+
+ This variable, if set to a non-zero value, causes the zero-argument form of
+ HGAnnotate when invoked on a HGAnnotate buffer to go to the version
+ previous to that displayed on the current line. If not set, it defaults to
+ 0.
+
+HGCommandCommitOnWrite *HGCommandCommitOnWrite*
+
+ This variable, if set to a non-zero value, causes the pending hg commit to
+ take place immediately as soon as the log message buffer is written. If
+ set to zero, only the HGCommit mapping will cause the pending commit to
+ occur. If not set, it defaults to 1.
+
+HGCommandHGExec *HGCommandHGExec*
+
+ This variable controls the executable used for all HG commands. If not
+ set, it defaults to "hg".
+
+HGCommandDeleteOnHide *HGCommandDeleteOnHide*
+
+ This variable, if set to a non-zero value, causes the temporary HG result
+ buffers to automatically delete themselves when hidden.
+
+HGCommandDiffOpt *HGCommandDiffOpt*
+
+ This variable, if set, determines the options passed to the diff command of
+ HG. If not set, it defaults to 'w'.
+
+HGCommandDiffSplit *HGCommandDiffSplit*
+
+ This variable overrides the |HGCommandSplit| variable, but only for buffers
+ created with |:HGVimDiff|.
+
+HGCommandEdit *HGCommandEdit*
+
+ This variable controls whether the original buffer is replaced ('edit') or
+ split ('split'). If not set, it defaults to 'edit'.
+
+HGCommandEnableBufferSetup *HGCommandEnableBufferSetup*
+
+ This variable, if set to a non-zero value, activates HG buffer management
+ mode see (|hgcommand-buffer-management|). This mode means that three
+ buffer variables, 'HGRepository', 'HGRevision' and 'HGBranch', are set if
+ the file is HG-controlled. This is useful for displaying version
+ information in the status bar.
+
+HGCommandInteractive *HGCommandInteractive*
+
+ This variable, if set to a non-zero value, causes appropriate commands (for
+ the moment, only |:HGReview|) to query the user for a revision to use
+ instead of the current revision if none is specified.
+
+HGCommandNameMarker *HGCommandNameMarker*
+
+ This variable, if set, configures the special attention-getting characters
+ that appear on either side of the hg buffer type in the buffer name. This
+ has no effect unless |HGCommandNameResultBuffers| is set to a true value.
+ If not set, it defaults to '_'.
+
+HGCommandNameResultBuffers *HGCommandNameResultBuffers*
+
+ This variable, if set to a true value, causes the hg result buffers to be
+ named in the old way ('<source file name> _<hg command>_'). If not set or
+ set to a false value, the result buffer is nameless.
+
+HGCommandSplit *HGCommandSplit*
+
+ This variable controls the orientation of the various window splits that
+ may occur (such as with HGVimDiff, when using a HG command on a HG command
+ buffer, or when the |HGCommandEdit| variable is set to 'split'. If set to
+ 'horizontal', the resulting windows will be on stacked on top of one
+ another. If set to 'vertical', the resulting windows will be side-by-side.
+ If not set, it defaults to 'horizontal' for all but HGVimDiff windows.
+
+5.2 HGCommand events *hgcommand-events*
+
+ For additional customization, HGCommand can trigger user-defined events.
+ Event handlers are provided by defining User event autocommands (see
+ |autocommand|, |User|) in the HGCommand group with patterns matching the
+ event name.
+
+ For instance, the following could be added to the vimrc to provide a 'q'
+ mapping to quit a HGCommand scratch buffer: >
+
+ augroup HGCommand
+ au HGCommand User HGBufferCreated silent! nmap <unique> <buffer> q:
+ bwipeout<cr>
+ augroup END
+<
+
+ The following hooks are available:
+
+HGBufferCreated This event is fired just after a hg command result
+ buffer is created and filled with the result of a hg
+ command. It is executed within the context of the HG
+ command buffer. The HGCommand buffer variables may be
+ useful for handlers of this event (please see
+ |hgcommand-buffer-variables|).
+
+HGBufferSetup This event is fired just after HG buffer setup occurs,
+ if enabled.
+
+HGPluginInit This event is fired when the HGCommand plugin first
+ loads.
+
+HGPluginFinish This event is fired just after the HGCommand plugin
+ loads.
+
+HGVimDiffFinish This event is fired just after the HGVimDiff command
+ executes to allow customization of, for instance,
+ window placement and focus.
+
+5.3 HGCommand buffer naming *hgcommand-naming*
+
+ By default, the buffers containing the result of HG commands are nameless
+ scratch buffers. It is intended that buffer variables of those buffers be
+ used to customize the statusline option so that the user may fully control
+ the display of result buffers.
+
+ If the old-style naming is desired, please enable the
+ |HGCommandNameResultBuffers| variable. Then, each result buffer will
+ receive a unique name that includes the source file name, the HG command,
+ and any extra data (such as revision numbers) that were part of the
+ command.
+
+5.4 HGCommand status line support *hgcommand-statusline*
+
+ It is intended that the user will customize the |'statusline'| option to
+ include HG result buffer attributes. A sample function that may be used in
+ the |'statusline'| option is provided by the plugin, HGGetStatusLine(). In
+ order to use that function in the status line, do something like the
+ following: >
+
+ set statusline=%<%f\ %{HGGetStatusLine()}\ %h%m%r%=%l,%c%V\ %P
+<
+ of which %{HGGetStatusLine()} is the relevant portion.
+
+ The sample HGGetStatusLine() function handles both HG result buffers and
+ HG-managed files if HGCommand buffer management is enabled (please see
+ |hgcommand-buffer-management|).
+
+5.5 HGCommand buffer management *hgcommand-buffer-management*
+
+ The HGCommand plugin can operate in buffer management mode, which means
+ that it attempts to set two buffer variables ('HGRevision' and 'HGBranch')
+ upon entry into a buffer. This is rather slow because it means that 'hg
+ status' will be invoked at each entry into a buffer (during the |BufEnter|
+ autocommand).
+
+ This mode is enabled by default. In order to disable it, set the
+ |HGCommandEnableBufferSetup| variable to a false (zero) value. Enabling
+ this mode simply provides the buffer variables mentioned above. The user
+ must explicitly include those in the |'statusline'| option if they are to
+ appear in the status line (but see |hgcommand-statusline| for a simple way
+ to do that).
+
+==============================================================================
+9. Tips *hgcommand-tips*
+
+9.1 Split window annotation, by Michael Anderson >
+
+ :nmap <Leader>hgN :vs<CR><C-w>h<Leader>hgn:vertical res 40<CR>
+ \ggdddd:set scb<CR>:set nowrap<CR><C-w>lgg:set scb<CR>
+ \:set nowrap<CR>
+<
+
+ This splits the buffer vertically, puts an annotation on the left (minus
+ the header) with the width set to 40. An editable/normal copy is placed on
+ the right. The two versions are scroll locked so they move as one. and
+ wrapping is turned off so that the lines line up correctly. The advantages
+ are...
+
+ 1) You get a versioning on the right.
+ 2) You can still edit your own code.
+ 3) Your own code still has syntax highlighting.
+
+==============================================================================
+
+8. Known bugs *hgcommand-bugs*
+
+ Please let me know if you run across any.
+
+ HGVimDiff, when using the original (real) source buffer as one of the diff
+ buffers, uses some hacks to try to restore the state of the original buffer
+ when the scratch buffer containing the other version is destroyed. There
+ may still be bugs in here, depending on many configuration details.
+
+==============================================================================
+
+9. TODO *hgcommand-todo*
+
+ Integrate symlink tracking once HG will support them.
+==============================================================================
+=== END_DOC
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" v im:tw=78:ts=8:ft=help:norl:
+" vim600: set foldmethod=marker tabstop=8 shiftwidth=2 softtabstop=2 smartindent smarttab :
+"fileencoding=iso-8859-15
diff --git a/sys/src/cmd/hg/contrib/vim/patchreview.txt b/sys/src/cmd/hg/contrib/vim/patchreview.txt
new file mode 100644
index 000000000..47bce4764
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/vim/patchreview.txt
@@ -0,0 +1,97 @@
+*patchreview.txt* Vim global plugin for doing single or multipatch code reviews
+
+ Author: Manpreet Singh (junkblocker-CAT-yahoo-DOG-com)
+ (Replace -CAT- and -DOG- with @ and . first)
+ Copyright (C) 2006 by Manpreet Singh
+ License : This file is placed in the public domain.
+
+=============================================================================
+
+CONTENTS *patchreview* *patchreview-contents*
+
+ 1. Contents.........................................: |patchreview-contents|
+ 2. Introduction.....................................: |patchreview-intro|
+ 3. PatchReview options..............................: |patchreview-options|
+ 4. PatchReview Usage................................: |patchreview-usage|
+ 4.1 PatchReview Usage............................: |:PatchReview|
+ 4.2 PatchReview Usage............................: |:PatchReviewCleanup|
+
+=============================================================================
+
+PatchReview Introduction *patchreview-intro*
+
+The Patch Review plugin allows single or multipatch code review to be done in
+VIM. VIM provides the |:diffpatch| command to do single file reviews but can
+not handle patch files containing multiple patches as is common with software
+development projects. This plugin provides that missing functionality. It also
+tries to improve on |:diffpatch|'s behaviour of creating the patched files in
+the same directory as original file which can lead to project workspace
+pollution.
+
+=============================================================================
+
+PatchReview Options *patchreview-options*
+
+ g:patchreview_filterdiff : Optional path to filterdiff binary. PatchReview
+ tries to locate filterdiff on system path
+ automatically. If the binary is not on system
+ path, this option tell PatchReview the full path
+ to the binary. This option, if specified,
+ overrides the default filterdiff binary on the
+ path.
+
+ examples:
+ (On Windows with Cygwin)
+
+ let g:patchreview_filterdiff = 'c:\\cygwin\\bin\\filterdiff.exe'
+
+ (On *nix systems)
+
+ let g:patchreview_filterdiff = '/usr/bin/filterdiff'
+
+ g:patchreview_patch : Optional path to patch binary. PatchReview tries
+ to locate patch on system path automatically. If
+ the binary is not on system path, this option
+ tell PatchReview the full path to the binary.
+ This option, if specified, overrides the default
+ patch binary on the path.
+
+ examples:
+ (On Windows with Cygwin)
+
+ let g:patchreview_patch = 'c:\\cygwin\\bin\\patch.exe'
+
+ (On *nix systems)
+
+ let g:patchreview_patch = '/usr/bin/gpatch'
+
+
+ g:patchreview_tmpdir : Optional path where the plugin can save temporary
+ files. If this is not specified, the plugin tries to
+ use TMP, TEMP and TMPDIR environment variables in
+ succession.
+
+ examples:
+ (On Windows) let g:patchreview_tmpdir = 'c:\\tmp'
+ (On *nix systems) let g:patchreview_tmpdir = '~/tmp'
+
+=============================================================================
+
+PatchReview Usage *patchreview-usage*
+ *:PatchReview*
+
+ :PatchReview patchfile_path [optional_source_directory]
+
+ Perform a patch review in the current directory based on the supplied
+ patchfile_path. If optional_source_directory is specified, patchreview is
+ done on that directory. Othewise, the current directory is assumed to be
+ the source directory.
+ *:PatchReviewCleanup*
+
+ :PatchReviewCleanup
+
+ After you are done using the :PatchReview command, you can cleanup the
+ temporary files in the temporary directory using this command.
+
+=============================================================================
+vim: ft=help:ts=2:sts=2:sw=2:tw=78:tw=78
diff --git a/sys/src/cmd/hg/contrib/vim/patchreview.vim b/sys/src/cmd/hg/contrib/vim/patchreview.vim
new file mode 100644
index 000000000..6235eeadd
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/vim/patchreview.vim
@@ -0,0 +1,332 @@
+" Vim global plugin for doing single or multipatch code reviews"{{{
+
+" Version : 0.1 "{{{
+" Last Modified : Thu 25 May 2006 10:15:11 PM PDT
+" Author : Manpreet Singh (junkblocker AT yahoo DOT com)
+" Copyright : 2006 by Manpreet Singh
+" License : This file is placed in the public domain.
+"
+" History : 0.1 - First released
+"}}}
+" Documentation: "{{{
+" ===========================================================================
+" This plugin allows single or multipatch code reviews to be done in VIM. Vim
+" has :diffpatch command to do single file reviews but can not handle patch
+" files containing multiple patches. This plugin provides that missing
+" functionality and doesn't require the original file to be open.
+"
+" Installing: "{{{
+"
+" For a quick start...
+"
+" Requirements: "{{{
+"
+" 1) (g)vim 7.0 or higher built with +diff option.
+" 2) patch and patchutils ( http://cyberelk.net/tim/patchutils/ ) installed
+" for your OS. For windows it is availble from Cygwin (
+" http://www.cygwin.com ) or GnuWin32 ( http://gnuwin32.sourceforge.net/
+" ).
+""}}}
+" Install: "{{{
+"
+" 1) Extract this in your $VIM/vimfiles or $HOME/.vim directory and restart
+" vim.
+"
+" 2) Make sure that you have filterdiff from patchutils and patch commands
+" installed.
+"
+" 3) Optinally, specify the locations to filterdiff and patch commands and
+" location of a temporary directory to use in your .vimrc.
+"
+" let g:patchreview_filterdiff = '/path/to/filterdiff'
+" let g:patchreview_patch = '/path/to/patch'
+" let g:patchreview_tmpdir = '/tmp/or/something'
+"
+" 4) Optionally, generate help tags to use help
+"
+" :helptags ~/.vim/doc
+" or
+" :helptags c:\vim\vimfiles\doc
+""}}}
+""}}}
+" Usage: "{{{
+"
+" :PatchReview path_to_submitted_patchfile [optional_source_directory]
+"
+" after review is done
+"
+" :PatchReviewCleanup
+"
+" See :help patchreview for details after you've created help tags.
+""}}}
+"}}}
+" Code "{{{
+
+" Enabled only during development "{{{
+" unlet! g:loaded_patchreview " DEBUG
+" unlet! g:patchreview_tmpdir " DEBUG
+" unlet! g:patchreview_filterdiff " DEBUG
+" unlet! g:patchreview_patch " DEBUG
+"}}}
+
+" load only once "{{{
+if exists('g:loaded_patchreview')
+ finish
+endif
+let g:loaded_patchreview=1
+let s:msgbufname = 'Patch Review Messages'
+"}}}
+
+function! <SID>PR_wipeMsgBuf() "{{{
+ let s:winnum = bufwinnr(s:msgbufname)
+ if s:winnum != -1 " If the window is already open, jump to it
+ let s:cur_winnr = winnr()
+ if winnr() != s:winnum
+ exe s:winnum . 'wincmd w'
+ exe 'bw'
+ exe s:cur_winnr . 'wincmd w'
+ endif
+ endif
+endfunction
+"}}}
+
+function! <SID>PR_echo(...) "{{{
+ " Usage: PR_echo(msg, [return_to_original_window_flag])
+ " default return_to_original_window_flag = 0
+ "
+ let s:cur_winnr = winnr()
+ let s:winnum = bufwinnr(s:msgbufname)
+ if s:winnum != -1 " If the window is already open, jump to it
+ if winnr() != s:winnum
+ exe s:winnum . 'wincmd w'
+ endif
+ else
+ let s:bufnum = bufnr(s:msgbufname)
+ if s:bufnum == -1
+ let s:wcmd = s:msgbufname
+ else
+ let s:wcmd = '+buffer' . s:bufnum
+ endif
+ exe 'silent! botright 5split ' . s:wcmd
+ endif
+ setlocal modifiable
+ setlocal buftype=nofile
+ setlocal bufhidden=delete
+ setlocal noswapfile
+ setlocal nowrap
+ setlocal nobuflisted
+ if a:0 != 0
+ silent! $put =a:1
+ endif
+ exe ':$'
+ setlocal nomodifiable
+ if a:0 > 1 && a:2
+ exe s:cur_winnr . 'wincmd w'
+ endif
+endfunction
+"}}}
+
+function! <SID>PR_checkBinary(BinaryName) "{{{
+ " Verify that BinaryName is specified or available
+ if ! exists('g:patchreview_' . a:BinaryName)
+ if executable(a:BinaryName)
+ let g:patchreview_{a:BinaryName} = a:BinaryName
+ return 1
+ else
+ call s:PR_echo('g:patchreview_' . a:BinaryName . ' is not defined and could not be found on path. Please define it in your .vimrc.')
+ return 0
+ endif
+ elseif ! executable(g:patchreview_{a:BinaryName})
+ call s:PR_echo('Specified g:patchreview_' . a:BinaryName . ' [' . g:patchreview_{a.BinaryName} . '] is not executable.')
+ return 0
+ else
+ return 1
+ endif
+endfunction
+"}}}
+
+function! <SID>PR_GetTempDirLocation(Quiet) "{{{
+ if exists('g:patchreview_tmpdir')
+ if ! isdirectory(g:patchreview_tmpdir) || ! filewritable(g:patchreview_tmpdir)
+ if ! a:Quiet
+ call s:PR_echo('Temporary directory specified by g:patchreview_tmpdir [' . g:patchreview_tmpdir . '] is not accessible.')
+ return 0
+ endif
+ endif
+ elseif exists("$TMP") && isdirectory($TMP) && filewritable($TMP)
+ let g:patchreview_tmpdir = $TMP
+ elseif exists("$TEMP") && isdirectory($TEMP) && filewritable($TEMP)
+ let g:patchreview_tmpdir = $TEMP
+ elseif exists("$TMPDIR") && isdirectory($TMPDIR) && filewritable($TMPDIR)
+ let g:patchreview_tmpdir = $TMPDIR
+ else
+ if ! a:Quiet
+ call s:PR_echo('Could not figure out a temporary directory to use. Please specify g:patchreview_tmpdir in your .vimrc.')
+ return 0
+ endif
+ endif
+ let g:patchreview_tmpdir = g:patchreview_tmpdir . '/'
+ let g:patchreview_tmpdir = substitute(g:patchreview_tmpdir, '\\', '/', 'g')
+ let g:patchreview_tmpdir = substitute(g:patchreview_tmpdir, '/+$', '/', '')
+ if has('win32')
+ let g:patchreview_tmpdir = substitute(g:patchreview_tmpdir, '/', '\\', 'g')
+ endif
+ return 1
+endfunction
+"}}}
+
+function! <SID>PatchReview(...) "{{{
+ " VIM 7+ required"{{{
+ if version < 700
+ call s:PR_echo('This plugin needs VIM 7 or higher')
+ return
+ endif
+"}}}
+
+ let s:save_shortmess = &shortmess
+ set shortmess+=aW
+ call s:PR_wipeMsgBuf()
+
+ " Check passed arguments "{{{
+ if a:0 == 0
+ call s:PR_echo('PatchReview command needs at least one argument specifying a patchfile path.')
+ let &shortmess = s:save_shortmess
+ return
+ endif
+ if a:0 >= 1 && a:0 <= 2
+ let s:PatchFilePath = expand(a:1, ':p')
+ if ! filereadable(s:PatchFilePath)
+ call s:PR_echo('File [' . s:PatchFilePath . '] is not accessible.')
+ let &shortmess = s:save_shortmess
+ return
+ endif
+ if a:0 == 2
+ let s:SrcDirectory = expand(a:2, ':p')
+ if ! isdirectory(s:SrcDirectory)
+ call s:PR_echo('[' . s:SrcDirectory . '] is not a directory')
+ let &shortmess = s:save_shortmess
+ return
+ endif
+ try
+ exe 'cd ' . s:SrcDirectory
+ catch /^.*E344.*/
+ call s:PR_echo('Could not change to directory [' . s:SrcDirectory . ']')
+ let &shortmess = s:save_shortmess
+ return
+ endtry
+ endif
+ else
+ call s:PR_echo('PatchReview command needs at most two arguments: patchfile path and optional source directory path.')
+ let &shortmess = s:save_shortmess
+ return
+ endif
+"}}}
+
+ " Verify that filterdiff and patch are specified or available "{{{
+ if ! s:PR_checkBinary('filterdiff') || ! s:PR_checkBinary('patch')
+ let &shortmess = s:save_shortmess
+ return
+ endif
+
+ let s:retval = s:PR_GetTempDirLocation(0)
+ if ! s:retval
+ let &shortmess = s:save_shortmess
+ return
+ endif
+"}}}
+
+ " Requirements met, now execute "{{{
+ let s:PatchFilePath = fnamemodify(s:PatchFilePath, ':p')
+ call s:PR_echo('Patch file : ' . s:PatchFilePath)
+ call s:PR_echo('Source directory: ' . getcwd())
+ call s:PR_echo('------------------')
+ let s:theFilterDiffCommand = '' . g:patchreview_filterdiff . ' --list -s ' . s:PatchFilePath
+ let s:theFilesString = system(s:theFilterDiffCommand)
+ let s:theFilesList = split(s:theFilesString, '[\r\n]')
+ for s:filewithchangetype in s:theFilesList
+ if s:filewithchangetype !~ '^[!+-] '
+ call s:PR_echo('*** Skipping review generation due to understood change for [' . s:filewithchangetype . ']', 1)
+ continue
+ endif
+ unlet! s:RelativeFilePath
+ let s:RelativeFilePath = substitute(s:filewithchangetype, '^. ', '', '')
+ let s:RelativeFilePath = substitute(s:RelativeFilePath, '^[a-z][^\\\/]*[\\\/]' , '' , '')
+ if s:filewithchangetype =~ '^! '
+ let s:msgtype = 'Modification : '
+ elseif s:filewithchangetype =~ '^+ '
+ let s:msgtype = 'Addition : '
+ elseif s:filewithchangetype =~ '^- '
+ let s:msgtype = 'Deletion : '
+ endif
+ let s:bufnum = bufnr(s:RelativeFilePath)
+ if buflisted(s:bufnum) && getbufvar(s:bufnum, '&mod')
+ call s:PR_echo('Old buffer for file [' . s:RelativeFilePath . '] exists in modified state. Skipping review.', 1)
+ continue
+ endif
+ let s:tmpname = substitute(s:RelativeFilePath, '/', '_', 'g')
+ let s:tmpname = substitute(s:tmpname, '\\', '_', 'g')
+ let s:tmpname = g:patchreview_tmpdir . 'PatchReview.' . s:tmpname . '.' . strftime('%Y%m%d%H%M%S')
+ if has('win32')
+ let s:tmpname = substitute(s:tmpname, '/', '\\', 'g')
+ endif
+ if ! exists('s:patchreview_tmpfiles')
+ let s:patchreview_tmpfiles = []
+ endif
+ let s:patchreview_tmpfiles = s:patchreview_tmpfiles + [s:tmpname]
+
+ let s:filterdiffcmd = '!' . g:patchreview_filterdiff . ' -i ' . s:RelativeFilePath . ' ' . s:PatchFilePath . ' > ' . s:tmpname
+ silent! exe s:filterdiffcmd
+ if s:filewithchangetype =~ '^+ '
+ if has('win32')
+ let s:inputfile = 'nul'
+ else
+ let s:inputfile = '/dev/null'
+ endif
+ else
+ let s:inputfile = expand(s:RelativeFilePath, ':p')
+ endif
+ silent exe '!' . g:patchreview_patch . ' -o ' . s:tmpname . '.file ' . s:inputfile . ' < ' . s:tmpname
+ let s:origtabpagenr = tabpagenr()
+ silent! exe 'tabedit ' . s:RelativeFilePath
+ silent! exe 'vert diffsplit ' . s:tmpname . '.file'
+ if filereadable(s:tmpname . '.file.rej')
+ silent! exe 'topleft 5split ' . s:tmpname . '.file.rej'
+ call s:PR_echo(s:msgtype . '*** REJECTED *** ' . s:RelativeFilePath, 1)
+ else
+ call s:PR_echo(s:msgtype . ' ' . s:RelativeFilePath, 1)
+ endif
+ silent! exe 'tabn ' . s:origtabpagenr
+ endfor
+ call s:PR_echo('-----')
+ call s:PR_echo('Done.')
+ let &shortmess = s:save_shortmess
+"}}}
+endfunction
+"}}}
+
+function! <SID>PatchReviewCleanup() "{{{
+ let s:retval = s:PR_GetTempDirLocation(1)
+ if s:retval && exists('g:patchreview_tmpdir') && isdirectory(g:patchreview_tmpdir) && filewritable(g:patchreview_tmpdir)
+ let s:zefilestr = globpath(g:patchreview_tmpdir, 'PatchReview.*')
+ let s:theFilesList = split(s:zefilestr, '\m[\r\n]\+')
+ for s:thefile in s:theFilesList
+ call delete(s:thefile)
+ endfor
+ endif
+endfunction
+"}}}
+
+" Commands "{{{
+"============================================================================
+" :PatchReview
+command! -nargs=* -complete=file PatchReview call s:PatchReview (<f-args>)
+
+
+" :PatchReviewCleanup
+command! -nargs=0 PatchReviewCleanup call s:PatchReviewCleanup ()
+"}}}
+"}}}
+
+" vim: textwidth=78 nowrap tabstop=2 shiftwidth=2 softtabstop=2 expandtab
+" vim: filetype=vim encoding=latin1 fileformat=unix foldlevel=0 foldmethod=marker
+"}}}
diff --git a/sys/src/cmd/hg/contrib/win32/ReadMe.html b/sys/src/cmd/hg/contrib/win32/ReadMe.html
new file mode 100644
index 000000000..b5c6d0e2a
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/win32/ReadMe.html
@@ -0,0 +1,163 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <title>Mercurial for Windows</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+ <style type="text/css">
+ <!--
+ html {
+ font-family: sans-serif;
+ margin: 1em 2em;
+ }
+
+ p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ }
+
+ pre {
+ margin: 0.25em 0em;
+ padding: 0.5em;
+ background-color: #EEE;
+ border: thin solid #CCC;
+ }
+
+ .indented {
+ padding-left: 10pt;
+ }
+ -->
+ </style>
+ </head>
+
+ <body>
+ <h1>Mercurial for Windows</h1>
+
+ <p>Welcome to Mercurial for Windows!</p>
+
+ <p>
+ Mercurial is a command-line application. You must run it from
+ the Windows command prompt (or if you're hard core, a <a
+ href="http://www.mingw.org/">MinGW</a> shell).
+ </p>
+
+ <p class="indented">
+ <i>Note: the standard <a href="http://www.mingw.org/">MinGW</a>
+ msys startup script uses rxvt which has problems setting up
+ standard input and output. Running bash directly works
+ correctly.</i>
+ </p>
+
+ <p>
+ For documentation, please visit the <a
+ href="http://mercurial.selenic.com/">Mercurial web site</a>.
+ You can also download a free book, <a
+ href="http://hgbook.red-bean.com/">Mercurial: The Definitive
+ Guide</a>.
+ </p>
+
+ <p>
+ By default, Mercurial installs to <tt>C:\Program
+ Files\Mercurial</tt>. The Mercurial command is called
+ <tt>hg.exe</tt>.
+ </p>
+
+ <h1>Testing Mercurial after you've installed it</h1>
+
+ <p>
+ The easiest way to check that Mercurial is installed properly is
+ to just type the following at the command prompt:
+ </p>
+
+ <pre>
+hg
+</pre>
+
+ <p>
+ This command should print a useful help message. If it does,
+ other Mercurial commands should work fine for you.
+ </p>
+
+ <h1>Configuration notes</h1>
+ <h4>Default editor</h4>
+ <p>
+ The default editor for commit messages is 'notepad'. You can set
+ the <tt>EDITOR</tt> (or <tt>HGEDITOR</tt>) environment variable
+ to specify your preference or set it in <tt>mercurial.ini</tt>:
+ </p>
+ <pre>
+[ui]
+editor = whatever
+</pre>
+
+ <h4>Configuring a Merge program</h4>
+ <p>
+ It should be emphasized that Mercurial by itself doesn't attempt
+ to do a Merge at the file level, neither does it make any
+ attempt to Resolve the conflicts.
+ </p>
+
+ <p>
+ By default, Mercurial will use the merge program defined by the
+ <tt>HGMERGE</tt> environment variable, or uses the one defined
+ in the <tt>mercurial.ini</tt> file. (see <a
+ href="http://mercurial.selenic.com/wiki/MergeProgram">MergeProgram</a>
+ on the Mercurial Wiki for more information)
+ </p>
+
+ <h1>Reporting problems</h1>
+
+ <p>
+ Before you report any problems, please consult the <a
+ href="http://mercurial.selenic.com/">Mercurial web site</a>
+ and see if your question is already in our list of <a
+ href="http://mercurial.selenic.com/wiki/FAQ">Frequently
+ Answered Questions</a> (the "FAQ").
+ </p>
+
+ <p>
+ If you cannot find an answer to your question, please feel free
+ to send mail to the Mercurial mailing list, at <a
+ href="mailto:mercurial@selenic.com">mercurial@selenic.com</a>.
+ <b>Remember</b>, the more useful information you include in your
+ report, the easier it will be for us to help you!
+ </p>
+
+ <p>
+ If you are IRC-savvy, that's usually the fastest way to get
+ help. Go to <tt>#mercurial</tt> on <tt>irc.freenode.net</tt>.
+ </p>
+
+ <h1>Author and copyright information</h1>
+
+ <p>
+ Mercurial was written by <a href="http://www.selenic.com">Matt
+ Mackall</a>, and is maintained by Matt and a team of volunteers.
+ </p>
+
+ <p>
+ The Windows installer was written by <a
+ href="http://www.serpentine.com/blog">Bryan O'Sullivan</a>.
+ </p>
+
+ <p>
+ Mercurial is Copyright 2005-2009 Matt Mackall and others. See
+ the <tt>Contributors.txt</tt> file for a list of contributors.
+ </p>
+
+ <p>
+ Mercurial is free software; you can redistribute it and/or
+ modify it under the terms of the <a
+ href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">GNU
+ General Public License version 2</a> as published by the Free
+ Software Foundation.
+ </p>
+
+ <p>
+ Mercurial is distributed in the hope that it will be useful, but
+ <b>without any warranty</b>; without even the implied warranty
+ of <b>merchantability</b> or <b>fitness for a particular
+ purpose</b>. See the GNU General Public License for more
+ details.
+ </p>
+ </body>
+</html>
diff --git a/sys/src/cmd/hg/contrib/win32/hg.bat b/sys/src/cmd/hg/contrib/win32/hg.bat
new file mode 100644
index 000000000..3da573894
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/win32/hg.bat
@@ -0,0 +1,12 @@
+@echo off
+rem Windows Driver script for Mercurial
+
+setlocal
+set HG=%~f0
+
+rem Use a full path to Python (relative to this script) as the standard Python
+rem install does not put python.exe on the PATH...
+rem %~dp0 is the directory of this script
+
+%~dp0..\python "%~dp0hg" %*
+endlocal
diff --git a/sys/src/cmd/hg/contrib/win32/mercurial.ico b/sys/src/cmd/hg/contrib/win32/mercurial.ico
new file mode 100644
index 000000000..046808d54
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/win32/mercurial.ico
Binary files differ
diff --git a/sys/src/cmd/hg/contrib/win32/mercurial.ini b/sys/src/cmd/hg/contrib/win32/mercurial.ini
new file mode 100644
index 000000000..b8ec7d1b5
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/win32/mercurial.ini
@@ -0,0 +1,124 @@
+; System-wide Mercurial config file.
+;
+; !!! Do Not Edit This File !!!
+;
+; This file will be replaced by the installer on every upgrade.
+; Editing this file can cause strange side effects on Vista.
+;
+; http://bitbucket.org/tortoisehg/stable/issue/135
+;
+; To change settings you see in this file, override (or enable) them in
+; your user Mercurial.ini file, where USERNAME is your Windows user name:
+;
+; XP or older - C:\Documents and Settings\USERNAME\Mercurial.ini
+; Vista or later - C:\Users\USERNAME\Mercurial.ini
+
+
+[ui]
+; editor used to enter commit logs, etc. Most text editors will work.
+editor = notepad
+; show changed files and be a bit more verbose if True
+; verbose = True
+
+; username data to appear in commits
+; it usually takes the form: Joe User <joe.user@host.com>
+; username = Joe User <j.user@example.com>
+
+; In order to push/pull over ssh you must specify an ssh tool
+;ssh = "C:\Progra~1\TortoiseSVN\bin\TortoisePlink.exe" -ssh -2
+;ssh = C:\cygwin\bin\ssh
+
+;
+; For more information about mercurial extensions, start here
+; http://www.selenic.com/mercurial/wiki/index.cgi/UsingExtensions
+;
+; Extensions shipped with Mercurial
+;
+[extensions]
+;acl =
+;alias =
+;bookmarks =
+;bugzilla =
+;children =
+;churn =
+;color =
+;convert =
+;extdiff =
+;fetch =
+;gpg =
+;graphlog =
+;hgcia =
+;hgk =
+;highlight =
+;interhg =
+;keyword =
+;mq =
+;notify =
+;pager =
+;parentrevspec =
+;patchbomb =
+;purge =
+;rebase =
+;record =
+;transplant =
+;win32mbcs =
+;win32text =
+;zeroconf =
+
+; To use cleverencode/cleverdecode, you must enable win32text extension
+
+[encode]
+; Encode files that don't contain NUL characters.
+
+; ** = cleverencode:
+
+; Alternatively, you can explicitly specify each file extension that
+; you want encoded (any you omit will be left untouched), like this:
+
+; *.txt = dumbencode:
+
+
+[decode]
+; Decode files that don't contain NUL characters.
+
+; ** = cleverdecode:
+
+; Alternatively, you can explicitly specify each file extension that
+; you want decoded (any you omit will be left untouched), like this:
+
+; **.txt = dumbdecode:
+
+[patch]
+; If you enable win32text filtering, you will want to enable this
+; line as well to allow patching to work correctly.
+
+; eol = crlf
+
+
+;
+; Define external diff commands
+;
+[extdiff]
+;cmd.bc3diff = C:\Program Files\Beyond Compare 3\BCompare.exe
+;cmd.vdiff = C:\Progra~1\TortoiseSVN\bin\TortoiseMerge.exe
+;cmd.vimdiff = gvim.exe
+;opts.vimdiff = -f '+next' '+execute "DirDiff ".argv(0)." ".argv(1)'
+
+
+[hgk]
+; Replace the following with your path to hgk, uncomment it and
+; install ActiveTcl (or another win32 port like tclkit)
+; path="C:\Program Files\Mercurial\Contrib\hgk.tcl"
+; vdiff=vdiff
+
+
+;
+; The git extended diff format can represent binary files, file
+; permission changes, and rename information that the normal patch format
+; cannot describe. However it is also not compatible with tools which
+; expect normal patches. so enable git patches at your own risk.
+;
+[diff]
+;git = false
+;nodates = false
+
diff --git a/sys/src/cmd/hg/contrib/win32/mercurial.iss b/sys/src/cmd/hg/contrib/win32/mercurial.iss
new file mode 100644
index 000000000..cd3bc1c94
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/win32/mercurial.iss
@@ -0,0 +1,103 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+[Setup]
+AppCopyright=Copyright 2005-2009 Matt Mackall and others
+AppName=Mercurial
+AppVerName=Mercurial snapshot
+InfoAfterFile=contrib/win32/postinstall.txt
+LicenseFile=COPYING
+ShowLanguageDialog=yes
+AppPublisher=Matt Mackall and others
+AppPublisherURL=http://mercurial.selenic.com/
+AppSupportURL=http://mercurial.selenic.com/
+AppUpdatesURL=http://mercurial.selenic.com/
+AppID={{4B95A5F1-EF59-4B08-BED8-C891C46121B3}
+AppContact=mercurial@selenic.com
+OutputBaseFilename=Mercurial-snapshot
+DefaultDirName={pf}\Mercurial
+SourceDir=..\..
+VersionInfoDescription=Mercurial distributed SCM
+VersionInfoCopyright=Copyright 2005-2009 Matt Mackall and others
+VersionInfoCompany=Matt Mackall and others
+InternalCompressLevel=max
+SolidCompression=true
+SetupIconFile=contrib\win32\mercurial.ico
+AllowNoIcons=true
+DefaultGroupName=Mercurial
+PrivilegesRequired=none
+
+[Files]
+Source: contrib\mercurial.el; DestDir: {app}/Contrib
+Source: contrib\vim\*.*; DestDir: {app}/Contrib/Vim
+Source: contrib\zsh_completion; DestDir: {app}/Contrib
+Source: contrib\hgk; DestDir: {app}/Contrib; DestName: hgk.tcl
+Source: contrib\win32\ReadMe.html; DestDir: {app}; Flags: isreadme
+Source: contrib\mergetools.hgrc; DestDir: {tmp};
+Source: contrib\win32\mercurial.ini; DestDir: {app}; DestName: Mercurial.ini; Check: CheckFile; AfterInstall: ConcatenateFiles;
+Source: contrib\win32\postinstall.txt; DestDir: {app}; DestName: ReleaseNotes.txt
+Source: dist\hg.exe; DestDir: {app}; AfterInstall: Touch('{app}\hg.exe.local')
+Source: dist\python*.dll; Destdir: {app}; Flags: skipifsourcedoesntexist
+Source: dist\library.zip; DestDir: {app}
+Source: dist\mfc*.dll; DestDir: {app}
+Source: dist\msvc*.dll; DestDir: {app}
+Source: dist\Microsoft.VC*.CRT.manifest; DestDir: {app}; Flags: skipifsourcedoesntexist
+Source: dist\Microsoft.VC*.MFC.manifest; DestDir: {app}; Flags: skipifsourcedoesntexist
+Source: dist\w9xpopen.exe; DestDir: {app}
+Source: dist\add_path.exe; DestDir: {app}
+Source: doc\*.html; DestDir: {app}\Docs
+Source: locale\*.*; DestDir: {app}\locale; Flags: recursesubdirs createallsubdirs
+Source: templates\*.*; DestDir: {app}\Templates; Flags: recursesubdirs createallsubdirs
+Source: CONTRIBUTORS; DestDir: {app}; DestName: Contributors.txt
+Source: COPYING; DestDir: {app}; DestName: Copying.txt
+
+[INI]
+Filename: {app}\Mercurial.url; Section: InternetShortcut; Key: URL; String: http://mercurial.selenic.com/
+
+[UninstallDelete]
+Type: files; Name: {app}\Mercurial.url
+
+[Icons]
+Name: {group}\Uninstall Mercurial; Filename: {uninstallexe}
+Name: {group}\Mercurial Command Reference; Filename: {app}\Docs\hg.1.html
+Name: {group}\Mercurial Configuration Files; Filename: {app}\Docs\hgrc.5.html
+Name: {group}\Mercurial Ignore Files; Filename: {app}\Docs\hgignore.5.html
+Name: {group}\Mercurial Web Site; Filename: {app}\Mercurial.url
+
+[Run]
+Filename: "{app}\add_path.exe"; Parameters: "{app}"; Flags: postinstall; Description: "Add the installation path to the search path"
+
+[UninstallRun]
+Filename: "{app}\add_path.exe"; Parameters: "/del {app}"
+
+[UninstallDelete]
+Type: files; Name: "{app}\hg.exe.local"
+[Code]
+var
+ WriteFile: Boolean;
+ CheckDone: Boolean;
+
+function CheckFile(): Boolean;
+begin
+ if not CheckDone then begin
+ WriteFile := True;
+ if FileExists(ExpandConstant(CurrentFileName)) then begin
+ WriteFile := MsgBox('' + ExpandConstant(CurrentFileName) + '' #13#13 'The file already exists.' #13#13 'Would you like Setup to overwrite it?', mbConfirmation, MB_YESNO) = idYes;
+ end;
+ CheckDone := True;
+ end;
+ Result := WriteFile;
+end;
+
+procedure ConcatenateFiles();
+var
+ MergeConfigs: TArrayOfString;
+begin
+ if LoadStringsFromFile(ExpandConstant('{tmp}\mergetools.hgrc'),MergeConfigs) then begin
+ SaveStringsToFile(ExpandConstant(CurrentFileName),MergeConfigs,True);
+ end;
+end;
+
+procedure Touch(fn: String);
+begin
+ SaveStringToFile(ExpandConstant(fn), '', False);
+end;
diff --git a/sys/src/cmd/hg/contrib/win32/postinstall.txt b/sys/src/cmd/hg/contrib/win32/postinstall.txt
new file mode 100644
index 000000000..786dc4837
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/win32/postinstall.txt
@@ -0,0 +1,9 @@
+Welcome to Mercurial for Windows!
+---------------------------------
+
+For configuration and usage directions, please read the ReadMe.html
+file that comes with this package.
+
+Also check the release notes at:
+
+ http://mercurial.selenic.com/wiki/WhatsNew
diff --git a/sys/src/cmd/hg/contrib/win32/win32-build.txt b/sys/src/cmd/hg/contrib/win32/win32-build.txt
new file mode 100644
index 000000000..7402658c0
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/win32/win32-build.txt
@@ -0,0 +1,114 @@
+The standalone Windows installer for Mercurial is built in a somewhat
+jury-rigged fashion.
+
+It has the following prerequisites, at least as I build it:
+
+ Python for Windows
+ http://www.python.org/ftp/python/2.4.3/python-2.4.3.msi
+
+ MinGW
+ http://www.mingw.org/
+
+ Python for Windows Extensions
+ http://sourceforge.net/projects/pywin32/
+
+ mfc71.dll (just download, don't install; not needed for Python 2.6)
+ http://starship.python.net/crew/mhammond/win32/
+
+ Visual C++ 2008 redistributable package (needed for Python 2.6)
+ http://www.microsoft.com/downloads/details.aspx?familyid=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&displaylang=en
+
+ The py2exe distutils extension
+ http://sourceforge.net/projects/py2exe/
+
+ GnuWin32 gettext utility
+ http://gnuwin32.sourceforge.net/packages/gettext.htm
+
+ Inno Setup
+ http://www.jrsoftware.org/isinfo.php
+
+ ISTool - optional
+ http://www.istool.org/default.aspx/
+
+ add_path (you need only add_path.exe in the zip file)
+ http://www.barisione.org/apps.html#add_path
+
+ Docutils
+ http://docutils.sourceforge.net/
+
+And, of course, Mercurial itself.
+
+Once you have all this installed and built, clone a copy of the
+Mercurial repository you want to package, and name the repo
+C:\hg\hg-release.
+
+In a shell, build a standalone copy of the hg.exe program:
+
+ python setup.py build -c mingw32
+ python setup.py py2exe -b 1
+
+Note: the previously suggested combined command of "python setup.py build -c
+mingw32 py2exe -b 1" doesn't work correctly anymore as it doesn't include the
+extensions in the mercurial subdirectory.
+
+If you want to create a file named setup.cfg with the contents:
+
+[build]
+compiler=mingw32
+
+you can skip the first build step.
+
+Copy add_path.exe into the dist directory that just got created.
+
+If you are using Python up to version 2.5.4, copy mfc71.dll into the dist
+directory that just got created.
+
+If you are using Python 2.6 or later, after installing the Visual C++ 2008
+redistributable package copy into the dist directory that just got created the
+following files:
+ - from the directory starting with
+ Windows/WinSxS/x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8
+ the files named: msvcm90.dll, msvcp90.dll and msvcr90.dll
+ - from the directory starting with
+ Windows/WinSxS/x86_Microsoft.VC90.MFC_1fc8b3b9a1e18e3b_9.0.21022.8
+ the files named: mfc90.dll, mfc90u.dll, mfcm90.dll and mfcm90u.dll
+ - from the directory named Windows/WinSxS/Manifests, the manifest file
+ starting with x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8
+ (rename it to Microsoft.VC90.CRT.manifest) and the manifest file starting
+ with x86_Microsoft.VC90.MFC_1fc8b3b9a1e18e3b_9.0.21022.8 (rename it to
+ Microsoft.VC90.MFC.manifest)
+
+Before building the installer, you have to build Mercurial HTML documentation
+(or fix mercurial.iss to not reference the doc directory). Docutils does not
+come with a ready-made script for rst2html.py, so you will have to write your
+own and put it in %PATH% like:
+
+ @python c:\pythonXX\scripts\rst2html.py %*
+
+Then build the documentation with:
+
+ cd doc
+ mingw32-make RST2HTML=rst2html.bat html
+ cd ..
+
+If you use ISTool, you open the C:\hg\hg-release\contrib\win32\mercurial.iss
+file and type Ctrl-F9 to compile the installer file.
+
+Otherwise you run the Inno Setup compiler. Assuming it's on the path you run:
+
+ iscc contrib\win32\mercurial.iss
+
+The actual installer will be in the C:\hg\hg-release\Output directory.
+
+To automate the steps above you may want to create a batchfile based on the
+following:
+
+ echo [build] > setup.cfg
+ echo compiler=mingw32 >> setup.cfg
+ python setup.py py2exe -b 1
+ cd doc
+ mingw32-make RST2HTML=rst2html.bat html
+ cd ..
+ iscc contrib\win32\mercurial.iss
+
+and run it from the root of the hg repository (c:\hg\hg-release).
diff --git a/sys/src/cmd/hg/contrib/zsh_completion b/sys/src/cmd/hg/contrib/zsh_completion
new file mode 100644
index 000000000..ef124ef6e
--- /dev/null
+++ b/sys/src/cmd/hg/contrib/zsh_completion
@@ -0,0 +1,946 @@
+#compdef hg
+
+# Zsh completion script for mercurial. Rename this file to _hg and copy
+# it into your zsh function path (/usr/share/zsh/site-functions for
+# instance)
+#
+# If you do not want to install it globally, you can copy it somewhere
+# else and add that directory to $fpath. This must be done before
+# compinit is called. If the file is copied to ~/.zsh.d, your ~/.zshrc
+# file could look like this:
+#
+# fpath=("$HOME/.zsh.d" $fpath)
+# autoload -U compinit
+# compinit
+#
+# Copyright (C) 2005, 2006 Steve Borho <steve@borho.org>
+# Copyright (C) 2006-9 Brendan Cully <brendan@kublai.com>
+#
+# Permission is hereby granted, without written agreement and without
+# licence or royalty fees, to use, copy, modify, and distribute this
+# software and to distribute modified versions of this software for any
+# purpose, provided that the above copyright notice and the following
+# two paragraphs appear in all copies of this software.
+#
+# In no event shall the authors be liable to any party for direct,
+# indirect, special, incidental, or consequential damages arising out of
+# the use of this software and its documentation, even if the authors
+# have been advised of the possibility of such damage.
+#
+# The authors specifically disclaim any warranties, including, but not
+# limited to, the implied warranties of merchantability and fitness for
+# a particular purpose. The software provided hereunder is on an "as
+# is" basis, and the authors have no obligation to provide maintenance,
+# support, updates, enhancements, or modifications.
+
+emulate -LR zsh
+setopt extendedglob
+
+local curcontext="$curcontext" state line
+typeset -A _hg_cmd_globals
+
+_hg() {
+ local cmd _hg_root
+ integer i=2
+ _hg_cmd_globals=()
+
+ while (( i < $#words ))
+ do
+ case "$words[$i]" in
+ -R|--repository)
+ eval _hg_root="$words[$i+1]"
+ _hg_cmd_globals+=("$words[$i]" "$_hg_root")
+ (( i += 2 ))
+ continue
+ ;;
+ -R*)
+ _hg_cmd_globals+="$words[$i]"
+ eval _hg_root="${words[$i]#-R}"
+ (( i++ ))
+ continue
+ ;;
+ --cwd|--config)
+ # pass along arguments to hg completer
+ _hg_cmd_globals+=("$words[$i]" "$words[$i+1]")
+ (( i += 2 ))
+ continue
+ ;;
+ -*)
+ # skip option
+ (( i++ ))
+ continue
+ ;;
+ esac
+ if [[ -z "$cmd" ]]
+ then
+ cmd="$words[$i]"
+ words[$i]=()
+ (( CURRENT-- ))
+ fi
+ (( i++ ))
+ done
+
+ if [[ -z "$cmd" ]]
+ then
+ _arguments -s -w : $_hg_global_opts \
+ ':mercurial command:_hg_commands'
+ return
+ fi
+
+ # resolve abbreviations and aliases
+ if ! (( $+functions[_hg_cmd_${cmd}] ))
+ then
+ local cmdexp
+ (( $#_hg_cmd_list )) || _hg_get_commands
+
+ cmdexp=$_hg_cmd_list[(r)${cmd}*]
+ if [[ $cmdexp == $_hg_cmd_list[(R)${cmd}*] ]]
+ then
+ # might be nice to rewrite the command line with the expansion
+ cmd="$cmdexp"
+ fi
+ if [[ -n $_hg_alias_list[$cmd] ]]
+ then
+ cmd=$_hg_alias_list[$cmd]
+ fi
+ fi
+
+ curcontext="${curcontext%:*:*}:hg-${cmd}:"
+
+ zstyle -s ":completion:$curcontext:" cache-policy update_policy
+
+ if [[ -z "$update_policy" ]]
+ then
+ zstyle ":completion:$curcontext:" cache-policy _hg_cache_policy
+ fi
+
+ if (( $+functions[_hg_cmd_${cmd}] ))
+ then
+ _hg_cmd_${cmd}
+ else
+ # complete unknown commands normally
+ _arguments -s -w : $_hg_global_opts \
+ '*:files:_hg_files'
+ fi
+}
+
+_hg_cache_policy() {
+ typeset -a old
+
+ # cache for a minute
+ old=( "$1"(mm+10) )
+ (( $#old )) && return 0
+
+ return 1
+}
+
+_hg_get_commands() {
+ typeset -ga _hg_cmd_list
+ typeset -gA _hg_alias_list
+ local hline cmd cmdalias
+
+ _call_program hg hg debugcomplete -v | while read -A hline
+ do
+ cmd=$hline[1]
+ _hg_cmd_list+=($cmd)
+
+ for cmdalias in $hline[2,-1]
+ do
+ _hg_cmd_list+=($cmdalias)
+ _hg_alias_list+=($cmdalias $cmd)
+ done
+ done
+}
+
+_hg_commands() {
+ (( $#_hg_cmd_list )) || _hg_get_commands
+ _describe -t commands 'mercurial command' _hg_cmd_list
+}
+
+_hg_revrange() {
+ compset -P 1 '*:'
+ _hg_tags "$@"
+}
+
+_hg_tags() {
+ typeset -a tags
+ local tag rev
+
+ _hg_cmd tags | while read tag
+ do
+ tags+=(${tag/ # [0-9]#:*})
+ done
+ (( $#tags )) && _describe -t tags 'tags' tags
+}
+
+# likely merge candidates
+_hg_mergerevs() {
+ typeset -a heads
+ local myrev
+
+ heads=(${(f)"$(_hg_cmd heads --template '{rev}\\n')"})
+ # exclude own revision
+ myrev=$(_hg_cmd log -r . --template '{rev}\\n')
+ heads=(${heads:#$myrev})
+
+ (( $#heads )) && _describe -t heads 'heads' heads
+}
+
+_hg_files() {
+ if [[ -n "$_hg_root" ]]
+ then
+ [[ -d "$_hg_root/.hg" ]] || return
+ case "$_hg_root" in
+ /*)
+ _files -W $_hg_root
+ ;;
+ *)
+ _files -W $PWD/$_hg_root
+ ;;
+ esac
+ else
+ _files
+ fi
+}
+
+_hg_status() {
+ [[ -d $PREFIX ]] || PREFIX=$PREFIX:h
+ status_files=(${(ps:\0:)"$(_hg_cmd status -0n$1 ./$PREFIX)"})
+}
+
+_hg_unknown() {
+ typeset -a status_files
+ _hg_status u
+ _wanted files expl 'unknown files' _multi_parts / status_files
+}
+
+_hg_missing() {
+ typeset -a status_files
+ _hg_status d
+ _wanted files expl 'missing files' _multi_parts / status_files
+}
+
+_hg_modified() {
+ typeset -a status_files
+ _hg_status m
+ _wanted files expl 'modified files' _multi_parts / status_files
+}
+
+_hg_resolve() {
+ local rstate rpath
+
+ [[ -d $PREFIX ]] || PREFIX=$PREFIX:h
+
+ _hg_cmd resolve -l ./$PREFIX | while read rstate rpath
+ do
+ [[ $rstate == 'R' ]] && resolved_files+=($rpath)
+ [[ $rstate == 'U' ]] && unresolved_files+=($rpath)
+ done
+}
+
+_hg_resolved() {
+ typeset -a resolved_files unresolved_files
+ _hg_resolve
+ _wanted files expl 'resolved files' _multi_parts / resolved_files
+}
+
+_hg_unresolved() {
+ typeset -a resolved_files unresolved_files
+ _hg_resolve
+ _wanted files expl 'unresolved files' _multi_parts / unresolved_files
+}
+
+_hg_config() {
+ typeset -a items
+ items=(${${(%f)"$(_call_program hg hg showconfig)"}%%\=*})
+ (( $#items )) && _describe -t config 'config item' items
+}
+
+_hg_addremove() {
+ _alternative 'files:unknown files:_hg_unknown' \
+ 'files:missing files:_hg_missing'
+}
+
+_hg_ssh_urls() {
+ if [[ -prefix */ ]]
+ then
+ if zstyle -T ":completion:${curcontext}:files" remote-access
+ then
+ local host=${PREFIX%%/*}
+ typeset -a remdirs
+ compset -p $(( $#host + 1 ))
+ local rempath=${(M)PREFIX##*/}
+ local cacheid="hg:${host}-${rempath//\//_}"
+ cacheid=${cacheid%[-_]}
+ compset -P '*/'
+ if _cache_invalid "$cacheid" || ! _retrieve_cache "$cacheid"
+ then
+ remdirs=(${${(M)${(f)"$(_call_program files ssh -a -x $host ls -1FL "${(q)rempath}")"}##*/}%/})
+ _store_cache "$cacheid" remdirs
+ fi
+ _describe -t directories 'remote directory' remdirs -S/
+ else
+ _message 'remote directory'
+ fi
+ else
+ if compset -P '*@'
+ then
+ _hosts -S/
+ else
+ _alternative 'hosts:remote host name:_hosts -S/' \
+ 'users:user:_users -S@'
+ fi
+ fi
+}
+
+_hg_urls() {
+ if compset -P bundle://
+ then
+ _files
+ elif compset -P ssh://
+ then
+ _hg_ssh_urls
+ elif [[ -prefix *: ]]
+ then
+ _urls
+ else
+ local expl
+ compset -S '[^:]*'
+ _wanted url-schemas expl 'URL schema' compadd -S '' - \
+ http:// https:// ssh:// bundle://
+ fi
+}
+
+_hg_paths() {
+ typeset -a paths pnames
+ _hg_cmd paths | while read -A pnames
+ do
+ paths+=($pnames[1])
+ done
+ (( $#paths )) && _describe -t path-aliases 'repository alias' paths
+}
+
+_hg_remote() {
+ _alternative 'path-aliases:repository alias:_hg_paths' \
+ 'directories:directory:_files -/' \
+ 'urls:URL:_hg_urls'
+}
+
+_hg_clone_dest() {
+ _alternative 'directories:directory:_files -/' \
+ 'urls:URL:_hg_urls'
+}
+
+# Common options
+_hg_global_opts=(
+ '(--repository -R)'{-R+,--repository}'[repository root directory]:repository:_files -/'
+ '--cwd[change working directory]:new working directory:_files -/'
+ '(--noninteractive -y)'{-y,--noninteractive}'[do not prompt, assume yes for any required answers]'
+ '(--verbose -v)'{-v,--verbose}'[enable additional output]'
+ '*--config[set/override config option]:defined config items:_hg_config'
+ '(--quiet -q)'{-q,--quiet}'[suppress output]'
+ '(--help -h)'{-h,--help}'[display help and exit]'
+ '--debug[debug mode]'
+ '--debugger[start debugger]'
+ '--encoding[set the charset encoding (default: UTF8)]'
+ '--encodingmode[set the charset encoding mode (default: strict)]'
+ '--lsprof[print improved command execution profile]'
+ '--traceback[print traceback on exception]'
+ '--time[time how long the command takes]'
+ '--profile[profile]'
+ '--version[output version information and exit]'
+)
+
+_hg_pat_opts=(
+ '*'{-I+,--include}'[include names matching the given patterns]:dir:_files -W $(_hg_cmd root) -/'
+ '*'{-X+,--exclude}'[exclude names matching the given patterns]:dir:_files -W $(_hg_cmd root) -/')
+
+_hg_diff_opts=(
+ '(--text -a)'{-a,--text}'[treat all files as text]'
+ '(--git -g)'{-g,--git}'[use git extended diff format]'
+ "--nodates[don't include dates in diff headers]")
+
+_hg_dryrun_opts=(
+ '(--dry-run -n)'{-n,--dry-run}'[do not perform actions, just print output]')
+
+_hg_style_opts=(
+ '--style[display using template map file]:'
+ '--template[display with template]:')
+
+_hg_commit_opts=(
+ '(-m --message -l --logfile --edit -e)'{-e,--edit}'[edit commit message]'
+ '(-e --edit -l --logfile --message -m)'{-m+,--message}'[use <text> as commit message]:message:'
+ '(-e --edit -m --message --logfile -l)'{-l+,--logfile}'[read the commit message from <file>]:log file:_files')
+
+_hg_remote_opts=(
+ '(--ssh -e)'{-e+,--ssh}'[specify ssh command to use]:'
+ '--remotecmd[specify hg command to run on the remote side]:')
+
+_hg_cmd() {
+ _call_program hg hg --config ui.verbose=0 --config defaults."$1"= \
+ "$_hg_cmd_globals[@]" "$@" 2> /dev/null
+}
+
+_hg_cmd_add() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_dryrun_opts \
+ '*:unknown files:_hg_unknown'
+}
+
+_hg_cmd_addremove() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_dryrun_opts \
+ '(--similarity -s)'{-s+,--similarity}'[guess renamed files by similarity (0<=s<=100)]:' \
+ '*:unknown or missing files:_hg_addremove'
+}
+
+_hg_cmd_annotate() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--rev -r)'{-r+,--rev}'[annotate the specified revision]:revision:_hg_tags' \
+ '(--follow -f)'{-f,--follow}'[follow file copies and renames]' \
+ '(--text -a)'{-a,--text}'[treat all files as text]' \
+ '(--user -u)'{-u,--user}'[list the author]' \
+ '(--date -d)'{-d,--date}'[list the date]' \
+ '(--number -n)'{-n,--number}'[list the revision number (default)]' \
+ '(--changeset -c)'{-c,--changeset}'[list the changeset]' \
+ '*:files:_hg_files'
+}
+
+_hg_cmd_archive() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '--no-decode[do not pass files through decoders]' \
+ '(--prefix -p)'{-p+,--prefix}'[directory prefix for files in archive]:' \
+ '(--rev -r)'{-r+,--rev}'[revision to distribute]:revision:_hg_tags' \
+ '(--type -t)'{-t+,--type}'[type of distribution to create]:archive type:(files tar tbz2 tgz uzip zip)' \
+ '*:destination:_files'
+}
+
+_hg_cmd_backout() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '--merge[merge with old dirstate parent after backout]' \
+ '(--date -d)'{-d+,--date}'[record datecode as commit date]:date code:' \
+ '--parent[parent to choose when backing out merge]' \
+ '(--user -u)'{-u+,--user}'[record user as commiter]:user:' \
+ '(--rev -r)'{-r+,--rev}'[revision]:revision:_hg_tags' \
+ '(--message -m)'{-m+,--message}'[use <text> as commit message]:text:' \
+ '(--logfile -l)'{-l+,--logfile}'[read commit message from <file>]:log file:_files -g \*.txt'
+}
+
+_hg_cmd_bisect() {
+ _arguments -s -w : $_hg_global_opts \
+ '(-)'{-r,--reset}'[reset bisect state]' \
+ '(--good -g --bad -b --skip -s --reset -r)'{-g,--good}'[mark changeset good]'::revision:_hg_tags \
+ '(--good -g --bad -b --skip -s --reset -r)'{-b,--bad}'[mark changeset bad]'::revision:_hg_tags \
+ '(--good -g --bad -b --skip -s --reset -r)'{-s,--skip}'[skip testing changeset]' \
+ '(--command -c --noupdate -U)'{-c+,--command}'[use command to check changeset state]':commands:_command_names \
+ '(--command -c --noupdate -U)'{-U,--noupdate}'[do not update to target]'
+}
+
+_hg_cmd_branch() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--force -f)'{-f,--force}'[set branch name even if it shadows an existing branch]' \
+ '(--clean -C)'{-C,--clean}'[reset branch name to parent branch name]'
+}
+
+_hg_cmd_branches() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--active -a)'{-a,--active}'[show only branches that have unmerge heads]'
+}
+
+_hg_cmd_bundle() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts \
+ '(--force -f)'{-f,--force}'[run even when remote repository is unrelated]' \
+ '(2)*--base[a base changeset to specify instead of a destination]:revision:_hg_tags' \
+ ':output file:_files' \
+ ':destination repository:_files -/'
+}
+
+_hg_cmd_cat() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--output -o)'{-o+,--output}'[print output to file with formatted name]:filespec:' \
+ '(--rev -r)'{-r+,--rev}'[revision]:revision:_hg_tags' \
+ '*:file:_hg_files'
+}
+
+_hg_cmd_clone() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts \
+ '(--noupdate -U)'{-U,--noupdate}'[do not update the new working directory]' \
+ '(--rev -r)'{-r+,--rev}'[a changeset you would like to have after cloning]:' \
+ '--uncompressed[use uncompressed transfer (fast over LAN)]' \
+ ':source repository:_hg_remote' \
+ ':destination:_hg_clone_dest'
+}
+
+_hg_cmd_commit() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--addremove -A)'{-A,--addremove}'[mark new/missing files as added/removed before committing]' \
+ '(--message -m)'{-m+,--message}'[use <text> as commit message]:text:' \
+ '(--logfile -l)'{-l+,--logfile}'[read commit message from <file>]:log file:_files -g \*.txt' \
+ '(--date -d)'{-d+,--date}'[record datecode as commit date]:date code:' \
+ '(--user -u)'{-u+,--user}'[record user as commiter]:user:' \
+ '*:file:_hg_files'
+}
+
+_hg_cmd_copy() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_dryrun_opts \
+ '(--after -A)'{-A,--after}'[record a copy that has already occurred]' \
+ '(--force -f)'{-f,--force}'[forcibly copy over an existing managed file]' \
+ '*:file:_hg_files'
+}
+
+_hg_cmd_diff() {
+ typeset -A opt_args
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_diff_opts \
+ '*'{-r,--rev}'+[revision]:revision:_hg_revrange' \
+ '(--show-function -p)'{-p,--show-function}'[show which function each change is in]' \
+ '(--ignore-all-space -w)'{-w,--ignore-all-space}'[ignore white space when comparing lines]' \
+ '(--ignore-space-change -b)'{-b,--ignore-space-change}'[ignore changes in the amount of white space]' \
+ '(--ignore-blank-lines -B)'{-B,--ignore-blank-lines}'[ignore changes whose lines are all blank]' \
+ '*:file:->diff_files'
+
+ if [[ $state == 'diff_files' ]]
+ then
+ if [[ -n $opt_args[-r] ]]
+ then
+ _hg_files
+ else
+ _hg_modified
+ fi
+ fi
+}
+
+_hg_cmd_export() {
+ _arguments -s -w : $_hg_global_opts $_hg_diff_opts \
+ '(--outout -o)'{-o+,--output}'[print output to file with formatted name]:filespec:' \
+ '--switch-parent[diff against the second parent]' \
+ '*:revision:_hg_tags'
+}
+
+_hg_cmd_grep() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--print0 -0)'{-0,--print0}'[end filenames with NUL]' \
+ '--all[print all revisions with matches]' \
+ '(--follow -f)'{-f,--follow}'[follow changeset or file history]' \
+ '(--ignore-case -i)'{-i,--ignore-case}'[ignore case when matching]' \
+ '(--files-with-matches -l)'{-l,--files-with-matches}'[print only filenames and revs that match]' \
+ '(--line-number -n)'{-n,--line-number}'[print matching line numbers]' \
+ '*'{-r+,--rev}'[search in given revision range]:revision:_hg_revrange' \
+ '(--user -u)'{-u,--user}'[print user who committed change]' \
+ '1:search pattern:' \
+ '*:files:_hg_files'
+}
+
+_hg_cmd_heads() {
+ _arguments -s -w : $_hg_global_opts $_hg_style_opts \
+ '(--rev -r)'{-r+,--rev}'[show only heads which are descendants of rev]:revision:_hg_tags'
+}
+
+_hg_cmd_help() {
+ _arguments -s -w : $_hg_global_opts \
+ '*:mercurial command:_hg_commands'
+}
+
+_hg_cmd_identify() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--rev -r)'{-r+,--rev}'[identify the specified rev]:revision:_hg_tags' \
+ '(--num -n)'{-n+,--num}'[show local revision number]' \
+ '(--id -i)'{-i+,--id}'[show global revision id]' \
+ '(--branch -b)'{-b+,--branch}'[show branch]' \
+ '(--tags -t)'{-t+,--tags}'[show tags]'
+}
+
+_hg_cmd_import() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--strip -p)'{-p+,--strip}'[directory strip option for patch (default: 1)]:count:' \
+ '(--message -m)'{-m+,--message}'[use <text> as commit message]:text:' \
+ '(--force -f)'{-f,--force}'[skip check for outstanding uncommitted changes]' \
+ '*:patch:_files'
+}
+
+_hg_cmd_incoming() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts $_hg_style_opts \
+ '(--no-merges -M)'{-M,--no-merges}'[do not show merge revisions]' \
+ '(--force -f)'{-f,--force}'[run even when the remote repository is unrelated]' \
+ '(--patch -p)'{-p,--patch}'[show patch]' \
+ '(--rev -r)'{-r+,--rev}'[a specific revision up to which you would like to pull]:revision:_hg_tags' \
+ '(--newest-first -n)'{-n,--newest-first}'[show newest record first]' \
+ '--bundle[file to store the bundles into]:bundle file:_files' \
+ ':source:_hg_remote'
+}
+
+_hg_cmd_init() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts \
+ ':dir:_files -/'
+}
+
+_hg_cmd_locate() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--rev -r)'{-r+,--rev}'[search repository as it stood at revision]:revision:_hg_tags' \
+ '(--print0 -0)'{-0,--print0}'[end filenames with NUL, for use with xargs]' \
+ '(--fullpath -f)'{-f,--fullpath}'[print complete paths]' \
+ '*:search pattern:_hg_files'
+}
+
+_hg_cmd_log() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_style_opts \
+ '(--follow --follow-first -f)'{-f,--follow}'[follow changeset or history]' \
+ '(-f --follow)--follow-first[only follow the first parent of merge changesets]' \
+ '(--copies -C)'{-C,--copies}'[show copied files]' \
+ '(--keyword -k)'{-k+,--keyword}'[search for a keyword]:' \
+ '(--limit -l)'{-l+,--limit}'[limit number of changes displayed]:' \
+ '*'{-r,--rev}'[show the specified revision or range]:revision:_hg_revrange' \
+ '(--no-merges -M)'{-M,--no-merges}'[do not show merges]' \
+ '(--only-merges -m)'{-m,--only-merges}'[show only merges]' \
+ '(--patch -p)'{-p,--patch}'[show patch]' \
+ '(--prune -P)'{-P+,--prune}'[do not display revision or any of its ancestors]:revision:_hg_tags' \
+ '*:files:_hg_files'
+}
+
+_hg_cmd_manifest() {
+ _arguments -s -w : $_hg_global_opts \
+ ':revision:_hg_tags'
+}
+
+_hg_cmd_merge() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--force -f)'{-f,--force}'[force a merge with outstanding changes]' \
+ '(--rev -r 1)'{-r,--rev}'[revision to merge]:revision:_hg_mergerevs' \
+ '(--preview -P)'{-P,--preview}'[review revisions to merge (no merge is performed)]' \
+ ':revision:_hg_mergerevs'
+}
+
+_hg_cmd_outgoing() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts $_hg_style_opts \
+ '(--no-merges -M)'{-M,--no-merges}'[do not show merge revisions]' \
+ '(--force -f)'{-f,--force}'[run even when the remote repository is unrelated]' \
+ '(--patch -p)'{-p,--patch}'[show patch]' \
+ '(--rev -r)'{-r+,--rev}'[a specific revision you would like to push]' \
+ '(--newest-first -n)'{-n,--newest-first}'[show newest record first]' \
+ ':destination:_hg_remote'
+}
+
+_hg_cmd_parents() {
+ _arguments -s -w : $_hg_global_opts $_hg_style_opts \
+ '(--rev -r)'{-r+,--rev}'[show parents of the specified rev]:revision:_hg_tags' \
+ ':last modified file:_hg_files'
+}
+
+_hg_cmd_paths() {
+ _arguments -s -w : $_hg_global_opts \
+ ':path:_hg_paths'
+}
+
+_hg_cmd_pull() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts \
+ '(--force -f)'{-f,--force}'[run even when the remote repository is unrelated]' \
+ '(--update -u)'{-u,--update}'[update to new tip if changesets were pulled]' \
+ '(--rev -r)'{-r+,--rev}'[a specific revision up to which you would like to pull]:revision:' \
+ ':source:_hg_remote'
+}
+
+_hg_cmd_push() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts \
+ '(--force -f)'{-f,--force}'[force push]' \
+ '(--rev -r)'{-r+,--rev}'[a specific revision you would like to push]:revision:_hg_tags' \
+ ':destination:_hg_remote'
+}
+
+_hg_cmd_remove() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--after -A)'{-A,--after}'[record remove that has already occurred]' \
+ '(--force -f)'{-f,--force}'[remove file even if modified]' \
+ '*:file:_hg_files'
+}
+
+_hg_cmd_rename() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_dryrun_opts \
+ '(--after -A)'{-A,--after}'[record a rename that has already occurred]' \
+ '(--force -f)'{-f,--force}'[forcibly copy over an existing managed file]' \
+ '*:file:_hg_files'
+}
+
+_hg_cmd_resolve() {
+ local context state line
+ typeset -A opt_args
+
+ _arguments -s -w : $_hg_global_opts \
+ '(--list -l --mark -m --unmark -u)'{-l,--list}'[list state of files needing merge]:*:merged files:->resolve_files' \
+ '(--mark -m --list -l --unmark -u)'{-m,--mark}'[mark files as resolved]:*:unresolved files:_hg_unresolved' \
+ '(--unmark -u --list -l --mark -m)'{-u,--unmark}'[unmark files as resolved]:*:resolved files:_hg_resolved' \
+ '*:file:_hg_unresolved'
+
+ if [[ $state == 'resolve_files' ]]
+ then
+ _alternative 'files:resolved files:_hg_resolved' \
+ 'files:unresolved files:_hg_unresolved'
+ fi
+}
+
+_hg_cmd_revert() {
+ local context state line
+ typeset -A opt_args
+
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_dryrun_opts \
+ '(--all -a :)'{-a,--all}'[revert all changes when no arguments given]' \
+ '(--rev -r)'{-r+,--rev}'[revision to revert to]:revision:_hg_tags' \
+ '--no-backup[do not save backup copies of files]' \
+ '*:file:->diff_files'
+
+ if [[ $state == 'diff_files' ]]
+ then
+ if [[ -n $opt_args[-r] ]]
+ then
+ _hg_files
+ else
+ typeset -a status_files
+ _hg_status mard
+ _wanted files expl 'modified, added, removed or deleted file' _multi_parts / status_files
+ fi
+ fi
+}
+
+_hg_cmd_serve() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--accesslog -A)'{-A+,--accesslog}'[name of access log file]:log file:_files' \
+ '(--errorlog -E)'{-E+,--errorlog}'[name of error log file]:log file:_files' \
+ '(--daemon -d)'{-d,--daemon}'[run server in background]' \
+ '(--port -p)'{-p+,--port}'[listen port]:listen port:' \
+ '(--address -a)'{-a+,--address}'[interface address]:interface address:' \
+ '(--name -n)'{-n+,--name}'[name to show in web pages]:repository name:' \
+ '(--templates -t)'{-t,--templates}'[web template directory]:template dir:_files -/' \
+ '--style[web template style]:style' \
+ '--stdio[for remote clients]' \
+ '(--ipv6 -6)'{-6,--ipv6}'[use IPv6 in addition to IPv4]'
+}
+
+_hg_cmd_showconfig() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--untrusted -u)'{-u+,--untrusted}'[show untrusted configuration options]' \
+ ':config item:_hg_config'
+}
+
+_hg_cmd_status() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--all -A)'{-A,--all}'[show status of all files]' \
+ '(--modified -m)'{-m,--modified}'[show only modified files]' \
+ '(--added -a)'{-a,--added}'[show only added files]' \
+ '(--removed -r)'{-r,--removed}'[show only removed files]' \
+ '(--deleted -d)'{-d,--deleted}'[show only deleted (but tracked) files]' \
+ '(--clean -c)'{-c,--clean}'[show only files without changes]' \
+ '(--unknown -u)'{-u,--unknown}'[show only unknown files]' \
+ '(--ignored -i)'{-i,--ignored}'[show ignored files]' \
+ '(--no-status -n)'{-n,--no-status}'[hide status prefix]' \
+ '(--copies -C)'{-C,--copies}'[show source of copied files]' \
+ '(--print0 -0)'{-0,--print0}'[end filenames with NUL, for use with xargs]' \
+ '--rev[show difference from revision]:revision:_hg_tags' \
+ '*:files:_files'
+}
+
+_hg_cmd_tag() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--local -l)'{-l,--local}'[make the tag local]' \
+ '(--message -m)'{-m+,--message}'[message for tag commit log entry]:message:' \
+ '(--date -d)'{-d+,--date}'[record datecode as commit date]:date code:' \
+ '(--user -u)'{-u+,--user}'[record user as commiter]:user:' \
+ '(--rev -r)'{-r+,--rev}'[revision to tag]:revision:_hg_tags' \
+ ':tag name:'
+}
+
+_hg_cmd_tip() {
+ _arguments -s -w : $_hg_global_opts $_hg_style_opts \
+ '(--patch -p)'{-p,--patch}'[show patch]'
+}
+
+_hg_cmd_unbundle() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--update -u)'{-u,--update}'[update to new tip if changesets were unbundled]' \
+ ':files:_files'
+}
+
+_hg_cmd_update() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--clean -C)'{-C,--clean}'[overwrite locally modified files]' \
+ '(--rev -r)'{-r+,--rev}'[revision]:revision:_hg_tags' \
+ ':revision:_hg_tags'
+}
+
+# HGK
+_hg_cmd_view() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--limit -l)'{-l+,--limit}'[limit number of changes displayed]:' \
+ ':revision range:_hg_tags'
+}
+
+# MQ
+_hg_qseries() {
+ typeset -a patches
+ patches=(${(f)"$(_hg_cmd qseries)"})
+ (( $#patches )) && _describe -t hg-patches 'patches' patches
+}
+
+_hg_qapplied() {
+ typeset -a patches
+ patches=(${(f)"$(_hg_cmd qapplied)"})
+ if (( $#patches ))
+ then
+ patches+=(qbase qtip)
+ _describe -t hg-applied-patches 'applied patches' patches
+ fi
+}
+
+_hg_qunapplied() {
+ typeset -a patches
+ patches=(${(f)"$(_hg_cmd qunapplied)"})
+ (( $#patches )) && _describe -t hg-unapplied-patches 'unapplied patches' patches
+}
+
+# unapplied, including guarded patches
+_hg_qdeletable() {
+ typeset -a unapplied
+ unapplied=(${(f)"$(_hg_cmd qseries)"})
+ for p in $(_hg_cmd qapplied)
+ do
+ unapplied=(${unapplied:#$p})
+ done
+
+ (( $#unapplied )) && _describe -t hg-allunapplied-patches 'all unapplied patches' unapplied
+}
+
+_hg_qguards() {
+ typeset -a guards
+ local guard
+ compset -P "+|-"
+ _hg_cmd qselect -s | while read guard
+ do
+ guards+=(${guard#(+|-)})
+ done
+ (( $#guards )) && _describe -t hg-guards 'guards' guards
+}
+
+_hg_qseries_opts=(
+ '(--summary -s)'{-s,--summary}'[print first line of patch header]')
+
+_hg_cmd_qapplied() {
+ _arguments -s -w : $_hg_global_opts $_hg_qseries_opts
+}
+
+_hg_cmd_qdelete() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--keep -k)'{-k,--keep}'[keep patch file]' \
+ '*'{-r+,--rev}'[stop managing a revision]:applied patch:_hg_revrange' \
+ '*:unapplied patch:_hg_qdeletable'
+}
+
+_hg_cmd_qdiff() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '*:pattern:_hg_files'
+}
+
+_hg_cmd_qfold() {
+ _arguments -s -w : $_hg_global_opts $_h_commit_opts \
+ '(--keep,-k)'{-k,--keep}'[keep folded patch files]' \
+ '*:unapplied patch:_hg_qunapplied'
+}
+
+_hg_cmd_qgoto() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--force -f)'{-f,--force}'[overwrite any local changes]' \
+ ':patch:_hg_qseries'
+}
+
+_hg_cmd_qguard() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--list -l)'{-l,--list}'[list all patches and guards]' \
+ '(--none -n)'{-n,--none}'[drop all guards]' \
+ ':patch:_hg_qseries' \
+ '*:guards:_hg_qguards'
+}
+
+_hg_cmd_qheader() {
+ _arguments -s -w : $_hg_global_opts \
+ ':patch:_hg_qseries'
+}
+
+_hg_cmd_qimport() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--existing -e)'{-e,--existing}'[import file in patch dir]' \
+ '(--name -n 2)'{-n+,--name}'[patch file name]:name:' \
+ '(--force -f)'{-f,--force}'[overwrite existing files]' \
+ '*'{-r+,--rev}'[place existing revisions under mq control]:revision:_hg_revrange' \
+ '*:patch:_files'
+}
+
+_hg_cmd_qnew() {
+ _arguments -s -w : $_hg_global_opts $_hg_commit_opts \
+ '(--force -f)'{-f,--force}'[import uncommitted changes into patch]' \
+ ':patch:'
+}
+
+_hg_cmd_qnext() {
+ _arguments -s -w : $_hg_global_opts $_hg_qseries_opts
+}
+
+_hg_cmd_qpop() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--all -a :)'{-a,--all}'[pop all patches]' \
+ '(--name -n)'{-n+,--name}'[queue name to pop]:' \
+ '(--force -f)'{-f,--force}'[forget any local changes]' \
+ ':patch:_hg_qapplied'
+}
+
+_hg_cmd_qprev() {
+ _arguments -s -w : $_hg_global_opts $_hg_qseries_opts
+}
+
+_hg_cmd_qpush() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--all -a :)'{-a,--all}'[apply all patches]' \
+ '(--list -l)'{-l,--list}'[list patch name in commit text]' \
+ '(--merge -m)'{-m+,--merge}'[merge from another queue]:' \
+ '(--name -n)'{-n+,--name}'[merge queue name]:' \
+ '(--force -f)'{-f,--force}'[apply if the patch has rejects]' \
+ ':patch:_hg_qunapplied'
+}
+
+_hg_cmd_qrefresh() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_commit_opts \
+ '(--git -g)'{-g,--git}'[use git extended diff format]' \
+ '(--short -s)'{-s,--short}'[short refresh]' \
+ '*:files:_hg_files'
+}
+
+_hg_cmd_qrename() {
+ _arguments -s -w : $_hg_global_opts \
+ ':patch:_hg_qseries' \
+ ':destination:'
+}
+
+_hg_cmd_qselect() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--none -n :)'{-n,--none}'[disable all guards]' \
+ '(--series -s :)'{-s,--series}'[list all guards in series file]' \
+ '--pop[pop to before first guarded applied patch]' \
+ '--reapply[pop and reapply patches]' \
+ '*:guards:_hg_qguards'
+}
+
+_hg_cmd_qseries() {
+ _arguments -s -w : $_hg_global_opts $_hg_qseries_opts \
+ '(--missing -m)'{-m,--missing}'[print patches not in series]'
+}
+
+_hg_cmd_qunapplied() {
+ _arguments -s -w : $_hg_global_opts $_hg_qseries_opts
+}
+
+_hg_cmd_qtop() {
+ _arguments -s -w : $_hg_global_opts $_hg_qseries_opts
+}
+
+_hg_cmd_strip() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--force -f)'{-f,--force}'[force multi-head removal]' \
+ '(--backup -b)'{-b,--backup}'[bundle unrelated changesets]' \
+ '(--nobackup -n)'{-n,--nobackup}'[no backups]' \
+ ':revision:_hg_tags'
+}
+
+_hg "$@"
diff --git a/sys/src/cmd/hg/doc/Makefile b/sys/src/cmd/hg/doc/Makefile
new file mode 100644
index 000000000..02f5fef36
--- /dev/null
+++ b/sys/src/cmd/hg/doc/Makefile
@@ -0,0 +1,48 @@
+SOURCES=$(wildcard *.[0-9].txt)
+MAN=$(SOURCES:%.txt=%)
+HTML=$(SOURCES:%.txt=%.html)
+PREFIX=/usr/local
+MANDIR=$(PREFIX)/share/man
+INSTALL=install -c -m 644
+PYTHON=python
+RST2HTML=rst2html
+RST2MAN=rst2man
+
+all: man html
+
+man: $(MAN)
+
+html: $(HTML)
+
+hg.1.txt: hg.1.gendoc.txt
+ touch hg.1.txt
+
+hg.1.gendoc.txt: gendoc.py ../mercurial/commands.py ../mercurial/help.py
+ ${PYTHON} gendoc.py > $@
+
+%: %.txt common.txt
+ # add newline after all literal blocks and fix backslash escape
+ $(RST2MAN) $*.txt \
+ | sed -e 's/^\.fi$$/.fi\n/' \
+ | sed -e 's/\\fB\\\\fP/\\fB\\e\\fP/' \
+ > $*
+
+%.html: %.txt common.txt
+ $(RST2HTML) $*.txt > $*.html
+
+MANIFEST: man html
+ # tracked files are already in the main MANIFEST
+ $(RM) $@
+ for i in $(MAN) $(HTML) hg.1.gendoc.txt; do \
+ echo "doc/$$i" >> $@ ; \
+ done
+
+install: man
+ for i in $(MAN) ; do \
+ subdir=`echo $$i | sed -n 's/^.*\.\([0-9]\)$$/man\1/p'` ; \
+ mkdir -p $(DESTDIR)$(MANDIR)/$$subdir ; \
+ $(INSTALL) $$i $(DESTDIR)$(MANDIR)/$$subdir ; \
+ done
+
+clean:
+ $(RM) $(MAN) $(MAN:%=%.html) *.[0-9].gendoc.txt MANIFEST
diff --git a/sys/src/cmd/hg/doc/README b/sys/src/cmd/hg/doc/README
new file mode 100644
index 000000000..d28170dac
--- /dev/null
+++ b/sys/src/cmd/hg/doc/README
@@ -0,0 +1,17 @@
+Mercurial's documentation is kept in reStructuredText format, which is
+a simple plain text format that's easy to read and edit:
+
+ http://docutils.sourceforge.net/rst.html
+
+It's also convertible to a variety of other formats including standard
+UNIX man page format and HTML.
+
+To do this, you'll need to install the rst2html and rst2man tools,
+which are part of Docutils:
+
+ http://docutils.sourceforge.net/
+
+The rst2man tool is still in their so-called "sandbox". The above page
+has links to tarballs of both Docutils and their sandbox.
+
+Use the Makefile in this directory to generate the man and HTML pages.
diff --git a/sys/src/cmd/hg/doc/common.txt b/sys/src/cmd/hg/doc/common.txt
new file mode 100644
index 000000000..936fc203b
--- /dev/null
+++ b/sys/src/cmd/hg/doc/common.txt
@@ -0,0 +1,8 @@
+.. Common link and substitution definitions.
+
+.. |hg(1)| replace:: **hg**\ (1)
+.. _hg(1): hg.1.html
+.. |hgrc(5)| replace:: **hgrc**\ (5)
+.. _hgrc(5): hgrc.5.html
+.. |hgignore(5)| replace:: **hgignore**\ (5)
+.. _hgignore(5): hgignore.5.html
diff --git a/sys/src/cmd/hg/doc/gendoc.py b/sys/src/cmd/hg/doc/gendoc.py
new file mode 100644
index 000000000..c0b0ec452
--- /dev/null
+++ b/sys/src/cmd/hg/doc/gendoc.py
@@ -0,0 +1,115 @@
+import os, sys, textwrap
+# import from the live mercurial repo
+sys.path.insert(0, "..")
+# fall back to pure modules if required C extensions are not available
+sys.path.append(os.path.join('..', 'mercurial', 'pure'))
+from mercurial import demandimport; demandimport.enable()
+from mercurial.commands import table, globalopts
+from mercurial.i18n import _
+from mercurial.help import helptable
+
+def get_desc(docstr):
+ if not docstr:
+ return "", ""
+ # sanitize
+ docstr = docstr.strip("\n")
+ docstr = docstr.rstrip()
+ shortdesc = docstr.splitlines()[0].strip()
+
+ i = docstr.find("\n")
+ if i != -1:
+ desc = docstr[i+2:]
+ else:
+ desc = " %s" % shortdesc
+ return (shortdesc, desc)
+
+def get_opts(opts):
+ for shortopt, longopt, default, desc in opts:
+ allopts = []
+ if shortopt:
+ allopts.append("-%s" % shortopt)
+ if longopt:
+ allopts.append("--%s" % longopt)
+ desc += default and _(" (default: %s)") % default or ""
+ yield(", ".join(allopts), desc)
+
+def get_cmd(cmd):
+ d = {}
+ attr = table[cmd]
+ cmds = cmd.lstrip("^").split("|")
+
+ d['cmd'] = cmds[0]
+ d['aliases'] = cmd.split("|")[1:]
+ d['desc'] = get_desc(attr[0].__doc__)
+ d['opts'] = list(get_opts(attr[1]))
+
+ s = 'hg ' + cmds[0]
+ if len(attr) > 2:
+ if not attr[2].startswith('hg'):
+ s += ' ' + attr[2]
+ else:
+ s = attr[2]
+ d['synopsis'] = s
+
+ return d
+
+def show_doc(ui):
+ def section(s):
+ ui.write("%s\n%s\n\n" % (s, "-" * len(s)))
+ def subsection(s):
+ ui.write("%s\n%s\n\n" % (s, '"' * len(s)))
+
+ # print options
+ section(_("OPTIONS"))
+ for optstr, desc in get_opts(globalopts):
+ ui.write("%s\n %s\n\n" % (optstr, desc))
+
+ # print cmds
+ section(_("COMMANDS"))
+ h = {}
+ for c, attr in table.items():
+ f = c.split("|")[0]
+ f = f.lstrip("^")
+ h[f] = c
+ cmds = h.keys()
+ cmds.sort()
+
+ for f in cmds:
+ if f.startswith("debug"): continue
+ d = get_cmd(h[f])
+ # synopsis
+ ui.write(".. _%s:\n\n" % d['cmd'])
+ ui.write("``%s``\n" % d['synopsis'].replace("hg ","", 1))
+ # description
+ ui.write("%s\n\n" % d['desc'][1])
+ # options
+ opt_output = list(d['opts'])
+ if opt_output:
+ opts_len = max([len(line[0]) for line in opt_output])
+ ui.write(_(" options:\n\n"))
+ for optstr, desc in opt_output:
+ if desc:
+ s = "%-*s %s" % (opts_len, optstr, desc)
+ else:
+ s = optstr
+ s = textwrap.fill(s, initial_indent=4 * " ",
+ subsequent_indent=(6 + opts_len) * " ")
+ ui.write("%s\n" % s)
+ ui.write("\n")
+ # aliases
+ if d['aliases']:
+ ui.write(_(" aliases: %s\n\n") % " ".join(d['aliases']))
+
+ # print topics
+ for names, sec, doc in helptable:
+ for name in names:
+ ui.write(".. _%s:\n" % name)
+ ui.write("\n")
+ section(sec.upper())
+ if callable(doc):
+ doc = doc()
+ ui.write(doc)
+ ui.write("\n")
+
+if __name__ == "__main__":
+ show_doc(sys.stdout)
diff --git a/sys/src/cmd/hg/doc/hg.1.txt b/sys/src/cmd/hg/doc/hg.1.txt
new file mode 100644
index 000000000..66e211217
--- /dev/null
+++ b/sys/src/cmd/hg/doc/hg.1.txt
@@ -0,0 +1,96 @@
+====
+ hg
+====
+
+---------------------------------------
+Mercurial source code management system
+---------------------------------------
+
+:Author: Matt Mackall <mpm@selenic.com>
+:Organization: Mercurial
+:Manual section: 1
+:Manual group: Mercurial Manual
+
+
+SYNOPSIS
+--------
+**hg** *command* [*option*]... [*argument*]...
+
+DESCRIPTION
+-----------
+The **hg** command provides a command line interface to the Mercurial
+system.
+
+COMMAND ELEMENTS
+----------------
+
+files...
+ indicates one or more filename or relative path filenames; see
+ "FILE NAME PATTERNS" for information on pattern matching
+
+path
+ indicates a path on the local machine
+
+revision
+ indicates a changeset which can be specified as a changeset
+ revision number, a tag, or a unique substring of the changeset
+ hash value
+
+repository path
+ either the pathname of a local repository or the URI of a remote
+ repository.
+
+.. include:: hg.1.gendoc.txt
+
+FILES
+-----
+
+``.hgignore``
+ This file contains regular expressions (one per line) that
+ describe file names that should be ignored by **hg**. For details,
+ see |hgignore(5)|_.
+
+``.hgtags``
+ This file contains changeset hash values and text tag names (one
+ of each separated by spaces) that correspond to tagged versions of
+ the repository contents.
+
+``/etc/mercurial/hgrc``, ``$HOME/.hgrc``, ``.hg/hgrc``
+ This file contains defaults and configuration. Values in
+ ``.hg/hgrc`` override those in ``$HOME/.hgrc``, and these override
+ settings made in the global ``/etc/mercurial/hgrc`` configuration.
+ See |hgrc(5)|_ for details of the contents and format of these
+ files.
+
+Some commands (e.g. revert) produce backup files ending in ``.orig``,
+if the ``.orig`` file already exists and is not tracked by Mercurial,
+it will be overwritten.
+
+BUGS
+----
+Probably lots, please post them to the mailing list (See Resources
+below) when you find them.
+
+SEE ALSO
+--------
+|hgignore(5)|_, |hgrc(5)|_
+
+AUTHOR
+------
+Written by Matt Mackall <mpm@selenic.com>
+
+RESOURCES
+---------
+Main Web Site: http://mercurial.selenic.com/
+
+Source code repository: http://selenic.com/hg
+
+Mailing list: http://selenic.com/mailman/listinfo/mercurial
+
+COPYING
+-------
+Copyright \(C) 2005-2009 Matt Mackall.
+Free use of this software is granted under the terms of the GNU General
+Public License (GPL).
+
+.. include:: common.txt
diff --git a/sys/src/cmd/hg/doc/hgignore.5.txt b/sys/src/cmd/hg/doc/hgignore.5.txt
new file mode 100644
index 000000000..e98dc40d1
--- /dev/null
+++ b/sys/src/cmd/hg/doc/hgignore.5.txt
@@ -0,0 +1,111 @@
+==========
+ hgignore
+==========
+
+---------------------------------
+syntax for Mercurial ignore files
+---------------------------------
+
+:Author: Vadim Gelfer <vadim.gelfer@gmail.com>
+:Organization: Mercurial
+:Manual section: 5
+:Manual group: Mercurial Manual
+
+SYNOPSIS
+--------
+
+The Mercurial system uses a file called ``.hgignore`` in the root
+directory of a repository to control its behavior when it searches
+for files that it is not currently tracking.
+
+DESCRIPTION
+-----------
+
+The working directory of a Mercurial repository will often contain
+files that should not be tracked by Mercurial. These include backup
+files created by editors and build products created by compilers.
+These files can be ignored by listing them in a ``.hgignore`` file in
+the root of the working directory. The ``.hgignore`` file must be
+created manually. It is typically put under version control, so that
+the settings will propagate to other repositories with push and pull.
+
+An untracked file is ignored if its path relative to the repository
+root directory, or any prefix path of that path, is matched against
+any pattern in ``.hgignore``.
+
+For example, say we have an an untracked file, ``file.c``, at
+``a/b/file.c`` inside our repository. Mercurial will ignore ``file.c``
+if any pattern in ``.hgignore`` matches ``a/b/file.c``, ``a/b`` or ``a``.
+
+In addition, a Mercurial configuration file can reference a set of
+per-user or global ignore files. See the |hgrc(5)|_ man page for details
+of how to configure these files. Look for the "ignore" entry in the
+"ui" section.
+
+To control Mercurial's handling of files that it manages, see the
+|hg(1)|_ man page. Look for the "``-I``" and "``-X``" options.
+
+SYNTAX
+------
+
+An ignore file is a plain text file consisting of a list of patterns,
+with one pattern per line. Empty lines are skipped. The "``#``"
+character is treated as a comment character, and the "``\``" character
+is treated as an escape character.
+
+Mercurial supports several pattern syntaxes. The default syntax used
+is Python/Perl-style regular expressions.
+
+To change the syntax used, use a line of the following form::
+
+ syntax: NAME
+
+where ``NAME`` is one of the following:
+
+``regexp``
+ Regular expression, Python/Perl syntax.
+``glob``
+ Shell-style glob.
+
+The chosen syntax stays in effect when parsing all patterns that
+follow, until another syntax is selected.
+
+Neither glob nor regexp patterns are rooted. A glob-syntax pattern of
+the form "``*.c``" will match a file ending in "``.c``" in any directory,
+and a regexp pattern of the form "``\.c$``" will do the same. To root a
+regexp pattern, start it with "``^``".
+
+EXAMPLE
+-------
+
+Here is an example ignore file. ::
+
+ # use glob syntax.
+ syntax: glob
+
+ *.elc
+ *.pyc
+ *~
+
+ # switch to regexp syntax.
+ syntax: regexp
+ ^\.pc/
+
+AUTHOR
+------
+Vadim Gelfer <vadim.gelfer@gmail.com>
+
+Mercurial was written by Matt Mackall <mpm@selenic.com>.
+
+SEE ALSO
+--------
+|hg(1)|_, |hgrc(5)|_
+
+COPYING
+-------
+This manual page is copyright 2006 Vadim Gelfer.
+Mercurial is copyright 2005-2009 Matt Mackall.
+Free use of this software is granted under the terms of the GNU General
+Public License (GPL).
+
+.. include:: common.txt
diff --git a/sys/src/cmd/hg/doc/hgrc.5.txt b/sys/src/cmd/hg/doc/hgrc.5.txt
new file mode 100644
index 000000000..7618cc614
--- /dev/null
+++ b/sys/src/cmd/hg/doc/hgrc.5.txt
@@ -0,0 +1,934 @@
+======
+ hgrc
+======
+
+---------------------------------
+configuration files for Mercurial
+---------------------------------
+
+:Author: Bryan O'Sullivan <bos@serpentine.com>
+:Organization: Mercurial
+:Manual section: 5
+:Manual group: Mercurial Manual
+
+
+SYNOPSIS
+--------
+
+The Mercurial system uses a set of configuration files to control
+aspects of its behavior.
+
+FILES
+-----
+
+Mercurial reads configuration data from several files, if they exist.
+The names of these files depend on the system on which Mercurial is
+installed. ``*.rc`` files from a single directory are read in
+alphabetical order, later ones overriding earlier ones. Where multiple
+paths are given below, settings from later paths override earlier
+ones.
+
+| (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc``
+| (Unix) ``<install-root>/etc/mercurial/hgrc``
+
+ Per-installation configuration files, searched for in the
+ directory where Mercurial is installed. ``<install-root>`` is the
+ parent directory of the **hg** executable (or symlink) being run. For
+ example, if installed in ``/shared/tools/bin/hg``, Mercurial will look
+ in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply
+ to all Mercurial commands executed by any user in any directory.
+
+| (Unix) ``/etc/mercurial/hgrc.d/*.rc``
+| (Unix) ``/etc/mercurial/hgrc``
+
+ Per-system configuration files, for the system on which Mercurial
+ is running. Options in these files apply to all Mercurial commands
+ executed by any user in any directory. Options in these files
+ override per-installation options.
+
+| (Windows) ``<install-dir>\Mercurial.ini`` or else
+| (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` or else
+| (Windows) ``C:\Mercurial\Mercurial.ini``
+
+ Per-installation/system configuration files, for the system on
+ which Mercurial is running. Options in these files apply to all
+ Mercurial commands executed by any user in any directory. Registry
+ keys contain PATH-like strings, every part of which must reference
+ a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
+ be read.
+
+| (Unix) ``$HOME/.hgrc``
+| (Windows) ``%HOME%\Mercurial.ini``
+| (Windows) ``%HOME%\.hgrc``
+| (Windows) ``%USERPROFILE%\Mercurial.ini``
+| (Windows) ``%USERPROFILE%\.hgrc``
+
+ Per-user configuration file(s), for the user running Mercurial. On
+ Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these
+ files apply to all Mercurial commands executed by this user in any
+ directory. Options in these files override per-installation and
+ per-system options.
+
+| (Unix, Windows) ``<repo>/.hg/hgrc``
+
+ Per-repository configuration options that only apply in a
+ particular repository. This file is not version-controlled, and
+ will not get transferred during a "clone" operation. Options in
+ this file override options in all other configuration files. On
+ Unix, most of this file will be ignored if it doesn't belong to a
+ trusted user or to a trusted group. See the documentation for the
+ trusted section below for more details.
+
+SYNTAX
+------
+
+A configuration file consists of sections, led by a "``[section]``" header
+and followed by "``name: value``" entries; "``name=value``" is also accepted.
+
+::
+
+ [spam]
+ eggs=ham
+ green=
+ eggs
+
+Each line contains one entry. If the lines that follow are indented,
+they are treated as continuations of that entry.
+
+Leading whitespace is removed from values. Empty lines are skipped.
+
+Lines beginning with "``#``" or "``;``" are ignored and may be used to provide
+comments.
+
+SECTIONS
+--------
+
+This section describes the different sections that may appear in a
+Mercurial "hgrc" file, the purpose of each section, its possible keys,
+and their possible values.
+
+``alias``
+"""""""""
+Defines command aliases.
+Aliases allow you to define your own commands in terms of other
+commands (or aliases), optionally including arguments.
+
+Alias definitions consist of lines of the form::
+
+ <alias> = <command> [<argument]...
+
+For example, this definition::
+
+ latest = log --limit 5
+
+creates a new command ``latest`` that shows only the five most recent
+changesets. You can define subsequent aliases using earlier ones::
+
+ stable5 = latest -b stable
+
+NOTE: It is possible to create aliases with the same names as existing
+commands, which will then override the original definitions. This is
+almost always a bad idea!
+
+
+``auth``
+""""""""
+Authentication credentials for HTTP authentication. Each line has
+the following format::
+
+ <name>.<argument> = <value>
+
+where <name> is used to group arguments into authentication entries.
+Example::
+
+ foo.prefix = hg.intevation.org/mercurial
+ foo.username = foo
+ foo.password = bar
+ foo.schemes = http https
+
+ bar.prefix = secure.example.org
+ bar.key = path/to/file.key
+ bar.cert = path/to/file.cert
+ bar.schemes = https
+
+Supported arguments:
+
+``prefix``
+ Either "``*``" or a URI prefix with or without the scheme part.
+ The authentication entry with the longest matching prefix is used
+ (where "``*``" matches everything and counts as a match of length
+ 1). If the prefix doesn't include a scheme, the match is performed
+ against the URI with its scheme stripped as well, and the schemes
+ argument, q.v., is then subsequently consulted.
+``username``
+ Optional. Username to authenticate with. If not given, and the
+ remote site requires basic or digest authentication, the user
+ will be prompted for it.
+``password``
+ Optional. Password to authenticate with. If not given, and the
+ remote site requires basic or digest authentication, the user
+ will be prompted for it.
+``key``
+ Optional. PEM encoded client certificate key file.
+``cert``
+ Optional. PEM encoded client certificate chain file.
+``schemes``
+ Optional. Space separated list of URI schemes to use this
+ authentication entry with. Only used if the prefix doesn't include
+ a scheme. Supported schemes are http and https. They will match
+ static-http and static-https respectively, as well.
+ Default: https.
+
+If no suitable authentication entry is found, the user is prompted
+for credentials as usual if required by the remote.
+
+
+``decode/encode``
+"""""""""""""""""
+Filters for transforming files on checkout/checkin. This would
+typically be used for newline processing or other
+localization/canonicalization of files.
+
+Filters consist of a filter pattern followed by a filter command.
+Filter patterns are globs by default, rooted at the repository root.
+For example, to match any file ending in "``.txt``" in the root
+directory only, use the pattern "``*.txt``". To match any file ending
+in "``.c``" anywhere in the repository, use the pattern "``**.c``".
+
+The filter command can start with a specifier, either "pipe:" or
+"tempfile:". If no specifier is given, "pipe:" is used by default.
+
+A "pipe:" command must accept data on stdin and return the transformed
+data on stdout.
+
+Pipe example::
+
+ [encode]
+ # uncompress gzip files on checkin to improve delta compression
+ # note: not necessarily a good idea, just an example
+ *.gz = pipe: gunzip
+
+ [decode]
+ # recompress gzip files when writing them to the working dir (we
+ # can safely omit "pipe:", because it's the default)
+ *.gz = gzip
+
+A "tempfile:" command is a template. The string INFILE is replaced
+with the name of a temporary file that contains the data to be
+filtered by the command. The string OUTFILE is replaced with the name
+of an empty temporary file, where the filtered data must be written by
+the command.
+
+NOTE: the tempfile mechanism is recommended for Windows systems, where
+the standard shell I/O redirection operators often have strange
+effects and may corrupt the contents of your files.
+
+The most common usage is for LF <-> CRLF translation on Windows. For
+this, use the "smart" converters which check for binary files::
+
+ [extensions]
+ hgext.win32text =
+ [encode]
+ ** = cleverencode:
+ [decode]
+ ** = cleverdecode:
+
+or if you only want to translate certain files::
+
+ [extensions]
+ hgext.win32text =
+ [encode]
+ **.txt = dumbencode:
+ [decode]
+ **.txt = dumbdecode:
+
+
+``defaults``
+""""""""""""
+
+Use the [defaults] section to define command defaults, i.e. the
+default options/arguments to pass to the specified commands.
+
+The following example makes 'hg log' run in verbose mode, and 'hg
+status' show only the modified files, by default::
+
+ [defaults]
+ log = -v
+ status = -m
+
+The actual commands, instead of their aliases, must be used when
+defining command defaults. The command defaults will also be applied
+to the aliases of the commands defined.
+
+
+``diff``
+""""""""
+
+Settings used when displaying diffs. They are all Boolean and
+defaults to False.
+
+``git``
+ Use git extended diff format.
+``nodates``
+ Don't include dates in diff headers.
+``showfunc``
+ Show which function each change is in.
+``ignorews``
+ Ignore white space when comparing lines.
+``ignorewsamount``
+ Ignore changes in the amount of white space.
+``ignoreblanklines``
+ Ignore changes whose lines are all blank.
+
+``email``
+"""""""""
+Settings for extensions that send email messages.
+
+``from``
+ Optional. Email address to use in "From" header and SMTP envelope
+ of outgoing messages.
+``to``
+ Optional. Comma-separated list of recipients' email addresses.
+``cc``
+ Optional. Comma-separated list of carbon copy recipients'
+ email addresses.
+``bcc``
+ Optional. Comma-separated list of blind carbon copy recipients'
+ email addresses. Cannot be set interactively.
+``method``
+ Optional. Method to use to send email messages. If value is "smtp"
+ (default), use SMTP (see section "[smtp]" for configuration).
+ Otherwise, use as name of program to run that acts like sendmail
+ (takes "-f" option for sender, list of recipients on command line,
+ message on stdin). Normally, setting this to "sendmail" or
+ "/usr/sbin/sendmail" is enough to use sendmail to send messages.
+``charsets``
+ Optional. Comma-separated list of character sets considered
+ convenient for recipients. Addresses, headers, and parts not
+ containing patches of outgoing messages will be encoded in the
+ first character set to which conversion from local encoding
+ (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
+ conversion fails, the text in question is sent as is. Defaults to
+ empty (explicit) list.
+
+Order of outgoing email character sets::
+
+ us-ascii always first, regardless of settings
+ email.charsets in order given by user
+ ui.fallbackencoding if not in email.charsets
+ $HGENCODING if not in email.charsets
+ utf-8 always last, regardless of settings
+
+Email example::
+
+ [email]
+ from = Joseph User <joe.user@example.com>
+ method = /usr/sbin/sendmail
+ # charsets for western Europeans
+ # us-ascii, utf-8 omitted, as they are tried first and last
+ charsets = iso-8859-1, iso-8859-15, windows-1252
+
+
+``extensions``
+""""""""""""""
+
+Mercurial has an extension mechanism for adding new features. To
+enable an extension, create an entry for it in this section.
+
+If you know that the extension is already in Python's search path,
+you can give the name of the module, followed by "``=``", with nothing
+after the "``=``".
+
+Otherwise, give a name that you choose, followed by "``=``", followed by
+the path to the "``.py``" file (including the file name extension) that
+defines the extension.
+
+To explicitly disable an extension that is enabled in an hgrc of
+broader scope, prepend its path with "``!``", as in
+"``hgext.foo = !/ext/path``" or "``hgext.foo = !``" when path is not
+supplied.
+
+Example for ``~/.hgrc``::
+
+ [extensions]
+ # (the mq extension will get loaded from Mercurial's path)
+ hgext.mq =
+ # (this extension will get loaded from the file specified)
+ myfeature = ~/.hgext/myfeature.py
+
+
+``format``
+""""""""""
+
+``usestore``
+ Enable or disable the "store" repository format which improves
+ compatibility with systems that fold case or otherwise mangle
+ filenames. Enabled by default. Disabling this option will allow
+ you to store longer filenames in some situations at the expense of
+ compatibility and ensures that the on-disk format of newly created
+ repositories will be compatible with Mercurial before version 0.9.4.
+
+``usefncache``
+ Enable or disable the "fncache" repository format which enhances
+ the "store" repository format (which has to be enabled to use
+ fncache) to allow longer filenames and avoids using Windows
+ reserved names, e.g. "nul". Enabled by default. Disabling this
+ option ensures that the on-disk format of newly created
+ repositories will be compatible with Mercurial before version 1.1.
+
+``merge-patterns``
+""""""""""""""""""
+
+This section specifies merge tools to associate with particular file
+patterns. Tools matched here will take precedence over the default
+merge tool. Patterns are globs by default, rooted at the repository
+root.
+
+Example::
+
+ [merge-patterns]
+ **.c = kdiff3
+ **.jpg = myimgmerge
+
+``merge-tools``
+"""""""""""""""
+
+This section configures external merge tools to use for file-level
+merges.
+
+Example ``~/.hgrc``::
+
+ [merge-tools]
+ # Override stock tool location
+ kdiff3.executable = ~/bin/kdiff3
+ # Specify command line
+ kdiff3.args = $base $local $other -o $output
+ # Give higher priority
+ kdiff3.priority = 1
+
+ # Define new tool
+ myHtmlTool.args = -m $local $other $base $output
+ myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
+ myHtmlTool.priority = 1
+
+Supported arguments:
+
+``priority``
+ The priority in which to evaluate this tool.
+ Default: 0.
+``executable``
+ Either just the name of the executable or its pathname.
+ Default: the tool name.
+``args``
+ The arguments to pass to the tool executable. You can refer to the
+ files being merged as well as the output file through these
+ variables: ``$base``, ``$local``, ``$other``, ``$output``.
+ Default: ``$local $base $other``
+``premerge``
+ Attempt to run internal non-interactive 3-way merge tool before
+ launching external tool.
+ Default: True
+``binary``
+ This tool can merge binary files. Defaults to False, unless tool
+ was selected by file pattern match.
+``symlink``
+ This tool can merge symlinks. Defaults to False, even if tool was
+ selected by file pattern match.
+``checkconflicts``
+ Check whether there are conflicts even though the tool reported
+ success.
+ Default: False
+``checkchanged``
+ Check whether outputs were written even though the tool reported
+ success.
+ Default: False
+``fixeol``
+ Attempt to fix up EOL changes caused by the merge tool.
+ Default: False
+``gui``
+ This tool requires a graphical interface to run. Default: False
+``regkey``
+ Windows registry key which describes install location of this
+ tool. Mercurial will search for this key first under
+ ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
+ Default: None
+``regname``
+ Name of value to read from specified registry key. Defaults to the
+ unnamed (default) value.
+``regappend``
+ String to append to the value read from the registry, typically
+ the executable name of the tool.
+ Default: None
+
+
+``hooks``
+"""""""""
+Commands or Python functions that get automatically executed by
+various actions such as starting or finishing a commit. Multiple
+hooks can be run for the same action by appending a suffix to the
+action. Overriding a site-wide hook can be done by changing its
+value or setting it to an empty string.
+
+Example ``.hg/hgrc``::
+
+ [hooks]
+ # do not use the site-wide hook
+ incoming =
+ incoming.email = /my/email/hook
+ incoming.autobuild = /my/build/hook
+
+Most hooks are run with environment variables set that give useful
+additional information. For each hook below, the environment
+variables it is passed are listed with names of the form "$HG_foo".
+
+``changegroup``
+ Run after a changegroup has been added via push, pull or unbundle.
+ ID of the first new changeset is in ``$HG_NODE``. URL from which
+ changes came is in ``$HG_URL``.
+``commit``
+ Run after a changeset has been created in the local repository. ID
+ of the newly created changeset is in ``$HG_NODE``. Parent changeset
+ IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
+``incoming``
+ Run after a changeset has been pulled, pushed, or unbundled into
+ the local repository. The ID of the newly arrived changeset is in
+ ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``.
+``outgoing``
+ Run after sending changes from local repository to another. ID of
+ first changeset sent is in ``$HG_NODE``. Source of operation is in
+ ``$HG_SOURCE``; see "preoutgoing" hook for description.
+``post-<command>``
+ Run after successful invocations of the associated command. The
+ contents of the command line are passed as ``$HG_ARGS`` and the result
+ code in ``$HG_RESULT``. Hook failure is ignored.
+``pre-<command>``
+ Run before executing the associated command. The contents of the
+ command line are passed as ``$HG_ARGS``. If the hook returns failure,
+ the command doesn't execute and Mercurial returns the failure
+ code.
+``prechangegroup``
+ Run before a changegroup is added via push, pull or unbundle. Exit
+ status 0 allows the changegroup to proceed. Non-zero status will
+ cause the push, pull or unbundle to fail. URL from which changes
+ will come is in ``$HG_URL``.
+``precommit``
+ Run before starting a local commit. Exit status 0 allows the
+ commit to proceed. Non-zero status will cause the commit to fail.
+ Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
+``preoutgoing``
+ Run before collecting changes to send from the local repository to
+ another. Non-zero status will cause failure. This lets you prevent
+ pull over HTTP or SSH. Also prevents against local pull, push
+ (outbound) or bundle commands, but not effective, since you can
+ just copy files instead then. Source of operation is in
+ ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
+ SSH or HTTP repository. If "push", "pull" or "bundle", operation
+ is happening on behalf of repository on same system.
+``pretag``
+ Run before creating a tag. Exit status 0 allows the tag to be
+ created. Non-zero status will cause the tag to fail. ID of
+ changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag is
+ local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``.
+``pretxnchangegroup``
+ Run after a changegroup has been added via push, pull or unbundle,
+ but before the transaction has been committed. Changegroup is
+ visible to hook program. This lets you validate incoming changes
+ before accepting them. Passed the ID of the first new changeset in
+ ``$HG_NODE``. Exit status 0 allows the transaction to commit. Non-zero
+ status will cause the transaction to be rolled back and the push,
+ pull or unbundle will fail. URL that was source of changes is in
+ ``$HG_URL``.
+``pretxncommit``
+ Run after a changeset has been created but the transaction not yet
+ committed. Changeset is visible to hook program. This lets you
+ validate commit message and changes. Exit status 0 allows the
+ commit to proceed. Non-zero status will cause the transaction to
+ be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset
+ IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
+``preupdate``
+ Run before updating the working directory. Exit status 0 allows
+ the update to proceed. Non-zero status will prevent the update.
+ Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
+ of second new parent is in ``$HG_PARENT2``.
+``tag``
+ Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
+ Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
+ repository if ``$HG_LOCAL=0``.
+``update``
+ Run after updating the working directory. Changeset ID of first
+ new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is
+ in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
+ update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``.
+
+NOTE: it is generally better to use standard hooks rather than the
+generic pre- and post- command hooks as they are guaranteed to be
+called in the appropriate contexts for influencing transactions.
+Also, hooks like "commit" will be called in all contexts that
+generate a commit (e.g. tag) and not just the commit command.
+
+NOTE: Environment variables with empty values may not be passed to
+hooks on platforms such as Windows. As an example, ``$HG_PARENT2`` will
+have an empty value under Unix-like platforms for non-merge
+changesets, while it will not be available at all under Windows.
+
+The syntax for Python hooks is as follows::
+
+ hookname = python:modulename.submodule.callable
+ hookname = python:/path/to/python/module.py:callable
+
+Python hooks are run within the Mercurial process. Each hook is
+called with at least three keyword arguments: a ui object (keyword
+"ui"), a repository object (keyword "repo"), and a "hooktype"
+keyword that tells what kind of hook is used. Arguments listed as
+environment variables above are passed as keyword arguments, with no
+"``HG_``" prefix, and names in lower case.
+
+If a Python hook returns a "true" value or raises an exception, this
+is treated as a failure.
+
+
+``http_proxy``
+""""""""""""""
+Used to access web-based Mercurial repositories through a HTTP
+proxy.
+
+``host``
+ Host name and (optional) port of the proxy server, for example
+ "myproxy:8000".
+``no``
+ Optional. Comma-separated list of host names that should bypass
+ the proxy.
+``passwd``
+ Optional. Password to authenticate with at the proxy server.
+``user``
+ Optional. User name to authenticate with at the proxy server.
+
+``smtp``
+""""""""
+Configuration for extensions that need to send email messages.
+
+``host``
+ Host name of mail server, e.g. "mail.example.com".
+``port``
+ Optional. Port to connect to on mail server. Default: 25.
+``tls``
+ Optional. Whether to connect to mail server using TLS. True or
+ False. Default: False.
+``username``
+ Optional. User name to authenticate to SMTP server with. If
+ username is specified, password must also be specified.
+ Default: none.
+``password``
+ Optional. Password to authenticate to SMTP server with. If
+ username is specified, password must also be specified.
+ Default: none.
+``local_hostname``
+ Optional. It's the hostname that the sender can use to identify
+ itself to the MTA.
+
+
+``patch``
+"""""""""
+Settings used when applying patches, for instance through the 'import'
+command or with Mercurial Queues extension.
+
+``eol``
+ When set to 'strict' patch content and patched files end of lines
+ are preserved. When set to 'lf' or 'crlf', both files end of lines
+ are ignored when patching and the result line endings are
+ normalized to either LF (Unix) or CRLF (Windows).
+ Default: strict.
+
+
+``paths``
+"""""""""
+Assigns symbolic names to repositories. The left side is the
+symbolic name, and the right gives the directory or URL that is the
+location of the repository. Default paths can be declared by setting
+the following entries.
+
+``default``
+ Directory or URL to use when pulling if no source is specified.
+ Default is set to repository from which the current repository was
+ cloned.
+``default-push``
+ Optional. Directory or URL to use when pushing if no destination
+ is specified.
+
+
+``profiling``
+"""""""""""""
+Specifies profiling format and file output. In this section
+description, 'profiling data' stands for the raw data collected
+during profiling, while 'profiling report' stands for a statistical
+text report generated from the profiling data. The profiling is done
+using lsprof.
+
+``format``
+ Profiling format.
+ Default: text.
+
+ ``text``
+ Generate a profiling report. When saving to a file, it should be
+ noted that only the report is saved, and the profiling data is
+ not kept.
+ ``kcachegrind``
+ Format profiling data for kcachegrind use: when saving to a
+ file, the generated file can directly be loaded into
+ kcachegrind.
+``output``
+ File path where profiling data or report should be saved. If the
+ file exists, it is replaced. Default: None, data is printed on
+ stderr
+
+``server``
+""""""""""
+Controls generic server settings.
+
+``uncompressed``
+ Whether to allow clients to clone a repository using the
+ uncompressed streaming protocol. This transfers about 40% more
+ data than a regular clone, but uses less memory and CPU on both
+ server and client. Over a LAN (100 Mbps or better) or a very fast
+ WAN, an uncompressed streaming clone is a lot faster (~10x) than a
+ regular clone. Over most WAN connections (anything slower than
+ about 6 Mbps), uncompressed streaming is slower, because of the
+ extra data transfer overhead. Default is False.
+
+
+``trusted``
+"""""""""""
+For security reasons, Mercurial will not use the settings in the
+``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
+user or to a trusted group. The main exception is the web interface,
+which automatically uses some safe settings, since it's common to
+serve repositories from different users.
+
+This section specifies what users and groups are trusted. The
+current user is always trusted. To trust everybody, list a user or a
+group with name "``*``".
+
+``users``
+ Comma-separated list of trusted users.
+``groups``
+ Comma-separated list of trusted groups.
+
+
+``ui``
+""""""
+
+User interface controls.
+
+``archivemeta``
+ Whether to include the .hg_archival.txt file containing meta data
+ (hashes for the repository base and for tip) in archives created
+ by the hg archive command or downloaded via hgweb.
+ Default is true.
+``askusername``
+ Whether to prompt for a username when committing. If True, and
+ neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
+ be prompted to enter a username. If no username is entered, the
+ default USER@HOST is used instead.
+ Default is False.
+``debug``
+ Print debugging information. True or False. Default is False.
+``editor``
+ The editor to use during a commit. Default is ``$EDITOR`` or "vi".
+``fallbackencoding``
+ Encoding to try if it's not possible to decode the changelog using
+ UTF-8. Default is ISO-8859-1.
+``ignore``
+ A file to read per-user ignore patterns from. This file should be
+ in the same format as a repository-wide .hgignore file. This
+ option supports hook syntax, so if you want to specify multiple
+ ignore files, you can do so by setting something like
+ "``ignore.other = ~/.hgignore2``". For details of the ignore file
+ format, see the |hgignore(5)|_ man page.
+``interactive``
+ Allow to prompt the user. True or False. Default is True.
+``logtemplate``
+ Template string for commands that print changesets.
+``merge``
+ The conflict resolution program to use during a manual merge.
+ There are some internal tools available:
+
+ ``internal:local``
+ keep the local version
+ ``internal:other``
+ use the other version
+ ``internal:merge``
+ use the internal non-interactive merge tool
+ ``internal:fail``
+ fail to merge
+
+For more information on configuring merge tools see the
+merge-tools section.
+
+``patch``
+ command to use to apply patches. Look for 'gpatch' or 'patch' in
+ PATH if unset.
+``quiet``
+ Reduce the amount of output printed. True or False. Default is False.
+``remotecmd``
+ remote command to use for clone/push/pull operations. Default is 'hg'.
+``report_untrusted``
+ Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
+ trusted user or group. True or False. Default is True.
+``slash``
+ Display paths using a slash ("``/``") as the path separator. This
+ only makes a difference on systems where the default path
+ separator is not the slash character (e.g. Windows uses the
+ backslash character ("``\``")).
+ Default is False.
+``ssh``
+ command to use for SSH connections. Default is 'ssh'.
+``strict``
+ Require exact command names, instead of allowing unambiguous
+ abbreviations. True or False. Default is False.
+``style``
+ Name of style to use for command output.
+``timeout``
+ The timeout used when a lock is held (in seconds), a negative value
+ means no timeout. Default is 600.
+``username``
+ The committer of a changeset created when running "commit".
+ Typically a person's name and email address, e.g. "Fred Widget
+ <fred@example.com>". Default is ``$EMAIL`` or username@hostname. If
+ the username in hgrc is empty, it has to be specified manually or
+ in a different hgrc file (e.g. ``$HOME/.hgrc``, if the admin set
+ "username =" in the system hgrc).
+``verbose``
+ Increase the amount of output printed. True or False. Default is False.
+
+
+``web``
+"""""""
+Web interface configuration.
+
+``accesslog``
+ Where to output the access log. Default is stdout.
+``address``
+ Interface address to bind to. Default is all.
+``allow_archive``
+ List of archive format (bz2, gz, zip) allowed for downloading.
+ Default is empty.
+``allowbz2``
+ (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
+ revisions.
+ Default is false.
+``allowgz``
+ (DEPRECATED) Whether to allow .tar.gz downloading of repository
+ revisions.
+ Default is false.
+``allowpull``
+ Whether to allow pulling from the repository. Default is true.
+``allow_push``
+ Whether to allow pushing to the repository. If empty or not set,
+ push is not allowed. If the special value "``*``", any remote user can
+ push, including unauthenticated users. Otherwise, the remote user
+ must have been authenticated, and the authenticated user name must
+ be present in this list (separated by whitespace or ","). The
+ contents of the allow_push list are examined after the deny_push
+ list.
+``allow_read``
+ If the user has not already been denied repository access due to
+ the contents of deny_read, this list determines whether to grant
+ repository access to the user. If this list is not empty, and the
+ user is unauthenticated or not present in the list (separated by
+ whitespace or ","), then access is denied for the user. If the
+ list is empty or not set, then access is permitted to all users by
+ default. Setting allow_read to the special value "``*``" is equivalent
+ to it not being set (i.e. access is permitted to all users). The
+ contents of the allow_read list are examined after the deny_read
+ list.
+``allowzip``
+ (DEPRECATED) Whether to allow .zip downloading of repository
+ revisions. Default is false. This feature creates temporary files.
+``baseurl``
+ Base URL to use when publishing URLs in other locations, so
+ third-party tools like email notification hooks can construct
+ URLs. Example: "http://hgserver/repos/"
+``contact``
+ Name or email address of the person in charge of the repository.
+ Defaults to ui.username or ``$EMAIL`` or "unknown" if unset or empty.
+``deny_push``
+ Whether to deny pushing to the repository. If empty or not set,
+ push is not denied. If the special value "``*``", all remote users are
+ denied push. Otherwise, unauthenticated users are all denied, and
+ any authenticated user name present in this list (separated by
+ whitespace or ",") is also denied. The contents of the deny_push
+ list are examined before the allow_push list.
+``deny_read``
+ Whether to deny reading/viewing of the repository. If this list is
+ not empty, unauthenticated users are all denied, and any
+ authenticated user name present in this list (separated by
+ whitespace or ",") is also denied access to the repository. If set
+ to the special value "``*``", all remote users are denied access
+ (rarely needed ;). If deny_read is empty or not set, the
+ determination of repository access depends on the presence and
+ content of the allow_read list (see description). If both
+ deny_read and allow_read are empty or not set, then access is
+ permitted to all users by default. If the repository is being
+ served via hgwebdir, denied users will not be able to see it in
+ the list of repositories. The contents of the deny_read list have
+ priority over (are examined before) the contents of the allow_read
+ list.
+``description``
+ Textual description of the repository's purpose or contents.
+ Default is "unknown".
+``encoding``
+ Character encoding name.
+ Example: "UTF-8"
+``errorlog``
+ Where to output the error log. Default is stderr.
+``hidden``
+ Whether to hide the repository in the hgwebdir index.
+ Default is false.
+``ipv6``
+ Whether to use IPv6. Default is false.
+``name``
+ Repository name to use in the web interface. Default is current
+ working directory.
+``maxchanges``
+ Maximum number of changes to list on the changelog. Default is 10.
+``maxfiles``
+ Maximum number of files to list per changeset. Default is 10.
+``port``
+ Port to listen on. Default is 8000.
+``prefix``
+ Prefix path to serve from. Default is '' (server root).
+``push_ssl``
+ Whether to require that inbound pushes be transported over SSL to
+ prevent password sniffing. Default is true.
+``staticurl``
+ Base URL to use for static files. If unset, static files (e.g. the
+ hgicon.png favicon) will be served by the CGI script itself. Use
+ this setting to serve them directly with the HTTP server.
+ Example: "http://hgserver/static/"
+``stripes``
+ How many lines a "zebra stripe" should span in multiline output.
+ Default is 1; set to 0 to disable.
+``style``
+ Which template map style to use.
+``templates``
+ Where to find the HTML templates. Default is install path.
+
+
+AUTHOR
+------
+Bryan O'Sullivan <bos@serpentine.com>.
+
+Mercurial was written by Matt Mackall <mpm@selenic.com>.
+
+SEE ALSO
+--------
+|hg(1)|_, |hgignore(5)|_
+
+COPYING
+-------
+This manual page is copyright 2005 Bryan O'Sullivan.
+Mercurial is copyright 2005-2009 Matt Mackall.
+Free use of this software is granted under the terms of the GNU General
+Public License (GPL).
+
+.. include:: common.txt
diff --git a/sys/src/cmd/hg/doc/ja/Makefile b/sys/src/cmd/hg/doc/ja/Makefile
new file mode 100644
index 000000000..154239fb4
--- /dev/null
+++ b/sys/src/cmd/hg/doc/ja/Makefile
@@ -0,0 +1,21 @@
+SOURCES=$(wildcard *.[0-9].ja.txt)
+MAN=$(SOURCES:%.txt=%)
+HTML=$(SOURCES:%.txt=%.html)
+
+all: man html
+
+man: $(MAN)
+
+html: $(HTML)
+
+%: %.xml
+ xmlto -x docbook.ja.xsl man $*.xml
+
+%.xml: %.txt
+ -asciidoc -d manpage -b docbook -f docbook.ja.conf $*.txt
+
+%.html: %.txt
+ asciidoc -b html4 $*.txt
+
+clean:
+ $(RM) $(MAN:%.ja=%) $(MAN:%=%.xml) $(MAN:%=%.html)
diff --git a/sys/src/cmd/hg/doc/ja/docbook.ja.conf b/sys/src/cmd/hg/doc/ja/docbook.ja.conf
new file mode 100644
index 000000000..355692ab2
--- /dev/null
+++ b/sys/src/cmd/hg/doc/ja/docbook.ja.conf
@@ -0,0 +1,583 @@
+#
+# docbook.conf
+#
+# Asciidoc configuration file.
+# Modified docbook backend for Japanese.
+#
+
+[miscellaneous]
+outfilesuffix=.xml
+# Printable page width in pts.
+pagewidth=380
+pageunits=pt
+
+[attributes]
+basebackend=docbook
+basebackend-docbook=
+
+[replacements]
+# Line break markup is dropped (there is no DocBook line break tag).
+(?m)^(.*)\s\+$=\1
+# Superscripts.
+\^(.+?)\^=<superscript>\1</superscript>
+# Subscripts.
+~(.+?)~=<subscript>\1</subscript>
+
+[ruler-blockmacro]
+# Only applies to HTML so don't output anything.
+
+[image-inlinemacro]
+<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="{target}"{width? contentwidth="{width}pt"}{height? contentdepth="{height}pt"}/>
+ </imageobject>
+ <textobject><phrase>{1={target}}</phrase></textobject>
+</inlinemediaobject>
+
+[image-blockmacro]
+<figure{id? id="{id}"}><title>{title}</title>
+{title%}<informalfigure{id? id="{id}"}>
+<mediaobject>
+ <imageobject>
+ <imagedata fileref="{target}"{width? contentwidth="{width}pt"}{height? contentdepth="{height}pt"}/>
+ </imageobject>
+ <textobject><phrase>{1={target}}</phrase></textobject>
+</mediaobject>
+{title#}</figure>
+{title%}</informalfigure>
+
+[indexterm-inlinemacro]
+# Inline index term.
+# Generate separate index entries for primary, secondary and tertiary
+# descriptions.
+# Primary only.
+{2%}<indexterm>
+{2%} <primary>{1}</primary>
+{2%}</indexterm>
+# Primary and secondary.
+{2#}{3%}<indexterm>
+{2#}{3%} <primary>{1}</primary><secondary>{2}</secondary>
+{2#}{3%}</indexterm>
+{2#}{3%}<indexterm>
+{2#}{3%} <primary>{2}</primary>
+{2#}{3%}</indexterm>
+# Primary, secondary and tertiary.
+{3#}<indexterm>
+ <primary>{1}</primary><secondary>{2}</secondary><tertiary>{3}</tertiary>
+{3#}</indexterm>
+{3#}<indexterm>
+ <primary>{2}</primary><secondary>{3}</secondary>
+{3#}</indexterm>
+{3#}<indexterm>
+ <primary>{3}</primary>
+{3#}</indexterm>
+
+[indexterm2-inlinemacro]
+# Inline index term.
+# Single entry index term that is visible in the primary text flow.
+<indexterm>
+ <primary>{1}</primary>
+</indexterm>
+{1}
+
+[footnote-inlinemacro]
+# Inline footnote.
+<footnote><simpara>{0}</simpara></footnote>
+
+[callout-inlinemacro]
+# Inline callout.
+<co id="{coid}"/>
+
+[tags]
+# Bulleted, numbered and labeled list tags.
+ilist=<itemizedlist{id? id="{id}"}>{title?<title>{title}</title>}|</itemizedlist>
+ilistitem=<listitem>|</listitem>
+ilisttext=<simpara>|</simpara>
+olist=<orderedlist{id? id="{id}"}>{title?<title>{title}</title>}|</orderedlist>
+olist2=<orderedlist{id? id="{id}"} numeration="loweralpha">|</orderedlist>
+olistitem=<listitem>|</listitem>
+olisttext=<simpara>|</simpara>
+vlist=<variablelist{id? id="{id}"}>{title?<title>{title}</title>}|</variablelist>
+vlistentry=<varlistentry>|</varlistentry>
+vlistterm=<term>|</term>
+vlisttext=<simpara>|</simpara>
+vlistitem=<listitem>|</listitem>
+# Horizontal labeled list (implemented with two column table).
+# Hardwired column widths to 30%,70% because the current crop of PDF
+# generators do not auto calculate column widths.
+hlist=<{title?table}{title!informaltable}{id? id="{id}"} tabstyle="{style=hlabeledlist}" pgwide="0" frame="none" colsep="0" rowsep="0">{title?<title>{title}</title>}<tgroup cols="2"><colspec colwidth="{1=3}*"/><colspec colwidth="{2=7}*"/><tbody valign="top">|</tbody></tgroup><{title?/table}{title!/informaltable}>
+hlistentry=<row>|</row>
+hlisttext=<simpara>|</simpara>
+hlistterm=<entry><simpara>|</simpara></entry>
+hlistitem=<entry>|</entry>
+
+# Question and Answer list.
+qlist=<qandaset{id? id="{id}"}>{title?<title>{title}</title>}|</qandaset>
+qlistentry=<qandaentry>|</qandaentry>
+qlistterm=<question><simpara>|</simpara></question>
+qlistitem=<answer>|</answer>
+qlisttext=<simpara>|</simpara>
+# Bibliography list.
+blist=|
+blistitem=<bibliomixed>|</bibliomixed>
+blisttext=<bibliomisc>|</bibliomisc>
+# Glossary list.
+glist=|
+glistentry=<glossentry>|</glossentry>
+glistterm=<glossterm>|</glossterm>
+glistitem=<glossdef>|</glossdef>
+glisttext=<simpara>|</simpara>
+# Callout list.
+colist=<calloutlist{id? id="{id}"}>{title?<title>{title}</title>}|</calloutlist>
+colistitem=<callout arearefs="{coids}">|</callout>
+colisttext=<simpara>|</simpara>
+
+# Quoted text
+emphasis=<emphasis>|</emphasis>
+strong=<emphasis role="strong">|</emphasis>
+monospaced=<literal>|</literal>
+quoted={amp}#8220;|{amp}#8221;
+
+# Inline macros
+[http-inlinemacro]
+<ulink url="{name}:{target}">{0={name}:{target}}</ulink>
+[https-inlinemacro]
+<ulink url="{name}:{target}">{0={name}:{target}}</ulink>
+[ftp-inlinemacro]
+<ulink url="{name}:{target}">{0={name}:{target}}</ulink>
+[file-inlinemacro]
+<ulink url="{name}:{target}">{0={name}:{target}}</ulink>
+[mailto-inlinemacro]
+<ulink url="{name}:{target}">{0={target}}</ulink>
+#<email>{target}</email>
+[link-inlinemacro]
+<ulink url="{target}">{0={target}}</ulink>
+# anchor:id[text]
+[anchor-inlinemacro]
+<anchor id="{target}" xreflabel="{0=[{target}]}"/>
+# [[id,text]]
+[anchor2-inlinemacro]
+<anchor id="{1}" xreflabel="{2=[{1}]}"/>
+# [[[id]]]
+[anchor3-inlinemacro]
+<anchor id="{1}" xreflabel="[{1}]"/>[{1}]
+# xref:id[text]
+[xref-inlinemacro]
+<link linkend="{target}">{0}</link>
+{2%}<xref linkend="{target}"/>
+# <<id,text>>
+[xref2-inlinemacro]
+<link linkend="{1}">{2}</link>
+{2%}<xref linkend="{1}"/>
+
+
+# Special word macros
+[emphasizedwords]
+<emphasis>{words}</emphasis>
+[monospacedwords]
+<literal>{words}</literal>
+[strongwords]
+<emphasis role="strong">{words}</emphasis>
+
+# Paragraph substitution.
+[paragraph]
+<formalpara{id? id="{id}"}><title>{title}</title><para>
+{title%}<simpara{id? id="{id}"}>
+|
+{title%}</simpara>
+{title#}</para></formalpara>
+{empty}
+
+[admonitionparagraph]
+<{name}{id? id="{id}"}><simpara>|</simpara></{name}>
+
+[literalparagraph]
+# The literal block employs the same markup.
+template::[literalblock]
+
+[verseparagraph]
+template::[verseblock]
+
+# Delimited blocks.
+[literalblock]
+<example><title>{title}</title>
+<literallayout{id? id="{id}"} class="{font=monospaced}">
+|
+</literallayout>
+{title#}</example>
+
+[listingblock]
+<example><title>{title}</title>
+<screen>
+|
+</screen>
+{title#}</example>
+
+[verseblock]
+<formalpara{id? id="{id}"}><title>{title}</title><para>
+{title%}<literallayout{id? id="{id}"}>
+{title#}<literallayout>
+|
+</literallayout>
+{title#}</para></formalpara>
+
+[sidebarblock]
+<sidebar{id? id="{id}"}>
+<title>{title}</title>
+|
+</sidebar>
+
+[backendblock]
+|
+
+[quoteblock]
+# The epigraph element may be more appropriate than blockquote.
+<blockquote{id? id="{id}"}>
+<title>{title}</title>
+<attribution>
+{attribution}
+<citetitle>{citetitle}</citetitle>
+</attribution>
+|
+</blockquote>
+
+[exampleblock]
+<{title?example}{title!informalexample}{id? id="{id}"}>
+<title>{title}</title>
+|
+</{title?example}{title!informalexample}>
+
+[admonitionblock]
+<{name}{id? id="{id}"}>
+<title>{title}</title>
+|
+</{name}>
+
+# Tables.
+[tabledef-default]
+template=table
+colspec=<colspec colwidth="{colwidth}{pageunits}" align="{colalign}"/>
+bodyrow=<row>|</row>
+bodydata=<entry>|</entry>
+
+[table]
+<{title?table}{title!informaltable}{id? id="{id}"} pgwide="0"
+frame="{frame=topbot}"
+{grid%rowsep="0" colsep="0"}
+{eval:\{"none":"rowsep=\"0\" colsep=\"0\"", "cols":"rowsep=\"0\" colsep=\"1\"", "all":"rowsep=\"1\" colsep=\"1\"", "rows":"rowsep=\"1\" colsep=\"0\"" \}["{grid}"]}
+>
+<title>{title}</title>
+<tgroup cols="{cols}">
+{colspecs}
+{headrows#}<thead>
+{headrows}
+{headrows#}</thead>
+{footrows#}<tfoot>
+{footrows}
+{footrows#}</tfoot>
+<tbody>
+{bodyrows}
+</tbody>
+</tgroup>
+</{title?table}{title!informaltable}>
+
+[specialsections]
+ifdef::doctype-article[]
+^Abstract$=sect-abstract
+endif::doctype-article[]
+
+ifdef::doctype-book[]
+^Colophon$=sect-colophon
+^Dedication$=sect-dedication
+^Preface$=sect-preface
+endif::doctype-book[]
+
+^Index$=sect-index
+^(Bibliography|References)$=sect-bibliography
+^Glossary$=sect-glossary
+^Appendix [A-Z][:.](?P<title>.*)$=sect-appendix
+
+# Special sections.
+[sect-preface]
+<preface{id? id="{id}"}>
+<title>{title}</title>
+|
+</preface>
+
+[sect-index]
+<index{id? id="{id}"}>
+<title>{title}</title>
+|
+</index>
+
+[sect-bibliography]
+<bibliography{id? id="{id}"}>
+<title>{title}</title>
+|
+</bibliography>
+
+[sect-glossary]
+<glossary{id? id="{id}"}>
+<title>{title}</title>
+|
+</glossary>
+
+[sect-appendix]
+<appendix{id? id="{id}"}>
+<title>{title}</title>
+|
+</appendix>
+
+
+[header-declarations]
+<?xml version="1.0" encoding="{encoding}"?>
+<!DOCTYPE {eval:\{"article":"article", "book":"book", "manpage":"refentry"\}["{doctype}"]} PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+#-------------------------
+# article document type
+#-------------------------
+ifdef::doctype-article[]
+
+[header]
+template::[header-declarations]
+
+<article lang="ja">
+{doctitle#}<articleinfo>
+ <title>{doctitle}</title>
+ <date>{date}</date>
+ {authored#}<author>
+ <firstname>{firstname}</firstname>
+ <othername>{middlename}</othername>
+ <surname>{lastname}</surname>
+ <affiliation><address><email>{email}</email></address></affiliation>
+ {authored#}</author>
+
+# If file named like source document with -revhistory.xml suffix exists
+# include it as the document history, otherwise use current revision.
+{revisionhistory#}{include:{docdir}/{docname}-revhistory.xml}
+{revisionhistory%}<revhistory><revision><revnumber>{revision}</revnumber><date>{date}</date>{revremark?<revremark>{revremark}</revremark>}</revision></revhistory>
+
+ <corpname>{companyname}</corpname>
+{doctitle#}</articleinfo>
+
+[footer]
+</article>
+
+[preamble]
+# Untitled elements between header and first section title.
+|
+
+[sect-abstract]
+<abstract{id? id="{id}"}>
+|
+</abstract>
+
+[sect1]
+<section{id? id="{id}"}>
+<title>{title}</title>
+|
+</section>
+
+[sect2]
+<section{id? id="{id}"}>
+<title>{title}</title>
+|
+</section>
+
+[sect3]
+<section{id? id="{id}"}>
+<title>{title}</title>
+|
+</section>
+
+[sect4]
+<section{id? id="{id}"}>
+<title>{title}</title>
+|
+</section>
+
+endif::doctype-article[]
+
+#-------------------------
+# manpage document type
+#-------------------------
+ifdef::doctype-manpage[]
+
+[replacements]
+# The roff format does not substitute special characters so just print them as
+# text.
+\(C\)=(C)
+\(TM\)=(TM)
+
+[header]
+template::[header-declarations]
+<refentry>
+<refmeta>
+<refentrytitle>{mantitle}</refentrytitle>
+<manvolnum>{manvolnum}</manvolnum>
+</refmeta>
+<refnamediv>
+ <refname>{manname}</refname>
+ <refpurpose>{manpurpose}</refpurpose>
+</refnamediv>
+
+[footer]
+</refentry>
+
+# Section macros
+[sect-synopsis]
+<refsynopsisdiv{id? id="{id}"}>
+|
+</refsynopsisdiv>
+
+[sect1]
+<refsect1{id? id="{id}"}>
+<title>{title}</title>
+|
+</refsect1>
+
+[sect2]
+<refsect2{id? id="{id}"}>
+<title>{title}</title>
+|
+</refsect2>
+
+[sect3]
+<refsect3{id? id="{id}"}>
+<title>{title}</title>
+|
+</refsect3>
+
+endif::doctype-manpage[]
+
+#-------------------------
+# book document type
+#-------------------------
+ifdef::doctype-book[]
+
+[header]
+template::[header-declarations]
+
+<book lang="ja">
+{doctitle#}<bookinfo>
+ <title>{doctitle}</title>
+ <date>{date}</date>
+ {authored#}<author>
+ <firstname>{firstname}</firstname>
+ <othername>{middlename}</othername>
+ <surname>{lastname}</surname>
+ <affiliation><address><email>{email}</email></address></affiliation>
+ {authored#}</author>
+
+# If file named like source document with -revhistory.xml suffix exists
+# include it as the document history, otherwise use current revision.
+{revisionhistory#}{include:{docdir}/{docname}-revhistory.xml}
+{revisionhistory%}<revhistory><revision><revnumber>{revision}</revnumber><date>{date}</date>{revremark?<revremark>{revremark}</revremark>}</revision></revhistory>
+
+ <corpname>{companyname}</corpname>
+{doctitle#}</bookinfo>
+
+[footer]
+</book>
+
+[preamble]
+# Preamble is not allowed in DocBook book so wrap it in a preface.
+<preface{id? id="{id}"}>
+<title>Preface</title>
+|
+</preface>
+
+[sect-dedication]
+<dedication{id? id="{id}"}>
+|
+</dedication>
+
+[sect-colophon]
+<colophon{id? id="{id}"}>
+|
+</colophon>
+
+[sect0]
+<part{id? id="{id}"}>
+<title>{title}</title>
+|
+</part>
+
+[sect1]
+<chapter{id? id="{id}"}>
+<title>{title}</title>
+|
+</chapter>
+
+[sect2]
+<section{id? id="{id}"}>
+<title>{title}</title>
+|
+</section>
+
+[sect3]
+<section{id? id="{id}"}>
+<title>{title}</title>
+|
+</section>
+
+[sect4]
+<section{id? id="{id}"}>
+<title>{title}</title>
+|
+</section>
+
+endif::doctype-book[]
+
+ifdef::sgml[]
+#
+# Optional DocBook SGML.
+#
+# Most of the differences between DocBook XML and DocBook SGML boils
+# down to the empty element syntax: SGML does not like the XML empty
+# element <.../> syntax, use <...> instead.
+#
+[miscellaneous]
+outfilesuffix=.sgml
+
+[header-declarations]
+<!DOCTYPE {eval:\{"article":"article", "book":"book", "manpage":"refentry"\}["{doctype}"]} PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+[tabledef-default]
+colspec=<colspec colwidth="{colwidth}{pageunits}" align="{colalign}">
+
+[image-inlinemacro]
+<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="{target}"{width? width="{width}pt"}{height? depth="{height}pt"}>
+ </imageobject>
+ <textobject><phrase>{1={target}}</phrase></textobject>
+</inlinemediaobject>
+
+[image-blockmacro]
+<figure><title>{title}</title>
+{title%}<informalfigure>
+<mediaobject>
+ <imageobject>
+ <imagedata fileref="{target}"{width? width="{width}pt"}{height? depth="{height}pt"}>
+ </imageobject>
+ <textobject><phrase>{1={target}}</phrase></textobject>
+</mediaobject>
+{title#}</figure>
+{title%}</informalfigure>
+
+# Inline macros
+[xref-inlinemacro]
+<link linkend="{target}">{0}</link>
+{2%}<xref linkend="{target}">
+[xref2-inlinemacro]
+# <<id,text>>
+<link linkend="{1}">{2}</link>
+{2%}<xref linkend="{1}">
+[anchor-inlinemacro]
+<anchor id="{target}" xreflabel="{0=[{target}]}">
+[anchor2-inlinemacro]
+# [[id,text]]
+<anchor id="{1}" xreflabel="{2=[{1}]}">
+
+endif::sgml[]
diff --git a/sys/src/cmd/hg/doc/ja/docbook.ja.xsl b/sys/src/cmd/hg/doc/ja/docbook.ja.xsl
new file mode 100644
index 000000000..aba2d65c1
--- /dev/null
+++ b/sys/src/cmd/hg/doc/ja/docbook.ja.xsl
@@ -0,0 +1,23 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+ <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl"/>
+ <xsl:output encoding="UTF-8"/>
+
+ <xsl:template match="refnamediv">
+ <xsl:text>.SH åå‰&#10;</xsl:text>
+ <xsl:for-each select="refname">
+ <xsl:if test="position()>1">
+ <xsl:text>, </xsl:text>
+ </xsl:if>
+ <xsl:value-of select="."/>
+ </xsl:for-each>
+ <xsl:text> \- </xsl:text>
+ <xsl:value-of select="normalize-space (refpurpose)"/>
+ </xsl:template>
+
+ <xsl:template match="refsynopsisdiv">
+ <xsl:text>&#10;.SH "書å¼"&#10;</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/sys/src/cmd/hg/doc/ja/hg.1.ja.txt b/sys/src/cmd/hg/doc/ja/hg.1.ja.txt
new file mode 100644
index 000000000..889cb4b57
--- /dev/null
+++ b/sys/src/cmd/hg/doc/ja/hg.1.ja.txt
@@ -0,0 +1,867 @@
+HG(1)
+=====
+Matt Mackall <mpm@selenic.com>
+
+åå‰
+--
+hg - Mercurial ソースコード管ç†ã‚·ã‚¹ãƒ†ãƒ 
+
+書å¼
+--
+'hg' [-v -d -q -y] <command> [command options] [files]
+
+説明
+--
+hg(1) コマンド㯠Mercurial システムã¸ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§
+イスをæä¾›ã—ã¾ã™ã€‚
+
+オプション
+----
+
+-R, --repository::
+ リãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’指定ã—ã¾ã™ã€‚
+
+--cwd::
+ 作業ディレクトリを変更ã—ã¾ã™ã€‚
+
+-y, --noninteractive::
+ プロンプトを出ã•ãšã«ã€è¦æ±‚ã•れãŸç­”ãˆãŒå…¨ã¦ 'yes' ã§ã‚ã‚‹ã¨ä»®å®š
+ ã—ã¾ã™ã€‚
+
+-q, --quiet::
+ 出力を抑制ã—ã¾ã™ã€‚
+
+-v, --verbose::
+ ã•らãªã‚‹å‡ºåŠ›ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚
+
+7--debug::
+ デãƒãƒƒã‚°å‡ºåŠ›ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚
+
+--traceback::
+ 例外時ã«ãƒˆãƒ¬ãƒ¼ã‚¹ãƒãƒƒã‚¯ã‚’表示ã—ã¾ã™ã€‚
+
+--time::
+ コマンドã«ã©ã®ãã‚‰ã„æ™‚é–“ãŒã‹ã‹ã‚‹ã‹ã‚’表示ã—ã¾ã™ã€‚
+
+--profile::
+ コマンドを実行ã—ãŸã¨ãã®ãƒ—ロファイルを表示ã—ã¾ã™ã€‚
+
+--version::
+ ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦çµ‚了ã—ã¾ã™ã€‚
+
+-h, --help::
+ ヘルプを表示ã—ã¦çµ‚了ã—ã¾ã™ã€‚
+
+コマンドã®è¦ç´ 
+-------
+
+files ...::
+ 1ã¤ä»¥ä¸Šã®ãƒ•ァイルåã‹ç›¸å¯¾çš„ãªãƒ‘スを表ã—ã¾ã™; パターンマッãƒãƒ³
+ ã‚°ã®æƒ…å ±ã¯ã€Œãƒ•ァイルåã®ãƒ‘ターンã€ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+
+path::
+ ローカルマシン上ã®ãƒ‘スを表ã—ã¾ã™
+
+revision::
+ ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ãƒªãƒ“ジョンナンãƒãƒ¼, ã‚¿ã‚°, ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ãƒãƒƒ
+ シュ値ã®ãƒ¦ãƒ‹ãƒ¼ã‚¯ãªéƒ¨åˆ†æ–‡å­—列ã«ã‚ˆã‚ŠæŒ‡å®šã§ãã‚‹ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’表
+ ã—ã¾ã™
+
+repository path::
+ ローカルã®ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ‘スåã‹ãƒªãƒ¢ãƒ¼ãƒˆã®ãƒªãƒã‚¸ãƒˆãƒªã® URI を表
+ ã—ã¾ã™ã€‚URI ã®ãƒ—ロトコルã¨ã—ã¦ã¯ç¾åœ¨ 2 ã¤ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
+ http:// ã¯é«˜é€Ÿã§ã€static-http:// ã¯é…ã„ã§ã™ãŒã‚¦ã‚§ãƒ–ã®ãƒ›ã‚¹ãƒˆã«ç‰¹åˆ¥
+ ãªã‚µãƒ¼ãƒã‚’å¿…è¦ã¨ã—ã¾ã›ã‚“。
+
+コマンド
+----
+
+add [options] [files ...]::
+ ファイルをãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ä¸‹ã«ç½®ãリãƒã‚¸ãƒˆãƒªã«è¿½åŠ ã™ã‚‹ã“ã¨ã‚’予定
+ ã—ã¾ã™ã€‚
+
+ ãƒ•ã‚¡ã‚¤ãƒ«ã¯æ¬¡ã«ã‚³ãƒŸãƒƒãƒˆæ™‚ã«ãƒªãƒã‚¸ãƒˆãƒªã«è¿½åŠ ã•れã¾ã™ã€‚
+
+ ファイルåãŒä¸Žãˆã‚‰ã‚Œãªã‘れã°ã€ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨ã‚µãƒ–ディレク
+ トリã®å…¨ã¦ã®ãƒ•ァイルを追加ã—ã¾ã™ã€‚
+
+addremove [options] [files ...]::
+ æ–°ã—ã„ファイルを全ã¦è¿½åŠ ã—ç„¡ããªã£ãŸãƒ•ァイルを全ã¦ãƒªãƒã‚¸ãƒˆãƒªã‹
+ らå–り除ãã¾ã™ã€‚
+
+ æ–°ã—ã„ファイル㯠.hgignore 中ã®ãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸå ´åˆç„¡è¦–ã•
+ れã¾ã™ã€‚add ã®ã‚ˆã†ã«ã“ã®å¤‰æ›´ã¯æ¬¡ã®ã‚³ãƒŸãƒƒãƒˆæ™‚ã«åŠ¹æžœã‚’æŒã¡ã¾ã™ã€‚
+
+annotate [-r <rev> -u -n -c] [files ...]::
+ ファイル中ã®å¤‰æ›´ã‚’列挙ã—ã€å„行ã®åŽŸå› ã§ã‚るリビジョン id を表示
+ ã—ã¾ã™ã€‚
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã‚る変更ãŒç”Ÿã˜ãŸéš›ã«èª°ãŒãã®å¤‰æ›´ã‚’ã—ãŸã‹ã‚’発見ã™ã‚‹
+ ã®ã«å½¹ã«ç«‹ã¡ã¾ã™ã€‚
+
+ -a オプションãŒç„¡ã„ã¨ã€annotate ã¯ãƒã‚¤ãƒŠãƒªã¨ã—ã¦æ¤œå‡ºã•れãŸãƒ•ã‚¡
+ イルをé¿ã‘るよã†ã«ãªã‚Šã¾ã™ã€‚-a ãŒã‚ã‚‹ã¨ã€annotate ã¯ã¨ãã‹ã注
+ 釈を生æˆã—ã€ãŠãã‚‰ãæœ›ã¾ã—ããªã„çµæžœã«ãªã‚‹ã§ã—ょã†ã€‚
+
+ オプション:
+ -a, --text å…¨ã¦ã®ãƒ•ァイルをテキストã¨ã—ã¦æ‰±ã„ã¾ã™
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’å«ã‚
+ ã¾ã™
+ -X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’除外
+ ã—ã¾ã™
+ -r, --revision <rev> 指定ã•れãŸãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æ³¨é‡ˆã‚’生æˆã—ã¾ã™
+ -u, --user 著者を列挙ã—ã¾ã™
+ -c, --changeset ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’列挙ã—ã¾ã™
+ -n, --number リビジョンナンãƒãƒ¼ã‚’列挙ã—ã¾ã™
+ (デフォルト)
+
+bundle <file> <other>::
+ (実験的)
+
+ ä»–ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã¯è¦‹ä»˜ã‹ã‚‰ãªã‹ã£ãŸå…¨ã¦ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’集ã‚ãŸã€
+ 圧縮済ã¿ãƒã‚§ãƒ³ã‚¸ã‚°ãƒ«ãƒ¼ãƒ—ファイルを生æˆã—ã¾ã™ã€‚
+
+ ã“ã®ãƒ•ァイルã¯å¾“æ¥ã®æ–¹æ³•ã§è»¢é€ã™ã‚‹ã“ã¨ãŒã§ãã€ä»–ã®ãƒªãƒã‚¸ãƒˆãƒªã«
+ unbundle コマンドã§é©ç”¨ã§ãã¾ã™ã€‚ã“れ㯠push 㨠pull ãŒä½¿ãˆãª
+ ã„ã‹ã€ãƒªãƒã‚¸ãƒˆãƒªå…¨ä½“をエクスãƒãƒ¼ãƒˆã—ã¦ã—ã¾ã†ã“ã¨ãŒæœ›ã¾ã—ããªã„
+ ã¨ãã«ä¾¿åˆ©ã§ã™ã€‚標準ã®ãƒ•ァイル拡張å­ã¯ ".hg" ã§ã™ã€‚
+
+ import/export ã¨é•ã£ã¦ã€ã“れã¯ãƒ‘ーミッションã€åå‰å¤‰æ›´ã®ãƒ‡ãƒ¼ã‚¿ã€
+ リビジョンã®å±¥æ­´ã‚’å«ã‚ãŸãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®å†…容全ã¦ã‚’ä¿å­˜ã—ã¾ã™ã€‚
+
+cat [options] <file ...>::
+ 指定ã•れãŸãƒ•ァイルを与ãˆã‚‰ã‚ŒãŸãƒªãƒ“ジョンã®å†…容ã§è¡¨ç¤ºã—ã¾ã™ã€‚リ
+ ãƒ“ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れãªã‹ã£ãŸå ´åˆã¯ tip ãŒä½¿ã‚れã¾ã™ã€‚
+
+ 出力ã¯ãƒ•ァイルã«å¯¾ã—ã¦ã‚‚å¯èƒ½ã§ã™ã€‚ãã®å ´åˆã€ãƒ•ァイルåã¯ãƒ•ォー
+ マット文字列ã«ã‚ˆã‚ŠæŒ‡å®šã•れã¾ã™ã€‚フォーマットè¦å‰‡ã¯ export コマ
+ ンドã¨åŒã˜ã§ã™ãŒã€ã•ã‚‰ã«æ¬¡ã®ã‚‚ã®ãŒè¿½åŠ ã•れã¾ã™ã€‚
+
+ %s 出力ã•れるファイルã®ãƒ™ãƒ¼ã‚¹å
+ %d 出力ã•れるファイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªåã‹ã€ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆ
+ ã«ã„ã‚‹å ´åˆã¯ "."
+ %p 出力ã•れるファイルã®ãƒ«ãƒ¼ãƒˆã‹ã‚‰ã®ç›¸å¯¾ãƒ‘ス
+
+ オプション:
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰
+ ã‚’å«ã‚ã¾ã™
+ -X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰
+ を除外ã—ã¾ã™
+ -o, --output <filespec> æ•´å½¢ã•れãŸåå‰ã§ãƒ•ァイルã«å‡ºåŠ›ã—ã¾
+ ã™
+ -r, --rev <rev> 与ãˆã‚‰ã‚ŒãŸãƒªãƒ“ジョンを表示ã—ã¾ã™
+
+clone [-U] <source> [dest]::
+ 既存ã®ãƒªãƒã‚¸ãƒˆãƒªã®ã‚³ãƒ”ーを新ã—ã„ディレクトリã«ä½œæˆã—ã¾ã™
+
+ コピー先ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªåãŒæŒ‡å®šã•れãªã‘れã°ã€ãƒ‡ãƒ•ォルトã§ã‚½ãƒ¼ã‚¹
+ ã®ãƒ™ãƒ¼ã‚¹åを使用ã—ã¾ã™ã€‚
+
+ 今後㮠pull ã«ä½¿ãˆã‚‹ã‚ˆã†ã«ã€ã‚³ãƒ”ãƒ¼å…ƒãŒæ–°ã—ã„リãƒã‚¸ãƒˆãƒªã®
+ .hg/hgrc ã«è¿½åŠ ã•れã¾ã™ã€‚
+
+ 効率ã®ãŸã‚ã«ã€ã‚³ãƒ”ー元ã¨ã‚³ãƒ”ー先ãŒåŒã˜ãƒ•ァイルシステム上ã«ã‚ã‚‹
+ å ´åˆã¯ãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ãŒä½¿ã‚れã¾ã™ã€‚
+
+ オプションン:
+ -U, --noupdate æ–°ã—ã„作業ディレクトリ㧠update を行ã„ã¾ã›ã‚“
+ -e, --ssh 使用ã•れる ssh コマンドを指定ã—ã¾ã™
+ --remotecmd リモートå´ã§å®Ÿè¡Œã™ã‚‹ hg コマンドを指定ã—ã¾ã™
+
+commit [options] [files...]::
+ 指定ã•れãŸãƒ•ァイルã®å¤‰æ›´ã‚’リãƒã‚¸ãƒˆãƒªã«ã‚³ãƒŸãƒƒãƒˆã—ã¾ã™ã€‚
+
+ ã‚‚ã—ファイルã®ãƒªã‚¹ãƒˆãŒçœç•¥ã•れãŸã‚‰ã€ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆã‹ã‚‰å®Ÿè¡Œ
+ ã—ãŸ"hg status" ã§å ±å‘Šã•れる全ã¦ã®å¤‰æ›´ãŒã‚³ãƒŸãƒƒãƒˆã•れã¾ã™ã€‚
+
+ HGEDITOR ã‚„ EDITOR 環境変数ã¯ã‚³ãƒŸãƒƒãƒˆæ™‚ã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’追加ã™ã‚‹ã‚¨
+ ディタを起動ã™ã‚‹ãŸã‚ã«ä½¿ã‚れã¾ã™ã€‚
+
+ オプション:
+
+ -A, --addremove コミット中㫠addremove を実行ã—ã¾ã™
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’å«ã‚
+ ã¾ã™
+ -X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’除外
+ ã—ã¾ã™
+ -m, --message <text> <text> をコミットメッセージã¨ã—ã¦ä½¿ã„ã¾
+ ã™
+ -l, --logfile <file> <file> ã‹ã‚‰ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’読ã¿è¾¼ã¿
+ ã¾ã™
+ -d, --date <datecode> datecode をコミットã—ãŸæ—¥ä»˜ã¨ã—ã¦è¨˜éŒ²ã—
+ ã¾ã™
+ -u, --user <user> user をコミッタã¨ã—ã¦è¨˜éŒ²ã—ã¾ã™ã€‚
+
+ 別å: ci
+
+copy <source ...> <dest>::
+ コピー先ãŒã‚³ãƒ”ー元ã®ãƒ•ァイルã®ã‚³ãƒ”ーをæŒã£ã¦ã„ã‚‹ã¨å°ã‚’付ã‘ã¾ã™ã€‚
+ ã‚‚ã—コピー先ãŒãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãªã‚‰ã€ã‚³ãƒ”ーã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸­ã«ç½®ã‹ã‚Œ
+ ã¾ã™ã€‚ã‚‚ã—コピー先ãŒãƒ•ァイルãªã‚‰ã€ã‚³ãƒ”ー元ã¯1ã¤ã®ã¿æŒ‡å®šå¯èƒ½ã§
+ ã™ã€‚
+
+ デフォルトã§ã¯ã€ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒ•ァイルãŒãã®ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«
+ ã‚ã‚‹ã‚‚ã®ã¨ã—ã¦ãã®å†…容をコピーã—ã¾ã™ã€‚ã‚‚ã— --after ã¨ä¸€ç·’ã«å‘¼
+ ã³å‡ºã•れれã°ã€æ“作ã¯è¨˜éŒ²ã•れã¾ã™ãŒã€ã‚³ãƒ”ーã¯å®Ÿè¡Œã•れã¾ã›ã‚“。
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯æ¬¡ã®ã‚³ãƒŸãƒƒãƒˆæ™‚ã«åŠ¹æžœã‚’æŒã¡ã¾ã™ã€‚
+
+ 注æ„: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯å®Ÿé¨“çš„ã§ã™ã€‚リãƒãƒ¼ãƒ ã•れãŸãƒ•ァイルをé©åˆ‡ã«
+ 記録ã§ãã¾ã™ãŒã€ã“ã®æƒ…å ±ã¯ãƒžãƒ¼ã‚¸ã«ã‚ˆã£ã¦ã¾ã å®Œå…¨ã«ã¯ä½¿ã‚れã¾ã›
+ ã‚“ã—ã€ãƒ­ã‚°ã§å®Œå…¨ã«å ±å‘Šã•れるã“ã¨ã‚‚ã‚りã¾ã›ã‚“。
+
+ オプション:
+ -A, --after æ—¢ã«ç™ºç”Ÿã—ãŸã‚³ãƒ”ーを記録ã—ã¾ã™ã€‚
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’å«ã‚
+ ã¾ã™
+ -X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’除外
+ ã—ã¾ã™
+ -f, --force 既存ã®å¤‰æ›´ã•れãŸãƒ•ァイルã«ç„¡ç†çŸ¢ç†ã‚³ãƒ”ー
+ ã—ã¾ã™
+ -p, --parents コピー先ã«ã‚³ãƒ”ー元ã®ãƒ‘スを追加ã—ã¾ã™
+
+ 別å: cp
+
+diff [-a] [-r revision] [-r revision] [files ...]::
+ 指定ã•れãŸãƒ•ァイルã®ãƒªãƒ“ジョン間ã®å·®åˆ†ã‚’表示ã—ã¾ã™ã€‚
+
+ ファイル間ã®å·®åˆ†ã¯ unified diff å½¢å¼ã§è¡¨ç¤ºã•れã¾ã™ã€‚
+
+ 2ã¤ã®ãƒªãƒ“ジョンãŒå¼•æ•°ã¨ã—ã¦æŒ‡å®šã•れãŸå ´åˆã€ãれらã®ãƒªãƒ“ジョン
+ é–“ã®å·®åˆ†ãŒè¡¨ç¤ºã•れã¾ã™ã€‚1ã¤ã®ãƒªãƒ“ジョンã—ã‹æŒ‡å®šã•れãªã‘れã°ã€
+ ãã®ãƒªãƒ“ジョンã¯ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨æ¯”較ã•れã¾ã™ã€‚ãã—㦠リビジョ
+ ãƒ³ãŒæŒ‡å®šã•れãªã‘れã°ã€ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ãƒ•ァイルãŒãã®è¦ªã¨æ¯”較
+ ã•れã¾ã™ã€‚
+
+ -a オプション無ã—ã§ã¯ã€diff ã¯ãƒã‚¤ãƒŠãƒªãƒ•ァイルを検出ã—ãŸã¨ãã«
+ ãã®å·®åˆ†ã‚’生æˆã™ã‚‹ã®ã‚’é¿ã‘ã¾ã™ã€‚-a オプションã§ã¯ã€diff ã¯ã¨ã«
+ ã‹ã差分を生æˆã—ã€æã‚‰ãæœ›ã¾ã—ããªã„çµæžœã‚’ã‚‚ãŸã‚‰ã™ã§ã—ょã†ã€‚
+
+ オプション:
+ -a, --text å…¨ã¦ã®ãƒ•ァイルをテキストã¨ã—ã¦æ‰±ã„ã¾ã™
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’å«ã‚
+ ã¾ã™
+ -X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’除外
+ ã—ã¾ã™
+
+export [-o filespec] [revision] ...::
+ 1ã¤ä»¥ä¸Šã®ãƒªãƒ“ジョンã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ãƒ˜ãƒƒãƒ€ã¨å·®åˆ†ã‚’出力ã—ã¾ã™ã€‚
+
+ ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ãƒ˜ãƒƒãƒ€ã«è¡¨ç¤ºã•れる情報ã¯: 著者ã€ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ
+ ã®ãƒãƒƒã‚·ãƒ¥ã€è¦ªã€ã‚³ãƒŸãƒƒãƒˆæ™‚ã®ã‚³ãƒ¡ãƒ³ãƒˆã§ã™ã€‚
+
+ 出力ã¯ãƒ•ァイルã«å¯¾ã—ã¦ã‚‚å¯èƒ½ã§ã™ã€‚ãã®å ´åˆã€ãƒ•ァイルåã¯ãƒ•ォー
+ マット文字列ã«ã‚ˆã‚ŠæŒ‡å®šã•れã¾ã™ã€‚フォーマットè¦å‰‡ã¯ä¸‹è¨˜ã®é€šã‚Šã§
+ ã™:
+
+ %% ãã®ã¾ã¾ã® "%" 文字
+ %H ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ãƒãƒƒã‚·ãƒ¥ (40 ãƒã‚¤ãƒˆã® 16 進数)
+ %N 生æˆã•れã¦ã„るパッãƒã®ç•ªå·
+ %R ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ãƒªãƒ“ジョンナンãƒãƒ¼
+ %b エクスãƒãƒ¼ãƒˆã—ã¦ã„るリãƒã‚¸ãƒˆãƒªã®ãƒ¡ãƒ¼ã‚¹å
+ %h 短ã„å½¢å¼ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ãƒãƒƒã‚·ãƒ¥ (12 ãƒã‚¤ãƒˆã® 16 進数)
+ %n 0 ã§ è©°ã‚られ㟠1 ã‹ã‚‰å§‹ã¾ã‚‹é€£ç•ª
+ %r 0 ã§ è©°ã‚られãŸãƒªãƒ“ジョンナンãƒãƒ¼
+
+ -a オプション無ã—ã§ã¯ã€diff ã¯ãƒã‚¤ãƒŠãƒªãƒ•ァイルを検出ã—ãŸã¨ãã«
+ ãã®å·®åˆ†ã‚’生æˆã™ã‚‹ã®ã‚’é¿ã‘ã¾ã™ã€‚-a オプションã§ã¯ã€diff ã¯ã¨ã«
+ ã‹ã差分を生æˆã—ã€æã‚‰ãæœ›ã¾ã—ããªã„çµæžœã‚’ã‚‚ãŸã‚‰ã™ã§ã—ょã†ã€‚
+
+ オプション:
+ -a, --text å…¨ã¦ã®ãƒ•ァイルをテキストã¨ã—ã¦æ‰±ã„ã¾ã™
+ -o, --output <filespec> æ•´å½¢ã•れãŸåå‰ã§ãƒ•ァイルã«å‡ºåŠ›ã—ã¾ã™
+
+forget [options] [files]::
+ 次ã®ã‚³ãƒŸãƒƒãƒˆæ™‚ã«äºˆå®šã•れ㟠'hg add' ã‚’å–り消ã—ã¾ã™ã€‚
+
+ オプション:
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’å«ã‚ã¾
+ -ã™X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’除外
+ -ã—ã¾ã™
+
+grep [options] pattern [files]::
+ æ­£è¦è¡¨ç¾ã«ã‚ˆã‚Šãƒ•ァイルã®ãƒªãƒ“ジョンを検索ã—ã¾ã™ã€‚
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ Unix ã® grep ã¨ã¯é•ã†æŒ¯èˆžã„ã‚’ã—ã¾ã™ã€‚ã“れã¯
+ Python/Perl ã®æ­£è¦è¡¨ç¾ã ã‘ã‚’å—ã‘ã¤ã‘ã¾ã™ã€‚ã“れã¯ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆ
+ リã§ã¯ãªãリãƒã‚¸ãƒˆãƒªã®å±¥æ­´ã‚’検索ã—ã¾ã™ã€‚ã“れã¯å¸¸ã«ãƒžãƒƒãƒã—ãŸã‚‚
+ ã®ãŒç¾ã‚ŒãŸãƒªãƒ“ジョンナンãƒãƒ¼ã‚’表示ã—ã¾ã™ã€‚
+
+ デフォルトã§ã¯ã€grep ã¯ãƒžãƒƒãƒã—ãŸã‚‚ã®ãŒè¦‹ã¤ã‹ã£ãŸãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€
+ åˆã®ãƒªãƒ“ジョンを出力ã—ã¾ã™ã€‚マッãƒçжæ³ã®å¤‰åŒ–("-" ã¯ãƒžãƒƒãƒãŒéž
+ マッãƒã«ã€"+" ã¯éžãƒžãƒƒãƒãŒãƒžãƒƒãƒã«)ã‚’å«ã‚“ã å„リビジョンを表示
+ ã™ã‚‹ã«ã¯ã€--all フラグを使ã£ã¦ãã ã•ã„。
+
+ オプション:
+ -0, --print0 ファイルåã‚’ NUL ã§çµ‚ãˆã¾ã™ã€‚
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰
+ ã‚’å«ã‚ã¾ã™
+ -X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰
+ を除外ã—ã¾ã™
+ --all マッãƒã—ãŸå…¨ã¦ã®ãƒªãƒ“ジョンを表示ã—
+ ã¾ã™
+ -i, --ignore-case マッãƒã®ã¨ãã«è‹±å¤§æ–‡å­—ã¨å°æ–‡å­—を区
+ 別ã—ãªã„よã†ã«ã—ã¾ã™
+ -l, --files-with-matches マッãƒã—ãŸãƒ•ァイルåã¨ãƒªãƒ“ジョンã®
+ ã¿ã‚’表示ã—ã¾ã™
+ -n, --line-number マッãƒã—ãŸè¡Œç•ªå·ã‚’表示ã—ã¾ã™
+ -r, --rev <rev> 指定ã•れãŸãƒªãƒ“ジョンã®é–“ã§æ¤œç´¢ã—ã¾
+ ã™
+ -u, --user ãã®å¤‰æ›´ã‚’コミットã—ãŸãƒ¦ãƒ¼ã‚¶ã‚’表示
+ ã—ã¾ã™
+
+heads::
+ リãƒã‚¸ãƒˆãƒªã®å…ˆé ­ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’å…¨ã¦è¡¨ç¤ºã—ã¾ã™ã€‚
+
+ リãƒã‚¸ãƒˆãƒªã®ã€Œå…ˆé ­ã€ã¨ã¯å­ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’æŒã£ã¦ã„ãªã„ãƒã‚§ãƒ³
+ ジセットã§ã™ã€‚ãれらã¯å¤§æŠµé–‹ç™ºãŒè¡Œã‚れる場所ã§ã€é€šå¸¸ update ã¨
+ merge æ“作ã®å¯¾è±¡ã¨ãªã‚‹ã¨ã“ã‚ã§ã™ã€‚
+
+identify::
+ レãƒã‚¸ãƒˆãƒªã®ç¾åœ¨ã®çŠ¶æ…‹ã®çŸ­ã„サマリを表示ã—ã¾ã™ã€‚
+
+ ã“ã®ã‚µãƒžãƒªã¯ãƒªãƒã‚¸ãƒˆãƒªã®çŠ¶æ…‹ã‚’1ã¤ã¾ãŸã¯2ã¤ã®è¦ªã®ãƒãƒƒã‚·ãƒ¥è­˜åˆ¥å­
+ を使ã£ã¦è­˜åˆ¥ã—ã¾ã™ã€‚親ã®ãƒãƒƒã‚·ãƒ¥è­˜åˆ¥å­ã¯ã‚‚ã—作業ディレクトリã«
+ コミットã•れã¦ã„ãªã„変更ãŒã‚れã°å¾Œã‚ã« + ãŒä»˜ãã€æ›´ã«ãã®å¾Œã«
+ ã“ã®ãƒªãƒ“ジョンã®ã‚¿ã‚°ã®ãƒªã‚¹ãƒˆãŒä»˜ãã¾ã™ã€‚
+
+ 別å: id
+
+import [-p <n> -b <base> -f] <patches>::
+ 一連ã®ãƒ‘ッãƒã‚’インãƒãƒ¼ãƒˆã—ã€ãれãžã‚Œå€‹åˆ¥ã«ã‚³ãƒŸãƒƒãƒˆã—ã¾ã™ã€‚
+
+ ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æœªè§£æ±ºã®å¤‰æ›´ãŒã‚ã£ãŸå ´åˆã€import 㯠-f フラ
+ ã‚°ãŒæŒ‡å®šã•れã¦ãªã‘れã°ä¸­æ–­ã—ã¾ã™ã€‚
+
+ ã‚‚ã—パッãƒãŒãƒ¡ãƒ¼ãƒ«ã®ã‚ˆã†(最åˆã®è¡ŒãŒ "From " ã‹ RFC 822 ヘッダ
+ ã®ã‚ˆã†) ã§ã‚れã°ã€-f オプションãŒä½¿ã‚れã¦ã„ãªã„é™ã‚Šãれã¯é©ç”¨
+ ã•れã¾ã›ã‚“。インãƒãƒ¼ãƒˆæ©Ÿæ§‹ã¯ãƒ¡ãƒ¼ãƒ«ã®ãƒ˜ãƒƒãƒ€ã‚’パースもã—ãªã‘れã°
+ 破棄もã—ãªã„ã®ã§ã€æœ¬ç‰©ã®ãƒ¡ãƒ¼ãƒ«ã‚’インãƒãƒ¼ãƒˆã—ãªã„よã†ã«ã™ã‚‹ã€Œãƒ¡ãƒ¼
+ ルã®ã‚ˆã†ãªã‚‚ã®ã®ã€å¥å…¨æ€§ãƒã‚§ãƒƒã‚¯ã‚’上書ãã™ã‚‹ãŸã‚ã ã‘ã« -f を使ã£
+ ã¦ãã ã•ã„。
+
+ オプション:
+ -p, --strip <n> patch 㮠ディレクトリ除去オプションã§ã™ã€‚ã“れ
+ ã¯é–¢é€£ã™ã‚‹ patch ã®ã‚ªãƒ—ションã¨åŒã˜æ„味をæŒã¡
+ ã¾ã™
+ -b <path> パッãƒã‚’読ã¿è¾¼ã‚€ãƒ™ãƒ¼ã‚¹ã¨ãªã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’指
+ 定ã—ã¾ã™
+ -f, --force 未解決ã§ã¾ã ã‚³ãƒŸãƒƒãƒˆã•れã¦ã„ãªã„変更ã®ãƒã‚§ãƒƒ
+ クをçœç•¥ã—ã¾ã™
+
+ 別å: patch
+
+incoming [-p] [source]::
+ 指定ã•れãŸãƒªãƒã‚¸ãƒˆãƒªã‹ã€ãƒ‡ãƒ•ォルト㧠pull ã™ã‚‹ãƒªãƒã‚¸ãƒˆãƒªä¸­ã«è¦‹
+ ã¤ã‹ã£ãŸæ–°ã—ã„ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’表示ã—ã¾ã™ã€‚ã“れら㯠pull ãŒè¦æ±‚
+ ã•れãŸã¨ãã«pull ã•れるãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã§ã™ã€‚
+
+ ç¾åœ¨ã¯ãƒ­ãƒ¼ã‚«ãƒ«ã®ãƒªãƒã‚¸ãƒˆãƒªã®ã¿ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™ã€‚
+
+ オプション:
+ -p, --patch パッãƒã‚’表示ã—ã¾ã™
+
+ 別å: in
+
+init [dest]::
+ 指定ã•れãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸­ã«æ–°ã—ã„リãƒã‚¸ãƒˆãƒªã‚’åˆæœŸåŒ–ã—ã¾ã™ã€‚指定
+ ã•れãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒå­˜åœ¨ã—ãªã„å ´åˆã¯ä½œæˆã•れã¾ã™ã€‚
+
+ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒæŒ‡å®šã•れãªã‘れã°ã€ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒä½¿ç”¨ã•れã¾
+ ã™ã€‚
+
+locate [options] [files]::
+ Mercurial ã®ç®¡ç†ä¸‹ã«ã‚るファイルã§åå‰ãŒæŒ‡å®šã•れãŸãƒ‘ターンã«ãƒžãƒƒ
+ ãƒã—ãŸã‚‚ã®ã‚’å…¨ã¦è¡¨ç¤ºã—ã¾ã™ã€‚
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨ã‚µãƒ–ディレクトリを検索ã—ã¾ã™ã€‚
+ リãƒã‚¸ãƒˆãƒªå…¨ä½“を検索ã™ã‚‹ã«ã¯ã€ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆã«ç§»å‹•ã—ã¦ãã 
+ ã•ã„。
+
+ ã‚‚ã—マッãƒã™ã‚‹ãŸã‚ã®ãƒ‘ターンãŒä¸Žãˆã‚‰ã‚Œãªã‘れã°ã€ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯
+ å…¨ã¦ã®ãƒ•ァイルã®åå‰ã‚’表示ã—ã¾ã™ã€‚
+
+ ã‚‚ã—ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã®å‡ºåŠ›ã‚’ "xargs" コマンドã«é€ã‚ŠãŸã„ãªã‚‰ã€
+ "-0" オプションをã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¨ "xargs" コマンドã®ä¸¡æ–¹ã§ä½¿ç”¨ã—
+ ã¦ãã ã•ã„。ã“れ㯠"xargs" ãŒã‚¹ãƒšãƒ¼ã‚¹ã®å…¥ã£ãŸãƒ•ァイルåを複数
+ ã®ãƒ•ァイルåã¨ã—ã¦æ‰±ã‚ãªã„よã†ã«ã—ã¾ã™ã€‚
+
+ オプション:
+
+ -0, --print0 xargs ã¨ä¸€ç·’ã«ä½¿ã†ãŸã‚ã«ã€ãƒ•ァイルåã‚’
+ NUL ã§çµ‚ãˆã¾ã™
+ -f, --fullpath ファイルシステムã®ãƒ«ãƒ¼ãƒˆã‹ã‚‰ã®å®Œå…¨ãªãƒ‘
+ スを表示ã—ã¾ã™
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’å«
+ ã‚ã¾ã™
+ -r, --rev <rev> rev ã®ã¨ãã®ãƒªãƒã‚¸ãƒˆãƒªã‚’検索ã—ã¾ã™
+ -X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’除外
+ ã—ã¾ã™
+
+log [-r revision ...] [-p] [files]::
+ 指定ã•れãŸãƒ•ァイルã‹ãƒ—ロジェクト全体ã®ãƒªãƒ“ジョンã®å±¥æ­´ã‚’表示ã—
+ ã¾ã™ã€‚
+
+ デフォルトã§ã¯ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯æ¬¡ã®ã‚‚ã®ã‚’出力ã—ã¾ã™: ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒ
+ トã®id ã¨ãƒãƒƒã‚·ãƒ¥ã€ã‚¿ã‚°ã€è¦ªã€ãƒ¦ãƒ¼ã‚¶ã€æ—¥ä»˜ã€å„コミットã®ã‚µãƒž
+ リ。-v スイッãƒã¯å¤‰æ›´ã•れãŸãƒ•ァイルやマニフェストã®ãƒãƒƒã‚·ãƒ¥ã€
+ メッセージã®ã‚·ã‚°ãƒãƒãƒ£ã¨ã„ã£ãŸã‚ˆã‚Šè©³ã—ã„æƒ…報を追加ã—ã¾ã™ã€‚
+
+ オプション:
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’å«ã‚
+ ã¾ã™
+ -X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’除外
+ ã—ã¾ã™
+ -r, --rev <A> 指定ã•れãŸãƒªãƒ“ジョンã¾ãŸã¯ç¯„囲を表示ã—ã¾
+ ã™
+ -p, --patch パッãƒã‚’表示ã—ã¾ã™
+
+ 別å: history
+
+manifest [revision]::
+ 指定ã•れãŸãƒªãƒ“ジョンã§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã•れã¦ã„るファイルã®ãƒªã‚¹ãƒˆ
+ を表示ã—ã¾ã™ã€‚
+
+ manifest ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã•れã¦ã„るファイルã®ãƒªã‚¹ãƒˆã§ã™ã€‚ã‚‚ã—
+ ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れãªã‘れã°ã€tip ãŒä½¿ã‚れã¾ã™ã€‚
+
+outgoing [-p] [dest]::
+ 指定ã•れãŸè¡Œãå…ˆã®ãƒªãƒã‚¸ãƒˆãƒªã‹ãƒ‡ãƒ•ォルト㧠push ã™ã‚‹ãƒªãƒã‚¸ãƒˆãƒª
+ 中ã«è¦‹ä»˜ã‹ã‚‰ãªã‹ã£ãŸãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’表示ã—ã¾ã™ã€‚ã“れら㯠push
+ ãŒè¦æ±‚ã•れãŸã¨ãã« push ã•れるã§ã‚ã‚ã†ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã§ã™ã€‚
+
+ オプション:
+ -p, --patch パッãƒã‚’表示ã—ã¾ã™
+
+ 別å: out
+
+parents::
+ 作業ディレクトリã®è¦ªãƒªãƒ“ジョンを表示ã—ã¾ã™ã€‚
+
+paths [NAME]::
+ シンボルã®ãƒ‘スåã§ã‚ã‚‹ NAME ã®è¡Œã先を表示ã—ã¾ã™ã€‚ã‚‚ã—シンボル
+ åãŒæŒ‡å®šã•れãªã‘れã°ã€åˆ©ç”¨å¯èƒ½ãªã‚·ãƒ³ãƒœãƒ«åã®è¡Œã先を表示ã—ã¾ã™ã€‚
+
+ パスå㯠/etc/mercurial/hgrc 㨠$HOME/.hgrc ã® [paths] セクショ
+ ンã§å®šç¾©ã•れã¾ã™ã€‚ã‚‚ã—リãƒã‚¸ãƒˆãƒªã®å†…部ã§å®Ÿè¡Œã•れãŸå ´
+ åˆã€.hg/hgrc も使用ã•れã¾ã™ã€‚
+
+pull <repository path>::
+ リモートã®ãƒªãƒã‚¸ãƒˆãƒªã®å¤‰æ›´ã‚’ローカルã®ãƒªãƒã‚¸ãƒˆãƒªã« pull ã—ã¾ã™ã€‚
+
+ ã“ã‚Œã¯æŒ‡å®šã•れãŸãƒ‘スや URL ã«ã‚るリãƒã‚¸ãƒˆãƒªã®å…¨ã¦ã®å¤‰æ›´ã‚’見ã¤
+ ã‘ã¦ã€ãれらをローカルã®ãƒªãƒã‚¸ãƒˆãƒªã«è¿½åŠ ã—ã¾ã™ã€‚デフォルトã§ã¯ã€
+ ã“れã¯ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ãƒ—ロジェクトã®ã‚³ãƒ”ーを更新ã—ã¾ã›ã‚“。
+
+ 有効㪠URL ã®æ¬¡ã®å½¢å¼ã§ã™:
+
+ local/filesystem/path
+ http://[user@]host[:port][/path]
+ https://[user@]host[:port][/path]
+ ssh://[user@]host[:port][/path]
+
+ SSH ã¯è¡Œãå…ˆã®ãƒžã‚·ãƒ³ã®ã‚·ã‚§ãƒ«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¨ã€ãƒªãƒ¢ãƒ¼ãƒˆã®ãƒ‘スã«hg
+ ã®ã‚³ãƒ”ーãŒå¿…è¦ã«ãªã‚Šã¾ã™ã€‚SSH を使用ã™ã‚‹ã¨ã€ãƒ‘スã¯ãƒ‡ãƒ•ォルトã§
+ ã¯ãƒªãƒ¢ãƒ¼ãƒˆã®ãƒ¦ãƒ¼ã‚¶ã®ãƒ›ãƒ¼ãƒ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ç›¸å¯¾ãƒ‘スã«ãªã‚Šã¾ã™; ファ
+ イルシステムã®ãƒ«ãƒ¼ãƒˆã‹ã‚‰ã®ç›¸å¯¾ãƒ‘スã§ã‚ã‚‹ã“ã¨ã‚’指定ã™ã‚‹ã«ã¯ã€ãƒ‘
+ ã‚¹ã®æœ€åˆã«ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã‚’ 2ã¤ä½¿ç”¨ã—ã¦ãã ã•ã„。
+
+ オプション:
+ -u, --update pull ã®å¾Œã«ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’ tip ã«æ›´æ–°ã—ã¾ã™
+ -e, --ssh 使用ã™ã‚‹ ssh コマンドを指定ã—ã¾ã™
+ --remotecmd リモートå´ã§ä½¿ã‚れる hg コマンドを指定ã—ã¾ã™
+
+push <destination>::
+ ローカルã®ãƒªãƒã‚¸ãƒˆãƒªã®å¤‰æ›´ã‚’指定ã•れãŸè¡Œã先㫠push ã—ã¾ã™ã€‚
+
+ ã“れ㯠pull ã¨å¯¾ç§°çš„ãªæ“作ã§ã™ã€‚ã“れã¯ç¾åœ¨ã®ãƒªãƒã‚¸ãƒˆãƒªã®å¤‰æ›´ã‚’
+ ä»–ã®ãƒªãƒã‚¸ãƒˆãƒªã¸ç§»ã™ã®ã«å½¹ç«‹ã¡ã¾ã™ã€‚ã‚‚ã—行ãå…ˆãŒãƒ­ãƒ¼ã‚«ãƒ«ã§ã‚れ
+ ã°ã€ã“れã¯ãã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‹ã‚‰ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«å¯¾ã—㦠pull
+ ã™ã‚‹ã®ã¨åŒã˜ã§ã™ã€‚
+
+ デフォルトã§ã¯ã€push ã¯å®Ÿè¡Œã—ãŸçµæžœãƒªãƒ¢ãƒ¼ãƒˆã®ãƒ˜ãƒƒãƒ‰ã®æ•°ãŒå¢—ãˆ
+ ã‚‹ãªã‚‰ã°ã€å®Ÿè¡Œã‚’æ‹’å¦ã—ã¾ã™ã€‚ã“れã¯ãŸã„ã¦ã„クライアント㌠push
+ ã™ã‚‹å‰ã« sync ã¨merge を忘れã¦ã„ã‚‹ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚
+
+ 有効㪠URL ã¯æ¬¡ã®å½¢å¼ã§ã™:
+
+ local/filesystem/path
+ ssh://[user@]host[:port][/path]
+
+ SSH ã¯è¡Œãå…ˆã®ãƒžã‚·ãƒ³ã®ã‚·ã‚§ãƒ«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¨ã€ãƒªãƒ¢ãƒ¼ãƒˆã®ãƒ‘ス㫠hg
+ ã®ã‚³ãƒ”ーãŒå¿…è¦ã«ãªã‚Šã¾ã™ã€‚
+
+ オプション:
+
+ -f, --force update を強行ã—ã¾ã™
+ -e, --ssh 使用ã•れる ssh コマンドを指定ã—ã¾ã™
+ --remotecmd リモートå´ã§å®Ÿè¡Œã•れる hg コマンドを指定ã—ã¾ã™
+
+rawcommit [-p -d -u -F -m -l]::
+ 低レベルã®ã‚³ãƒŸãƒƒãƒˆã§ã€ãƒ˜ãƒ«ãƒ‘ースクリプト中ã§ä½¿ç”¨ã•れã¾ã™ã€‚
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯é€šå¸¸ã®ãƒ¦ãƒ¼ã‚¶ã«ä½¿ã‚れるã“ã¨ã¯æƒ³å®šã—ã¦ã„ã¾ã›ã‚“。ã“
+ れã¯ä¸»ã«ä»–ã® SCM ã‹ã‚‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆã™ã‚‹ã¨ãã«ä¾¿åˆ©ã§ã™ã€‚
+
+recover::
+ 中断ã•れ㟠commit ã‚„ pull ã‹ã‚‰å¾©å¸°ã—ã¾ã™ã€‚
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ä¸­æ–­ã•ã‚ŒãŸæ“作ã‹ã‚‰ãƒªãƒã‚¸ãƒˆãƒªã®çŠ¶æ…‹ã‚’ä¿®æ•´ã—よã†ã¨
+ 試ã¿ã¾ã™ã€‚ã“れ㯠Mercurial ãŒãã†ã™ã‚‹ã‚ˆã†ææ¡ˆã—ãŸã¨ãã®ã¿å¿…è¦
+ ã§ã—ょã†ã€‚
+
+remove [options] [files ...]::
+ 指定ã•れãŸãƒ•ァイルをリãƒã‚¸ãƒˆãƒªã‹ã‚‰å‰Šé™¤ã™ã‚‹ã“ã¨ã‚’予定ã—ã¾ã™ã€‚
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒ•ァイルを次ã®ã‚³ãƒŸãƒƒãƒˆæ™‚ã«å‰Šé™¤ã™ã‚‹ã“ã¨ã‚’予定ã—ã¾
+ ã™ã€‚ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒ•ァイルをç¾åœ¨ã®æžã‹ã‚‰å–り除ãã ã‘ã§ã€ãƒ—ロジェ
+ クトã®å±¥æ­´å…¨ä½“ã‹ã‚‰ã¯å‰Šé™¤ã—ã¾ã›ã‚“。もã—ファイルãŒä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆ
+ リ中ã«ã¾ã å­˜åœ¨ã—ã¦ã„れã°ã€ãれらã¯ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‹ã‚‰å‰Šé™¤ã•れ
+ ã¾ã™ã€‚
+
+ 別å: rm
+
+rename <source ...> <dest>::
+ コピー先をコピー元ã®ã‚³ãƒ”ーã®ã‚³ãƒ”ーã§ã‚ã‚‹ã¨å°ã‚’ã¤ã‘ã¾ã™; コピー
+ å…ƒã«å‰Šé™¤ã®å°ã‚’ã¤ã‘ã¾ã™ã€‚ã‚‚ã—コピー先ãŒãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã‚れã°ã€ã‚³
+ ピーã¯ãã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸­ã«ç½®ã‹ã‚Œã¾ã™ã€‚ã‚‚ã—コピー先ãŒãƒ•ァイルãª
+ らã€ã‚³ãƒ”ー元㯠1 ã¤ã®ã¿æŒ‡å®šå¯èƒ½ã§ã™ã€‚
+
+ デフォルトã§ã¯ã€ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒ•ァイルãŒãã®ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«
+ ã‚ã‚‹ã‚‚ã®ã¨ã—ã¦ãã®å†…容をコピーã—ã¾ã™ã€‚ã‚‚ã— --after ã¨ä¸€ç·’ã«å‘¼
+ ã³å‡ºã•れれã°ã€æ“作ã¯è¨˜éŒ²ã•れã¾ã™ãŒã€ã‚³ãƒ”ーã¯å®Ÿè¡Œã•れã¾ã›ã‚“。
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯æ¬¡ã®ã‚³ãƒŸãƒƒãƒˆæ™‚ã«åŠ¹æžœã‚’æŒã¡ã¾ã™ã€‚
+
+ 注æ„: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯å®Ÿé¨“çš„ã§ã™ã€‚リãƒãƒ¼ãƒ ã•れãŸãƒ•ァイルをé©åˆ‡ã«
+ 記録ã§ãã¾ã™ãŒã€ã“ã®æƒ…å ±ã¯ãƒžãƒ¼ã‚¸ã«ã‚ˆã£ã¦ã¾ã å®Œå…¨ã«ã¯ä½¿ã‚れã¾ã›
+ ã‚“ã—ã€ãƒ­ã‚°ã§å®Œå…¨ã«å ±å‘Šã•れるã“ã¨ã‚‚ã‚りã¾ã›ã‚“。
+
+ オプション:
+ -A, --after æ—¢ã«ç™ºç”Ÿã—ãŸãƒªãƒãƒ¼ãƒ ã‚’記録ã—ã¾ã™
+ -f, --force 既存ã®å¤‰æ›´ã•れãŸãƒ•ァイルã«ç„¡ç†çŸ¢ç†ã‚³ãƒ”ーã—
+ ã¾ã™
+ -p, --parents コピー先ã«ã‚³ãƒ”ー元ã®ãƒ‘スを追加ã—ã¾ã™
+
+ 別å: mv
+
+revert [names ...]::
+ 指定ã•れãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚„ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®æœªã‚³ãƒŸãƒƒãƒˆã®å¤‰æ›´ã‚’å–り消ã—ã¾
+ ã™ã€‚ã“れã¯é–¢é€£ã—ãŸãƒ•ァイルã®å†…容をコミットã•れã¦ãªã„çŠ¶æ…‹ã«æˆ»ã—
+ ã¾ã™ã€‚
+
+ ã‚‚ã—ファイルãŒå‰Šé™¤ã•れã¦ã„れã°ã€å†ä½œæˆã•れã¾ã™ã€‚ã‚‚ã—ファイルã®
+ 実行モードãŒå¤‰æ›´ã•れã¦ã„れã°ã€ãƒªã‚»ãƒƒãƒˆã•れã¾ã™ã€‚
+
+ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒæŒ‡å®šã•れãŸå ´åˆã€ãã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸­ã®ã™ã¹ã¦ã®ãƒ•ã‚¡
+ イルã¨ã‚µãƒ–ディレクトリãŒå…ƒã«æˆ»ã•れã¾ã™ã€‚
+
+ ã‚‚ã—å¼•æ•°ãŒæŒ‡å®šã•れãªã‘れã°ã€ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸­ã®å…¨ã¦ã®ãƒ•ァイ
+ ルã¨ã‚µãƒ–ディレクトリãŒå…ƒã®æˆ»ã•れã¾ã™ã€‚
+
+ オプション:
+ -r, --rev <rev> å…ƒã«æˆ»ã™å…ˆã®ãƒªãƒ“ジョンを指定ã—ã¾ã™
+ -n, --nonrecursive サブディレクトリをå†å¸°çš„ã«è¾¿ã‚‰ãªã„よã†ã«
+ ã—ã¾ã™
+
+root::
+ ç¾åœ¨ã®ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’表示ã—ã¾ã™ã€‚
+
+serve [options]::
+ ローカル㮠HTTP リãƒã‚¸ãƒˆãƒªã¨ pull サーãƒã‚’èµ·å‹•ã—ã¾ã™ã€‚
+
+ デフォルトã§ã¯ã€ã‚µãƒ¼ãƒã¯ã‚¢ã‚¯ã‚»ã‚¹ãƒ­ã‚°ã‚’標準出力ã«ã€ã‚¨ãƒ©ãƒ¼ãƒ­ã‚°ã‚’
+ 標準エラー出力ã«å‡ºåŠ›ã—ã¾ã™ã€‚ファイルã«ãƒ­ã‚°ã‚’å–ã‚‹ã«ã¯ "-A" ã¨
+ "-E" オプションを使ã£ã¦ãã ã•ã„。
+
+ オプション:
+ -A, --accesslog <file> アクセスログãŒå‡ºåŠ›ã•れるファイルã®åå‰
+ を指定ã—ã¾ã™
+ -E, --errorlog <file> エラーログãŒå‡ºåŠ›ã•れるファイルã®åå‰ã‚’
+ 指定ã—ã¾ã™
+ -a, --address <addr> 使用ã™ã‚‹ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’指定ã—ã¾ã™
+ -p, --port <n> 使用ã™ã‚‹ãƒãƒ¼ãƒˆã‚’指定ã—ã¾ã™
+ (デフォルト: 8000)
+ -n, --name <name> ウェブページã§è¡¨ç¤ºã™ã‚‹åå‰ã‚’指定ã—ã¾ã™
+ (デフォルト: working dir)
+ -t, --templatedir <path> 使用ã™ã‚‹ã‚¦ã‚§ãƒ–ã®é››åž‹ã‚’指定ã—ã¾ã™
+ -6, --ipv6 IPv4 ã«åŠ ãˆã¦ IPv6 も使用ã—ã¾ã™
+
+status [options] [files]::
+ 作業ディレクトリ中ã®å¤‰æ›´ã•れãŸãƒ•ァイルを表示ã—ã¾ã™ã€‚åå‰ãŒæŒ‡å®š
+ ã•れãªã‘れã°ã€å…¨ã¦ã®ãƒ•ァイルãŒè¡¨ç¤ºã•れã¾ã™ã€‚åå‰ãŒæŒ‡å®šã•れれã°ã€
+ 指定ã•れãŸåå‰ã«ãƒžãƒƒãƒã—ãŸãƒ•ァイルã®ã¿ãŒè¡¨ç¤ºã•れã¾ã™ã€‚
+
+ ファイルã®çŠ¶æ…‹ã‚’è¡¨ç¤ºã™ã‚‹ã®ã«ä½¿ã‚れる記å·:
+
+ M = 変更ã•れã¾ã—ãŸ
+ A = 追加ã•れã¾ã—ãŸ
+ R = 削除ã•れã¾ã—ãŸ
+ ? = ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ä¸‹ã«ã‚りã¾ã›ã‚“
+
+ オプション:
+
+ -m, --modified 変更ã•れãŸãƒ•ァイルã®ã¿ã‚’表示ã—ã¾ã™
+ -a, --added 追加ã•れãŸãƒ•ァイルã®ã¿ã‚’表示ã—ã¾ã™
+ -r, --removed 削除ã•れãŸãƒ•ァイルã®ã¿ã‚’表示ã—ã¾ã™
+ -u, --unknown 䏿˜Žãª(ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ä¸‹ã«ãªã„)ファイルã®ã¿
+ を表示ã—ã¾ã™
+ -n, --no-status çŠ¶æ…‹ã‚’ç¤ºã™æŽ¥é ­è¾žã‚’éš ã—ã¾ã™
+ -0, --print0 xargs ã¨ä¸€ç·’ã«ä½¿ã†ãŸã‚ã«ã€ãƒ•ァイルåã‚’ NUL
+ ã§çµ‚ãˆã¾ã™
+ -I, --include <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’å«ã‚ã¾
+ ã™
+ -X, --exclude <pat> 与ãˆã‚‰ã‚ŒãŸãƒ‘ターンã«ãƒžãƒƒãƒã—ãŸåå‰ã‚’除外ã—
+ ã¾ã™
+
+tag [-l -m <text> -d <datecode> -u <user>] <name> [revision]::
+ 特定ã®ãƒªãƒ“ジョン㫠<name> を使ã£ã¦åå‰ã‚’付ã‘ã¾ã™ã€‚
+
+ ã‚¿ã‚°ã¯ãƒªãƒã‚¸ãƒˆãƒªã®ç‰¹å®šã®ãƒªãƒ“ジョンã«åå‰ã‚’付ã‘ã‚‹ãŸã‚ã«ä½¿ã‚れã€
+ ãã—ã¦ç•°ãªã‚‹ãƒªãƒ“ジョンを比較ã—ãŸã‚Šã€é‡è¦ãªä»¥å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«æˆ»ã£
+ ãŸã‚Šã€ãƒªãƒªãƒ¼ã‚¹ç­‰ã®åˆ†å²ç‚¹ã«å°ã‚’ã¤ã‘ãŸã‚Šã™ã‚‹ã®ã«ä¾¿åˆ©ã§ã™ã€‚
+
+ ã‚‚ã—ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れãªã‘れã°ã€tip ãŒä½¿ã‚れã¾ã™ã€‚
+
+ ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã€é…布ã€ã‚¿ã‚°ã®ãƒžãƒ¼ã‚¸ã‚’楽ã«ã™ã‚‹ãŸã‚ã«ã€ãれらã¯
+ ".hgtags" ã¨ã„ã†åå‰ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«æ ¼ç´ã•れã€ä»–ã®ãƒ—ロジェクトã®ãƒ•ã‚¡
+ イルã¨åŒæ§˜ã«æ‰±ã£ãŸã‚Šã€å¿…è¦ã§ã‚ã‚Œã°æ‰‹ã§ç·¨é›†ã§ãã¾ã™ã€‚
+
+ オプション:
+ -l, --local タグをローカルã«ã—ã¾ã™
+ -m, --message <text> タグをコミットã—ãŸã¨ãã®ãƒ­ã‚°ã®ã‚¨ãƒ³ãƒˆãƒªã®
+ メッセージを指定ã—ã¾ã™
+ -d, --date <datecode> ã‚³ãƒŸãƒƒãƒˆã®æ—¥ä»˜ã‚’指定ã—ã¾ã™
+ -u, --user <user> コミットã™ã‚‹ãƒ¦ãƒ¼ã‚¶ã‚’指定ã—ã¾ã™
+
+ 注æ„: ローカルã®ã‚¿ã‚°ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã‚„é…布ã•れるã“ã¨ã¯ãªãã€ã¾
+ ãŸ. hg/localtags ãƒ•ã‚¡ã‚¤ãƒ«ã«æ ¼ç´ã•れã¾ã™ã€‚ã‚‚ã—åŒã˜åå‰ã®ãƒ­ãƒ¼ã‚«
+ ルã®ã‚¿ã‚°ã¨å…¬é–‹ã•れãŸã‚¿ã‚°ãŒã‚れã°ã€ãƒ­ãƒ¼ã‚«ãƒ«ã®ã‚¿ã‚°ãŒä½¿ã‚れã¾ã™ã€‚
+
+tags::
+ リãƒã‚¸ãƒˆãƒªã®ã‚¿ã‚°ã‚’列挙ã—ã¾ã™ã€‚
+
+ ã“れã¯é€šå¸¸ã®ã‚¿ã‚°ã¨ãƒ­ãƒ¼ã‚«ãƒ«ã®ã‚¿ã‚°ã‚’両方列挙ã—ã¾ã™ã€‚
+
+tip::
+ tip ã®ãƒªãƒ“ジョンを表示ã—ã¾ã™ã€‚
+
+unbundle <file>::
+ (実験的)
+
+ bundle コマンドã§ç”Ÿæˆã•れãŸã€åœ§ç¸®æ¸ˆã¿ãƒã‚§ãƒ³ã‚¸ã‚°ãƒ«ãƒ¼ãƒ—ファイル
+ ã‚’é©ç”¨ã—ã¾ã™ã€‚
+
+undo::
+ 最後㮠commit ã‚„ pull ã®å‡¦ç†ã‚’å–り消ã—ã¾ã™ã€‚
+
+ リãƒã‚¸ãƒˆãƒªã®æœ€å¾Œã® pull ã‚„ commit 処ç†ã‚’巻戻ã—ã€ãƒ—ロジェクトを
+ ãれよりå‰ã®çŠ¶æ…‹ã«æˆ»ã—ã¾ã™ã€‚
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯æ³¨æ„ã—ã¦ä½¿ã£ã¦ãã ã•ã„。ã¾ã  1回㮠undo ã ã‘ã§ã€
+ redo ã¯ã‚りã¾ã›ã‚“。
+
+ ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯å…¬é–‹ã—ãŸãƒªãƒã‚¸ãƒˆãƒªã§ä½¿ã‚れるã“ã¨ã¯æƒ³å®šã—ã¦ã„ã¾ã›
+ ん。ã„ã£ãŸã‚“ä»–ã®ãƒ¦ãƒ¼ã‚¶ã‹ã‚‰ pull ã§å¤‰æ›´ãŒè¦‹ãˆã‚‹ã‚ˆã†ã«ãªã‚Œã°ã€ãƒ­ãƒ¼
+ カルã§ãれをå–り消ã—ã¦ã‚‚æ„味ãŒã‚りã¾ã›ã‚“。
+
+update [-m -C] [revision]::
+ 作業ディレクトリを指定ã•れãŸãƒªãƒ“ã‚¸ãƒ§ãƒ³ã«æ›´æ–°ã—ã¾ã™ã€‚
+
+ デフォルトã§ã¯ã€æ›´æ–°ã«ã‚ˆã‚Šãƒ­ãƒ¼ã‚«ãƒ«ã®å¤‰æ›´ã‚’マージã—ãŸã‚Šç ´æ£„ã—ãŸ
+ りã™ã‚‹ã“ã¨ãŒå¿…è¦ã¨ãªã‚‹ã¨ãã€update ã¯ãれを拒å¦ã—ã¾ã™ã€‚
+
+ -m オプションã§ã€ãƒžãƒ¼ã‚¸ãŒå®Ÿè¡Œã•れã¾ã™ã€‚
+
+ -C オプションã§ã€ãƒ­ãƒ¼ã‚«ãƒ«ã®å¤‰æ›´ãŒå¤±ã‚れã¾ã™ã€‚
+
+ オプション:
+ -m, --merge æžã®ãƒžãƒ¼ã‚¸ã‚’許å¯ã—ã¾ã™
+ -C, --clean ローカルã§å¤‰æ›´ã•れãŸãƒ•ァイルを上書ãã—ã¾ã™
+
+ 別å: up checkout co
+
+verify::
+ ç¾åœ¨ã®ãƒªãƒã‚¸ãƒˆãƒªã®æ•´åˆæ€§ã‚’検証ã—ã¾ã™ã€‚
+
+ ã“れã¯ãƒªãƒã‚¸ãƒˆãƒªã®æ•´åˆæ€§ã‚’å…¨é¢çš„ã«ãƒã‚§ãƒƒã‚¯ã—ã€ãƒã‚§ãƒ³ã‚¸ãƒ­ã‚°ã®å„
+ エントリã€manifest, 管ç†ä¸‹ã®ãƒ•ァイルã®ãƒãƒƒã‚·ãƒ¥ã¨ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã‚’
+ 検証ã—ã€ã¾ãŸã‚¯ãƒ­ã‚¹ãƒªãƒ³ã‚¯ã¨ã‚¤ãƒ³ãƒ‡ã‚¯ã‚¹ã®æ•´åˆæ€§ã‚‚検証ã—ã¾ã™ã€‚
+
+ファイルåã¨ãƒ‘ターン
+---------
+
+ Mercurial ã§ã¯åŒæ™‚ã«è¤‡æ•°ã®ãƒ•ァイルを識別ã™ã‚‹ã®ã«è¤‡æ•°ã®è¨˜æ³•ãŒä½¿
+ ãˆã¾ã™ã€‚
+
+ デフォルトã§ã¯ã€Mercurial ã¯ãƒ•ァイルåをシェルã®ã‚¹ã‚¿ã‚¤ãƒ«ã®æ‹¡å¼µ
+ glob パターンã¨ã—ã¦æ‰±ã„ã¾ã™ã€‚
+
+ 別ã®ãƒ‘ã‚¿ãƒ¼ãƒ³è¡¨è¨˜ã¯æ˜Žç¤ºçš„ã«æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚
+
+ パターンマッãƒãƒ³ã‚°ãªã—ã®å˜ç´”ãªãƒ‘スåを使ã†ã«ã¯ã€ãƒ‘スåã‚’
+ "path:" ã§å§‹ã‚ã¦ãã ã•ã„。ã“れらã®ãƒ‘スåã¯ã€ç¾åœ¨ã®ãƒªãƒã‚¸ãƒˆãƒªã®
+ ルートã‹ã‚‰å®Œå…¨ã«ãƒžãƒƒãƒã—ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚
+
+ æ‹¡å¼µ glob を使ã†ã«ã¯ã€åå‰ã‚’ "glob:" ã§å§‹ã‚ã¦ãã ã•ã„。glob ã¯
+ ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ã¿ã«é©ç”¨ã•れã¾ã™: "*.c" ã¨ã„ã£ãŸ glob ã¯ç¾
+ 在ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸­ã® ".c" ã§çµ‚ã‚るファイルã®ã¿ã«ãƒžãƒƒãƒã—ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã•れã¦ã„ã‚‹ glob æ–‡æ³•ã®æ‹¡å¼µã¯ãƒ‘スã®åˆ†é›¢è¨˜å·ã‚’è¶Šãˆã¦å…¨ã¦
+ ã®æ–‡å­—列ã«ãƒžãƒƒãƒã™ã‚‹ "**" ã¨ã€"a ã¾ãŸã¯ b" ã‚’æ„味ã™ã‚‹ "{a,b}"
+ ã§ã™ã€‚
+
+ Perl/Python ã®æ­£è¦è¡¨ç¾ã‚’使ã†ã«ã¯ã€åå‰ã‚’ "re:" ã§å§‹ã‚ã¦ãã ã•
+ ã„。正è¦è¡¨ç¾ã«ã‚ˆã‚‹ãƒžãƒƒãƒã¯ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆã®å›ºå®šã•れã¦ã„ã¾ã™ã€‚
+
+ å˜ç´”ãªä¾‹:
+
+ path:foo/bar リãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆã«ã‚ã‚‹ foo ã¨ã„ã†ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª
+ ã® bar ã¨ã„ã†åå‰
+ path:path:name "path:name" ã¨ã„ã†åå‰ã®ãƒ•ァイルã¾ãŸã¯ãƒ‡ã‚£ãƒ¬ã‚¯
+ トリ
+
+ Glob ã®ä¾‹:
+
+ glob:*.c ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸­ã® ".c" ã§çµ‚ã‚ã‚‹å…¨ã¦ã®åå‰
+ *.c ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸­ã® ".c" ã§çµ‚ã‚ã‚‹å…¨ã¦ã®åå‰
+ **.c ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨å…¨ã¦ã®ã‚µãƒ–ディレクトリ中ã®
+ ".c" ã§çµ‚ã‚ã‚‹å…¨ã¦ã®åå‰
+ foo/*.c ディレクトリ foo 中㮠".c" ã§çµ‚ã‚ã‚‹å…¨ã¦ã®åå‰
+ foo/**.c ディレクトリ foo ã¨ãã®å…¨ã¦ã®ã‚µãƒ–ディレクトリ中
+ ã® ".c" ã§çµ‚ã‚ã‚‹å…¨ã¦ã®åå‰
+
+ æ­£è¦è¡¨ç¾ã®ä¾‹:
+
+ re:.*\.c$ リãƒã‚¸ãƒˆãƒªå…¨ä½“ã®ä¸­ã® ".c" ã§çµ‚ã‚ã‚‹å…¨ã¦ã®åå‰
+
+
+å˜ä¸€ã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŒ‡å®šæ³•
+-----------
+
+ Mercurial ã§ã¯å€‹ã€…ã®ãƒªãƒ“ジョンを識別ã™ã‚‹ã®ã«è¤‡æ•°ã®è¨˜æ³•ãŒä½¿ãˆã¾
+ ã™ã€‚
+
+ å˜ç´”ãªæ•´æ•°ã¯ãƒªãƒ“ジョンナンãƒãƒ¼ã¨ã—ã¦æ‰±ã‚れã¾ã™ã€‚è² ã®æ•´æ•°ã¯tip
+ ã‹ã‚‰ã®ã‚ªãƒ•セットã¨ã—ã¦æ‰±ã‚れã€-1 ㌠tip を表ã—ã¾ã™ã€‚
+
+ 40 æ¡ã® 16 é€²æ•°ã®æ–‡å­—列ã¯ãƒ¦ãƒ‹ãƒ¼ã‚¯ãªãƒªãƒ“ジョン識別å­ã¨ã—ã¦æ‰±ã‚
+ れã¾ã™ã€‚
+
+ 40 æ¡ã‚ˆã‚Šå°‘ãªã„ 16 é€²æ•°ã®æ–‡å­—列ã¯ãƒ¦ãƒ‹ãƒ¼ã‚¯ãªãƒªãƒ“ジョン識別å­ã¨
+ ã—ã¦æ‰±ã‚れã€çŸ­ã„å½¢å¼ã®è­˜åˆ¥å­ã¨å‘¼ã°ã‚Œã¾ã™ã€‚短ã„å½¢å¼ã®è­˜åˆ¥å­ã¯ã
+ れãŒå®Œå…¨ãªé•·ã•ã®è­˜åˆ¥å­ã®æŽ¥é ­èªžã§ã‚ã‚‹ã¨ãã ã‘有効ã§ã™ã€‚
+
+ ä»–ã®æ–‡å­—列ã¯å…¨ã¦ã‚¿ã‚°åã¨ã—ã¦æ‰±ã‚れã¾ã™ã€‚ã‚¿ã‚°ã¯ã‚るリビジョン識
+ 別å­ã«é–¢é€£ä»˜ã‘られãŸã‚·ãƒ³ãƒœãƒ«åã§ã™ã€‚ã‚¿ã‚°å㯠":" 文字をå«ã‚“ã§
+ ã¯ã„ã‘ã¾ã›ã‚“。
+
+ リビジョンå "tip" ã¯ç‰¹åˆ¥ãªã‚¿ã‚°ã§ã€å¸¸ã«ä¸€ç•ªæœ€æ–°ã®ãƒªãƒ“ジョンを
+ 指ã—ã¾ã™ã€‚
+
+複数ã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŒ‡å®šæ³•
+-----------
+
+ Mercurial ㌠1ã¤ã‚ˆã‚Šå¤šãã®ãƒªãƒ“ジョンをå—ã‘ã„れるã¨ãã€ãれらã¯
+ åˆ¥ã€…ã«æŒ‡å®šã•れるã‹ã€é€£ç¶šã—ãŸç¯„囲ã¨ã—㦠":" 文字ã§åŒºåˆ‡ã£ã¦ä¸Žãˆ
+ られるã‹ã‚‚れã¾ã›ã‚“。
+
+ ç¯„å›²è¡¨è¨˜ã®æ§‹æ–‡ã¯ [BEGIN]:[END] ã§ BEGIN 㨠END ã¯ãƒªãƒ“ジョンã®
+ 識別å­ã§ã™ã€‚BEGIN ã‚‚ END も両方ã¨ã‚‚ä»»æ„ã§ã™ã€‚ã‚‚ã— BEGIN ãŒæŒ‡å®š
+ ã•れãªã‘れã°ã€ãƒ‡ãƒ•ォルトã§ãƒªãƒ“ジョンナンãƒãƒ¼ 0 ã«ãªã‚Šã¾ã™ã€‚ã‚‚
+ ã— END ãŒæŒ‡å®šã•れãªã‘れã°ã€ãƒ‡ãƒ•ォルト㧠tip ã«ãªã‚Šã¾ã™ã€‚従ã£ã¦
+ 範囲 ":" 㯠"å…¨ã¦ã®ãƒªãƒ“ジョン" ã‚’æ„味ã—ã¾ã™ã€‚
+
+ ã‚‚ã— BEGIN ㌠END より大ãã‘れã°ã€ãƒªãƒ“ジョンã¯é€†ã®é †åºã¨ã—ã¦æ‰±
+ ã‚れã¾ã™ã€‚
+
+ 範囲ã¯é–‰åŒºé–“ã¨ã—ã¦å‹•作ã—ã¾ã™ã€‚ã“れã¯ç¯„囲㌠3:5 㯠3,4,5 ã«ãªã‚‹
+ ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚åŒæ§˜ã«ã€ç¯„囲 4:2 㯠4,3,2 ã«ãªã‚Šã¾ã™ã€‚
+
+環境変数
+----
+
+HGEDITOR::
+ ã“れã¯ã‚³ãƒŸãƒƒãƒæ™‚ã«ä½¿ã‚れるエディタã®åå‰ã§ã™ã€‚デフォルトã§ã¯
+ EDITOR ã®å€¤ãŒä½¿ã‚れã¾ã™ã€‚
+
+ (廃止予定ã§ã™, .hgrc を使ã£ã¦ãã ã•ã„)
+
+HGMERGE::
+ merge 時ã®è¡çªã‚’解決ã™ã‚‹ã®ã«ä½¿ã‚れる実行ファイルã§ã™ã€‚プログラ
+ ムã¯3 ã¤ã®å¼•æ•°ã§å®Ÿè¡Œã•れã¾ã™: ローカルã®ãƒ•ァイルã€ãƒªãƒ¢ãƒ¼ãƒˆã®ãƒ•ã‚¡
+ イルã€1 世代å‰ã®ãƒ•ァイルã§ã™ã€‚
+
+ デフォルトã®ãƒ—ログラム㯠"hgmerge" ã§ã€ã“れ㯠Mercurial ã«ã‚ˆã£
+ ã¦æä¾›ã•れる常識的ãªè¨­å®šã®ã‚·ã‚§ãƒ«ã‚¹ã‚¯ãƒªãƒ—トã§ã™ã€‚
+
+ (廃止予定ã§ã™, .hgrc を使ã£ã¦ãã ã•ã„)
+
+HGUSER::
+ ã“れã¯ã‚³ãƒŸãƒƒãƒˆæ™‚ã®è‘—者ã¨ã—ã¦ä½¿ã‚れる文字列ã§ã™ã€‚
+
+ (廃止予定ã§ã™, .hgrc を使ã£ã¦ãã ã•ã„)
+
+EMAIL::
+ ã‚‚ã— HGUSER ãŒè¨­å®šã•れã¦ã„ãªã‘れã°ã€ã“れãŒã‚³ãƒŸãƒƒãƒˆæ™‚ã®è‘—者ã¨ã—
+ ã¦ä½¿ã‚れã¾ã™ã€‚
+
+LOGNAME::
+ ã‚‚ã— HGUSER ã‚‚ EMAIL も設定ã•れã¦ã„ãªã‘れã°ã€ã‚³ãƒŸãƒƒãƒˆæ™‚ã®è‘—者
+ ã¨ã—ã¦LOGNAME ãŒ('@hostname' を付ã‘ãŸå½¢ã§)使ã‚れã¾ã™ã€‚
+
+EDITOR::
+ ã“れ㯠hgmerge スクリプト中ã§ä½¿ã‚れるエディタã®åå‰ã§ã™ã€‚ã‚‚ã—
+ HGEDITOR ãŒè¨­å®šã•れã¦ã„ãªã‘れã°ã€ã‚³ãƒŸãƒƒãƒˆæ™‚ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã«ä½¿ã‚
+ れã¾ã™ã€‚デフォルト㯠'vi' ã§ã™ã€‚
+
+PYTHONPATH::
+ ã“れã¯ã‚¤ãƒ³ãƒãƒ¼ãƒˆã•れるモジュールを見ã¤ã‘ã‚‹ãŸã‚ã« Python ã«ã‚ˆã£
+ ã¦ä½¿ã‚れã€Mercurial ãŒã‚·ã‚¹ãƒ†ãƒ å…¨ä½“ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ãªã‘れ
+ ã°ã€é©åˆ‡ã«è¨­å®šã•れる必è¦ãŒã‚ã‚‹ã§ã—ょã†ã€‚
+
+ファイル
+----
+ .hgignore::
+ ã“ã®ãƒ•ァイルã¯(1行ã”ã¨ã«) hg ã«ã‚ˆã£ã¦ç„¡è¦–ã•れるã¹ãファイルを
+ 記述ã—ãŸæ­£è¦è¡¨ç¾ã‚’å«ã¿ã¾ã™ã€‚
+
+ .hgtags::
+ ã“ã®ãƒ•ァイルã¯ãƒªãƒã‚¸ãƒˆãƒªã®å†…容ã®ã‚¿ã‚°ä»˜ã‘ã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ä¸€è‡´
+ ã—ãŸãƒãƒƒã‚·ãƒ¥å€¤ã¨ãƒ†ã‚­ã‚¹ãƒˆã®ã‚¿ã‚°å(ãれãžã‚Œã¯ç©ºç™½ã§åŒºåˆ‡ã‚‰ã‚Œã¾ã™)ã‚’
+ å«ã¿ã¾ã™ã€‚
+
+ /etc/mercurial/hgrc, $HOME/.hgrc, .hg/hgrc::
+ ã“ã®ãƒ•ァイルã¯ãƒ‡ãƒ•ォルトã®è¨­å®šã‚’å«ã¿ã¾ã™ã€‚.hg/hgrc ã®å€¤ã¯
+ $HOME/.hgrc ã®è¨­å®šã‚’上書ãã—ã€$HOME/.hgrc ã®è¨­å®šã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«ãª
+ /etc/mercurial/hgrc ã®è¨­å®šã‚’上書ãã—ã¾ã™ã€‚ã“れらã®ãƒ•ァイルã®å†…
+ å®¹ã¨æ›¸å¼ã®è©³ç´°ã«ã¤ã„ã¦ã¯ hgrc(5) ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+
+ãƒã‚°
+--
+沢山ã‚ã‚‹ã§ã—ょã†ã‹ã‚‰ã€ã‚‚ã—ãƒã‚°ã‚’見ã¤ã‘ãŸã‚‰ãれをメーリングリスト
+(ä¸‹ã®æƒ…å ±æºã‚’å‚ç…§)ã«é€ã£ã¦ãã ã•ã„。
+
+関連項目
+----
+hgrc(5)
+
+著者
+--
+Matt Mackall <mpm@selenic.com> ã«ã‚ˆã‚Šæ›¸ã‹ã‚Œã¾ã—ãŸã€‚
+
+情報æº
+---
+http://mercurial.selenic.com/[主ãªã‚¦ã‚§ãƒ–サイト]
+
+http://www.serpentine.com/mercurial[Wiki サイト]
+
+http://selenic.com/hg[ソースコードã®ãƒªãƒã‚¸ãƒˆãƒª]
+
+http://selenic.com/mailman/listinfo/mercurial[メーリングリスト]
+
+著作権情報
+-----
+Copyright (C) 2005-2007 Matt Mackall.
+ã“ã®ã‚½ãƒ•トウェアã®è‡ªç”±ãªä½¿ç”¨ã¯ GNU 一般公有使用許諾 (GPL) ã®ã‚‚ã¨ã§
+èªã‚られã¾ã™ã€‚
diff --git a/sys/src/cmd/hg/doc/ja/hgrc.5.ja.txt b/sys/src/cmd/hg/doc/ja/hgrc.5.ja.txt
new file mode 100644
index 000000000..d775080c6
--- /dev/null
+++ b/sys/src/cmd/hg/doc/ja/hgrc.5.ja.txt
@@ -0,0 +1,204 @@
+HGRC(5)
+=======
+Bryan O'Sullivan <bos@serpentine.com>
+
+åå‰
+--
+hgrc - Mercurial ã®è¨­å®šãƒ•ァイル
+
+書å¼
+--
+
+Mercurial システムã¯ãã®æŒ¯èˆžã„ã®æ­£å¸¸ã‚’制御ã™ã‚‹ã®ã«ã€ä¸€é€£ã®è¨­å®šãƒ•ã‚¡
+イルを使用ã—ã¾ã™ã€‚
+
+ファイル
+----
+
+Mercurial 㯠3ã¤ã®ãƒ•ァイルã‹ã‚‰è¨­å®šã‚’読ã¿ã¾ã™:
+
+/etc/mercurial/hgrc::
+ ã“ã®ã‚°ãƒ­ãƒ¼ãƒãƒ«ã®è¨­å®šãƒ•ァイルã®ã‚ªãƒ—ションã¯å®Ÿè¡Œã—ãŸãƒ¦ãƒ¼ã‚¶ã€ãƒ‡ã‚£
+ レクトリをå•ã‚ãšå…¨ã¦ã® Mercurial コマンドã«é©ç”¨ã•れã¾ã™ã€‚
+
+$HOME/.hgrc::
+ ユーザ毎ã®è¨­å®šã‚ªãƒ—ションã§ã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å•ã‚ãšå…¨ã¦ã®
+ Mercurial コマンドã«é©ç”¨ã•れã¾ã™ã€‚ã“ã®ãƒ•ァイルã®å€¤ã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«
+ ã®è¨­å®šã‚’上書ãã—ã¾ã™ã€‚
+
+<repo>/.hg/hgrc::
+ リãƒã‚¸ãƒˆãƒªæ¯Žã®è¨­å®šã‚ªãƒ—ションã§ã€ãã®ãƒªãƒã‚¸ãƒˆãƒªã®ã¿ã«é©ç”¨ã•れã¾
+ ã™ã€‚ã“ã®ãƒ•ァイルã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã•れãšã€ "clone" æ“作ã§è»¢é€ã•
+ れるã“ã¨ã‚‚ã‚りã¾ã›ã‚“。ã“ã®ãƒ•ァイルã®å€¤ã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«ã®è¨­å®šã¨ãƒ¦ãƒ¼
+ ザ毎ã®è¨­å®šã‚’上書ãã—ã¾ã™ã€‚
+
+æ§‹æ–‡
+--
+
+設定ファイル㯠"[セクション]" ヘッダã‹ã‚‰å§‹ã¾ã‚‹ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã¨ã€ãれã«
+ç¶šã"åå‰: 値"ã®ã‚¨ãƒ³ãƒˆãƒªã‹ã‚‰æˆã‚Šã¾ã™: "åå‰=値"ã‚‚èªã‚られã¾ã™ã€‚
+
+ [spam]
+ eggs=ham
+ green=
+ eggs
+
+å„行ã¯1ã¤ã®ã‚¨ãƒ³ãƒˆãƒªã‚’å«ã¿ã¾ã™ã€‚ã‚‚ã—æ¬¡ã®è¡ŒãŒã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•れã¦ã„ãŸå ´
+åˆã€ãれã¯å‰ã®è¡Œã®ç¶šãã¨ã—ã¦æ‰±ã‚れã¾ã™ã€‚
+
+先行ã™ã‚‹ç©ºç™½ã¯å€¤ã‹ã‚‰å–り除ã‹ã‚Œã¾ã™ã€‚空行ã¯èª­ã¿é£›ã°ã•れã¾ã™ã€‚
+
+オプションã®å€¤ã¯åŒã˜ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚„ã€ç‰¹åˆ¥ãª DEFAULT セクションã®åˆ¥ã®
+値をå‚ç…§ã™ã‚‹ãƒ•ォーマット文字列をå«ã‚€ã“ã¨ãŒã§ãã¾ã™ã€‚
+
+"#" ã‚„ ";" ã§å§‹ã¾ã‚‹è¡Œã¯ç„¡è¦–ã•れるã®ã§ã€ã‚³ãƒ¡ãƒ³ãƒˆã¨ã—ã¦ä½¿ã†ã“ã¨ãŒã§
+ãã¾ã™ã€‚
+
+セクション
+-----
+
+ã“ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã¯ Merucurial ã® "hgrc" ã«ä½¿ã†ã“ã¨ãŒã§ãã‚‹ç•°ãªã£ãŸã‚»
+クションã®ãれãžã‚Œã®ç›®çš„ã‚„å¯èƒ½ãªã‚­ãƒ¼ã€ãã—ã¦å–り得る値ã«ã¤ã„ã¦è¨˜è¿°
+ã—ã¾ã™ã€‚
+
+decode/encode::
+ checkout/checkin ã§ãƒ•ァイルを転é€ã™ã‚‹ã¨ãã®ãƒ•ィルターã§ã™ã€‚ã“れ
+ ã¯å…¸åž‹çš„ã«ã¯æ”¹è¡Œã‚’処ç†ã—ãŸã‚Šã€ä»–ã®åœ°åŸŸåŒ–/標準化ã«ä½¿ã‚れるã§ã—ょ
+ ã†ã€‚
+
+ フィルターã¯ãƒ•ィルターパターンã¨ãれã«ç¶šãフィルターコマンドã‹ã‚‰
+ ãªã‚Šã¾ã™ã€‚ã‚³ãƒžãƒ³ãƒ‰ã¯æ¨™æº–入力ã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿ã‚’å—ã‘付ã‘ã€å¤‰æ›ã—ãŸãƒ‡ãƒ¼
+ タを標準出力ã«è¿”ã™å¿…è¦ãŒã‚りã¾ã™ã€‚
+
+ 例:
+
+ [encode]
+ # delta 圧縮を改善ã™ã‚‹ãŸã‚ã«ãƒã‚§ãƒƒã‚¯ã‚¤ãƒ³æ™‚ã« gzip ファイルを
+ # 伸長ã—ã¾ã™
+ # 注æ„: å¿…ãšã—も良ã„アイディアã§ã¯ã‚りã¾ã›ã‚“。ãŸã ã®ä¾‹ã§ã™
+ *.gz = gunzip
+
+ [decode]
+ # ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ›¸ã出ã™ã¨ãã«ãƒ•ァイルを gzip ã§å†åœ§ç¸®ã—ã¾ã™
+ *.gz = gzip
+
+hooks::
+ コミットã®é–‹å§‹ã€çµ‚了時ãªã©æ§˜ã€…ãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã§è‡ªå‹•çš„ã«å®Ÿè¡Œã•れるコ
+ マンドã§ã™ã€‚
+ changegroup;;
+ push ã‚„ pull ã§ãƒã‚§ãƒ³ã‚¸ã‚°ãƒ«ãƒ¼ãƒ—ãŒåŠ ãˆã‚‰ã‚ŒãŸã‚ã¨ã«èµ·å‹•ã—ã¾ã™ã€‚
+ commit;;
+ ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆãŒä½œæˆã•れãŸå¾Œã«èµ·å‹•ã—ã¾ã™ã€‚æ–°ã—ã作æˆã•れãŸãƒã‚§
+ ンジセット㮠ID ãŒæ¸¡ã•れã¾ã™ã€‚
+ precommit;;
+ コミットå‰ã«èµ·å‹•ã—ã¾ã™ã€‚終了ステータス 0 ã«ã‚ˆã‚Šã‚³ãƒŸãƒƒãƒˆã‚’続行
+ ã—ã¾ã™ã€‚éžã‚¼ãƒ­ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã§ã‚³ãƒŸãƒƒãƒˆã¯å¤±æ•—ã—ã¾ã™ã€‚
+
+http_proxy::
+ HTTP プロキシを通ã—ã¦ã‚¦ã‚§ãƒ–を使ã£ãŸ Mercurial ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã‚¢ã‚¯
+ セスã™ã‚‹ã®ã«ä½¿ã‚れã¾ã™ã€‚
+ host;;
+ プロキシサーãƒã®ãƒ›ã‚¹ãƒˆåã¨(オプションã®)ãƒãƒ¼ãƒˆã§ã€ä¾‹ãˆã°
+ "myproxy:8000"ãªã©ã§ã™ã€‚
+ no;;
+ オプションã§ã™ã€‚コンマã§åŒºåˆ‡ã‚‰ã‚ŒãŸãƒ—ロキシを通éŽã™ã¹ãホストå
+ ã®ãƒªã‚¹ãƒˆã§ã™ã€‚
+ passwd;;
+ オプションã§ã™ã€‚プロキシサーãƒã®èªè¨¼ç”¨ã®ãƒ‘スワードã§ã™ã€‚
+ user;;
+ オプションã§ã™ã€‚プロキシサーãƒã®èªè¨¼ç”¨ã®ãƒ¦ãƒ¼ã‚¶åã§ã™ã€‚
+
+paths::
+ リãƒã‚¸ãƒˆãƒªã«ã‚·ãƒ³ãƒœãƒ«åを割当ã¦ã¾ã™ã€‚å·¦å´ãŒã‚·ãƒ³ãƒœãƒ«åã§ã€å³å´ãŒãƒª
+ ãƒã‚¸ãƒˆãƒªã®å ´æ‰€ã‚’示ã™ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚„ URL ã§ã™ã€‚
+
+ui::
+ ユーザインターフェースã®è¨­å®šã§ã™ã€‚
+ debug;;
+ デãƒãƒƒã‚°æƒ…報を表示ã—ã¾ã™ã€‚True ã‹ False ã‚’å–りã¾ã™ã€‚デフォルト
+ ã§ã¯ False ã§ã™ã€‚
+ editor;;
+ コミット中ã«ä½¿ç”¨ã™ã‚‹ã‚¨ãƒ‡ã‚£ã‚¿ã§ã™ã€‚デフォルト㯠$EDITOR ã‹
+ "vi" ã§ã™ã€‚
+ interactive;;
+ ユーザã«å¯¾ã—ã¦ãƒ—ロンプトを出ã™ã‚ˆã†ã«ã—ã¾ã™ã€‚True ã‹ False ã‚’å–
+ りã¾ã™ã€‚デフォルトã§ã¯ True ã§ã™ã€‚
+ merge;;
+ 手動ã§ã® merge 中ã«è¡çªã‚’解決ã™ã‚‹ãŸã‚ã«ä½¿ã‚れるプログラムã§ã™ã€‚
+ デフォルト㯠"hgmerge" ã§ã™ã€‚
+ quiet;;
+ 表示ã•れる出力ã®é‡ã‚’減らã—ã¾ã™ã€‚True ã‹ False ã‚’å–りã¾ã™ã€‚デフォ
+ ルト㯠False ã§ã™ã€‚
+ remotecmd;;
+ clone/push/pull æ“作ã§ä½¿ã‚れるリモートã®ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚デフォル
+ ト㯠'hg' ã§ã™ã€‚
+ ssh;;
+ SSH 接続ã§ä½¿ã‚れるコマンドã§ã™ã€‚デフォルト㯠'ssh' ã§ã™ã€‚
+ username;;
+ コミットを実行ã—ãŸã¨ãã«ä½œæˆã•れるãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ã‚³ãƒŸãƒƒã‚¿ã§ã™ã€‚
+ 一般的ã«ã¯äººåã¨é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã€ä¾‹ãˆã° "Fred Widget
+ <fred@example.com>" ãªã©ã§ã™ã€‚デフォルト㯠$EMAIL ã‹
+ username@hostname ã§ã™ã€‚
+ verbose;;
+ 表示ã•れる出力ã®é‡ã‚’増やã—ã¾ã™ã€‚True ã‹ False ã‚’å–りã¾ã™ã€‚デフォ
+ ルト㯠False ã§ã™ã€‚
+
+web::
+ ウェブインターフェイスã®è¨­å®šã§ã™ã€‚
+ accesslog;;
+ アクセスログã®å‡ºåŠ›å…ˆã§ã™ã€‚デフォルトã§ã¯æ¨™æº–出力ã§ã™ã€‚
+ address;;
+ ãƒã‚¤ãƒ³ãƒ‰ã™ã‚‹ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェイスアドレスã§ã™ã€‚デフォルトã§ã¯å…¨ã¦ã§
+ ã™ã€‚
+ allowbz2;;
+ リãƒã‚¸ãƒˆãƒªã®ãƒªãƒ“ジョンã‹ã‚‰ .tar.bz2 をダウンロードã•ã›ã‚‹ã‹ã©ã†
+ ã‹ã§ã™ã€‚デフォルトã§ã¯ false ã§ã™ã€‚
+ allowgz;;
+ リãƒã‚¸ãƒˆãƒªã®ãƒªãƒ“ジョンã‹ã‚‰ .tar.gz をダウンロードã•ã›ã‚‹ã‹ã©ã†
+ ã‹ã§ã™ã€‚デフォルトã§ã¯ false ã§ã™ã€‚
+ allowpull;;
+ リãƒã‚¸ãƒˆãƒªã‹ã‚‰ pull ã•ã›ã‚‹ã‹ã©ã†ã‹ã§ã™ã€‚デフォルトã§ã¯ true ã§
+ ã™ã€‚
+ allowzip;;
+ リãƒã‚¸ãƒˆãƒªã®ãƒªãƒ“ジョンã‹ã‚‰ .zip をダウンロードã•ã›ã‚‹ã‹ã©ã†ã‹ã§
+ ã™ã€‚デフォルトã§ã¯ false ã§ã™ã€‚ã“ã®æ©Ÿèƒ½ã¯ä¸€æ™‚ファイルを作æˆã—
+ ã¾ã™ã€‚
+ description;;
+ リãƒã‚¸ãƒˆãƒªã®ç›®çš„や内容ã«ã¤ã„ã¦ã®ãƒ†ã‚­ã‚¹ãƒˆã«ã‚ˆã‚‹èª¬æ˜Žã§ã™ã€‚デフォ
+ ルトã§ã¯"unknown" ã§ã™ã€‚
+ errorlog;;
+ エラーログã®å‡ºåŠ›å…ˆã§ã™ã€‚デフォルトã§ã¯æ¨™æº–エラー出力ã§ã™ã€‚
+ ipv6;;
+ IPv6 を使ã†ã‹ã©ã†ã‹ã§ã™ã€‚デフォルトã§ã¯ false ã§ã™ã€‚
+ name;;
+ ウェブインターフェイスを使ã†ã¨ãã®ãƒªãƒã‚¸ãƒˆãƒªã®åå‰ã§ã™ã€‚デフォ
+ ルトã¯ç¾åœ¨ã®ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™ã€‚
+ maxchanges;;
+ ãƒã‚§ãƒ³ã‚¸ãƒ­ã‚°ã«è¨˜è¼‰ã™ã‚‹å¤‰æ›´ã®æœ€å¤§æ•°ã§ã™ã€‚デフォルトã§ã¯ 10 ã§ã™ã€‚
+ maxfiles;;
+ ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã«è¨˜è¼‰ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€å¤§æ•°ã§ã™ã€‚デフォルトã§ã¯
+ 10 ã§ã™ã€‚
+ port;;
+ リスンã™ã‚‹ãƒãƒ¼ãƒˆã§ã™ã€‚デフォルト 㯠8000 ã§ã™ã€‚
+ style;;
+ 使用ã™ã‚‹ãƒ†ãƒ³ãƒ—レートマップã®ã‚¹ã‚¿ã‚¤ãƒ«ã§ã™ã€‚
+ templates;;
+ HTML テンプレートã®åœ¨å‡¦ã§ã™ã€‚デフォルトã§ã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ãŸã¨
+ ãã®ãƒ‘スã§ã™ã€‚
+
+著者
+--
+Bryan O'Sullivan <bos@serpentine.com>.
+
+Mercurial 㯠Matt Mackall <mpm@selenic.com> ã«ã‚ˆã‚Šæ›¸ã‹ã‚Œã¾ã—ãŸã€‚
+
+関連項目
+----
+hg(1)
+
+COPYING
+-------
+ã“ã®ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ã®è‘—作権㯠2005 Bryan O'Sullivan ã§ã™ã€‚
+Mercurial ã®è‘—作権㯠2005 Matt Mackall ã§ã™ã€‚
+ã“ã®ã‚½ãƒ•トウェアã®è‡ªç”±ãªä½¿ç”¨ã¯ GNU 一般公有使用許諾 (GPL) ã®ã‚‚ã¨ã§
+èªã‚られã¾ã™ã€‚
diff --git a/sys/src/cmd/hg/hg b/sys/src/cmd/hg/hg
new file mode 100755
index 000000000..9e2cdb0e9
--- /dev/null
+++ b/sys/src/cmd/hg/hg
@@ -0,0 +1,31 @@
+#!/bin/python
+#
+# mercurial - scalable distributed SCM
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+# enable importing on demand to reduce startup time
+try:
+ from mercurial import demandimport; demandimport.enable()
+except ImportError:
+ import sys
+ sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" %
+ ' '.join(sys.path))
+ sys.stderr.write("(check your install and PYTHONPATH)\n")
+ sys.exit(-1)
+
+# PLAN9 hack to keep hgrc in $home/lib
+import os
+os.environ['HGRCPATH']=os.environ['home']+'/lib/hgrc'
+
+import sys
+import mercurial.util
+import mercurial.dispatch
+
+for fp in (sys.stdin, sys.stdout, sys.stderr):
+ mercurial.util.set_binary(fp)
+
+mercurial.dispatch.run()
diff --git a/sys/src/cmd/hg/hg.proto b/sys/src/cmd/hg/hg.proto
new file mode 100644
index 000000000..f4f32e625
--- /dev/null
+++ b/sys/src/cmd/hg/hg.proto
@@ -0,0 +1,14 @@
+rc - sys sys
+ bin - sys sys
+ hg - sys sys
+sys - sys sys
+ man - sys sys
+ 1 - sys sys
+ hg - sys sys
+ 8 - sys sys
+ hgignore - sys sys
+ hgrc - sys sys
+ src - sys sys
+ cmd - sys sys
+ hg - sys sys
+ + - sys sys
diff --git a/sys/src/cmd/hg/hgeditor b/sys/src/cmd/hg/hgeditor
new file mode 100755
index 000000000..8ab51b698
--- /dev/null
+++ b/sys/src/cmd/hg/hgeditor
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# This is an example of using HGEDITOR to create of diff to review the
+# changes while commiting.
+
+# If you want to pass your favourite editor some other parameters
+# only for Mercurial, modify this:
+case "${EDITOR}" in
+ "")
+ EDITOR="vi"
+ ;;
+ emacs)
+ EDITOR="$EDITOR -nw"
+ ;;
+ gvim|vim)
+ EDITOR="$EDITOR -f -o"
+ ;;
+esac
+
+
+HGTMP=""
+cleanup_exit() {
+ rm -rf "$HGTMP"
+}
+
+# Remove temporary files even if we get interrupted
+trap "cleanup_exit" 0 # normal exit
+trap "exit 255" 1 2 3 6 15 # HUP INT QUIT ABRT TERM
+
+HGTMP="${TMPDIR-/tmp}/hgeditor.$RANDOM.$RANDOM.$RANDOM.$$"
+(umask 077 && mkdir "$HGTMP") || {
+ echo "Could not create temporary directory! Exiting." 1>&2
+ exit 1
+}
+
+(
+ grep '^HG: changed' "$1" | cut -b 13- | while read changed; do
+ "$HG" diff "$changed" >> "$HGTMP/diff"
+ done
+)
+
+cat "$1" > "$HGTMP/msg"
+
+MD5=$(which md5sum 2>/dev/null) || \
+ MD5=$(which md5 2>/dev/null)
+[ -x "${MD5}" ] && CHECKSUM=`${MD5} "$HGTMP/msg"`
+if [ -s "$HGTMP/diff" ]; then
+ $EDITOR "$HGTMP/msg" "$HGTMP/diff" || exit $?
+else
+ $EDITOR "$HGTMP/msg" || exit $?
+fi
+[ -x "${MD5}" ] && (echo "$CHECKSUM" | ${MD5} -c >/dev/null 2>&1 && exit 13)
+
+mv "$HGTMP/msg" "$1"
+
+exit $?
diff --git a/sys/src/cmd/hg/hgext/__init__.py b/sys/src/cmd/hg/hgext/__init__.py
new file mode 100644
index 000000000..fdffa2a0f
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/__init__.py
@@ -0,0 +1 @@
+# placeholder
diff --git a/sys/src/cmd/hg/hgext/acl.py b/sys/src/cmd/hg/hgext/acl.py
new file mode 100644
index 000000000..f9b3927af
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/acl.py
@@ -0,0 +1,107 @@
+# acl.py - changeset access control for mercurial
+#
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+#
+
+'''hooks for controlling repository access
+
+This hook makes it possible to allow or deny write access to portions
+of a repository when receiving incoming changesets.
+
+The authorization is matched based on the local user name on the
+system where the hook runs, and not the committer of the original
+changeset (since the latter is merely informative).
+
+The acl hook is best used along with a restricted shell like hgsh,
+preventing authenticating users from doing anything other than
+pushing or pulling. The hook is not safe to use if users have
+interactive shell access, as they can then disable the hook.
+Nor is it safe if remote users share an account, because then there
+is no way to distinguish them.
+
+To use this hook, configure the acl extension in your hgrc like this::
+
+ [extensions]
+ hgext.acl =
+
+ [hooks]
+ pretxnchangegroup.acl = python:hgext.acl.hook
+
+ [acl]
+ # Check whether the source of incoming changes is in this list
+ # ("serve" == ssh or http, "push", "pull", "bundle")
+ sources = serve
+
+The allow and deny sections take a subtree pattern as key (with a glob
+syntax by default), and a comma separated list of users as the
+corresponding value. The deny list is checked before the allow list
+is. ::
+
+ [acl.allow]
+ # If acl.allow is not present, all users are allowed by default.
+ # An empty acl.allow section means no users allowed.
+ docs/** = doc_writer
+ .hgtags = release_engineer
+
+ [acl.deny]
+ # If acl.deny is not present, no users are refused by default.
+ # An empty acl.deny section means all users allowed.
+ glob pattern = user4, user5
+ ** = user6
+'''
+
+from mercurial.i18n import _
+from mercurial import util, match
+import getpass, urllib
+
+def buildmatch(ui, repo, user, key):
+ '''return tuple of (match function, list enabled).'''
+ if not ui.has_section(key):
+ ui.debug(_('acl: %s not enabled\n') % key)
+ return None
+
+ pats = [pat for pat, users in ui.configitems(key)
+ if user in users.replace(',', ' ').split()]
+ ui.debug(_('acl: %s enabled, %d entries for user %s\n') %
+ (key, len(pats), user))
+ if pats:
+ return match.match(repo.root, '', pats)
+ return match.exact(repo.root, '', [])
+
+
+def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
+ if hooktype != 'pretxnchangegroup':
+ raise util.Abort(_('config error - hook type "%s" cannot stop '
+ 'incoming changesets') % hooktype)
+ if source not in ui.config('acl', 'sources', 'serve').split():
+ ui.debug(_('acl: changes have source "%s" - skipping\n') % source)
+ return
+
+ user = None
+ if source == 'serve' and 'url' in kwargs:
+ url = kwargs['url'].split(':')
+ if url[0] == 'remote' and url[1].startswith('http'):
+ user = urllib.unquote(url[3])
+
+ if user is None:
+ user = getpass.getuser()
+
+ cfg = ui.config('acl', 'config')
+ if cfg:
+ ui.readconfig(cfg, sections = ['acl.allow', 'acl.deny'])
+ allow = buildmatch(ui, repo, user, 'acl.allow')
+ deny = buildmatch(ui, repo, user, 'acl.deny')
+
+ for rev in xrange(repo[node], len(repo)):
+ ctx = repo[rev]
+ for f in ctx.files():
+ if deny and deny(f):
+ ui.debug(_('acl: user %s denied on %s\n') % (user, f))
+ raise util.Abort(_('acl: access denied for changeset %s') % ctx)
+ if allow and not allow(f):
+ ui.debug(_('acl: user %s not allowed on %s\n') % (user, f))
+ raise util.Abort(_('acl: access denied for changeset %s') % ctx)
+ ui.debug(_('acl: allowing changeset %s\n') % ctx)
diff --git a/sys/src/cmd/hg/hgext/bookmarks.py b/sys/src/cmd/hg/hgext/bookmarks.py
new file mode 100644
index 000000000..58aaec4fa
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/bookmarks.py
@@ -0,0 +1,340 @@
+# Mercurial extension to provide the 'hg bookmark' command
+#
+# Copyright 2008 David Soria Parra <dsp@php.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''track a line of development with movable markers
+
+Bookmarks are local movable markers to changesets. Every bookmark
+points to a changeset identified by its hash. If you commit a
+changeset that is based on a changeset that has a bookmark on it, the
+bookmark shifts to the new changeset.
+
+It is possible to use bookmark names in every revision lookup (e.g. hg
+merge, hg update).
+
+By default, when several bookmarks point to the same changeset, they
+will all move forward together. It is possible to obtain a more
+git-like experience by adding the following configuration option to
+your .hgrc::
+
+ [bookmarks]
+ track.current = True
+
+This will cause Mercurial to track the bookmark that you are currently
+using, and only update it. This is similar to git's approach to
+branching.
+'''
+
+from mercurial.i18n import _
+from mercurial.node import nullid, nullrev, hex, short
+from mercurial import util, commands, localrepo, repair, extensions
+import os
+
+def parse(repo):
+ '''Parse .hg/bookmarks file and return a dictionary
+
+ Bookmarks are stored as {HASH}\\s{NAME}\\n (localtags format) values
+ in the .hg/bookmarks file. They are read by the parse() method and
+ returned as a dictionary with name => hash values.
+
+ The parsed dictionary is cached until a write() operation is done.
+ '''
+ try:
+ if repo._bookmarks:
+ return repo._bookmarks
+ repo._bookmarks = {}
+ for line in repo.opener('bookmarks'):
+ sha, refspec = line.strip().split(' ', 1)
+ repo._bookmarks[refspec] = repo.lookup(sha)
+ except:
+ pass
+ return repo._bookmarks
+
+def write(repo, refs):
+ '''Write bookmarks
+
+ Write the given bookmark => hash dictionary to the .hg/bookmarks file
+ in a format equal to those of localtags.
+
+ We also store a backup of the previous state in undo.bookmarks that
+ can be copied back on rollback.
+ '''
+ if os.path.exists(repo.join('bookmarks')):
+ util.copyfile(repo.join('bookmarks'), repo.join('undo.bookmarks'))
+ if current(repo) not in refs:
+ setcurrent(repo, None)
+ wlock = repo.wlock()
+ try:
+ file = repo.opener('bookmarks', 'w', atomictemp=True)
+ for refspec, node in refs.iteritems():
+ file.write("%s %s\n" % (hex(node), refspec))
+ file.rename()
+ finally:
+ wlock.release()
+
+def current(repo):
+ '''Get the current bookmark
+
+ If we use gittishsh branches we have a current bookmark that
+ we are on. This function returns the name of the bookmark. It
+ is stored in .hg/bookmarks.current
+ '''
+ if repo._bookmarkcurrent:
+ return repo._bookmarkcurrent
+ mark = None
+ if os.path.exists(repo.join('bookmarks.current')):
+ file = repo.opener('bookmarks.current')
+ # No readline() in posixfile_nt, reading everything is cheap
+ mark = (file.readlines() or [''])[0]
+ if mark == '':
+ mark = None
+ file.close()
+ repo._bookmarkcurrent = mark
+ return mark
+
+def setcurrent(repo, mark):
+ '''Set the name of the bookmark that we are currently on
+
+ Set the name of the bookmark that we are on (hg update <bookmark>).
+ The name is recorded in .hg/bookmarks.current
+ '''
+ if current(repo) == mark:
+ return
+
+ refs = parse(repo)
+
+ # do not update if we do update to a rev equal to the current bookmark
+ if (mark and mark not in refs and
+ current(repo) and refs[current(repo)] == repo.changectx('.').node()):
+ return
+ if mark not in refs:
+ mark = ''
+ wlock = repo.wlock()
+ try:
+ file = repo.opener('bookmarks.current', 'w', atomictemp=True)
+ file.write(mark)
+ file.rename()
+ finally:
+ wlock.release()
+ repo._bookmarkcurrent = mark
+
+def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None):
+ '''track a line of development with movable markers
+
+ Bookmarks are pointers to certain commits that move when
+ committing. Bookmarks are local. They can be renamed, copied and
+ deleted. It is possible to use bookmark names in 'hg merge' and
+ 'hg update' to merge and update respectively to a given bookmark.
+
+ You can use 'hg bookmark NAME' to set a bookmark on the working
+ directory's parent revision with the given name. If you specify
+ a revision using -r REV (where REV may be an existing bookmark),
+ the bookmark is assigned to that revision.
+ '''
+ hexfn = ui.debugflag and hex or short
+ marks = parse(repo)
+ cur = repo.changectx('.').node()
+
+ if rename:
+ if rename not in marks:
+ raise util.Abort(_("a bookmark of this name does not exist"))
+ if mark in marks and not force:
+ raise util.Abort(_("a bookmark of the same name already exists"))
+ if mark is None:
+ raise util.Abort(_("new bookmark name required"))
+ marks[mark] = marks[rename]
+ del marks[rename]
+ if current(repo) == rename:
+ setcurrent(repo, mark)
+ write(repo, marks)
+ return
+
+ if delete:
+ if mark is None:
+ raise util.Abort(_("bookmark name required"))
+ if mark not in marks:
+ raise util.Abort(_("a bookmark of this name does not exist"))
+ if mark == current(repo):
+ setcurrent(repo, None)
+ del marks[mark]
+ write(repo, marks)
+ return
+
+ if mark != None:
+ if "\n" in mark:
+ raise util.Abort(_("bookmark name cannot contain newlines"))
+ mark = mark.strip()
+ if mark in marks and not force:
+ raise util.Abort(_("a bookmark of the same name already exists"))
+ if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
+ and not force):
+ raise util.Abort(
+ _("a bookmark cannot have the name of an existing branch"))
+ if rev:
+ marks[mark] = repo.lookup(rev)
+ else:
+ marks[mark] = repo.changectx('.').node()
+ setcurrent(repo, mark)
+ write(repo, marks)
+ return
+
+ if mark is None:
+ if rev:
+ raise util.Abort(_("bookmark name required"))
+ if len(marks) == 0:
+ ui.status("no bookmarks set\n")
+ else:
+ for bmark, n in marks.iteritems():
+ if ui.configbool('bookmarks', 'track.current'):
+ prefix = (bmark == current(repo) and n == cur) and '*' or ' '
+ else:
+ prefix = (n == cur) and '*' or ' '
+
+ ui.write(" %s %-25s %d:%s\n" % (
+ prefix, bmark, repo.changelog.rev(n), hexfn(n)))
+ return
+
+def _revstostrip(changelog, node):
+ srev = changelog.rev(node)
+ tostrip = [srev]
+ saveheads = []
+ for r in xrange(srev, len(changelog)):
+ parents = changelog.parentrevs(r)
+ if parents[0] in tostrip or parents[1] in tostrip:
+ tostrip.append(r)
+ if parents[1] != nullrev:
+ for p in parents:
+ if p not in tostrip and p > srev:
+ saveheads.append(p)
+ return [r for r in tostrip if r not in saveheads]
+
+def strip(oldstrip, ui, repo, node, backup="all"):
+ """Strip bookmarks if revisions are stripped using
+ the mercurial.strip method. This usually happens during
+ qpush and qpop"""
+ revisions = _revstostrip(repo.changelog, node)
+ marks = parse(repo)
+ update = []
+ for mark, n in marks.iteritems():
+ if repo.changelog.rev(n) in revisions:
+ update.append(mark)
+ oldstrip(ui, repo, node, backup)
+ if len(update) > 0:
+ for m in update:
+ marks[m] = repo.changectx('.').node()
+ write(repo, marks)
+
+def reposetup(ui, repo):
+ if not isinstance(repo, localrepo.localrepository):
+ return
+
+ # init a bookmark cache as otherwise we would get a infinite reading
+ # in lookup()
+ repo._bookmarks = None
+ repo._bookmarkcurrent = None
+
+ class bookmark_repo(repo.__class__):
+ def rollback(self):
+ if os.path.exists(self.join('undo.bookmarks')):
+ util.rename(self.join('undo.bookmarks'), self.join('bookmarks'))
+ return super(bookmark_repo, self).rollback()
+
+ def lookup(self, key):
+ if self._bookmarks is None:
+ self._bookmarks = parse(self)
+ if key in self._bookmarks:
+ key = self._bookmarks[key]
+ return super(bookmark_repo, self).lookup(key)
+
+ def commitctx(self, ctx, error=False):
+ """Add a revision to the repository and
+ move the bookmark"""
+ wlock = self.wlock() # do both commit and bookmark with lock held
+ try:
+ node = super(bookmark_repo, self).commitctx(ctx, error)
+ if node is None:
+ return None
+ parents = self.changelog.parents(node)
+ if parents[1] == nullid:
+ parents = (parents[0],)
+ marks = parse(self)
+ update = False
+ if ui.configbool('bookmarks', 'track.current'):
+ mark = current(self)
+ if mark and marks[mark] in parents:
+ marks[mark] = node
+ update = True
+ else:
+ for mark, n in marks.items():
+ if n in parents:
+ marks[mark] = node
+ update = True
+ if update:
+ write(self, marks)
+ return node
+ finally:
+ wlock.release()
+
+ def addchangegroup(self, source, srctype, url, emptyok=False):
+ parents = self.dirstate.parents()
+
+ result = super(bookmark_repo, self).addchangegroup(
+ source, srctype, url, emptyok)
+ if result > 1:
+ # We have more heads than before
+ return result
+ node = self.changelog.tip()
+ marks = parse(self)
+ update = False
+ if ui.configbool('bookmarks', 'track.current'):
+ mark = current(self)
+ if mark and marks[mark] in parents:
+ marks[mark] = node
+ update = True
+ else:
+ for mark, n in marks.items():
+ if n in parents:
+ marks[mark] = node
+ update = True
+ if update:
+ write(self, marks)
+ return result
+
+ def _findtags(self):
+ """Merge bookmarks with normal tags"""
+ (tags, tagtypes) = super(bookmark_repo, self)._findtags()
+ tags.update(parse(self))
+ return (tags, tagtypes)
+
+ repo.__class__ = bookmark_repo
+
+def uisetup(ui):
+ extensions.wrapfunction(repair, "strip", strip)
+ if ui.configbool('bookmarks', 'track.current'):
+ extensions.wrapcommand(commands.table, 'update', updatecurbookmark)
+
+def updatecurbookmark(orig, ui, repo, *args, **opts):
+ '''Set the current bookmark
+
+ If the user updates to a bookmark we update the .hg/bookmarks.current
+ file.
+ '''
+ res = orig(ui, repo, *args, **opts)
+ rev = opts['rev']
+ if not rev and len(args) > 0:
+ rev = args[0]
+ setcurrent(repo, rev)
+ return res
+
+cmdtable = {
+ "bookmarks":
+ (bookmark,
+ [('f', 'force', False, _('force')),
+ ('r', 'rev', '', _('revision')),
+ ('d', 'delete', False, _('delete a given bookmark')),
+ ('m', 'rename', '', _('rename a given bookmark'))],
+ _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
+}
diff --git a/sys/src/cmd/hg/hgext/bugzilla.py b/sys/src/cmd/hg/hgext/bugzilla.py
new file mode 100644
index 000000000..774ed3385
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/bugzilla.py
@@ -0,0 +1,439 @@
+# bugzilla.py - bugzilla integration for mercurial
+#
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''hooks for integrating with the Bugzilla bug tracker
+
+This hook extension adds comments on bugs in Bugzilla when changesets
+that refer to bugs by Bugzilla ID are seen. The hook does not change
+bug status.
+
+The hook updates the Bugzilla database directly. Only Bugzilla
+installations using MySQL are supported.
+
+The hook relies on a Bugzilla script to send bug change notification
+emails. That script changes between Bugzilla versions; the
+'processmail' script used prior to 2.18 is replaced in 2.18 and
+subsequent versions by 'config/sendbugmail.pl'. Note that these will
+be run by Mercurial as the user pushing the change; you will need to
+ensure the Bugzilla install file permissions are set appropriately.
+
+The extension is configured through three different configuration
+sections. These keys are recognized in the [bugzilla] section:
+
+host
+ Hostname of the MySQL server holding the Bugzilla database.
+
+db
+ Name of the Bugzilla database in MySQL. Default 'bugs'.
+
+user
+ Username to use to access MySQL server. Default 'bugs'.
+
+password
+ Password to use to access MySQL server.
+
+timeout
+ Database connection timeout (seconds). Default 5.
+
+version
+ Bugzilla version. Specify '3.0' for Bugzilla versions 3.0 and later,
+ '2.18' for Bugzilla versions from 2.18 and '2.16' for versions prior
+ to 2.18.
+
+bzuser
+ Fallback Bugzilla user name to record comments with, if changeset
+ committer cannot be found as a Bugzilla user.
+
+bzdir
+ Bugzilla install directory. Used by default notify. Default
+ '/var/www/html/bugzilla'.
+
+notify
+ The command to run to get Bugzilla to send bug change notification
+ emails. Substitutes from a map with 3 keys, 'bzdir', 'id' (bug id)
+ and 'user' (committer bugzilla email). Default depends on version;
+ from 2.18 it is "cd %(bzdir)s && perl -T contrib/sendbugmail.pl
+ %(id)s %(user)s".
+
+regexp
+ Regular expression to match bug IDs in changeset commit message.
+ Must contain one "()" group. The default expression matches 'Bug
+ 1234', 'Bug no. 1234', 'Bug number 1234', 'Bugs 1234,5678', 'Bug
+ 1234 and 5678' and variations thereof. Matching is case insensitive.
+
+style
+ The style file to use when formatting comments.
+
+template
+ Template to use when formatting comments. Overrides style if
+ specified. In addition to the usual Mercurial keywords, the
+ extension specifies::
+
+ {bug} The Bugzilla bug ID.
+ {root} The full pathname of the Mercurial repository.
+ {webroot} Stripped pathname of the Mercurial repository.
+ {hgweb} Base URL for browsing Mercurial repositories.
+
+ Default 'changeset {node|short} in repo {root} refers '
+ 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'
+
+strip
+ The number of slashes to strip from the front of {root} to produce
+ {webroot}. Default 0.
+
+usermap
+ Path of file containing Mercurial committer ID to Bugzilla user ID
+ mappings. If specified, the file should contain one mapping per
+ line, "committer"="Bugzilla user". See also the [usermap] section.
+
+The [usermap] section is used to specify mappings of Mercurial
+committer ID to Bugzilla user ID. See also [bugzilla].usermap.
+"committer"="Bugzilla user"
+
+Finally, the [web] section supports one entry:
+
+baseurl
+ Base URL for browsing Mercurial repositories. Reference from
+ templates as {hgweb}.
+
+Activating the extension::
+
+ [extensions]
+ hgext.bugzilla =
+
+ [hooks]
+ # run bugzilla hook on every change pulled or pushed in here
+ incoming.bugzilla = python:hgext.bugzilla.hook
+
+Example configuration:
+
+This example configuration is for a collection of Mercurial
+repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2
+installation in /opt/bugzilla-3.2. ::
+
+ [bugzilla]
+ host=localhost
+ password=XYZZY
+ version=3.0
+ bzuser=unknown@domain.com
+ bzdir=/opt/bugzilla-3.2
+ template=Changeset {node|short} in {root|basename}.
+ {hgweb}/{webroot}/rev/{node|short}\\n
+ {desc}\\n
+ strip=5
+
+ [web]
+ baseurl=http://dev.domain.com/hg
+
+ [usermap]
+ user@emaildomain.com=user.name@bugzilladomain.com
+
+Commits add a comment to the Bugzilla bug record of the form::
+
+ Changeset 3b16791d6642 in repository-name.
+ http://dev.domain.com/hg/repository-name/rev/3b16791d6642
+
+ Changeset commit comment. Bug 1234.
+'''
+
+from mercurial.i18n import _
+from mercurial.node import short
+from mercurial import cmdutil, templater, util
+import re, time
+
+MySQLdb = None
+
+def buglist(ids):
+ return '(' + ','.join(map(str, ids)) + ')'
+
+class bugzilla_2_16(object):
+ '''support for bugzilla version 2.16.'''
+
+ def __init__(self, ui):
+ self.ui = ui
+ host = self.ui.config('bugzilla', 'host', 'localhost')
+ user = self.ui.config('bugzilla', 'user', 'bugs')
+ passwd = self.ui.config('bugzilla', 'password')
+ db = self.ui.config('bugzilla', 'db', 'bugs')
+ timeout = int(self.ui.config('bugzilla', 'timeout', 5))
+ usermap = self.ui.config('bugzilla', 'usermap')
+ if usermap:
+ self.ui.readconfig(usermap, sections=['usermap'])
+ self.ui.note(_('connecting to %s:%s as %s, password %s\n') %
+ (host, db, user, '*' * len(passwd)))
+ self.conn = MySQLdb.connect(host=host, user=user, passwd=passwd,
+ db=db, connect_timeout=timeout)
+ self.cursor = self.conn.cursor()
+ self.longdesc_id = self.get_longdesc_id()
+ self.user_ids = {}
+ self.default_notify = "cd %(bzdir)s && ./processmail %(id)s %(user)s"
+
+ def run(self, *args, **kwargs):
+ '''run a query.'''
+ self.ui.note(_('query: %s %s\n') % (args, kwargs))
+ try:
+ self.cursor.execute(*args, **kwargs)
+ except MySQLdb.MySQLError:
+ self.ui.note(_('failed query: %s %s\n') % (args, kwargs))
+ raise
+
+ def get_longdesc_id(self):
+ '''get identity of longdesc field'''
+ self.run('select fieldid from fielddefs where name = "longdesc"')
+ ids = self.cursor.fetchall()
+ if len(ids) != 1:
+ raise util.Abort(_('unknown database schema'))
+ return ids[0][0]
+
+ def filter_real_bug_ids(self, ids):
+ '''filter not-existing bug ids from list.'''
+ self.run('select bug_id from bugs where bug_id in %s' % buglist(ids))
+ return sorted([c[0] for c in self.cursor.fetchall()])
+
+ def filter_unknown_bug_ids(self, node, ids):
+ '''filter bug ids from list that already refer to this changeset.'''
+
+ self.run('''select bug_id from longdescs where
+ bug_id in %s and thetext like "%%%s%%"''' %
+ (buglist(ids), short(node)))
+ unknown = set(ids)
+ for (id,) in self.cursor.fetchall():
+ self.ui.status(_('bug %d already knows about changeset %s\n') %
+ (id, short(node)))
+ unknown.discard(id)
+ return sorted(unknown)
+
+ def notify(self, ids, committer):
+ '''tell bugzilla to send mail.'''
+
+ self.ui.status(_('telling bugzilla to send mail:\n'))
+ (user, userid) = self.get_bugzilla_user(committer)
+ for id in ids:
+ self.ui.status(_(' bug %s\n') % id)
+ cmdfmt = self.ui.config('bugzilla', 'notify', self.default_notify)
+ bzdir = self.ui.config('bugzilla', 'bzdir', '/var/www/html/bugzilla')
+ try:
+ # Backwards-compatible with old notify string, which
+ # took one string. This will throw with a new format
+ # string.
+ cmd = cmdfmt % id
+ except TypeError:
+ cmd = cmdfmt % {'bzdir': bzdir, 'id': id, 'user': user}
+ self.ui.note(_('running notify command %s\n') % cmd)
+ fp = util.popen('(%s) 2>&1' % cmd)
+ out = fp.read()
+ ret = fp.close()
+ if ret:
+ self.ui.warn(out)
+ raise util.Abort(_('bugzilla notify command %s') %
+ util.explain_exit(ret)[0])
+ self.ui.status(_('done\n'))
+
+ def get_user_id(self, user):
+ '''look up numeric bugzilla user id.'''
+ try:
+ return self.user_ids[user]
+ except KeyError:
+ try:
+ userid = int(user)
+ except ValueError:
+ self.ui.note(_('looking up user %s\n') % user)
+ self.run('''select userid from profiles
+ where login_name like %s''', user)
+ all = self.cursor.fetchall()
+ if len(all) != 1:
+ raise KeyError(user)
+ userid = int(all[0][0])
+ self.user_ids[user] = userid
+ return userid
+
+ def map_committer(self, user):
+ '''map name of committer to bugzilla user name.'''
+ for committer, bzuser in self.ui.configitems('usermap'):
+ if committer.lower() == user.lower():
+ return bzuser
+ return user
+
+ def get_bugzilla_user(self, committer):
+ '''see if committer is a registered bugzilla user. Return
+ bugzilla username and userid if so. If not, return default
+ bugzilla username and userid.'''
+ user = self.map_committer(committer)
+ try:
+ userid = self.get_user_id(user)
+ except KeyError:
+ try:
+ defaultuser = self.ui.config('bugzilla', 'bzuser')
+ if not defaultuser:
+ raise util.Abort(_('cannot find bugzilla user id for %s') %
+ user)
+ userid = self.get_user_id(defaultuser)
+ user = defaultuser
+ except KeyError:
+ raise util.Abort(_('cannot find bugzilla user id for %s or %s') %
+ (user, defaultuser))
+ return (user, userid)
+
+ def add_comment(self, bugid, text, committer):
+ '''add comment to bug. try adding comment as committer of
+ changeset, otherwise as default bugzilla user.'''
+ (user, userid) = self.get_bugzilla_user(committer)
+ now = time.strftime('%Y-%m-%d %H:%M:%S')
+ self.run('''insert into longdescs
+ (bug_id, who, bug_when, thetext)
+ values (%s, %s, %s, %s)''',
+ (bugid, userid, now, text))
+ self.run('''insert into bugs_activity (bug_id, who, bug_when, fieldid)
+ values (%s, %s, %s, %s)''',
+ (bugid, userid, now, self.longdesc_id))
+ self.conn.commit()
+
+class bugzilla_2_18(bugzilla_2_16):
+ '''support for bugzilla 2.18 series.'''
+
+ def __init__(self, ui):
+ bugzilla_2_16.__init__(self, ui)
+ self.default_notify = "cd %(bzdir)s && perl -T contrib/sendbugmail.pl %(id)s %(user)s"
+
+class bugzilla_3_0(bugzilla_2_18):
+ '''support for bugzilla 3.0 series.'''
+
+ def __init__(self, ui):
+ bugzilla_2_18.__init__(self, ui)
+
+ def get_longdesc_id(self):
+ '''get identity of longdesc field'''
+ self.run('select id from fielddefs where name = "longdesc"')
+ ids = self.cursor.fetchall()
+ if len(ids) != 1:
+ raise util.Abort(_('unknown database schema'))
+ return ids[0][0]
+
+class bugzilla(object):
+ # supported versions of bugzilla. different versions have
+ # different schemas.
+ _versions = {
+ '2.16': bugzilla_2_16,
+ '2.18': bugzilla_2_18,
+ '3.0': bugzilla_3_0
+ }
+
+ _default_bug_re = (r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*'
+ r'((?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)')
+
+ _bz = None
+
+ def __init__(self, ui, repo):
+ self.ui = ui
+ self.repo = repo
+
+ def bz(self):
+ '''return object that knows how to talk to bugzilla version in
+ use.'''
+
+ if bugzilla._bz is None:
+ bzversion = self.ui.config('bugzilla', 'version')
+ try:
+ bzclass = bugzilla._versions[bzversion]
+ except KeyError:
+ raise util.Abort(_('bugzilla version %s not supported') %
+ bzversion)
+ bugzilla._bz = bzclass(self.ui)
+ return bugzilla._bz
+
+ def __getattr__(self, key):
+ return getattr(self.bz(), key)
+
+ _bug_re = None
+ _split_re = None
+
+ def find_bug_ids(self, ctx):
+ '''find valid bug ids that are referred to in changeset
+ comments and that do not already have references to this
+ changeset.'''
+
+ if bugzilla._bug_re is None:
+ bugzilla._bug_re = re.compile(
+ self.ui.config('bugzilla', 'regexp', bugzilla._default_bug_re),
+ re.IGNORECASE)
+ bugzilla._split_re = re.compile(r'\D+')
+ start = 0
+ ids = set()
+ while True:
+ m = bugzilla._bug_re.search(ctx.description(), start)
+ if not m:
+ break
+ start = m.end()
+ for id in bugzilla._split_re.split(m.group(1)):
+ if not id: continue
+ ids.add(int(id))
+ if ids:
+ ids = self.filter_real_bug_ids(ids)
+ if ids:
+ ids = self.filter_unknown_bug_ids(ctx.node(), ids)
+ return ids
+
+ def update(self, bugid, ctx):
+ '''update bugzilla bug with reference to changeset.'''
+
+ def webroot(root):
+ '''strip leading prefix of repo root and turn into
+ url-safe path.'''
+ count = int(self.ui.config('bugzilla', 'strip', 0))
+ root = util.pconvert(root)
+ while count > 0:
+ c = root.find('/')
+ if c == -1:
+ break
+ root = root[c+1:]
+ count -= 1
+ return root
+
+ mapfile = self.ui.config('bugzilla', 'style')
+ tmpl = self.ui.config('bugzilla', 'template')
+ t = cmdutil.changeset_templater(self.ui, self.repo,
+ False, None, mapfile, False)
+ if not mapfile and not tmpl:
+ tmpl = _('changeset {node|short} in repo {root} refers '
+ 'to bug {bug}.\ndetails:\n\t{desc|tabindent}')
+ if tmpl:
+ tmpl = templater.parsestring(tmpl, quoted=False)
+ t.use_template(tmpl)
+ self.ui.pushbuffer()
+ t.show(ctx, changes=ctx.changeset(),
+ bug=str(bugid),
+ hgweb=self.ui.config('web', 'baseurl'),
+ root=self.repo.root,
+ webroot=webroot(self.repo.root))
+ data = self.ui.popbuffer()
+ self.add_comment(bugid, data, util.email(ctx.user()))
+
+def hook(ui, repo, hooktype, node=None, **kwargs):
+ '''add comment to bugzilla for each changeset that refers to a
+ bugzilla bug id. only add a comment once per bug, so same change
+ seen multiple times does not fill bug with duplicate data.'''
+ try:
+ import MySQLdb as mysql
+ global MySQLdb
+ MySQLdb = mysql
+ except ImportError, err:
+ raise util.Abort(_('python mysql support not available: %s') % err)
+
+ if node is None:
+ raise util.Abort(_('hook type %s does not pass a changeset id') %
+ hooktype)
+ try:
+ bz = bugzilla(ui, repo)
+ ctx = repo[node]
+ ids = bz.find_bug_ids(ctx)
+ if ids:
+ for id in ids:
+ bz.update(id, ctx)
+ bz.notify(ids, util.email(ctx.user()))
+ except MySQLdb.MySQLError, err:
+ raise util.Abort(_('database error: %s') % err[1])
+
diff --git a/sys/src/cmd/hg/hgext/children.py b/sys/src/cmd/hg/hgext/children.py
new file mode 100644
index 000000000..35ddeca43
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/children.py
@@ -0,0 +1,44 @@
+# Mercurial extension to provide the 'hg children' command
+#
+# Copyright 2007 by Intevation GmbH <intevation@intevation.de>
+#
+# Author(s):
+# Thomas Arendsen Hein <thomas@intevation.de>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''command to display child changesets'''
+
+from mercurial import cmdutil
+from mercurial.commands import templateopts
+from mercurial.i18n import _
+
+
+def children(ui, repo, file_=None, **opts):
+ """show the children of the given or working directory revision
+
+ Print the children of the working directory's revisions. If a
+ revision is given via -r/--rev, the children of that revision will
+ be printed. If a file argument is given, revision in which the
+ file was last changed (after the working directory revision or the
+ argument to --rev if given) is printed.
+ """
+ rev = opts.get('rev')
+ if file_:
+ ctx = repo.filectx(file_, changeid=rev)
+ else:
+ ctx = repo[rev]
+
+ displayer = cmdutil.show_changeset(ui, repo, opts)
+ for cctx in ctx.children():
+ displayer.show(cctx)
+
+
+cmdtable = {
+ "children":
+ (children,
+ [('r', 'rev', '', _('show children of the specified revision')),
+ ] + templateopts,
+ _('hg children [-r REV] [FILE]')),
+}
diff --git a/sys/src/cmd/hg/hgext/churn.py b/sys/src/cmd/hg/hgext/churn.py
new file mode 100644
index 000000000..930009ab3
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/churn.py
@@ -0,0 +1,174 @@
+# churn.py - create a graph of revisions count grouped by template
+#
+# Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
+# Copyright 2008 Alexander Solovyov <piranha@piranha.org.ua>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''command to display statistics about repository history'''
+
+from mercurial.i18n import _
+from mercurial import patch, cmdutil, util, templater
+import sys, os
+import time, datetime
+
+def maketemplater(ui, repo, tmpl):
+ tmpl = templater.parsestring(tmpl, quoted=False)
+ try:
+ t = cmdutil.changeset_templater(ui, repo, False, None, None, False)
+ except SyntaxError, inst:
+ raise util.Abort(inst.args[0])
+ t.use_template(tmpl)
+ return t
+
+def changedlines(ui, repo, ctx1, ctx2, fns):
+ lines = 0
+ fmatch = cmdutil.matchfiles(repo, fns)
+ diff = ''.join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch))
+ for l in diff.split('\n'):
+ if (l.startswith("+") and not l.startswith("+++ ") or
+ l.startswith("-") and not l.startswith("--- ")):
+ lines += 1
+ return lines
+
+def countrate(ui, repo, amap, *pats, **opts):
+ """Calculate stats"""
+ if opts.get('dateformat'):
+ def getkey(ctx):
+ t, tz = ctx.date()
+ date = datetime.datetime(*time.gmtime(float(t) - tz)[:6])
+ return date.strftime(opts['dateformat'])
+ else:
+ tmpl = opts.get('template', '{author|email}')
+ tmpl = maketemplater(ui, repo, tmpl)
+ def getkey(ctx):
+ ui.pushbuffer()
+ tmpl.show(ctx)
+ return ui.popbuffer()
+
+ count = pct = 0
+ rate = {}
+ df = False
+ if opts.get('date'):
+ df = util.matchdate(opts['date'])
+
+ get = util.cachefunc(lambda r: repo[r].changeset())
+ changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
+ for st, rev, fns in changeiter:
+ if not st == 'add':
+ continue
+ if df and not df(get(rev)[2][0]): # doesn't match date format
+ continue
+
+ ctx = repo[rev]
+ key = getkey(ctx)
+ key = amap.get(key, key) # alias remap
+ if opts.get('changesets'):
+ rate[key] = rate.get(key, 0) + 1
+ else:
+ parents = ctx.parents()
+ if len(parents) > 1:
+ ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,))
+ continue
+
+ ctx1 = parents[0]
+ lines = changedlines(ui, repo, ctx1, ctx, fns)
+ rate[key] = rate.get(key, 0) + lines
+
+ if opts.get('progress'):
+ count += 1
+ newpct = int(100.0 * count / max(len(repo), 1))
+ if pct < newpct:
+ pct = newpct
+ ui.write("\r" + _("generating stats: %d%%") % pct)
+ sys.stdout.flush()
+
+ if opts.get('progress'):
+ ui.write("\r")
+ sys.stdout.flush()
+
+ return rate
+
+
+def churn(ui, repo, *pats, **opts):
+ '''histogram of changes to the repository
+
+ This command will display a histogram representing the number
+ of changed lines or revisions, grouped according to the given
+ template. The default template will group changes by author.
+ The --dateformat option may be used to group the results by
+ date instead.
+
+ Statistics are based on the number of changed lines, or
+ alternatively the number of matching revisions if the
+ --changesets option is specified.
+
+ Examples::
+
+ # display count of changed lines for every committer
+ hg churn -t '{author|email}'
+
+ # display daily activity graph
+ hg churn -f '%H' -s -c
+
+ # display activity of developers by month
+ hg churn -f '%Y-%m' -s -c
+
+ # display count of lines changed in every year
+ hg churn -f '%Y' -s
+
+ It is possible to map alternate email addresses to a main address
+ by providing a file using the following format::
+
+ <alias email> <actual email>
+
+ Such a file may be specified with the --aliases option, otherwise
+ a .hgchurn file will be looked for in the working directory root.
+ '''
+ def pad(s, l):
+ return (s + " " * l)[:l]
+
+ amap = {}
+ aliases = opts.get('aliases')
+ if not aliases and os.path.exists(repo.wjoin('.hgchurn')):
+ aliases = repo.wjoin('.hgchurn')
+ if aliases:
+ for l in open(aliases, "r"):
+ l = l.strip()
+ alias, actual = l.split()
+ amap[alias] = actual
+
+ rate = countrate(ui, repo, amap, *pats, **opts).items()
+ if not rate:
+ return
+
+ sortkey = ((not opts.get('sort')) and (lambda x: -x[1]) or None)
+ rate.sort(key=sortkey)
+
+ maxcount = float(max([v for k, v in rate]))
+ maxname = max([len(k) for k, v in rate])
+
+ ttywidth = util.termwidth()
+ ui.debug(_("assuming %i character terminal\n") % ttywidth)
+ width = ttywidth - maxname - 2 - 6 - 2 - 2
+
+ for date, count in rate:
+ print "%s %6d %s" % (pad(date, maxname), count,
+ "*" * int(count * width / maxcount))
+
+
+cmdtable = {
+ "churn":
+ (churn,
+ [('r', 'rev', [], _('count rate for the specified revision or range')),
+ ('d', 'date', '', _('count rate for revisions matching date spec')),
+ ('t', 'template', '{author|email}', _('template to group changesets')),
+ ('f', 'dateformat', '',
+ _('strftime-compatible format for grouping by date')),
+ ('c', 'changesets', False, _('count rate by number of changesets')),
+ ('s', 'sort', False, _('sort by key (default: sort by count)')),
+ ('', 'aliases', '', _('file with email aliases')),
+ ('', 'progress', None, _('show progress'))],
+ _("hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]")),
+}
diff --git a/sys/src/cmd/hg/hgext/color.py b/sys/src/cmd/hg/hgext/color.py
new file mode 100644
index 000000000..4a736db43
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/color.py
@@ -0,0 +1,286 @@
+# color.py color output for the status and qseries commands
+#
+# Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+'''colorize output from some commands
+
+This extension modifies the status command to add color to its output
+to reflect file status, the qseries command to add color to reflect
+patch status (applied, unapplied, missing), and to diff-related
+commands to highlight additions, removals, diff headers, and trailing
+whitespace.
+
+Other effects in addition to color, like bold and underlined text, are
+also available. Effects are rendered with the ECMA-48 SGR control
+function (aka ANSI escape codes). This module also provides the
+render_text function, which can be used to add effects to any text.
+
+Default effects may be overridden from the .hgrc file::
+
+ [color]
+ status.modified = blue bold underline red_background
+ status.added = green bold
+ status.removed = red bold blue_background
+ status.deleted = cyan bold underline
+ status.unknown = magenta bold underline
+ status.ignored = black bold
+
+ # 'none' turns off all effects
+ status.clean = none
+ status.copied = none
+
+ qseries.applied = blue bold underline
+ qseries.unapplied = black bold
+ qseries.missing = red bold
+
+ diff.diffline = bold
+ diff.extended = cyan bold
+ diff.file_a = red bold
+ diff.file_b = green bold
+ diff.hunk = magenta
+ diff.deleted = red
+ diff.inserted = green
+ diff.changed = white
+ diff.trailingwhitespace = bold red_background
+'''
+
+import os, sys
+import itertools
+
+from mercurial import cmdutil, commands, extensions, error
+from mercurial.i18n import _
+
+# start and stop parameters for effects
+_effect_params = {'none': 0,
+ 'black': 30,
+ 'red': 31,
+ 'green': 32,
+ 'yellow': 33,
+ 'blue': 34,
+ 'magenta': 35,
+ 'cyan': 36,
+ 'white': 37,
+ 'bold': 1,
+ 'italic': 3,
+ 'underline': 4,
+ 'inverse': 7,
+ 'black_background': 40,
+ 'red_background': 41,
+ 'green_background': 42,
+ 'yellow_background': 43,
+ 'blue_background': 44,
+ 'purple_background': 45,
+ 'cyan_background': 46,
+ 'white_background': 47}
+
+def render_effects(text, effects):
+ 'Wrap text in commands to turn on each effect.'
+ start = [str(_effect_params[e]) for e in ['none'] + effects]
+ start = '\033[' + ';'.join(start) + 'm'
+ stop = '\033[' + str(_effect_params['none']) + 'm'
+ return ''.join([start, text, stop])
+
+def colorstatus(orig, ui, repo, *pats, **opts):
+ '''run the status command with colored output'''
+
+ delimiter = opts['print0'] and '\0' or '\n'
+
+ nostatus = opts.get('no_status')
+ opts['no_status'] = False
+ # run status and capture its output
+ ui.pushbuffer()
+ retval = orig(ui, repo, *pats, **opts)
+ # filter out empty strings
+ lines_with_status = [ line for line in ui.popbuffer().split(delimiter) if line ]
+
+ if nostatus:
+ lines = [l[2:] for l in lines_with_status]
+ else:
+ lines = lines_with_status
+
+ # apply color to output and display it
+ for i in xrange(len(lines)):
+ status = _status_abbreviations[lines_with_status[i][0]]
+ effects = _status_effects[status]
+ if effects:
+ lines[i] = render_effects(lines[i], effects)
+ ui.write(lines[i] + delimiter)
+ return retval
+
+_status_abbreviations = { 'M': 'modified',
+ 'A': 'added',
+ 'R': 'removed',
+ '!': 'deleted',
+ '?': 'unknown',
+ 'I': 'ignored',
+ 'C': 'clean',
+ ' ': 'copied', }
+
+_status_effects = { 'modified': ['blue', 'bold'],
+ 'added': ['green', 'bold'],
+ 'removed': ['red', 'bold'],
+ 'deleted': ['cyan', 'bold', 'underline'],
+ 'unknown': ['magenta', 'bold', 'underline'],
+ 'ignored': ['black', 'bold'],
+ 'clean': ['none'],
+ 'copied': ['none'], }
+
+def colorqseries(orig, ui, repo, *dummy, **opts):
+ '''run the qseries command with colored output'''
+ ui.pushbuffer()
+ retval = orig(ui, repo, **opts)
+ patchlines = ui.popbuffer().splitlines()
+ patchnames = repo.mq.series
+
+ for patch, patchname in itertools.izip(patchlines, patchnames):
+ if opts['missing']:
+ effects = _patch_effects['missing']
+ # Determine if patch is applied.
+ elif [ applied for applied in repo.mq.applied
+ if patchname == applied.name ]:
+ effects = _patch_effects['applied']
+ else:
+ effects = _patch_effects['unapplied']
+
+ patch = patch.replace(patchname, render_effects(patchname, effects), 1)
+ ui.write(patch + '\n')
+ return retval
+
+_patch_effects = { 'applied': ['blue', 'bold', 'underline'],
+ 'missing': ['red', 'bold'],
+ 'unapplied': ['black', 'bold'], }
+
+def colorwrap(orig, s):
+ '''wrap ui.write for colored diff output'''
+ lines = s.split('\n')
+ for i, line in enumerate(lines):
+ stripline = line
+ if line and line[0] in '+-':
+ # highlight trailing whitespace, but only in changed lines
+ stripline = line.rstrip()
+ for prefix, style in _diff_prefixes:
+ if stripline.startswith(prefix):
+ lines[i] = render_effects(stripline, _diff_effects[style])
+ break
+ if line != stripline:
+ lines[i] += render_effects(
+ line[len(stripline):], _diff_effects['trailingwhitespace'])
+ orig('\n'.join(lines))
+
+def colorshowpatch(orig, self, node):
+ '''wrap cmdutil.changeset_printer.showpatch with colored output'''
+ oldwrite = extensions.wrapfunction(self.ui, 'write', colorwrap)
+ try:
+ orig(self, node)
+ finally:
+ self.ui.write = oldwrite
+
+def colordiff(orig, ui, repo, *pats, **opts):
+ '''run the diff command with colored output'''
+ oldwrite = extensions.wrapfunction(ui, 'write', colorwrap)
+ try:
+ orig(ui, repo, *pats, **opts)
+ finally:
+ ui.write = oldwrite
+
+_diff_prefixes = [('diff', 'diffline'),
+ ('copy', 'extended'),
+ ('rename', 'extended'),
+ ('old', 'extended'),
+ ('new', 'extended'),
+ ('deleted', 'extended'),
+ ('---', 'file_a'),
+ ('+++', 'file_b'),
+ ('@', 'hunk'),
+ ('-', 'deleted'),
+ ('+', 'inserted')]
+
+_diff_effects = {'diffline': ['bold'],
+ 'extended': ['cyan', 'bold'],
+ 'file_a': ['red', 'bold'],
+ 'file_b': ['green', 'bold'],
+ 'hunk': ['magenta'],
+ 'deleted': ['red'],
+ 'inserted': ['green'],
+ 'changed': ['white'],
+ 'trailingwhitespace': ['bold', 'red_background']}
+
+_ui = None
+
+def uisetup(ui):
+ '''Initialize the extension.'''
+ global _ui
+ _ui = ui
+ _setupcmd(ui, 'diff', commands.table, colordiff, _diff_effects)
+ _setupcmd(ui, 'incoming', commands.table, None, _diff_effects)
+ _setupcmd(ui, 'log', commands.table, None, _diff_effects)
+ _setupcmd(ui, 'outgoing', commands.table, None, _diff_effects)
+ _setupcmd(ui, 'tip', commands.table, None, _diff_effects)
+ _setupcmd(ui, 'status', commands.table, colorstatus, _status_effects)
+
+def extsetup():
+ try:
+ mq = extensions.find('mq')
+ try:
+ # If we are loaded after mq, we must wrap commands.table
+ _setupcmd(_ui, 'qdiff', commands.table, colordiff, _diff_effects)
+ _setupcmd(_ui, 'qseries', commands.table, colorqseries, _patch_effects)
+ except error.UnknownCommand:
+ # Otherwise we wrap mq.cmdtable
+ _setupcmd(_ui, 'qdiff', mq.cmdtable, colordiff, _diff_effects)
+ _setupcmd(_ui, 'qseries', mq.cmdtable, colorqseries, _patch_effects)
+ except KeyError:
+ # The mq extension is not enabled
+ pass
+
+def _setupcmd(ui, cmd, table, func, effectsmap):
+ '''patch in command to command table and load effect map'''
+ def nocolor(orig, *args, **opts):
+
+ if (opts['no_color'] or opts['color'] == 'never' or
+ (opts['color'] == 'auto' and (os.environ.get('TERM') == 'dumb'
+ or not sys.__stdout__.isatty()))):
+ return orig(*args, **opts)
+
+ oldshowpatch = extensions.wrapfunction(cmdutil.changeset_printer,
+ 'showpatch', colorshowpatch)
+ try:
+ if func is not None:
+ return func(orig, *args, **opts)
+ return orig(*args, **opts)
+ finally:
+ cmdutil.changeset_printer.showpatch = oldshowpatch
+
+ entry = extensions.wrapcommand(table, cmd, nocolor)
+ entry[1].extend([
+ ('', 'color', 'auto', _("when to colorize (always, auto, or never)")),
+ ('', 'no-color', None, _("don't colorize output")),
+ ])
+
+ for status in effectsmap:
+ configkey = cmd + '.' + status
+ effects = ui.configlist('color', configkey)
+ if effects:
+ good = []
+ for e in effects:
+ if e in _effect_params:
+ good.append(e)
+ else:
+ ui.warn(_("ignoring unknown color/effect %r "
+ "(configured in color.%s)\n")
+ % (e, configkey))
+ effectsmap[status] = good
diff --git a/sys/src/cmd/hg/hgext/convert/__init__.py b/sys/src/cmd/hg/hgext/convert/__init__.py
new file mode 100644
index 000000000..2d04dc34a
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/__init__.py
@@ -0,0 +1,296 @@
+# convert.py Foreign SCM converter
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''import revisions from foreign VCS repositories into Mercurial'''
+
+import convcmd
+import cvsps
+import subversion
+from mercurial import commands
+from mercurial.i18n import _
+
+# Commands definition was moved elsewhere to ease demandload job.
+
+def convert(ui, src, dest=None, revmapfile=None, **opts):
+ """convert a foreign SCM repository to a Mercurial one.
+
+ Accepted source formats [identifiers]:
+
+ - Mercurial [hg]
+ - CVS [cvs]
+ - Darcs [darcs]
+ - git [git]
+ - Subversion [svn]
+ - Monotone [mtn]
+ - GNU Arch [gnuarch]
+ - Bazaar [bzr]
+ - Perforce [p4]
+
+ Accepted destination formats [identifiers]:
+
+ - Mercurial [hg]
+ - Subversion [svn] (history on branches is not preserved)
+
+ If no revision is given, all revisions will be converted.
+ Otherwise, convert will only import up to the named revision
+ (given in a format understood by the source).
+
+ If no destination directory name is specified, it defaults to the
+ basename of the source with '-hg' appended. If the destination
+ repository doesn't exist, it will be created.
+
+ By default, all sources except Mercurial will use --branchsort.
+ Mercurial uses --sourcesort to preserve original revision numbers
+ order. Sort modes have the following effects:
+
+ --branchsort convert from parent to child revision when possible,
+ which means branches are usually converted one after
+ the other. It generates more compact repositories.
+
+ --datesort sort revisions by date. Converted repositories have
+ good-looking changelogs but are often an order of
+ magnitude larger than the same ones generated by
+ --branchsort.
+
+ --sourcesort try to preserve source revisions order, only
+ supported by Mercurial sources.
+
+ If <REVMAP> isn't given, it will be put in a default location
+ (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file
+ that maps each source commit ID to the destination ID for that
+ revision, like so::
+
+ <source ID> <destination ID>
+
+ If the file doesn't exist, it's automatically created. It's
+ updated on each commit copied, so convert-repo can be interrupted
+ and can be run repeatedly to copy new commits.
+
+ The [username mapping] file is a simple text file that maps each
+ source commit author to a destination commit author. It is handy
+ for source SCMs that use unix logins to identify authors (eg:
+ CVS). One line per author mapping and the line format is:
+ srcauthor=whatever string you want
+
+ The filemap is a file that allows filtering and remapping of files
+ and directories. Comment lines start with '#'. Each line can
+ contain one of the following directives::
+
+ include path/to/file
+
+ exclude path/to/file
+
+ rename from/file to/file
+
+ The 'include' directive causes a file, or all files under a
+ directory, to be included in the destination repository, and the
+ exclusion of all other files and directories not explicitly
+ included. The 'exclude' directive causes files or directories to
+ be omitted. The 'rename' directive renames a file or directory. To
+ rename from a subdirectory into the root of the repository, use
+ '.' as the path to rename to.
+
+ The splicemap is a file that allows insertion of synthetic
+ history, letting you specify the parents of a revision. This is
+ useful if you want to e.g. give a Subversion merge two parents, or
+ graft two disconnected series of history together. Each entry
+ contains a key, followed by a space, followed by one or two
+ comma-separated values. The key is the revision ID in the source
+ revision control system whose parents should be modified (same
+ format as a key in .hg/shamap). The values are the revision IDs
+ (in either the source or destination revision control system) that
+ should be used as the new parents for that node.
+
+ The branchmap is a file that allows you to rename a branch when it is
+ being brought in from whatever external repository. When used in
+ conjunction with a splicemap, it allows for a powerful combination
+ to help fix even the most badly mismanaged repositories and turn them
+ into nicely structured Mercurial repositories. The branchmap contains
+ lines of the form "original_branch_name new_branch_name".
+ "original_branch_name" is the name of the branch in the source
+ repository, and "new_branch_name" is the name of the branch is the
+ destination repository. This can be used to (for instance) move code
+ in one repository from "default" to a named branch.
+
+ Mercurial Source
+ ----------------
+
+ --config convert.hg.ignoreerrors=False (boolean)
+ ignore integrity errors when reading. Use it to fix Mercurial
+ repositories with missing revlogs, by converting from and to
+ Mercurial.
+ --config convert.hg.saverev=False (boolean)
+ store original revision ID in changeset (forces target IDs to
+ change)
+ --config convert.hg.startrev=0 (hg revision identifier)
+ convert start revision and its descendants
+
+ CVS Source
+ ----------
+
+ CVS source will use a sandbox (i.e. a checked-out copy) from CVS
+ to indicate the starting point of what will be converted. Direct
+ access to the repository files is not needed, unless of course the
+ repository is :local:. The conversion uses the top level directory
+ in the sandbox to find the CVS repository, and then uses CVS rlog
+ commands to find files to convert. This means that unless a
+ filemap is given, all files under the starting directory will be
+ converted, and that any directory reorganization in the CVS
+ sandbox is ignored.
+
+ Because CVS does not have changesets, it is necessary to collect
+ individual commits to CVS and merge them into changesets. CVS
+ source uses its internal changeset merging code by default but can
+ be configured to call the external 'cvsps' program by setting::
+
+ --config convert.cvsps='cvsps -A -u --cvs-direct -q'
+
+ This option is deprecated and will be removed in Mercurial 1.4.
+
+ The options shown are the defaults.
+
+ Internal cvsps is selected by setting ::
+
+ --config convert.cvsps=builtin
+
+ and has a few more configurable options:
+
+ --config convert.cvsps.cache=True (boolean)
+ Set to False to disable remote log caching, for testing and
+ debugging purposes.
+ --config convert.cvsps.fuzz=60 (integer)
+ Specify the maximum time (in seconds) that is allowed between
+ commits with identical user and log message in a single
+ changeset. When very large files were checked in as part of a
+ changeset then the default may not be long enough.
+ --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'
+ Specify a regular expression to which commit log messages are
+ matched. If a match occurs, then the conversion process will
+ insert a dummy revision merging the branch on which this log
+ message occurs to the branch indicated in the regex.
+ --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'
+ Specify a regular expression to which commit log messages are
+ matched. If a match occurs, then the conversion process will
+ add the most recent revision on the branch indicated in the
+ regex as the second parent of the changeset.
+
+ The hgext/convert/cvsps wrapper script allows the builtin
+ changeset merging code to be run without doing a conversion. Its
+ parameters and output are similar to that of cvsps 2.1.
+
+ Subversion Source
+ -----------------
+
+ Subversion source detects classical trunk/branches/tags layouts.
+ By default, the supplied "svn://repo/path/" source URL is
+ converted as a single branch. If "svn://repo/path/trunk" exists it
+ replaces the default branch. If "svn://repo/path/branches" exists,
+ its subdirectories are listed as possible branches. If
+ "svn://repo/path/tags" exists, it is looked for tags referencing
+ converted branches. Default "trunk", "branches" and "tags" values
+ can be overridden with following options. Set them to paths
+ relative to the source URL, or leave them blank to disable auto
+ detection.
+
+ --config convert.svn.branches=branches (directory name)
+ specify the directory containing branches
+ --config convert.svn.tags=tags (directory name)
+ specify the directory containing tags
+ --config convert.svn.trunk=trunk (directory name)
+ specify the name of the trunk branch
+
+ Source history can be retrieved starting at a specific revision,
+ instead of being integrally converted. Only single branch
+ conversions are supported.
+
+ --config convert.svn.startrev=0 (svn revision number)
+ specify start Subversion revision.
+
+ Perforce Source
+ ---------------
+
+ The Perforce (P4) importer can be given a p4 depot path or a
+ client specification as source. It will convert all files in the
+ source to a flat Mercurial repository, ignoring labels, branches
+ and integrations. Note that when a depot path is given you then
+ usually should specify a target directory, because otherwise the
+ target may be named ...-hg.
+
+ It is possible to limit the amount of source history to be
+ converted by specifying an initial Perforce revision.
+
+ --config convert.p4.startrev=0 (perforce changelist number)
+ specify initial Perforce revision.
+
+ Mercurial Destination
+ ---------------------
+
+ --config convert.hg.clonebranches=False (boolean)
+ dispatch source branches in separate clones.
+ --config convert.hg.tagsbranch=default (branch name)
+ tag revisions branch name
+ --config convert.hg.usebranchnames=True (boolean)
+ preserve branch names
+
+ """
+ return convcmd.convert(ui, src, dest, revmapfile, **opts)
+
+def debugsvnlog(ui, **opts):
+ return subversion.debugsvnlog(ui, **opts)
+
+def debugcvsps(ui, *args, **opts):
+ '''create changeset information from CVS
+
+ This command is intended as a debugging tool for the CVS to
+ Mercurial converter, and can be used as a direct replacement for
+ cvsps.
+
+ Hg debugcvsps reads the CVS rlog for current directory (or any
+ named directory) in the CVS repository, and converts the log to a
+ series of changesets based on matching commit log entries and
+ dates.'''
+ return cvsps.debugcvsps(ui, *args, **opts)
+
+commands.norepo += " convert debugsvnlog debugcvsps"
+
+cmdtable = {
+ "convert":
+ (convert,
+ [('A', 'authors', '', _('username mapping filename')),
+ ('d', 'dest-type', '', _('destination repository type')),
+ ('', 'filemap', '', _('remap file names using contents of file')),
+ ('r', 'rev', '', _('import up to target revision REV')),
+ ('s', 'source-type', '', _('source repository type')),
+ ('', 'splicemap', '', _('splice synthesized history into place')),
+ ('', 'branchmap', '', _('change branch names while converting')),
+ ('', 'branchsort', None, _('try to sort changesets by branches')),
+ ('', 'datesort', None, _('try to sort changesets by date')),
+ ('', 'sourcesort', None, _('preserve source changesets order'))],
+ _('hg convert [OPTION]... SOURCE [DEST [REVMAP]]')),
+ "debugsvnlog":
+ (debugsvnlog,
+ [],
+ 'hg debugsvnlog'),
+ "debugcvsps":
+ (debugcvsps,
+ [
+ # Main options shared with cvsps-2.1
+ ('b', 'branches', [], _('only return changes on specified branches')),
+ ('p', 'prefix', '', _('prefix to remove from file names')),
+ ('r', 'revisions', [], _('only return changes after or between specified tags')),
+ ('u', 'update-cache', None, _("update cvs log cache")),
+ ('x', 'new-cache', None, _("create new cvs log cache")),
+ ('z', 'fuzz', 60, _('set commit time fuzz in seconds')),
+ ('', 'root', '', _('specify cvsroot')),
+ # Options specific to builtin cvsps
+ ('', 'parents', '', _('show parent changesets')),
+ ('', 'ancestors', '', _('show current changeset in ancestor branches')),
+ # Options that are ignored for compatibility with cvsps-2.1
+ ('A', 'cvs-direct', None, _('ignored for compatibility')),
+ ],
+ _('hg debugcvsps [OPTION]... [PATH]...')),
+}
diff --git a/sys/src/cmd/hg/hgext/convert/bzr.py b/sys/src/cmd/hg/hgext/convert/bzr.py
new file mode 100644
index 000000000..6d2abe0bb
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/bzr.py
@@ -0,0 +1,259 @@
+# bzr.py - bzr support for the convert extension
+#
+# Copyright 2008, 2009 Marek Kubica <marek@xivilization.net> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+# This module is for handling 'bzr', that was formerly known as Bazaar-NG;
+# it cannot access 'bar' repositories, but they were never used very much
+
+import os
+from mercurial import demandimport
+# these do not work with demandimport, blacklist
+demandimport.ignore.extend([
+ 'bzrlib.transactions',
+ 'bzrlib.urlutils',
+ ])
+
+from mercurial.i18n import _
+from mercurial import util
+from common import NoRepo, commit, converter_source
+
+try:
+ # bazaar imports
+ from bzrlib import branch, revision, errors
+ from bzrlib.revisionspec import RevisionSpec
+except ImportError:
+ pass
+
+supportedkinds = ('file', 'symlink')
+
+class bzr_source(converter_source):
+ """Reads Bazaar repositories by using the Bazaar Python libraries"""
+
+ def __init__(self, ui, path, rev=None):
+ super(bzr_source, self).__init__(ui, path, rev=rev)
+
+ if not os.path.exists(os.path.join(path, '.bzr')):
+ raise NoRepo('%s does not look like a Bazaar repo' % path)
+
+ try:
+ # access bzrlib stuff
+ branch
+ except NameError:
+ raise NoRepo('Bazaar modules could not be loaded')
+
+ path = os.path.abspath(path)
+ self._checkrepotype(path)
+ self.branch = branch.Branch.open(path)
+ self.sourcerepo = self.branch.repository
+ self._parentids = {}
+
+ def _checkrepotype(self, path):
+ # Lightweight checkouts detection is informational but probably
+ # fragile at API level. It should not terminate the conversion.
+ try:
+ from bzrlib import bzrdir
+ dir = bzrdir.BzrDir.open_containing(path)[0]
+ try:
+ tree = dir.open_workingtree(recommend_upgrade=False)
+ branch = tree.branch
+ except (errors.NoWorkingTree, errors.NotLocalUrl), e:
+ tree = None
+ branch = dir.open_branch()
+ if (tree is not None and tree.bzrdir.root_transport.base !=
+ branch.bzrdir.root_transport.base):
+ self.ui.warn(_('warning: lightweight checkouts may cause '
+ 'conversion failures, try with a regular '
+ 'branch instead.\n'))
+ except:
+ self.ui.note(_('bzr source type could not be determined\n'))
+
+ def before(self):
+ """Before the conversion begins, acquire a read lock
+ for all the operations that might need it. Fortunately
+ read locks don't block other reads or writes to the
+ repository, so this shouldn't have any impact on the usage of
+ the source repository.
+
+ The alternative would be locking on every operation that
+ needs locks (there are currently two: getting the file and
+ getting the parent map) and releasing immediately after,
+ but this approach can take even 40% longer."""
+ self.sourcerepo.lock_read()
+
+ def after(self):
+ self.sourcerepo.unlock()
+
+ def getheads(self):
+ if not self.rev:
+ return [self.branch.last_revision()]
+ try:
+ r = RevisionSpec.from_string(self.rev)
+ info = r.in_history(self.branch)
+ except errors.BzrError:
+ raise util.Abort(_('%s is not a valid revision in current branch')
+ % self.rev)
+ return [info.rev_id]
+
+ def getfile(self, name, rev):
+ revtree = self.sourcerepo.revision_tree(rev)
+ fileid = revtree.path2id(name.decode(self.encoding or 'utf-8'))
+ kind = None
+ if fileid is not None:
+ kind = revtree.kind(fileid)
+ if kind not in supportedkinds:
+ # the file is not available anymore - was deleted
+ raise IOError(_('%s is not available in %s anymore') %
+ (name, rev))
+ if kind == 'symlink':
+ target = revtree.get_symlink_target(fileid)
+ if target is None:
+ raise util.Abort(_('%s.%s symlink has no target')
+ % (name, rev))
+ return target
+ else:
+ sio = revtree.get_file(fileid)
+ return sio.read()
+
+ def getmode(self, name, rev):
+ return self._modecache[(name, rev)]
+
+ def getchanges(self, version):
+ # set up caches: modecache and revtree
+ self._modecache = {}
+ self._revtree = self.sourcerepo.revision_tree(version)
+ # get the parentids from the cache
+ parentids = self._parentids.pop(version)
+ # only diff against first parent id
+ prevtree = self.sourcerepo.revision_tree(parentids[0])
+ return self._gettreechanges(self._revtree, prevtree)
+
+ def getcommit(self, version):
+ rev = self.sourcerepo.get_revision(version)
+ # populate parent id cache
+ if not rev.parent_ids:
+ parents = []
+ self._parentids[version] = (revision.NULL_REVISION,)
+ else:
+ parents = self._filterghosts(rev.parent_ids)
+ self._parentids[version] = parents
+
+ return commit(parents=parents,
+ date='%d %d' % (rev.timestamp, -rev.timezone),
+ author=self.recode(rev.committer),
+ # bzr returns bytestrings or unicode, depending on the content
+ desc=self.recode(rev.message),
+ rev=version)
+
+ def gettags(self):
+ if not self.branch.supports_tags():
+ return {}
+ tagdict = self.branch.tags.get_tag_dict()
+ bytetags = {}
+ for name, rev in tagdict.iteritems():
+ bytetags[self.recode(name)] = rev
+ return bytetags
+
+ def getchangedfiles(self, rev, i):
+ self._modecache = {}
+ curtree = self.sourcerepo.revision_tree(rev)
+ if i is not None:
+ parentid = self._parentids[rev][i]
+ else:
+ # no parent id, get the empty revision
+ parentid = revision.NULL_REVISION
+
+ prevtree = self.sourcerepo.revision_tree(parentid)
+ changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
+ return changes
+
+ def _gettreechanges(self, current, origin):
+ revid = current._revision_id;
+ changes = []
+ renames = {}
+ for (fileid, paths, changed_content, versioned, parent, name,
+ kind, executable) in current.iter_changes(origin):
+
+ if paths[0] == u'' or paths[1] == u'':
+ # ignore changes to tree root
+ continue
+
+ # bazaar tracks directories, mercurial does not, so
+ # we have to rename the directory contents
+ if kind[1] == 'directory':
+ if kind[0] not in (None, 'directory'):
+ # Replacing 'something' with a directory, record it
+ # so it can be removed.
+ changes.append((self.recode(paths[0]), revid))
+
+ if None not in paths and paths[0] != paths[1]:
+ # neither an add nor an delete - a move
+ # rename all directory contents manually
+ subdir = origin.inventory.path2id(paths[0])
+ # get all child-entries of the directory
+ for name, entry in origin.inventory.iter_entries(subdir):
+ # hg does not track directory renames
+ if entry.kind == 'directory':
+ continue
+ frompath = self.recode(paths[0] + '/' + name)
+ topath = self.recode(paths[1] + '/' + name)
+ # register the files as changed
+ changes.append((frompath, revid))
+ changes.append((topath, revid))
+ # add to mode cache
+ mode = ((entry.executable and 'x') or (entry.kind == 'symlink' and 's')
+ or '')
+ self._modecache[(topath, revid)] = mode
+ # register the change as move
+ renames[topath] = frompath
+
+ # no futher changes, go to the next change
+ continue
+
+ # we got unicode paths, need to convert them
+ path, topath = [self.recode(part) for part in paths]
+
+ if topath is None:
+ # file deleted
+ changes.append((path, revid))
+ continue
+
+ # renamed
+ if path and path != topath:
+ renames[topath] = path
+ changes.append((path, revid))
+
+ # populate the mode cache
+ kind, executable = [e[1] for e in (kind, executable)]
+ mode = ((executable and 'x') or (kind == 'symlink' and 'l')
+ or '')
+ self._modecache[(topath, revid)] = mode
+ changes.append((topath, revid))
+
+ return changes, renames
+
+ def _filterghosts(self, ids):
+ """Filters out ghost revisions which hg does not support, see
+ <http://bazaar-vcs.org/GhostRevision>
+ """
+ parentmap = self.sourcerepo.get_parent_map(ids)
+ parents = tuple([parent for parent in ids if parent in parentmap])
+ return parents
+
+ def recode(self, s, encoding=None):
+ """This version of recode tries to encode unicode to bytecode,
+ and preferably using the UTF-8 codec.
+ Other types than Unicode are silently returned, this is by
+ intention, e.g. the None-type is not going to be encoded but instead
+ just passed through
+ """
+ if not encoding:
+ encoding = self.encoding or 'utf-8'
+
+ if isinstance(s, unicode):
+ return s.encode(encoding)
+ else:
+ # leave it alone
+ return s
diff --git a/sys/src/cmd/hg/hgext/convert/common.py b/sys/src/cmd/hg/hgext/convert/common.py
new file mode 100644
index 000000000..0519d99a0
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/common.py
@@ -0,0 +1,389 @@
+# common.py - common code for the convert extension
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import base64, errno
+import os
+import cPickle as pickle
+from mercurial import util
+from mercurial.i18n import _
+
+def encodeargs(args):
+ def encodearg(s):
+ lines = base64.encodestring(s)
+ lines = [l.splitlines()[0] for l in lines]
+ return ''.join(lines)
+
+ s = pickle.dumps(args)
+ return encodearg(s)
+
+def decodeargs(s):
+ s = base64.decodestring(s)
+ return pickle.loads(s)
+
+class MissingTool(Exception): pass
+
+def checktool(exe, name=None, abort=True):
+ name = name or exe
+ if not util.find_exe(exe):
+ exc = abort and util.Abort or MissingTool
+ raise exc(_('cannot find required "%s" tool') % name)
+
+class NoRepo(Exception): pass
+
+SKIPREV = 'SKIP'
+
+class commit(object):
+ def __init__(self, author, date, desc, parents, branch=None, rev=None,
+ extra={}, sortkey=None):
+ self.author = author or 'unknown'
+ self.date = date or '0 0'
+ self.desc = desc
+ self.parents = parents
+ self.branch = branch
+ self.rev = rev
+ self.extra = extra
+ self.sortkey = sortkey
+
+class converter_source(object):
+ """Conversion source interface"""
+
+ def __init__(self, ui, path=None, rev=None):
+ """Initialize conversion source (or raise NoRepo("message")
+ exception if path is not a valid repository)"""
+ self.ui = ui
+ self.path = path
+ self.rev = rev
+
+ self.encoding = 'utf-8'
+
+ def before(self):
+ pass
+
+ def after(self):
+ pass
+
+ def setrevmap(self, revmap):
+ """set the map of already-converted revisions"""
+ pass
+
+ def getheads(self):
+ """Return a list of this repository's heads"""
+ raise NotImplementedError()
+
+ def getfile(self, name, rev):
+ """Return file contents as a string. rev is the identifier returned
+ by a previous call to getchanges(). Raise IOError to indicate that
+ name was deleted in rev.
+ """
+ raise NotImplementedError()
+
+ def getmode(self, name, rev):
+ """Return file mode, eg. '', 'x', or 'l'. rev is the identifier
+ returned by a previous call to getchanges().
+ """
+ raise NotImplementedError()
+
+ def getchanges(self, version):
+ """Returns a tuple of (files, copies).
+
+ files is a sorted list of (filename, id) tuples for all files
+ changed between version and its first parent returned by
+ getcommit(). id is the source revision id of the file.
+
+ copies is a dictionary of dest: source
+ """
+ raise NotImplementedError()
+
+ def getcommit(self, version):
+ """Return the commit object for version"""
+ raise NotImplementedError()
+
+ def gettags(self):
+ """Return the tags as a dictionary of name: revision
+
+ Tag names must be UTF-8 strings.
+ """
+ raise NotImplementedError()
+
+ def recode(self, s, encoding=None):
+ if not encoding:
+ encoding = self.encoding or 'utf-8'
+
+ if isinstance(s, unicode):
+ return s.encode("utf-8")
+ try:
+ return s.decode(encoding).encode("utf-8")
+ except:
+ try:
+ return s.decode("latin-1").encode("utf-8")
+ except:
+ return s.decode(encoding, "replace").encode("utf-8")
+
+ def getchangedfiles(self, rev, i):
+ """Return the files changed by rev compared to parent[i].
+
+ i is an index selecting one of the parents of rev. The return
+ value should be the list of files that are different in rev and
+ this parent.
+
+ If rev has no parents, i is None.
+
+ This function is only needed to support --filemap
+ """
+ raise NotImplementedError()
+
+ def converted(self, rev, sinkrev):
+ '''Notify the source that a revision has been converted.'''
+ pass
+
+ def hasnativeorder(self):
+ """Return true if this source has a meaningful, native revision
+ order. For instance, Mercurial revisions are store sequentially
+ while there is no such global ordering with Darcs.
+ """
+ return False
+
+ def lookuprev(self, rev):
+ """If rev is a meaningful revision reference in source, return
+ the referenced identifier in the same format used by getcommit().
+ return None otherwise.
+ """
+ return None
+
+class converter_sink(object):
+ """Conversion sink (target) interface"""
+
+ def __init__(self, ui, path):
+ """Initialize conversion sink (or raise NoRepo("message")
+ exception if path is not a valid repository)
+
+ created is a list of paths to remove if a fatal error occurs
+ later"""
+ self.ui = ui
+ self.path = path
+ self.created = []
+
+ def getheads(self):
+ """Return a list of this repository's heads"""
+ raise NotImplementedError()
+
+ def revmapfile(self):
+ """Path to a file that will contain lines
+ source_rev_id sink_rev_id
+ mapping equivalent revision identifiers for each system."""
+ raise NotImplementedError()
+
+ def authorfile(self):
+ """Path to a file that will contain lines
+ srcauthor=dstauthor
+ mapping equivalent authors identifiers for each system."""
+ return None
+
+ def putcommit(self, files, copies, parents, commit, source, revmap):
+ """Create a revision with all changed files listed in 'files'
+ and having listed parents. 'commit' is a commit object
+ containing at a minimum the author, date, and message for this
+ changeset. 'files' is a list of (path, version) tuples,
+ 'copies' is a dictionary mapping destinations to sources,
+ 'source' is the source repository, and 'revmap' is a mapfile
+ of source revisions to converted revisions. Only getfile(),
+ getmode(), and lookuprev() should be called on 'source'.
+
+ Note that the sink repository is not told to update itself to
+ a particular revision (or even what that revision would be)
+ before it receives the file data.
+ """
+ raise NotImplementedError()
+
+ def puttags(self, tags):
+ """Put tags into sink.
+
+ tags: {tagname: sink_rev_id, ...} where tagname is an UTF-8 string.
+ """
+ raise NotImplementedError()
+
+ def setbranch(self, branch, pbranches):
+ """Set the current branch name. Called before the first putcommit
+ on the branch.
+ branch: branch name for subsequent commits
+ pbranches: (converted parent revision, parent branch) tuples"""
+ pass
+
+ def setfilemapmode(self, active):
+ """Tell the destination that we're using a filemap
+
+ Some converter_sources (svn in particular) can claim that a file
+ was changed in a revision, even if there was no change. This method
+ tells the destination that we're using a filemap and that it should
+ filter empty revisions.
+ """
+ pass
+
+ def before(self):
+ pass
+
+ def after(self):
+ pass
+
+
+class commandline(object):
+ def __init__(self, ui, command):
+ self.ui = ui
+ self.command = command
+
+ def prerun(self):
+ pass
+
+ def postrun(self):
+ pass
+
+ def _cmdline(self, cmd, *args, **kwargs):
+ cmdline = [self.command, cmd] + list(args)
+ for k, v in kwargs.iteritems():
+ if len(k) == 1:
+ cmdline.append('-' + k)
+ else:
+ cmdline.append('--' + k.replace('_', '-'))
+ try:
+ if len(k) == 1:
+ cmdline.append('' + v)
+ else:
+ cmdline[-1] += '=' + v
+ except TypeError:
+ pass
+ cmdline = [util.shellquote(arg) for arg in cmdline]
+ if not self.ui.debugflag:
+ cmdline += ['2>', util.nulldev]
+ cmdline += ['<', util.nulldev]
+ cmdline = ' '.join(cmdline)
+ return cmdline
+
+ def _run(self, cmd, *args, **kwargs):
+ cmdline = self._cmdline(cmd, *args, **kwargs)
+ self.ui.debug(_('running: %s\n') % (cmdline,))
+ self.prerun()
+ try:
+ return util.popen(cmdline)
+ finally:
+ self.postrun()
+
+ def run(self, cmd, *args, **kwargs):
+ fp = self._run(cmd, *args, **kwargs)
+ output = fp.read()
+ self.ui.debug(output)
+ return output, fp.close()
+
+ def runlines(self, cmd, *args, **kwargs):
+ fp = self._run(cmd, *args, **kwargs)
+ output = fp.readlines()
+ self.ui.debug(''.join(output))
+ return output, fp.close()
+
+ def checkexit(self, status, output=''):
+ if status:
+ if output:
+ self.ui.warn(_('%s error:\n') % self.command)
+ self.ui.warn(output)
+ msg = util.explain_exit(status)[0]
+ raise util.Abort('%s %s' % (self.command, msg))
+
+ def run0(self, cmd, *args, **kwargs):
+ output, status = self.run(cmd, *args, **kwargs)
+ self.checkexit(status, output)
+ return output
+
+ def runlines0(self, cmd, *args, **kwargs):
+ output, status = self.runlines(cmd, *args, **kwargs)
+ self.checkexit(status, ''.join(output))
+ return output
+
+ def getargmax(self):
+ if '_argmax' in self.__dict__:
+ return self._argmax
+
+ # POSIX requires at least 4096 bytes for ARG_MAX
+ self._argmax = 4096
+ try:
+ self._argmax = os.sysconf("SC_ARG_MAX")
+ except:
+ pass
+
+ # Windows shells impose their own limits on command line length,
+ # down to 2047 bytes for cmd.exe under Windows NT/2k and 2500 bytes
+ # for older 4nt.exe. See http://support.microsoft.com/kb/830473 for
+ # details about cmd.exe limitations.
+
+ # Since ARG_MAX is for command line _and_ environment, lower our limit
+ # (and make happy Windows shells while doing this).
+
+ self._argmax = self._argmax/2 - 1
+ return self._argmax
+
+ def limit_arglist(self, arglist, cmd, *args, **kwargs):
+ limit = self.getargmax() - len(self._cmdline(cmd, *args, **kwargs))
+ bytes = 0
+ fl = []
+ for fn in arglist:
+ b = len(fn) + 3
+ if bytes + b < limit or len(fl) == 0:
+ fl.append(fn)
+ bytes += b
+ else:
+ yield fl
+ fl = [fn]
+ bytes = b
+ if fl:
+ yield fl
+
+ def xargs(self, arglist, cmd, *args, **kwargs):
+ for l in self.limit_arglist(arglist, cmd, *args, **kwargs):
+ self.run0(cmd, *(list(args) + l), **kwargs)
+
+class mapfile(dict):
+ def __init__(self, ui, path):
+ super(mapfile, self).__init__()
+ self.ui = ui
+ self.path = path
+ self.fp = None
+ self.order = []
+ self._read()
+
+ def _read(self):
+ if not self.path:
+ return
+ try:
+ fp = open(self.path, 'r')
+ except IOError, err:
+ if err.errno != errno.ENOENT:
+ raise
+ return
+ for i, line in enumerate(fp):
+ try:
+ key, value = line[:-1].rsplit(' ', 1)
+ except ValueError:
+ raise util.Abort(_('syntax error in %s(%d): key/value pair expected')
+ % (self.path, i+1))
+ if key not in self:
+ self.order.append(key)
+ super(mapfile, self).__setitem__(key, value)
+ fp.close()
+
+ def __setitem__(self, key, value):
+ if self.fp is None:
+ try:
+ self.fp = open(self.path, 'a')
+ except IOError, err:
+ raise util.Abort(_('could not open map file %r: %s') %
+ (self.path, err.strerror))
+ self.fp.write('%s %s\n' % (key, value))
+ self.fp.flush()
+ super(mapfile, self).__setitem__(key, value)
+
+ def close(self):
+ if self.fp:
+ self.fp.close()
+ self.fp = None
diff --git a/sys/src/cmd/hg/hgext/convert/convcmd.py b/sys/src/cmd/hg/hgext/convert/convcmd.py
new file mode 100644
index 000000000..50be03af0
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/convcmd.py
@@ -0,0 +1,396 @@
+# convcmd - convert extension commands definition
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from common import NoRepo, MissingTool, SKIPREV, mapfile
+from cvs import convert_cvs
+from darcs import darcs_source
+from git import convert_git
+from hg import mercurial_source, mercurial_sink
+from subversion import svn_source, svn_sink
+from monotone import monotone_source
+from gnuarch import gnuarch_source
+from bzr import bzr_source
+from p4 import p4_source
+import filemap
+
+import os, shutil
+from mercurial import hg, util, encoding
+from mercurial.i18n import _
+
+orig_encoding = 'ascii'
+
+def recode(s):
+ if isinstance(s, unicode):
+ return s.encode(orig_encoding, 'replace')
+ else:
+ return s.decode('utf-8').encode(orig_encoding, 'replace')
+
+source_converters = [
+ ('cvs', convert_cvs, 'branchsort'),
+ ('git', convert_git, 'branchsort'),
+ ('svn', svn_source, 'branchsort'),
+ ('hg', mercurial_source, 'sourcesort'),
+ ('darcs', darcs_source, 'branchsort'),
+ ('mtn', monotone_source, 'branchsort'),
+ ('gnuarch', gnuarch_source, 'branchsort'),
+ ('bzr', bzr_source, 'branchsort'),
+ ('p4', p4_source, 'branchsort'),
+ ]
+
+sink_converters = [
+ ('hg', mercurial_sink),
+ ('svn', svn_sink),
+ ]
+
+def convertsource(ui, path, type, rev):
+ exceptions = []
+ for name, source, sortmode in source_converters:
+ try:
+ if not type or name == type:
+ return source(ui, path, rev), sortmode
+ except (NoRepo, MissingTool), inst:
+ exceptions.append(inst)
+ if not ui.quiet:
+ for inst in exceptions:
+ ui.write("%s\n" % inst)
+ raise util.Abort(_('%s: missing or unsupported repository') % path)
+
+def convertsink(ui, path, type):
+ for name, sink in sink_converters:
+ try:
+ if not type or name == type:
+ return sink(ui, path)
+ except NoRepo, inst:
+ ui.note(_("convert: %s\n") % inst)
+ raise util.Abort(_('%s: unknown repository type') % path)
+
+class converter(object):
+ def __init__(self, ui, source, dest, revmapfile, opts):
+
+ self.source = source
+ self.dest = dest
+ self.ui = ui
+ self.opts = opts
+ self.commitcache = {}
+ self.authors = {}
+ self.authorfile = None
+
+ # Record converted revisions persistently: maps source revision
+ # ID to target revision ID (both strings). (This is how
+ # incremental conversions work.)
+ self.map = mapfile(ui, revmapfile)
+
+ # Read first the dst author map if any
+ authorfile = self.dest.authorfile()
+ if authorfile and os.path.exists(authorfile):
+ self.readauthormap(authorfile)
+ # Extend/Override with new author map if necessary
+ if opts.get('authors'):
+ self.readauthormap(opts.get('authors'))
+ self.authorfile = self.dest.authorfile()
+
+ self.splicemap = mapfile(ui, opts.get('splicemap'))
+ self.branchmap = mapfile(ui, opts.get('branchmap'))
+
+ def walktree(self, heads):
+ '''Return a mapping that identifies the uncommitted parents of every
+ uncommitted changeset.'''
+ visit = heads
+ known = set()
+ parents = {}
+ while visit:
+ n = visit.pop(0)
+ if n in known or n in self.map: continue
+ known.add(n)
+ commit = self.cachecommit(n)
+ parents[n] = []
+ for p in commit.parents:
+ parents[n].append(p)
+ visit.append(p)
+
+ return parents
+
+ def toposort(self, parents, sortmode):
+ '''Return an ordering such that every uncommitted changeset is
+ preceeded by all its uncommitted ancestors.'''
+
+ def mapchildren(parents):
+ """Return a (children, roots) tuple where 'children' maps parent
+ revision identifiers to children ones, and 'roots' is the list of
+ revisions without parents. 'parents' must be a mapping of revision
+ identifier to its parents ones.
+ """
+ visit = parents.keys()
+ seen = set()
+ children = {}
+ roots = []
+
+ while visit:
+ n = visit.pop(0)
+ if n in seen:
+ continue
+ seen.add(n)
+ # Ensure that nodes without parents are present in the
+ # 'children' mapping.
+ children.setdefault(n, [])
+ hasparent = False
+ for p in parents[n]:
+ if not p in self.map:
+ visit.append(p)
+ hasparent = True
+ children.setdefault(p, []).append(n)
+ if not hasparent:
+ roots.append(n)
+
+ return children, roots
+
+ # Sort functions are supposed to take a list of revisions which
+ # can be converted immediately and pick one
+
+ def makebranchsorter():
+ """If the previously converted revision has a child in the
+ eligible revisions list, pick it. Return the list head
+ otherwise. Branch sort attempts to minimize branch
+ switching, which is harmful for Mercurial backend
+ compression.
+ """
+ prev = [None]
+ def picknext(nodes):
+ next = nodes[0]
+ for n in nodes:
+ if prev[0] in parents[n]:
+ next = n
+ break
+ prev[0] = next
+ return next
+ return picknext
+
+ def makesourcesorter():
+ """Source specific sort."""
+ keyfn = lambda n: self.commitcache[n].sortkey
+ def picknext(nodes):
+ return sorted(nodes, key=keyfn)[0]
+ return picknext
+
+ def makedatesorter():
+ """Sort revisions by date."""
+ dates = {}
+ def getdate(n):
+ if n not in dates:
+ dates[n] = util.parsedate(self.commitcache[n].date)
+ return dates[n]
+
+ def picknext(nodes):
+ return min([(getdate(n), n) for n in nodes])[1]
+
+ return picknext
+
+ if sortmode == 'branchsort':
+ picknext = makebranchsorter()
+ elif sortmode == 'datesort':
+ picknext = makedatesorter()
+ elif sortmode == 'sourcesort':
+ picknext = makesourcesorter()
+ else:
+ raise util.Abort(_('unknown sort mode: %s') % sortmode)
+
+ children, actives = mapchildren(parents)
+
+ s = []
+ pendings = {}
+ while actives:
+ n = picknext(actives)
+ actives.remove(n)
+ s.append(n)
+
+ # Update dependents list
+ for c in children.get(n, []):
+ if c not in pendings:
+ pendings[c] = [p for p in parents[c] if p not in self.map]
+ try:
+ pendings[c].remove(n)
+ except ValueError:
+ raise util.Abort(_('cycle detected between %s and %s')
+ % (recode(c), recode(n)))
+ if not pendings[c]:
+ # Parents are converted, node is eligible
+ actives.insert(0, c)
+ pendings[c] = None
+
+ if len(s) != len(parents):
+ raise util.Abort(_("not all revisions were sorted"))
+
+ return s
+
+ def writeauthormap(self):
+ authorfile = self.authorfile
+ if authorfile:
+ self.ui.status(_('Writing author map file %s\n') % authorfile)
+ ofile = open(authorfile, 'w+')
+ for author in self.authors:
+ ofile.write("%s=%s\n" % (author, self.authors[author]))
+ ofile.close()
+
+ def readauthormap(self, authorfile):
+ afile = open(authorfile, 'r')
+ for line in afile:
+
+ line = line.strip()
+ if not line or line.startswith('#'):
+ continue
+
+ try:
+ srcauthor, dstauthor = line.split('=', 1)
+ except ValueError:
+ msg = _('Ignoring bad line in author map file %s: %s\n')
+ self.ui.warn(msg % (authorfile, line.rstrip()))
+ continue
+
+ srcauthor = srcauthor.strip()
+ dstauthor = dstauthor.strip()
+ if self.authors.get(srcauthor) in (None, dstauthor):
+ msg = _('mapping author %s to %s\n')
+ self.ui.debug(msg % (srcauthor, dstauthor))
+ self.authors[srcauthor] = dstauthor
+ continue
+
+ m = _('overriding mapping for author %s, was %s, will be %s\n')
+ self.ui.status(m % (srcauthor, self.authors[srcauthor], dstauthor))
+
+ afile.close()
+
+ def cachecommit(self, rev):
+ commit = self.source.getcommit(rev)
+ commit.author = self.authors.get(commit.author, commit.author)
+ commit.branch = self.branchmap.get(commit.branch, commit.branch)
+ self.commitcache[rev] = commit
+ return commit
+
+ def copy(self, rev):
+ commit = self.commitcache[rev]
+
+ changes = self.source.getchanges(rev)
+ if isinstance(changes, basestring):
+ if changes == SKIPREV:
+ dest = SKIPREV
+ else:
+ dest = self.map[changes]
+ self.map[rev] = dest
+ return
+ files, copies = changes
+ pbranches = []
+ if commit.parents:
+ for prev in commit.parents:
+ if prev not in self.commitcache:
+ self.cachecommit(prev)
+ pbranches.append((self.map[prev],
+ self.commitcache[prev].branch))
+ self.dest.setbranch(commit.branch, pbranches)
+ try:
+ parents = self.splicemap[rev].replace(',', ' ').split()
+ self.ui.status(_('spliced in %s as parents of %s\n') %
+ (parents, rev))
+ parents = [self.map.get(p, p) for p in parents]
+ except KeyError:
+ parents = [b[0] for b in pbranches]
+ newnode = self.dest.putcommit(files, copies, parents, commit,
+ self.source, self.map)
+ self.source.converted(rev, newnode)
+ self.map[rev] = newnode
+
+ def convert(self, sortmode):
+ try:
+ self.source.before()
+ self.dest.before()
+ self.source.setrevmap(self.map)
+ self.ui.status(_("scanning source...\n"))
+ heads = self.source.getheads()
+ parents = self.walktree(heads)
+ self.ui.status(_("sorting...\n"))
+ t = self.toposort(parents, sortmode)
+ num = len(t)
+ c = None
+
+ self.ui.status(_("converting...\n"))
+ for c in t:
+ num -= 1
+ desc = self.commitcache[c].desc
+ if "\n" in desc:
+ desc = desc.splitlines()[0]
+ # convert log message to local encoding without using
+ # tolocal() because encoding.encoding conver() use it as
+ # 'utf-8'
+ self.ui.status("%d %s\n" % (num, recode(desc)))
+ self.ui.note(_("source: %s\n") % recode(c))
+ self.copy(c)
+
+ tags = self.source.gettags()
+ ctags = {}
+ for k in tags:
+ v = tags[k]
+ if self.map.get(v, SKIPREV) != SKIPREV:
+ ctags[k] = self.map[v]
+
+ if c and ctags:
+ nrev = self.dest.puttags(ctags)
+ # write another hash correspondence to override the previous
+ # one so we don't end up with extra tag heads
+ if nrev:
+ self.map[c] = nrev
+
+ self.writeauthormap()
+ finally:
+ self.cleanup()
+
+ def cleanup(self):
+ try:
+ self.dest.after()
+ finally:
+ self.source.after()
+ self.map.close()
+
+def convert(ui, src, dest=None, revmapfile=None, **opts):
+ global orig_encoding
+ orig_encoding = encoding.encoding
+ encoding.encoding = 'UTF-8'
+
+ if not dest:
+ dest = hg.defaultdest(src) + "-hg"
+ ui.status(_("assuming destination %s\n") % dest)
+
+ destc = convertsink(ui, dest, opts.get('dest_type'))
+
+ try:
+ srcc, defaultsort = convertsource(ui, src, opts.get('source_type'),
+ opts.get('rev'))
+ except Exception:
+ for path in destc.created:
+ shutil.rmtree(path, True)
+ raise
+
+ sortmodes = ('branchsort', 'datesort', 'sourcesort')
+ sortmode = [m for m in sortmodes if opts.get(m)]
+ if len(sortmode) > 1:
+ raise util.Abort(_('more than one sort mode specified'))
+ sortmode = sortmode and sortmode[0] or defaultsort
+ if sortmode == 'sourcesort' and not srcc.hasnativeorder():
+ raise util.Abort(_('--sourcesort is not supported by this data source'))
+
+ fmap = opts.get('filemap')
+ if fmap:
+ srcc = filemap.filemap_source(ui, srcc, fmap)
+ destc.setfilemapmode(True)
+
+ if not revmapfile:
+ try:
+ revmapfile = destc.revmapfile()
+ except:
+ revmapfile = os.path.join(destc, "map")
+
+ c = converter(ui, srcc, destc, revmapfile, opts)
+ c.convert(sortmode)
+
diff --git a/sys/src/cmd/hg/hgext/convert/cvs.py b/sys/src/cmd/hg/hgext/convert/cvs.py
new file mode 100644
index 000000000..c215747be
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/cvs.py
@@ -0,0 +1,372 @@
+# cvs.py: CVS conversion code inspired by hg-cvs-import and git-cvsimport
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os, locale, re, socket, errno
+from cStringIO import StringIO
+from mercurial import util
+from mercurial.i18n import _
+
+from common import NoRepo, commit, converter_source, checktool
+import cvsps
+
+class convert_cvs(converter_source):
+ def __init__(self, ui, path, rev=None):
+ super(convert_cvs, self).__init__(ui, path, rev=rev)
+
+ cvs = os.path.join(path, "CVS")
+ if not os.path.exists(cvs):
+ raise NoRepo("%s does not look like a CVS checkout" % path)
+
+ checktool('cvs')
+ self.cmd = ui.config('convert', 'cvsps', 'builtin')
+ cvspsexe = self.cmd.split(None, 1)[0]
+ self.builtin = cvspsexe == 'builtin'
+ if not self.builtin:
+ ui.warn(_('warning: support for external cvsps is deprecated and '
+ 'will be removed in Mercurial 1.4\n'))
+
+ if not self.builtin:
+ checktool(cvspsexe)
+
+ self.changeset = None
+ self.files = {}
+ self.tags = {}
+ self.lastbranch = {}
+ self.parent = {}
+ self.socket = None
+ self.cvsroot = open(os.path.join(cvs, "Root")).read()[:-1]
+ self.cvsrepo = open(os.path.join(cvs, "Repository")).read()[:-1]
+ self.encoding = locale.getpreferredencoding()
+
+ self._connect()
+
+ def _parse(self):
+ if self.changeset is not None:
+ return
+ self.changeset = {}
+
+ maxrev = 0
+ cmd = self.cmd
+ if self.rev:
+ # TODO: handle tags
+ try:
+ # patchset number?
+ maxrev = int(self.rev)
+ except ValueError:
+ try:
+ # date
+ util.parsedate(self.rev, ['%Y/%m/%d %H:%M:%S'])
+ cmd = '%s -d "1970/01/01 00:00:01" -d "%s"' % (cmd, self.rev)
+ except util.Abort:
+ raise util.Abort(_('revision %s is not a patchset number or date') % self.rev)
+
+ d = os.getcwd()
+ try:
+ os.chdir(self.path)
+ id = None
+ state = 0
+ filerevids = {}
+
+ if self.builtin:
+ # builtin cvsps code
+ self.ui.status(_('using builtin cvsps\n'))
+
+ cache = 'update'
+ if not self.ui.configbool('convert', 'cvsps.cache', True):
+ cache = None
+ db = cvsps.createlog(self.ui, cache=cache)
+ db = cvsps.createchangeset(self.ui, db,
+ fuzz=int(self.ui.config('convert', 'cvsps.fuzz', 60)),
+ mergeto=self.ui.config('convert', 'cvsps.mergeto', None),
+ mergefrom=self.ui.config('convert', 'cvsps.mergefrom', None))
+
+ for cs in db:
+ if maxrev and cs.id>maxrev:
+ break
+ id = str(cs.id)
+ cs.author = self.recode(cs.author)
+ self.lastbranch[cs.branch] = id
+ cs.comment = self.recode(cs.comment)
+ date = util.datestr(cs.date)
+ self.tags.update(dict.fromkeys(cs.tags, id))
+
+ files = {}
+ for f in cs.entries:
+ files[f.file] = "%s%s" % ('.'.join([str(x) for x in f.revision]),
+ ['', '(DEAD)'][f.dead])
+
+ # add current commit to set
+ c = commit(author=cs.author, date=date,
+ parents=[str(p.id) for p in cs.parents],
+ desc=cs.comment, branch=cs.branch or '')
+ self.changeset[id] = c
+ self.files[id] = files
+ else:
+ # external cvsps
+ for l in util.popen(cmd):
+ if state == 0: # header
+ if l.startswith("PatchSet"):
+ id = l[9:-2]
+ if maxrev and int(id) > maxrev:
+ # ignore everything
+ state = 3
+ elif l.startswith("Date:"):
+ date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"])
+ date = util.datestr(date)
+ elif l.startswith("Branch:"):
+ branch = l[8:-1]
+ self.parent[id] = self.lastbranch.get(branch, 'bad')
+ self.lastbranch[branch] = id
+ elif l.startswith("Ancestor branch:"):
+ ancestor = l[17:-1]
+ # figure out the parent later
+ self.parent[id] = self.lastbranch[ancestor]
+ elif l.startswith("Author:"):
+ author = self.recode(l[8:-1])
+ elif l.startswith("Tag:") or l.startswith("Tags:"):
+ t = l[l.index(':')+1:]
+ t = [ut.strip() for ut in t.split(',')]
+ if (len(t) > 1) or (t[0] and (t[0] != "(none)")):
+ self.tags.update(dict.fromkeys(t, id))
+ elif l.startswith("Log:"):
+ # switch to gathering log
+ state = 1
+ log = ""
+ elif state == 1: # log
+ if l == "Members: \n":
+ # switch to gathering members
+ files = {}
+ oldrevs = []
+ log = self.recode(log[:-1])
+ state = 2
+ else:
+ # gather log
+ log += l
+ elif state == 2: # members
+ if l == "\n": # start of next entry
+ state = 0
+ p = [self.parent[id]]
+ if id == "1":
+ p = []
+ if branch == "HEAD":
+ branch = ""
+ if branch:
+ latest = 0
+ # the last changeset that contains a base
+ # file is our parent
+ for r in oldrevs:
+ latest = max(filerevids.get(r, 0), latest)
+ if latest:
+ p = [latest]
+
+ # add current commit to set
+ c = commit(author=author, date=date, parents=p,
+ desc=log, branch=branch)
+ self.changeset[id] = c
+ self.files[id] = files
+ else:
+ colon = l.rfind(':')
+ file = l[1:colon]
+ rev = l[colon+1:-2]
+ oldrev, rev = rev.split("->")
+ files[file] = rev
+
+ # save some information for identifying branch points
+ oldrevs.append("%s:%s" % (oldrev, file))
+ filerevids["%s:%s" % (rev, file)] = id
+ elif state == 3:
+ # swallow all input
+ continue
+
+ self.heads = self.lastbranch.values()
+ finally:
+ os.chdir(d)
+
+ def _connect(self):
+ root = self.cvsroot
+ conntype = None
+ user, host = None, None
+ cmd = ['cvs', 'server']
+
+ self.ui.status(_("connecting to %s\n") % root)
+
+ if root.startswith(":pserver:"):
+ root = root[9:]
+ m = re.match(r'(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?(.*)',
+ root)
+ if m:
+ conntype = "pserver"
+ user, passw, serv, port, root = m.groups()
+ if not user:
+ user = "anonymous"
+ if not port:
+ port = 2401
+ else:
+ port = int(port)
+ format0 = ":pserver:%s@%s:%s" % (user, serv, root)
+ format1 = ":pserver:%s@%s:%d%s" % (user, serv, port, root)
+
+ if not passw:
+ passw = "A"
+ cvspass = os.path.expanduser("~/.cvspass")
+ try:
+ pf = open(cvspass)
+ for line in pf.read().splitlines():
+ part1, part2 = line.split(' ', 1)
+ if part1 == '/1':
+ # /1 :pserver:user@example.com:2401/cvsroot/foo Ah<Z
+ part1, part2 = part2.split(' ', 1)
+ format = format1
+ else:
+ # :pserver:user@example.com:/cvsroot/foo Ah<Z
+ format = format0
+ if part1 == format:
+ passw = part2
+ break
+ pf.close()
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ if not getattr(inst, 'filename', None):
+ inst.filename = cvspass
+ raise
+
+ sck = socket.socket()
+ sck.connect((serv, port))
+ sck.send("\n".join(["BEGIN AUTH REQUEST", root, user, passw,
+ "END AUTH REQUEST", ""]))
+ if sck.recv(128) != "I LOVE YOU\n":
+ raise util.Abort(_("CVS pserver authentication failed"))
+
+ self.writep = self.readp = sck.makefile('r+')
+
+ if not conntype and root.startswith(":local:"):
+ conntype = "local"
+ root = root[7:]
+
+ if not conntype:
+ # :ext:user@host/home/user/path/to/cvsroot
+ if root.startswith(":ext:"):
+ root = root[5:]
+ m = re.match(r'(?:([^@:/]+)@)?([^:/]+):?(.*)', root)
+ # Do not take Windows path "c:\foo\bar" for a connection strings
+ if os.path.isdir(root) or not m:
+ conntype = "local"
+ else:
+ conntype = "rsh"
+ user, host, root = m.group(1), m.group(2), m.group(3)
+
+ if conntype != "pserver":
+ if conntype == "rsh":
+ rsh = os.environ.get("CVS_RSH") or "ssh"
+ if user:
+ cmd = [rsh, '-l', user, host] + cmd
+ else:
+ cmd = [rsh, host] + cmd
+
+ # popen2 does not support argument lists under Windows
+ cmd = [util.shellquote(arg) for arg in cmd]
+ cmd = util.quotecommand(' '.join(cmd))
+ self.writep, self.readp = util.popen2(cmd)
+
+ self.realroot = root
+
+ self.writep.write("Root %s\n" % root)
+ self.writep.write("Valid-responses ok error Valid-requests Mode"
+ " M Mbinary E Checked-in Created Updated"
+ " Merged Removed\n")
+ self.writep.write("valid-requests\n")
+ self.writep.flush()
+ r = self.readp.readline()
+ if not r.startswith("Valid-requests"):
+ raise util.Abort(_("unexpected response from CVS server "
+ "(expected \"Valid-requests\", but got %r)")
+ % r)
+ if "UseUnchanged" in r:
+ self.writep.write("UseUnchanged\n")
+ self.writep.flush()
+ r = self.readp.readline()
+
+ def getheads(self):
+ self._parse()
+ return self.heads
+
+ def _getfile(self, name, rev):
+
+ def chunkedread(fp, count):
+ # file-objects returned by socked.makefile() do not handle
+ # large read() requests very well.
+ chunksize = 65536
+ output = StringIO()
+ while count > 0:
+ data = fp.read(min(count, chunksize))
+ if not data:
+ raise util.Abort(_("%d bytes missing from remote file") % count)
+ count -= len(data)
+ output.write(data)
+ return output.getvalue()
+
+ if rev.endswith("(DEAD)"):
+ raise IOError
+
+ args = ("-N -P -kk -r %s --" % rev).split()
+ args.append(self.cvsrepo + '/' + name)
+ for x in args:
+ self.writep.write("Argument %s\n" % x)
+ self.writep.write("Directory .\n%s\nco\n" % self.realroot)
+ self.writep.flush()
+
+ data = ""
+ while 1:
+ line = self.readp.readline()
+ if line.startswith("Created ") or line.startswith("Updated "):
+ self.readp.readline() # path
+ self.readp.readline() # entries
+ mode = self.readp.readline()[:-1]
+ count = int(self.readp.readline()[:-1])
+ data = chunkedread(self.readp, count)
+ elif line.startswith(" "):
+ data += line[1:]
+ elif line.startswith("M "):
+ pass
+ elif line.startswith("Mbinary "):
+ count = int(self.readp.readline()[:-1])
+ data = chunkedread(self.readp, count)
+ else:
+ if line == "ok\n":
+ return (data, "x" in mode and "x" or "")
+ elif line.startswith("E "):
+ self.ui.warn(_("cvs server: %s\n") % line[2:])
+ elif line.startswith("Remove"):
+ self.readp.readline()
+ else:
+ raise util.Abort(_("unknown CVS response: %s") % line)
+
+ def getfile(self, file, rev):
+ self._parse()
+ data, mode = self._getfile(file, rev)
+ self.modecache[(file, rev)] = mode
+ return data
+
+ def getmode(self, file, rev):
+ return self.modecache[(file, rev)]
+
+ def getchanges(self, rev):
+ self._parse()
+ self.modecache = {}
+ return sorted(self.files[rev].iteritems()), {}
+
+ def getcommit(self, rev):
+ self._parse()
+ return self.changeset[rev]
+
+ def gettags(self):
+ self._parse()
+ return self.tags
+
+ def getchangedfiles(self, rev, i):
+ self._parse()
+ return sorted(self.files[rev])
diff --git a/sys/src/cmd/hg/hgext/convert/cvsps.py b/sys/src/cmd/hg/hgext/convert/cvsps.py
new file mode 100644
index 000000000..02db47e25
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/cvsps.py
@@ -0,0 +1,831 @@
+#
+# Mercurial built-in replacement for cvsps.
+#
+# Copyright 2008, Frank Kingswood <frank@kingswood-consulting.co.uk>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os
+import re
+import cPickle as pickle
+from mercurial import util
+from mercurial.i18n import _
+
+class logentry(object):
+ '''Class logentry has the following attributes:
+ .author - author name as CVS knows it
+ .branch - name of branch this revision is on
+ .branches - revision tuple of branches starting at this revision
+ .comment - commit message
+ .date - the commit date as a (time, tz) tuple
+ .dead - true if file revision is dead
+ .file - Name of file
+ .lines - a tuple (+lines, -lines) or None
+ .parent - Previous revision of this entry
+ .rcs - name of file as returned from CVS
+ .revision - revision number as tuple
+ .tags - list of tags on the file
+ .synthetic - is this a synthetic "file ... added on ..." revision?
+ .mergepoint- the branch that has been merged from
+ (if present in rlog output)
+ .branchpoints- the branches that start at the current entry
+ '''
+ def __init__(self, **entries):
+ self.__dict__.update(entries)
+
+ def __repr__(self):
+ return "<%s at 0x%x: %s %s>" % (self.__class__.__name__,
+ id(self),
+ self.file,
+ ".".join(map(str, self.revision)))
+
+class logerror(Exception):
+ pass
+
+def getrepopath(cvspath):
+ """Return the repository path from a CVS path.
+
+ >>> getrepopath('/foo/bar')
+ '/foo/bar'
+ >>> getrepopath('c:/foo/bar')
+ 'c:/foo/bar'
+ >>> getrepopath(':pserver:10/foo/bar')
+ '/foo/bar'
+ >>> getrepopath(':pserver:10c:/foo/bar')
+ '/foo/bar'
+ >>> getrepopath(':pserver:/foo/bar')
+ '/foo/bar'
+ >>> getrepopath(':pserver:c:/foo/bar')
+ 'c:/foo/bar'
+ >>> getrepopath(':pserver:truc@foo.bar:/foo/bar')
+ '/foo/bar'
+ >>> getrepopath(':pserver:truc@foo.bar:c:/foo/bar')
+ 'c:/foo/bar'
+ """
+ # According to CVS manual, CVS paths are expressed like:
+ # [:method:][[user][:password]@]hostname[:[port]]/path/to/repository
+ #
+ # Unfortunately, Windows absolute paths start with a drive letter
+ # like 'c:' making it harder to parse. Here we assume that drive
+ # letters are only one character long and any CVS component before
+ # the repository path is at least 2 characters long, and use this
+ # to disambiguate.
+ parts = cvspath.split(':')
+ if len(parts) == 1:
+ return parts[0]
+ # Here there is an ambiguous case if we have a port number
+ # immediately followed by a Windows driver letter. We assume this
+ # never happens and decide it must be CVS path component,
+ # therefore ignoring it.
+ if len(parts[-2]) > 1:
+ return parts[-1].lstrip('0123456789')
+ return parts[-2] + ':' + parts[-1]
+
+def createlog(ui, directory=None, root="", rlog=True, cache=None):
+ '''Collect the CVS rlog'''
+
+ # Because we store many duplicate commit log messages, reusing strings
+ # saves a lot of memory and pickle storage space.
+ _scache = {}
+ def scache(s):
+ "return a shared version of a string"
+ return _scache.setdefault(s, s)
+
+ ui.status(_('collecting CVS rlog\n'))
+
+ log = [] # list of logentry objects containing the CVS state
+
+ # patterns to match in CVS (r)log output, by state of use
+ re_00 = re.compile('RCS file: (.+)$')
+ re_01 = re.compile('cvs \\[r?log aborted\\]: (.+)$')
+ re_02 = re.compile('cvs (r?log|server): (.+)\n$')
+ re_03 = re.compile("(Cannot access.+CVSROOT)|"
+ "(can't create temporary directory.+)$")
+ re_10 = re.compile('Working file: (.+)$')
+ re_20 = re.compile('symbolic names:')
+ re_30 = re.compile('\t(.+): ([\\d.]+)$')
+ re_31 = re.compile('----------------------------$')
+ re_32 = re.compile('======================================='
+ '======================================$')
+ re_50 = re.compile('revision ([\\d.]+)(\s+locked by:\s+.+;)?$')
+ re_60 = re.compile(r'date:\s+(.+);\s+author:\s+(.+);\s+state:\s+(.+?);'
+ r'(\s+lines:\s+(\+\d+)?\s+(-\d+)?;)?'
+ r'(.*mergepoint:\s+([^;]+);)?')
+ re_70 = re.compile('branches: (.+);$')
+
+ file_added_re = re.compile(r'file [^/]+ was (initially )?added on branch')
+
+ prefix = '' # leading path to strip of what we get from CVS
+
+ if directory is None:
+ # Current working directory
+
+ # Get the real directory in the repository
+ try:
+ prefix = open(os.path.join('CVS','Repository')).read().strip()
+ if prefix == ".":
+ prefix = ""
+ directory = prefix
+ except IOError:
+ raise logerror('Not a CVS sandbox')
+
+ if prefix and not prefix.endswith(os.sep):
+ prefix += os.sep
+
+ # Use the Root file in the sandbox, if it exists
+ try:
+ root = open(os.path.join('CVS','Root')).read().strip()
+ except IOError:
+ pass
+
+ if not root:
+ root = os.environ.get('CVSROOT', '')
+
+ # read log cache if one exists
+ oldlog = []
+ date = None
+
+ if cache:
+ cachedir = os.path.expanduser('~/.hg.cvsps')
+ if not os.path.exists(cachedir):
+ os.mkdir(cachedir)
+
+ # The cvsps cache pickle needs a uniquified name, based on the
+ # repository location. The address may have all sort of nasties
+ # in it, slashes, colons and such. So here we take just the
+ # alphanumerics, concatenated in a way that does not mix up the
+ # various components, so that
+ # :pserver:user@server:/path
+ # and
+ # /pserver/user/server/path
+ # are mapped to different cache file names.
+ cachefile = root.split(":") + [directory, "cache"]
+ cachefile = ['-'.join(re.findall(r'\w+', s)) for s in cachefile if s]
+ cachefile = os.path.join(cachedir,
+ '.'.join([s for s in cachefile if s]))
+
+ if cache == 'update':
+ try:
+ ui.note(_('reading cvs log cache %s\n') % cachefile)
+ oldlog = pickle.load(open(cachefile))
+ ui.note(_('cache has %d log entries\n') % len(oldlog))
+ except Exception, e:
+ ui.note(_('error reading cache: %r\n') % e)
+
+ if oldlog:
+ date = oldlog[-1].date # last commit date as a (time,tz) tuple
+ date = util.datestr(date, '%Y/%m/%d %H:%M:%S %1%2')
+
+ # build the CVS commandline
+ cmd = ['cvs', '-q']
+ if root:
+ cmd.append('-d%s' % root)
+ p = util.normpath(getrepopath(root))
+ if not p.endswith('/'):
+ p += '/'
+ prefix = p + util.normpath(prefix)
+ cmd.append(['log', 'rlog'][rlog])
+ if date:
+ # no space between option and date string
+ cmd.append('-d>%s' % date)
+ cmd.append(directory)
+
+ # state machine begins here
+ tags = {} # dictionary of revisions on current file with their tags
+ branchmap = {} # mapping between branch names and revision numbers
+ state = 0
+ store = False # set when a new record can be appended
+
+ cmd = [util.shellquote(arg) for arg in cmd]
+ ui.note(_("running %s\n") % (' '.join(cmd)))
+ ui.debug(_("prefix=%r directory=%r root=%r\n") % (prefix, directory, root))
+
+ pfp = util.popen(' '.join(cmd))
+ peek = pfp.readline()
+ while True:
+ line = peek
+ if line == '':
+ break
+ peek = pfp.readline()
+ if line.endswith('\n'):
+ line = line[:-1]
+ #ui.debug('state=%d line=%r\n' % (state, line))
+
+ if state == 0:
+ # initial state, consume input until we see 'RCS file'
+ match = re_00.match(line)
+ if match:
+ rcs = match.group(1)
+ tags = {}
+ if rlog:
+ filename = util.normpath(rcs[:-2])
+ if filename.startswith(prefix):
+ filename = filename[len(prefix):]
+ if filename.startswith('/'):
+ filename = filename[1:]
+ if filename.startswith('Attic/'):
+ filename = filename[6:]
+ else:
+ filename = filename.replace('/Attic/', '/')
+ state = 2
+ continue
+ state = 1
+ continue
+ match = re_01.match(line)
+ if match:
+ raise Exception(match.group(1))
+ match = re_02.match(line)
+ if match:
+ raise Exception(match.group(2))
+ if re_03.match(line):
+ raise Exception(line)
+
+ elif state == 1:
+ # expect 'Working file' (only when using log instead of rlog)
+ match = re_10.match(line)
+ assert match, _('RCS file must be followed by working file')
+ filename = util.normpath(match.group(1))
+ state = 2
+
+ elif state == 2:
+ # expect 'symbolic names'
+ if re_20.match(line):
+ branchmap = {}
+ state = 3
+
+ elif state == 3:
+ # read the symbolic names and store as tags
+ match = re_30.match(line)
+ if match:
+ rev = [int(x) for x in match.group(2).split('.')]
+
+ # Convert magic branch number to an odd-numbered one
+ revn = len(rev)
+ if revn > 3 and (revn % 2) == 0 and rev[-2] == 0:
+ rev = rev[:-2] + rev[-1:]
+ rev = tuple(rev)
+
+ if rev not in tags:
+ tags[rev] = []
+ tags[rev].append(match.group(1))
+ branchmap[match.group(1)] = match.group(2)
+
+ elif re_31.match(line):
+ state = 5
+ elif re_32.match(line):
+ state = 0
+
+ elif state == 4:
+ # expecting '------' separator before first revision
+ if re_31.match(line):
+ state = 5
+ else:
+ assert not re_32.match(line), _('must have at least '
+ 'some revisions')
+
+ elif state == 5:
+ # expecting revision number and possibly (ignored) lock indication
+ # we create the logentry here from values stored in states 0 to 4,
+ # as this state is re-entered for subsequent revisions of a file.
+ match = re_50.match(line)
+ assert match, _('expected revision number')
+ e = logentry(rcs=scache(rcs), file=scache(filename),
+ revision=tuple([int(x) for x in match.group(1).split('.')]),
+ branches=[], parent=None,
+ synthetic=False)
+ state = 6
+
+ elif state == 6:
+ # expecting date, author, state, lines changed
+ match = re_60.match(line)
+ assert match, _('revision must be followed by date line')
+ d = match.group(1)
+ if d[2] == '/':
+ # Y2K
+ d = '19' + d
+
+ if len(d.split()) != 3:
+ # cvs log dates always in GMT
+ d = d + ' UTC'
+ e.date = util.parsedate(d, ['%y/%m/%d %H:%M:%S',
+ '%Y/%m/%d %H:%M:%S',
+ '%Y-%m-%d %H:%M:%S'])
+ e.author = scache(match.group(2))
+ e.dead = match.group(3).lower() == 'dead'
+
+ if match.group(5):
+ if match.group(6):
+ e.lines = (int(match.group(5)), int(match.group(6)))
+ else:
+ e.lines = (int(match.group(5)), 0)
+ elif match.group(6):
+ e.lines = (0, int(match.group(6)))
+ else:
+ e.lines = None
+
+ if match.group(7): # cvsnt mergepoint
+ myrev = match.group(8).split('.')
+ if len(myrev) == 2: # head
+ e.mergepoint = 'HEAD'
+ else:
+ myrev = '.'.join(myrev[:-2] + ['0', myrev[-2]])
+ branches = [b for b in branchmap if branchmap[b] == myrev]
+ assert len(branches) == 1, 'unknown branch: %s' % e.mergepoint
+ e.mergepoint = branches[0]
+ else:
+ e.mergepoint = None
+ e.comment = []
+ state = 7
+
+ elif state == 7:
+ # read the revision numbers of branches that start at this revision
+ # or store the commit log message otherwise
+ m = re_70.match(line)
+ if m:
+ e.branches = [tuple([int(y) for y in x.strip().split('.')])
+ for x in m.group(1).split(';')]
+ state = 8
+ elif re_31.match(line) and re_50.match(peek):
+ state = 5
+ store = True
+ elif re_32.match(line):
+ state = 0
+ store = True
+ else:
+ e.comment.append(line)
+
+ elif state == 8:
+ # store commit log message
+ if re_31.match(line):
+ state = 5
+ store = True
+ elif re_32.match(line):
+ state = 0
+ store = True
+ else:
+ e.comment.append(line)
+
+ # When a file is added on a branch B1, CVS creates a synthetic
+ # dead trunk revision 1.1 so that the branch has a root.
+ # Likewise, if you merge such a file to a later branch B2 (one
+ # that already existed when the file was added on B1), CVS
+ # creates a synthetic dead revision 1.1.x.1 on B2. Don't drop
+ # these revisions now, but mark them synthetic so
+ # createchangeset() can take care of them.
+ if (store and
+ e.dead and
+ e.revision[-1] == 1 and # 1.1 or 1.1.x.1
+ len(e.comment) == 1 and
+ file_added_re.match(e.comment[0])):
+ ui.debug(_('found synthetic revision in %s: %r\n')
+ % (e.rcs, e.comment[0]))
+ e.synthetic = True
+
+ if store:
+ # clean up the results and save in the log.
+ store = False
+ e.tags = sorted([scache(x) for x in tags.get(e.revision, [])])
+ e.comment = scache('\n'.join(e.comment))
+
+ revn = len(e.revision)
+ if revn > 3 and (revn % 2) == 0:
+ e.branch = tags.get(e.revision[:-1], [None])[0]
+ else:
+ e.branch = None
+
+ # find the branches starting from this revision
+ branchpoints = set()
+ for branch, revision in branchmap.iteritems():
+ revparts = tuple([int(i) for i in revision.split('.')])
+ if revparts[-2] == 0 and revparts[-1] % 2 == 0:
+ # normal branch
+ if revparts[:-2] == e.revision:
+ branchpoints.add(branch)
+ elif revparts == (1,1,1): # vendor branch
+ if revparts in e.branches:
+ branchpoints.add(branch)
+ e.branchpoints = branchpoints
+
+ log.append(e)
+
+ if len(log) % 100 == 0:
+ ui.status(util.ellipsis('%d %s' % (len(log), e.file), 80)+'\n')
+
+ log.sort(key=lambda x: (x.rcs, x.revision))
+
+ # find parent revisions of individual files
+ versions = {}
+ for e in log:
+ branch = e.revision[:-1]
+ p = versions.get((e.rcs, branch), None)
+ if p is None:
+ p = e.revision[:-2]
+ e.parent = p
+ versions[(e.rcs, branch)] = e.revision
+
+ # update the log cache
+ if cache:
+ if log:
+ # join up the old and new logs
+ log.sort(key=lambda x: x.date)
+
+ if oldlog and oldlog[-1].date >= log[0].date:
+ raise logerror('Log cache overlaps with new log entries,'
+ ' re-run without cache.')
+
+ log = oldlog + log
+
+ # write the new cachefile
+ ui.note(_('writing cvs log cache %s\n') % cachefile)
+ pickle.dump(log, open(cachefile, 'w'))
+ else:
+ log = oldlog
+
+ ui.status(_('%d log entries\n') % len(log))
+
+ return log
+
+
+class changeset(object):
+ '''Class changeset has the following attributes:
+ .id - integer identifying this changeset (list index)
+ .author - author name as CVS knows it
+ .branch - name of branch this changeset is on, or None
+ .comment - commit message
+ .date - the commit date as a (time,tz) tuple
+ .entries - list of logentry objects in this changeset
+ .parents - list of one or two parent changesets
+ .tags - list of tags on this changeset
+ .synthetic - from synthetic revision "file ... added on branch ..."
+ .mergepoint- the branch that has been merged from
+ (if present in rlog output)
+ .branchpoints- the branches that start at the current entry
+ '''
+ def __init__(self, **entries):
+ self.__dict__.update(entries)
+
+ def __repr__(self):
+ return "<%s at 0x%x: %s>" % (self.__class__.__name__,
+ id(self),
+ getattr(self, 'id', "(no id)"))
+
+def createchangeset(ui, log, fuzz=60, mergefrom=None, mergeto=None):
+ '''Convert log into changesets.'''
+
+ ui.status(_('creating changesets\n'))
+
+ # Merge changesets
+
+ log.sort(key=lambda x: (x.comment, x.author, x.branch, x.date))
+
+ changesets = []
+ files = set()
+ c = None
+ for i, e in enumerate(log):
+
+ # Check if log entry belongs to the current changeset or not.
+
+ # Since CVS is file centric, two different file revisions with
+ # different branchpoints should be treated as belonging to two
+ # different changesets (and the ordering is important and not
+ # honoured by cvsps at this point).
+ #
+ # Consider the following case:
+ # foo 1.1 branchpoints: [MYBRANCH]
+ # bar 1.1 branchpoints: [MYBRANCH, MYBRANCH2]
+ #
+ # Here foo is part only of MYBRANCH, but not MYBRANCH2, e.g. a
+ # later version of foo may be in MYBRANCH2, so foo should be the
+ # first changeset and bar the next and MYBRANCH and MYBRANCH2
+ # should both start off of the bar changeset. No provisions are
+ # made to ensure that this is, in fact, what happens.
+ if not (c and
+ e.comment == c.comment and
+ e.author == c.author and
+ e.branch == c.branch and
+ (not hasattr(e, 'branchpoints') or
+ not hasattr (c, 'branchpoints') or
+ e.branchpoints == c.branchpoints) and
+ ((c.date[0] + c.date[1]) <=
+ (e.date[0] + e.date[1]) <=
+ (c.date[0] + c.date[1]) + fuzz) and
+ e.file not in files):
+ c = changeset(comment=e.comment, author=e.author,
+ branch=e.branch, date=e.date, entries=[],
+ mergepoint=getattr(e, 'mergepoint', None),
+ branchpoints=getattr(e, 'branchpoints', set()))
+ changesets.append(c)
+ files = set()
+ if len(changesets) % 100 == 0:
+ t = '%d %s' % (len(changesets), repr(e.comment)[1:-1])
+ ui.status(util.ellipsis(t, 80) + '\n')
+
+ c.entries.append(e)
+ files.add(e.file)
+ c.date = e.date # changeset date is date of latest commit in it
+
+ # Mark synthetic changesets
+
+ for c in changesets:
+ # Synthetic revisions always get their own changeset, because
+ # the log message includes the filename. E.g. if you add file3
+ # and file4 on a branch, you get four log entries and three
+ # changesets:
+ # "File file3 was added on branch ..." (synthetic, 1 entry)
+ # "File file4 was added on branch ..." (synthetic, 1 entry)
+ # "Add file3 and file4 to fix ..." (real, 2 entries)
+ # Hence the check for 1 entry here.
+ synth = getattr(c.entries[0], 'synthetic', None)
+ c.synthetic = (len(c.entries) == 1 and synth)
+
+ # Sort files in each changeset
+
+ for c in changesets:
+ def pathcompare(l, r):
+ 'Mimic cvsps sorting order'
+ l = l.split('/')
+ r = r.split('/')
+ nl = len(l)
+ nr = len(r)
+ n = min(nl, nr)
+ for i in range(n):
+ if i + 1 == nl and nl < nr:
+ return -1
+ elif i + 1 == nr and nl > nr:
+ return +1
+ elif l[i] < r[i]:
+ return -1
+ elif l[i] > r[i]:
+ return +1
+ return 0
+ def entitycompare(l, r):
+ return pathcompare(l.file, r.file)
+
+ c.entries.sort(entitycompare)
+
+ # Sort changesets by date
+
+ def cscmp(l, r):
+ d = sum(l.date) - sum(r.date)
+ if d:
+ return d
+
+ # detect vendor branches and initial commits on a branch
+ le = {}
+ for e in l.entries:
+ le[e.rcs] = e.revision
+ re = {}
+ for e in r.entries:
+ re[e.rcs] = e.revision
+
+ d = 0
+ for e in l.entries:
+ if re.get(e.rcs, None) == e.parent:
+ assert not d
+ d = 1
+ break
+
+ for e in r.entries:
+ if le.get(e.rcs, None) == e.parent:
+ assert not d
+ d = -1
+ break
+
+ return d
+
+ changesets.sort(cscmp)
+
+ # Collect tags
+
+ globaltags = {}
+ for c in changesets:
+ for e in c.entries:
+ for tag in e.tags:
+ # remember which is the latest changeset to have this tag
+ globaltags[tag] = c
+
+ for c in changesets:
+ tags = set()
+ for e in c.entries:
+ tags.update(e.tags)
+ # remember tags only if this is the latest changeset to have it
+ c.tags = sorted(tag for tag in tags if globaltags[tag] is c)
+
+ # Find parent changesets, handle {{mergetobranch BRANCHNAME}}
+ # by inserting dummy changesets with two parents, and handle
+ # {{mergefrombranch BRANCHNAME}} by setting two parents.
+
+ if mergeto is None:
+ mergeto = r'{{mergetobranch ([-\w]+)}}'
+ if mergeto:
+ mergeto = re.compile(mergeto)
+
+ if mergefrom is None:
+ mergefrom = r'{{mergefrombranch ([-\w]+)}}'
+ if mergefrom:
+ mergefrom = re.compile(mergefrom)
+
+ versions = {} # changeset index where we saw any particular file version
+ branches = {} # changeset index where we saw a branch
+ n = len(changesets)
+ i = 0
+ while i<n:
+ c = changesets[i]
+
+ for f in c.entries:
+ versions[(f.rcs, f.revision)] = i
+
+ p = None
+ if c.branch in branches:
+ p = branches[c.branch]
+ else:
+ # first changeset on a new branch
+ # the parent is a changeset with the branch in its
+ # branchpoints such that it is the latest possible
+ # commit without any intervening, unrelated commits.
+
+ for candidate in xrange(i):
+ if c.branch not in changesets[candidate].branchpoints:
+ if p is not None:
+ break
+ continue
+ p = candidate
+
+ c.parents = []
+ if p is not None:
+ p = changesets[p]
+
+ # Ensure no changeset has a synthetic changeset as a parent.
+ while p.synthetic:
+ assert len(p.parents) <= 1, \
+ _('synthetic changeset cannot have multiple parents')
+ if p.parents:
+ p = p.parents[0]
+ else:
+ p = None
+ break
+
+ if p is not None:
+ c.parents.append(p)
+
+ if c.mergepoint:
+ if c.mergepoint == 'HEAD':
+ c.mergepoint = None
+ c.parents.append(changesets[branches[c.mergepoint]])
+
+ if mergefrom:
+ m = mergefrom.search(c.comment)
+ if m:
+ m = m.group(1)
+ if m == 'HEAD':
+ m = None
+ try:
+ candidate = changesets[branches[m]]
+ except KeyError:
+ ui.warn(_("warning: CVS commit message references "
+ "non-existent branch %r:\n%s\n")
+ % (m, c.comment))
+ if m in branches and c.branch != m and not candidate.synthetic:
+ c.parents.append(candidate)
+
+ if mergeto:
+ m = mergeto.search(c.comment)
+ if m:
+ try:
+ m = m.group(1)
+ if m == 'HEAD':
+ m = None
+ except:
+ m = None # if no group found then merge to HEAD
+ if m in branches and c.branch != m:
+ # insert empty changeset for merge
+ cc = changeset(author=c.author, branch=m, date=c.date,
+ comment='convert-repo: CVS merge from branch %s' % c.branch,
+ entries=[], tags=[], parents=[changesets[branches[m]], c])
+ changesets.insert(i + 1, cc)
+ branches[m] = i + 1
+
+ # adjust our loop counters now we have inserted a new entry
+ n += 1
+ i += 2
+ continue
+
+ branches[c.branch] = i
+ i += 1
+
+ # Drop synthetic changesets (safe now that we have ensured no other
+ # changesets can have them as parents).
+ i = 0
+ while i < len(changesets):
+ if changesets[i].synthetic:
+ del changesets[i]
+ else:
+ i += 1
+
+ # Number changesets
+
+ for i, c in enumerate(changesets):
+ c.id = i + 1
+
+ ui.status(_('%d changeset entries\n') % len(changesets))
+
+ return changesets
+
+
+def debugcvsps(ui, *args, **opts):
+ '''Read CVS rlog for current directory or named path in
+ repository, and convert the log to changesets based on matching
+ commit log entries and dates.
+ '''
+ if opts["new_cache"]:
+ cache = "write"
+ elif opts["update_cache"]:
+ cache = "update"
+ else:
+ cache = None
+
+ revisions = opts["revisions"]
+
+ try:
+ if args:
+ log = []
+ for d in args:
+ log += createlog(ui, d, root=opts["root"], cache=cache)
+ else:
+ log = createlog(ui, root=opts["root"], cache=cache)
+ except logerror, e:
+ ui.write("%r\n"%e)
+ return
+
+ changesets = createchangeset(ui, log, opts["fuzz"])
+ del log
+
+ # Print changesets (optionally filtered)
+
+ off = len(revisions)
+ branches = {} # latest version number in each branch
+ ancestors = {} # parent branch
+ for cs in changesets:
+
+ if opts["ancestors"]:
+ if cs.branch not in branches and cs.parents and cs.parents[0].id:
+ ancestors[cs.branch] = (changesets[cs.parents[0].id-1].branch,
+ cs.parents[0].id)
+ branches[cs.branch] = cs.id
+
+ # limit by branches
+ if opts["branches"] and (cs.branch or 'HEAD') not in opts["branches"]:
+ continue
+
+ if not off:
+ # Note: trailing spaces on several lines here are needed to have
+ # bug-for-bug compatibility with cvsps.
+ ui.write('---------------------\n')
+ ui.write('PatchSet %d \n' % cs.id)
+ ui.write('Date: %s\n' % util.datestr(cs.date,
+ '%Y/%m/%d %H:%M:%S %1%2'))
+ ui.write('Author: %s\n' % cs.author)
+ ui.write('Branch: %s\n' % (cs.branch or 'HEAD'))
+ ui.write('Tag%s: %s \n' % (['', 's'][len(cs.tags)>1],
+ ','.join(cs.tags) or '(none)'))
+ branchpoints = getattr(cs, 'branchpoints', None)
+ if branchpoints:
+ ui.write('Branchpoints: %s \n' % ', '.join(branchpoints))
+ if opts["parents"] and cs.parents:
+ if len(cs.parents)>1:
+ ui.write('Parents: %s\n' % (','.join([str(p.id) for p in cs.parents])))
+ else:
+ ui.write('Parent: %d\n' % cs.parents[0].id)
+
+ if opts["ancestors"]:
+ b = cs.branch
+ r = []
+ while b:
+ b, c = ancestors[b]
+ r.append('%s:%d:%d' % (b or "HEAD", c, branches[b]))
+ if r:
+ ui.write('Ancestors: %s\n' % (','.join(r)))
+
+ ui.write('Log:\n')
+ ui.write('%s\n\n' % cs.comment)
+ ui.write('Members: \n')
+ for f in cs.entries:
+ fn = f.file
+ if fn.startswith(opts["prefix"]):
+ fn = fn[len(opts["prefix"]):]
+ ui.write('\t%s:%s->%s%s \n' % (fn, '.'.join([str(x) for x in f.parent]) or 'INITIAL',
+ '.'.join([str(x) for x in f.revision]), ['', '(DEAD)'][f.dead]))
+ ui.write('\n')
+
+ # have we seen the start tag?
+ if revisions and off:
+ if revisions[0] == str(cs.id) or \
+ revisions[0] in cs.tags:
+ off = False
+
+ # see if we reached the end tag
+ if len(revisions)>1 and not off:
+ if revisions[1] == str(cs.id) or \
+ revisions[1] in cs.tags:
+ break
diff --git a/sys/src/cmd/hg/hgext/convert/darcs.py b/sys/src/cmd/hg/hgext/convert/darcs.py
new file mode 100644
index 000000000..fd51f38bd
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/darcs.py
@@ -0,0 +1,135 @@
+# darcs.py - darcs support for the convert extension
+#
+# Copyright 2007-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from common import NoRepo, checktool, commandline, commit, converter_source
+from mercurial.i18n import _
+from mercurial import util
+import os, shutil, tempfile
+
+# The naming drift of ElementTree is fun!
+
+try: from xml.etree.cElementTree import ElementTree
+except ImportError:
+ try: from xml.etree.ElementTree import ElementTree
+ except ImportError:
+ try: from elementtree.cElementTree import ElementTree
+ except ImportError:
+ try: from elementtree.ElementTree import ElementTree
+ except ImportError: ElementTree = None
+
+
+class darcs_source(converter_source, commandline):
+ def __init__(self, ui, path, rev=None):
+ converter_source.__init__(self, ui, path, rev=rev)
+ commandline.__init__(self, ui, 'darcs')
+
+ # check for _darcs, ElementTree, _darcs/inventory so that we can
+ # easily skip test-convert-darcs if ElementTree is not around
+ if not os.path.exists(os.path.join(path, '_darcs', 'inventories')):
+ raise NoRepo("%s does not look like a darcs repo" % path)
+
+ if not os.path.exists(os.path.join(path, '_darcs')):
+ raise NoRepo("%s does not look like a darcs repo" % path)
+
+ checktool('darcs')
+ version = self.run0('--version').splitlines()[0].strip()
+ if version < '2.1':
+ raise util.Abort(_('darcs version 2.1 or newer needed (found %r)') %
+ version)
+
+ if ElementTree is None:
+ raise util.Abort(_("Python ElementTree module is not available"))
+
+ self.path = os.path.realpath(path)
+
+ self.lastrev = None
+ self.changes = {}
+ self.parents = {}
+ self.tags = {}
+
+ def before(self):
+ self.tmppath = tempfile.mkdtemp(
+ prefix='convert-' + os.path.basename(self.path) + '-')
+ output, status = self.run('init', repodir=self.tmppath)
+ self.checkexit(status)
+
+ tree = self.xml('changes', xml_output=True, summary=True,
+ repodir=self.path)
+ tagname = None
+ child = None
+ for elt in tree.findall('patch'):
+ node = elt.get('hash')
+ name = elt.findtext('name', '')
+ if name.startswith('TAG '):
+ tagname = name[4:].strip()
+ elif tagname is not None:
+ self.tags[tagname] = node
+ tagname = None
+ self.changes[node] = elt
+ self.parents[child] = [node]
+ child = node
+ self.parents[child] = []
+
+ def after(self):
+ self.ui.debug(_('cleaning up %s\n') % self.tmppath)
+ shutil.rmtree(self.tmppath, ignore_errors=True)
+
+ def xml(self, cmd, **kwargs):
+ etree = ElementTree()
+ fp = self._run(cmd, **kwargs)
+ etree.parse(fp)
+ self.checkexit(fp.close())
+ return etree.getroot()
+
+ def getheads(self):
+ return self.parents[None]
+
+ def getcommit(self, rev):
+ elt = self.changes[rev]
+ date = util.strdate(elt.get('local_date'), '%a %b %d %H:%M:%S %Z %Y')
+ desc = elt.findtext('name') + '\n' + elt.findtext('comment', '')
+ return commit(author=elt.get('author'), date=util.datestr(date),
+ desc=desc.strip(), parents=self.parents[rev])
+
+ def pull(self, rev):
+ output, status = self.run('pull', self.path, all=True,
+ match='hash %s' % rev,
+ no_test=True, no_posthook=True,
+ external_merge='/bin/false',
+ repodir=self.tmppath)
+ if status:
+ if output.find('We have conflicts in') == -1:
+ self.checkexit(status, output)
+ output, status = self.run('revert', all=True, repodir=self.tmppath)
+ self.checkexit(status, output)
+
+ def getchanges(self, rev):
+ self.pull(rev)
+ copies = {}
+ changes = []
+ for elt in self.changes[rev].find('summary').getchildren():
+ if elt.tag in ('add_directory', 'remove_directory'):
+ continue
+ if elt.tag == 'move':
+ changes.append((elt.get('from'), rev))
+ copies[elt.get('from')] = elt.get('to')
+ else:
+ changes.append((elt.text.strip(), rev))
+ self.lastrev = rev
+ return sorted(changes), copies
+
+ def getfile(self, name, rev):
+ if rev != self.lastrev:
+ raise util.Abort(_('internal calling inconsistency'))
+ return open(os.path.join(self.tmppath, name), 'rb').read()
+
+ def getmode(self, name, rev):
+ mode = os.lstat(os.path.join(self.tmppath, name)).st_mode
+ return (mode & 0111) and 'x' or ''
+
+ def gettags(self):
+ return self.tags
diff --git a/sys/src/cmd/hg/hgext/convert/filemap.py b/sys/src/cmd/hg/hgext/convert/filemap.py
new file mode 100644
index 000000000..3c8307ae8
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/filemap.py
@@ -0,0 +1,359 @@
+# Copyright 2007 Bryan O'Sullivan <bos@serpentine.com>
+# Copyright 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import shlex
+from mercurial.i18n import _
+from mercurial import util
+from common import SKIPREV, converter_source
+
+def rpairs(name):
+ yield '.', name
+ e = len(name)
+ while e != -1:
+ yield name[:e], name[e+1:]
+ e = name.rfind('/', 0, e)
+
+class filemapper(object):
+ '''Map and filter filenames when importing.
+ A name can be mapped to itself, a new name, or None (omit from new
+ repository).'''
+
+ def __init__(self, ui, path=None):
+ self.ui = ui
+ self.include = {}
+ self.exclude = {}
+ self.rename = {}
+ if path:
+ if self.parse(path):
+ raise util.Abort(_('errors in filemap'))
+
+ def parse(self, path):
+ errs = 0
+ def check(name, mapping, listname):
+ if name in mapping:
+ self.ui.warn(_('%s:%d: %r already in %s list\n') %
+ (lex.infile, lex.lineno, name, listname))
+ return 1
+ return 0
+ lex = shlex.shlex(open(path), path, True)
+ lex.wordchars += '!@#$%^&*()-=+[]{}|;:,./<>?'
+ cmd = lex.get_token()
+ while cmd:
+ if cmd == 'include':
+ name = lex.get_token()
+ errs += check(name, self.exclude, 'exclude')
+ self.include[name] = name
+ elif cmd == 'exclude':
+ name = lex.get_token()
+ errs += check(name, self.include, 'include')
+ errs += check(name, self.rename, 'rename')
+ self.exclude[name] = name
+ elif cmd == 'rename':
+ src = lex.get_token()
+ dest = lex.get_token()
+ errs += check(src, self.exclude, 'exclude')
+ self.rename[src] = dest
+ elif cmd == 'source':
+ errs += self.parse(lex.get_token())
+ else:
+ self.ui.warn(_('%s:%d: unknown directive %r\n') %
+ (lex.infile, lex.lineno, cmd))
+ errs += 1
+ cmd = lex.get_token()
+ return errs
+
+ def lookup(self, name, mapping):
+ for pre, suf in rpairs(name):
+ try:
+ return mapping[pre], pre, suf
+ except KeyError:
+ pass
+ return '', name, ''
+
+ def __call__(self, name):
+ if self.include:
+ inc = self.lookup(name, self.include)[0]
+ else:
+ inc = name
+ if self.exclude:
+ exc = self.lookup(name, self.exclude)[0]
+ else:
+ exc = ''
+ if not inc or exc:
+ return None
+ newpre, pre, suf = self.lookup(name, self.rename)
+ if newpre:
+ if newpre == '.':
+ return suf
+ if suf:
+ return newpre + '/' + suf
+ return newpre
+ return name
+
+ def active(self):
+ return bool(self.include or self.exclude or self.rename)
+
+# This class does two additional things compared to a regular source:
+#
+# - Filter and rename files. This is mostly wrapped by the filemapper
+# class above. We hide the original filename in the revision that is
+# returned by getchanges to be able to find things later in getfile
+# and getmode.
+#
+# - Return only revisions that matter for the files we're interested in.
+# This involves rewriting the parents of the original revision to
+# create a graph that is restricted to those revisions.
+#
+# This set of revisions includes not only revisions that directly
+# touch files we're interested in, but also merges that merge two
+# or more interesting revisions.
+
+class filemap_source(converter_source):
+ def __init__(self, ui, baseconverter, filemap):
+ super(filemap_source, self).__init__(ui)
+ self.base = baseconverter
+ self.filemapper = filemapper(ui, filemap)
+ self.commits = {}
+ # if a revision rev has parent p in the original revision graph, then
+ # rev will have parent self.parentmap[p] in the restricted graph.
+ self.parentmap = {}
+ # self.wantedancestors[rev] is the set of all ancestors of rev that
+ # are in the restricted graph.
+ self.wantedancestors = {}
+ self.convertedorder = None
+ self._rebuilt = False
+ self.origparents = {}
+ self.children = {}
+ self.seenchildren = {}
+
+ def before(self):
+ self.base.before()
+
+ def after(self):
+ self.base.after()
+
+ def setrevmap(self, revmap):
+ # rebuild our state to make things restartable
+ #
+ # To avoid calling getcommit for every revision that has already
+ # been converted, we rebuild only the parentmap, delaying the
+ # rebuild of wantedancestors until we need it (i.e. until a
+ # merge).
+ #
+ # We assume the order argument lists the revisions in
+ # topological order, so that we can infer which revisions were
+ # wanted by previous runs.
+ self._rebuilt = not revmap
+ seen = {SKIPREV: SKIPREV}
+ dummyset = set()
+ converted = []
+ for rev in revmap.order:
+ mapped = revmap[rev]
+ wanted = mapped not in seen
+ if wanted:
+ seen[mapped] = rev
+ self.parentmap[rev] = rev
+ else:
+ self.parentmap[rev] = seen[mapped]
+ self.wantedancestors[rev] = dummyset
+ arg = seen[mapped]
+ if arg == SKIPREV:
+ arg = None
+ converted.append((rev, wanted, arg))
+ self.convertedorder = converted
+ return self.base.setrevmap(revmap)
+
+ def rebuild(self):
+ if self._rebuilt:
+ return True
+ self._rebuilt = True
+ self.parentmap.clear()
+ self.wantedancestors.clear()
+ self.seenchildren.clear()
+ for rev, wanted, arg in self.convertedorder:
+ if rev not in self.origparents:
+ self.origparents[rev] = self.getcommit(rev).parents
+ if arg is not None:
+ self.children[arg] = self.children.get(arg, 0) + 1
+
+ for rev, wanted, arg in self.convertedorder:
+ parents = self.origparents[rev]
+ if wanted:
+ self.mark_wanted(rev, parents)
+ else:
+ self.mark_not_wanted(rev, arg)
+ self._discard(arg, *parents)
+
+ return True
+
+ def getheads(self):
+ return self.base.getheads()
+
+ def getcommit(self, rev):
+ # We want to save a reference to the commit objects to be able
+ # to rewrite their parents later on.
+ c = self.commits[rev] = self.base.getcommit(rev)
+ for p in c.parents:
+ self.children[p] = self.children.get(p, 0) + 1
+ return c
+
+ def _discard(self, *revs):
+ for r in revs:
+ if r is None:
+ continue
+ self.seenchildren[r] = self.seenchildren.get(r, 0) + 1
+ if self.seenchildren[r] == self.children[r]:
+ del self.wantedancestors[r]
+ del self.parentmap[r]
+ del self.seenchildren[r]
+ if self._rebuilt:
+ del self.children[r]
+
+ def wanted(self, rev, i):
+ # Return True if we're directly interested in rev.
+ #
+ # i is an index selecting one of the parents of rev (if rev
+ # has no parents, i is None). getchangedfiles will give us
+ # the list of files that are different in rev and in the parent
+ # indicated by i. If we're interested in any of these files,
+ # we're interested in rev.
+ try:
+ files = self.base.getchangedfiles(rev, i)
+ except NotImplementedError:
+ raise util.Abort(_("source repository doesn't support --filemap"))
+ for f in files:
+ if self.filemapper(f):
+ return True
+ return False
+
+ def mark_not_wanted(self, rev, p):
+ # Mark rev as not interesting and update data structures.
+
+ if p is None:
+ # A root revision. Use SKIPREV to indicate that it doesn't
+ # map to any revision in the restricted graph. Put SKIPREV
+ # in the set of wanted ancestors to simplify code elsewhere
+ self.parentmap[rev] = SKIPREV
+ self.wantedancestors[rev] = set((SKIPREV,))
+ return
+
+ # Reuse the data from our parent.
+ self.parentmap[rev] = self.parentmap[p]
+ self.wantedancestors[rev] = self.wantedancestors[p]
+
+ def mark_wanted(self, rev, parents):
+ # Mark rev ss wanted and update data structures.
+
+ # rev will be in the restricted graph, so children of rev in
+ # the original graph should still have rev as a parent in the
+ # restricted graph.
+ self.parentmap[rev] = rev
+
+ # The set of wanted ancestors of rev is the union of the sets
+ # of wanted ancestors of its parents. Plus rev itself.
+ wrev = set()
+ for p in parents:
+ wrev.update(self.wantedancestors[p])
+ wrev.add(rev)
+ self.wantedancestors[rev] = wrev
+
+ def getchanges(self, rev):
+ parents = self.commits[rev].parents
+ if len(parents) > 1:
+ self.rebuild()
+
+ # To decide whether we're interested in rev we:
+ #
+ # - calculate what parents rev will have if it turns out we're
+ # interested in it. If it's going to have more than 1 parent,
+ # we're interested in it.
+ #
+ # - otherwise, we'll compare it with the single parent we found.
+ # If any of the files we're interested in is different in the
+ # the two revisions, we're interested in rev.
+
+ # A parent p is interesting if its mapped version (self.parentmap[p]):
+ # - is not SKIPREV
+ # - is still not in the list of parents (we don't want duplicates)
+ # - is not an ancestor of the mapped versions of the other parents
+ mparents = []
+ wp = None
+ for i, p1 in enumerate(parents):
+ mp1 = self.parentmap[p1]
+ if mp1 == SKIPREV or mp1 in mparents:
+ continue
+ for p2 in parents:
+ if p1 == p2 or mp1 == self.parentmap[p2]:
+ continue
+ if mp1 in self.wantedancestors[p2]:
+ break
+ else:
+ mparents.append(mp1)
+ wp = i
+
+ if wp is None and parents:
+ wp = 0
+
+ self.origparents[rev] = parents
+
+ if len(mparents) < 2 and not self.wanted(rev, wp):
+ # We don't want this revision.
+ # Update our state and tell the convert process to map this
+ # revision to the same revision its parent as mapped to.
+ p = None
+ if parents:
+ p = parents[wp]
+ self.mark_not_wanted(rev, p)
+ self.convertedorder.append((rev, False, p))
+ self._discard(*parents)
+ return self.parentmap[rev]
+
+ # We want this revision.
+ # Rewrite the parents of the commit object
+ self.commits[rev].parents = mparents
+ self.mark_wanted(rev, parents)
+ self.convertedorder.append((rev, True, None))
+ self._discard(*parents)
+
+ # Get the real changes and do the filtering/mapping.
+ # To be able to get the files later on in getfile and getmode,
+ # we hide the original filename in the rev part of the return
+ # value.
+ changes, copies = self.base.getchanges(rev)
+ newnames = {}
+ files = []
+ for f, r in changes:
+ newf = self.filemapper(f)
+ if newf:
+ files.append((newf, (f, r)))
+ newnames[f] = newf
+
+ ncopies = {}
+ for c in copies:
+ newc = self.filemapper(c)
+ if newc:
+ newsource = self.filemapper(copies[c])
+ if newsource:
+ ncopies[newc] = newsource
+
+ return files, ncopies
+
+ def getfile(self, name, rev):
+ realname, realrev = rev
+ return self.base.getfile(realname, realrev)
+
+ def getmode(self, name, rev):
+ realname, realrev = rev
+ return self.base.getmode(realname, realrev)
+
+ def gettags(self):
+ return self.base.gettags()
+
+ def hasnativeorder(self):
+ return self.base.hasnativeorder()
+
+ def lookuprev(self, rev):
+ return self.base.lookuprev(rev)
diff --git a/sys/src/cmd/hg/hgext/convert/git.py b/sys/src/cmd/hg/hgext/convert/git.py
new file mode 100644
index 000000000..d529744ac
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/git.py
@@ -0,0 +1,152 @@
+# git.py - git support for the convert extension
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os
+from mercurial import util
+
+from common import NoRepo, commit, converter_source, checktool
+
+class convert_git(converter_source):
+ # Windows does not support GIT_DIR= construct while other systems
+ # cannot remove environment variable. Just assume none have
+ # both issues.
+ if hasattr(os, 'unsetenv'):
+ def gitcmd(self, s):
+ prevgitdir = os.environ.get('GIT_DIR')
+ os.environ['GIT_DIR'] = self.path
+ try:
+ return util.popen(s, 'rb')
+ finally:
+ if prevgitdir is None:
+ del os.environ['GIT_DIR']
+ else:
+ os.environ['GIT_DIR'] = prevgitdir
+ else:
+ def gitcmd(self, s):
+ return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
+
+ def __init__(self, ui, path, rev=None):
+ super(convert_git, self).__init__(ui, path, rev=rev)
+
+ if os.path.isdir(path + "/.git"):
+ path += "/.git"
+ if not os.path.exists(path + "/objects"):
+ raise NoRepo("%s does not look like a Git repo" % path)
+
+ checktool('git', 'git')
+
+ self.path = path
+
+ def getheads(self):
+ if not self.rev:
+ return self.gitcmd('git rev-parse --branches --remotes').read().splitlines()
+ else:
+ fh = self.gitcmd("git rev-parse --verify %s" % self.rev)
+ return [fh.read()[:-1]]
+
+ def catfile(self, rev, type):
+ if rev == "0" * 40: raise IOError()
+ fh = self.gitcmd("git cat-file %s %s" % (type, rev))
+ return fh.read()
+
+ def getfile(self, name, rev):
+ return self.catfile(rev, "blob")
+
+ def getmode(self, name, rev):
+ return self.modecache[(name, rev)]
+
+ def getchanges(self, version):
+ self.modecache = {}
+ fh = self.gitcmd("git diff-tree -z --root -m -r %s" % version)
+ changes = []
+ seen = set()
+ entry = None
+ for l in fh.read().split('\x00'):
+ if not entry:
+ if not l.startswith(':'):
+ continue
+ entry = l
+ continue
+ f = l
+ if f not in seen:
+ seen.add(f)
+ entry = entry.split()
+ h = entry[3]
+ p = (entry[1] == "100755")
+ s = (entry[1] == "120000")
+ self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
+ changes.append((f, h))
+ entry = None
+ return (changes, {})
+
+ def getcommit(self, version):
+ c = self.catfile(version, "commit") # read the commit hash
+ end = c.find("\n\n")
+ message = c[end+2:]
+ message = self.recode(message)
+ l = c[:end].splitlines()
+ parents = []
+ author = committer = None
+ for e in l[1:]:
+ n, v = e.split(" ", 1)
+ if n == "author":
+ p = v.split()
+ tm, tz = p[-2:]
+ author = " ".join(p[:-2])
+ if author[0] == "<": author = author[1:-1]
+ author = self.recode(author)
+ if n == "committer":
+ p = v.split()
+ tm, tz = p[-2:]
+ committer = " ".join(p[:-2])
+ if committer[0] == "<": committer = committer[1:-1]
+ committer = self.recode(committer)
+ if n == "parent": parents.append(v)
+
+ if committer and committer != author:
+ message += "\ncommitter: %s\n" % committer
+ tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
+ tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
+ date = tm + " " + str(tz)
+
+ c = commit(parents=parents, date=date, author=author, desc=message,
+ rev=version)
+ return c
+
+ def gettags(self):
+ tags = {}
+ fh = self.gitcmd('git ls-remote --tags "%s"' % self.path)
+ prefix = 'refs/tags/'
+ for line in fh:
+ line = line.strip()
+ if not line.endswith("^{}"):
+ continue
+ node, tag = line.split(None, 1)
+ if not tag.startswith(prefix):
+ continue
+ tag = tag[len(prefix):-3]
+ tags[tag] = node
+
+ return tags
+
+ def getchangedfiles(self, version, i):
+ changes = []
+ if i is None:
+ fh = self.gitcmd("git diff-tree --root -m -r %s" % version)
+ for l in fh:
+ if "\t" not in l:
+ continue
+ m, f = l[:-1].split("\t")
+ changes.append(f)
+ fh.close()
+ else:
+ fh = self.gitcmd('git diff-tree --name-only --root -r %s "%s^%s" --'
+ % (version, version, i+1))
+ changes = [f.rstrip('\n') for f in fh]
+ fh.close()
+
+ return changes
diff --git a/sys/src/cmd/hg/hgext/convert/gnuarch.py b/sys/src/cmd/hg/hgext/convert/gnuarch.py
new file mode 100644
index 000000000..8d2475e18
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/gnuarch.py
@@ -0,0 +1,342 @@
+# gnuarch.py - GNU Arch support for the convert extension
+#
+# Copyright 2008, 2009 Aleix Conchillo Flaque <aleix@member.fsf.org>
+# and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from common import NoRepo, commandline, commit, converter_source
+from mercurial.i18n import _
+from mercurial import util
+import os, shutil, tempfile, stat, locale
+from email.Parser import Parser
+
+class gnuarch_source(converter_source, commandline):
+
+ class gnuarch_rev(object):
+ def __init__(self, rev):
+ self.rev = rev
+ self.summary = ''
+ self.date = None
+ self.author = ''
+ self.continuationof = None
+ self.add_files = []
+ self.mod_files = []
+ self.del_files = []
+ self.ren_files = {}
+ self.ren_dirs = {}
+
+ def __init__(self, ui, path, rev=None):
+ super(gnuarch_source, self).__init__(ui, path, rev=rev)
+
+ if not os.path.exists(os.path.join(path, '{arch}')):
+ raise NoRepo(_("%s does not look like a GNU Arch repo") % path)
+
+ # Could use checktool, but we want to check for baz or tla.
+ self.execmd = None
+ if util.find_exe('baz'):
+ self.execmd = 'baz'
+ else:
+ if util.find_exe('tla'):
+ self.execmd = 'tla'
+ else:
+ raise util.Abort(_('cannot find a GNU Arch tool'))
+
+ commandline.__init__(self, ui, self.execmd)
+
+ self.path = os.path.realpath(path)
+ self.tmppath = None
+
+ self.treeversion = None
+ self.lastrev = None
+ self.changes = {}
+ self.parents = {}
+ self.tags = {}
+ self.modecache = {}
+ self.catlogparser = Parser()
+ self.locale = locale.getpreferredencoding()
+ self.archives = []
+
+ def before(self):
+ # Get registered archives
+ self.archives = [i.rstrip('\n')
+ for i in self.runlines0('archives', '-n')]
+
+ if self.execmd == 'tla':
+ output = self.run0('tree-version', self.path)
+ else:
+ output = self.run0('tree-version', '-d', self.path)
+ self.treeversion = output.strip()
+
+ # Get name of temporary directory
+ version = self.treeversion.split('/')
+ self.tmppath = os.path.join(tempfile.gettempdir(),
+ 'hg-%s' % version[1])
+
+ # Generate parents dictionary
+ self.parents[None] = []
+ treeversion = self.treeversion
+ child = None
+ while treeversion:
+ self.ui.status(_('analyzing tree version %s...\n') % treeversion)
+
+ archive = treeversion.split('/')[0]
+ if archive not in self.archives:
+ self.ui.status(_('tree analysis stopped because it points to '
+ 'an unregistered archive %s...\n') % archive)
+ break
+
+ # Get the complete list of revisions for that tree version
+ output, status = self.runlines('revisions', '-r', '-f', treeversion)
+ self.checkexit(status, 'failed retrieveing revisions for %s' % treeversion)
+
+ # No new iteration unless a revision has a continuation-of header
+ treeversion = None
+
+ for l in output:
+ rev = l.strip()
+ self.changes[rev] = self.gnuarch_rev(rev)
+ self.parents[rev] = []
+
+ # Read author, date and summary
+ catlog, status = self.run('cat-log', '-d', self.path, rev)
+ if status:
+ catlog = self.run0('cat-archive-log', rev)
+ self._parsecatlog(catlog, rev)
+
+ # Populate the parents map
+ self.parents[child].append(rev)
+
+ # Keep track of the current revision as the child of the next
+ # revision scanned
+ child = rev
+
+ # Check if we have to follow the usual incremental history
+ # or if we have to 'jump' to a different treeversion given
+ # by the continuation-of header.
+ if self.changes[rev].continuationof:
+ treeversion = '--'.join(self.changes[rev].continuationof.split('--')[:-1])
+ break
+
+ # If we reached a base-0 revision w/o any continuation-of
+ # header, it means the tree history ends here.
+ if rev[-6:] == 'base-0':
+ break
+
+ def after(self):
+ self.ui.debug(_('cleaning up %s\n') % self.tmppath)
+ shutil.rmtree(self.tmppath, ignore_errors=True)
+
+ def getheads(self):
+ return self.parents[None]
+
+ def getfile(self, name, rev):
+ if rev != self.lastrev:
+ raise util.Abort(_('internal calling inconsistency'))
+
+ # Raise IOError if necessary (i.e. deleted files).
+ if not os.path.exists(os.path.join(self.tmppath, name)):
+ raise IOError
+
+ data, mode = self._getfile(name, rev)
+ self.modecache[(name, rev)] = mode
+
+ return data
+
+ def getmode(self, name, rev):
+ return self.modecache[(name, rev)]
+
+ def getchanges(self, rev):
+ self.modecache = {}
+ self._update(rev)
+ changes = []
+ copies = {}
+
+ for f in self.changes[rev].add_files:
+ changes.append((f, rev))
+
+ for f in self.changes[rev].mod_files:
+ changes.append((f, rev))
+
+ for f in self.changes[rev].del_files:
+ changes.append((f, rev))
+
+ for src in self.changes[rev].ren_files:
+ to = self.changes[rev].ren_files[src]
+ changes.append((src, rev))
+ changes.append((to, rev))
+ copies[to] = src
+
+ for src in self.changes[rev].ren_dirs:
+ to = self.changes[rev].ren_dirs[src]
+ chgs, cps = self._rendirchanges(src, to);
+ changes += [(f, rev) for f in chgs]
+ copies.update(cps)
+
+ self.lastrev = rev
+ return sorted(set(changes)), copies
+
+ def getcommit(self, rev):
+ changes = self.changes[rev]
+ return commit(author=changes.author, date=changes.date,
+ desc=changes.summary, parents=self.parents[rev], rev=rev)
+
+ def gettags(self):
+ return self.tags
+
+ def _execute(self, cmd, *args, **kwargs):
+ cmdline = [self.execmd, cmd]
+ cmdline += args
+ cmdline = [util.shellquote(arg) for arg in cmdline]
+ cmdline += ['>', util.nulldev, '2>', util.nulldev]
+ cmdline = util.quotecommand(' '.join(cmdline))
+ self.ui.debug(cmdline, '\n')
+ return os.system(cmdline)
+
+ def _update(self, rev):
+ self.ui.debug(_('applying revision %s...\n') % rev)
+ changeset, status = self.runlines('replay', '-d', self.tmppath,
+ rev)
+ if status:
+ # Something went wrong while merging (baz or tla
+ # issue?), get latest revision and try from there
+ shutil.rmtree(self.tmppath, ignore_errors=True)
+ self._obtainrevision(rev)
+ else:
+ old_rev = self.parents[rev][0]
+ self.ui.debug(_('computing changeset between %s and %s...\n')
+ % (old_rev, rev))
+ self._parsechangeset(changeset, rev)
+
+ def _getfile(self, name, rev):
+ mode = os.lstat(os.path.join(self.tmppath, name)).st_mode
+ if stat.S_ISLNK(mode):
+ data = os.readlink(os.path.join(self.tmppath, name))
+ mode = mode and 'l' or ''
+ else:
+ data = open(os.path.join(self.tmppath, name), 'rb').read()
+ mode = (mode & 0111) and 'x' or ''
+ return data, mode
+
+ def _exclude(self, name):
+ exclude = [ '{arch}', '.arch-ids', '.arch-inventory' ]
+ for exc in exclude:
+ if name.find(exc) != -1:
+ return True
+ return False
+
+ def _readcontents(self, path):
+ files = []
+ contents = os.listdir(path)
+ while len(contents) > 0:
+ c = contents.pop()
+ p = os.path.join(path, c)
+ # os.walk could be used, but here we avoid internal GNU
+ # Arch files and directories, thus saving a lot time.
+ if not self._exclude(p):
+ if os.path.isdir(p):
+ contents += [os.path.join(c, f) for f in os.listdir(p)]
+ else:
+ files.append(c)
+ return files
+
+ def _rendirchanges(self, src, dest):
+ changes = []
+ copies = {}
+ files = self._readcontents(os.path.join(self.tmppath, dest))
+ for f in files:
+ s = os.path.join(src, f)
+ d = os.path.join(dest, f)
+ changes.append(s)
+ changes.append(d)
+ copies[d] = s
+ return changes, copies
+
+ def _obtainrevision(self, rev):
+ self.ui.debug(_('obtaining revision %s...\n') % rev)
+ output = self._execute('get', rev, self.tmppath)
+ self.checkexit(output)
+ self.ui.debug(_('analyzing revision %s...\n') % rev)
+ files = self._readcontents(self.tmppath)
+ self.changes[rev].add_files += files
+
+ def _stripbasepath(self, path):
+ if path.startswith('./'):
+ return path[2:]
+ return path
+
+ def _parsecatlog(self, data, rev):
+ try:
+ catlog = self.catlogparser.parsestr(data)
+
+ # Commit date
+ self.changes[rev].date = util.datestr(
+ util.strdate(catlog['Standard-date'],
+ '%Y-%m-%d %H:%M:%S'))
+
+ # Commit author
+ self.changes[rev].author = self.recode(catlog['Creator'])
+
+ # Commit description
+ self.changes[rev].summary = '\n\n'.join((catlog['Summary'],
+ catlog.get_payload()))
+ self.changes[rev].summary = self.recode(self.changes[rev].summary)
+
+ # Commit revision origin when dealing with a branch or tag
+ if catlog.has_key('Continuation-of'):
+ self.changes[rev].continuationof = self.recode(catlog['Continuation-of'])
+ except Exception:
+ raise util.Abort(_('could not parse cat-log of %s') % rev)
+
+ def _parsechangeset(self, data, rev):
+ for l in data:
+ l = l.strip()
+ # Added file (ignore added directory)
+ if l.startswith('A') and not l.startswith('A/'):
+ file = self._stripbasepath(l[1:].strip())
+ if not self._exclude(file):
+ self.changes[rev].add_files.append(file)
+ # Deleted file (ignore deleted directory)
+ elif l.startswith('D') and not l.startswith('D/'):
+ file = self._stripbasepath(l[1:].strip())
+ if not self._exclude(file):
+ self.changes[rev].del_files.append(file)
+ # Modified binary file
+ elif l.startswith('Mb'):
+ file = self._stripbasepath(l[2:].strip())
+ if not self._exclude(file):
+ self.changes[rev].mod_files.append(file)
+ # Modified link
+ elif l.startswith('M->'):
+ file = self._stripbasepath(l[3:].strip())
+ if not self._exclude(file):
+ self.changes[rev].mod_files.append(file)
+ # Modified file
+ elif l.startswith('M'):
+ file = self._stripbasepath(l[1:].strip())
+ if not self._exclude(file):
+ self.changes[rev].mod_files.append(file)
+ # Renamed file (or link)
+ elif l.startswith('=>'):
+ files = l[2:].strip().split(' ')
+ if len(files) == 1:
+ files = l[2:].strip().split('\t')
+ src = self._stripbasepath(files[0])
+ dst = self._stripbasepath(files[1])
+ if not self._exclude(src) and not self._exclude(dst):
+ self.changes[rev].ren_files[src] = dst
+ # Conversion from file to link or from link to file (modified)
+ elif l.startswith('ch'):
+ file = self._stripbasepath(l[2:].strip())
+ if not self._exclude(file):
+ self.changes[rev].mod_files.append(file)
+ # Renamed directory
+ elif l.startswith('/>'):
+ dirs = l[2:].strip().split(' ')
+ if len(dirs) == 1:
+ dirs = l[2:].strip().split('\t')
+ src = self._stripbasepath(dirs[0])
+ dst = self._stripbasepath(dirs[1])
+ if not self._exclude(src) and not self._exclude(dst):
+ self.changes[rev].ren_dirs[src] = dst
diff --git a/sys/src/cmd/hg/hgext/convert/hg.py b/sys/src/cmd/hg/hgext/convert/hg.py
new file mode 100644
index 000000000..060c1430a
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/hg.py
@@ -0,0 +1,363 @@
+# hg.py - hg backend for convert extension
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+# Notes for hg->hg conversion:
+#
+# * Old versions of Mercurial didn't trim the whitespace from the ends
+# of commit messages, but new versions do. Changesets created by
+# those older versions, then converted, may thus have different
+# hashes for changesets that are otherwise identical.
+#
+# * Using "--config convert.hg.saverev=true" will make the source
+# identifier to be stored in the converted revision. This will cause
+# the converted revision to have a different identity than the
+# source.
+
+
+import os, time, cStringIO
+from mercurial.i18n import _
+from mercurial.node import bin, hex, nullid
+from mercurial import hg, util, context, error
+
+from common import NoRepo, commit, converter_source, converter_sink
+
+class mercurial_sink(converter_sink):
+ def __init__(self, ui, path):
+ converter_sink.__init__(self, ui, path)
+ self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
+ self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
+ self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
+ self.lastbranch = None
+ if os.path.isdir(path) and len(os.listdir(path)) > 0:
+ try:
+ self.repo = hg.repository(self.ui, path)
+ if not self.repo.local():
+ raise NoRepo(_('%s is not a local Mercurial repo') % path)
+ except error.RepoError, err:
+ ui.traceback()
+ raise NoRepo(err.args[0])
+ else:
+ try:
+ ui.status(_('initializing destination %s repository\n') % path)
+ self.repo = hg.repository(self.ui, path, create=True)
+ if not self.repo.local():
+ raise NoRepo(_('%s is not a local Mercurial repo') % path)
+ self.created.append(path)
+ except error.RepoError:
+ ui.traceback()
+ raise NoRepo("could not create hg repo %s as sink" % path)
+ self.lock = None
+ self.wlock = None
+ self.filemapmode = False
+
+ def before(self):
+ self.ui.debug(_('run hg sink pre-conversion action\n'))
+ self.wlock = self.repo.wlock()
+ self.lock = self.repo.lock()
+
+ def after(self):
+ self.ui.debug(_('run hg sink post-conversion action\n'))
+ self.lock.release()
+ self.wlock.release()
+
+ def revmapfile(self):
+ return os.path.join(self.path, ".hg", "shamap")
+
+ def authorfile(self):
+ return os.path.join(self.path, ".hg", "authormap")
+
+ def getheads(self):
+ h = self.repo.changelog.heads()
+ return [ hex(x) for x in h ]
+
+ def setbranch(self, branch, pbranches):
+ if not self.clonebranches:
+ return
+
+ setbranch = (branch != self.lastbranch)
+ self.lastbranch = branch
+ if not branch:
+ branch = 'default'
+ pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
+ pbranch = pbranches and pbranches[0][1] or 'default'
+
+ branchpath = os.path.join(self.path, branch)
+ if setbranch:
+ self.after()
+ try:
+ self.repo = hg.repository(self.ui, branchpath)
+ except:
+ self.repo = hg.repository(self.ui, branchpath, create=True)
+ self.before()
+
+ # pbranches may bring revisions from other branches (merge parents)
+ # Make sure we have them, or pull them.
+ missings = {}
+ for b in pbranches:
+ try:
+ self.repo.lookup(b[0])
+ except:
+ missings.setdefault(b[1], []).append(b[0])
+
+ if missings:
+ self.after()
+ for pbranch, heads in missings.iteritems():
+ pbranchpath = os.path.join(self.path, pbranch)
+ prepo = hg.repository(self.ui, pbranchpath)
+ self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
+ self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
+ self.before()
+
+ def _rewritetags(self, source, revmap, data):
+ fp = cStringIO.StringIO()
+ for line in data.splitlines():
+ s = line.split(' ', 1)
+ if len(s) != 2:
+ continue
+ revid = revmap.get(source.lookuprev(s[0]))
+ if not revid:
+ continue
+ fp.write('%s %s\n' % (revid, s[1]))
+ return fp.getvalue()
+
+ def putcommit(self, files, copies, parents, commit, source, revmap):
+
+ files = dict(files)
+ def getfilectx(repo, memctx, f):
+ v = files[f]
+ data = source.getfile(f, v)
+ e = source.getmode(f, v)
+ if f == '.hgtags':
+ data = self._rewritetags(source, revmap, data)
+ return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f))
+
+ pl = []
+ for p in parents:
+ if p not in pl:
+ pl.append(p)
+ parents = pl
+ nparents = len(parents)
+ if self.filemapmode and nparents == 1:
+ m1node = self.repo.changelog.read(bin(parents[0]))[0]
+ parent = parents[0]
+
+ if len(parents) < 2: parents.append(nullid)
+ if len(parents) < 2: parents.append(nullid)
+ p2 = parents.pop(0)
+
+ text = commit.desc
+ extra = commit.extra.copy()
+ if self.branchnames and commit.branch:
+ extra['branch'] = commit.branch
+ if commit.rev:
+ extra['convert_revision'] = commit.rev
+
+ while parents:
+ p1 = p2
+ p2 = parents.pop(0)
+ ctx = context.memctx(self.repo, (p1, p2), text, files.keys(), getfilectx,
+ commit.author, commit.date, extra)
+ self.repo.commitctx(ctx)
+ text = "(octopus merge fixup)\n"
+ p2 = hex(self.repo.changelog.tip())
+
+ if self.filemapmode and nparents == 1:
+ man = self.repo.manifest
+ mnode = self.repo.changelog.read(bin(p2))[0]
+ if not man.cmp(m1node, man.revision(mnode)):
+ self.ui.status(_("filtering out empty revision\n"))
+ self.repo.rollback()
+ return parent
+ return p2
+
+ def puttags(self, tags):
+ try:
+ parentctx = self.repo[self.tagsbranch]
+ tagparent = parentctx.node()
+ except error.RepoError:
+ parentctx = None
+ tagparent = nullid
+
+ try:
+ oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
+ except:
+ oldlines = []
+
+ newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
+ if newlines == oldlines:
+ return None
+ data = "".join(newlines)
+ def getfilectx(repo, memctx, f):
+ return context.memfilectx(f, data, False, False, None)
+
+ self.ui.status(_("updating tags\n"))
+ date = "%s 0" % int(time.mktime(time.gmtime()))
+ extra = {'branch': self.tagsbranch}
+ ctx = context.memctx(self.repo, (tagparent, None), "update tags",
+ [".hgtags"], getfilectx, "convert-repo", date,
+ extra)
+ self.repo.commitctx(ctx)
+ return hex(self.repo.changelog.tip())
+
+ def setfilemapmode(self, active):
+ self.filemapmode = active
+
+class mercurial_source(converter_source):
+ def __init__(self, ui, path, rev=None):
+ converter_source.__init__(self, ui, path, rev)
+ self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
+ self.ignored = set()
+ self.saverev = ui.configbool('convert', 'hg.saverev', False)
+ try:
+ self.repo = hg.repository(self.ui, path)
+ # try to provoke an exception if this isn't really a hg
+ # repo, but some other bogus compatible-looking url
+ if not self.repo.local():
+ raise error.RepoError()
+ except error.RepoError:
+ ui.traceback()
+ raise NoRepo("%s is not a local Mercurial repo" % path)
+ self.lastrev = None
+ self.lastctx = None
+ self._changescache = None
+ self.convertfp = None
+ # Restrict converted revisions to startrev descendants
+ startnode = ui.config('convert', 'hg.startrev')
+ if startnode is not None:
+ try:
+ startnode = self.repo.lookup(startnode)
+ except error.RepoError:
+ raise util.Abort(_('%s is not a valid start revision')
+ % startnode)
+ startrev = self.repo.changelog.rev(startnode)
+ children = {startnode: 1}
+ for rev in self.repo.changelog.descendants(startrev):
+ children[self.repo.changelog.node(rev)] = 1
+ self.keep = children.__contains__
+ else:
+ self.keep = util.always
+
+ def changectx(self, rev):
+ if self.lastrev != rev:
+ self.lastctx = self.repo[rev]
+ self.lastrev = rev
+ return self.lastctx
+
+ def parents(self, ctx):
+ return [p.node() for p in ctx.parents()
+ if p and self.keep(p.node())]
+
+ def getheads(self):
+ if self.rev:
+ heads = [self.repo[self.rev].node()]
+ else:
+ heads = self.repo.heads()
+ return [hex(h) for h in heads if self.keep(h)]
+
+ def getfile(self, name, rev):
+ try:
+ return self.changectx(rev)[name].data()
+ except error.LookupError, err:
+ raise IOError(err)
+
+ def getmode(self, name, rev):
+ return self.changectx(rev).manifest().flags(name)
+
+ def getchanges(self, rev):
+ ctx = self.changectx(rev)
+ parents = self.parents(ctx)
+ if not parents:
+ files = sorted(ctx.manifest())
+ if self.ignoreerrors:
+ # calling getcopies() is a simple way to detect missing
+ # revlogs and populate self.ignored
+ self.getcopies(ctx, files)
+ return [(f, rev) for f in files if f not in self.ignored], {}
+ if self._changescache and self._changescache[0] == rev:
+ m, a, r = self._changescache[1]
+ else:
+ m, a, r = self.repo.status(parents[0], ctx.node())[:3]
+ # getcopies() detects missing revlogs early, run it before
+ # filtering the changes.
+ copies = self.getcopies(ctx, m + a)
+ changes = [(name, rev) for name in m + a + r
+ if name not in self.ignored]
+ return sorted(changes), copies
+
+ def getcopies(self, ctx, files):
+ copies = {}
+ for name in files:
+ if name in self.ignored:
+ continue
+ try:
+ copysource, copynode = ctx.filectx(name).renamed()
+ if copysource in self.ignored or not self.keep(copynode):
+ continue
+ copies[name] = copysource
+ except TypeError:
+ pass
+ except error.LookupError, e:
+ if not self.ignoreerrors:
+ raise
+ self.ignored.add(name)
+ self.ui.warn(_('ignoring: %s\n') % e)
+ return copies
+
+ def getcommit(self, rev):
+ ctx = self.changectx(rev)
+ parents = [hex(p) for p in self.parents(ctx)]
+ if self.saverev:
+ crev = rev
+ else:
+ crev = None
+ return commit(author=ctx.user(), date=util.datestr(ctx.date()),
+ desc=ctx.description(), rev=crev, parents=parents,
+ branch=ctx.branch(), extra=ctx.extra(),
+ sortkey=ctx.rev())
+
+ def gettags(self):
+ tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
+ return dict([(name, hex(node)) for name, node in tags
+ if self.keep(node)])
+
+ def getchangedfiles(self, rev, i):
+ ctx = self.changectx(rev)
+ parents = self.parents(ctx)
+ if not parents and i is None:
+ i = 0
+ changes = [], ctx.manifest().keys(), []
+ else:
+ i = i or 0
+ changes = self.repo.status(parents[i], ctx.node())[:3]
+ changes = [[f for f in l if f not in self.ignored] for l in changes]
+
+ if i == 0:
+ self._changescache = (rev, changes)
+
+ return changes[0] + changes[1] + changes[2]
+
+ def converted(self, rev, destrev):
+ if self.convertfp is None:
+ self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
+ 'a')
+ self.convertfp.write('%s %s\n' % (destrev, rev))
+ self.convertfp.flush()
+
+ def before(self):
+ self.ui.debug(_('run hg source pre-conversion action\n'))
+
+ def after(self):
+ self.ui.debug(_('run hg source post-conversion action\n'))
+
+ def hasnativeorder(self):
+ return True
+
+ def lookuprev(self, rev):
+ try:
+ return hex(self.repo.lookup(rev))
+ except error.RepoError:
+ return None
diff --git a/sys/src/cmd/hg/hgext/convert/monotone.py b/sys/src/cmd/hg/hgext/convert/monotone.py
new file mode 100644
index 000000000..085510ce9
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/monotone.py
@@ -0,0 +1,217 @@
+# monotone.py - monotone support for the convert extension
+#
+# Copyright 2008, 2009 Mikkel Fahnoe Jorgensen <mikkel@dvide.com> and
+# others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os, re
+from mercurial import util
+from common import NoRepo, commit, converter_source, checktool
+from common import commandline
+from mercurial.i18n import _
+
+class monotone_source(converter_source, commandline):
+ def __init__(self, ui, path=None, rev=None):
+ converter_source.__init__(self, ui, path, rev)
+ commandline.__init__(self, ui, 'mtn')
+
+ self.ui = ui
+ self.path = path
+
+ norepo = NoRepo (_("%s does not look like a monotone repo") % path)
+ if not os.path.exists(os.path.join(path, '_MTN')):
+ # Could be a monotone repository (SQLite db file)
+ try:
+ header = file(path, 'rb').read(16)
+ except:
+ header = ''
+ if header != 'SQLite format 3\x00':
+ raise norepo
+
+ # regular expressions for parsing monotone output
+ space = r'\s*'
+ name = r'\s+"((?:\\"|[^"])*)"\s*'
+ value = name
+ revision = r'\s+\[(\w+)\]\s*'
+ lines = r'(?:.|\n)+'
+
+ self.dir_re = re.compile(space + "dir" + name)
+ self.file_re = re.compile(space + "file" + name + "content" + revision)
+ self.add_file_re = re.compile(space + "add_file" + name + "content" + revision)
+ self.patch_re = re.compile(space + "patch" + name + "from" + revision + "to" + revision)
+ self.rename_re = re.compile(space + "rename" + name + "to" + name)
+ self.delete_re = re.compile(space + "delete" + name)
+ self.tag_re = re.compile(space + "tag" + name + "revision" + revision)
+ self.cert_re = re.compile(lines + space + "name" + name + "value" + value)
+
+ attr = space + "file" + lines + space + "attr" + space
+ self.attr_execute_re = re.compile(attr + '"mtn:execute"' + space + '"true"')
+
+ # cached data
+ self.manifest_rev = None
+ self.manifest = None
+ self.files = None
+ self.dirs = None
+
+ checktool('mtn', abort=False)
+
+ # test if there are any revisions
+ self.rev = None
+ try:
+ self.getheads()
+ except:
+ raise norepo
+ self.rev = rev
+
+ def mtnrun(self, *args, **kwargs):
+ kwargs['d'] = self.path
+ return self.run0('automate', *args, **kwargs)
+
+ def mtnloadmanifest(self, rev):
+ if self.manifest_rev == rev:
+ return
+ self.manifest = self.mtnrun("get_manifest_of", rev).split("\n\n")
+ self.manifest_rev = rev
+ self.files = {}
+ self.dirs = {}
+
+ for e in self.manifest:
+ m = self.file_re.match(e)
+ if m:
+ attr = ""
+ name = m.group(1)
+ node = m.group(2)
+ if self.attr_execute_re.match(e):
+ attr += "x"
+ self.files[name] = (node, attr)
+ m = self.dir_re.match(e)
+ if m:
+ self.dirs[m.group(1)] = True
+
+ def mtnisfile(self, name, rev):
+ # a non-file could be a directory or a deleted or renamed file
+ self.mtnloadmanifest(rev)
+ return name in self.files
+
+ def mtnisdir(self, name, rev):
+ self.mtnloadmanifest(rev)
+ return name in self.dirs
+
+ def mtngetcerts(self, rev):
+ certs = {"author":"<missing>", "date":"<missing>",
+ "changelog":"<missing>", "branch":"<missing>"}
+ cert_list = self.mtnrun("certs", rev).split('\n\n key "')
+ for e in cert_list:
+ m = self.cert_re.match(e)
+ if m:
+ name, value = m.groups()
+ value = value.replace(r'\"', '"')
+ value = value.replace(r'\\', '\\')
+ certs[name] = value
+ # Monotone may have subsecond dates: 2005-02-05T09:39:12.364306
+ # and all times are stored in UTC
+ certs["date"] = certs["date"].split('.')[0] + " UTC"
+ return certs
+
+ # implement the converter_source interface:
+
+ def getheads(self):
+ if not self.rev:
+ return self.mtnrun("leaves").splitlines()
+ else:
+ return [self.rev]
+
+ def getchanges(self, rev):
+ #revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
+ revision = self.mtnrun("get_revision", rev).split("\n\n")
+ files = {}
+ ignoremove = {}
+ renameddirs = []
+ copies = {}
+ for e in revision:
+ m = self.add_file_re.match(e)
+ if m:
+ files[m.group(1)] = rev
+ ignoremove[m.group(1)] = rev
+ m = self.patch_re.match(e)
+ if m:
+ files[m.group(1)] = rev
+ # Delete/rename is handled later when the convert engine
+ # discovers an IOError exception from getfile,
+ # but only if we add the "from" file to the list of changes.
+ m = self.delete_re.match(e)
+ if m:
+ files[m.group(1)] = rev
+ m = self.rename_re.match(e)
+ if m:
+ toname = m.group(2)
+ fromname = m.group(1)
+ if self.mtnisfile(toname, rev):
+ ignoremove[toname] = 1
+ copies[toname] = fromname
+ files[toname] = rev
+ files[fromname] = rev
+ elif self.mtnisdir(toname, rev):
+ renameddirs.append((fromname, toname))
+
+ # Directory renames can be handled only once we have recorded
+ # all new files
+ for fromdir, todir in renameddirs:
+ renamed = {}
+ for tofile in self.files:
+ if tofile in ignoremove:
+ continue
+ if tofile.startswith(todir + '/'):
+ renamed[tofile] = fromdir + tofile[len(todir):]
+ # Avoid chained moves like:
+ # d1(/a) => d3/d1(/a)
+ # d2 => d3
+ ignoremove[tofile] = 1
+ for tofile, fromfile in renamed.items():
+ self.ui.debug (_("copying file in renamed directory "
+ "from '%s' to '%s'")
+ % (fromfile, tofile), '\n')
+ files[tofile] = rev
+ copies[tofile] = fromfile
+ for fromfile in renamed.values():
+ files[fromfile] = rev
+
+ return (files.items(), copies)
+
+ def getmode(self, name, rev):
+ self.mtnloadmanifest(rev)
+ node, attr = self.files.get(name, (None, ""))
+ return attr
+
+ def getfile(self, name, rev):
+ if not self.mtnisfile(name, rev):
+ raise IOError() # file was deleted or renamed
+ try:
+ return self.mtnrun("get_file_of", name, r=rev)
+ except:
+ raise IOError() # file was deleted or renamed
+
+ def getcommit(self, rev):
+ certs = self.mtngetcerts(rev)
+ return commit(
+ author=certs["author"],
+ date=util.datestr(util.strdate(certs["date"], "%Y-%m-%dT%H:%M:%S")),
+ desc=certs["changelog"],
+ rev=rev,
+ parents=self.mtnrun("parents", rev).splitlines(),
+ branch=certs["branch"])
+
+ def gettags(self):
+ tags = {}
+ for e in self.mtnrun("tags").split("\n\n"):
+ m = self.tag_re.match(e)
+ if m:
+ tags[m.group(1)] = m.group(2)
+ return tags
+
+ def getchangedfiles(self, rev, i):
+ # This function is only needed to support --filemap
+ # ... and we don't support that
+ raise NotImplementedError()
diff --git a/sys/src/cmd/hg/hgext/convert/p4.py b/sys/src/cmd/hg/hgext/convert/p4.py
new file mode 100644
index 000000000..d65867126
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/p4.py
@@ -0,0 +1,205 @@
+#
+# Perforce source for convert extension.
+#
+# Copyright 2009, Frank Kingswood <frank@kingswood-consulting.co.uk>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+#
+
+from mercurial import util
+from mercurial.i18n import _
+
+from common import commit, converter_source, checktool, NoRepo
+import marshal
+import re
+
+def loaditer(f):
+ "Yield the dictionary objects generated by p4"
+ try:
+ while True:
+ d = marshal.load(f)
+ if not d:
+ break
+ yield d
+ except EOFError:
+ pass
+
+class p4_source(converter_source):
+ def __init__(self, ui, path, rev=None):
+ super(p4_source, self).__init__(ui, path, rev=rev)
+
+ if "/" in path and not path.startswith('//'):
+ raise NoRepo('%s does not look like a P4 repo' % path)
+
+ checktool('p4', abort=False)
+
+ self.p4changes = {}
+ self.heads = {}
+ self.changeset = {}
+ self.files = {}
+ self.tags = {}
+ self.lastbranch = {}
+ self.parent = {}
+ self.encoding = "latin_1"
+ self.depotname = {} # mapping from local name to depot name
+ self.modecache = {}
+ self.re_type = re.compile("([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)(\+\w+)?$")
+ self.re_keywords = re.compile(r"\$(Id|Header|Date|DateTime|Change|File|Revision|Author):[^$\n]*\$")
+ self.re_keywords_old = re.compile("\$(Id|Header):[^$\n]*\$")
+
+ self._parse(ui, path)
+
+ def _parse_view(self, path):
+ "Read changes affecting the path"
+ cmd = 'p4 -G changes -s submitted "%s"' % path
+ stdout = util.popen(cmd)
+ for d in loaditer(stdout):
+ c = d.get("change", None)
+ if c:
+ self.p4changes[c] = True
+
+ def _parse(self, ui, path):
+ "Prepare list of P4 filenames and revisions to import"
+ ui.status(_('reading p4 views\n'))
+
+ # read client spec or view
+ if "/" in path:
+ self._parse_view(path)
+ if path.startswith("//") and path.endswith("/..."):
+ views = {path[:-3]:""}
+ else:
+ views = {"//": ""}
+ else:
+ cmd = 'p4 -G client -o "%s"' % path
+ clientspec = marshal.load(util.popen(cmd))
+
+ views = {}
+ for client in clientspec:
+ if client.startswith("View"):
+ sview, cview = clientspec[client].split()
+ self._parse_view(sview)
+ if sview.endswith("...") and cview.endswith("..."):
+ sview = sview[:-3]
+ cview = cview[:-3]
+ cview = cview[2:]
+ cview = cview[cview.find("/") + 1:]
+ views[sview] = cview
+
+ # list of changes that affect our source files
+ self.p4changes = self.p4changes.keys()
+ self.p4changes.sort(key=int)
+
+ # list with depot pathnames, longest first
+ vieworder = views.keys()
+ vieworder.sort(key=len, reverse=True)
+
+ # handle revision limiting
+ startrev = self.ui.config('convert', 'p4.startrev', default=0)
+ self.p4changes = [x for x in self.p4changes
+ if ((not startrev or int(x) >= int(startrev)) and
+ (not self.rev or int(x) <= int(self.rev)))]
+
+ # now read the full changelists to get the list of file revisions
+ ui.status(_('collecting p4 changelists\n'))
+ lastid = None
+ for change in self.p4changes:
+ cmd = "p4 -G describe %s" % change
+ stdout = util.popen(cmd)
+ d = marshal.load(stdout)
+
+ desc = self.recode(d["desc"])
+ shortdesc = desc.split("\n", 1)[0]
+ t = '%s %s' % (d["change"], repr(shortdesc)[1:-1])
+ ui.status(util.ellipsis(t, 80) + '\n')
+
+ if lastid:
+ parents = [lastid]
+ else:
+ parents = []
+
+ date = (int(d["time"]), 0) # timezone not set
+ c = commit(author=self.recode(d["user"]), date=util.datestr(date),
+ parents=parents, desc=desc, branch='', extra={"p4": change})
+
+ files = []
+ i = 0
+ while ("depotFile%d" % i) in d and ("rev%d" % i) in d:
+ oldname = d["depotFile%d" % i]
+ filename = None
+ for v in vieworder:
+ if oldname.startswith(v):
+ filename = views[v] + oldname[len(v):]
+ break
+ if filename:
+ files.append((filename, d["rev%d" % i]))
+ self.depotname[filename] = oldname
+ i += 1
+ self.changeset[change] = c
+ self.files[change] = files
+ lastid = change
+
+ if lastid:
+ self.heads = [lastid]
+
+ def getheads(self):
+ return self.heads
+
+ def getfile(self, name, rev):
+ cmd = 'p4 -G print "%s#%s"' % (self.depotname[name], rev)
+ stdout = util.popen(cmd)
+
+ mode = None
+ contents = ""
+ keywords = None
+
+ for d in loaditer(stdout):
+ code = d["code"]
+ data = d.get("data")
+
+ if code == "error":
+ raise IOError(d["generic"], data)
+
+ elif code == "stat":
+ p4type = self.re_type.match(d["type"])
+ if p4type:
+ mode = ""
+ flags = (p4type.group(1) or "") + (p4type.group(3) or "")
+ if "x" in flags:
+ mode = "x"
+ if p4type.group(2) == "symlink":
+ mode = "l"
+ if "ko" in flags:
+ keywords = self.re_keywords_old
+ elif "k" in flags:
+ keywords = self.re_keywords
+
+ elif code == "text" or code == "binary":
+ contents += data
+
+ if mode is None:
+ raise IOError(0, "bad stat")
+
+ self.modecache[(name, rev)] = mode
+
+ if keywords:
+ contents = keywords.sub("$\\1$", contents)
+ if mode == "l" and contents.endswith("\n"):
+ contents = contents[:-1]
+
+ return contents
+
+ def getmode(self, name, rev):
+ return self.modecache[(name, rev)]
+
+ def getchanges(self, rev):
+ return self.files[rev], {}
+
+ def getcommit(self, rev):
+ return self.changeset[rev]
+
+ def gettags(self):
+ return self.tags
+
+ def getchangedfiles(self, rev, i):
+ return sorted([x[0] for x in self.files[rev]])
diff --git a/sys/src/cmd/hg/hgext/convert/subversion.py b/sys/src/cmd/hg/hgext/convert/subversion.py
new file mode 100644
index 000000000..5a0367485
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/subversion.py
@@ -0,0 +1,1136 @@
+# Subversion 1.4/1.5 Python API backend
+#
+# Copyright(C) 2007 Daniel Holth et al
+
+import os
+import re
+import sys
+import cPickle as pickle
+import tempfile
+import urllib
+
+from mercurial import strutil, util, encoding
+from mercurial.i18n import _
+
+# Subversion stuff. Works best with very recent Python SVN bindings
+# e.g. SVN 1.5 or backports. Thanks to the bzr folks for enhancing
+# these bindings.
+
+from cStringIO import StringIO
+
+from common import NoRepo, MissingTool, commit, encodeargs, decodeargs
+from common import commandline, converter_source, converter_sink, mapfile
+
+try:
+ from svn.core import SubversionException, Pool
+ import svn
+ import svn.client
+ import svn.core
+ import svn.ra
+ import svn.delta
+ import transport
+ import warnings
+ warnings.filterwarnings('ignore',
+ module='svn.core',
+ category=DeprecationWarning)
+
+except ImportError:
+ pass
+
+class SvnPathNotFound(Exception):
+ pass
+
+def geturl(path):
+ try:
+ return svn.client.url_from_path(svn.core.svn_path_canonicalize(path))
+ except SubversionException:
+ pass
+ if os.path.isdir(path):
+ path = os.path.normpath(os.path.abspath(path))
+ if os.name == 'nt':
+ path = '/' + util.normpath(path)
+ # Module URL is later compared with the repository URL returned
+ # by svn API, which is UTF-8.
+ path = encoding.tolocal(path)
+ return 'file://%s' % urllib.quote(path)
+ return path
+
+def optrev(number):
+ optrev = svn.core.svn_opt_revision_t()
+ optrev.kind = svn.core.svn_opt_revision_number
+ optrev.value.number = number
+ return optrev
+
+class changedpath(object):
+ def __init__(self, p):
+ self.copyfrom_path = p.copyfrom_path
+ self.copyfrom_rev = p.copyfrom_rev
+ self.action = p.action
+
+def get_log_child(fp, url, paths, start, end, limit=0, discover_changed_paths=True,
+ strict_node_history=False):
+ protocol = -1
+ def receiver(orig_paths, revnum, author, date, message, pool):
+ if orig_paths is not None:
+ for k, v in orig_paths.iteritems():
+ orig_paths[k] = changedpath(v)
+ pickle.dump((orig_paths, revnum, author, date, message),
+ fp, protocol)
+
+ try:
+ # Use an ra of our own so that our parent can consume
+ # our results without confusing the server.
+ t = transport.SvnRaTransport(url=url)
+ svn.ra.get_log(t.ra, paths, start, end, limit,
+ discover_changed_paths,
+ strict_node_history,
+ receiver)
+ except SubversionException, (inst, num):
+ pickle.dump(num, fp, protocol)
+ except IOError:
+ # Caller may interrupt the iteration
+ pickle.dump(None, fp, protocol)
+ else:
+ pickle.dump(None, fp, protocol)
+ fp.close()
+ # With large history, cleanup process goes crazy and suddenly
+ # consumes *huge* amount of memory. The output file being closed,
+ # there is no need for clean termination.
+ os._exit(0)
+
+def debugsvnlog(ui, **opts):
+ """Fetch SVN log in a subprocess and channel them back to parent to
+ avoid memory collection issues.
+ """
+ util.set_binary(sys.stdin)
+ util.set_binary(sys.stdout)
+ args = decodeargs(sys.stdin.read())
+ get_log_child(sys.stdout, *args)
+
+class logstream(object):
+ """Interruptible revision log iterator."""
+ def __init__(self, stdout):
+ self._stdout = stdout
+
+ def __iter__(self):
+ while True:
+ entry = pickle.load(self._stdout)
+ try:
+ orig_paths, revnum, author, date, message = entry
+ except:
+ if entry is None:
+ break
+ raise SubversionException("child raised exception", entry)
+ yield entry
+
+ def close(self):
+ if self._stdout:
+ self._stdout.close()
+ self._stdout = None
+
+
+# Check to see if the given path is a local Subversion repo. Verify this by
+# looking for several svn-specific files and directories in the given
+# directory.
+def filecheck(path, proto):
+ for x in ('locks', 'hooks', 'format', 'db', ):
+ if not os.path.exists(os.path.join(path, x)):
+ return False
+ return True
+
+# Check to see if a given path is the root of an svn repo over http. We verify
+# this by requesting a version-controlled URL we know can't exist and looking
+# for the svn-specific "not found" XML.
+def httpcheck(path, proto):
+ return ('<m:human-readable errcode="160013">' in
+ urllib.urlopen('%s://%s/!svn/ver/0/.svn' % (proto, path)).read())
+
+protomap = {'http': httpcheck,
+ 'https': httpcheck,
+ 'file': filecheck,
+ }
+def issvnurl(url):
+ try:
+ proto, path = url.split('://', 1)
+ path = urllib.url2pathname(path)
+ except ValueError:
+ proto = 'file'
+ path = os.path.abspath(url)
+ path = path.replace(os.sep, '/')
+ check = protomap.get(proto, lambda p, p2: False)
+ while '/' in path:
+ if check(path, proto):
+ return True
+ path = path.rsplit('/', 1)[0]
+ return False
+
+# SVN conversion code stolen from bzr-svn and tailor
+#
+# Subversion looks like a versioned filesystem, branches structures
+# are defined by conventions and not enforced by the tool. First,
+# we define the potential branches (modules) as "trunk" and "branches"
+# children directories. Revisions are then identified by their
+# module and revision number (and a repository identifier).
+#
+# The revision graph is really a tree (or a forest). By default, a
+# revision parent is the previous revision in the same module. If the
+# module directory is copied/moved from another module then the
+# revision is the module root and its parent the source revision in
+# the parent module. A revision has at most one parent.
+#
+class svn_source(converter_source):
+ def __init__(self, ui, url, rev=None):
+ super(svn_source, self).__init__(ui, url, rev=rev)
+
+ if not (url.startswith('svn://') or url.startswith('svn+ssh://') or
+ (os.path.exists(url) and
+ os.path.exists(os.path.join(url, '.svn'))) or
+ issvnurl(url)):
+ raise NoRepo("%s does not look like a Subversion repo" % url)
+
+ try:
+ SubversionException
+ except NameError:
+ raise MissingTool(_('Subversion python bindings could not be loaded'))
+
+ try:
+ version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
+ if version < (1, 4):
+ raise MissingTool(_('Subversion python bindings %d.%d found, '
+ '1.4 or later required') % version)
+ except AttributeError:
+ raise MissingTool(_('Subversion python bindings are too old, 1.4 '
+ 'or later required'))
+
+ self.lastrevs = {}
+
+ latest = None
+ try:
+ # Support file://path@rev syntax. Useful e.g. to convert
+ # deleted branches.
+ at = url.rfind('@')
+ if at >= 0:
+ latest = int(url[at+1:])
+ url = url[:at]
+ except ValueError:
+ pass
+ self.url = geturl(url)
+ self.encoding = 'UTF-8' # Subversion is always nominal UTF-8
+ try:
+ self.transport = transport.SvnRaTransport(url=self.url)
+ self.ra = self.transport.ra
+ self.ctx = self.transport.client
+ self.baseurl = svn.ra.get_repos_root(self.ra)
+ # Module is either empty or a repository path starting with
+ # a slash and not ending with a slash.
+ self.module = urllib.unquote(self.url[len(self.baseurl):])
+ self.prevmodule = None
+ self.rootmodule = self.module
+ self.commits = {}
+ self.paths = {}
+ self.uuid = svn.ra.get_uuid(self.ra)
+ except SubversionException:
+ ui.traceback()
+ raise NoRepo("%s does not look like a Subversion repo" % self.url)
+
+ if rev:
+ try:
+ latest = int(rev)
+ except ValueError:
+ raise util.Abort(_('svn: revision %s is not an integer') % rev)
+
+ self.startrev = self.ui.config('convert', 'svn.startrev', default=0)
+ try:
+ self.startrev = int(self.startrev)
+ if self.startrev < 0:
+ self.startrev = 0
+ except ValueError:
+ raise util.Abort(_('svn: start revision %s is not an integer')
+ % self.startrev)
+
+ self.head = self.latest(self.module, latest)
+ if not self.head:
+ raise util.Abort(_('no revision found in module %s')
+ % self.module)
+ self.last_changed = self.revnum(self.head)
+
+ self._changescache = None
+
+ if os.path.exists(os.path.join(url, '.svn/entries')):
+ self.wc = url
+ else:
+ self.wc = None
+ self.convertfp = None
+
+ def setrevmap(self, revmap):
+ lastrevs = {}
+ for revid in revmap.iterkeys():
+ uuid, module, revnum = self.revsplit(revid)
+ lastrevnum = lastrevs.setdefault(module, revnum)
+ if revnum > lastrevnum:
+ lastrevs[module] = revnum
+ self.lastrevs = lastrevs
+
+ def exists(self, path, optrev):
+ try:
+ svn.client.ls(self.url.rstrip('/') + '/' + urllib.quote(path),
+ optrev, False, self.ctx)
+ return True
+ except SubversionException:
+ return False
+
+ def getheads(self):
+
+ def isdir(path, revnum):
+ kind = self._checkpath(path, revnum)
+ return kind == svn.core.svn_node_dir
+
+ def getcfgpath(name, rev):
+ cfgpath = self.ui.config('convert', 'svn.' + name)
+ if cfgpath is not None and cfgpath.strip() == '':
+ return None
+ path = (cfgpath or name).strip('/')
+ if not self.exists(path, rev):
+ if cfgpath:
+ raise util.Abort(_('expected %s to be at %r, but not found')
+ % (name, path))
+ return None
+ self.ui.note(_('found %s at %r\n') % (name, path))
+ return path
+
+ rev = optrev(self.last_changed)
+ oldmodule = ''
+ trunk = getcfgpath('trunk', rev)
+ self.tags = getcfgpath('tags', rev)
+ branches = getcfgpath('branches', rev)
+
+ # If the project has a trunk or branches, we will extract heads
+ # from them. We keep the project root otherwise.
+ if trunk:
+ oldmodule = self.module or ''
+ self.module += '/' + trunk
+ self.head = self.latest(self.module, self.last_changed)
+ if not self.head:
+ raise util.Abort(_('no revision found in module %s')
+ % self.module)
+
+ # First head in the list is the module's head
+ self.heads = [self.head]
+ if self.tags is not None:
+ self.tags = '%s/%s' % (oldmodule , (self.tags or 'tags'))
+
+ # Check if branches bring a few more heads to the list
+ if branches:
+ rpath = self.url.strip('/')
+ branchnames = svn.client.ls(rpath + '/' + urllib.quote(branches),
+ rev, False, self.ctx)
+ for branch in branchnames.keys():
+ module = '%s/%s/%s' % (oldmodule, branches, branch)
+ if not isdir(module, self.last_changed):
+ continue
+ brevid = self.latest(module, self.last_changed)
+ if not brevid:
+ self.ui.note(_('ignoring empty branch %s\n') % branch)
+ continue
+ self.ui.note(_('found branch %s at %d\n') %
+ (branch, self.revnum(brevid)))
+ self.heads.append(brevid)
+
+ if self.startrev and self.heads:
+ if len(self.heads) > 1:
+ raise util.Abort(_('svn: start revision is not supported '
+ 'with more than one branch'))
+ revnum = self.revnum(self.heads[0])
+ if revnum < self.startrev:
+ raise util.Abort(_('svn: no revision found after start revision %d')
+ % self.startrev)
+
+ return self.heads
+
+ def getfile(self, file, rev):
+ data, mode = self._getfile(file, rev)
+ self.modecache[(file, rev)] = mode
+ return data
+
+ def getmode(self, file, rev):
+ return self.modecache[(file, rev)]
+
+ def getchanges(self, rev):
+ if self._changescache and self._changescache[0] == rev:
+ return self._changescache[1]
+ self._changescache = None
+ self.modecache = {}
+ (paths, parents) = self.paths[rev]
+ if parents:
+ files, copies = self.expandpaths(rev, paths, parents)
+ else:
+ # Perform a full checkout on roots
+ uuid, module, revnum = self.revsplit(rev)
+ entries = svn.client.ls(self.baseurl + urllib.quote(module),
+ optrev(revnum), True, self.ctx)
+ files = [n for n,e in entries.iteritems()
+ if e.kind == svn.core.svn_node_file]
+ copies = {}
+
+ files.sort()
+ files = zip(files, [rev] * len(files))
+
+ # caller caches the result, so free it here to release memory
+ del self.paths[rev]
+ return (files, copies)
+
+ def getchangedfiles(self, rev, i):
+ changes = self.getchanges(rev)
+ self._changescache = (rev, changes)
+ return [f[0] for f in changes[0]]
+
+ def getcommit(self, rev):
+ if rev not in self.commits:
+ uuid, module, revnum = self.revsplit(rev)
+ self.module = module
+ self.reparent(module)
+ # We assume that:
+ # - requests for revisions after "stop" come from the
+ # revision graph backward traversal. Cache all of them
+ # down to stop, they will be used eventually.
+ # - requests for revisions before "stop" come to get
+ # isolated branches parents. Just fetch what is needed.
+ stop = self.lastrevs.get(module, 0)
+ if revnum < stop:
+ stop = revnum + 1
+ self._fetch_revisions(revnum, stop)
+ commit = self.commits[rev]
+ # caller caches the result, so free it here to release memory
+ del self.commits[rev]
+ return commit
+
+ def gettags(self):
+ tags = {}
+ if self.tags is None:
+ return tags
+
+ # svn tags are just a convention, project branches left in a
+ # 'tags' directory. There is no other relationship than
+ # ancestry, which is expensive to discover and makes them hard
+ # to update incrementally. Worse, past revisions may be
+ # referenced by tags far away in the future, requiring a deep
+ # history traversal on every calculation. Current code
+ # performs a single backward traversal, tracking moves within
+ # the tags directory (tag renaming) and recording a new tag
+ # everytime a project is copied from outside the tags
+ # directory. It also lists deleted tags, this behaviour may
+ # change in the future.
+ pendings = []
+ tagspath = self.tags
+ start = svn.ra.get_latest_revnum(self.ra)
+ try:
+ for entry in self._getlog([self.tags], start, self.startrev):
+ origpaths, revnum, author, date, message = entry
+ copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p, e
+ in origpaths.iteritems() if e.copyfrom_path]
+ # Apply moves/copies from more specific to general
+ copies.sort(reverse=True)
+
+ srctagspath = tagspath
+ if copies and copies[-1][2] == tagspath:
+ # Track tags directory moves
+ srctagspath = copies.pop()[0]
+
+ for source, sourcerev, dest in copies:
+ if not dest.startswith(tagspath + '/'):
+ continue
+ for tag in pendings:
+ if tag[0].startswith(dest):
+ tagpath = source + tag[0][len(dest):]
+ tag[:2] = [tagpath, sourcerev]
+ break
+ else:
+ pendings.append([source, sourcerev, dest])
+
+ # Filter out tags with children coming from different
+ # parts of the repository like:
+ # /tags/tag.1 (from /trunk:10)
+ # /tags/tag.1/foo (from /branches/foo:12)
+ # Here/tags/tag.1 discarded as well as its children.
+ # It happens with tools like cvs2svn. Such tags cannot
+ # be represented in mercurial.
+ addeds = dict((p, e.copyfrom_path) for p, e
+ in origpaths.iteritems()
+ if e.action == 'A' and e.copyfrom_path)
+ badroots = set()
+ for destroot in addeds:
+ for source, sourcerev, dest in pendings:
+ if (not dest.startswith(destroot + '/')
+ or source.startswith(addeds[destroot] + '/')):
+ continue
+ badroots.add(destroot)
+ break
+
+ for badroot in badroots:
+ pendings = [p for p in pendings if p[2] != badroot
+ and not p[2].startswith(badroot + '/')]
+
+ # Tell tag renamings from tag creations
+ remainings = []
+ for source, sourcerev, dest in pendings:
+ tagname = dest.split('/')[-1]
+ if source.startswith(srctagspath):
+ remainings.append([source, sourcerev, tagname])
+ continue
+ if tagname in tags:
+ # Keep the latest tag value
+ continue
+ # From revision may be fake, get one with changes
+ try:
+ tagid = self.latest(source, sourcerev)
+ if tagid and tagname not in tags:
+ tags[tagname] = tagid
+ except SvnPathNotFound:
+ # It happens when we are following directories
+ # we assumed were copied with their parents
+ # but were really created in the tag
+ # directory.
+ pass
+ pendings = remainings
+ tagspath = srctagspath
+
+ except SubversionException:
+ self.ui.note(_('no tags found at revision %d\n') % start)
+ return tags
+
+ def converted(self, rev, destrev):
+ if not self.wc:
+ return
+ if self.convertfp is None:
+ self.convertfp = open(os.path.join(self.wc, '.svn', 'hg-shamap'),
+ 'a')
+ self.convertfp.write('%s %d\n' % (destrev, self.revnum(rev)))
+ self.convertfp.flush()
+
+ def revid(self, revnum, module=None):
+ return 'svn:%s%s@%s' % (self.uuid, module or self.module, revnum)
+
+ def revnum(self, rev):
+ return int(rev.split('@')[-1])
+
+ def revsplit(self, rev):
+ url, revnum = rev.rsplit('@', 1)
+ revnum = int(revnum)
+ parts = url.split('/', 1)
+ uuid = parts.pop(0)[4:]
+ mod = ''
+ if parts:
+ mod = '/' + parts[0]
+ return uuid, mod, revnum
+
+ def latest(self, path, stop=0):
+ """Find the latest revid affecting path, up to stop. It may return
+ a revision in a different module, since a branch may be moved without
+ a change being reported. Return None if computed module does not
+ belong to rootmodule subtree.
+ """
+ if not path.startswith(self.rootmodule):
+ # Requests on foreign branches may be forbidden at server level
+ self.ui.debug(_('ignoring foreign branch %r\n') % path)
+ return None
+
+ if not stop:
+ stop = svn.ra.get_latest_revnum(self.ra)
+ try:
+ prevmodule = self.reparent('')
+ dirent = svn.ra.stat(self.ra, path.strip('/'), stop)
+ self.reparent(prevmodule)
+ except SubversionException:
+ dirent = None
+ if not dirent:
+ raise SvnPathNotFound(_('%s not found up to revision %d') % (path, stop))
+
+ # stat() gives us the previous revision on this line of
+ # development, but it might be in *another module*. Fetch the
+ # log and detect renames down to the latest revision.
+ stream = self._getlog([path], stop, dirent.created_rev)
+ try:
+ for entry in stream:
+ paths, revnum, author, date, message = entry
+ if revnum <= dirent.created_rev:
+ break
+
+ for p in paths:
+ if not path.startswith(p) or not paths[p].copyfrom_path:
+ continue
+ newpath = paths[p].copyfrom_path + path[len(p):]
+ self.ui.debug(_("branch renamed from %s to %s at %d\n") %
+ (path, newpath, revnum))
+ path = newpath
+ break
+ finally:
+ stream.close()
+
+ if not path.startswith(self.rootmodule):
+ self.ui.debug(_('ignoring foreign branch %r\n') % path)
+ return None
+ return self.revid(dirent.created_rev, path)
+
+ def reparent(self, module):
+ """Reparent the svn transport and return the previous parent."""
+ if self.prevmodule == module:
+ return module
+ svnurl = self.baseurl + urllib.quote(module)
+ prevmodule = self.prevmodule
+ if prevmodule is None:
+ prevmodule = ''
+ self.ui.debug(_("reparent to %s\n") % svnurl)
+ svn.ra.reparent(self.ra, svnurl)
+ self.prevmodule = module
+ return prevmodule
+
+ def expandpaths(self, rev, paths, parents):
+ entries = []
+ # Map of entrypath, revision for finding source of deleted
+ # revisions.
+ copyfrom = {}
+ copies = {}
+
+ new_module, revnum = self.revsplit(rev)[1:]
+ if new_module != self.module:
+ self.module = new_module
+ self.reparent(self.module)
+
+ for path, ent in paths:
+ entrypath = self.getrelpath(path)
+
+ kind = self._checkpath(entrypath, revnum)
+ if kind == svn.core.svn_node_file:
+ entries.append(self.recode(entrypath))
+ if not ent.copyfrom_path or not parents:
+ continue
+ # Copy sources not in parent revisions cannot be
+ # represented, ignore their origin for now
+ pmodule, prevnum = self.revsplit(parents[0])[1:]
+ if ent.copyfrom_rev < prevnum:
+ continue
+ copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule)
+ if not copyfrom_path:
+ continue
+ self.ui.debug(_("copied to %s from %s@%s\n") %
+ (entrypath, copyfrom_path, ent.copyfrom_rev))
+ copies[self.recode(entrypath)] = self.recode(copyfrom_path)
+ elif kind == 0: # gone, but had better be a deleted *file*
+ self.ui.debug(_("gone from %s\n") % ent.copyfrom_rev)
+ pmodule, prevnum = self.revsplit(parents[0])[1:]
+ parentpath = pmodule + "/" + entrypath
+ self.ui.debug(_("entry %s\n") % parentpath)
+
+ # We can avoid the reparent calls if the module has
+ # not changed but it probably does not worth the pain.
+ prevmodule = self.reparent('')
+ fromkind = svn.ra.check_path(self.ra, parentpath.strip('/'), prevnum)
+ self.reparent(prevmodule)
+
+ if fromkind == svn.core.svn_node_file:
+ entries.append(self.recode(entrypath))
+ elif fromkind == svn.core.svn_node_dir:
+ if ent.action == 'C':
+ children = self._find_children(path, prevnum)
+ else:
+ oroot = parentpath.strip('/')
+ nroot = path.strip('/')
+ children = self._find_children(oroot, prevnum)
+ children = [s.replace(oroot,nroot) for s in children]
+
+ for child in children:
+ childpath = self.getrelpath("/" + child, pmodule)
+ if not childpath:
+ continue
+ if childpath in copies:
+ del copies[childpath]
+ entries.append(childpath)
+ else:
+ self.ui.debug(_('unknown path in revision %d: %s\n') % \
+ (revnum, path))
+ elif kind == svn.core.svn_node_dir:
+ # If the directory just had a prop change,
+ # then we shouldn't need to look for its children.
+ if ent.action == 'M':
+ continue
+
+ children = sorted(self._find_children(path, revnum))
+ for child in children:
+ # Can we move a child directory and its
+ # parent in the same commit? (probably can). Could
+ # cause problems if instead of revnum -1,
+ # we have to look in (copyfrom_path, revnum - 1)
+ entrypath = self.getrelpath("/" + child)
+ if entrypath:
+ # Need to filter out directories here...
+ kind = self._checkpath(entrypath, revnum)
+ if kind != svn.core.svn_node_dir:
+ entries.append(self.recode(entrypath))
+
+ # Handle directory copies
+ if not ent.copyfrom_path or not parents:
+ continue
+ # Copy sources not in parent revisions cannot be
+ # represented, ignore their origin for now
+ pmodule, prevnum = self.revsplit(parents[0])[1:]
+ if ent.copyfrom_rev < prevnum:
+ continue
+ copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule)
+ if not copyfrompath:
+ continue
+ copyfrom[path] = ent
+ self.ui.debug(_("mark %s came from %s:%d\n")
+ % (path, copyfrompath, ent.copyfrom_rev))
+ children = self._find_children(ent.copyfrom_path, ent.copyfrom_rev)
+ children.sort()
+ for child in children:
+ entrypath = self.getrelpath("/" + child, pmodule)
+ if not entrypath:
+ continue
+ copytopath = path + entrypath[len(copyfrompath):]
+ copytopath = self.getrelpath(copytopath)
+ copies[self.recode(copytopath)] = self.recode(entrypath)
+
+ return (list(set(entries)), copies)
+
+ def _fetch_revisions(self, from_revnum, to_revnum):
+ if from_revnum < to_revnum:
+ from_revnum, to_revnum = to_revnum, from_revnum
+
+ self.child_cset = None
+
+ def parselogentry(orig_paths, revnum, author, date, message):
+ """Return the parsed commit object or None, and True if
+ the revision is a branch root.
+ """
+ self.ui.debug(_("parsing revision %d (%d changes)\n") %
+ (revnum, len(orig_paths)))
+
+ branched = False
+ rev = self.revid(revnum)
+ # branch log might return entries for a parent we already have
+
+ if rev in self.commits or revnum < to_revnum:
+ return None, branched
+
+ parents = []
+ # check whether this revision is the start of a branch or part
+ # of a branch renaming
+ orig_paths = sorted(orig_paths.iteritems())
+ root_paths = [(p,e) for p,e in orig_paths if self.module.startswith(p)]
+ if root_paths:
+ path, ent = root_paths[-1]
+ if ent.copyfrom_path:
+ branched = True
+ newpath = ent.copyfrom_path + self.module[len(path):]
+ # ent.copyfrom_rev may not be the actual last revision
+ previd = self.latest(newpath, ent.copyfrom_rev)
+ if previd is not None:
+ prevmodule, prevnum = self.revsplit(previd)[1:]
+ if prevnum >= self.startrev:
+ parents = [previd]
+ self.ui.note(_('found parent of branch %s at %d: %s\n') %
+ (self.module, prevnum, prevmodule))
+ else:
+ self.ui.debug(_("no copyfrom path, don't know what to do.\n"))
+
+ paths = []
+ # filter out unrelated paths
+ for path, ent in orig_paths:
+ if self.getrelpath(path) is None:
+ continue
+ paths.append((path, ent))
+
+ # Example SVN datetime. Includes microseconds.
+ # ISO-8601 conformant
+ # '2007-01-04T17:35:00.902377Z'
+ date = util.parsedate(date[:19] + " UTC", ["%Y-%m-%dT%H:%M:%S"])
+
+ log = message and self.recode(message) or ''
+ author = author and self.recode(author) or ''
+ try:
+ branch = self.module.split("/")[-1]
+ if branch == 'trunk':
+ branch = ''
+ except IndexError:
+ branch = None
+
+ cset = commit(author=author,
+ date=util.datestr(date),
+ desc=log,
+ parents=parents,
+ branch=branch,
+ rev=rev)
+
+ self.commits[rev] = cset
+ # The parents list is *shared* among self.paths and the
+ # commit object. Both will be updated below.
+ self.paths[rev] = (paths, cset.parents)
+ if self.child_cset and not self.child_cset.parents:
+ self.child_cset.parents[:] = [rev]
+ self.child_cset = cset
+ return cset, branched
+
+ self.ui.note(_('fetching revision log for "%s" from %d to %d\n') %
+ (self.module, from_revnum, to_revnum))
+
+ try:
+ firstcset = None
+ lastonbranch = False
+ stream = self._getlog([self.module], from_revnum, to_revnum)
+ try:
+ for entry in stream:
+ paths, revnum, author, date, message = entry
+ if revnum < self.startrev:
+ lastonbranch = True
+ break
+ if not paths:
+ self.ui.debug(_('revision %d has no entries\n') % revnum)
+ continue
+ cset, lastonbranch = parselogentry(paths, revnum, author,
+ date, message)
+ if cset:
+ firstcset = cset
+ if lastonbranch:
+ break
+ finally:
+ stream.close()
+
+ if not lastonbranch and firstcset and not firstcset.parents:
+ # The first revision of the sequence (the last fetched one)
+ # has invalid parents if not a branch root. Find the parent
+ # revision now, if any.
+ try:
+ firstrevnum = self.revnum(firstcset.rev)
+ if firstrevnum > 1:
+ latest = self.latest(self.module, firstrevnum - 1)
+ if latest:
+ firstcset.parents.append(latest)
+ except SvnPathNotFound:
+ pass
+ except SubversionException, (inst, num):
+ if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
+ raise util.Abort(_('svn: branch has no revision %s') % to_revnum)
+ raise
+
+ def _getfile(self, file, rev):
+ # TODO: ra.get_file transmits the whole file instead of diffs.
+ mode = ''
+ try:
+ new_module, revnum = self.revsplit(rev)[1:]
+ if self.module != new_module:
+ self.module = new_module
+ self.reparent(self.module)
+ io = StringIO()
+ info = svn.ra.get_file(self.ra, file, revnum, io)
+ data = io.getvalue()
+ # ra.get_files() seems to keep a reference on the input buffer
+ # preventing collection. Release it explicitely.
+ io.close()
+ if isinstance(info, list):
+ info = info[-1]
+ mode = ("svn:executable" in info) and 'x' or ''
+ mode = ("svn:special" in info) and 'l' or mode
+ except SubversionException, e:
+ notfound = (svn.core.SVN_ERR_FS_NOT_FOUND,
+ svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND)
+ if e.apr_err in notfound: # File not found
+ raise IOError()
+ raise
+ if mode == 'l':
+ link_prefix = "link "
+ if data.startswith(link_prefix):
+ data = data[len(link_prefix):]
+ return data, mode
+
+ def _find_children(self, path, revnum):
+ path = path.strip('/')
+ pool = Pool()
+ rpath = '/'.join([self.baseurl, urllib.quote(path)]).strip('/')
+ return ['%s/%s' % (path, x) for x in
+ svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool).keys()]
+
+ def getrelpath(self, path, module=None):
+ if module is None:
+ module = self.module
+ # Given the repository url of this wc, say
+ # "http://server/plone/CMFPlone/branches/Plone-2_0-branch"
+ # extract the "entry" portion (a relative path) from what
+ # svn log --xml says, ie
+ # "/CMFPlone/branches/Plone-2_0-branch/tests/PloneTestCase.py"
+ # that is to say "tests/PloneTestCase.py"
+ if path.startswith(module):
+ relative = path.rstrip('/')[len(module):]
+ if relative.startswith('/'):
+ return relative[1:]
+ elif relative == '':
+ return relative
+
+ # The path is outside our tracked tree...
+ self.ui.debug(_('%r is not under %r, ignoring\n') % (path, module))
+ return None
+
+ def _checkpath(self, path, revnum):
+ # ra.check_path does not like leading slashes very much, it leads
+ # to PROPFIND subversion errors
+ return svn.ra.check_path(self.ra, path.strip('/'), revnum)
+
+ def _getlog(self, paths, start, end, limit=0, discover_changed_paths=True,
+ strict_node_history=False):
+ # Normalize path names, svn >= 1.5 only wants paths relative to
+ # supplied URL
+ relpaths = []
+ for p in paths:
+ if not p.startswith('/'):
+ p = self.module + '/' + p
+ relpaths.append(p.strip('/'))
+ args = [self.baseurl, relpaths, start, end, limit, discover_changed_paths,
+ strict_node_history]
+ arg = encodeargs(args)
+ hgexe = util.hgexecutable()
+ cmd = '%s debugsvnlog' % util.shellquote(hgexe)
+ stdin, stdout = util.popen2(cmd)
+ stdin.write(arg)
+ stdin.close()
+ return logstream(stdout)
+
+pre_revprop_change = '''#!/bin/sh
+
+REPOS="$1"
+REV="$2"
+USER="$3"
+PROPNAME="$4"
+ACTION="$5"
+
+if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi
+if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-branch" ]; then exit 0; fi
+if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-rev" ]; then exit 0; fi
+
+echo "Changing prohibited revision property" >&2
+exit 1
+'''
+
+class svn_sink(converter_sink, commandline):
+ commit_re = re.compile(r'Committed revision (\d+).', re.M)
+
+ def prerun(self):
+ if self.wc:
+ os.chdir(self.wc)
+
+ def postrun(self):
+ if self.wc:
+ os.chdir(self.cwd)
+
+ def join(self, name):
+ return os.path.join(self.wc, '.svn', name)
+
+ def revmapfile(self):
+ return self.join('hg-shamap')
+
+ def authorfile(self):
+ return self.join('hg-authormap')
+
+ def __init__(self, ui, path):
+ converter_sink.__init__(self, ui, path)
+ commandline.__init__(self, ui, 'svn')
+ self.delete = []
+ self.setexec = []
+ self.delexec = []
+ self.copies = []
+ self.wc = None
+ self.cwd = os.getcwd()
+
+ path = os.path.realpath(path)
+
+ created = False
+ if os.path.isfile(os.path.join(path, '.svn', 'entries')):
+ self.wc = path
+ self.run0('update')
+ else:
+ wcpath = os.path.join(os.getcwd(), os.path.basename(path) + '-wc')
+
+ if os.path.isdir(os.path.dirname(path)):
+ if not os.path.exists(os.path.join(path, 'db', 'fs-type')):
+ ui.status(_('initializing svn repo %r\n') %
+ os.path.basename(path))
+ commandline(ui, 'svnadmin').run0('create', path)
+ created = path
+ path = util.normpath(path)
+ if not path.startswith('/'):
+ path = '/' + path
+ path = 'file://' + path
+
+ ui.status(_('initializing svn wc %r\n') % os.path.basename(wcpath))
+ self.run0('checkout', path, wcpath)
+
+ self.wc = wcpath
+ self.opener = util.opener(self.wc)
+ self.wopener = util.opener(self.wc)
+ self.childmap = mapfile(ui, self.join('hg-childmap'))
+ self.is_exec = util.checkexec(self.wc) and util.is_exec or None
+
+ if created:
+ hook = os.path.join(created, 'hooks', 'pre-revprop-change')
+ fp = open(hook, 'w')
+ fp.write(pre_revprop_change)
+ fp.close()
+ util.set_flags(hook, False, True)
+
+ xport = transport.SvnRaTransport(url=geturl(path))
+ self.uuid = svn.ra.get_uuid(xport.ra)
+
+ def wjoin(self, *names):
+ return os.path.join(self.wc, *names)
+
+ def putfile(self, filename, flags, data):
+ if 'l' in flags:
+ self.wopener.symlink(data, filename)
+ else:
+ try:
+ if os.path.islink(self.wjoin(filename)):
+ os.unlink(filename)
+ except OSError:
+ pass
+ self.wopener(filename, 'w').write(data)
+
+ if self.is_exec:
+ was_exec = self.is_exec(self.wjoin(filename))
+ else:
+ # On filesystems not supporting execute-bit, there is no way
+ # to know if it is set but asking subversion. Setting it
+ # systematically is just as expensive and much simpler.
+ was_exec = 'x' not in flags
+
+ util.set_flags(self.wjoin(filename), False, 'x' in flags)
+ if was_exec:
+ if 'x' not in flags:
+ self.delexec.append(filename)
+ else:
+ if 'x' in flags:
+ self.setexec.append(filename)
+
+ def _copyfile(self, source, dest):
+ # SVN's copy command pukes if the destination file exists, but
+ # our copyfile method expects to record a copy that has
+ # already occurred. Cross the semantic gap.
+ wdest = self.wjoin(dest)
+ exists = os.path.exists(wdest)
+ if exists:
+ fd, tempname = tempfile.mkstemp(
+ prefix='hg-copy-', dir=os.path.dirname(wdest))
+ os.close(fd)
+ os.unlink(tempname)
+ os.rename(wdest, tempname)
+ try:
+ self.run0('copy', source, dest)
+ finally:
+ if exists:
+ try:
+ os.unlink(wdest)
+ except OSError:
+ pass
+ os.rename(tempname, wdest)
+
+ def dirs_of(self, files):
+ dirs = set()
+ for f in files:
+ if os.path.isdir(self.wjoin(f)):
+ dirs.add(f)
+ for i in strutil.rfindall(f, '/'):
+ dirs.add(f[:i])
+ return dirs
+
+ def add_dirs(self, files):
+ add_dirs = [d for d in sorted(self.dirs_of(files))
+ if not os.path.exists(self.wjoin(d, '.svn', 'entries'))]
+ if add_dirs:
+ self.xargs(add_dirs, 'add', non_recursive=True, quiet=True)
+ return add_dirs
+
+ def add_files(self, files):
+ if files:
+ self.xargs(files, 'add', quiet=True)
+ return files
+
+ def tidy_dirs(self, names):
+ deleted = []
+ for d in sorted(self.dirs_of(names), reverse=True):
+ wd = self.wjoin(d)
+ if os.listdir(wd) == '.svn':
+ self.run0('delete', d)
+ deleted.append(d)
+ return deleted
+
+ def addchild(self, parent, child):
+ self.childmap[parent] = child
+
+ def revid(self, rev):
+ return u"svn:%s@%s" % (self.uuid, rev)
+
+ def putcommit(self, files, copies, parents, commit, source, revmap):
+ # Apply changes to working copy
+ for f, v in files:
+ try:
+ data = source.getfile(f, v)
+ except IOError:
+ self.delete.append(f)
+ else:
+ e = source.getmode(f, v)
+ self.putfile(f, e, data)
+ if f in copies:
+ self.copies.append([copies[f], f])
+ files = [f[0] for f in files]
+
+ for parent in parents:
+ try:
+ return self.revid(self.childmap[parent])
+ except KeyError:
+ pass
+ entries = set(self.delete)
+ files = frozenset(files)
+ entries.update(self.add_dirs(files.difference(entries)))
+ if self.copies:
+ for s, d in self.copies:
+ self._copyfile(s, d)
+ self.copies = []
+ if self.delete:
+ self.xargs(self.delete, 'delete')
+ self.delete = []
+ entries.update(self.add_files(files.difference(entries)))
+ entries.update(self.tidy_dirs(entries))
+ if self.delexec:
+ self.xargs(self.delexec, 'propdel', 'svn:executable')
+ self.delexec = []
+ if self.setexec:
+ self.xargs(self.setexec, 'propset', 'svn:executable', '*')
+ self.setexec = []
+
+ fd, messagefile = tempfile.mkstemp(prefix='hg-convert-')
+ fp = os.fdopen(fd, 'w')
+ fp.write(commit.desc)
+ fp.close()
+ try:
+ output = self.run0('commit',
+ username=util.shortuser(commit.author),
+ file=messagefile,
+ encoding='utf-8')
+ try:
+ rev = self.commit_re.search(output).group(1)
+ except AttributeError:
+ self.ui.warn(_('unexpected svn output:\n'))
+ self.ui.warn(output)
+ raise util.Abort(_('unable to cope with svn output'))
+ if commit.rev:
+ self.run('propset', 'hg:convert-rev', commit.rev,
+ revprop=True, revision=rev)
+ if commit.branch and commit.branch != 'default':
+ self.run('propset', 'hg:convert-branch', commit.branch,
+ revprop=True, revision=rev)
+ for parent in parents:
+ self.addchild(parent, rev)
+ return self.revid(rev)
+ finally:
+ os.unlink(messagefile)
+
+ def puttags(self, tags):
+ self.ui.warn(_('XXX TAGS NOT IMPLEMENTED YET\n'))
diff --git a/sys/src/cmd/hg/hgext/convert/transport.py b/sys/src/cmd/hg/hgext/convert/transport.py
new file mode 100644
index 000000000..0d77cca4d
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/convert/transport.py
@@ -0,0 +1,128 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2007 Daniel Holth <dholth@fastmail.fm>
+# This is a stripped-down version of the original bzr-svn transport.py,
+# Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org>
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+from svn.core import SubversionException, Pool
+import svn.ra
+import svn.client
+import svn.core
+
+# Some older versions of the Python bindings need to be
+# explicitly initialized. But what we want to do probably
+# won't work worth a darn against those libraries anyway!
+svn.ra.initialize()
+
+svn_config = svn.core.svn_config_get_config(None)
+
+
+def _create_auth_baton(pool):
+ """Create a Subversion authentication baton. """
+ import svn.client
+ # Give the client context baton a suite of authentication
+ # providers.h
+ providers = [
+ svn.client.get_simple_provider(pool),
+ svn.client.get_username_provider(pool),
+ svn.client.get_ssl_client_cert_file_provider(pool),
+ svn.client.get_ssl_client_cert_pw_file_provider(pool),
+ svn.client.get_ssl_server_trust_file_provider(pool),
+ ]
+ # Platform-dependant authentication methods
+ getprovider = getattr(svn.core, 'svn_auth_get_platform_specific_provider',
+ None)
+ if getprovider:
+ # Available in svn >= 1.6
+ for name in ('gnome_keyring', 'keychain', 'kwallet', 'windows'):
+ for type in ('simple', 'ssl_client_cert_pw', 'ssl_server_trust'):
+ p = getprovider(name, type, pool)
+ if p:
+ providers.append(p)
+ else:
+ if hasattr(svn.client, 'get_windows_simple_provider'):
+ providers.append(svn.client.get_windows_simple_provider(pool))
+
+ return svn.core.svn_auth_open(providers, pool)
+
+class NotBranchError(SubversionException):
+ pass
+
+class SvnRaTransport(object):
+ """
+ Open an ra connection to a Subversion repository.
+ """
+ def __init__(self, url="", ra=None):
+ self.pool = Pool()
+ self.svn_url = url
+ self.username = ''
+ self.password = ''
+
+ # Only Subversion 1.4 has reparent()
+ if ra is None or not hasattr(svn.ra, 'reparent'):
+ self.client = svn.client.create_context(self.pool)
+ ab = _create_auth_baton(self.pool)
+ if False:
+ svn.core.svn_auth_set_parameter(
+ ab, svn.core.SVN_AUTH_PARAM_DEFAULT_USERNAME, self.username)
+ svn.core.svn_auth_set_parameter(
+ ab, svn.core.SVN_AUTH_PARAM_DEFAULT_PASSWORD, self.password)
+ self.client.auth_baton = ab
+ self.client.config = svn_config
+ try:
+ self.ra = svn.client.open_ra_session(
+ self.svn_url.encode('utf8'),
+ self.client, self.pool)
+ except SubversionException, (inst, num):
+ if num in (svn.core.SVN_ERR_RA_ILLEGAL_URL,
+ svn.core.SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED,
+ svn.core.SVN_ERR_BAD_URL):
+ raise NotBranchError(url)
+ raise
+ else:
+ self.ra = ra
+ svn.ra.reparent(self.ra, self.svn_url.encode('utf8'))
+
+ class Reporter(object):
+ def __init__(self, (reporter, report_baton)):
+ self._reporter = reporter
+ self._baton = report_baton
+
+ def set_path(self, path, revnum, start_empty, lock_token, pool=None):
+ svn.ra.reporter2_invoke_set_path(self._reporter, self._baton,
+ path, revnum, start_empty, lock_token, pool)
+
+ def delete_path(self, path, pool=None):
+ svn.ra.reporter2_invoke_delete_path(self._reporter, self._baton,
+ path, pool)
+
+ def link_path(self, path, url, revision, start_empty, lock_token,
+ pool=None):
+ svn.ra.reporter2_invoke_link_path(self._reporter, self._baton,
+ path, url, revision, start_empty, lock_token,
+ pool)
+
+ def finish_report(self, pool=None):
+ svn.ra.reporter2_invoke_finish_report(self._reporter,
+ self._baton, pool)
+
+ def abort_report(self, pool=None):
+ svn.ra.reporter2_invoke_abort_report(self._reporter,
+ self._baton, pool)
+
+ def do_update(self, revnum, path, *args, **kwargs):
+ return self.Reporter(svn.ra.do_update(self.ra, revnum, path, *args, **kwargs))
diff --git a/sys/src/cmd/hg/hgext/extdiff.py b/sys/src/cmd/hg/hgext/extdiff.py
new file mode 100644
index 000000000..56e29f4df
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/extdiff.py
@@ -0,0 +1,228 @@
+# extdiff.py - external diff program support for mercurial
+#
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''command to allow external programs to compare revisions
+
+The extdiff Mercurial extension allows you to use external programs
+to compare revisions, or revision with working directory. The external
+diff programs are called with a configurable set of options and two
+non-option arguments: paths to directories containing snapshots of
+files to compare.
+
+The extdiff extension also allows to configure new diff commands, so
+you do not need to type "hg extdiff -p kdiff3" always. ::
+
+ [extdiff]
+ # add new command that runs GNU diff(1) in 'context diff' mode
+ cdiff = gdiff -Nprc5
+ ## or the old way:
+ #cmd.cdiff = gdiff
+ #opts.cdiff = -Nprc5
+
+ # add new command called vdiff, runs kdiff3
+ vdiff = kdiff3
+
+ # add new command called meld, runs meld (no need to name twice)
+ meld =
+
+ # add new command called vimdiff, runs gvimdiff with DirDiff plugin
+ # (see http://www.vim.org/scripts/script.php?script_id=102) Non
+ # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
+ # your .vimrc
+ vimdiff = gvim -f '+next' '+execute "DirDiff" argv(0) argv(1)'
+
+You can use -I/-X and list of file or directory names like normal "hg
+diff" command. The extdiff extension makes snapshots of only needed
+files, so running the external diff program will actually be pretty
+fast (at least faster than having to compare the entire tree).
+'''
+
+from mercurial.i18n import _
+from mercurial.node import short
+from mercurial import cmdutil, util, commands
+import os, shlex, shutil, tempfile
+
+def snapshot(ui, repo, files, node, tmproot):
+ '''snapshot files as of some revision
+ if not using snapshot, -I/-X does not work and recursive diff
+ in tools like kdiff3 and meld displays too many files.'''
+ dirname = os.path.basename(repo.root)
+ if dirname == "":
+ dirname = "root"
+ if node is not None:
+ dirname = '%s.%s' % (dirname, short(node))
+ base = os.path.join(tmproot, dirname)
+ os.mkdir(base)
+ if node is not None:
+ ui.note(_('making snapshot of %d files from rev %s\n') %
+ (len(files), short(node)))
+ else:
+ ui.note(_('making snapshot of %d files from working directory\n') %
+ (len(files)))
+ wopener = util.opener(base)
+ fns_and_mtime = []
+ ctx = repo[node]
+ for fn in files:
+ wfn = util.pconvert(fn)
+ if not wfn in ctx:
+ # skipping new file after a merge ?
+ continue
+ ui.note(' %s\n' % wfn)
+ dest = os.path.join(base, wfn)
+ fctx = ctx[wfn]
+ data = repo.wwritedata(wfn, fctx.data())
+ if 'l' in fctx.flags():
+ wopener.symlink(data, wfn)
+ else:
+ wopener(wfn, 'w').write(data)
+ if 'x' in fctx.flags():
+ util.set_flags(dest, False, True)
+ if node is None:
+ fns_and_mtime.append((dest, repo.wjoin(fn), os.path.getmtime(dest)))
+ return dirname, fns_and_mtime
+
+def dodiff(ui, repo, diffcmd, diffopts, pats, opts):
+ '''Do the actuall diff:
+
+ - copy to a temp structure if diffing 2 internal revisions
+ - copy to a temp structure if diffing working revision with
+ another one and more than 1 file is changed
+ - just invoke the diff for a single file in the working dir
+ '''
+
+ revs = opts.get('rev')
+ change = opts.get('change')
+
+ if revs and change:
+ msg = _('cannot specify --rev and --change at the same time')
+ raise util.Abort(msg)
+ elif change:
+ node2 = repo.lookup(change)
+ node1 = repo[node2].parents()[0].node()
+ else:
+ node1, node2 = cmdutil.revpair(repo, revs)
+
+ matcher = cmdutil.match(repo, pats, opts)
+ modified, added, removed = repo.status(node1, node2, matcher)[:3]
+ if not (modified or added or removed):
+ return 0
+
+ tmproot = tempfile.mkdtemp(prefix='extdiff.')
+ dir2root = ''
+ try:
+ # Always make a copy of node1
+ dir1 = snapshot(ui, repo, modified + removed, node1, tmproot)[0]
+ changes = len(modified) + len(removed) + len(added)
+
+ # If node2 in not the wc or there is >1 change, copy it
+ if node2 or changes > 1:
+ dir2, fns_and_mtime = snapshot(ui, repo, modified + added, node2, tmproot)
+ else:
+ # This lets the diff tool open the changed file directly
+ dir2 = ''
+ dir2root = repo.root
+ fns_and_mtime = []
+
+ # If only one change, diff the files instead of the directories
+ if changes == 1 :
+ if len(modified):
+ dir1 = os.path.join(dir1, util.localpath(modified[0]))
+ dir2 = os.path.join(dir2root, dir2, util.localpath(modified[0]))
+ elif len(removed) :
+ dir1 = os.path.join(dir1, util.localpath(removed[0]))
+ dir2 = os.devnull
+ else:
+ dir1 = os.devnull
+ dir2 = os.path.join(dir2root, dir2, util.localpath(added[0]))
+
+ cmdline = ('%s %s %s %s' %
+ (util.shellquote(diffcmd), ' '.join(diffopts),
+ util.shellquote(dir1), util.shellquote(dir2)))
+ ui.debug(_('running %r in %s\n') % (cmdline, tmproot))
+ util.system(cmdline, cwd=tmproot)
+
+ for copy_fn, working_fn, mtime in fns_and_mtime:
+ if os.path.getmtime(copy_fn) != mtime:
+ ui.debug(_('file changed while diffing. '
+ 'Overwriting: %s (src: %s)\n') % (working_fn, copy_fn))
+ util.copyfile(copy_fn, working_fn)
+
+ return 1
+ finally:
+ ui.note(_('cleaning up temp directory\n'))
+ shutil.rmtree(tmproot)
+
+def extdiff(ui, repo, *pats, **opts):
+ '''use external program to diff repository (or selected files)
+
+ Show differences between revisions for the specified files, using
+ an external program. The default program used is diff, with
+ default options "-Npru".
+
+ To select a different program, use the -p/--program option. The
+ program will be passed the names of two directories to compare. To
+ pass additional options to the program, use -o/--option. These
+ will be passed before the names of the directories to compare.
+
+ When two revision arguments are given, then changes are shown
+ between those revisions. If only one revision is specified then
+ that revision is compared to the working directory, and, when no
+ revisions are specified, the working directory files are compared
+ to its parent.'''
+ program = opts['program'] or 'diff'
+ if opts['program']:
+ option = opts['option']
+ else:
+ option = opts['option'] or ['-Npru']
+ return dodiff(ui, repo, program, option, pats, opts)
+
+cmdtable = {
+ "extdiff":
+ (extdiff,
+ [('p', 'program', '', _('comparison program to run')),
+ ('o', 'option', [], _('pass option to comparison program')),
+ ('r', 'rev', [], _('revision')),
+ ('c', 'change', '', _('change made by revision')),
+ ] + commands.walkopts,
+ _('hg extdiff [OPT]... [FILE]...')),
+ }
+
+def uisetup(ui):
+ for cmd, path in ui.configitems('extdiff'):
+ if cmd.startswith('cmd.'):
+ cmd = cmd[4:]
+ if not path: path = cmd
+ diffopts = ui.config('extdiff', 'opts.' + cmd, '')
+ diffopts = diffopts and [diffopts] or []
+ elif cmd.startswith('opts.'):
+ continue
+ else:
+ # command = path opts
+ if path:
+ diffopts = shlex.split(path)
+ path = diffopts.pop(0)
+ else:
+ path, diffopts = cmd, []
+ def save(cmd, path, diffopts):
+ '''use closure to save diff command to use'''
+ def mydiff(ui, repo, *pats, **opts):
+ return dodiff(ui, repo, path, diffopts, pats, opts)
+ mydiff.__doc__ = _('''\
+use %(path)s to diff repository (or selected files)
+
+ Show differences between revisions for the specified files, using the
+ %(path)s program.
+
+ When two revision arguments are given, then changes are shown between
+ those revisions. If only one revision is specified then that revision is
+ compared to the working directory, and, when no revisions are specified,
+ the working directory files are compared to its parent.\
+''') % dict(path=util.uirepr(path))
+ return mydiff
+ cmdtable[cmd] = (save(cmd, path, diffopts),
+ cmdtable['extdiff'][1][1:],
+ _('hg %s [OPTION]... [FILE]...') % cmd)
diff --git a/sys/src/cmd/hg/hgext/fetch.py b/sys/src/cmd/hg/hgext/fetch.py
new file mode 100644
index 000000000..05cd3fcc3
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/fetch.py
@@ -0,0 +1,148 @@
+# fetch.py - pull and merge remote changes
+#
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''pull, update and merge in one command'''
+
+from mercurial.i18n import _
+from mercurial.node import nullid, short
+from mercurial import commands, cmdutil, hg, util, url, error
+from mercurial.lock import release
+
+def fetch(ui, repo, source='default', **opts):
+ '''pull changes from a remote repository, merge new changes if needed.
+
+ This finds all changes from the repository at the specified path
+ or URL and adds them to the local repository.
+
+ If the pulled changes add a new branch head, the head is
+ automatically merged, and the result of the merge is committed.
+ Otherwise, the working directory is updated to include the new
+ changes.
+
+ When a merge occurs, the newly pulled changes are assumed to be
+ "authoritative". The head of the new changes is used as the first
+ parent, with local changes as the second. To switch the merge
+ order, use --switch-parent.
+
+ See 'hg help dates' for a list of formats valid for -d/--date.
+ '''
+
+ date = opts.get('date')
+ if date:
+ opts['date'] = util.parsedate(date)
+
+ parent, p2 = repo.dirstate.parents()
+ branch = repo.dirstate.branch()
+ branchnode = repo.branchtags().get(branch)
+ if parent != branchnode:
+ raise util.Abort(_('working dir not at branch tip '
+ '(use "hg update" to check out branch tip)'))
+
+ if p2 != nullid:
+ raise util.Abort(_('outstanding uncommitted merge'))
+
+ wlock = lock = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ mod, add, rem, del_ = repo.status()[:4]
+
+ if mod or add or rem:
+ raise util.Abort(_('outstanding uncommitted changes'))
+ if del_:
+ raise util.Abort(_('working directory is missing some files'))
+ bheads = repo.branchheads(branch)
+ bheads = [head for head in bheads if len(repo[head].children()) == 0]
+ if len(bheads) > 1:
+ raise util.Abort(_('multiple heads in this branch '
+ '(use "hg heads ." and "hg merge" to merge)'))
+
+ other = hg.repository(cmdutil.remoteui(repo, opts),
+ ui.expandpath(source))
+ ui.status(_('pulling from %s\n') %
+ url.hidepassword(ui.expandpath(source)))
+ revs = None
+ if opts['rev']:
+ try:
+ revs = [other.lookup(rev) for rev in opts['rev']]
+ except error.CapabilityError:
+ err = _("Other repository doesn't support revision lookup, "
+ "so a rev cannot be specified.")
+ raise util.Abort(err)
+
+ # Are there any changes at all?
+ modheads = repo.pull(other, heads=revs)
+ if modheads == 0:
+ return 0
+
+ # Is this a simple fast-forward along the current branch?
+ newheads = repo.branchheads(branch)
+ newheads = [head for head in newheads if len(repo[head].children()) == 0]
+ newchildren = repo.changelog.nodesbetween([parent], newheads)[2]
+ if len(newheads) == 1:
+ if newchildren[0] != parent:
+ return hg.clean(repo, newchildren[0])
+ else:
+ return
+
+ # Are there more than one additional branch heads?
+ newchildren = [n for n in newchildren if n != parent]
+ newparent = parent
+ if newchildren:
+ newparent = newchildren[0]
+ hg.clean(repo, newparent)
+ newheads = [n for n in newheads if n != newparent]
+ if len(newheads) > 1:
+ ui.status(_('not merging with %d other new branch heads '
+ '(use "hg heads ." and "hg merge" to merge them)\n') %
+ (len(newheads) - 1))
+ return
+
+ # Otherwise, let's merge.
+ err = False
+ if newheads:
+ # By default, we consider the repository we're pulling
+ # *from* as authoritative, so we merge our changes into
+ # theirs.
+ if opts['switch_parent']:
+ firstparent, secondparent = newparent, newheads[0]
+ else:
+ firstparent, secondparent = newheads[0], newparent
+ ui.status(_('updating to %d:%s\n') %
+ (repo.changelog.rev(firstparent),
+ short(firstparent)))
+ hg.clean(repo, firstparent)
+ ui.status(_('merging with %d:%s\n') %
+ (repo.changelog.rev(secondparent), short(secondparent)))
+ err = hg.merge(repo, secondparent, remind=False)
+
+ if not err:
+ # we don't translate commit messages
+ message = (cmdutil.logmessage(opts) or
+ ('Automated merge with %s' %
+ url.removeauth(other.url())))
+ editor = cmdutil.commiteditor
+ if opts.get('force_editor') or opts.get('edit'):
+ editor = cmdutil.commitforceeditor
+ n = repo.commit(message, opts['user'], opts['date'], editor=editor)
+ ui.status(_('new changeset %d:%s merges remote changes '
+ 'with local\n') % (repo.changelog.rev(n),
+ short(n)))
+
+ finally:
+ release(lock, wlock)
+
+cmdtable = {
+ 'fetch':
+ (fetch,
+ [('r', 'rev', [], _('a specific revision you would like to pull')),
+ ('e', 'edit', None, _('edit commit message')),
+ ('', 'force-editor', None, _('edit commit message (DEPRECATED)')),
+ ('', 'switch-parent', None, _('switch parents when merging')),
+ ] + commands.commitopts + commands.commitopts2 + commands.remoteopts,
+ _('hg fetch [SOURCE]')),
+}
diff --git a/sys/src/cmd/hg/hgext/gpg.py b/sys/src/cmd/hg/hgext/gpg.py
new file mode 100644
index 000000000..4a2f07d8e
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/gpg.py
@@ -0,0 +1,284 @@
+# Copyright 2005, 2006 Benoit Boissinot <benoit.boissinot@ens-lyon.org>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''commands to sign and verify changesets'''
+
+import os, tempfile, binascii
+from mercurial import util, commands, match
+from mercurial import node as hgnode
+from mercurial.i18n import _
+
+class gpg(object):
+ def __init__(self, path, key=None):
+ self.path = path
+ self.key = (key and " --local-user \"%s\"" % key) or ""
+
+ def sign(self, data):
+ gpgcmd = "%s --sign --detach-sign%s" % (self.path, self.key)
+ return util.filter(data, gpgcmd)
+
+ def verify(self, data, sig):
+ """ returns of the good and bad signatures"""
+ sigfile = datafile = None
+ try:
+ # create temporary files
+ fd, sigfile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".sig")
+ fp = os.fdopen(fd, 'wb')
+ fp.write(sig)
+ fp.close()
+ fd, datafile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".txt")
+ fp = os.fdopen(fd, 'wb')
+ fp.write(data)
+ fp.close()
+ gpgcmd = ("%s --logger-fd 1 --status-fd 1 --verify "
+ "\"%s\" \"%s\"" % (self.path, sigfile, datafile))
+ ret = util.filter("", gpgcmd)
+ finally:
+ for f in (sigfile, datafile):
+ try:
+ if f: os.unlink(f)
+ except: pass
+ keys = []
+ key, fingerprint = None, None
+ err = ""
+ for l in ret.splitlines():
+ # see DETAILS in the gnupg documentation
+ # filter the logger output
+ if not l.startswith("[GNUPG:]"):
+ continue
+ l = l[9:]
+ if l.startswith("ERRSIG"):
+ err = _("error while verifying signature")
+ break
+ elif l.startswith("VALIDSIG"):
+ # fingerprint of the primary key
+ fingerprint = l.split()[10]
+ elif (l.startswith("GOODSIG") or
+ l.startswith("EXPSIG") or
+ l.startswith("EXPKEYSIG") or
+ l.startswith("BADSIG")):
+ if key is not None:
+ keys.append(key + [fingerprint])
+ key = l.split(" ", 2)
+ fingerprint = None
+ if err:
+ return err, []
+ if key is not None:
+ keys.append(key + [fingerprint])
+ return err, keys
+
+def newgpg(ui, **opts):
+ """create a new gpg instance"""
+ gpgpath = ui.config("gpg", "cmd", "gpg")
+ gpgkey = opts.get('key')
+ if not gpgkey:
+ gpgkey = ui.config("gpg", "key", None)
+ return gpg(gpgpath, gpgkey)
+
+def sigwalk(repo):
+ """
+ walk over every sigs, yields a couple
+ ((node, version, sig), (filename, linenumber))
+ """
+ def parsefile(fileiter, context):
+ ln = 1
+ for l in fileiter:
+ if not l:
+ continue
+ yield (l.split(" ", 2), (context, ln))
+ ln +=1
+
+ # read the heads
+ fl = repo.file(".hgsigs")
+ for r in reversed(fl.heads()):
+ fn = ".hgsigs|%s" % hgnode.short(r)
+ for item in parsefile(fl.read(r).splitlines(), fn):
+ yield item
+ try:
+ # read local signatures
+ fn = "localsigs"
+ for item in parsefile(repo.opener(fn), fn):
+ yield item
+ except IOError:
+ pass
+
+def getkeys(ui, repo, mygpg, sigdata, context):
+ """get the keys who signed a data"""
+ fn, ln = context
+ node, version, sig = sigdata
+ prefix = "%s:%d" % (fn, ln)
+ node = hgnode.bin(node)
+
+ data = node2txt(repo, node, version)
+ sig = binascii.a2b_base64(sig)
+ err, keys = mygpg.verify(data, sig)
+ if err:
+ ui.warn("%s:%d %s\n" % (fn, ln , err))
+ return None
+
+ validkeys = []
+ # warn for expired key and/or sigs
+ for key in keys:
+ if key[0] == "BADSIG":
+ ui.write(_("%s Bad signature from \"%s\"\n") % (prefix, key[2]))
+ continue
+ if key[0] == "EXPSIG":
+ ui.write(_("%s Note: Signature has expired"
+ " (signed by: \"%s\")\n") % (prefix, key[2]))
+ elif key[0] == "EXPKEYSIG":
+ ui.write(_("%s Note: This key has expired"
+ " (signed by: \"%s\")\n") % (prefix, key[2]))
+ validkeys.append((key[1], key[2], key[3]))
+ return validkeys
+
+def sigs(ui, repo):
+ """list signed changesets"""
+ mygpg = newgpg(ui)
+ revs = {}
+
+ for data, context in sigwalk(repo):
+ node, version, sig = data
+ fn, ln = context
+ try:
+ n = repo.lookup(node)
+ except KeyError:
+ ui.warn(_("%s:%d node does not exist\n") % (fn, ln))
+ continue
+ r = repo.changelog.rev(n)
+ keys = getkeys(ui, repo, mygpg, data, context)
+ if not keys:
+ continue
+ revs.setdefault(r, [])
+ revs[r].extend(keys)
+ for rev in sorted(revs, reverse=True):
+ for k in revs[rev]:
+ r = "%5d:%s" % (rev, hgnode.hex(repo.changelog.node(rev)))
+ ui.write("%-30s %s\n" % (keystr(ui, k), r))
+
+def check(ui, repo, rev):
+ """verify all the signatures there may be for a particular revision"""
+ mygpg = newgpg(ui)
+ rev = repo.lookup(rev)
+ hexrev = hgnode.hex(rev)
+ keys = []
+
+ for data, context in sigwalk(repo):
+ node, version, sig = data
+ if node == hexrev:
+ k = getkeys(ui, repo, mygpg, data, context)
+ if k:
+ keys.extend(k)
+
+ if not keys:
+ ui.write(_("No valid signature for %s\n") % hgnode.short(rev))
+ return
+
+ # print summary
+ ui.write("%s is signed by:\n" % hgnode.short(rev))
+ for key in keys:
+ ui.write(" %s\n" % keystr(ui, key))
+
+def keystr(ui, key):
+ """associate a string to a key (username, comment)"""
+ keyid, user, fingerprint = key
+ comment = ui.config("gpg", fingerprint, None)
+ if comment:
+ return "%s (%s)" % (user, comment)
+ else:
+ return user
+
+def sign(ui, repo, *revs, **opts):
+ """add a signature for the current or given revision
+
+ If no revision is given, the parent of the working directory is used,
+ or tip if no revision is checked out.
+
+ See 'hg help dates' for a list of formats valid for -d/--date.
+ """
+
+ mygpg = newgpg(ui, **opts)
+ sigver = "0"
+ sigmessage = ""
+
+ date = opts.get('date')
+ if date:
+ opts['date'] = util.parsedate(date)
+
+ if revs:
+ nodes = [repo.lookup(n) for n in revs]
+ else:
+ nodes = [node for node in repo.dirstate.parents()
+ if node != hgnode.nullid]
+ if len(nodes) > 1:
+ raise util.Abort(_('uncommitted merge - please provide a '
+ 'specific revision'))
+ if not nodes:
+ nodes = [repo.changelog.tip()]
+
+ for n in nodes:
+ hexnode = hgnode.hex(n)
+ ui.write("Signing %d:%s\n" % (repo.changelog.rev(n),
+ hgnode.short(n)))
+ # build data
+ data = node2txt(repo, n, sigver)
+ sig = mygpg.sign(data)
+ if not sig:
+ raise util.Abort(_("Error while signing"))
+ sig = binascii.b2a_base64(sig)
+ sig = sig.replace("\n", "")
+ sigmessage += "%s %s %s\n" % (hexnode, sigver, sig)
+
+ # write it
+ if opts['local']:
+ repo.opener("localsigs", "ab").write(sigmessage)
+ return
+
+ for x in repo.status(unknown=True)[:5]:
+ if ".hgsigs" in x and not opts["force"]:
+ raise util.Abort(_("working copy of .hgsigs is changed "
+ "(please commit .hgsigs manually "
+ "or use --force)"))
+
+ repo.wfile(".hgsigs", "ab").write(sigmessage)
+
+ if '.hgsigs' not in repo.dirstate:
+ repo.add([".hgsigs"])
+
+ if opts["no_commit"]:
+ return
+
+ message = opts['message']
+ if not message:
+ # we don't translate commit messages
+ message = "\n".join(["Added signature for changeset %s"
+ % hgnode.short(n)
+ for n in nodes])
+ try:
+ m = match.exact(repo.root, '', ['.hgsigs'])
+ repo.commit(message, opts['user'], opts['date'], match=m)
+ except ValueError, inst:
+ raise util.Abort(str(inst))
+
+def node2txt(repo, node, ver):
+ """map a manifest into some text"""
+ if ver == "0":
+ return "%s\n" % hgnode.hex(node)
+ else:
+ raise util.Abort(_("unknown signature version"))
+
+cmdtable = {
+ "sign":
+ (sign,
+ [('l', 'local', None, _('make the signature local')),
+ ('f', 'force', None, _('sign even if the sigfile is modified')),
+ ('', 'no-commit', None, _('do not commit the sigfile after signing')),
+ ('k', 'key', '', _('the key id to sign with')),
+ ('m', 'message', '', _('commit message')),
+ ] + commands.commitopts2,
+ _('hg sign [OPTION]... [REVISION]...')),
+ "sigcheck": (check, [], _('hg sigcheck REVISION')),
+ "sigs": (sigs, [], _('hg sigs')),
+}
+
diff --git a/sys/src/cmd/hg/hgext/graphlog.py b/sys/src/cmd/hg/hgext/graphlog.py
new file mode 100644
index 000000000..d77edf931
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/graphlog.py
@@ -0,0 +1,378 @@
+# ASCII graph log extension for Mercurial
+#
+# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''command to view revision graphs from a shell
+
+This extension adds a --graph option to the incoming, outgoing and log
+commands. When this options is given, an ASCII representation of the
+revision graph is also shown.
+'''
+
+import os, sys
+from mercurial.cmdutil import revrange, show_changeset
+from mercurial.commands import templateopts
+from mercurial.i18n import _
+from mercurial.node import nullrev
+from mercurial import bundlerepo, changegroup, cmdutil, commands, extensions
+from mercurial import hg, url, util, graphmod
+
+ASCIIDATA = 'ASC'
+
+def asciiformat(ui, repo, revdag, opts, parentrepo=None):
+ """formats a changelog DAG walk for ASCII output"""
+ if parentrepo is None:
+ parentrepo = repo
+ showparents = [ctx.node() for ctx in parentrepo[None].parents()]
+ displayer = show_changeset(ui, repo, opts, buffered=True)
+ for (id, type, ctx, parentids) in revdag:
+ if type != graphmod.CHANGESET:
+ continue
+ displayer.show(ctx)
+ lines = displayer.hunk.pop(ctx.rev()).split('\n')[:-1]
+ char = ctx.node() in showparents and '@' or 'o'
+ yield (id, ASCIIDATA, (char, lines), parentids)
+
+def asciiedges(nodes):
+ """adds edge info to changelog DAG walk suitable for ascii()"""
+ seen = []
+ for node, type, data, parents in nodes:
+ if node not in seen:
+ seen.append(node)
+ nodeidx = seen.index(node)
+
+ knownparents = []
+ newparents = []
+ for parent in parents:
+ if parent in seen:
+ knownparents.append(parent)
+ else:
+ newparents.append(parent)
+
+ ncols = len(seen)
+ nextseen = seen[:]
+ nextseen[nodeidx:nodeidx + 1] = newparents
+ edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
+
+ if len(newparents) > 0:
+ edges.append((nodeidx, nodeidx))
+ if len(newparents) > 1:
+ edges.append((nodeidx, nodeidx + 1))
+ nmorecols = len(nextseen) - ncols
+ seen = nextseen
+ yield (nodeidx, type, data, edges, ncols, nmorecols)
+
+def fix_long_right_edges(edges):
+ for (i, (start, end)) in enumerate(edges):
+ if end > start:
+ edges[i] = (start, end + 1)
+
+def get_nodeline_edges_tail(
+ node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
+ if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
+ # Still going in the same non-vertical direction.
+ if n_columns_diff == -1:
+ start = max(node_index + 1, p_node_index)
+ tail = ["|", " "] * (start - node_index - 1)
+ tail.extend(["/", " "] * (n_columns - start))
+ return tail
+ else:
+ return ["\\", " "] * (n_columns - node_index - 1)
+ else:
+ return ["|", " "] * (n_columns - node_index - 1)
+
+def draw_edges(edges, nodeline, interline):
+ for (start, end) in edges:
+ if start == end + 1:
+ interline[2 * end + 1] = "/"
+ elif start == end - 1:
+ interline[2 * start + 1] = "\\"
+ elif start == end:
+ interline[2 * start] = "|"
+ else:
+ nodeline[2 * end] = "+"
+ if start > end:
+ (start, end) = (end, start)
+ for i in range(2 * start + 1, 2 * end):
+ if nodeline[i] != "+":
+ nodeline[i] = "-"
+
+def get_padding_line(ni, n_columns, edges):
+ line = []
+ line.extend(["|", " "] * ni)
+ if (ni, ni - 1) in edges or (ni, ni) in edges:
+ # (ni, ni - 1) (ni, ni)
+ # | | | | | | | |
+ # +---o | | o---+
+ # | | c | | c | |
+ # | |/ / | |/ /
+ # | | | | | |
+ c = "|"
+ else:
+ c = " "
+ line.extend([c, " "])
+ line.extend(["|", " "] * (n_columns - ni - 1))
+ return line
+
+def ascii(ui, dag):
+ """prints an ASCII graph of the DAG
+
+ dag is a generator that emits tuples with the following elements:
+
+ - Column of the current node in the set of ongoing edges.
+ - Type indicator of node data == ASCIIDATA.
+ - Payload: (char, lines):
+ - Character to use as node's symbol.
+ - List of lines to display as the node's text.
+ - Edges; a list of (col, next_col) indicating the edges between
+ the current node and its parents.
+ - Number of columns (ongoing edges) in the current revision.
+ - The difference between the number of columns (ongoing edges)
+ in the next revision and the number of columns (ongoing edges)
+ in the current revision. That is: -1 means one column removed;
+ 0 means no columns added or removed; 1 means one column added.
+ """
+ prev_n_columns_diff = 0
+ prev_node_index = 0
+ for (node_index, type, (node_ch, node_lines), edges, n_columns, n_columns_diff) in dag:
+
+ assert -2 < n_columns_diff < 2
+ if n_columns_diff == -1:
+ # Transform
+ #
+ # | | | | | |
+ # o | | into o---+
+ # |X / |/ /
+ # | | | |
+ fix_long_right_edges(edges)
+
+ # add_padding_line says whether to rewrite
+ #
+ # | | | | | | | |
+ # | o---+ into | o---+
+ # | / / | | | # <--- padding line
+ # o | | | / /
+ # o | |
+ add_padding_line = (len(node_lines) > 2 and
+ n_columns_diff == -1 and
+ [x for (x, y) in edges if x + 1 < y])
+
+ # fix_nodeline_tail says whether to rewrite
+ #
+ # | | o | | | | o | |
+ # | | |/ / | | |/ /
+ # | o | | into | o / / # <--- fixed nodeline tail
+ # | |/ / | |/ /
+ # o | | o | |
+ fix_nodeline_tail = len(node_lines) <= 2 and not add_padding_line
+
+ # nodeline is the line containing the node character (typically o)
+ nodeline = ["|", " "] * node_index
+ nodeline.extend([node_ch, " "])
+
+ nodeline.extend(
+ get_nodeline_edges_tail(
+ node_index, prev_node_index, n_columns, n_columns_diff,
+ prev_n_columns_diff, fix_nodeline_tail))
+
+ # shift_interline is the line containing the non-vertical
+ # edges between this entry and the next
+ shift_interline = ["|", " "] * node_index
+ if n_columns_diff == -1:
+ n_spaces = 1
+ edge_ch = "/"
+ elif n_columns_diff == 0:
+ n_spaces = 2
+ edge_ch = "|"
+ else:
+ n_spaces = 3
+ edge_ch = "\\"
+ shift_interline.extend(n_spaces * [" "])
+ shift_interline.extend([edge_ch, " "] * (n_columns - node_index - 1))
+
+ # draw edges from the current node to its parents
+ draw_edges(edges, nodeline, shift_interline)
+
+ # lines is the list of all graph lines to print
+ lines = [nodeline]
+ if add_padding_line:
+ lines.append(get_padding_line(node_index, n_columns, edges))
+ lines.append(shift_interline)
+
+ # make sure that there are as many graph lines as there are
+ # log strings
+ while len(node_lines) < len(lines):
+ node_lines.append("")
+ if len(lines) < len(node_lines):
+ extra_interline = ["|", " "] * (n_columns + n_columns_diff)
+ while len(lines) < len(node_lines):
+ lines.append(extra_interline)
+
+ # print lines
+ indentation_level = max(n_columns, n_columns + n_columns_diff)
+ for (line, logstr) in zip(lines, node_lines):
+ ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
+ ui.write(ln.rstrip() + '\n')
+
+ # ... and start over
+ prev_node_index = node_index
+ prev_n_columns_diff = n_columns_diff
+
+def get_revs(repo, rev_opt):
+ if rev_opt:
+ revs = revrange(repo, rev_opt)
+ return (max(revs), min(revs))
+ else:
+ return (len(repo) - 1, 0)
+
+def check_unsupported_flags(opts):
+ for op in ["follow", "follow_first", "date", "copies", "keyword", "remove",
+ "only_merges", "user", "only_branch", "prune", "newest_first",
+ "no_merges", "include", "exclude"]:
+ if op in opts and opts[op]:
+ raise util.Abort(_("--graph option is incompatible with --%s") % op)
+
+def graphlog(ui, repo, path=None, **opts):
+ """show revision history alongside an ASCII revision graph
+
+ Print a revision history alongside a revision graph drawn with
+ ASCII characters.
+
+ Nodes printed as an @ character are parents of the working
+ directory.
+ """
+
+ check_unsupported_flags(opts)
+ limit = cmdutil.loglimit(opts)
+ start, stop = get_revs(repo, opts["rev"])
+ stop = max(stop, start - limit + 1)
+ if start == nullrev:
+ return
+
+ if path:
+ path = util.canonpath(repo.root, os.getcwd(), path)
+ if path: # could be reset in canonpath
+ revdag = graphmod.filerevs(repo, path, start, stop)
+ else:
+ revdag = graphmod.revisions(repo, start, stop)
+
+ fmtdag = asciiformat(ui, repo, revdag, opts)
+ ascii(ui, asciiedges(fmtdag))
+
+def graphrevs(repo, nodes, opts):
+ limit = cmdutil.loglimit(opts)
+ nodes.reverse()
+ if limit < sys.maxint:
+ nodes = nodes[:limit]
+ return graphmod.nodes(repo, nodes)
+
+def goutgoing(ui, repo, dest=None, **opts):
+ """show the outgoing changesets alongside an ASCII revision graph
+
+ Print the outgoing changesets alongside a revision graph drawn with
+ ASCII characters.
+
+ Nodes printed as an @ character are parents of the working
+ directory.
+ """
+
+ check_unsupported_flags(opts)
+ dest, revs, checkout = hg.parseurl(
+ ui.expandpath(dest or 'default-push', dest or 'default'),
+ opts.get('rev'))
+ if revs:
+ revs = [repo.lookup(rev) for rev in revs]
+ other = hg.repository(cmdutil.remoteui(ui, opts), dest)
+ ui.status(_('comparing with %s\n') % url.hidepassword(dest))
+ o = repo.findoutgoing(other, force=opts.get('force'))
+ if not o:
+ ui.status(_("no changes found\n"))
+ return
+
+ o = repo.changelog.nodesbetween(o, revs)[0]
+ revdag = graphrevs(repo, o, opts)
+ fmtdag = asciiformat(ui, repo, revdag, opts)
+ ascii(ui, asciiedges(fmtdag))
+
+def gincoming(ui, repo, source="default", **opts):
+ """show the incoming changesets alongside an ASCII revision graph
+
+ Print the incoming changesets alongside a revision graph drawn with
+ ASCII characters.
+
+ Nodes printed as an @ character are parents of the working
+ directory.
+ """
+
+ check_unsupported_flags(opts)
+ source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
+ other = hg.repository(cmdutil.remoteui(repo, opts), source)
+ ui.status(_('comparing with %s\n') % url.hidepassword(source))
+ if revs:
+ revs = [other.lookup(rev) for rev in revs]
+ incoming = repo.findincoming(other, heads=revs, force=opts["force"])
+ if not incoming:
+ try:
+ os.unlink(opts["bundle"])
+ except:
+ pass
+ ui.status(_("no changes found\n"))
+ return
+
+ cleanup = None
+ try:
+
+ fname = opts["bundle"]
+ if fname or not other.local():
+ # create a bundle (uncompressed if other repo is not local)
+ if revs is None:
+ cg = other.changegroup(incoming, "incoming")
+ else:
+ cg = other.changegroupsubset(incoming, revs, 'incoming')
+ bundletype = other.local() and "HG10BZ" or "HG10UN"
+ fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
+ # keep written bundle?
+ if opts["bundle"]:
+ cleanup = None
+ if not other.local():
+ # use the created uncompressed bundlerepo
+ other = bundlerepo.bundlerepository(ui, repo.root, fname)
+
+ chlist = other.changelog.nodesbetween(incoming, revs)[0]
+ revdag = graphrevs(other, chlist, opts)
+ fmtdag = asciiformat(ui, other, revdag, opts, parentrepo=repo)
+ ascii(ui, asciiedges(fmtdag))
+
+ finally:
+ if hasattr(other, 'close'):
+ other.close()
+ if cleanup:
+ os.unlink(cleanup)
+
+def uisetup(ui):
+ '''Initialize the extension.'''
+ _wrapcmd(ui, 'log', commands.table, graphlog)
+ _wrapcmd(ui, 'incoming', commands.table, gincoming)
+ _wrapcmd(ui, 'outgoing', commands.table, goutgoing)
+
+def _wrapcmd(ui, cmd, table, wrapfn):
+ '''wrap the command'''
+ def graph(orig, *args, **kwargs):
+ if kwargs['graph']:
+ return wrapfn(*args, **kwargs)
+ return orig(*args, **kwargs)
+ entry = extensions.wrapcommand(table, cmd, graph)
+ entry[1].append(('G', 'graph', None, _("show the revision DAG")))
+
+cmdtable = {
+ "glog":
+ (graphlog,
+ [('l', 'limit', '', _('limit number of changes displayed')),
+ ('p', 'patch', False, _('show patch')),
+ ('r', 'rev', [], _('show the specified revision or range')),
+ ] + templateopts,
+ _('hg glog [OPTION]... [FILE]')),
+}
diff --git a/sys/src/cmd/hg/hgext/hgcia.py b/sys/src/cmd/hg/hgext/hgcia.py
new file mode 100644
index 000000000..dfae38919
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/hgcia.py
@@ -0,0 +1,246 @@
+# Copyright (C) 2007-8 Brendan Cully <brendan@kublai.com>
+# Published under the GNU GPL
+
+"""hooks for integrating with the CIA.vc notification service
+
+This is meant to be run as a changegroup or incoming hook. To
+configure it, set the following options in your hgrc::
+
+ [cia]
+ # your registered CIA user name
+ user = foo
+ # the name of the project in CIA
+ project = foo
+ # the module (subproject) (optional)
+ #module = foo
+ # Append a diffstat to the log message (optional)
+ #diffstat = False
+ # Template to use for log messages (optional)
+ #template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}
+ # Style to use (optional)
+ #style = foo
+ # The URL of the CIA notification service (optional)
+ # You can use mailto: URLs to send by email, eg
+ # mailto:cia@cia.vc
+ # Make sure to set email.from if you do this.
+ #url = http://cia.vc/
+ # print message instead of sending it (optional)
+ #test = False
+
+ [hooks]
+ # one of these:
+ changegroup.cia = python:hgcia.hook
+ #incoming.cia = python:hgcia.hook
+
+ [web]
+ # If you want hyperlinks (optional)
+ baseurl = http://server/path/to/repo
+"""
+
+from mercurial.i18n import _
+from mercurial.node import *
+from mercurial import cmdutil, patch, templater, util, mail
+import email.Parser
+
+import xmlrpclib
+from xml.sax import saxutils
+
+socket_timeout = 30 # seconds
+try:
+ # set a timeout for the socket so you don't have to wait so looooong
+ # when cia.vc is having problems. requires python >= 2.3:
+ import socket
+ socket.setdefaulttimeout(socket_timeout)
+except:
+ pass
+
+HGCIA_VERSION = '0.1'
+HGCIA_URL = 'http://hg.kublai.com/mercurial/hgcia'
+
+
+class ciamsg(object):
+ """ A CIA message """
+ def __init__(self, cia, ctx):
+ self.cia = cia
+ self.ctx = ctx
+ self.url = self.cia.url
+
+ def fileelem(self, path, uri, action):
+ if uri:
+ uri = ' uri=%s' % saxutils.quoteattr(uri)
+ return '<file%s action=%s>%s</file>' % (
+ uri, saxutils.quoteattr(action), saxutils.escape(path))
+
+ def fileelems(self):
+ n = self.ctx.node()
+ f = self.cia.repo.status(self.ctx.parents()[0].node(), n)
+ url = self.url or ''
+ elems = []
+ for path in f[0]:
+ uri = '%s/diff/%s/%s' % (url, short(n), path)
+ elems.append(self.fileelem(path, url and uri, 'modify'))
+ for path in f[1]:
+ # TODO: copy/rename ?
+ uri = '%s/file/%s/%s' % (url, short(n), path)
+ elems.append(self.fileelem(path, url and uri, 'add'))
+ for path in f[2]:
+ elems.append(self.fileelem(path, '', 'remove'))
+
+ return '\n'.join(elems)
+
+ def sourceelem(self, project, module=None, branch=None):
+ msg = ['<source>', '<project>%s</project>' % saxutils.escape(project)]
+ if module:
+ msg.append('<module>%s</module>' % saxutils.escape(module))
+ if branch:
+ msg.append('<branch>%s</branch>' % saxutils.escape(branch))
+ msg.append('</source>')
+
+ return '\n'.join(msg)
+
+ def diffstat(self):
+ class patchbuf(object):
+ def __init__(self):
+ self.lines = []
+ # diffstat is stupid
+ self.name = 'cia'
+ def write(self, data):
+ self.lines.append(data)
+ def close(self):
+ pass
+
+ n = self.ctx.node()
+ pbuf = patchbuf()
+ patch.export(self.cia.repo, [n], fp=pbuf)
+ return patch.diffstat(pbuf.lines) or ''
+
+ def logmsg(self):
+ diffstat = self.cia.diffstat and self.diffstat() or ''
+ self.cia.ui.pushbuffer()
+ self.cia.templater.show(self.ctx, changes=self.ctx.changeset(),
+ url=self.cia.url, diffstat=diffstat)
+ return self.cia.ui.popbuffer()
+
+ def xml(self):
+ n = short(self.ctx.node())
+ src = self.sourceelem(self.cia.project, module=self.cia.module,
+ branch=self.ctx.branch())
+ # unix timestamp
+ dt = self.ctx.date()
+ timestamp = dt[0]
+
+ author = saxutils.escape(self.ctx.user())
+ rev = '%d:%s' % (self.ctx.rev(), n)
+ log = saxutils.escape(self.logmsg())
+
+ url = self.url and '<url>%s/rev/%s</url>' % (saxutils.escape(self.url),
+ n) or ''
+
+ msg = """
+<message>
+ <generator>
+ <name>Mercurial (hgcia)</name>
+ <version>%s</version>
+ <url>%s</url>
+ <user>%s</user>
+ </generator>
+ %s
+ <body>
+ <commit>
+ <author>%s</author>
+ <version>%s</version>
+ <log>%s</log>
+ %s
+ <files>%s</files>
+ </commit>
+ </body>
+ <timestamp>%d</timestamp>
+</message>
+""" % \
+ (HGCIA_VERSION, saxutils.escape(HGCIA_URL),
+ saxutils.escape(self.cia.user), src, author, rev, log, url,
+ self.fileelems(), timestamp)
+
+ return msg
+
+
+class hgcia(object):
+ """ CIA notification class """
+
+ deftemplate = '{desc}'
+ dstemplate = '{desc}\n-- \n{diffstat}'
+
+ def __init__(self, ui, repo):
+ self.ui = ui
+ self.repo = repo
+
+ self.ciaurl = self.ui.config('cia', 'url', 'http://cia.vc')
+ self.user = self.ui.config('cia', 'user')
+ self.project = self.ui.config('cia', 'project')
+ self.module = self.ui.config('cia', 'module')
+ self.diffstat = self.ui.configbool('cia', 'diffstat')
+ self.emailfrom = self.ui.config('email', 'from')
+ self.dryrun = self.ui.configbool('cia', 'test')
+ self.url = self.ui.config('web', 'baseurl')
+
+ style = self.ui.config('cia', 'style')
+ template = self.ui.config('cia', 'template')
+ if not template:
+ template = self.diffstat and self.dstemplate or self.deftemplate
+ template = templater.parsestring(template, quoted=False)
+ t = cmdutil.changeset_templater(self.ui, self.repo, False, None,
+ style, False)
+ t.use_template(template)
+ self.templater = t
+
+ def sendrpc(self, msg):
+ srv = xmlrpclib.Server(self.ciaurl)
+ srv.hub.deliver(msg)
+
+ def sendemail(self, address, data):
+ p = email.Parser.Parser()
+ msg = p.parsestr(data)
+ msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
+ msg['To'] = address
+ msg['From'] = self.emailfrom
+ msg['Subject'] = 'DeliverXML'
+ msg['Content-type'] = 'text/xml'
+ msgtext = msg.as_string()
+
+ self.ui.status(_('hgcia: sending update to %s\n') % address)
+ mail.sendmail(self.ui, util.email(self.emailfrom),
+ [address], msgtext)
+
+
+def hook(ui, repo, hooktype, node=None, url=None, **kwargs):
+ """ send CIA notification """
+ def sendmsg(cia, ctx):
+ msg = ciamsg(cia, ctx).xml()
+ if cia.dryrun:
+ ui.write(msg)
+ elif cia.ciaurl.startswith('mailto:'):
+ if not cia.emailfrom:
+ raise util.Abort(_('email.from must be defined when '
+ 'sending by email'))
+ cia.sendemail(cia.ciaurl[7:], msg)
+ else:
+ cia.sendrpc(msg)
+
+ n = bin(node)
+ cia = hgcia(ui, repo)
+ if not cia.user:
+ ui.debug(_('cia: no user specified'))
+ return
+ if not cia.project:
+ ui.debug(_('cia: no project specified'))
+ return
+ if hooktype == 'changegroup':
+ start = repo.changelog.rev(n)
+ end = len(repo.changelog)
+ for rev in xrange(start, end):
+ n = repo.changelog.node(rev)
+ ctx = repo.changectx(n)
+ sendmsg(cia, ctx)
+ else:
+ ctx = repo.changectx(n)
+ sendmsg(cia, ctx)
diff --git a/sys/src/cmd/hg/hgext/hgk.py b/sys/src/cmd/hg/hgext/hgk.py
new file mode 100644
index 000000000..03441ce00
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/hgk.py
@@ -0,0 +1,347 @@
+# Minimal support for git commands on an hg repository
+#
+# Copyright 2005, 2006 Chris Mason <mason@suse.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''browse the repository in a graphical way
+
+The hgk extension allows browsing the history of a repository in a
+graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not
+distributed with Mercurial.)
+
+hgk consists of two parts: a Tcl script that does the displaying and
+querying of information, and an extension to Mercurial named hgk.py,
+which provides hooks for hgk to get information. hgk can be found in
+the contrib directory, and the extension is shipped in the hgext
+repository, and needs to be enabled.
+
+The hg view command will launch the hgk Tcl script. For this command
+to work, hgk must be in your search path. Alternately, you can specify
+the path to hgk in your .hgrc file::
+
+ [hgk]
+ path=/location/of/hgk
+
+hgk can make use of the extdiff extension to visualize revisions.
+Assuming you had already configured extdiff vdiff command, just add::
+
+ [hgk]
+ vdiff=vdiff
+
+Revisions context menu will now display additional entries to fire
+vdiff on hovered and selected revisions.
+'''
+
+import os
+from mercurial import commands, util, patch, revlog, cmdutil
+from mercurial.node import nullid, nullrev, short
+from mercurial.i18n import _
+
+def difftree(ui, repo, node1=None, node2=None, *files, **opts):
+ """diff trees from two commits"""
+ def __difftree(repo, node1, node2, files=[]):
+ assert node2 is not None
+ mmap = repo[node1].manifest()
+ mmap2 = repo[node2].manifest()
+ m = cmdutil.match(repo, files)
+ modified, added, removed = repo.status(node1, node2, m)[:3]
+ empty = short(nullid)
+
+ for f in modified:
+ # TODO get file permissions
+ ui.write(":100664 100664 %s %s M\t%s\t%s\n" %
+ (short(mmap[f]), short(mmap2[f]), f, f))
+ for f in added:
+ ui.write(":000000 100664 %s %s N\t%s\t%s\n" %
+ (empty, short(mmap2[f]), f, f))
+ for f in removed:
+ ui.write(":100664 000000 %s %s D\t%s\t%s\n" %
+ (short(mmap[f]), empty, f, f))
+ ##
+
+ while True:
+ if opts['stdin']:
+ try:
+ line = raw_input().split(' ')
+ node1 = line[0]
+ if len(line) > 1:
+ node2 = line[1]
+ else:
+ node2 = None
+ except EOFError:
+ break
+ node1 = repo.lookup(node1)
+ if node2:
+ node2 = repo.lookup(node2)
+ else:
+ node2 = node1
+ node1 = repo.changelog.parents(node1)[0]
+ if opts['patch']:
+ if opts['pretty']:
+ catcommit(ui, repo, node2, "")
+ m = cmdutil.match(repo, files)
+ chunks = patch.diff(repo, node1, node2, match=m,
+ opts=patch.diffopts(ui, {'git': True}))
+ for chunk in chunks:
+ ui.write(chunk)
+ else:
+ __difftree(repo, node1, node2, files=files)
+ if not opts['stdin']:
+ break
+
+def catcommit(ui, repo, n, prefix, ctx=None):
+ nlprefix = '\n' + prefix;
+ if ctx is None:
+ ctx = repo[n]
+ ui.write("tree %s\n" % short(ctx.changeset()[0])) # use ctx.node() instead ??
+ for p in ctx.parents():
+ ui.write("parent %s\n" % p)
+
+ date = ctx.date()
+ description = ctx.description().replace("\0", "")
+ lines = description.splitlines()
+ if lines and lines[-1].startswith('committer:'):
+ committer = lines[-1].split(': ')[1].rstrip()
+ else:
+ committer = ctx.user()
+
+ ui.write("author %s %s %s\n" % (ctx.user(), int(date[0]), date[1]))
+ ui.write("committer %s %s %s\n" % (committer, int(date[0]), date[1]))
+ ui.write("revision %d\n" % ctx.rev())
+ ui.write("branch %s\n\n" % ctx.branch())
+
+ if prefix != "":
+ ui.write("%s%s\n" % (prefix, description.replace('\n', nlprefix).strip()))
+ else:
+ ui.write(description + "\n")
+ if prefix:
+ ui.write('\0')
+
+def base(ui, repo, node1, node2):
+ """output common ancestor information"""
+ node1 = repo.lookup(node1)
+ node2 = repo.lookup(node2)
+ n = repo.changelog.ancestor(node1, node2)
+ ui.write(short(n) + "\n")
+
+def catfile(ui, repo, type=None, r=None, **opts):
+ """cat a specific revision"""
+ # in stdin mode, every line except the commit is prefixed with two
+ # spaces. This way the our caller can find the commit without magic
+ # strings
+ #
+ prefix = ""
+ if opts['stdin']:
+ try:
+ (type, r) = raw_input().split(' ');
+ prefix = " "
+ except EOFError:
+ return
+
+ else:
+ if not type or not r:
+ ui.warn(_("cat-file: type or revision not supplied\n"))
+ commands.help_(ui, 'cat-file')
+
+ while r:
+ if type != "commit":
+ ui.warn(_("aborting hg cat-file only understands commits\n"))
+ return 1;
+ n = repo.lookup(r)
+ catcommit(ui, repo, n, prefix)
+ if opts['stdin']:
+ try:
+ (type, r) = raw_input().split(' ');
+ except EOFError:
+ break
+ else:
+ break
+
+# git rev-tree is a confusing thing. You can supply a number of
+# commit sha1s on the command line, and it walks the commit history
+# telling you which commits are reachable from the supplied ones via
+# a bitmask based on arg position.
+# you can specify a commit to stop at by starting the sha1 with ^
+def revtree(ui, args, repo, full="tree", maxnr=0, parents=False):
+ def chlogwalk():
+ count = len(repo)
+ i = count
+ l = [0] * 100
+ chunk = 100
+ while True:
+ if chunk > i:
+ chunk = i
+ i = 0
+ else:
+ i -= chunk
+
+ for x in xrange(chunk):
+ if i + x >= count:
+ l[chunk - x:] = [0] * (chunk - x)
+ break
+ if full != None:
+ l[x] = repo[i + x]
+ l[x].changeset() # force reading
+ else:
+ l[x] = 1
+ for x in xrange(chunk-1, -1, -1):
+ if l[x] != 0:
+ yield (i + x, full != None and l[x] or None)
+ if i == 0:
+ break
+
+ # calculate and return the reachability bitmask for sha
+ def is_reachable(ar, reachable, sha):
+ if len(ar) == 0:
+ return 1
+ mask = 0
+ for i in xrange(len(ar)):
+ if sha in reachable[i]:
+ mask |= 1 << i
+
+ return mask
+
+ reachable = []
+ stop_sha1 = []
+ want_sha1 = []
+ count = 0
+
+ # figure out which commits they are asking for and which ones they
+ # want us to stop on
+ for i, arg in enumerate(args):
+ if arg.startswith('^'):
+ s = repo.lookup(arg[1:])
+ stop_sha1.append(s)
+ want_sha1.append(s)
+ elif arg != 'HEAD':
+ want_sha1.append(repo.lookup(arg))
+
+ # calculate the graph for the supplied commits
+ for i, n in enumerate(want_sha1):
+ reachable.append(set());
+ visit = [n];
+ reachable[i].add(n)
+ while visit:
+ n = visit.pop(0)
+ if n in stop_sha1:
+ continue
+ for p in repo.changelog.parents(n):
+ if p not in reachable[i]:
+ reachable[i].add(p)
+ visit.append(p)
+ if p in stop_sha1:
+ continue
+
+ # walk the repository looking for commits that are in our
+ # reachability graph
+ for i, ctx in chlogwalk():
+ n = repo.changelog.node(i)
+ mask = is_reachable(want_sha1, reachable, n)
+ if mask:
+ parentstr = ""
+ if parents:
+ pp = repo.changelog.parents(n)
+ if pp[0] != nullid:
+ parentstr += " " + short(pp[0])
+ if pp[1] != nullid:
+ parentstr += " " + short(pp[1])
+ if not full:
+ ui.write("%s%s\n" % (short(n), parentstr))
+ elif full == "commit":
+ ui.write("%s%s\n" % (short(n), parentstr))
+ catcommit(ui, repo, n, ' ', ctx)
+ else:
+ (p1, p2) = repo.changelog.parents(n)
+ (h, h1, h2) = map(short, (n, p1, p2))
+ (i1, i2) = map(repo.changelog.rev, (p1, p2))
+
+ date = ctx.date()[0]
+ ui.write("%s %s:%s" % (date, h, mask))
+ mask = is_reachable(want_sha1, reachable, p1)
+ if i1 != nullrev and mask > 0:
+ ui.write("%s:%s " % (h1, mask)),
+ mask = is_reachable(want_sha1, reachable, p2)
+ if i2 != nullrev and mask > 0:
+ ui.write("%s:%s " % (h2, mask))
+ ui.write("\n")
+ if maxnr and count >= maxnr:
+ break
+ count += 1
+
+def revparse(ui, repo, *revs, **opts):
+ """parse given revisions"""
+ def revstr(rev):
+ if rev == 'HEAD':
+ rev = 'tip'
+ return revlog.hex(repo.lookup(rev))
+
+ for r in revs:
+ revrange = r.split(':', 1)
+ ui.write('%s\n' % revstr(revrange[0]))
+ if len(revrange) == 2:
+ ui.write('^%s\n' % revstr(revrange[1]))
+
+# git rev-list tries to order things by date, and has the ability to stop
+# at a given commit without walking the whole repo. TODO add the stop
+# parameter
+def revlist(ui, repo, *revs, **opts):
+ """print revisions"""
+ if opts['header']:
+ full = "commit"
+ else:
+ full = None
+ copy = [x for x in revs]
+ revtree(ui, copy, repo, full, opts['max_count'], opts['parents'])
+
+def config(ui, repo, **opts):
+ """print extension options"""
+ def writeopt(name, value):
+ ui.write('k=%s\nv=%s\n' % (name, value))
+
+ writeopt('vdiff', ui.config('hgk', 'vdiff', ''))
+
+
+def view(ui, repo, *etc, **opts):
+ "start interactive history viewer"
+ os.chdir(repo.root)
+ optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v])
+ cmd = ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc))
+ ui.debug(_("running %s\n") % cmd)
+ util.system(cmd)
+
+cmdtable = {
+ "^view":
+ (view,
+ [('l', 'limit', '', _('limit number of changes displayed'))],
+ _('hg view [-l LIMIT] [REVRANGE]')),
+ "debug-diff-tree":
+ (difftree,
+ [('p', 'patch', None, _('generate patch')),
+ ('r', 'recursive', None, _('recursive')),
+ ('P', 'pretty', None, _('pretty')),
+ ('s', 'stdin', None, _('stdin')),
+ ('C', 'copy', None, _('detect copies')),
+ ('S', 'search', "", _('search'))],
+ _('hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]...')),
+ "debug-cat-file":
+ (catfile,
+ [('s', 'stdin', None, _('stdin'))],
+ _('hg debug-cat-file [OPTION]... TYPE FILE')),
+ "debug-config":
+ (config, [], _('hg debug-config')),
+ "debug-merge-base":
+ (base, [], _('hg debug-merge-base REV REV')),
+ "debug-rev-parse":
+ (revparse,
+ [('', 'default', '', _('ignored'))],
+ _('hg debug-rev-parse REV')),
+ "debug-rev-list":
+ (revlist,
+ [('H', 'header', None, _('header')),
+ ('t', 'topo-order', None, _('topo-order')),
+ ('p', 'parents', None, _('parents')),
+ ('n', 'max-count', 0, _('max-count'))],
+ _('hg debug-rev-list [OPTION]... REV...')),
+}
diff --git a/sys/src/cmd/hg/hgext/highlight/__init__.py b/sys/src/cmd/hg/hgext/highlight/__init__.py
new file mode 100644
index 000000000..65efae3c9
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/highlight/__init__.py
@@ -0,0 +1,60 @@
+# highlight - syntax highlighting in hgweb, based on Pygments
+#
+# Copyright 2008, 2009 Patrick Mezard <pmezard@gmail.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+#
+# The original module was split in an interface and an implementation
+# file to defer pygments loading and speedup extension setup.
+
+"""syntax highlighting for hgweb (requires Pygments)
+
+It depends on the Pygments syntax highlighting library:
+http://pygments.org/
+
+There is a single configuration option::
+
+ [web]
+ pygments_style = <style>
+
+The default is 'colorful'.
+"""
+
+import highlight
+from mercurial.hgweb import webcommands, webutil, common
+from mercurial import extensions, encoding
+
+def filerevision_highlight(orig, web, tmpl, fctx):
+ mt = ''.join(tmpl('mimetype', encoding=encoding.encoding))
+ # only pygmentize for mimetype containing 'html' so we both match
+ # 'text/html' and possibly 'application/xhtml+xml' in the future
+ # so that we don't have to touch the extension when the mimetype
+ # for a template changes; also hgweb optimizes the case that a
+ # raw file is sent using rawfile() and doesn't call us, so we
+ # can't clash with the file's content-type here in case we
+ # pygmentize a html file
+ if 'html' in mt:
+ style = web.config('web', 'pygments_style', 'colorful')
+ highlight.pygmentize('fileline', fctx, style, tmpl)
+ return orig(web, tmpl, fctx)
+
+def annotate_highlight(orig, web, req, tmpl):
+ mt = ''.join(tmpl('mimetype', encoding=encoding.encoding))
+ if 'html' in mt:
+ fctx = webutil.filectx(web.repo, req)
+ style = web.config('web', 'pygments_style', 'colorful')
+ highlight.pygmentize('annotateline', fctx, style, tmpl)
+ return orig(web, req, tmpl)
+
+def generate_css(web, req, tmpl):
+ pg_style = web.config('web', 'pygments_style', 'colorful')
+ fmter = highlight.HtmlFormatter(style = pg_style)
+ req.respond(common.HTTP_OK, 'text/css')
+ return ['/* pygments_style = %s */\n\n' % pg_style, fmter.get_style_defs('')]
+
+# monkeypatch in the new version
+extensions.wrapfunction(webcommands, '_filerevision', filerevision_highlight)
+extensions.wrapfunction(webcommands, 'annotate', annotate_highlight)
+webcommands.highlightcss = generate_css
+webcommands.__all__.append('highlightcss')
diff --git a/sys/src/cmd/hg/hgext/highlight/highlight.py b/sys/src/cmd/hg/hgext/highlight/highlight.py
new file mode 100644
index 000000000..0f767234d
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/highlight/highlight.py
@@ -0,0 +1,60 @@
+# highlight.py - highlight extension implementation file
+#
+# Copyright 2007-2009 Adam Hupp <adam@hupp.org> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+#
+# The original module was split in an interface and an implementation
+# file to defer pygments loading and speedup extension setup.
+
+from mercurial import demandimport
+demandimport.ignore.extend(['pkgutil', 'pkg_resources', '__main__',])
+from mercurial import util, encoding
+
+from pygments import highlight
+from pygments.util import ClassNotFound
+from pygments.lexers import guess_lexer, guess_lexer_for_filename, TextLexer
+from pygments.formatters import HtmlFormatter
+
+SYNTAX_CSS = ('\n<link rel="stylesheet" href="{url}highlightcss" '
+ 'type="text/css" />')
+
+def pygmentize(field, fctx, style, tmpl):
+
+ # append a <link ...> to the syntax highlighting css
+ old_header = ''.join(tmpl('header'))
+ if SYNTAX_CSS not in old_header:
+ new_header = old_header + SYNTAX_CSS
+ tmpl.cache['header'] = new_header
+
+ text = fctx.data()
+ if util.binary(text):
+ return
+
+ # avoid UnicodeDecodeError in pygments
+ text = encoding.tolocal(text)
+
+ # To get multi-line strings right, we can't format line-by-line
+ try:
+ lexer = guess_lexer_for_filename(fctx.path(), text[:1024],
+ encoding=encoding.encoding)
+ except (ClassNotFound, ValueError):
+ try:
+ lexer = guess_lexer(text[:1024], encoding=encoding.encoding)
+ except (ClassNotFound, ValueError):
+ lexer = TextLexer(encoding=encoding.encoding)
+
+ formatter = HtmlFormatter(style=style, encoding=encoding.encoding)
+
+ colorized = highlight(text, lexer, formatter)
+ # strip wrapping div
+ colorized = colorized[:colorized.find('\n</pre>')]
+ colorized = colorized[colorized.find('<pre>')+5:]
+ coloriter = iter(colorized.splitlines())
+
+ tmpl.filters['colorize'] = lambda x: coloriter.next()
+
+ oldl = tmpl.cache[field]
+ newl = oldl.replace('line|escape', 'line|colorize')
+ tmpl.cache[field] = newl
diff --git a/sys/src/cmd/hg/hgext/inotify/__init__.py b/sys/src/cmd/hg/hgext/inotify/__init__.py
new file mode 100644
index 000000000..cc952c2c6
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/inotify/__init__.py
@@ -0,0 +1,109 @@
+# __init__.py - inotify-based status acceleration for Linux
+#
+# Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
+# Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''accelerate status report using Linux's inotify service'''
+
+# todo: socket permissions
+
+from mercurial.i18n import _
+from mercurial import cmdutil, util
+import server
+from weakref import proxy
+from client import client, QueryFailed
+
+def serve(ui, repo, **opts):
+ '''start an inotify server for this repository'''
+ timeout = opts.get('timeout')
+ if timeout:
+ timeout = float(timeout) * 1e3
+
+ class service(object):
+ def init(self):
+ try:
+ self.master = server.master(ui, repo.dirstate,
+ repo.root, timeout)
+ except server.AlreadyStartedException, inst:
+ raise util.Abort(str(inst))
+
+ def run(self):
+ try:
+ self.master.run()
+ finally:
+ self.master.shutdown()
+
+ service = service()
+ logfile = ui.config('inotify', 'log')
+ cmdutil.service(opts, initfn=service.init, runfn=service.run,
+ logfile=logfile)
+
+def debuginotify(ui, repo, **opts):
+ '''debugging information for inotify extension
+
+ Prints the list of directories being watched by the inotify server.
+ '''
+ cli = client(ui, repo)
+ response = cli.debugquery()
+
+ ui.write(_('directories being watched:\n'))
+ for path in response:
+ ui.write((' %s/\n') % path)
+
+def reposetup(ui, repo):
+ if not hasattr(repo, 'dirstate'):
+ return
+
+ class inotifydirstate(repo.dirstate.__class__):
+
+ # We'll set this to false after an unsuccessful attempt so that
+ # next calls of status() within the same instance don't try again
+ # to start an inotify server if it won't start.
+ _inotifyon = True
+
+ def status(self, match, ignored, clean, unknown=True):
+ files = match.files()
+ if '.' in files:
+ files = []
+ if self._inotifyon and not ignored:
+ cli = client(ui, repo)
+ try:
+ result = cli.statusquery(files, match, False,
+ clean, unknown)
+ except QueryFailed, instr:
+ ui.debug(str(instr))
+ # don't retry within the same hg instance
+ inotifydirstate._inotifyon = False
+ pass
+ else:
+ if ui.config('inotify', 'debug'):
+ r2 = super(inotifydirstate, self).status(
+ match, False, clean, unknown)
+ for c,a,b in zip('LMARDUIC', result, r2):
+ for f in a:
+ if f not in b:
+ ui.warn('*** inotify: %s +%s\n' % (c, f))
+ for f in b:
+ if f not in a:
+ ui.warn('*** inotify: %s -%s\n' % (c, f))
+ result = r2
+ return result
+ return super(inotifydirstate, self).status(
+ match, ignored, clean, unknown)
+
+ repo.dirstate.__class__ = inotifydirstate
+
+cmdtable = {
+ 'debuginotify':
+ (debuginotify, [], ('hg debuginotify')),
+ '^inserve':
+ (serve,
+ [('d', 'daemon', None, _('run server in background')),
+ ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
+ ('t', 'idle-timeout', '', _('minutes to sit idle before exiting')),
+ ('', 'pid-file', '', _('name of file to write process ID to'))],
+ _('hg inserve [OPTION]...')),
+ }
diff --git a/sys/src/cmd/hg/hgext/inotify/client.py b/sys/src/cmd/hg/hgext/inotify/client.py
new file mode 100644
index 000000000..800d4a3aa
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/inotify/client.py
@@ -0,0 +1,160 @@
+# client.py - inotify status client
+#
+# Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
+# Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
+# Copyright 2009 Nicolas Dumazet <nicdumz@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from mercurial.i18n import _
+import common, server
+import errno, os, socket, struct
+
+class QueryFailed(Exception): pass
+
+def start_server(function):
+ """
+ Decorator.
+ Tries to call function, if it fails, try to (re)start inotify server.
+ Raise QueryFailed if something went wrong
+ """
+ def decorated_function(self, *args):
+ result = None
+ try:
+ return function(self, *args)
+ except (OSError, socket.error), err:
+ autostart = self.ui.configbool('inotify', 'autostart', True)
+
+ if err[0] == errno.ECONNREFUSED:
+ self.ui.warn(_('(found dead inotify server socket; '
+ 'removing it)\n'))
+ os.unlink(os.path.join(self.root, '.hg', 'inotify.sock'))
+ if err[0] in (errno.ECONNREFUSED, errno.ENOENT) and autostart:
+ self.ui.debug(_('(starting inotify server)\n'))
+ try:
+ try:
+ server.start(self.ui, self.dirstate, self.root)
+ except server.AlreadyStartedException, inst:
+ # another process may have started its own
+ # inotify server while this one was starting.
+ self.ui.debug(str(inst))
+ except Exception, inst:
+ self.ui.warn(_('could not start inotify server: '
+ '%s\n') % inst)
+ else:
+ try:
+ return function(self, *args)
+ except socket.error, err:
+ self.ui.warn(_('could not talk to new inotify '
+ 'server: %s\n') % err[-1])
+ elif err[0] in (errno.ECONNREFUSED, errno.ENOENT):
+ # silently ignore normal errors if autostart is False
+ self.ui.debug(_('(inotify server not running)\n'))
+ else:
+ self.ui.warn(_('failed to contact inotify server: %s\n')
+ % err[-1])
+
+ self.ui.traceback()
+ raise QueryFailed('inotify query failed')
+
+ return decorated_function
+
+
+class client(object):
+ def __init__(self, ui, repo):
+ self.ui = ui
+ self.dirstate = repo.dirstate
+ self.root = repo.root
+ self.sock = socket.socket(socket.AF_UNIX)
+
+ def _connect(self):
+ sockpath = os.path.join(self.root, '.hg', 'inotify.sock')
+ try:
+ self.sock.connect(sockpath)
+ except socket.error, err:
+ if err[0] == "AF_UNIX path too long":
+ sockpath = os.readlink(sockpath)
+ self.sock.connect(sockpath)
+ else:
+ raise
+
+ def _send(self, type, data):
+ """Sends protocol version number, and the data"""
+ self.sock.sendall(chr(common.version) + type + data)
+
+ self.sock.shutdown(socket.SHUT_WR)
+
+ def _receive(self, type):
+ """
+ Read data, check version number, extract headers,
+ and returns a tuple (data descriptor, header)
+ Raises QueryFailed on error
+ """
+ cs = common.recvcs(self.sock)
+ try:
+ version = ord(cs.read(1))
+ except TypeError:
+ # empty answer, assume the server crashed
+ self.ui.warn(_('received empty answer from inotify server'))
+ raise QueryFailed('server crashed')
+
+ if version != common.version:
+ self.ui.warn(_('(inotify: received response from incompatible '
+ 'server version %d)\n') % version)
+ raise QueryFailed('incompatible server version')
+
+ readtype = cs.read(4)
+ if readtype != type:
+ self.ui.warn(_('(inotify: received \'%s\' response when expecting'
+ ' \'%s\')\n') % (readtype, type))
+ raise QueryFailed('wrong response type')
+
+ hdrfmt = common.resphdrfmts[type]
+ hdrsize = common.resphdrsizes[type]
+ try:
+ resphdr = struct.unpack(hdrfmt, cs.read(hdrsize))
+ except struct.error:
+ raise QueryFailed('unable to retrieve query response headers')
+
+ return cs, resphdr
+
+ def query(self, type, req):
+ self._connect()
+
+ self._send(type, req)
+
+ return self._receive(type)
+
+ @start_server
+ def statusquery(self, names, match, ignored, clean, unknown=True):
+
+ def genquery():
+ for n in names:
+ yield n
+ states = 'almrx!'
+ if ignored:
+ raise ValueError('this is insanity')
+ if clean: states += 'c'
+ if unknown: states += '?'
+ yield states
+
+ req = '\0'.join(genquery())
+
+ cs, resphdr = self.query('STAT', req)
+
+ def readnames(nbytes):
+ if nbytes:
+ names = cs.read(nbytes)
+ if names:
+ return filter(match, names.split('\0'))
+ return []
+ return map(readnames, resphdr)
+
+ @start_server
+ def debugquery(self):
+ cs, resphdr = self.query('DBUG', '')
+
+ nbytes = resphdr[0]
+ names = cs.read(nbytes)
+ return names.split('\0')
diff --git a/sys/src/cmd/hg/hgext/inotify/common.py b/sys/src/cmd/hg/hgext/inotify/common.py
new file mode 100644
index 000000000..2b18b5f12
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/inotify/common.py
@@ -0,0 +1,51 @@
+# server.py - inotify common protocol code
+#
+# Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
+# Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import cStringIO, socket, struct
+
+"""
+ Protocol between inotify clients and server:
+
+ Client sending query:
+ 1) send protocol version number
+ 2) send query type (string, 4 letters long)
+ 3) send query parameters:
+ - For STAT, N+1 \0-separated strings:
+ 1) N different names that need checking
+ 2) 1 string containing all the status types to match
+ - No parameter needed for DBUG
+
+ Server sending query answer:
+ 1) send protocol version number
+ 2) send query type
+ 3) send struct.pack'ed headers describing the length of the content:
+ e.g. for STAT, receive 8 integers describing the length of the
+ 8 \0-separated string lists ( one list for each lmar!?ic status type )
+
+"""
+
+version = 2
+
+resphdrfmts = {
+ 'STAT': '>llllllll', # status requests
+ 'DBUG': '>l' # debugging queries
+}
+resphdrsizes = dict((k, struct.calcsize(v))
+ for k, v in resphdrfmts.iteritems())
+
+def recvcs(sock):
+ cs = cStringIO.StringIO()
+ s = True
+ try:
+ while s:
+ s = sock.recv(65536)
+ cs.write(s)
+ finally:
+ sock.shutdown(socket.SHUT_RD)
+ cs.seek(0)
+ return cs
diff --git a/sys/src/cmd/hg/hgext/inotify/linux/__init__.py b/sys/src/cmd/hg/hgext/inotify/linux/__init__.py
new file mode 100644
index 000000000..2fae16ab3
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/inotify/linux/__init__.py
@@ -0,0 +1,41 @@
+# __init__.py - low-level interfaces to the Linux inotify subsystem
+
+# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>
+
+# This library is free software; you can redistribute it and/or modify
+# it under the terms of version 2.1 of the GNU Lesser General Public
+# License, incorporated herein by reference.
+
+'''Low-level interface to the Linux inotify subsystem.
+
+The inotify subsystem provides an efficient mechanism for file status
+monitoring and change notification.
+
+This package provides the low-level inotify system call interface and
+associated constants and helper functions.
+
+For a higher-level interface that remains highly efficient, use the
+inotify.watcher package.'''
+
+__author__ = "Bryan O'Sullivan <bos@serpentine.com>"
+
+from _inotify import *
+
+procfs_path = '/proc/sys/fs/inotify'
+
+def _read_procfs_value(name):
+ def read_value():
+ try:
+ return int(open(procfs_path + '/' + name).read())
+ except OSError:
+ return None
+
+ read_value.__doc__ = '''Return the value of the %s setting from /proc.
+
+ If inotify is not enabled on this system, return None.''' % name
+
+ return read_value
+
+max_queued_events = _read_procfs_value('max_queued_events')
+max_user_instances = _read_procfs_value('max_user_instances')
+max_user_watches = _read_procfs_value('max_user_watches')
diff --git a/sys/src/cmd/hg/hgext/inotify/linux/_inotify.c b/sys/src/cmd/hg/hgext/inotify/linux/_inotify.c
new file mode 100644
index 000000000..42502aa0c
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/inotify/linux/_inotify.c
@@ -0,0 +1,608 @@
+/*
+ * _inotify.c - Python extension interfacing to the Linux inotify subsystem
+ *
+ * Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of version 2.1 of the GNU Lesser General
+ * Public License, incorporated herein by reference.
+ */
+
+#include <Python.h>
+#include <alloca.h>
+#include <sys/inotify.h>
+#include <stdint.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+static PyObject *init(PyObject *self, PyObject *args)
+{
+ PyObject *ret = NULL;
+ int fd = -1;
+
+ if (!PyArg_ParseTuple(args, ":init"))
+ goto bail;
+
+ Py_BEGIN_ALLOW_THREADS
+ fd = inotify_init();
+ Py_END_ALLOW_THREADS
+
+ if (fd == -1) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ goto bail;
+ }
+
+ ret = PyInt_FromLong(fd);
+ if (ret == NULL)
+ goto bail;
+
+ goto done;
+
+bail:
+ if (fd != -1)
+ close(fd);
+
+ Py_CLEAR(ret);
+
+done:
+ return ret;
+}
+
+PyDoc_STRVAR(
+ init_doc,
+ "init() -> fd\n"
+ "\n"
+ "Initialise an inotify instance.\n"
+ "Return a file descriptor associated with a new inotify event queue.");
+
+static PyObject *add_watch(PyObject *self, PyObject *args)
+{
+ PyObject *ret = NULL;
+ uint32_t mask;
+ int wd = -1;
+ char *path;
+ int fd;
+
+ if (!PyArg_ParseTuple(args, "isI:add_watch", &fd, &path, &mask))
+ goto bail;
+
+ Py_BEGIN_ALLOW_THREADS
+ wd = inotify_add_watch(fd, path, mask);
+ Py_END_ALLOW_THREADS
+
+ if (wd == -1) {
+ PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
+ goto bail;
+ }
+
+ ret = PyInt_FromLong(wd);
+ if (ret == NULL)
+ goto bail;
+
+ goto done;
+
+bail:
+ if (wd != -1)
+ inotify_rm_watch(fd, wd);
+
+ Py_CLEAR(ret);
+
+done:
+ return ret;
+}
+
+PyDoc_STRVAR(
+ add_watch_doc,
+ "add_watch(fd, path, mask) -> wd\n"
+ "\n"
+ "Add a watch to an inotify instance, or modify an existing watch.\n"
+ "\n"
+ " fd: file descriptor returned by init()\n"
+ " path: path to watch\n"
+ " mask: mask of events to watch for\n"
+ "\n"
+ "Return a unique numeric watch descriptor for the inotify instance\n"
+ "mapped by the file descriptor.");
+
+static PyObject *remove_watch(PyObject *self, PyObject *args)
+{
+ PyObject *ret = NULL;
+ uint32_t wd;
+ int fd;
+ int r;
+
+ if (!PyArg_ParseTuple(args, "iI:remove_watch", &fd, &wd))
+ goto bail;
+
+ Py_BEGIN_ALLOW_THREADS
+ r = inotify_rm_watch(fd, wd);
+ Py_END_ALLOW_THREADS
+
+ if (r == -1) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ goto bail;
+ }
+
+ Py_INCREF(Py_None);
+
+ goto done;
+
+bail:
+ Py_CLEAR(ret);
+
+done:
+ return ret;
+}
+
+PyDoc_STRVAR(
+ remove_watch_doc,
+ "remove_watch(fd, wd)\n"
+ "\n"
+ " fd: file descriptor returned by init()\n"
+ " wd: watch descriptor returned by add_watch()\n"
+ "\n"
+ "Remove a watch associated with the watch descriptor wd from the\n"
+ "inotify instance associated with the file descriptor fd.\n"
+ "\n"
+ "Removing a watch causes an IN_IGNORED event to be generated for this\n"
+ "watch descriptor.");
+
+#define bit_name(x) {x, #x}
+
+static struct {
+ int bit;
+ const char *name;
+ PyObject *pyname;
+} bit_names[] = {
+ bit_name(IN_ACCESS),
+ bit_name(IN_MODIFY),
+ bit_name(IN_ATTRIB),
+ bit_name(IN_CLOSE_WRITE),
+ bit_name(IN_CLOSE_NOWRITE),
+ bit_name(IN_OPEN),
+ bit_name(IN_MOVED_FROM),
+ bit_name(IN_MOVED_TO),
+ bit_name(IN_CREATE),
+ bit_name(IN_DELETE),
+ bit_name(IN_DELETE_SELF),
+ bit_name(IN_MOVE_SELF),
+ bit_name(IN_UNMOUNT),
+ bit_name(IN_Q_OVERFLOW),
+ bit_name(IN_IGNORED),
+ bit_name(IN_ONLYDIR),
+ bit_name(IN_DONT_FOLLOW),
+ bit_name(IN_MASK_ADD),
+ bit_name(IN_ISDIR),
+ bit_name(IN_ONESHOT),
+ {0}
+};
+
+static PyObject *decode_mask(int mask)
+{
+ PyObject *ret = PyList_New(0);
+ int i;
+
+ if (ret == NULL)
+ goto bail;
+
+ for (i = 0; bit_names[i].bit; i++) {
+ if (mask & bit_names[i].bit) {
+ if (bit_names[i].pyname == NULL) {
+ bit_names[i].pyname = PyString_FromString(bit_names[i].name);
+ if (bit_names[i].pyname == NULL)
+ goto bail;
+ }
+ Py_INCREF(bit_names[i].pyname);
+ if (PyList_Append(ret, bit_names[i].pyname) == -1)
+ goto bail;
+ }
+ }
+
+ goto done;
+
+bail:
+ Py_CLEAR(ret);
+
+done:
+ return ret;
+}
+
+static PyObject *pydecode_mask(PyObject *self, PyObject *args)
+{
+ int mask;
+
+ if (!PyArg_ParseTuple(args, "i:decode_mask", &mask))
+ return NULL;
+
+ return decode_mask(mask);
+}
+
+PyDoc_STRVAR(
+ decode_mask_doc,
+ "decode_mask(mask) -> list_of_strings\n"
+ "\n"
+ "Decode an inotify mask value into a list of strings that give the\n"
+ "name of each bit set in the mask.");
+
+static char doc[] = "Low-level inotify interface wrappers.";
+
+static void define_const(PyObject *dict, const char *name, uint32_t val)
+{
+ PyObject *pyval = PyInt_FromLong(val);
+ PyObject *pyname = PyString_FromString(name);
+
+ if (!pyname || !pyval)
+ goto bail;
+
+ PyDict_SetItem(dict, pyname, pyval);
+
+bail:
+ Py_XDECREF(pyname);
+ Py_XDECREF(pyval);
+}
+
+static void define_consts(PyObject *dict)
+{
+ define_const(dict, "IN_ACCESS", IN_ACCESS);
+ define_const(dict, "IN_MODIFY", IN_MODIFY);
+ define_const(dict, "IN_ATTRIB", IN_ATTRIB);
+ define_const(dict, "IN_CLOSE_WRITE", IN_CLOSE_WRITE);
+ define_const(dict, "IN_CLOSE_NOWRITE", IN_CLOSE_NOWRITE);
+ define_const(dict, "IN_OPEN", IN_OPEN);
+ define_const(dict, "IN_MOVED_FROM", IN_MOVED_FROM);
+ define_const(dict, "IN_MOVED_TO", IN_MOVED_TO);
+
+ define_const(dict, "IN_CLOSE", IN_CLOSE);
+ define_const(dict, "IN_MOVE", IN_MOVE);
+
+ define_const(dict, "IN_CREATE", IN_CREATE);
+ define_const(dict, "IN_DELETE", IN_DELETE);
+ define_const(dict, "IN_DELETE_SELF", IN_DELETE_SELF);
+ define_const(dict, "IN_MOVE_SELF", IN_MOVE_SELF);
+ define_const(dict, "IN_UNMOUNT", IN_UNMOUNT);
+ define_const(dict, "IN_Q_OVERFLOW", IN_Q_OVERFLOW);
+ define_const(dict, "IN_IGNORED", IN_IGNORED);
+
+ define_const(dict, "IN_ONLYDIR", IN_ONLYDIR);
+ define_const(dict, "IN_DONT_FOLLOW", IN_DONT_FOLLOW);
+ define_const(dict, "IN_MASK_ADD", IN_MASK_ADD);
+ define_const(dict, "IN_ISDIR", IN_ISDIR);
+ define_const(dict, "IN_ONESHOT", IN_ONESHOT);
+ define_const(dict, "IN_ALL_EVENTS", IN_ALL_EVENTS);
+}
+
+struct event {
+ PyObject_HEAD
+ PyObject *wd;
+ PyObject *mask;
+ PyObject *cookie;
+ PyObject *name;
+};
+
+static PyObject *event_wd(PyObject *self, void *x)
+{
+ struct event *evt = (struct event *) self;
+ Py_INCREF(evt->wd);
+ return evt->wd;
+}
+
+static PyObject *event_mask(PyObject *self, void *x)
+{
+ struct event *evt = (struct event *) self;
+ Py_INCREF(evt->mask);
+ return evt->mask;
+}
+
+static PyObject *event_cookie(PyObject *self, void *x)
+{
+ struct event *evt = (struct event *) self;
+ Py_INCREF(evt->cookie);
+ return evt->cookie;
+}
+
+static PyObject *event_name(PyObject *self, void *x)
+{
+ struct event *evt = (struct event *) self;
+ Py_INCREF(evt->name);
+ return evt->name;
+}
+
+static struct PyGetSetDef event_getsets[] = {
+ {"wd", event_wd, NULL,
+ "watch descriptor"},
+ {"mask", event_mask, NULL,
+ "event mask"},
+ {"cookie", event_cookie, NULL,
+ "rename cookie, if rename-related event"},
+ {"name", event_name, NULL,
+ "file name"},
+ {NULL}
+};
+
+PyDoc_STRVAR(
+ event_doc,
+ "event: Structure describing an inotify event.");
+
+static PyObject *event_new(PyTypeObject *t, PyObject *a, PyObject *k)
+{
+ return (*t->tp_alloc)(t, 0);
+}
+
+static void event_dealloc(struct event *evt)
+{
+ Py_XDECREF(evt->wd);
+ Py_XDECREF(evt->mask);
+ Py_XDECREF(evt->cookie);
+ Py_XDECREF(evt->name);
+
+ (*evt->ob_type->tp_free)(evt);
+}
+
+static PyObject *event_repr(struct event *evt)
+{
+ int wd = PyInt_AsLong(evt->wd);
+ int cookie = evt->cookie == Py_None ? -1 : PyInt_AsLong(evt->cookie);
+ PyObject *ret = NULL, *pymasks = NULL, *pymask = NULL;
+ PyObject *join = NULL;
+ char *maskstr;
+
+ join = PyString_FromString("|");
+ if (join == NULL)
+ goto bail;
+
+ pymasks = decode_mask(PyInt_AsLong(evt->mask));
+ if (pymasks == NULL)
+ goto bail;
+
+ pymask = _PyString_Join(join, pymasks);
+ if (pymask == NULL)
+ goto bail;
+
+ maskstr = PyString_AsString(pymask);
+
+ if (evt->name != Py_None) {
+ PyObject *pyname = PyString_Repr(evt->name, 1);
+ char *name = pyname ? PyString_AsString(pyname) : "???";
+
+ if (cookie == -1)
+ ret = PyString_FromFormat("event(wd=%d, mask=%s, name=%s)",
+ wd, maskstr, name);
+ else
+ ret = PyString_FromFormat("event(wd=%d, mask=%s, "
+ "cookie=0x%x, name=%s)",
+ wd, maskstr, cookie, name);
+
+ Py_XDECREF(pyname);
+ } else {
+ if (cookie == -1)
+ ret = PyString_FromFormat("event(wd=%d, mask=%s)",
+ wd, maskstr);
+ else {
+ ret = PyString_FromFormat("event(wd=%d, mask=%s, cookie=0x%x)",
+ wd, maskstr, cookie);
+ }
+ }
+
+ goto done;
+bail:
+ Py_CLEAR(ret);
+
+done:
+ Py_XDECREF(pymask);
+ Py_XDECREF(pymasks);
+ Py_XDECREF(join);
+
+ return ret;
+}
+
+static PyTypeObject event_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_inotify.event", /*tp_name*/
+ sizeof(struct event), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)event_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc)event_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ event_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ event_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ event_new, /* tp_new */
+};
+
+PyObject *read_events(PyObject *self, PyObject *args)
+{
+ PyObject *ctor_args = NULL;
+ PyObject *pybufsize = NULL;
+ PyObject *ret = NULL;
+ int bufsize = 65536;
+ char *buf = NULL;
+ int nread, pos;
+ int fd;
+
+ if (!PyArg_ParseTuple(args, "i|O:read", &fd, &pybufsize))
+ goto bail;
+
+ if (pybufsize && pybufsize != Py_None)
+ bufsize = PyInt_AsLong(pybufsize);
+
+ ret = PyList_New(0);
+ if (ret == NULL)
+ goto bail;
+
+ if (bufsize <= 0) {
+ int r;
+
+ Py_BEGIN_ALLOW_THREADS
+ r = ioctl(fd, FIONREAD, &bufsize);
+ Py_END_ALLOW_THREADS
+
+ if (r == -1) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ goto bail;
+ }
+ if (bufsize == 0)
+ goto done;
+ }
+ else {
+ static long name_max;
+ static long name_fd = -1;
+ long min;
+
+ if (name_fd != fd) {
+ name_fd = fd;
+ Py_BEGIN_ALLOW_THREADS
+ name_max = fpathconf(fd, _PC_NAME_MAX);
+ Py_END_ALLOW_THREADS
+ }
+
+ min = sizeof(struct inotify_event) + name_max + 1;
+
+ if (bufsize < min) {
+ PyErr_Format(PyExc_ValueError, "bufsize must be at least %d",
+ (int) min);
+ goto bail;
+ }
+ }
+
+ buf = alloca(bufsize);
+
+ Py_BEGIN_ALLOW_THREADS
+ nread = read(fd, buf, bufsize);
+ Py_END_ALLOW_THREADS
+
+ if (nread == -1) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ goto bail;
+ }
+
+ ctor_args = PyTuple_New(0);
+
+ if (ctor_args == NULL)
+ goto bail;
+
+ pos = 0;
+
+ while (pos < nread) {
+ struct inotify_event *in = (struct inotify_event *) (buf + pos);
+ struct event *evt;
+ PyObject *obj;
+
+ obj = PyObject_CallObject((PyObject *) &event_type, ctor_args);
+
+ if (obj == NULL)
+ goto bail;
+
+ evt = (struct event *) obj;
+
+ evt->wd = PyInt_FromLong(in->wd);
+ evt->mask = PyInt_FromLong(in->mask);
+ if (in->mask & IN_MOVE)
+ evt->cookie = PyInt_FromLong(in->cookie);
+ else {
+ Py_INCREF(Py_None);
+ evt->cookie = Py_None;
+ }
+ if (in->len)
+ evt->name = PyString_FromString(in->name);
+ else {
+ Py_INCREF(Py_None);
+ evt->name = Py_None;
+ }
+
+ if (!evt->wd || !evt->mask || !evt->cookie || !evt->name)
+ goto mybail;
+
+ if (PyList_Append(ret, obj) == -1)
+ goto mybail;
+
+ pos += sizeof(struct inotify_event) + in->len;
+ continue;
+
+ mybail:
+ Py_CLEAR(evt->wd);
+ Py_CLEAR(evt->mask);
+ Py_CLEAR(evt->cookie);
+ Py_CLEAR(evt->name);
+ Py_DECREF(obj);
+
+ goto bail;
+ }
+
+ goto done;
+
+bail:
+ Py_CLEAR(ret);
+
+done:
+ Py_XDECREF(ctor_args);
+
+ return ret;
+}
+
+PyDoc_STRVAR(
+ read_doc,
+ "read(fd, bufsize[=65536]) -> list_of_events\n"
+ "\n"
+ "\nRead inotify events from a file descriptor.\n"
+ "\n"
+ " fd: file descriptor returned by init()\n"
+ " bufsize: size of buffer to read into, in bytes\n"
+ "\n"
+ "Return a list of event objects.\n"
+ "\n"
+ "If bufsize is > 0, block until events are available to be read.\n"
+ "Otherwise, immediately return all events that can be read without\n"
+ "blocking.");
+
+
+static PyMethodDef methods[] = {
+ {"init", init, METH_VARARGS, init_doc},
+ {"add_watch", add_watch, METH_VARARGS, add_watch_doc},
+ {"remove_watch", remove_watch, METH_VARARGS, remove_watch_doc},
+ {"read", read_events, METH_VARARGS, read_doc},
+ {"decode_mask", pydecode_mask, METH_VARARGS, decode_mask_doc},
+ {NULL},
+};
+
+void init_inotify(void)
+{
+ PyObject *mod, *dict;
+
+ if (PyType_Ready(&event_type) == -1)
+ return;
+
+ mod = Py_InitModule3("_inotify", methods, doc);
+
+ dict = PyModule_GetDict(mod);
+
+ if (dict)
+ define_consts(dict);
+}
diff --git a/sys/src/cmd/hg/hgext/inotify/linux/watcher.py b/sys/src/cmd/hg/hgext/inotify/linux/watcher.py
new file mode 100644
index 000000000..5695f8686
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/inotify/linux/watcher.py
@@ -0,0 +1,335 @@
+# watcher.py - high-level interfaces to the Linux inotify subsystem
+
+# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>
+
+# This library is free software; you can redistribute it and/or modify
+# it under the terms of version 2.1 of the GNU Lesser General Public
+# License, incorporated herein by reference.
+
+'''High-level interfaces to the Linux inotify subsystem.
+
+The inotify subsystem provides an efficient mechanism for file status
+monitoring and change notification.
+
+The watcher class hides the low-level details of the inotify
+interface, and provides a Pythonic wrapper around it. It generates
+events that provide somewhat more information than raw inotify makes
+available.
+
+The autowatcher class is more useful, as it automatically watches
+newly-created directories on your behalf.'''
+
+__author__ = "Bryan O'Sullivan <bos@serpentine.com>"
+
+import _inotify as inotify
+import array
+import errno
+import fcntl
+import os
+import termios
+
+
+class event(object):
+ '''Derived inotify event class.
+
+ The following fields are available:
+
+ mask: event mask, indicating what kind of event this is
+
+ cookie: rename cookie, if a rename-related event
+
+ path: path of the directory in which the event occurred
+
+ name: name of the directory entry to which the event occurred
+ (may be None if the event happened to a watched directory)
+
+ fullpath: complete path at which the event occurred
+
+ wd: watch descriptor that triggered this event'''
+
+ __slots__ = (
+ 'cookie',
+ 'fullpath',
+ 'mask',
+ 'name',
+ 'path',
+ 'raw',
+ 'wd',
+ )
+
+ def __init__(self, raw, path):
+ self.path = path
+ self.raw = raw
+ if raw.name:
+ self.fullpath = path + '/' + raw.name
+ else:
+ self.fullpath = path
+
+ self.wd = raw.wd
+ self.mask = raw.mask
+ self.cookie = raw.cookie
+ self.name = raw.name
+
+ def __repr__(self):
+ r = repr(self.raw)
+ return 'event(path=' + repr(self.path) + ', ' + r[r.find('(')+1:]
+
+
+_event_props = {
+ 'access': 'File was accessed',
+ 'modify': 'File was modified',
+ 'attrib': 'Attribute of a directory entry was changed',
+ 'close_write': 'File was closed after being written to',
+ 'close_nowrite': 'File was closed without being written to',
+ 'open': 'File was opened',
+ 'moved_from': 'Directory entry was renamed from this name',
+ 'moved_to': 'Directory entry was renamed to this name',
+ 'create': 'Directory entry was created',
+ 'delete': 'Directory entry was deleted',
+ 'delete_self': 'The watched directory entry was deleted',
+ 'move_self': 'The watched directory entry was renamed',
+ 'unmount': 'Directory was unmounted, and can no longer be watched',
+ 'q_overflow': 'Kernel dropped events due to queue overflow',
+ 'ignored': 'Directory entry is no longer being watched',
+ 'isdir': 'Event occurred on a directory',
+ }
+
+for k, v in _event_props.iteritems():
+ mask = getattr(inotify, 'IN_' + k.upper())
+ def getter(self):
+ return self.mask & mask
+ getter.__name__ = k
+ getter.__doc__ = v
+ setattr(event, k, property(getter, doc=v))
+
+del _event_props
+
+
+class watcher(object):
+ '''Provide a Pythonic interface to the low-level inotify API.
+
+ Also adds derived information to each event that is not available
+ through the normal inotify API, such as directory name.'''
+
+ __slots__ = (
+ 'fd',
+ '_paths',
+ '_wds',
+ )
+
+ def __init__(self):
+ '''Create a new inotify instance.'''
+
+ self.fd = inotify.init()
+ self._paths = {}
+ self._wds = {}
+
+ def fileno(self):
+ '''Return the file descriptor this watcher uses.
+
+ Useful for passing to select and poll.'''
+
+ return self.fd
+
+ def add(self, path, mask):
+ '''Add or modify a watch.
+
+ Return the watch descriptor added or modified.'''
+
+ path = os.path.normpath(path)
+ wd = inotify.add_watch(self.fd, path, mask)
+ self._paths[path] = wd, mask
+ self._wds[wd] = path, mask
+ return wd
+
+ def remove(self, wd):
+ '''Remove the given watch.'''
+
+ inotify.remove_watch(self.fd, wd)
+ self._remove(wd)
+
+ def _remove(self, wd):
+ path_mask = self._wds.pop(wd, None)
+ if path_mask is not None:
+ self._paths.pop(path_mask[0])
+
+ def path(self, path):
+ '''Return a (watch descriptor, event mask) pair for the given path.
+
+ If the path is not being watched, return None.'''
+
+ return self._paths.get(path)
+
+ def wd(self, wd):
+ '''Return a (path, event mask) pair for the given watch descriptor.
+
+ If the watch descriptor is not valid or not associated with
+ this watcher, return None.'''
+
+ return self._wds.get(wd)
+
+ def read(self, bufsize=None):
+ '''Read a list of queued inotify events.
+
+ If bufsize is zero, only return those events that can be read
+ immediately without blocking. Otherwise, block until events are
+ available.'''
+
+ events = []
+ for evt in inotify.read(self.fd, bufsize):
+ events.append(event(evt, self._wds[evt.wd][0]))
+ if evt.mask & inotify.IN_IGNORED:
+ self._remove(evt.wd)
+ elif evt.mask & inotify.IN_UNMOUNT:
+ self.close()
+ return events
+
+ def close(self):
+ '''Shut down this watcher.
+
+ All subsequent method calls are likely to raise exceptions.'''
+
+ os.close(self.fd)
+ self.fd = None
+ self._paths = None
+ self._wds = None
+
+ def __len__(self):
+ '''Return the number of active watches.'''
+
+ return len(self._paths)
+
+ def __iter__(self):
+ '''Yield a (path, watch descriptor, event mask) tuple for each
+ entry being watched.'''
+
+ for path, (wd, mask) in self._paths.iteritems():
+ yield path, wd, mask
+
+ def __del__(self):
+ if self.fd is not None:
+ os.close(self.fd)
+
+ ignored_errors = [errno.ENOENT, errno.EPERM, errno.ENOTDIR]
+
+ def add_iter(self, path, mask, onerror=None):
+ '''Add or modify watches over path and its subdirectories.
+
+ Yield each added or modified watch descriptor.
+
+ To ensure that this method runs to completion, you must
+ iterate over all of its results, even if you do not care what
+ they are. For example:
+
+ for wd in w.add_iter(path, mask):
+ pass
+
+ By default, errors are ignored. If optional arg "onerror" is
+ specified, it should be a function; it will be called with one
+ argument, an OSError instance. It can report the error to
+ continue with the walk, or raise the exception to abort the
+ walk.'''
+
+ # Add the IN_ONLYDIR flag to the event mask, to avoid a possible
+ # race when adding a subdirectory. In the time between the
+ # event being queued by the kernel and us processing it, the
+ # directory may have been deleted, or replaced with a different
+ # kind of entry with the same name.
+
+ submask = mask | inotify.IN_ONLYDIR
+
+ try:
+ yield self.add(path, mask)
+ except OSError, err:
+ if onerror and err.errno not in self.ignored_errors:
+ onerror(err)
+ for root, dirs, names in os.walk(path, topdown=False, onerror=onerror):
+ for d in dirs:
+ try:
+ yield self.add(root + '/' + d, submask)
+ except OSError, err:
+ if onerror and err.errno not in self.ignored_errors:
+ onerror(err)
+
+ def add_all(self, path, mask, onerror=None):
+ '''Add or modify watches over path and its subdirectories.
+
+ Return a list of added or modified watch descriptors.
+
+ By default, errors are ignored. If optional arg "onerror" is
+ specified, it should be a function; it will be called with one
+ argument, an OSError instance. It can report the error to
+ continue with the walk, or raise the exception to abort the
+ walk.'''
+
+ return [w for w in self.add_iter(path, mask, onerror)]
+
+
+class autowatcher(watcher):
+ '''watcher class that automatically watches newly created directories.'''
+
+ __slots__ = (
+ 'addfilter',
+ )
+
+ def __init__(self, addfilter=None):
+ '''Create a new inotify instance.
+
+ This instance will automatically watch newly created
+ directories.
+
+ If the optional addfilter parameter is not None, it must be a
+ callable that takes one parameter. It will be called each time
+ a directory is about to be automatically watched. If it returns
+ True, the directory will be watched if it still exists,
+ otherwise, it will beb skipped.'''
+
+ super(autowatcher, self).__init__()
+ self.addfilter = addfilter
+
+ _dir_create_mask = inotify.IN_ISDIR | inotify.IN_CREATE
+
+ def read(self, bufsize=None):
+ events = super(autowatcher, self).read(bufsize)
+ for evt in events:
+ if evt.mask & self._dir_create_mask == self._dir_create_mask:
+ if self.addfilter is None or self.addfilter(evt):
+ parentmask = self._wds[evt.wd][1]
+ # See note about race avoidance via IN_ONLYDIR above.
+ mask = parentmask | inotify.IN_ONLYDIR
+ try:
+ self.add_all(evt.fullpath, mask)
+ except OSError, err:
+ if err.errno not in self.ignored_errors:
+ raise
+ return events
+
+
+class threshold(object):
+ '''Class that indicates whether a file descriptor has reached a
+ threshold of readable bytes available.
+
+ This class is not thread-safe.'''
+
+ __slots__ = (
+ 'fd',
+ 'threshold',
+ '_iocbuf',
+ )
+
+ def __init__(self, fd, threshold=1024):
+ self.fd = fd
+ self.threshold = threshold
+ self._iocbuf = array.array('i', [0])
+
+ def readable(self):
+ '''Return the number of bytes readable on this file descriptor.'''
+
+ fcntl.ioctl(self.fd, termios.FIONREAD, self._iocbuf, True)
+ return self._iocbuf[0]
+
+ def __call__(self):
+ '''Indicate whether the number of readable bytes has met or
+ exceeded the threshold.'''
+
+ return self.readable() >= self.threshold
diff --git a/sys/src/cmd/hg/hgext/inotify/server.py b/sys/src/cmd/hg/hgext/inotify/server.py
new file mode 100644
index 000000000..75c00d632
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/inotify/server.py
@@ -0,0 +1,874 @@
+# server.py - inotify status server
+#
+# Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
+# Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from mercurial.i18n import _
+from mercurial import osutil, util
+import common
+import errno, os, select, socket, stat, struct, sys, tempfile, time
+
+try:
+ import linux as inotify
+ from linux import watcher
+except ImportError:
+ raise
+
+class AlreadyStartedException(Exception): pass
+
+def join(a, b):
+ if a:
+ if a[-1] == '/':
+ return a + b
+ return a + '/' + b
+ return b
+
+def split(path):
+ c = path.rfind('/')
+ if c == -1:
+ return '', path
+ return path[:c], path[c+1:]
+
+walk_ignored_errors = (errno.ENOENT, errno.ENAMETOOLONG)
+
+def walkrepodirs(dirstate, absroot):
+ '''Iterate over all subdirectories of this repo.
+ Exclude the .hg directory, any nested repos, and ignored dirs.'''
+ def walkit(dirname, top):
+ fullpath = join(absroot, dirname)
+ try:
+ for name, kind in osutil.listdir(fullpath):
+ if kind == stat.S_IFDIR:
+ if name == '.hg':
+ if not top:
+ return
+ else:
+ d = join(dirname, name)
+ if dirstate._ignore(d):
+ continue
+ for subdir in walkit(d, False):
+ yield subdir
+ except OSError, err:
+ if err.errno not in walk_ignored_errors:
+ raise
+ yield fullpath
+
+ return walkit('', True)
+
+def walk(dirstate, absroot, root):
+ '''Like os.walk, but only yields regular files.'''
+
+ # This function is critical to performance during startup.
+
+ def walkit(root, reporoot):
+ files, dirs = [], []
+
+ try:
+ fullpath = join(absroot, root)
+ for name, kind in osutil.listdir(fullpath):
+ if kind == stat.S_IFDIR:
+ if name == '.hg':
+ if not reporoot:
+ return
+ else:
+ dirs.append(name)
+ path = join(root, name)
+ if dirstate._ignore(path):
+ continue
+ for result in walkit(path, False):
+ yield result
+ elif kind in (stat.S_IFREG, stat.S_IFLNK):
+ files.append(name)
+ yield fullpath, dirs, files
+
+ except OSError, err:
+ if err.errno == errno.ENOTDIR:
+ # fullpath was a directory, but has since been replaced
+ # by a file.
+ yield fullpath, dirs, files
+ elif err.errno not in walk_ignored_errors:
+ raise
+
+ return walkit(root, root == '')
+
+def _explain_watch_limit(ui, dirstate, rootabs):
+ path = '/proc/sys/fs/inotify/max_user_watches'
+ try:
+ limit = int(file(path).read())
+ except IOError, err:
+ if err.errno != errno.ENOENT:
+ raise
+ raise util.Abort(_('this system does not seem to '
+ 'support inotify'))
+ ui.warn(_('*** the current per-user limit on the number '
+ 'of inotify watches is %s\n') % limit)
+ ui.warn(_('*** this limit is too low to watch every '
+ 'directory in this repository\n'))
+ ui.warn(_('*** counting directories: '))
+ ndirs = len(list(walkrepodirs(dirstate, rootabs)))
+ ui.warn(_('found %d\n') % ndirs)
+ newlimit = min(limit, 1024)
+ while newlimit < ((limit + ndirs) * 1.1):
+ newlimit *= 2
+ ui.warn(_('*** to raise the limit from %d to %d (run as root):\n') %
+ (limit, newlimit))
+ ui.warn(_('*** echo %d > %s\n') % (newlimit, path))
+ raise util.Abort(_('cannot watch %s until inotify watch limit is raised')
+ % rootabs)
+
+class pollable(object):
+ """
+ Interface to support polling.
+ The file descriptor returned by fileno() is registered to a polling
+ object.
+ Usage:
+ Every tick, check if an event has happened since the last tick:
+ * If yes, call handle_events
+ * If no, call handle_timeout
+ """
+ poll_events = select.POLLIN
+ instances = {}
+ poll = select.poll()
+
+ def fileno(self):
+ raise NotImplementedError
+
+ def handle_events(self, events):
+ raise NotImplementedError
+
+ def handle_timeout(self):
+ raise NotImplementedError
+
+ def shutdown(self):
+ raise NotImplementedError
+
+ def register(self, timeout):
+ fd = self.fileno()
+
+ pollable.poll.register(fd, pollable.poll_events)
+ pollable.instances[fd] = self
+
+ self.registered = True
+ self.timeout = timeout
+
+ def unregister(self):
+ pollable.poll.unregister(self)
+ self.registered = False
+
+ @classmethod
+ def run(cls):
+ while True:
+ timeout = None
+ timeobj = None
+ for obj in cls.instances.itervalues():
+ if obj.timeout is not None and (timeout is None or obj.timeout < timeout):
+ timeout, timeobj = obj.timeout, obj
+ try:
+ events = cls.poll.poll(timeout)
+ except select.error, err:
+ if err[0] == errno.EINTR:
+ continue
+ raise
+ if events:
+ by_fd = {}
+ for fd, event in events:
+ by_fd.setdefault(fd, []).append(event)
+
+ for fd, events in by_fd.iteritems():
+ cls.instances[fd].handle_pollevents(events)
+
+ elif timeobj:
+ timeobj.handle_timeout()
+
+def eventaction(code):
+ """
+ Decorator to help handle events in repowatcher
+ """
+ def decorator(f):
+ def wrapper(self, wpath):
+ if code == 'm' and wpath in self.lastevent and \
+ self.lastevent[wpath] in 'cm':
+ return
+ self.lastevent[wpath] = code
+ self.timeout = 250
+
+ f(self, wpath)
+
+ wrapper.func_name = f.func_name
+ return wrapper
+ return decorator
+
+class directory(object):
+ """
+ Representing a directory
+
+ * path is the relative path from repo root to this directory
+ * files is a dict listing the files in this directory
+ - keys are file names
+ - values are file status
+ * dirs is a dict listing the subdirectories
+ - key are subdirectories names
+ - values are directory objects
+ """
+ def __init__(self, relpath=''):
+ self.path = relpath
+ self.files = {}
+ self.dirs = {}
+
+ def dir(self, relpath):
+ """
+ Returns the directory contained at the relative path relpath.
+ Creates the intermediate directories if necessary.
+ """
+ if not relpath:
+ return self
+ l = relpath.split('/')
+ ret = self
+ while l:
+ next = l.pop(0)
+ try:
+ ret = ret.dirs[next]
+ except KeyError:
+ d = directory(join(ret.path, next))
+ ret.dirs[next] = d
+ ret = d
+ return ret
+
+ def walk(self, states):
+ """
+ yield (filename, status) pairs for items in the trees
+ that have status in states.
+ filenames are relative to the repo root
+ """
+ for file, st in self.files.iteritems():
+ if st in states:
+ yield join(self.path, file), st
+ for dir in self.dirs.itervalues():
+ for e in dir.walk(states):
+ yield e
+
+ def lookup(self, states, path):
+ """
+ yield root-relative filenames that match path, and whose
+ status are in states:
+ * if path is a file, yield path
+ * if path is a directory, yield directory files
+ * if path is not tracked, yield nothing
+ """
+ if path[-1] == '/':
+ path = path[:-1]
+
+ paths = path.split('/')
+
+ # we need to check separately for last node
+ last = paths.pop()
+
+ tree = self
+ try:
+ for dir in paths:
+ tree = tree.dirs[dir]
+ except KeyError:
+ # path is not tracked
+ return
+
+ try:
+ # if path is a directory, walk it
+ for file, st in tree.dirs[last].walk(states):
+ yield file
+ except KeyError:
+ try:
+ if tree.files[last] in states:
+ # path is a file
+ yield path
+ except KeyError:
+ # path is not tracked
+ pass
+
+class repowatcher(pollable):
+ """
+ Watches inotify events
+ """
+ statuskeys = 'almr!?'
+ mask = (
+ inotify.IN_ATTRIB |
+ inotify.IN_CREATE |
+ inotify.IN_DELETE |
+ inotify.IN_DELETE_SELF |
+ inotify.IN_MODIFY |
+ inotify.IN_MOVED_FROM |
+ inotify.IN_MOVED_TO |
+ inotify.IN_MOVE_SELF |
+ inotify.IN_ONLYDIR |
+ inotify.IN_UNMOUNT |
+ 0)
+
+ def __init__(self, ui, dirstate, root):
+ self.ui = ui
+ self.dirstate = dirstate
+
+ self.wprefix = join(root, '')
+ self.prefixlen = len(self.wprefix)
+ try:
+ self.watcher = watcher.watcher()
+ except OSError, err:
+ raise util.Abort(_('inotify service not available: %s') %
+ err.strerror)
+ self.threshold = watcher.threshold(self.watcher)
+ self.fileno = self.watcher.fileno
+
+ self.tree = directory()
+ self.statcache = {}
+ self.statustrees = dict([(s, directory()) for s in self.statuskeys])
+
+ self.last_event = None
+
+ self.lastevent = {}
+
+ self.register(timeout=None)
+
+ self.ds_info = self.dirstate_info()
+ self.handle_timeout()
+ self.scan()
+
+ def event_time(self):
+ last = self.last_event
+ now = time.time()
+ self.last_event = now
+
+ if last is None:
+ return 'start'
+ delta = now - last
+ if delta < 5:
+ return '+%.3f' % delta
+ if delta < 50:
+ return '+%.2f' % delta
+ return '+%.1f' % delta
+
+ def dirstate_info(self):
+ try:
+ st = os.lstat(self.wprefix + '.hg/dirstate')
+ return st.st_mtime, st.st_ino
+ except OSError, err:
+ if err.errno != errno.ENOENT:
+ raise
+ return 0, 0
+
+ def add_watch(self, path, mask):
+ if not path:
+ return
+ if self.watcher.path(path) is None:
+ if self.ui.debugflag:
+ self.ui.note(_('watching %r\n') % path[self.prefixlen:])
+ try:
+ self.watcher.add(path, mask)
+ except OSError, err:
+ if err.errno in (errno.ENOENT, errno.ENOTDIR):
+ return
+ if err.errno != errno.ENOSPC:
+ raise
+ _explain_watch_limit(self.ui, self.dirstate, self.wprefix)
+
+ def setup(self):
+ self.ui.note(_('watching directories under %r\n') % self.wprefix)
+ self.add_watch(self.wprefix + '.hg', inotify.IN_DELETE)
+ self.check_dirstate()
+
+ def filestatus(self, fn, st):
+ try:
+ type_, mode, size, time = self.dirstate._map[fn][:4]
+ except KeyError:
+ type_ = '?'
+ if type_ == 'n':
+ st_mode, st_size, st_mtime = st
+ if size == -1:
+ return 'l'
+ if size and (size != st_size or (mode ^ st_mode) & 0100):
+ return 'm'
+ if time != int(st_mtime):
+ return 'l'
+ return 'n'
+ if type_ == '?' and self.dirstate._ignore(fn):
+ return 'i'
+ return type_
+
+ def updatefile(self, wfn, osstat):
+ '''
+ update the file entry of an existing file.
+
+ osstat: (mode, size, time) tuple, as returned by os.lstat(wfn)
+ '''
+
+ self._updatestatus(wfn, self.filestatus(wfn, osstat))
+
+ def deletefile(self, wfn, oldstatus):
+ '''
+ update the entry of a file which has been deleted.
+
+ oldstatus: char in statuskeys, status of the file before deletion
+ '''
+ if oldstatus == 'r':
+ newstatus = 'r'
+ elif oldstatus in 'almn':
+ newstatus = '!'
+ else:
+ newstatus = None
+
+ self.statcache.pop(wfn, None)
+ self._updatestatus(wfn, newstatus)
+
+ def _updatestatus(self, wfn, newstatus):
+ '''
+ Update the stored status of a file.
+
+ newstatus: - char in (statuskeys + 'ni'), new status to apply.
+ - or None, to stop tracking wfn
+ '''
+ root, fn = split(wfn)
+ d = self.tree.dir(root)
+
+ oldstatus = d.files.get(fn)
+ # oldstatus can be either:
+ # - None : fn is new
+ # - a char in statuskeys: fn is a (tracked) file
+
+ if self.ui.debugflag and oldstatus != newstatus:
+ self.ui.note(_('status: %r %s -> %s\n') %
+ (wfn, oldstatus, newstatus))
+
+ if oldstatus and oldstatus in self.statuskeys \
+ and oldstatus != newstatus:
+ del self.statustrees[oldstatus].dir(root).files[fn]
+
+ if newstatus in (None, 'i'):
+ d.files.pop(fn, None)
+ elif oldstatus != newstatus:
+ d.files[fn] = newstatus
+ if newstatus != 'n':
+ self.statustrees[newstatus].dir(root).files[fn] = newstatus
+
+
+ def check_deleted(self, key):
+ # Files that had been deleted but were present in the dirstate
+ # may have vanished from the dirstate; we must clean them up.
+ nuke = []
+ for wfn, ignore in self.statustrees[key].walk(key):
+ if wfn not in self.dirstate:
+ nuke.append(wfn)
+ for wfn in nuke:
+ root, fn = split(wfn)
+ del self.statustrees[key].dir(root).files[fn]
+ del self.tree.dir(root).files[fn]
+
+ def scan(self, topdir=''):
+ ds = self.dirstate._map.copy()
+ self.add_watch(join(self.wprefix, topdir), self.mask)
+ for root, dirs, files in walk(self.dirstate, self.wprefix, topdir):
+ for d in dirs:
+ self.add_watch(join(root, d), self.mask)
+ wroot = root[self.prefixlen:]
+ for fn in files:
+ wfn = join(wroot, fn)
+ self.updatefile(wfn, self.getstat(wfn))
+ ds.pop(wfn, None)
+ wtopdir = topdir
+ if wtopdir and wtopdir[-1] != '/':
+ wtopdir += '/'
+ for wfn, state in ds.iteritems():
+ if not wfn.startswith(wtopdir):
+ continue
+ try:
+ st = self.stat(wfn)
+ except OSError:
+ status = state[0]
+ self.deletefile(wfn, status)
+ else:
+ self.updatefile(wfn, st)
+ self.check_deleted('!')
+ self.check_deleted('r')
+
+ def check_dirstate(self):
+ ds_info = self.dirstate_info()
+ if ds_info == self.ds_info:
+ return
+ self.ds_info = ds_info
+ if not self.ui.debugflag:
+ self.last_event = None
+ self.ui.note(_('%s dirstate reload\n') % self.event_time())
+ self.dirstate.invalidate()
+ self.handle_timeout()
+ self.scan()
+ self.ui.note(_('%s end dirstate reload\n') % self.event_time())
+
+ def update_hgignore(self):
+ # An update of the ignore file can potentially change the
+ # states of all unknown and ignored files.
+
+ # XXX If the user has other ignore files outside the repo, or
+ # changes their list of ignore files at run time, we'll
+ # potentially never see changes to them. We could get the
+ # client to report to us what ignore data they're using.
+ # But it's easier to do nothing than to open that can of
+ # worms.
+
+ if '_ignore' in self.dirstate.__dict__:
+ delattr(self.dirstate, '_ignore')
+ self.ui.note(_('rescanning due to .hgignore change\n'))
+ self.handle_timeout()
+ self.scan()
+
+ def getstat(self, wpath):
+ try:
+ return self.statcache[wpath]
+ except KeyError:
+ try:
+ return self.stat(wpath)
+ except OSError, err:
+ if err.errno != errno.ENOENT:
+ raise
+
+ def stat(self, wpath):
+ try:
+ st = os.lstat(join(self.wprefix, wpath))
+ ret = st.st_mode, st.st_size, st.st_mtime
+ self.statcache[wpath] = ret
+ return ret
+ except OSError:
+ self.statcache.pop(wpath, None)
+ raise
+
+ @eventaction('c')
+ def created(self, wpath):
+ if wpath == '.hgignore':
+ self.update_hgignore()
+ try:
+ st = self.stat(wpath)
+ if stat.S_ISREG(st[0]):
+ self.updatefile(wpath, st)
+ except OSError:
+ pass
+
+ @eventaction('m')
+ def modified(self, wpath):
+ if wpath == '.hgignore':
+ self.update_hgignore()
+ try:
+ st = self.stat(wpath)
+ if stat.S_ISREG(st[0]):
+ if self.dirstate[wpath] in 'lmn':
+ self.updatefile(wpath, st)
+ except OSError:
+ pass
+
+ @eventaction('d')
+ def deleted(self, wpath):
+ if wpath == '.hgignore':
+ self.update_hgignore()
+ elif wpath.startswith('.hg/'):
+ if wpath == '.hg/wlock':
+ self.check_dirstate()
+ return
+
+ self.deletefile(wpath, self.dirstate[wpath])
+
+ def process_create(self, wpath, evt):
+ if self.ui.debugflag:
+ self.ui.note(_('%s event: created %s\n') %
+ (self.event_time(), wpath))
+
+ if evt.mask & inotify.IN_ISDIR:
+ self.scan(wpath)
+ else:
+ self.created(wpath)
+
+ def process_delete(self, wpath, evt):
+ if self.ui.debugflag:
+ self.ui.note(_('%s event: deleted %s\n') %
+ (self.event_time(), wpath))
+
+ if evt.mask & inotify.IN_ISDIR:
+ tree = self.tree.dir(wpath)
+ todelete = [wfn for wfn, ignore in tree.walk('?')]
+ for fn in todelete:
+ self.deletefile(fn, '?')
+ self.scan(wpath)
+ else:
+ self.deleted(wpath)
+
+ def process_modify(self, wpath, evt):
+ if self.ui.debugflag:
+ self.ui.note(_('%s event: modified %s\n') %
+ (self.event_time(), wpath))
+
+ if not (evt.mask & inotify.IN_ISDIR):
+ self.modified(wpath)
+
+ def process_unmount(self, evt):
+ self.ui.warn(_('filesystem containing %s was unmounted\n') %
+ evt.fullpath)
+ sys.exit(0)
+
+ def handle_pollevents(self, events):
+ if self.ui.debugflag:
+ self.ui.note(_('%s readable: %d bytes\n') %
+ (self.event_time(), self.threshold.readable()))
+ if not self.threshold():
+ if self.registered:
+ if self.ui.debugflag:
+ self.ui.note(_('%s below threshold - unhooking\n') %
+ (self.event_time()))
+ self.unregister()
+ self.timeout = 250
+ else:
+ self.read_events()
+
+ def read_events(self, bufsize=None):
+ events = self.watcher.read(bufsize)
+ if self.ui.debugflag:
+ self.ui.note(_('%s reading %d events\n') %
+ (self.event_time(), len(events)))
+ for evt in events:
+ assert evt.fullpath.startswith(self.wprefix)
+ wpath = evt.fullpath[self.prefixlen:]
+
+ # paths have been normalized, wpath never ends with a '/'
+
+ if wpath.startswith('.hg/') and evt.mask & inotify.IN_ISDIR:
+ # ignore subdirectories of .hg/ (merge, patches...)
+ continue
+
+ if evt.mask & inotify.IN_UNMOUNT:
+ self.process_unmount(wpath, evt)
+ elif evt.mask & (inotify.IN_MODIFY | inotify.IN_ATTRIB):
+ self.process_modify(wpath, evt)
+ elif evt.mask & (inotify.IN_DELETE | inotify.IN_DELETE_SELF |
+ inotify.IN_MOVED_FROM):
+ self.process_delete(wpath, evt)
+ elif evt.mask & (inotify.IN_CREATE | inotify.IN_MOVED_TO):
+ self.process_create(wpath, evt)
+
+ self.lastevent.clear()
+
+ def handle_timeout(self):
+ if not self.registered:
+ if self.ui.debugflag:
+ self.ui.note(_('%s hooking back up with %d bytes readable\n') %
+ (self.event_time(), self.threshold.readable()))
+ self.read_events(0)
+ self.register(timeout=None)
+
+ self.timeout = None
+
+ def shutdown(self):
+ self.watcher.close()
+
+ def debug(self):
+ """
+ Returns a sorted list of relatives paths currently watched,
+ for debugging purposes.
+ """
+ return sorted(tuple[0][self.prefixlen:] for tuple in self.watcher)
+
+class server(pollable):
+ """
+ Listens for client queries on unix socket inotify.sock
+ """
+ def __init__(self, ui, root, repowatcher, timeout):
+ self.ui = ui
+ self.repowatcher = repowatcher
+ self.sock = socket.socket(socket.AF_UNIX)
+ self.sockpath = join(root, '.hg/inotify.sock')
+ self.realsockpath = None
+ try:
+ self.sock.bind(self.sockpath)
+ except socket.error, err:
+ if err[0] == errno.EADDRINUSE:
+ raise AlreadyStartedException(_('could not start server: %s')
+ % err[1])
+ if err[0] == "AF_UNIX path too long":
+ tempdir = tempfile.mkdtemp(prefix="hg-inotify-")
+ self.realsockpath = os.path.join(tempdir, "inotify.sock")
+ try:
+ self.sock.bind(self.realsockpath)
+ os.symlink(self.realsockpath, self.sockpath)
+ except (OSError, socket.error), inst:
+ try:
+ os.unlink(self.realsockpath)
+ except:
+ pass
+ os.rmdir(tempdir)
+ if inst.errno == errno.EEXIST:
+ raise AlreadyStartedException(_('could not start server: %s')
+ % inst.strerror)
+ raise
+ else:
+ raise
+ self.sock.listen(5)
+ self.fileno = self.sock.fileno
+ self.register(timeout=timeout)
+
+ def handle_timeout(self):
+ pass
+
+ def answer_stat_query(self, cs):
+ names = cs.read().split('\0')
+
+ states = names.pop()
+
+ self.ui.note(_('answering query for %r\n') % states)
+
+ if self.repowatcher.timeout:
+ # We got a query while a rescan is pending. Make sure we
+ # rescan before responding, or we could give back a wrong
+ # answer.
+ self.repowatcher.handle_timeout()
+
+ if not names:
+ def genresult(states, tree):
+ for fn, state in tree.walk(states):
+ yield fn
+ else:
+ def genresult(states, tree):
+ for fn in names:
+ for f in tree.lookup(states, fn):
+ yield f
+
+ return ['\0'.join(r) for r in [
+ genresult('l', self.repowatcher.statustrees['l']),
+ genresult('m', self.repowatcher.statustrees['m']),
+ genresult('a', self.repowatcher.statustrees['a']),
+ genresult('r', self.repowatcher.statustrees['r']),
+ genresult('!', self.repowatcher.statustrees['!']),
+ '?' in states
+ and genresult('?', self.repowatcher.statustrees['?'])
+ or [],
+ [],
+ 'c' in states and genresult('n', self.repowatcher.tree) or [],
+ ]]
+
+ def answer_dbug_query(self):
+ return ['\0'.join(self.repowatcher.debug())]
+
+ def handle_pollevents(self, events):
+ for e in events:
+ self.handle_pollevent()
+
+ def handle_pollevent(self):
+ sock, addr = self.sock.accept()
+
+ cs = common.recvcs(sock)
+ version = ord(cs.read(1))
+
+ if version != common.version:
+ self.ui.warn(_('received query from incompatible client '
+ 'version %d\n') % version)
+ try:
+ # try to send back our version to the client
+ # this way, the client too is informed of the mismatch
+ sock.sendall(chr(common.version))
+ except:
+ pass
+ return
+
+ type = cs.read(4)
+
+ if type == 'STAT':
+ results = self.answer_stat_query(cs)
+ elif type == 'DBUG':
+ results = self.answer_dbug_query()
+ else:
+ self.ui.warn(_('unrecognized query type: %s\n') % type)
+ return
+
+ try:
+ try:
+ v = chr(common.version)
+
+ sock.sendall(v + type + struct.pack(common.resphdrfmts[type],
+ *map(len, results)))
+ sock.sendall(''.join(results))
+ finally:
+ sock.shutdown(socket.SHUT_WR)
+ except socket.error, err:
+ if err[0] != errno.EPIPE:
+ raise
+
+ def shutdown(self):
+ self.sock.close()
+ try:
+ os.unlink(self.sockpath)
+ if self.realsockpath:
+ os.unlink(self.realsockpath)
+ os.rmdir(os.path.dirname(self.realsockpath))
+ except OSError, err:
+ if err.errno != errno.ENOENT:
+ raise
+
+class master(object):
+ def __init__(self, ui, dirstate, root, timeout=None):
+ self.ui = ui
+ self.repowatcher = repowatcher(ui, dirstate, root)
+ self.server = server(ui, root, self.repowatcher, timeout)
+
+ def shutdown(self):
+ for obj in pollable.instances.itervalues():
+ obj.shutdown()
+
+ def run(self):
+ self.repowatcher.setup()
+ self.ui.note(_('finished setup\n'))
+ if os.getenv('TIME_STARTUP'):
+ sys.exit(0)
+ pollable.run()
+
+def start(ui, dirstate, root):
+ def closefds(ignore):
+ # (from python bug #1177468)
+ # close all inherited file descriptors
+ # Python 2.4.1 and later use /dev/urandom to seed the random module's RNG
+ # a file descriptor is kept internally as os._urandomfd (created on demand
+ # the first time os.urandom() is called), and should not be closed
+ try:
+ os.urandom(4)
+ urandom_fd = getattr(os, '_urandomfd', None)
+ except AttributeError:
+ urandom_fd = None
+ ignore.append(urandom_fd)
+ for fd in range(3, 256):
+ if fd in ignore:
+ continue
+ try:
+ os.close(fd)
+ except OSError:
+ pass
+
+ m = master(ui, dirstate, root)
+ sys.stdout.flush()
+ sys.stderr.flush()
+
+ pid = os.fork()
+ if pid:
+ return pid
+
+ closefds(pollable.instances.keys())
+ os.setsid()
+
+ fd = os.open('/dev/null', os.O_RDONLY)
+ os.dup2(fd, 0)
+ if fd > 0:
+ os.close(fd)
+
+ fd = os.open(ui.config('inotify', 'log', '/dev/null'),
+ os.O_RDWR | os.O_CREAT | os.O_TRUNC)
+ os.dup2(fd, 1)
+ os.dup2(fd, 2)
+ if fd > 2:
+ os.close(fd)
+
+ try:
+ m.run()
+ finally:
+ m.shutdown()
+ os._exit(0)
diff --git a/sys/src/cmd/hg/hgext/interhg.py b/sys/src/cmd/hg/hgext/interhg.py
new file mode 100644
index 000000000..3660c4081
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/interhg.py
@@ -0,0 +1,80 @@
+# interhg.py - interhg
+#
+# Copyright 2007 OHASHI Hideya <ohachige@gmail.com>
+#
+# Contributor(s):
+# Edward Lee <edward.lee@engineering.uiuc.edu>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''expand expressions into changelog and summaries
+
+This extension allows the use of a special syntax in summaries, which
+will be automatically expanded into links or any other arbitrary
+expression, much like InterWiki does.
+
+A few example patterns (link to bug tracking, etc.) that may be used
+in your hgrc::
+
+ [interhg]
+ issues = s!issue(\\d+)!<a href="http://bts/issue\\1">issue\\1</a>!
+ bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2">\\1</a>!i
+ boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!
+'''
+
+import re
+from mercurial.hgweb import hgweb_mod
+from mercurial import templatefilters, extensions
+from mercurial.i18n import _
+
+orig_escape = templatefilters.filters["escape"]
+
+interhg_table = []
+
+def interhg_escape(x):
+ escstr = orig_escape(x)
+ for regexp, format in interhg_table:
+ escstr = regexp.sub(format, escstr)
+ return escstr
+
+templatefilters.filters["escape"] = interhg_escape
+
+def interhg_refresh(orig, self):
+ interhg_table[:] = []
+ for key, pattern in self.repo.ui.configitems('interhg'):
+ # grab the delimiter from the character after the "s"
+ unesc = pattern[1]
+ delim = re.escape(unesc)
+
+ # identify portions of the pattern, taking care to avoid escaped
+ # delimiters. the replace format and flags are optional, but delimiters
+ # are required.
+ match = re.match(r'^s%s(.+)(?:(?<=\\\\)|(?<!\\))%s(.*)%s([ilmsux])*$'
+ % (delim, delim, delim), pattern)
+ if not match:
+ self.repo.ui.warn(_("interhg: invalid pattern for %s: %s\n")
+ % (key, pattern))
+ continue
+
+ # we need to unescape the delimiter for regexp and format
+ delim_re = re.compile(r'(?<!\\)\\%s' % delim)
+ regexp = delim_re.sub(unesc, match.group(1))
+ format = delim_re.sub(unesc, match.group(2))
+
+ # the pattern allows for 6 regexp flags, so set them if necessary
+ flagin = match.group(3)
+ flags = 0
+ if flagin:
+ for flag in flagin.upper():
+ flags |= re.__dict__[flag]
+
+ try:
+ regexp = re.compile(regexp, flags)
+ interhg_table.append((regexp, format))
+ except re.error:
+ self.repo.ui.warn(_("interhg: invalid regexp for %s: %s\n")
+ % (key, regexp))
+ return orig(self)
+
+extensions.wrapfunction(hgweb_mod.hgweb, 'refresh', interhg_refresh)
diff --git a/sys/src/cmd/hg/hgext/keyword.py b/sys/src/cmd/hg/hgext/keyword.py
new file mode 100644
index 000000000..b331389cf
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/keyword.py
@@ -0,0 +1,555 @@
+# keyword.py - $Keyword$ expansion for Mercurial
+#
+# Copyright 2007-2009 Christian Ebert <blacktrash@gmx.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+#
+# $Id$
+#
+# Keyword expansion hack against the grain of a DSCM
+#
+# There are many good reasons why this is not needed in a distributed
+# SCM, still it may be useful in very small projects based on single
+# files (like LaTeX packages), that are mostly addressed to an
+# audience not running a version control system.
+#
+# For in-depth discussion refer to
+# <http://mercurial.selenic.com/wiki/KeywordPlan>.
+#
+# Keyword expansion is based on Mercurial's changeset template mappings.
+#
+# Binary files are not touched.
+#
+# Files to act upon/ignore are specified in the [keyword] section.
+# Customized keyword template mappings in the [keywordmaps] section.
+#
+# Run "hg help keyword" and "hg kwdemo" to get info on configuration.
+
+'''expand keywords in tracked files
+
+This extension expands RCS/CVS-like or self-customized $Keywords$ in
+tracked text files selected by your configuration.
+
+Keywords are only expanded in local repositories and not stored in the
+change history. The mechanism can be regarded as a convenience for the
+current user or for archive distribution.
+
+Configuration is done in the [keyword] and [keywordmaps] sections of
+hgrc files.
+
+Example::
+
+ [keyword]
+ # expand keywords in every python file except those matching "x*"
+ **.py =
+ x* = ignore
+
+NOTE: the more specific you are in your filename patterns the less you
+lose speed in huge repositories.
+
+For [keywordmaps] template mapping and expansion demonstration and
+control run "hg kwdemo". See "hg help templates" for a list of
+available templates and filters.
+
+An additional date template filter {date|utcdate} is provided. It
+returns a date like "2006/09/18 15:13:13".
+
+The default template mappings (view with "hg kwdemo -d") can be
+replaced with customized keywords and templates. Again, run "hg
+kwdemo" to control the results of your config changes.
+
+Before changing/disabling active keywords, run "hg kwshrink" to avoid
+the risk of inadvertently storing expanded keywords in the change
+history.
+
+To force expansion after enabling it, or a configuration change, run
+"hg kwexpand".
+
+Also, when committing with the record extension or using mq's qrecord,
+be aware that keywords cannot be updated. Again, run "hg kwexpand" on
+the files in question to update keyword expansions after all changes
+have been checked in.
+
+Expansions spanning more than one line and incremental expansions,
+like CVS' $Log$, are not supported. A keyword template map "Log =
+{desc}" expands to the first line of the changeset description.
+'''
+
+from mercurial import commands, cmdutil, dispatch, filelog, revlog, extensions
+from mercurial import patch, localrepo, templater, templatefilters, util, match
+from mercurial.hgweb import webcommands
+from mercurial.lock import release
+from mercurial.node import nullid
+from mercurial.i18n import _
+import re, shutil, tempfile
+
+commands.optionalrepo += ' kwdemo'
+
+# hg commands that do not act on keywords
+nokwcommands = ('add addremove annotate bundle copy export grep incoming init'
+ ' log outgoing push rename rollback tip verify'
+ ' convert email glog')
+
+# hg commands that trigger expansion only when writing to working dir,
+# not when reading filelog, and unexpand when reading from working dir
+restricted = 'merge record resolve qfold qimport qnew qpush qrefresh qrecord'
+
+# provide cvs-like UTC date filter
+utcdate = lambda x: util.datestr(x, '%Y/%m/%d %H:%M:%S')
+
+# make keyword tools accessible
+kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']}
+
+
+class kwtemplater(object):
+ '''
+ Sets up keyword templates, corresponding keyword regex, and
+ provides keyword substitution functions.
+ '''
+ templates = {
+ 'Revision': '{node|short}',
+ 'Author': '{author|user}',
+ 'Date': '{date|utcdate}',
+ 'RCSFile': '{file|basename},v',
+ 'Source': '{root}/{file},v',
+ 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
+ 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
+ }
+
+ def __init__(self, ui, repo):
+ self.ui = ui
+ self.repo = repo
+ self.match = match.match(repo.root, '', [],
+ kwtools['inc'], kwtools['exc'])
+ self.restrict = kwtools['hgcmd'] in restricted.split()
+
+ kwmaps = self.ui.configitems('keywordmaps')
+ if kwmaps: # override default templates
+ self.templates = dict((k, templater.parsestring(v, False))
+ for k, v in kwmaps)
+ escaped = map(re.escape, self.templates.keys())
+ kwpat = r'\$(%s)(: [^$\n\r]*? )??\$' % '|'.join(escaped)
+ self.re_kw = re.compile(kwpat)
+
+ templatefilters.filters['utcdate'] = utcdate
+ self.ct = cmdutil.changeset_templater(self.ui, self.repo,
+ False, None, '', False)
+
+ def substitute(self, data, path, ctx, subfunc):
+ '''Replaces keywords in data with expanded template.'''
+ def kwsub(mobj):
+ kw = mobj.group(1)
+ self.ct.use_template(self.templates[kw])
+ self.ui.pushbuffer()
+ self.ct.show(ctx, root=self.repo.root, file=path)
+ ekw = templatefilters.firstline(self.ui.popbuffer())
+ return '$%s: %s $' % (kw, ekw)
+ return subfunc(kwsub, data)
+
+ def expand(self, path, node, data):
+ '''Returns data with keywords expanded.'''
+ if not self.restrict and self.match(path) and not util.binary(data):
+ ctx = self.repo.filectx(path, fileid=node).changectx()
+ return self.substitute(data, path, ctx, self.re_kw.sub)
+ return data
+
+ def iskwfile(self, path, flagfunc):
+ '''Returns true if path matches [keyword] pattern
+ and is not a symbolic link.
+ Caveat: localrepository._link fails on Windows.'''
+ return self.match(path) and not 'l' in flagfunc(path)
+
+ def overwrite(self, node, expand, files):
+ '''Overwrites selected files expanding/shrinking keywords.'''
+ ctx = self.repo[node]
+ mf = ctx.manifest()
+ if node is not None: # commit
+ files = [f for f in ctx.files() if f in mf]
+ notify = self.ui.debug
+ else: # kwexpand/kwshrink
+ notify = self.ui.note
+ candidates = [f for f in files if self.iskwfile(f, ctx.flags)]
+ if candidates:
+ self.restrict = True # do not expand when reading
+ msg = (expand and _('overwriting %s expanding keywords\n')
+ or _('overwriting %s shrinking keywords\n'))
+ for f in candidates:
+ fp = self.repo.file(f)
+ data = fp.read(mf[f])
+ if util.binary(data):
+ continue
+ if expand:
+ if node is None:
+ ctx = self.repo.filectx(f, fileid=mf[f]).changectx()
+ data, found = self.substitute(data, f, ctx,
+ self.re_kw.subn)
+ else:
+ found = self.re_kw.search(data)
+ if found:
+ notify(msg % f)
+ self.repo.wwrite(f, data, mf.flags(f))
+ if node is None:
+ self.repo.dirstate.normal(f)
+ self.restrict = False
+
+ def shrinktext(self, text):
+ '''Unconditionally removes all keyword substitutions from text.'''
+ return self.re_kw.sub(r'$\1$', text)
+
+ def shrink(self, fname, text):
+ '''Returns text with all keyword substitutions removed.'''
+ if self.match(fname) and not util.binary(text):
+ return self.shrinktext(text)
+ return text
+
+ def shrinklines(self, fname, lines):
+ '''Returns lines with keyword substitutions removed.'''
+ if self.match(fname):
+ text = ''.join(lines)
+ if not util.binary(text):
+ return self.shrinktext(text).splitlines(True)
+ return lines
+
+ def wread(self, fname, data):
+ '''If in restricted mode returns data read from wdir with
+ keyword substitutions removed.'''
+ return self.restrict and self.shrink(fname, data) or data
+
+class kwfilelog(filelog.filelog):
+ '''
+ Subclass of filelog to hook into its read, add, cmp methods.
+ Keywords are "stored" unexpanded, and processed on reading.
+ '''
+ def __init__(self, opener, kwt, path):
+ super(kwfilelog, self).__init__(opener, path)
+ self.kwt = kwt
+ self.path = path
+
+ def read(self, node):
+ '''Expands keywords when reading filelog.'''
+ data = super(kwfilelog, self).read(node)
+ return self.kwt.expand(self.path, node, data)
+
+ def add(self, text, meta, tr, link, p1=None, p2=None):
+ '''Removes keyword substitutions when adding to filelog.'''
+ text = self.kwt.shrink(self.path, text)
+ return super(kwfilelog, self).add(text, meta, tr, link, p1, p2)
+
+ def cmp(self, node, text):
+ '''Removes keyword substitutions for comparison.'''
+ text = self.kwt.shrink(self.path, text)
+ if self.renamed(node):
+ t2 = super(kwfilelog, self).read(node)
+ return t2 != text
+ return revlog.revlog.cmp(self, node, text)
+
+def _status(ui, repo, kwt, unknown, *pats, **opts):
+ '''Bails out if [keyword] configuration is not active.
+ Returns status of working directory.'''
+ if kwt:
+ match = cmdutil.match(repo, pats, opts)
+ return repo.status(match=match, unknown=unknown, clean=True)
+ if ui.configitems('keyword'):
+ raise util.Abort(_('[keyword] patterns cannot match'))
+ raise util.Abort(_('no [keyword] patterns configured'))
+
+def _kwfwrite(ui, repo, expand, *pats, **opts):
+ '''Selects files and passes them to kwtemplater.overwrite.'''
+ if repo.dirstate.parents()[1] != nullid:
+ raise util.Abort(_('outstanding uncommitted merge'))
+ kwt = kwtools['templater']
+ status = _status(ui, repo, kwt, False, *pats, **opts)
+ modified, added, removed, deleted = status[:4]
+ if modified or added or removed or deleted:
+ raise util.Abort(_('outstanding uncommitted changes'))
+ wlock = lock = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ kwt.overwrite(None, expand, status[6])
+ finally:
+ release(lock, wlock)
+
+def demo(ui, repo, *args, **opts):
+ '''print [keywordmaps] configuration and an expansion example
+
+ Show current, custom, or default keyword template maps and their
+ expansions.
+
+ Extend the current configuration by specifying maps as arguments
+ and using -f/--rcfile to source an external hgrc file.
+
+ Use -d/--default to disable current configuration.
+
+ See "hg help templates" for information on templates and filters.
+ '''
+ def demoitems(section, items):
+ ui.write('[%s]\n' % section)
+ for k, v in items:
+ ui.write('%s = %s\n' % (k, v))
+
+ msg = 'hg keyword config and expansion example'
+ fn = 'demo.txt'
+ branchname = 'demobranch'
+ tmpdir = tempfile.mkdtemp('', 'kwdemo.')
+ ui.note(_('creating temporary repository at %s\n') % tmpdir)
+ repo = localrepo.localrepository(ui, tmpdir, True)
+ ui.setconfig('keyword', fn, '')
+
+ uikwmaps = ui.configitems('keywordmaps')
+ if args or opts.get('rcfile'):
+ ui.status(_('\n\tconfiguration using custom keyword template maps\n'))
+ if uikwmaps:
+ ui.status(_('\textending current template maps\n'))
+ if opts.get('default') or not uikwmaps:
+ ui.status(_('\toverriding default template maps\n'))
+ if opts.get('rcfile'):
+ ui.readconfig(opts.get('rcfile'))
+ if args:
+ # simulate hgrc parsing
+ rcmaps = ['[keywordmaps]\n'] + [a + '\n' for a in args]
+ fp = repo.opener('hgrc', 'w')
+ fp.writelines(rcmaps)
+ fp.close()
+ ui.readconfig(repo.join('hgrc'))
+ kwmaps = dict(ui.configitems('keywordmaps'))
+ elif opts.get('default'):
+ ui.status(_('\n\tconfiguration using default keyword template maps\n'))
+ kwmaps = kwtemplater.templates
+ if uikwmaps:
+ ui.status(_('\tdisabling current template maps\n'))
+ for k, v in kwmaps.iteritems():
+ ui.setconfig('keywordmaps', k, v)
+ else:
+ ui.status(_('\n\tconfiguration using current keyword template maps\n'))
+ kwmaps = dict(uikwmaps) or kwtemplater.templates
+
+ uisetup(ui)
+ reposetup(ui, repo)
+ for k, v in ui.configitems('extensions'):
+ if k.endswith('keyword'):
+ extension = '%s = %s' % (k, v)
+ break
+ ui.write('[extensions]\n%s\n' % extension)
+ demoitems('keyword', ui.configitems('keyword'))
+ demoitems('keywordmaps', kwmaps.iteritems())
+ keywords = '$' + '$\n$'.join(kwmaps.keys()) + '$\n'
+ repo.wopener(fn, 'w').write(keywords)
+ repo.add([fn])
+ path = repo.wjoin(fn)
+ ui.note(_('\nkeywords written to %s:\n') % path)
+ ui.note(keywords)
+ ui.note('\nhg -R "%s" branch "%s"\n' % (tmpdir, branchname))
+ # silence branch command if not verbose
+ quiet = ui.quiet
+ ui.quiet = not ui.verbose
+ commands.branch(ui, repo, branchname)
+ ui.quiet = quiet
+ for name, cmd in ui.configitems('hooks'):
+ if name.split('.', 1)[0].find('commit') > -1:
+ repo.ui.setconfig('hooks', name, '')
+ ui.note(_('unhooked all commit hooks\n'))
+ ui.note('hg -R "%s" ci -m "%s"\n' % (tmpdir, msg))
+ repo.commit(text=msg)
+ ui.status(_('\n\tkeywords expanded\n'))
+ ui.write(repo.wread(fn))
+ ui.debug(_('\nremoving temporary repository %s\n') % tmpdir)
+ shutil.rmtree(tmpdir, ignore_errors=True)
+
+def expand(ui, repo, *pats, **opts):
+ '''expand keywords in the working directory
+
+ Run after (re)enabling keyword expansion.
+
+ kwexpand refuses to run if given files contain local changes.
+ '''
+ # 3rd argument sets expansion to True
+ _kwfwrite(ui, repo, True, *pats, **opts)
+
+def files(ui, repo, *pats, **opts):
+ '''show files configured for keyword expansion
+
+ List which files in the working directory are matched by the
+ [keyword] configuration patterns.
+
+ Useful to prevent inadvertent keyword expansion and to speed up
+ execution by including only files that are actual candidates for
+ expansion.
+
+ See "hg help keyword" on how to construct patterns both for
+ inclusion and exclusion of files.
+
+ Use -u/--untracked to list untracked files as well.
+
+ With -a/--all and -v/--verbose the codes used to show the status
+ of files are::
+
+ K = keyword expansion candidate
+ k = keyword expansion candidate (untracked)
+ I = ignored
+ i = ignored (untracked)
+ '''
+ kwt = kwtools['templater']
+ status = _status(ui, repo, kwt, opts.get('untracked'), *pats, **opts)
+ modified, added, removed, deleted, unknown, ignored, clean = status
+ files = sorted(modified + added + clean)
+ wctx = repo[None]
+ kwfiles = [f for f in files if kwt.iskwfile(f, wctx.flags)]
+ kwuntracked = [f for f in unknown if kwt.iskwfile(f, wctx.flags)]
+ cwd = pats and repo.getcwd() or ''
+ kwfstats = (not opts.get('ignore') and
+ (('K', kwfiles), ('k', kwuntracked),) or ())
+ if opts.get('all') or opts.get('ignore'):
+ kwfstats += (('I', [f for f in files if f not in kwfiles]),
+ ('i', [f for f in unknown if f not in kwuntracked]),)
+ for char, filenames in kwfstats:
+ fmt = (opts.get('all') or ui.verbose) and '%s %%s\n' % char or '%s\n'
+ for f in filenames:
+ ui.write(fmt % repo.pathto(f, cwd))
+
+def shrink(ui, repo, *pats, **opts):
+ '''revert expanded keywords in the working directory
+
+ Run before changing/disabling active keywords or if you experience
+ problems with "hg import" or "hg merge".
+
+ kwshrink refuses to run if given files contain local changes.
+ '''
+ # 3rd argument sets expansion to False
+ _kwfwrite(ui, repo, False, *pats, **opts)
+
+
+def uisetup(ui):
+ '''Collects [keyword] config in kwtools.
+ Monkeypatches dispatch._parse if needed.'''
+
+ for pat, opt in ui.configitems('keyword'):
+ if opt != 'ignore':
+ kwtools['inc'].append(pat)
+ else:
+ kwtools['exc'].append(pat)
+
+ if kwtools['inc']:
+ def kwdispatch_parse(orig, ui, args):
+ '''Monkeypatch dispatch._parse to obtain running hg command.'''
+ cmd, func, args, options, cmdoptions = orig(ui, args)
+ kwtools['hgcmd'] = cmd
+ return cmd, func, args, options, cmdoptions
+
+ extensions.wrapfunction(dispatch, '_parse', kwdispatch_parse)
+
+def reposetup(ui, repo):
+ '''Sets up repo as kwrepo for keyword substitution.
+ Overrides file method to return kwfilelog instead of filelog
+ if file matches user configuration.
+ Wraps commit to overwrite configured files with updated
+ keyword substitutions.
+ Monkeypatches patch and webcommands.'''
+
+ try:
+ if (not repo.local() or not kwtools['inc']
+ or kwtools['hgcmd'] in nokwcommands.split()
+ or '.hg' in util.splitpath(repo.root)
+ or repo._url.startswith('bundle:')):
+ return
+ except AttributeError:
+ pass
+
+ kwtools['templater'] = kwt = kwtemplater(ui, repo)
+
+ class kwrepo(repo.__class__):
+ def file(self, f):
+ if f[0] == '/':
+ f = f[1:]
+ return kwfilelog(self.sopener, kwt, f)
+
+ def wread(self, filename):
+ data = super(kwrepo, self).wread(filename)
+ return kwt.wread(filename, data)
+
+ def commit(self, *args, **opts):
+ # use custom commitctx for user commands
+ # other extensions can still wrap repo.commitctx directly
+ self.commitctx = self.kwcommitctx
+ try:
+ return super(kwrepo, self).commit(*args, **opts)
+ finally:
+ del self.commitctx
+
+ def kwcommitctx(self, ctx, error=False):
+ wlock = lock = None
+ try:
+ wlock = self.wlock()
+ lock = self.lock()
+ # store and postpone commit hooks
+ commithooks = {}
+ for name, cmd in ui.configitems('hooks'):
+ if name.split('.', 1)[0] == 'commit':
+ commithooks[name] = cmd
+ ui.setconfig('hooks', name, None)
+ if commithooks:
+ # store parents for commit hooks
+ p1, p2 = ctx.p1(), ctx.p2()
+ xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
+
+ n = super(kwrepo, self).commitctx(ctx, error)
+
+ kwt.overwrite(n, True, None)
+ if commithooks:
+ for name, cmd in commithooks.iteritems():
+ ui.setconfig('hooks', name, cmd)
+ self.hook('commit', node=n, parent1=xp1, parent2=xp2)
+ return n
+ finally:
+ release(lock, wlock)
+
+ # monkeypatches
+ def kwpatchfile_init(orig, self, ui, fname, opener,
+ missing=False, eol=None):
+ '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
+ rejects or conflicts due to expanded keywords in working dir.'''
+ orig(self, ui, fname, opener, missing, eol)
+ # shrink keywords read from working dir
+ self.lines = kwt.shrinklines(self.fname, self.lines)
+
+ def kw_diff(orig, repo, node1=None, node2=None, match=None, changes=None,
+ opts=None):
+ '''Monkeypatch patch.diff to avoid expansion except when
+ comparing against working dir.'''
+ if node2 is not None:
+ kwt.match = util.never
+ elif node1 is not None and node1 != repo['.'].node():
+ kwt.restrict = True
+ return orig(repo, node1, node2, match, changes, opts)
+
+ def kwweb_skip(orig, web, req, tmpl):
+ '''Wraps webcommands.x turning off keyword expansion.'''
+ kwt.match = util.never
+ return orig(web, req, tmpl)
+
+ repo.__class__ = kwrepo
+
+ extensions.wrapfunction(patch.patchfile, '__init__', kwpatchfile_init)
+ extensions.wrapfunction(patch, 'diff', kw_diff)
+ for c in 'annotate changeset rev filediff diff'.split():
+ extensions.wrapfunction(webcommands, c, kwweb_skip)
+
+cmdtable = {
+ 'kwdemo':
+ (demo,
+ [('d', 'default', None, _('show default keyword template maps')),
+ ('f', 'rcfile', '', _('read maps from rcfile'))],
+ _('hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...')),
+ 'kwexpand': (expand, commands.walkopts,
+ _('hg kwexpand [OPTION]... [FILE]...')),
+ 'kwfiles':
+ (files,
+ [('a', 'all', None, _('show keyword status flags of all files')),
+ ('i', 'ignore', None, _('show files excluded from expansion')),
+ ('u', 'untracked', None, _('additionally show untracked files')),
+ ] + commands.walkopts,
+ _('hg kwfiles [OPTION]... [FILE]...')),
+ 'kwshrink': (shrink, commands.walkopts,
+ _('hg kwshrink [OPTION]... [FILE]...')),
+}
diff --git a/sys/src/cmd/hg/hgext/mq.py b/sys/src/cmd/hg/hgext/mq.py
new file mode 100644
index 000000000..a2be932c4
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/mq.py
@@ -0,0 +1,2653 @@
+# mq.py - patch queues for mercurial
+#
+# Copyright 2005, 2006 Chris Mason <mason@suse.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''manage a stack of patches
+
+This extension lets you work with a stack of patches in a Mercurial
+repository. It manages two stacks of patches - all known patches, and
+applied patches (subset of known patches).
+
+Known patches are represented as patch files in the .hg/patches
+directory. Applied patches are both patch files and changesets.
+
+Common tasks (use "hg help command" for more details)::
+
+ prepare repository to work with patches qinit
+ create new patch qnew
+ import existing patch qimport
+
+ print patch series qseries
+ print applied patches qapplied
+ print name of top applied patch qtop
+
+ add known patch to applied stack qpush
+ remove patch from applied stack qpop
+ refresh contents of top applied patch qrefresh
+'''
+
+from mercurial.i18n import _
+from mercurial.node import bin, hex, short, nullid, nullrev
+from mercurial.lock import release
+from mercurial import commands, cmdutil, hg, patch, util
+from mercurial import repair, extensions, url, error
+import os, sys, re, errno
+
+commands.norepo += " qclone"
+
+# Patch names looks like unix-file names.
+# They must be joinable with queue directory and result in the patch path.
+normname = util.normpath
+
+class statusentry(object):
+ def __init__(self, rev, name=None):
+ if not name:
+ fields = rev.split(':', 1)
+ if len(fields) == 2:
+ self.rev, self.name = fields
+ else:
+ self.rev, self.name = None, None
+ else:
+ self.rev, self.name = rev, name
+
+ def __str__(self):
+ return self.rev + ':' + self.name
+
+class patchheader(object):
+ def __init__(self, pf):
+ def eatdiff(lines):
+ while lines:
+ l = lines[-1]
+ if (l.startswith("diff -") or
+ l.startswith("Index:") or
+ l.startswith("===========")):
+ del lines[-1]
+ else:
+ break
+ def eatempty(lines):
+ while lines:
+ l = lines[-1]
+ if re.match('\s*$', l):
+ del lines[-1]
+ else:
+ break
+
+ message = []
+ comments = []
+ user = None
+ date = None
+ format = None
+ subject = None
+ diffstart = 0
+
+ for line in file(pf):
+ line = line.rstrip()
+ if line.startswith('diff --git'):
+ diffstart = 2
+ break
+ if diffstart:
+ if line.startswith('+++ '):
+ diffstart = 2
+ break
+ if line.startswith("--- "):
+ diffstart = 1
+ continue
+ elif format == "hgpatch":
+ # parse values when importing the result of an hg export
+ if line.startswith("# User "):
+ user = line[7:]
+ elif line.startswith("# Date "):
+ date = line[7:]
+ elif not line.startswith("# ") and line:
+ message.append(line)
+ format = None
+ elif line == '# HG changeset patch':
+ message = []
+ format = "hgpatch"
+ elif (format != "tagdone" and (line.startswith("Subject: ") or
+ line.startswith("subject: "))):
+ subject = line[9:]
+ format = "tag"
+ elif (format != "tagdone" and (line.startswith("From: ") or
+ line.startswith("from: "))):
+ user = line[6:]
+ format = "tag"
+ elif format == "tag" and line == "":
+ # when looking for tags (subject: from: etc) they
+ # end once you find a blank line in the source
+ format = "tagdone"
+ elif message or line:
+ message.append(line)
+ comments.append(line)
+
+ eatdiff(message)
+ eatdiff(comments)
+ eatempty(message)
+ eatempty(comments)
+
+ # make sure message isn't empty
+ if format and format.startswith("tag") and subject:
+ message.insert(0, "")
+ message.insert(0, subject)
+
+ self.message = message
+ self.comments = comments
+ self.user = user
+ self.date = date
+ self.haspatch = diffstart > 1
+
+ def setuser(self, user):
+ if not self.updateheader(['From: ', '# User '], user):
+ try:
+ patchheaderat = self.comments.index('# HG changeset patch')
+ self.comments.insert(patchheaderat + 1, '# User ' + user)
+ except ValueError:
+ if self._hasheader(['Date: ']):
+ self.comments = ['From: ' + user] + self.comments
+ else:
+ tmp = ['# HG changeset patch', '# User ' + user, '']
+ self.comments = tmp + self.comments
+ self.user = user
+
+ def setdate(self, date):
+ if not self.updateheader(['Date: ', '# Date '], date):
+ try:
+ patchheaderat = self.comments.index('# HG changeset patch')
+ self.comments.insert(patchheaderat + 1, '# Date ' + date)
+ except ValueError:
+ if self._hasheader(['From: ']):
+ self.comments = ['Date: ' + date] + self.comments
+ else:
+ tmp = ['# HG changeset patch', '# Date ' + date, '']
+ self.comments = tmp + self.comments
+ self.date = date
+
+ def setmessage(self, message):
+ if self.comments:
+ self._delmsg()
+ self.message = [message]
+ self.comments += self.message
+
+ def updateheader(self, prefixes, new):
+ '''Update all references to a field in the patch header.
+ Return whether the field is present.'''
+ res = False
+ for prefix in prefixes:
+ for i in xrange(len(self.comments)):
+ if self.comments[i].startswith(prefix):
+ self.comments[i] = prefix + new
+ res = True
+ break
+ return res
+
+ def _hasheader(self, prefixes):
+ '''Check if a header starts with any of the given prefixes.'''
+ for prefix in prefixes:
+ for comment in self.comments:
+ if comment.startswith(prefix):
+ return True
+ return False
+
+ def __str__(self):
+ if not self.comments:
+ return ''
+ return '\n'.join(self.comments) + '\n\n'
+
+ def _delmsg(self):
+ '''Remove existing message, keeping the rest of the comments fields.
+ If comments contains 'subject: ', message will prepend
+ the field and a blank line.'''
+ if self.message:
+ subj = 'subject: ' + self.message[0].lower()
+ for i in xrange(len(self.comments)):
+ if subj == self.comments[i].lower():
+ del self.comments[i]
+ self.message = self.message[2:]
+ break
+ ci = 0
+ for mi in self.message:
+ while mi != self.comments[ci]:
+ ci += 1
+ del self.comments[ci]
+
+class queue(object):
+ def __init__(self, ui, path, patchdir=None):
+ self.basepath = path
+ self.path = patchdir or os.path.join(path, "patches")
+ self.opener = util.opener(self.path)
+ self.ui = ui
+ self.applied_dirty = 0
+ self.series_dirty = 0
+ self.series_path = "series"
+ self.status_path = "status"
+ self.guards_path = "guards"
+ self.active_guards = None
+ self.guards_dirty = False
+ self._diffopts = None
+
+ @util.propertycache
+ def applied(self):
+ if os.path.exists(self.join(self.status_path)):
+ lines = self.opener(self.status_path).read().splitlines()
+ return [statusentry(l) for l in lines]
+ return []
+
+ @util.propertycache
+ def full_series(self):
+ if os.path.exists(self.join(self.series_path)):
+ return self.opener(self.series_path).read().splitlines()
+ return []
+
+ @util.propertycache
+ def series(self):
+ self.parse_series()
+ return self.series
+
+ @util.propertycache
+ def series_guards(self):
+ self.parse_series()
+ return self.series_guards
+
+ def invalidate(self):
+ for a in 'applied full_series series series_guards'.split():
+ if a in self.__dict__:
+ delattr(self, a)
+ self.applied_dirty = 0
+ self.series_dirty = 0
+ self.guards_dirty = False
+ self.active_guards = None
+
+ def diffopts(self):
+ if self._diffopts is None:
+ self._diffopts = patch.diffopts(self.ui)
+ return self._diffopts
+
+ def join(self, *p):
+ return os.path.join(self.path, *p)
+
+ def find_series(self, patch):
+ pre = re.compile("(\s*)([^#]+)")
+ index = 0
+ for l in self.full_series:
+ m = pre.match(l)
+ if m:
+ s = m.group(2)
+ s = s.rstrip()
+ if s == patch:
+ return index
+ index += 1
+ return None
+
+ guard_re = re.compile(r'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)')
+
+ def parse_series(self):
+ self.series = []
+ self.series_guards = []
+ for l in self.full_series:
+ h = l.find('#')
+ if h == -1:
+ patch = l
+ comment = ''
+ elif h == 0:
+ continue
+ else:
+ patch = l[:h]
+ comment = l[h:]
+ patch = patch.strip()
+ if patch:
+ if patch in self.series:
+ raise util.Abort(_('%s appears more than once in %s') %
+ (patch, self.join(self.series_path)))
+ self.series.append(patch)
+ self.series_guards.append(self.guard_re.findall(comment))
+
+ def check_guard(self, guard):
+ if not guard:
+ return _('guard cannot be an empty string')
+ bad_chars = '# \t\r\n\f'
+ first = guard[0]
+ if first in '-+':
+ return (_('guard %r starts with invalid character: %r') %
+ (guard, first))
+ for c in bad_chars:
+ if c in guard:
+ return _('invalid character in guard %r: %r') % (guard, c)
+
+ def set_active(self, guards):
+ for guard in guards:
+ bad = self.check_guard(guard)
+ if bad:
+ raise util.Abort(bad)
+ guards = sorted(set(guards))
+ self.ui.debug(_('active guards: %s\n') % ' '.join(guards))
+ self.active_guards = guards
+ self.guards_dirty = True
+
+ def active(self):
+ if self.active_guards is None:
+ self.active_guards = []
+ try:
+ guards = self.opener(self.guards_path).read().split()
+ except IOError, err:
+ if err.errno != errno.ENOENT: raise
+ guards = []
+ for i, guard in enumerate(guards):
+ bad = self.check_guard(guard)
+ if bad:
+ self.ui.warn('%s:%d: %s\n' %
+ (self.join(self.guards_path), i + 1, bad))
+ else:
+ self.active_guards.append(guard)
+ return self.active_guards
+
+ def set_guards(self, idx, guards):
+ for g in guards:
+ if len(g) < 2:
+ raise util.Abort(_('guard %r too short') % g)
+ if g[0] not in '-+':
+ raise util.Abort(_('guard %r starts with invalid char') % g)
+ bad = self.check_guard(g[1:])
+ if bad:
+ raise util.Abort(bad)
+ drop = self.guard_re.sub('', self.full_series[idx])
+ self.full_series[idx] = drop + ''.join([' #' + g for g in guards])
+ self.parse_series()
+ self.series_dirty = True
+
+ def pushable(self, idx):
+ if isinstance(idx, str):
+ idx = self.series.index(idx)
+ patchguards = self.series_guards[idx]
+ if not patchguards:
+ return True, None
+ guards = self.active()
+ exactneg = [g for g in patchguards if g[0] == '-' and g[1:] in guards]
+ if exactneg:
+ return False, exactneg[0]
+ pos = [g for g in patchguards if g[0] == '+']
+ exactpos = [g for g in pos if g[1:] in guards]
+ if pos:
+ if exactpos:
+ return True, exactpos[0]
+ return False, pos
+ return True, ''
+
+ def explain_pushable(self, idx, all_patches=False):
+ write = all_patches and self.ui.write or self.ui.warn
+ if all_patches or self.ui.verbose:
+ if isinstance(idx, str):
+ idx = self.series.index(idx)
+ pushable, why = self.pushable(idx)
+ if all_patches and pushable:
+ if why is None:
+ write(_('allowing %s - no guards in effect\n') %
+ self.series[idx])
+ else:
+ if not why:
+ write(_('allowing %s - no matching negative guards\n') %
+ self.series[idx])
+ else:
+ write(_('allowing %s - guarded by %r\n') %
+ (self.series[idx], why))
+ if not pushable:
+ if why:
+ write(_('skipping %s - guarded by %r\n') %
+ (self.series[idx], why))
+ else:
+ write(_('skipping %s - no matching guards\n') %
+ self.series[idx])
+
+ def save_dirty(self):
+ def write_list(items, path):
+ fp = self.opener(path, 'w')
+ for i in items:
+ fp.write("%s\n" % i)
+ fp.close()
+ if self.applied_dirty: write_list(map(str, self.applied), self.status_path)
+ if self.series_dirty: write_list(self.full_series, self.series_path)
+ if self.guards_dirty: write_list(self.active_guards, self.guards_path)
+
+ def removeundo(self, repo):
+ undo = repo.sjoin('undo')
+ if not os.path.exists(undo):
+ return
+ try:
+ os.unlink(undo)
+ except OSError, inst:
+ self.ui.warn(_('error removing undo: %s\n') % str(inst))
+
+ def printdiff(self, repo, node1, node2=None, files=None,
+ fp=None, changes=None, opts={}):
+ m = cmdutil.match(repo, files, opts)
+ chunks = patch.diff(repo, node1, node2, m, changes, self.diffopts())
+ write = fp is None and repo.ui.write or fp.write
+ for chunk in chunks:
+ write(chunk)
+
+ def mergeone(self, repo, mergeq, head, patch, rev):
+ # first try just applying the patch
+ (err, n) = self.apply(repo, [ patch ], update_status=False,
+ strict=True, merge=rev)
+
+ if err == 0:
+ return (err, n)
+
+ if n is None:
+ raise util.Abort(_("apply failed for patch %s") % patch)
+
+ self.ui.warn(_("patch didn't work out, merging %s\n") % patch)
+
+ # apply failed, strip away that rev and merge.
+ hg.clean(repo, head)
+ self.strip(repo, n, update=False, backup='strip')
+
+ ctx = repo[rev]
+ ret = hg.merge(repo, rev)
+ if ret:
+ raise util.Abort(_("update returned %d") % ret)
+ n = repo.commit(ctx.description(), ctx.user(), force=True)
+ if n is None:
+ raise util.Abort(_("repo commit failed"))
+ try:
+ ph = patchheader(mergeq.join(patch))
+ except:
+ raise util.Abort(_("unable to read %s") % patch)
+
+ patchf = self.opener(patch, "w")
+ comments = str(ph)
+ if comments:
+ patchf.write(comments)
+ self.printdiff(repo, head, n, fp=patchf)
+ patchf.close()
+ self.removeundo(repo)
+ return (0, n)
+
+ def qparents(self, repo, rev=None):
+ if rev is None:
+ (p1, p2) = repo.dirstate.parents()
+ if p2 == nullid:
+ return p1
+ if len(self.applied) == 0:
+ return None
+ return bin(self.applied[-1].rev)
+ pp = repo.changelog.parents(rev)
+ if pp[1] != nullid:
+ arevs = [ x.rev for x in self.applied ]
+ p0 = hex(pp[0])
+ p1 = hex(pp[1])
+ if p0 in arevs:
+ return pp[0]
+ if p1 in arevs:
+ return pp[1]
+ return pp[0]
+
+ def mergepatch(self, repo, mergeq, series):
+ if len(self.applied) == 0:
+ # each of the patches merged in will have two parents. This
+ # can confuse the qrefresh, qdiff, and strip code because it
+ # needs to know which parent is actually in the patch queue.
+ # so, we insert a merge marker with only one parent. This way
+ # the first patch in the queue is never a merge patch
+ #
+ pname = ".hg.patches.merge.marker"
+ n = repo.commit('[mq]: merge marker', force=True)
+ self.removeundo(repo)
+ self.applied.append(statusentry(hex(n), pname))
+ self.applied_dirty = 1
+
+ head = self.qparents(repo)
+
+ for patch in series:
+ patch = mergeq.lookup(patch, strict=True)
+ if not patch:
+ self.ui.warn(_("patch %s does not exist\n") % patch)
+ return (1, None)
+ pushable, reason = self.pushable(patch)
+ if not pushable:
+ self.explain_pushable(patch, all_patches=True)
+ continue
+ info = mergeq.isapplied(patch)
+ if not info:
+ self.ui.warn(_("patch %s is not applied\n") % patch)
+ return (1, None)
+ rev = bin(info[1])
+ (err, head) = self.mergeone(repo, mergeq, head, patch, rev)
+ if head:
+ self.applied.append(statusentry(hex(head), patch))
+ self.applied_dirty = 1
+ if err:
+ return (err, head)
+ self.save_dirty()
+ return (0, head)
+
+ def patch(self, repo, patchfile):
+ '''Apply patchfile to the working directory.
+ patchfile: name of patch file'''
+ files = {}
+ try:
+ fuzz = patch.patch(patchfile, self.ui, strip=1, cwd=repo.root,
+ files=files, eolmode=None)
+ except Exception, inst:
+ self.ui.note(str(inst) + '\n')
+ if not self.ui.verbose:
+ self.ui.warn(_("patch failed, unable to continue (try -v)\n"))
+ return (False, files, False)
+
+ return (True, files, fuzz)
+
+ def apply(self, repo, series, list=False, update_status=True,
+ strict=False, patchdir=None, merge=None, all_files={}):
+ wlock = lock = tr = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ tr = repo.transaction()
+ try:
+ ret = self._apply(repo, series, list, update_status,
+ strict, patchdir, merge, all_files=all_files)
+ tr.close()
+ self.save_dirty()
+ return ret
+ except:
+ try:
+ tr.abort()
+ finally:
+ repo.invalidate()
+ repo.dirstate.invalidate()
+ raise
+ finally:
+ del tr
+ release(lock, wlock)
+ self.removeundo(repo)
+
+ def _apply(self, repo, series, list=False, update_status=True,
+ strict=False, patchdir=None, merge=None, all_files={}):
+ '''returns (error, hash)
+ error = 1 for unable to read, 2 for patch failed, 3 for patch fuzz'''
+ # TODO unify with commands.py
+ if not patchdir:
+ patchdir = self.path
+ err = 0
+ n = None
+ for patchname in series:
+ pushable, reason = self.pushable(patchname)
+ if not pushable:
+ self.explain_pushable(patchname, all_patches=True)
+ continue
+ self.ui.status(_("applying %s\n") % patchname)
+ pf = os.path.join(patchdir, patchname)
+
+ try:
+ ph = patchheader(self.join(patchname))
+ except:
+ self.ui.warn(_("unable to read %s\n") % patchname)
+ err = 1
+ break
+
+ message = ph.message
+ if not message:
+ message = _("imported patch %s\n") % patchname
+ else:
+ if list:
+ message.append(_("\nimported patch %s") % patchname)
+ message = '\n'.join(message)
+
+ if ph.haspatch:
+ (patcherr, files, fuzz) = self.patch(repo, pf)
+ all_files.update(files)
+ patcherr = not patcherr
+ else:
+ self.ui.warn(_("patch %s is empty\n") % patchname)
+ patcherr, files, fuzz = 0, [], 0
+
+ if merge and files:
+ # Mark as removed/merged and update dirstate parent info
+ removed = []
+ merged = []
+ for f in files:
+ if os.path.exists(repo.wjoin(f)):
+ merged.append(f)
+ else:
+ removed.append(f)
+ for f in removed:
+ repo.dirstate.remove(f)
+ for f in merged:
+ repo.dirstate.merge(f)
+ p1, p2 = repo.dirstate.parents()
+ repo.dirstate.setparents(p1, merge)
+
+ files = patch.updatedir(self.ui, repo, files)
+ match = cmdutil.matchfiles(repo, files or [])
+ n = repo.commit(message, ph.user, ph.date, match=match, force=True)
+
+ if n is None:
+ raise util.Abort(_("repo commit failed"))
+
+ if update_status:
+ self.applied.append(statusentry(hex(n), patchname))
+
+ if patcherr:
+ self.ui.warn(_("patch failed, rejects left in working dir\n"))
+ err = 2
+ break
+
+ if fuzz and strict:
+ self.ui.warn(_("fuzz found when applying patch, stopping\n"))
+ err = 3
+ break
+ return (err, n)
+
+ def _cleanup(self, patches, numrevs, keep=False):
+ if not keep:
+ r = self.qrepo()
+ if r:
+ r.remove(patches, True)
+ else:
+ for p in patches:
+ os.unlink(self.join(p))
+
+ if numrevs:
+ del self.applied[:numrevs]
+ self.applied_dirty = 1
+
+ for i in sorted([self.find_series(p) for p in patches], reverse=True):
+ del self.full_series[i]
+ self.parse_series()
+ self.series_dirty = 1
+
+ def _revpatches(self, repo, revs):
+ firstrev = repo[self.applied[0].rev].rev()
+ patches = []
+ for i, rev in enumerate(revs):
+
+ if rev < firstrev:
+ raise util.Abort(_('revision %d is not managed') % rev)
+
+ ctx = repo[rev]
+ base = bin(self.applied[i].rev)
+ if ctx.node() != base:
+ msg = _('cannot delete revision %d above applied patches')
+ raise util.Abort(msg % rev)
+
+ patch = self.applied[i].name
+ for fmt in ('[mq]: %s', 'imported patch %s'):
+ if ctx.description() == fmt % patch:
+ msg = _('patch %s finalized without changeset message\n')
+ repo.ui.status(msg % patch)
+ break
+
+ patches.append(patch)
+ return patches
+
+ def finish(self, repo, revs):
+ patches = self._revpatches(repo, sorted(revs))
+ self._cleanup(patches, len(patches))
+
+ def delete(self, repo, patches, opts):
+ if not patches and not opts.get('rev'):
+ raise util.Abort(_('qdelete requires at least one revision or '
+ 'patch name'))
+
+ realpatches = []
+ for patch in patches:
+ patch = self.lookup(patch, strict=True)
+ info = self.isapplied(patch)
+ if info:
+ raise util.Abort(_("cannot delete applied patch %s") % patch)
+ if patch not in self.series:
+ raise util.Abort(_("patch %s not in series file") % patch)
+ realpatches.append(patch)
+
+ numrevs = 0
+ if opts.get('rev'):
+ if not self.applied:
+ raise util.Abort(_('no patches applied'))
+ revs = cmdutil.revrange(repo, opts['rev'])
+ if len(revs) > 1 and revs[0] > revs[1]:
+ revs.reverse()
+ revpatches = self._revpatches(repo, revs)
+ realpatches += revpatches
+ numrevs = len(revpatches)
+
+ self._cleanup(realpatches, numrevs, opts.get('keep'))
+
+ def check_toppatch(self, repo):
+ if len(self.applied) > 0:
+ top = bin(self.applied[-1].rev)
+ pp = repo.dirstate.parents()
+ if top not in pp:
+ raise util.Abort(_("working directory revision is not qtip"))
+ return top
+ return None
+ def check_localchanges(self, repo, force=False, refresh=True):
+ m, a, r, d = repo.status()[:4]
+ if m or a or r or d:
+ if not force:
+ if refresh:
+ raise util.Abort(_("local changes found, refresh first"))
+ else:
+ raise util.Abort(_("local changes found"))
+ return m, a, r, d
+
+ _reserved = ('series', 'status', 'guards')
+ def check_reserved_name(self, name):
+ if (name in self._reserved or name.startswith('.hg')
+ or name.startswith('.mq')):
+ raise util.Abort(_('"%s" cannot be used as the name of a patch')
+ % name)
+
+ def new(self, repo, patchfn, *pats, **opts):
+ """options:
+ msg: a string or a no-argument function returning a string
+ """
+ msg = opts.get('msg')
+ force = opts.get('force')
+ user = opts.get('user')
+ date = opts.get('date')
+ if date:
+ date = util.parsedate(date)
+ self.check_reserved_name(patchfn)
+ if os.path.exists(self.join(patchfn)):
+ raise util.Abort(_('patch "%s" already exists') % patchfn)
+ if opts.get('include') or opts.get('exclude') or pats:
+ match = cmdutil.match(repo, pats, opts)
+ # detect missing files in pats
+ def badfn(f, msg):
+ raise util.Abort('%s: %s' % (f, msg))
+ match.bad = badfn
+ m, a, r, d = repo.status(match=match)[:4]
+ else:
+ m, a, r, d = self.check_localchanges(repo, force)
+ match = cmdutil.matchfiles(repo, m + a + r)
+ commitfiles = m + a + r
+ self.check_toppatch(repo)
+ insert = self.full_series_end()
+ wlock = repo.wlock()
+ try:
+ # if patch file write fails, abort early
+ p = self.opener(patchfn, "w")
+ try:
+ if date:
+ p.write("# HG changeset patch\n")
+ if user:
+ p.write("# User " + user + "\n")
+ p.write("# Date %d %d\n\n" % date)
+ elif user:
+ p.write("From: " + user + "\n\n")
+
+ if hasattr(msg, '__call__'):
+ msg = msg()
+ commitmsg = msg and msg or ("[mq]: %s" % patchfn)
+ n = repo.commit(commitmsg, user, date, match=match, force=True)
+ if n is None:
+ raise util.Abort(_("repo commit failed"))
+ try:
+ self.full_series[insert:insert] = [patchfn]
+ self.applied.append(statusentry(hex(n), patchfn))
+ self.parse_series()
+ self.series_dirty = 1
+ self.applied_dirty = 1
+ if msg:
+ msg = msg + "\n\n"
+ p.write(msg)
+ if commitfiles:
+ diffopts = self.diffopts()
+ if opts.get('git'): diffopts.git = True
+ parent = self.qparents(repo, n)
+ chunks = patch.diff(repo, node1=parent, node2=n,
+ match=match, opts=diffopts)
+ for chunk in chunks:
+ p.write(chunk)
+ p.close()
+ wlock.release()
+ wlock = None
+ r = self.qrepo()
+ if r: r.add([patchfn])
+ except:
+ repo.rollback()
+ raise
+ except Exception:
+ patchpath = self.join(patchfn)
+ try:
+ os.unlink(patchpath)
+ except:
+ self.ui.warn(_('error unlinking %s\n') % patchpath)
+ raise
+ self.removeundo(repo)
+ finally:
+ release(wlock)
+
+ def strip(self, repo, rev, update=True, backup="all", force=None):
+ wlock = lock = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+
+ if update:
+ self.check_localchanges(repo, force=force, refresh=False)
+ urev = self.qparents(repo, rev)
+ hg.clean(repo, urev)
+ repo.dirstate.write()
+
+ self.removeundo(repo)
+ repair.strip(self.ui, repo, rev, backup)
+ # strip may have unbundled a set of backed up revisions after
+ # the actual strip
+ self.removeundo(repo)
+ finally:
+ release(lock, wlock)
+
+ def isapplied(self, patch):
+ """returns (index, rev, patch)"""
+ for i, a in enumerate(self.applied):
+ if a.name == patch:
+ return (i, a.rev, a.name)
+ return None
+
+ # if the exact patch name does not exist, we try a few
+ # variations. If strict is passed, we try only #1
+ #
+ # 1) a number to indicate an offset in the series file
+ # 2) a unique substring of the patch name was given
+ # 3) patchname[-+]num to indicate an offset in the series file
+ def lookup(self, patch, strict=False):
+ patch = patch and str(patch)
+
+ def partial_name(s):
+ if s in self.series:
+ return s
+ matches = [x for x in self.series if s in x]
+ if len(matches) > 1:
+ self.ui.warn(_('patch name "%s" is ambiguous:\n') % s)
+ for m in matches:
+ self.ui.warn(' %s\n' % m)
+ return None
+ if matches:
+ return matches[0]
+ if len(self.series) > 0 and len(self.applied) > 0:
+ if s == 'qtip':
+ return self.series[self.series_end(True)-1]
+ if s == 'qbase':
+ return self.series[0]
+ return None
+
+ if patch is None:
+ return None
+ if patch in self.series:
+ return patch
+
+ if not os.path.isfile(self.join(patch)):
+ try:
+ sno = int(patch)
+ except(ValueError, OverflowError):
+ pass
+ else:
+ if -len(self.series) <= sno < len(self.series):
+ return self.series[sno]
+
+ if not strict:
+ res = partial_name(patch)
+ if res:
+ return res
+ minus = patch.rfind('-')
+ if minus >= 0:
+ res = partial_name(patch[:minus])
+ if res:
+ i = self.series.index(res)
+ try:
+ off = int(patch[minus+1:] or 1)
+ except(ValueError, OverflowError):
+ pass
+ else:
+ if i - off >= 0:
+ return self.series[i - off]
+ plus = patch.rfind('+')
+ if plus >= 0:
+ res = partial_name(patch[:plus])
+ if res:
+ i = self.series.index(res)
+ try:
+ off = int(patch[plus+1:] or 1)
+ except(ValueError, OverflowError):
+ pass
+ else:
+ if i + off < len(self.series):
+ return self.series[i + off]
+ raise util.Abort(_("patch %s not in series") % patch)
+
+ def push(self, repo, patch=None, force=False, list=False,
+ mergeq=None, all=False):
+ wlock = repo.wlock()
+ try:
+ if repo.dirstate.parents()[0] not in repo.heads():
+ self.ui.status(_("(working directory not at a head)\n"))
+
+ if not self.series:
+ self.ui.warn(_('no patches in series\n'))
+ return 0
+
+ patch = self.lookup(patch)
+ # Suppose our series file is: A B C and the current 'top'
+ # patch is B. qpush C should be performed (moving forward)
+ # qpush B is a NOP (no change) qpush A is an error (can't
+ # go backwards with qpush)
+ if patch:
+ info = self.isapplied(patch)
+ if info:
+ if info[0] < len(self.applied) - 1:
+ raise util.Abort(
+ _("cannot push to a previous patch: %s") % patch)
+ self.ui.warn(
+ _('qpush: %s is already at the top\n') % patch)
+ return
+ pushable, reason = self.pushable(patch)
+ if not pushable:
+ if reason:
+ reason = _('guarded by %r') % reason
+ else:
+ reason = _('no matching guards')
+ self.ui.warn(_("cannot push '%s' - %s\n") % (patch, reason))
+ return 1
+ elif all:
+ patch = self.series[-1]
+ if self.isapplied(patch):
+ self.ui.warn(_('all patches are currently applied\n'))
+ return 0
+
+ # Following the above example, starting at 'top' of B:
+ # qpush should be performed (pushes C), but a subsequent
+ # qpush without an argument is an error (nothing to
+ # apply). This allows a loop of "...while hg qpush..." to
+ # work as it detects an error when done
+ start = self.series_end()
+ if start == len(self.series):
+ self.ui.warn(_('patch series already fully applied\n'))
+ return 1
+ if not force:
+ self.check_localchanges(repo)
+
+ self.applied_dirty = 1
+ if start > 0:
+ self.check_toppatch(repo)
+ if not patch:
+ patch = self.series[start]
+ end = start + 1
+ else:
+ end = self.series.index(patch, start) + 1
+
+ s = self.series[start:end]
+ all_files = {}
+ try:
+ if mergeq:
+ ret = self.mergepatch(repo, mergeq, s)
+ else:
+ ret = self.apply(repo, s, list, all_files=all_files)
+ except:
+ self.ui.warn(_('cleaning up working directory...'))
+ node = repo.dirstate.parents()[0]
+ hg.revert(repo, node, None)
+ unknown = repo.status(unknown=True)[4]
+ # only remove unknown files that we know we touched or
+ # created while patching
+ for f in unknown:
+ if f in all_files:
+ util.unlink(repo.wjoin(f))
+ self.ui.warn(_('done\n'))
+ raise
+
+ top = self.applied[-1].name
+ if ret[0] and ret[0] > 1:
+ msg = _("errors during apply, please fix and refresh %s\n")
+ self.ui.write(msg % top)
+ else:
+ self.ui.write(_("now at: %s\n") % top)
+ return ret[0]
+
+ finally:
+ wlock.release()
+
+ def pop(self, repo, patch=None, force=False, update=True, all=False):
+ def getfile(f, rev, flags):
+ t = repo.file(f).read(rev)
+ repo.wwrite(f, t, flags)
+
+ wlock = repo.wlock()
+ try:
+ if patch:
+ # index, rev, patch
+ info = self.isapplied(patch)
+ if not info:
+ patch = self.lookup(patch)
+ info = self.isapplied(patch)
+ if not info:
+ raise util.Abort(_("patch %s is not applied") % patch)
+
+ if len(self.applied) == 0:
+ # Allow qpop -a to work repeatedly,
+ # but not qpop without an argument
+ self.ui.warn(_("no patches applied\n"))
+ return not all
+
+ if all:
+ start = 0
+ elif patch:
+ start = info[0] + 1
+ else:
+ start = len(self.applied) - 1
+
+ if start >= len(self.applied):
+ self.ui.warn(_("qpop: %s is already at the top\n") % patch)
+ return
+
+ if not update:
+ parents = repo.dirstate.parents()
+ rr = [ bin(x.rev) for x in self.applied ]
+ for p in parents:
+ if p in rr:
+ self.ui.warn(_("qpop: forcing dirstate update\n"))
+ update = True
+ else:
+ parents = [p.hex() for p in repo[None].parents()]
+ needupdate = False
+ for entry in self.applied[start:]:
+ if entry.rev in parents:
+ needupdate = True
+ break
+ update = needupdate
+
+ if not force and update:
+ self.check_localchanges(repo)
+
+ self.applied_dirty = 1
+ end = len(self.applied)
+ rev = bin(self.applied[start].rev)
+ if update:
+ top = self.check_toppatch(repo)
+
+ try:
+ heads = repo.changelog.heads(rev)
+ except error.LookupError:
+ node = short(rev)
+ raise util.Abort(_('trying to pop unknown node %s') % node)
+
+ if heads != [bin(self.applied[-1].rev)]:
+ raise util.Abort(_("popping would remove a revision not "
+ "managed by this patch queue"))
+
+ # we know there are no local changes, so we can make a simplified
+ # form of hg.update.
+ if update:
+ qp = self.qparents(repo, rev)
+ changes = repo.changelog.read(qp)
+ mmap = repo.manifest.read(changes[0])
+ m, a, r, d = repo.status(qp, top)[:4]
+ if d:
+ raise util.Abort(_("deletions found between repo revs"))
+ for f in m:
+ getfile(f, mmap[f], mmap.flags(f))
+ for f in r:
+ getfile(f, mmap[f], mmap.flags(f))
+ for f in m + r:
+ repo.dirstate.normal(f)
+ for f in a:
+ try:
+ os.unlink(repo.wjoin(f))
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+ try: os.removedirs(os.path.dirname(repo.wjoin(f)))
+ except: pass
+ repo.dirstate.forget(f)
+ repo.dirstate.setparents(qp, nullid)
+ for patch in reversed(self.applied[start:end]):
+ self.ui.status(_("popping %s\n") % patch.name)
+ del self.applied[start:end]
+ self.strip(repo, rev, update=False, backup='strip')
+ if len(self.applied):
+ self.ui.write(_("now at: %s\n") % self.applied[-1].name)
+ else:
+ self.ui.write(_("patch queue now empty\n"))
+ finally:
+ wlock.release()
+
+ def diff(self, repo, pats, opts):
+ top = self.check_toppatch(repo)
+ if not top:
+ self.ui.write(_("no patches applied\n"))
+ return
+ qp = self.qparents(repo, top)
+ self._diffopts = patch.diffopts(self.ui, opts)
+ self.printdiff(repo, qp, files=pats, opts=opts)
+
+ def refresh(self, repo, pats=None, **opts):
+ if len(self.applied) == 0:
+ self.ui.write(_("no patches applied\n"))
+ return 1
+ msg = opts.get('msg', '').rstrip()
+ newuser = opts.get('user')
+ newdate = opts.get('date')
+ if newdate:
+ newdate = '%d %d' % util.parsedate(newdate)
+ wlock = repo.wlock()
+ try:
+ self.check_toppatch(repo)
+ (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name)
+ top = bin(top)
+ if repo.changelog.heads(top) != [top]:
+ raise util.Abort(_("cannot refresh a revision with children"))
+ cparents = repo.changelog.parents(top)
+ patchparent = self.qparents(repo, top)
+ ph = patchheader(self.join(patchfn))
+
+ patchf = self.opener(patchfn, 'r')
+
+ # if the patch was a git patch, refresh it as a git patch
+ for line in patchf:
+ if line.startswith('diff --git'):
+ self.diffopts().git = True
+ break
+
+ if msg:
+ ph.setmessage(msg)
+ if newuser:
+ ph.setuser(newuser)
+ if newdate:
+ ph.setdate(newdate)
+
+ # only commit new patch when write is complete
+ patchf = self.opener(patchfn, 'w', atomictemp=True)
+
+ patchf.seek(0)
+ patchf.truncate()
+
+ comments = str(ph)
+ if comments:
+ patchf.write(comments)
+
+ if opts.get('git'):
+ self.diffopts().git = True
+ tip = repo.changelog.tip()
+ if top == tip:
+ # if the top of our patch queue is also the tip, there is an
+ # optimization here. We update the dirstate in place and strip
+ # off the tip commit. Then just commit the current directory
+ # tree. We can also send repo.commit the list of files
+ # changed to speed up the diff
+ #
+ # in short mode, we only diff the files included in the
+ # patch already plus specified files
+ #
+ # this should really read:
+ # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
+ # but we do it backwards to take advantage of manifest/chlog
+ # caching against the next repo.status call
+ #
+ mm, aa, dd, aa2 = repo.status(patchparent, tip)[:4]
+ changes = repo.changelog.read(tip)
+ man = repo.manifest.read(changes[0])
+ aaa = aa[:]
+ matchfn = cmdutil.match(repo, pats, opts)
+ if opts.get('short'):
+ # if amending a patch, we start with existing
+ # files plus specified files - unfiltered
+ match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
+ # filter with inc/exl options
+ matchfn = cmdutil.match(repo, opts=opts)
+ else:
+ match = cmdutil.matchall(repo)
+ m, a, r, d = repo.status(match=match)[:4]
+
+ # we might end up with files that were added between
+ # tip and the dirstate parent, but then changed in the
+ # local dirstate. in this case, we want them to only
+ # show up in the added section
+ for x in m:
+ if x not in aa:
+ mm.append(x)
+ # we might end up with files added by the local dirstate that
+ # were deleted by the patch. In this case, they should only
+ # show up in the changed section.
+ for x in a:
+ if x in dd:
+ del dd[dd.index(x)]
+ mm.append(x)
+ else:
+ aa.append(x)
+ # make sure any files deleted in the local dirstate
+ # are not in the add or change column of the patch
+ forget = []
+ for x in d + r:
+ if x in aa:
+ del aa[aa.index(x)]
+ forget.append(x)
+ continue
+ elif x in mm:
+ del mm[mm.index(x)]
+ dd.append(x)
+
+ m = list(set(mm))
+ r = list(set(dd))
+ a = list(set(aa))
+ c = [filter(matchfn, l) for l in (m, a, r)]
+ match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
+ chunks = patch.diff(repo, patchparent, match=match,
+ changes=c, opts=self.diffopts())
+ for chunk in chunks:
+ patchf.write(chunk)
+
+ try:
+ if self.diffopts().git:
+ copies = {}
+ for dst in a:
+ src = repo.dirstate.copied(dst)
+ # during qfold, the source file for copies may
+ # be removed. Treat this as a simple add.
+ if src is not None and src in repo.dirstate:
+ copies.setdefault(src, []).append(dst)
+ repo.dirstate.add(dst)
+ # remember the copies between patchparent and tip
+ for dst in aaa:
+ f = repo.file(dst)
+ src = f.renamed(man[dst])
+ if src:
+ copies.setdefault(src[0], []).extend(copies.get(dst, []))
+ if dst in a:
+ copies[src[0]].append(dst)
+ # we can't copy a file created by the patch itself
+ if dst in copies:
+ del copies[dst]
+ for src, dsts in copies.iteritems():
+ for dst in dsts:
+ repo.dirstate.copy(src, dst)
+ else:
+ for dst in a:
+ repo.dirstate.add(dst)
+ # Drop useless copy information
+ for f in list(repo.dirstate.copies()):
+ repo.dirstate.copy(None, f)
+ for f in r:
+ repo.dirstate.remove(f)
+ # if the patch excludes a modified file, mark that
+ # file with mtime=0 so status can see it.
+ mm = []
+ for i in xrange(len(m)-1, -1, -1):
+ if not matchfn(m[i]):
+ mm.append(m[i])
+ del m[i]
+ for f in m:
+ repo.dirstate.normal(f)
+ for f in mm:
+ repo.dirstate.normallookup(f)
+ for f in forget:
+ repo.dirstate.forget(f)
+
+ if not msg:
+ if not ph.message:
+ message = "[mq]: %s\n" % patchfn
+ else:
+ message = "\n".join(ph.message)
+ else:
+ message = msg
+
+ user = ph.user or changes[1]
+
+ # assumes strip can roll itself back if interrupted
+ repo.dirstate.setparents(*cparents)
+ self.applied.pop()
+ self.applied_dirty = 1
+ self.strip(repo, top, update=False,
+ backup='strip')
+ except:
+ repo.dirstate.invalidate()
+ raise
+
+ try:
+ # might be nice to attempt to roll back strip after this
+ patchf.rename()
+ n = repo.commit(message, user, ph.date, match=match,
+ force=True)
+ self.applied.append(statusentry(hex(n), patchfn))
+ except:
+ ctx = repo[cparents[0]]
+ repo.dirstate.rebuild(ctx.node(), ctx.manifest())
+ self.save_dirty()
+ self.ui.warn(_('refresh interrupted while patch was popped! '
+ '(revert --all, qpush to recover)\n'))
+ raise
+ else:
+ self.printdiff(repo, patchparent, fp=patchf)
+ patchf.rename()
+ added = repo.status()[1]
+ for a in added:
+ f = repo.wjoin(a)
+ try:
+ os.unlink(f)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+ try: os.removedirs(os.path.dirname(f))
+ except: pass
+ # forget the file copies in the dirstate
+ # push should readd the files later on
+ repo.dirstate.forget(a)
+ self.pop(repo, force=True)
+ self.push(repo, force=True)
+ finally:
+ wlock.release()
+ self.removeundo(repo)
+
+ def init(self, repo, create=False):
+ if not create and os.path.isdir(self.path):
+ raise util.Abort(_("patch queue directory already exists"))
+ try:
+ os.mkdir(self.path)
+ except OSError, inst:
+ if inst.errno != errno.EEXIST or not create:
+ raise
+ if create:
+ return self.qrepo(create=True)
+
+ def unapplied(self, repo, patch=None):
+ if patch and patch not in self.series:
+ raise util.Abort(_("patch %s is not in series file") % patch)
+ if not patch:
+ start = self.series_end()
+ else:
+ start = self.series.index(patch) + 1
+ unapplied = []
+ for i in xrange(start, len(self.series)):
+ pushable, reason = self.pushable(i)
+ if pushable:
+ unapplied.append((i, self.series[i]))
+ self.explain_pushable(i)
+ return unapplied
+
+ def qseries(self, repo, missing=None, start=0, length=None, status=None,
+ summary=False):
+ def displayname(pfx, patchname):
+ if summary:
+ ph = patchheader(self.join(patchname))
+ msg = ph.message
+ msg = msg and ': ' + msg[0] or ': '
+ else:
+ msg = ''
+ msg = "%s%s%s" % (pfx, patchname, msg)
+ if self.ui.interactive():
+ msg = util.ellipsis(msg, util.termwidth())
+ self.ui.write(msg + '\n')
+
+ applied = set([p.name for p in self.applied])
+ if length is None:
+ length = len(self.series) - start
+ if not missing:
+ if self.ui.verbose:
+ idxwidth = len(str(start+length - 1))
+ for i in xrange(start, start+length):
+ patch = self.series[i]
+ if patch in applied:
+ stat = 'A'
+ elif self.pushable(i)[0]:
+ stat = 'U'
+ else:
+ stat = 'G'
+ pfx = ''
+ if self.ui.verbose:
+ pfx = '%*d %s ' % (idxwidth, i, stat)
+ elif status and status != stat:
+ continue
+ displayname(pfx, patch)
+ else:
+ msng_list = []
+ for root, dirs, files in os.walk(self.path):
+ d = root[len(self.path) + 1:]
+ for f in files:
+ fl = os.path.join(d, f)
+ if (fl not in self.series and
+ fl not in (self.status_path, self.series_path,
+ self.guards_path)
+ and not fl.startswith('.')):
+ msng_list.append(fl)
+ for x in sorted(msng_list):
+ pfx = self.ui.verbose and ('D ') or ''
+ displayname(pfx, x)
+
+ def issaveline(self, l):
+ if l.name == '.hg.patches.save.line':
+ return True
+
+ def qrepo(self, create=False):
+ if create or os.path.isdir(self.join(".hg")):
+ return hg.repository(self.ui, path=self.path, create=create)
+
+ def restore(self, repo, rev, delete=None, qupdate=None):
+ c = repo.changelog.read(rev)
+ desc = c[4].strip()
+ lines = desc.splitlines()
+ i = 0
+ datastart = None
+ series = []
+ applied = []
+ qpp = None
+ for i, line in enumerate(lines):
+ if line == 'Patch Data:':
+ datastart = i + 1
+ elif line.startswith('Dirstate:'):
+ l = line.rstrip()
+ l = l[10:].split(' ')
+ qpp = [ bin(x) for x in l ]
+ elif datastart != None:
+ l = line.rstrip()
+ se = statusentry(l)
+ file_ = se.name
+ if se.rev:
+ applied.append(se)
+ else:
+ series.append(file_)
+ if datastart is None:
+ self.ui.warn(_("No saved patch data found\n"))
+ return 1
+ self.ui.warn(_("restoring status: %s\n") % lines[0])
+ self.full_series = series
+ self.applied = applied
+ self.parse_series()
+ self.series_dirty = 1
+ self.applied_dirty = 1
+ heads = repo.changelog.heads()
+ if delete:
+ if rev not in heads:
+ self.ui.warn(_("save entry has children, leaving it alone\n"))
+ else:
+ self.ui.warn(_("removing save entry %s\n") % short(rev))
+ pp = repo.dirstate.parents()
+ if rev in pp:
+ update = True
+ else:
+ update = False
+ self.strip(repo, rev, update=update, backup='strip')
+ if qpp:
+ self.ui.warn(_("saved queue repository parents: %s %s\n") %
+ (short(qpp[0]), short(qpp[1])))
+ if qupdate:
+ self.ui.status(_("queue directory updating\n"))
+ r = self.qrepo()
+ if not r:
+ self.ui.warn(_("Unable to load queue repository\n"))
+ return 1
+ hg.clean(r, qpp[0])
+
+ def save(self, repo, msg=None):
+ if len(self.applied) == 0:
+ self.ui.warn(_("save: no patches applied, exiting\n"))
+ return 1
+ if self.issaveline(self.applied[-1]):
+ self.ui.warn(_("status is already saved\n"))
+ return 1
+
+ ar = [ ':' + x for x in self.full_series ]
+ if not msg:
+ msg = _("hg patches saved state")
+ else:
+ msg = "hg patches: " + msg.rstrip('\r\n')
+ r = self.qrepo()
+ if r:
+ pp = r.dirstate.parents()
+ msg += "\nDirstate: %s %s" % (hex(pp[0]), hex(pp[1]))
+ msg += "\n\nPatch Data:\n"
+ text = msg + "\n".join([str(x) for x in self.applied]) + '\n' + (ar and
+ "\n".join(ar) + '\n' or "")
+ n = repo.commit(text, force=True)
+ if not n:
+ self.ui.warn(_("repo commit failed\n"))
+ return 1
+ self.applied.append(statusentry(hex(n),'.hg.patches.save.line'))
+ self.applied_dirty = 1
+ self.removeundo(repo)
+
+ def full_series_end(self):
+ if len(self.applied) > 0:
+ p = self.applied[-1].name
+ end = self.find_series(p)
+ if end is None:
+ return len(self.full_series)
+ return end + 1
+ return 0
+
+ def series_end(self, all_patches=False):
+ """If all_patches is False, return the index of the next pushable patch
+ in the series, or the series length. If all_patches is True, return the
+ index of the first patch past the last applied one.
+ """
+ end = 0
+ def next(start):
+ if all_patches:
+ return start
+ i = start
+ while i < len(self.series):
+ p, reason = self.pushable(i)
+ if p:
+ break
+ self.explain_pushable(i)
+ i += 1
+ return i
+ if len(self.applied) > 0:
+ p = self.applied[-1].name
+ try:
+ end = self.series.index(p)
+ except ValueError:
+ return 0
+ return next(end + 1)
+ return next(end)
+
+ def appliedname(self, index):
+ pname = self.applied[index].name
+ if not self.ui.verbose:
+ p = pname
+ else:
+ p = str(self.series.index(pname)) + " " + pname
+ return p
+
+ def qimport(self, repo, files, patchname=None, rev=None, existing=None,
+ force=None, git=False):
+ def checkseries(patchname):
+ if patchname in self.series:
+ raise util.Abort(_('patch %s is already in the series file')
+ % patchname)
+ def checkfile(patchname):
+ if not force and os.path.exists(self.join(patchname)):
+ raise util.Abort(_('patch "%s" already exists')
+ % patchname)
+
+ if rev:
+ if files:
+ raise util.Abort(_('option "-r" not valid when importing '
+ 'files'))
+ rev = cmdutil.revrange(repo, rev)
+ rev.sort(reverse=True)
+ if (len(files) > 1 or len(rev) > 1) and patchname:
+ raise util.Abort(_('option "-n" not valid when importing multiple '
+ 'patches'))
+ i = 0
+ added = []
+ if rev:
+ # If mq patches are applied, we can only import revisions
+ # that form a linear path to qbase.
+ # Otherwise, they should form a linear path to a head.
+ heads = repo.changelog.heads(repo.changelog.node(rev[-1]))
+ if len(heads) > 1:
+ raise util.Abort(_('revision %d is the root of more than one '
+ 'branch') % rev[-1])
+ if self.applied:
+ base = hex(repo.changelog.node(rev[0]))
+ if base in [n.rev for n in self.applied]:
+ raise util.Abort(_('revision %d is already managed')
+ % rev[0])
+ if heads != [bin(self.applied[-1].rev)]:
+ raise util.Abort(_('revision %d is not the parent of '
+ 'the queue') % rev[0])
+ base = repo.changelog.rev(bin(self.applied[0].rev))
+ lastparent = repo.changelog.parentrevs(base)[0]
+ else:
+ if heads != [repo.changelog.node(rev[0])]:
+ raise util.Abort(_('revision %d has unmanaged children')
+ % rev[0])
+ lastparent = None
+
+ if git:
+ self.diffopts().git = True
+
+ for r in rev:
+ p1, p2 = repo.changelog.parentrevs(r)
+ n = repo.changelog.node(r)
+ if p2 != nullrev:
+ raise util.Abort(_('cannot import merge revision %d') % r)
+ if lastparent and lastparent != r:
+ raise util.Abort(_('revision %d is not the parent of %d')
+ % (r, lastparent))
+ lastparent = p1
+
+ if not patchname:
+ patchname = normname('%d.diff' % r)
+ self.check_reserved_name(patchname)
+ checkseries(patchname)
+ checkfile(patchname)
+ self.full_series.insert(0, patchname)
+
+ patchf = self.opener(patchname, "w")
+ patch.export(repo, [n], fp=patchf, opts=self.diffopts())
+ patchf.close()
+
+ se = statusentry(hex(n), patchname)
+ self.applied.insert(0, se)
+
+ added.append(patchname)
+ patchname = None
+ self.parse_series()
+ self.applied_dirty = 1
+
+ for filename in files:
+ if existing:
+ if filename == '-':
+ raise util.Abort(_('-e is incompatible with import from -'))
+ if not patchname:
+ patchname = normname(filename)
+ self.check_reserved_name(patchname)
+ if not os.path.isfile(self.join(patchname)):
+ raise util.Abort(_("patch %s does not exist") % patchname)
+ else:
+ try:
+ if filename == '-':
+ if not patchname:
+ raise util.Abort(_('need --name to import a patch from -'))
+ text = sys.stdin.read()
+ else:
+ text = url.open(self.ui, filename).read()
+ except (OSError, IOError):
+ raise util.Abort(_("unable to read %s") % filename)
+ if not patchname:
+ patchname = normname(os.path.basename(filename))
+ self.check_reserved_name(patchname)
+ checkfile(patchname)
+ patchf = self.opener(patchname, "w")
+ patchf.write(text)
+ if not force:
+ checkseries(patchname)
+ if patchname not in self.series:
+ index = self.full_series_end() + i
+ self.full_series[index:index] = [patchname]
+ self.parse_series()
+ self.ui.warn(_("adding %s to series file\n") % patchname)
+ i += 1
+ added.append(patchname)
+ patchname = None
+ self.series_dirty = 1
+ qrepo = self.qrepo()
+ if qrepo:
+ qrepo.add(added)
+
+def delete(ui, repo, *patches, **opts):
+ """remove patches from queue
+
+ The patches must not be applied, and at least one patch is required. With
+ -k/--keep, the patch files are preserved in the patch directory.
+
+ To stop managing a patch and move it into permanent history,
+ use the qfinish command."""
+ q = repo.mq
+ q.delete(repo, patches, opts)
+ q.save_dirty()
+ return 0
+
+def applied(ui, repo, patch=None, **opts):
+ """print the patches already applied"""
+ q = repo.mq
+ if patch:
+ if patch not in q.series:
+ raise util.Abort(_("patch %s is not in series file") % patch)
+ end = q.series.index(patch) + 1
+ else:
+ end = q.series_end(True)
+ return q.qseries(repo, length=end, status='A', summary=opts.get('summary'))
+
+def unapplied(ui, repo, patch=None, **opts):
+ """print the patches not yet applied"""
+ q = repo.mq
+ if patch:
+ if patch not in q.series:
+ raise util.Abort(_("patch %s is not in series file") % patch)
+ start = q.series.index(patch) + 1
+ else:
+ start = q.series_end(True)
+ q.qseries(repo, start=start, status='U', summary=opts.get('summary'))
+
+def qimport(ui, repo, *filename, **opts):
+ """import a patch
+
+ The patch is inserted into the series after the last applied
+ patch. If no patches have been applied, qimport prepends the patch
+ to the series.
+
+ The patch will have the same name as its source file unless you
+ give it a new one with -n/--name.
+
+ You can register an existing patch inside the patch directory with
+ the -e/--existing flag.
+
+ With -f/--force, an existing patch of the same name will be
+ overwritten.
+
+ An existing changeset may be placed under mq control with -r/--rev
+ (e.g. qimport --rev tip -n patch will place tip under mq control).
+ With -g/--git, patches imported with --rev will use the git diff
+ format. See the diffs help topic for information on why this is
+ important for preserving rename/copy information and permission
+ changes.
+
+ To import a patch from standard input, pass - as the patch file.
+ When importing from standard input, a patch name must be specified
+ using the --name flag.
+ """
+ q = repo.mq
+ q.qimport(repo, filename, patchname=opts['name'],
+ existing=opts['existing'], force=opts['force'], rev=opts['rev'],
+ git=opts['git'])
+ q.save_dirty()
+
+ if opts.get('push') and not opts.get('rev'):
+ return q.push(repo, None)
+ return 0
+
+def init(ui, repo, **opts):
+ """init a new queue repository
+
+ The queue repository is unversioned by default. If
+ -c/--create-repo is specified, qinit will create a separate nested
+ repository for patches (qinit -c may also be run later to convert
+ an unversioned patch repository into a versioned one). You can use
+ qcommit to commit changes to this queue repository."""
+ q = repo.mq
+ r = q.init(repo, create=opts['create_repo'])
+ q.save_dirty()
+ if r:
+ if not os.path.exists(r.wjoin('.hgignore')):
+ fp = r.wopener('.hgignore', 'w')
+ fp.write('^\\.hg\n')
+ fp.write('^\\.mq\n')
+ fp.write('syntax: glob\n')
+ fp.write('status\n')
+ fp.write('guards\n')
+ fp.close()
+ if not os.path.exists(r.wjoin('series')):
+ r.wopener('series', 'w').close()
+ r.add(['.hgignore', 'series'])
+ commands.add(ui, r)
+ return 0
+
+def clone(ui, source, dest=None, **opts):
+ '''clone main and patch repository at same time
+
+ If source is local, destination will have no patches applied. If
+ source is remote, this command can not check if patches are
+ applied in source, so cannot guarantee that patches are not
+ applied in destination. If you clone remote repository, be sure
+ before that it has no patches applied.
+
+ Source patch repository is looked for in <src>/.hg/patches by
+ default. Use -p <url> to change.
+
+ The patch directory must be a nested Mercurial repository, as
+ would be created by qinit -c.
+ '''
+ def patchdir(repo):
+ url = repo.url()
+ if url.endswith('/'):
+ url = url[:-1]
+ return url + '/.hg/patches'
+ if dest is None:
+ dest = hg.defaultdest(source)
+ sr = hg.repository(cmdutil.remoteui(ui, opts), ui.expandpath(source))
+ if opts['patches']:
+ patchespath = ui.expandpath(opts['patches'])
+ else:
+ patchespath = patchdir(sr)
+ try:
+ hg.repository(ui, patchespath)
+ except error.RepoError:
+ raise util.Abort(_('versioned patch repository not found'
+ ' (see qinit -c)'))
+ qbase, destrev = None, None
+ if sr.local():
+ if sr.mq.applied:
+ qbase = bin(sr.mq.applied[0].rev)
+ if not hg.islocal(dest):
+ heads = set(sr.heads())
+ destrev = list(heads.difference(sr.heads(qbase)))
+ destrev.append(sr.changelog.parents(qbase)[0])
+ elif sr.capable('lookup'):
+ try:
+ qbase = sr.lookup('qbase')
+ except error.RepoError:
+ pass
+ ui.note(_('cloning main repository\n'))
+ sr, dr = hg.clone(ui, sr.url(), dest,
+ pull=opts['pull'],
+ rev=destrev,
+ update=False,
+ stream=opts['uncompressed'])
+ ui.note(_('cloning patch repository\n'))
+ hg.clone(ui, opts['patches'] or patchdir(sr), patchdir(dr),
+ pull=opts['pull'], update=not opts['noupdate'],
+ stream=opts['uncompressed'])
+ if dr.local():
+ if qbase:
+ ui.note(_('stripping applied patches from destination '
+ 'repository\n'))
+ dr.mq.strip(dr, qbase, update=False, backup=None)
+ if not opts['noupdate']:
+ ui.note(_('updating destination repository\n'))
+ hg.update(dr, dr.changelog.tip())
+
+def commit(ui, repo, *pats, **opts):
+ """commit changes in the queue repository"""
+ q = repo.mq
+ r = q.qrepo()
+ if not r: raise util.Abort('no queue repository')
+ commands.commit(r.ui, r, *pats, **opts)
+
+def series(ui, repo, **opts):
+ """print the entire series file"""
+ repo.mq.qseries(repo, missing=opts['missing'], summary=opts['summary'])
+ return 0
+
+def top(ui, repo, **opts):
+ """print the name of the current patch"""
+ q = repo.mq
+ t = q.applied and q.series_end(True) or 0
+ if t:
+ return q.qseries(repo, start=t-1, length=1, status='A',
+ summary=opts.get('summary'))
+ else:
+ ui.write(_("no patches applied\n"))
+ return 1
+
+def next(ui, repo, **opts):
+ """print the name of the next patch"""
+ q = repo.mq
+ end = q.series_end()
+ if end == len(q.series):
+ ui.write(_("all patches applied\n"))
+ return 1
+ return q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
+
+def prev(ui, repo, **opts):
+ """print the name of the previous patch"""
+ q = repo.mq
+ l = len(q.applied)
+ if l == 1:
+ ui.write(_("only one patch applied\n"))
+ return 1
+ if not l:
+ ui.write(_("no patches applied\n"))
+ return 1
+ return q.qseries(repo, start=l-2, length=1, status='A',
+ summary=opts.get('summary'))
+
+def setupheaderopts(ui, opts):
+ def do(opt, val):
+ if not opts[opt] and opts['current' + opt]:
+ opts[opt] = val
+ do('user', ui.username())
+ do('date', "%d %d" % util.makedate())
+
+def new(ui, repo, patch, *args, **opts):
+ """create a new patch
+
+ qnew creates a new patch on top of the currently-applied patch (if
+ any). It will refuse to run if there are any outstanding changes
+ unless -f/--force is specified, in which case the patch will be
+ initialized with them. You may also use -I/--include,
+ -X/--exclude, and/or a list of files after the patch name to add
+ only changes to matching files to the new patch, leaving the rest
+ as uncommitted modifications.
+
+ -u/--user and -d/--date can be used to set the (given) user and
+ date, respectively. -U/--currentuser and -D/--currentdate set user
+ to current user and date to current date.
+
+ -e/--edit, -m/--message or -l/--logfile set the patch header as
+ well as the commit message. If none is specified, the header is
+ empty and the commit message is '[mq]: PATCH'.
+
+ Use the -g/--git option to keep the patch in the git extended diff
+ format. Read the diffs help topic for more information on why this
+ is important for preserving permission changes and copy/rename
+ information.
+ """
+ msg = cmdutil.logmessage(opts)
+ def getmsg(): return ui.edit(msg, ui.username())
+ q = repo.mq
+ opts['msg'] = msg
+ if opts.get('edit'):
+ opts['msg'] = getmsg
+ else:
+ opts['msg'] = msg
+ setupheaderopts(ui, opts)
+ q.new(repo, patch, *args, **opts)
+ q.save_dirty()
+ return 0
+
+def refresh(ui, repo, *pats, **opts):
+ """update the current patch
+
+ If any file patterns are provided, the refreshed patch will
+ contain only the modifications that match those patterns; the
+ remaining modifications will remain in the working directory.
+
+ If -s/--short is specified, files currently included in the patch
+ will be refreshed just like matched files and remain in the patch.
+
+ hg add/remove/copy/rename work as usual, though you might want to
+ use git-style patches (-g/--git or [diff] git=1) to track copies
+ and renames. See the diffs help topic for more information on the
+ git diff format.
+ """
+ q = repo.mq
+ message = cmdutil.logmessage(opts)
+ if opts['edit']:
+ if not q.applied:
+ ui.write(_("no patches applied\n"))
+ return 1
+ if message:
+ raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
+ patch = q.applied[-1].name
+ ph = patchheader(q.join(patch))
+ message = ui.edit('\n'.join(ph.message), ph.user or ui.username())
+ setupheaderopts(ui, opts)
+ ret = q.refresh(repo, pats, msg=message, **opts)
+ q.save_dirty()
+ return ret
+
+def diff(ui, repo, *pats, **opts):
+ """diff of the current patch and subsequent modifications
+
+ Shows a diff which includes the current patch as well as any
+ changes which have been made in the working directory since the
+ last refresh (thus showing what the current patch would become
+ after a qrefresh).
+
+ Use 'hg diff' if you only want to see the changes made since the
+ last qrefresh, or 'hg export qtip' if you want to see changes made
+ by the current patch without including changes made since the
+ qrefresh.
+ """
+ repo.mq.diff(repo, pats, opts)
+ return 0
+
+def fold(ui, repo, *files, **opts):
+ """fold the named patches into the current patch
+
+ Patches must not yet be applied. Each patch will be successively
+ applied to the current patch in the order given. If all the
+ patches apply successfully, the current patch will be refreshed
+ with the new cumulative patch, and the folded patches will be
+ deleted. With -k/--keep, the folded patch files will not be
+ removed afterwards.
+
+ The header for each folded patch will be concatenated with the
+ current patch header, separated by a line of '* * *'."""
+
+ q = repo.mq
+
+ if not files:
+ raise util.Abort(_('qfold requires at least one patch name'))
+ if not q.check_toppatch(repo):
+ raise util.Abort(_('No patches applied'))
+ q.check_localchanges(repo)
+
+ message = cmdutil.logmessage(opts)
+ if opts['edit']:
+ if message:
+ raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
+
+ parent = q.lookup('qtip')
+ patches = []
+ messages = []
+ for f in files:
+ p = q.lookup(f)
+ if p in patches or p == parent:
+ ui.warn(_('Skipping already folded patch %s') % p)
+ if q.isapplied(p):
+ raise util.Abort(_('qfold cannot fold already applied patch %s') % p)
+ patches.append(p)
+
+ for p in patches:
+ if not message:
+ ph = patchheader(q.join(p))
+ if ph.message:
+ messages.append(ph.message)
+ pf = q.join(p)
+ (patchsuccess, files, fuzz) = q.patch(repo, pf)
+ if not patchsuccess:
+ raise util.Abort(_('Error folding patch %s') % p)
+ patch.updatedir(ui, repo, files)
+
+ if not message:
+ ph = patchheader(q.join(parent))
+ message, user = ph.message, ph.user
+ for msg in messages:
+ message.append('* * *')
+ message.extend(msg)
+ message = '\n'.join(message)
+
+ if opts['edit']:
+ message = ui.edit(message, user or ui.username())
+
+ q.refresh(repo, msg=message)
+ q.delete(repo, patches, opts)
+ q.save_dirty()
+
+def goto(ui, repo, patch, **opts):
+ '''push or pop patches until named patch is at top of stack'''
+ q = repo.mq
+ patch = q.lookup(patch)
+ if q.isapplied(patch):
+ ret = q.pop(repo, patch, force=opts['force'])
+ else:
+ ret = q.push(repo, patch, force=opts['force'])
+ q.save_dirty()
+ return ret
+
+def guard(ui, repo, *args, **opts):
+ '''set or print guards for a patch
+
+ Guards control whether a patch can be pushed. A patch with no
+ guards is always pushed. A patch with a positive guard ("+foo") is
+ pushed only if the qselect command has activated it. A patch with
+ a negative guard ("-foo") is never pushed if the qselect command
+ has activated it.
+
+ With no arguments, print the currently active guards.
+ With arguments, set guards for the named patch.
+ NOTE: Specifying negative guards now requires '--'.
+
+ To set guards on another patch:
+ hg qguard -- other.patch +2.6.17 -stable
+ '''
+ def status(idx):
+ guards = q.series_guards[idx] or ['unguarded']
+ ui.write('%s: %s\n' % (q.series[idx], ' '.join(guards)))
+ q = repo.mq
+ patch = None
+ args = list(args)
+ if opts['list']:
+ if args or opts['none']:
+ raise util.Abort(_('cannot mix -l/--list with options or arguments'))
+ for i in xrange(len(q.series)):
+ status(i)
+ return
+ if not args or args[0][0:1] in '-+':
+ if not q.applied:
+ raise util.Abort(_('no patches applied'))
+ patch = q.applied[-1].name
+ if patch is None and args[0][0:1] not in '-+':
+ patch = args.pop(0)
+ if patch is None:
+ raise util.Abort(_('no patch to work with'))
+ if args or opts['none']:
+ idx = q.find_series(patch)
+ if idx is None:
+ raise util.Abort(_('no patch named %s') % patch)
+ q.set_guards(idx, args)
+ q.save_dirty()
+ else:
+ status(q.series.index(q.lookup(patch)))
+
+def header(ui, repo, patch=None):
+ """print the header of the topmost or specified patch"""
+ q = repo.mq
+
+ if patch:
+ patch = q.lookup(patch)
+ else:
+ if not q.applied:
+ ui.write('no patches applied\n')
+ return 1
+ patch = q.lookup('qtip')
+ ph = patchheader(repo.mq.join(patch))
+
+ ui.write('\n'.join(ph.message) + '\n')
+
+def lastsavename(path):
+ (directory, base) = os.path.split(path)
+ names = os.listdir(directory)
+ namere = re.compile("%s.([0-9]+)" % base)
+ maxindex = None
+ maxname = None
+ for f in names:
+ m = namere.match(f)
+ if m:
+ index = int(m.group(1))
+ if maxindex is None or index > maxindex:
+ maxindex = index
+ maxname = f
+ if maxname:
+ return (os.path.join(directory, maxname), maxindex)
+ return (None, None)
+
+def savename(path):
+ (last, index) = lastsavename(path)
+ if last is None:
+ index = 0
+ newpath = path + ".%d" % (index + 1)
+ return newpath
+
+def push(ui, repo, patch=None, **opts):
+ """push the next patch onto the stack
+
+ When -f/--force is applied, all local changes in patched files
+ will be lost.
+ """
+ q = repo.mq
+ mergeq = None
+
+ if opts['merge']:
+ if opts['name']:
+ newpath = repo.join(opts['name'])
+ else:
+ newpath, i = lastsavename(q.path)
+ if not newpath:
+ ui.warn(_("no saved queues found, please use -n\n"))
+ return 1
+ mergeq = queue(ui, repo.join(""), newpath)
+ ui.warn(_("merging with queue at: %s\n") % mergeq.path)
+ ret = q.push(repo, patch, force=opts['force'], list=opts['list'],
+ mergeq=mergeq, all=opts.get('all'))
+ return ret
+
+def pop(ui, repo, patch=None, **opts):
+ """pop the current patch off the stack
+
+ By default, pops off the top of the patch stack. If given a patch
+ name, keeps popping off patches until the named patch is at the
+ top of the stack.
+ """
+ localupdate = True
+ if opts['name']:
+ q = queue(ui, repo.join(""), repo.join(opts['name']))
+ ui.warn(_('using patch queue: %s\n') % q.path)
+ localupdate = False
+ else:
+ q = repo.mq
+ ret = q.pop(repo, patch, force=opts['force'], update=localupdate,
+ all=opts['all'])
+ q.save_dirty()
+ return ret
+
+def rename(ui, repo, patch, name=None, **opts):
+ """rename a patch
+
+ With one argument, renames the current patch to PATCH1.
+ With two arguments, renames PATCH1 to PATCH2."""
+
+ q = repo.mq
+
+ if not name:
+ name = patch
+ patch = None
+
+ if patch:
+ patch = q.lookup(patch)
+ else:
+ if not q.applied:
+ ui.write(_('no patches applied\n'))
+ return
+ patch = q.lookup('qtip')
+ absdest = q.join(name)
+ if os.path.isdir(absdest):
+ name = normname(os.path.join(name, os.path.basename(patch)))
+ absdest = q.join(name)
+ if os.path.exists(absdest):
+ raise util.Abort(_('%s already exists') % absdest)
+
+ if name in q.series:
+ raise util.Abort(_('A patch named %s already exists in the series file') % name)
+
+ if ui.verbose:
+ ui.write('renaming %s to %s\n' % (patch, name))
+ i = q.find_series(patch)
+ guards = q.guard_re.findall(q.full_series[i])
+ q.full_series[i] = name + ''.join([' #' + g for g in guards])
+ q.parse_series()
+ q.series_dirty = 1
+
+ info = q.isapplied(patch)
+ if info:
+ q.applied[info[0]] = statusentry(info[1], name)
+ q.applied_dirty = 1
+
+ util.rename(q.join(patch), absdest)
+ r = q.qrepo()
+ if r:
+ wlock = r.wlock()
+ try:
+ if r.dirstate[patch] == 'a':
+ r.dirstate.forget(patch)
+ r.dirstate.add(name)
+ else:
+ if r.dirstate[name] == 'r':
+ r.undelete([name])
+ r.copy(patch, name)
+ r.remove([patch], False)
+ finally:
+ wlock.release()
+
+ q.save_dirty()
+
+def restore(ui, repo, rev, **opts):
+ """restore the queue state saved by a revision"""
+ rev = repo.lookup(rev)
+ q = repo.mq
+ q.restore(repo, rev, delete=opts['delete'],
+ qupdate=opts['update'])
+ q.save_dirty()
+ return 0
+
+def save(ui, repo, **opts):
+ """save current queue state"""
+ q = repo.mq
+ message = cmdutil.logmessage(opts)
+ ret = q.save(repo, msg=message)
+ if ret:
+ return ret
+ q.save_dirty()
+ if opts['copy']:
+ path = q.path
+ if opts['name']:
+ newpath = os.path.join(q.basepath, opts['name'])
+ if os.path.exists(newpath):
+ if not os.path.isdir(newpath):
+ raise util.Abort(_('destination %s exists and is not '
+ 'a directory') % newpath)
+ if not opts['force']:
+ raise util.Abort(_('destination %s exists, '
+ 'use -f to force') % newpath)
+ else:
+ newpath = savename(path)
+ ui.warn(_("copy %s to %s\n") % (path, newpath))
+ util.copyfiles(path, newpath)
+ if opts['empty']:
+ try:
+ os.unlink(q.join(q.status_path))
+ except:
+ pass
+ return 0
+
+def strip(ui, repo, rev, **opts):
+ """strip a revision and all its descendants from the repository
+
+ If one of the working directory's parent revisions is stripped, the
+ working directory will be updated to the parent of the stripped
+ revision.
+ """
+ backup = 'all'
+ if opts['backup']:
+ backup = 'strip'
+ elif opts['nobackup']:
+ backup = 'none'
+
+ rev = repo.lookup(rev)
+ p = repo.dirstate.parents()
+ cl = repo.changelog
+ update = True
+ if p[0] == nullid:
+ update = False
+ elif p[1] == nullid and rev != cl.ancestor(p[0], rev):
+ update = False
+ elif rev not in (cl.ancestor(p[0], rev), cl.ancestor(p[1], rev)):
+ update = False
+
+ repo.mq.strip(repo, rev, backup=backup, update=update, force=opts['force'])
+ return 0
+
+def select(ui, repo, *args, **opts):
+ '''set or print guarded patches to push
+
+ Use the qguard command to set or print guards on patch, then use
+ qselect to tell mq which guards to use. A patch will be pushed if
+ it has no guards or any positive guards match the currently
+ selected guard, but will not be pushed if any negative guards
+ match the current guard. For example:
+
+ qguard foo.patch -stable (negative guard)
+ qguard bar.patch +stable (positive guard)
+ qselect stable
+
+ This activates the "stable" guard. mq will skip foo.patch (because
+ it has a negative match) but push bar.patch (because it has a
+ positive match).
+
+ With no arguments, prints the currently active guards.
+ With one argument, sets the active guard.
+
+ Use -n/--none to deactivate guards (no other arguments needed).
+ When no guards are active, patches with positive guards are
+ skipped and patches with negative guards are pushed.
+
+ qselect can change the guards on applied patches. It does not pop
+ guarded patches by default. Use --pop to pop back to the last
+ applied patch that is not guarded. Use --reapply (which implies
+ --pop) to push back to the current patch afterwards, but skip
+ guarded patches.
+
+ Use -s/--series to print a list of all guards in the series file
+ (no other arguments needed). Use -v for more information.'''
+
+ q = repo.mq
+ guards = q.active()
+ if args or opts['none']:
+ old_unapplied = q.unapplied(repo)
+ old_guarded = [i for i in xrange(len(q.applied)) if
+ not q.pushable(i)[0]]
+ q.set_active(args)
+ q.save_dirty()
+ if not args:
+ ui.status(_('guards deactivated\n'))
+ if not opts['pop'] and not opts['reapply']:
+ unapplied = q.unapplied(repo)
+ guarded = [i for i in xrange(len(q.applied))
+ if not q.pushable(i)[0]]
+ if len(unapplied) != len(old_unapplied):
+ ui.status(_('number of unguarded, unapplied patches has '
+ 'changed from %d to %d\n') %
+ (len(old_unapplied), len(unapplied)))
+ if len(guarded) != len(old_guarded):
+ ui.status(_('number of guarded, applied patches has changed '
+ 'from %d to %d\n') %
+ (len(old_guarded), len(guarded)))
+ elif opts['series']:
+ guards = {}
+ noguards = 0
+ for gs in q.series_guards:
+ if not gs:
+ noguards += 1
+ for g in gs:
+ guards.setdefault(g, 0)
+ guards[g] += 1
+ if ui.verbose:
+ guards['NONE'] = noguards
+ guards = guards.items()
+ guards.sort(key=lambda x: x[0][1:])
+ if guards:
+ ui.note(_('guards in series file:\n'))
+ for guard, count in guards:
+ ui.note('%2d ' % count)
+ ui.write(guard, '\n')
+ else:
+ ui.note(_('no guards in series file\n'))
+ else:
+ if guards:
+ ui.note(_('active guards:\n'))
+ for g in guards:
+ ui.write(g, '\n')
+ else:
+ ui.write(_('no active guards\n'))
+ reapply = opts['reapply'] and q.applied and q.appliedname(-1)
+ popped = False
+ if opts['pop'] or opts['reapply']:
+ for i in xrange(len(q.applied)):
+ pushable, reason = q.pushable(i)
+ if not pushable:
+ ui.status(_('popping guarded patches\n'))
+ popped = True
+ if i == 0:
+ q.pop(repo, all=True)
+ else:
+ q.pop(repo, i-1)
+ break
+ if popped:
+ try:
+ if reapply:
+ ui.status(_('reapplying unguarded patches\n'))
+ q.push(repo, reapply)
+ finally:
+ q.save_dirty()
+
+def finish(ui, repo, *revrange, **opts):
+ """move applied patches into repository history
+
+ Finishes the specified revisions (corresponding to applied
+ patches) by moving them out of mq control into regular repository
+ history.
+
+ Accepts a revision range or the -a/--applied option. If --applied
+ is specified, all applied mq revisions are removed from mq
+ control. Otherwise, the given revisions must be at the base of the
+ stack of applied patches.
+
+ This can be especially useful if your changes have been applied to
+ an upstream repository, or if you are about to push your changes
+ to upstream.
+ """
+ if not opts['applied'] and not revrange:
+ raise util.Abort(_('no revisions specified'))
+ elif opts['applied']:
+ revrange = ('qbase:qtip',) + revrange
+
+ q = repo.mq
+ if not q.applied:
+ ui.status(_('no patches applied\n'))
+ return 0
+
+ revs = cmdutil.revrange(repo, revrange)
+ q.finish(repo, revs)
+ q.save_dirty()
+ return 0
+
+def reposetup(ui, repo):
+ class mqrepo(repo.__class__):
+ @util.propertycache
+ def mq(self):
+ return queue(self.ui, self.join(""))
+
+ def abort_if_wdir_patched(self, errmsg, force=False):
+ if self.mq.applied and not force:
+ parent = hex(self.dirstate.parents()[0])
+ if parent in [s.rev for s in self.mq.applied]:
+ raise util.Abort(errmsg)
+
+ def commit(self, text="", user=None, date=None, match=None,
+ force=False, editor=False, extra={}):
+ self.abort_if_wdir_patched(
+ _('cannot commit over an applied mq patch'),
+ force)
+
+ return super(mqrepo, self).commit(text, user, date, match, force,
+ editor, extra)
+
+ def push(self, remote, force=False, revs=None):
+ if self.mq.applied and not force and not revs:
+ raise util.Abort(_('source has mq patches applied'))
+ return super(mqrepo, self).push(remote, force, revs)
+
+ def _findtags(self):
+ '''augment tags from base class with patch tags'''
+ result = super(mqrepo, self)._findtags()
+
+ q = self.mq
+ if not q.applied:
+ return result
+
+ mqtags = [(bin(patch.rev), patch.name) for patch in q.applied]
+
+ if mqtags[-1][0] not in self.changelog.nodemap:
+ self.ui.warn(_('mq status file refers to unknown node %s\n')
+ % short(mqtags[-1][0]))
+ return result
+
+ mqtags.append((mqtags[-1][0], 'qtip'))
+ mqtags.append((mqtags[0][0], 'qbase'))
+ mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent'))
+ tags = result[0]
+ for patch in mqtags:
+ if patch[1] in tags:
+ self.ui.warn(_('Tag %s overrides mq patch of the same name\n')
+ % patch[1])
+ else:
+ tags[patch[1]] = patch[0]
+
+ return result
+
+ def _branchtags(self, partial, lrev):
+ q = self.mq
+ if not q.applied:
+ return super(mqrepo, self)._branchtags(partial, lrev)
+
+ cl = self.changelog
+ qbasenode = bin(q.applied[0].rev)
+ if qbasenode not in cl.nodemap:
+ self.ui.warn(_('mq status file refers to unknown node %s\n')
+ % short(qbasenode))
+ return super(mqrepo, self)._branchtags(partial, lrev)
+
+ qbase = cl.rev(qbasenode)
+ start = lrev + 1
+ if start < qbase:
+ # update the cache (excluding the patches) and save it
+ self._updatebranchcache(partial, lrev+1, qbase)
+ self._writebranchcache(partial, cl.node(qbase-1), qbase-1)
+ start = qbase
+ # if start = qbase, the cache is as updated as it should be.
+ # if start > qbase, the cache includes (part of) the patches.
+ # we might as well use it, but we won't save it.
+
+ # update the cache up to the tip
+ self._updatebranchcache(partial, start, len(cl))
+
+ return partial
+
+ if repo.local():
+ repo.__class__ = mqrepo
+
+def mqimport(orig, ui, repo, *args, **kwargs):
+ if hasattr(repo, 'abort_if_wdir_patched'):
+ repo.abort_if_wdir_patched(_('cannot import over an applied patch'),
+ kwargs.get('force'))
+ return orig(ui, repo, *args, **kwargs)
+
+def uisetup(ui):
+ extensions.wrapcommand(commands.table, 'import', mqimport)
+
+seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
+
+cmdtable = {
+ "qapplied": (applied, [] + seriesopts, _('hg qapplied [-s] [PATCH]')),
+ "qclone":
+ (clone,
+ [('', 'pull', None, _('use pull protocol to copy metadata')),
+ ('U', 'noupdate', None, _('do not update the new working directories')),
+ ('', 'uncompressed', None,
+ _('use uncompressed transfer (fast over LAN)')),
+ ('p', 'patches', '', _('location of source patch repository')),
+ ] + commands.remoteopts,
+ _('hg qclone [OPTION]... SOURCE [DEST]')),
+ "qcommit|qci":
+ (commit,
+ commands.table["^commit|ci"][1],
+ _('hg qcommit [OPTION]... [FILE]...')),
+ "^qdiff":
+ (diff,
+ commands.diffopts + commands.diffopts2 + commands.walkopts,
+ _('hg qdiff [OPTION]... [FILE]...')),
+ "qdelete|qremove|qrm":
+ (delete,
+ [('k', 'keep', None, _('keep patch file')),
+ ('r', 'rev', [], _('stop managing a revision (DEPRECATED)'))],
+ _('hg qdelete [-k] [-r REV]... [PATCH]...')),
+ 'qfold':
+ (fold,
+ [('e', 'edit', None, _('edit patch header')),
+ ('k', 'keep', None, _('keep folded patch files')),
+ ] + commands.commitopts,
+ _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...')),
+ 'qgoto':
+ (goto,
+ [('f', 'force', None, _('overwrite any local changes'))],
+ _('hg qgoto [OPTION]... PATCH')),
+ 'qguard':
+ (guard,
+ [('l', 'list', None, _('list all patches and guards')),
+ ('n', 'none', None, _('drop all guards'))],
+ _('hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]...')),
+ 'qheader': (header, [], _('hg qheader [PATCH]')),
+ "^qimport":
+ (qimport,
+ [('e', 'existing', None, _('import file in patch directory')),
+ ('n', 'name', '', _('name of patch file')),
+ ('f', 'force', None, _('overwrite existing files')),
+ ('r', 'rev', [], _('place existing revisions under mq control')),
+ ('g', 'git', None, _('use git extended diff format')),
+ ('P', 'push', None, _('qpush after importing'))],
+ _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE...')),
+ "^qinit":
+ (init,
+ [('c', 'create-repo', None, _('create queue repository'))],
+ _('hg qinit [-c]')),
+ "qnew":
+ (new,
+ [('e', 'edit', None, _('edit commit message')),
+ ('f', 'force', None, _('import uncommitted changes into patch')),
+ ('g', 'git', None, _('use git extended diff format')),
+ ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
+ ('u', 'user', '', _('add "From: <given user>" to patch')),
+ ('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
+ ('d', 'date', '', _('add "Date: <given date>" to patch'))
+ ] + commands.walkopts + commands.commitopts,
+ _('hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]...')),
+ "qnext": (next, [] + seriesopts, _('hg qnext [-s]')),
+ "qprev": (prev, [] + seriesopts, _('hg qprev [-s]')),
+ "^qpop":
+ (pop,
+ [('a', 'all', None, _('pop all patches')),
+ ('n', 'name', '', _('queue name to pop')),
+ ('f', 'force', None, _('forget any local changes'))],
+ _('hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]')),
+ "^qpush":
+ (push,
+ [('f', 'force', None, _('apply if the patch has rejects')),
+ ('l', 'list', None, _('list patch name in commit text')),
+ ('a', 'all', None, _('apply all patches')),
+ ('m', 'merge', None, _('merge from another queue')),
+ ('n', 'name', '', _('merge queue name'))],
+ _('hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]')),
+ "^qrefresh":
+ (refresh,
+ [('e', 'edit', None, _('edit commit message')),
+ ('g', 'git', None, _('use git extended diff format')),
+ ('s', 'short', None, _('refresh only files already in the patch and specified files')),
+ ('U', 'currentuser', None, _('add/update author field in patch with current user')),
+ ('u', 'user', '', _('add/update author field in patch with given user')),
+ ('D', 'currentdate', None, _('add/update date field in patch with current date')),
+ ('d', 'date', '', _('add/update date field in patch with given date'))
+ ] + commands.walkopts + commands.commitopts,
+ _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...')),
+ 'qrename|qmv':
+ (rename, [], _('hg qrename PATCH1 [PATCH2]')),
+ "qrestore":
+ (restore,
+ [('d', 'delete', None, _('delete save entry')),
+ ('u', 'update', None, _('update queue working directory'))],
+ _('hg qrestore [-d] [-u] REV')),
+ "qsave":
+ (save,
+ [('c', 'copy', None, _('copy patch directory')),
+ ('n', 'name', '', _('copy directory name')),
+ ('e', 'empty', None, _('clear queue status file')),
+ ('f', 'force', None, _('force copy'))] + commands.commitopts,
+ _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]')),
+ "qselect":
+ (select,
+ [('n', 'none', None, _('disable all guards')),
+ ('s', 'series', None, _('list all guards in series file')),
+ ('', 'pop', None, _('pop to before first guarded applied patch')),
+ ('', 'reapply', None, _('pop, then reapply patches'))],
+ _('hg qselect [OPTION]... [GUARD]...')),
+ "qseries":
+ (series,
+ [('m', 'missing', None, _('print patches not in series')),
+ ] + seriesopts,
+ _('hg qseries [-ms]')),
+ "^strip":
+ (strip,
+ [('f', 'force', None, _('force removal with local changes')),
+ ('b', 'backup', None, _('bundle unrelated changesets')),
+ ('n', 'nobackup', None, _('no backups'))],
+ _('hg strip [-f] [-b] [-n] REV')),
+ "qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
+ "qunapplied": (unapplied, [] + seriesopts, _('hg qunapplied [-s] [PATCH]')),
+ "qfinish":
+ (finish,
+ [('a', 'applied', None, _('finish all applied changesets'))],
+ _('hg qfinish [-a] [REV]...')),
+}
diff --git a/sys/src/cmd/hg/hgext/notify.py b/sys/src/cmd/hg/hgext/notify.py
new file mode 100644
index 000000000..4cd27dc05
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/notify.py
@@ -0,0 +1,298 @@
+# notify.py - email notifications for mercurial
+#
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''hooks for sending email notifications at commit/push time
+
+Subscriptions can be managed through a hgrc file. Default mode is to
+print messages to stdout, for testing and configuring.
+
+To use, configure the notify extension and enable it in hgrc like
+this::
+
+ [extensions]
+ hgext.notify =
+
+ [hooks]
+ # one email for each incoming changeset
+ incoming.notify = python:hgext.notify.hook
+ # batch emails when many changesets incoming at one time
+ changegroup.notify = python:hgext.notify.hook
+
+ [notify]
+ # config items go here
+
+Required configuration items::
+
+ config = /path/to/file # file containing subscriptions
+
+Optional configuration items::
+
+ test = True # print messages to stdout for testing
+ strip = 3 # number of slashes to strip for url paths
+ domain = example.com # domain to use if committer missing domain
+ style = ... # style file to use when formatting email
+ template = ... # template to use when formatting email
+ incoming = ... # template to use when run as incoming hook
+ changegroup = ... # template when run as changegroup hook
+ maxdiff = 300 # max lines of diffs to include (0=none, -1=all)
+ maxsubject = 67 # truncate subject line longer than this
+ diffstat = True # add a diffstat before the diff content
+ sources = serve # notify if source of incoming changes in this list
+ # (serve == ssh or http, push, pull, bundle)
+ [email]
+ from = user@host.com # email address to send as if none given
+ [web]
+ baseurl = http://hgserver/... # root of hg web site for browsing commits
+
+The notify config file has same format as a regular hgrc file. It has
+two sections so you can express subscriptions in whatever way is
+handier for you.
+
+::
+
+ [usersubs]
+ # key is subscriber email, value is ","-separated list of glob patterns
+ user@host = pattern
+
+ [reposubs]
+ # key is glob pattern, value is ","-separated list of subscriber emails
+ pattern = user@host
+
+Glob patterns are matched against path to repository root.
+
+If you like, you can put notify config file in repository that users
+can push changes to, they can manage their own subscriptions.
+'''
+
+from mercurial.i18n import _
+from mercurial import patch, cmdutil, templater, util, mail
+import email.Parser, email.Errors, fnmatch, socket, time
+
+# template for single changeset can include email headers.
+single_template = '''
+Subject: changeset in {webroot}: {desc|firstline|strip}
+From: {author}
+
+changeset {node|short} in {root}
+details: {baseurl}{webroot}?cmd=changeset;node={node|short}
+description:
+\t{desc|tabindent|strip}
+'''.lstrip()
+
+# template for multiple changesets should not contain email headers,
+# because only first set of headers will be used and result will look
+# strange.
+multiple_template = '''
+changeset {node|short} in {root}
+details: {baseurl}{webroot}?cmd=changeset;node={node|short}
+summary: {desc|firstline}
+'''
+
+deftemplates = {
+ 'changegroup': multiple_template,
+}
+
+class notifier(object):
+ '''email notification class.'''
+
+ def __init__(self, ui, repo, hooktype):
+ self.ui = ui
+ cfg = self.ui.config('notify', 'config')
+ if cfg:
+ self.ui.readconfig(cfg, sections=['usersubs', 'reposubs'])
+ self.repo = repo
+ self.stripcount = int(self.ui.config('notify', 'strip', 0))
+ self.root = self.strip(self.repo.root)
+ self.domain = self.ui.config('notify', 'domain')
+ self.test = self.ui.configbool('notify', 'test', True)
+ self.charsets = mail._charsets(self.ui)
+ self.subs = self.subscribers()
+
+ mapfile = self.ui.config('notify', 'style')
+ template = (self.ui.config('notify', hooktype) or
+ self.ui.config('notify', 'template'))
+ self.t = cmdutil.changeset_templater(self.ui, self.repo,
+ False, None, mapfile, False)
+ if not mapfile and not template:
+ template = deftemplates.get(hooktype) or single_template
+ if template:
+ template = templater.parsestring(template, quoted=False)
+ self.t.use_template(template)
+
+ def strip(self, path):
+ '''strip leading slashes from local path, turn into web-safe path.'''
+
+ path = util.pconvert(path)
+ count = self.stripcount
+ while count > 0:
+ c = path.find('/')
+ if c == -1:
+ break
+ path = path[c+1:]
+ count -= 1
+ return path
+
+ def fixmail(self, addr):
+ '''try to clean up email addresses.'''
+
+ addr = util.email(addr.strip())
+ if self.domain:
+ a = addr.find('@localhost')
+ if a != -1:
+ addr = addr[:a]
+ if '@' not in addr:
+ return addr + '@' + self.domain
+ return addr
+
+ def subscribers(self):
+ '''return list of email addresses of subscribers to this repo.'''
+ subs = set()
+ for user, pats in self.ui.configitems('usersubs'):
+ for pat in pats.split(','):
+ if fnmatch.fnmatch(self.repo.root, pat.strip()):
+ subs.add(self.fixmail(user))
+ for pat, users in self.ui.configitems('reposubs'):
+ if fnmatch.fnmatch(self.repo.root, pat):
+ for user in users.split(','):
+ subs.add(self.fixmail(user))
+ return [mail.addressencode(self.ui, s, self.charsets, self.test)
+ for s in sorted(subs)]
+
+ def url(self, path=None):
+ return self.ui.config('web', 'baseurl') + (path or self.root)
+
+ def node(self, ctx):
+ '''format one changeset.'''
+ self.t.show(ctx, changes=ctx.changeset(),
+ baseurl=self.ui.config('web', 'baseurl'),
+ root=self.repo.root, webroot=self.root)
+
+ def skipsource(self, source):
+ '''true if incoming changes from this source should be skipped.'''
+ ok_sources = self.ui.config('notify', 'sources', 'serve').split()
+ return source not in ok_sources
+
+ def send(self, ctx, count, data):
+ '''send message.'''
+
+ p = email.Parser.Parser()
+ try:
+ msg = p.parsestr(data)
+ except email.Errors.MessageParseError, inst:
+ raise util.Abort(inst)
+
+ # store sender and subject
+ sender, subject = msg['From'], msg['Subject']
+ del msg['From'], msg['Subject']
+
+ if not msg.is_multipart():
+ # create fresh mime message from scratch
+ # (multipart templates must take care of this themselves)
+ headers = msg.items()
+ payload = msg.get_payload()
+ # for notification prefer readability over data precision
+ msg = mail.mimeencode(self.ui, payload, self.charsets, self.test)
+ # reinstate custom headers
+ for k, v in headers:
+ msg[k] = v
+
+ msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
+
+ # try to make subject line exist and be useful
+ if not subject:
+ if count > 1:
+ subject = _('%s: %d new changesets') % (self.root, count)
+ else:
+ s = ctx.description().lstrip().split('\n', 1)[0].rstrip()
+ subject = '%s: %s' % (self.root, s)
+ maxsubject = int(self.ui.config('notify', 'maxsubject', 67))
+ if maxsubject and len(subject) > maxsubject:
+ subject = subject[:maxsubject-3] + '...'
+ msg['Subject'] = mail.headencode(self.ui, subject,
+ self.charsets, self.test)
+
+ # try to make message have proper sender
+ if not sender:
+ sender = self.ui.config('email', 'from') or self.ui.username()
+ if '@' not in sender or '@localhost' in sender:
+ sender = self.fixmail(sender)
+ msg['From'] = mail.addressencode(self.ui, sender,
+ self.charsets, self.test)
+
+ msg['X-Hg-Notification'] = 'changeset %s' % ctx
+ if not msg['Message-Id']:
+ msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' %
+ (ctx, int(time.time()),
+ hash(self.repo.root), socket.getfqdn()))
+ msg['To'] = ', '.join(self.subs)
+
+ msgtext = msg.as_string()
+ if self.test:
+ self.ui.write(msgtext)
+ if not msgtext.endswith('\n'):
+ self.ui.write('\n')
+ else:
+ self.ui.status(_('notify: sending %d subscribers %d changes\n') %
+ (len(self.subs), count))
+ mail.sendmail(self.ui, util.email(msg['From']),
+ self.subs, msgtext)
+
+ def diff(self, ctx, ref=None):
+
+ maxdiff = int(self.ui.config('notify', 'maxdiff', 300))
+ prev = ctx.parents()[0].node()
+ ref = ref and ref.node() or ctx.node()
+ chunks = patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui))
+ difflines = ''.join(chunks).splitlines()
+
+ if self.ui.configbool('notify', 'diffstat', True):
+ s = patch.diffstat(difflines)
+ # s may be nil, don't include the header if it is
+ if s:
+ self.ui.write('\ndiffstat:\n\n%s' % s)
+
+ if maxdiff == 0:
+ return
+ elif maxdiff > 0 and len(difflines) > maxdiff:
+ msg = _('\ndiffs (truncated from %d to %d lines):\n\n')
+ self.ui.write(msg % (len(difflines), maxdiff))
+ difflines = difflines[:maxdiff]
+ elif difflines:
+ self.ui.write(_('\ndiffs (%d lines):\n\n') % len(difflines))
+
+ self.ui.write("\n".join(difflines))
+
+def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
+ '''send email notifications to interested subscribers.
+
+ if used as changegroup hook, send one email for all changesets in
+ changegroup. else send one email per changeset.'''
+
+ n = notifier(ui, repo, hooktype)
+ ctx = repo[node]
+
+ if not n.subs:
+ ui.debug(_('notify: no subscribers to repository %s\n') % n.root)
+ return
+ if n.skipsource(source):
+ ui.debug(_('notify: changes have source "%s" - skipping\n') % source)
+ return
+
+ ui.pushbuffer()
+ if hooktype == 'changegroup':
+ start, end = ctx.rev(), len(repo)
+ count = end - start
+ for rev in xrange(start, end):
+ n.node(repo[rev])
+ n.diff(ctx, repo['tip'])
+ else:
+ count = 1
+ n.node(ctx)
+ n.diff(ctx)
+
+ data = ui.popbuffer()
+ n.send(ctx, count, data)
diff --git a/sys/src/cmd/hg/hgext/pager.py b/sys/src/cmd/hg/hgext/pager.py
new file mode 100644
index 000000000..1d973c485
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/pager.py
@@ -0,0 +1,64 @@
+# pager.py - display output using a pager
+#
+# Copyright 2008 David Soria Parra <dsp@php.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+#
+# To load the extension, add it to your .hgrc file:
+#
+# [extension]
+# hgext.pager =
+#
+# Run "hg help pager" to get info on configuration.
+
+'''browse command output with an external pager
+
+To set the pager that should be used, set the application variable::
+
+ [pager]
+ pager = LESS='FSRX' less
+
+If no pager is set, the pager extensions uses the environment variable
+$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.
+
+If you notice "BROKEN PIPE" error messages, you can disable them by
+setting::
+
+ [pager]
+ quiet = True
+
+You can disable the pager for certain commands by adding them to the
+pager.ignore list::
+
+ [pager]
+ ignore = version, help, update
+
+You can also enable the pager only for certain commands using
+pager.attend::
+
+ [pager]
+ attend = log
+
+If pager.attend is present, pager.ignore will be ignored.
+
+To ignore global commands like "hg version" or "hg help", you have to
+specify them in the global .hgrc
+'''
+
+import sys, os, signal
+from mercurial import dispatch, util, extensions
+
+def uisetup(ui):
+ def pagecmd(orig, ui, options, cmd, cmdfunc):
+ p = ui.config("pager", "pager", os.environ.get("PAGER"))
+ if p and sys.stdout.isatty() and '--debugger' not in sys.argv:
+ attend = ui.configlist('pager', 'attend')
+ if (cmd in attend or
+ (cmd not in ui.configlist('pager', 'ignore') and not attend)):
+ sys.stderr = sys.stdout = util.popen(p, "wb")
+ if ui.configbool('pager', 'quiet'):
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+ return orig(ui, options, cmd, cmdfunc)
+
+ extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
diff --git a/sys/src/cmd/hg/hgext/parentrevspec.py b/sys/src/cmd/hg/hgext/parentrevspec.py
new file mode 100644
index 000000000..6d6b2eb6c
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/parentrevspec.py
@@ -0,0 +1,96 @@
+# Mercurial extension to make it easy to refer to the parent of a revision
+#
+# Copyright (C) 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''interpret suffixes to refer to ancestor revisions
+
+This extension allows you to use git-style suffixes to refer to the
+ancestors of a specific revision.
+
+For example, if you can refer to a revision as "foo", then::
+
+ foo^N = Nth parent of foo
+ foo^0 = foo
+ foo^1 = first parent of foo
+ foo^2 = second parent of foo
+ foo^ = foo^1
+
+ foo~N = Nth first grandparent of foo
+ foo~0 = foo
+ foo~1 = foo^1 = foo^ = first parent of foo
+ foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo
+'''
+from mercurial import error
+
+def reposetup(ui, repo):
+ if not repo.local():
+ return
+
+ class parentrevspecrepo(repo.__class__):
+ def lookup(self, key):
+ try:
+ _super = super(parentrevspecrepo, self)
+ return _super.lookup(key)
+ except error.RepoError:
+ pass
+
+ circ = key.find('^')
+ tilde = key.find('~')
+ if circ < 0 and tilde < 0:
+ raise
+ elif circ >= 0 and tilde >= 0:
+ end = min(circ, tilde)
+ else:
+ end = max(circ, tilde)
+
+ cl = self.changelog
+ base = key[:end]
+ try:
+ node = _super.lookup(base)
+ except error.RepoError:
+ # eek - reraise the first error
+ return _super.lookup(key)
+
+ rev = cl.rev(node)
+ suffix = key[end:]
+ i = 0
+ while i < len(suffix):
+ # foo^N => Nth parent of foo
+ # foo^0 == foo
+ # foo^1 == foo^ == 1st parent of foo
+ # foo^2 == 2nd parent of foo
+ if suffix[i] == '^':
+ j = i + 1
+ p = cl.parentrevs(rev)
+ if j < len(suffix) and suffix[j].isdigit():
+ j += 1
+ n = int(suffix[i+1:j])
+ if n > 2 or n == 2 and p[1] == -1:
+ raise
+ else:
+ n = 1
+ if n:
+ rev = p[n - 1]
+ i = j
+ # foo~N => Nth first grandparent of foo
+ # foo~0 = foo
+ # foo~1 = foo^1 == foo^ == 1st parent of foo
+ # foo~2 = foo^1^1 == foo^^ == 1st parent of 1st parent of foo
+ elif suffix[i] == '~':
+ j = i + 1
+ while j < len(suffix) and suffix[j].isdigit():
+ j += 1
+ if j == i + 1:
+ raise
+ n = int(suffix[i+1:j])
+ for k in xrange(n):
+ rev = cl.parentrevs(rev)[0]
+ i = j
+ else:
+ raise
+ return cl.node(rev)
+
+ repo.__class__ = parentrevspecrepo
diff --git a/sys/src/cmd/hg/hgext/patchbomb.py b/sys/src/cmd/hg/hgext/patchbomb.py
new file mode 100644
index 000000000..8ad33384b
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/patchbomb.py
@@ -0,0 +1,513 @@
+# patchbomb.py - sending Mercurial changesets as patch emails
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''command to send changesets as (a series of) patch emails
+
+The series is started off with a "[PATCH 0 of N]" introduction, which
+describes the series as a whole.
+
+Each patch email has a Subject line of "[PATCH M of N] ...", using the
+first line of the changeset description as the subject text. The
+message contains two or three body parts:
+
+- The changeset description.
+- [Optional] The result of running diffstat on the patch.
+- The patch itself, as generated by "hg export".
+
+Each message refers to the first in the series using the In-Reply-To
+and References headers, so they will show up as a sequence in threaded
+mail and news readers, and in mail archives.
+
+With the -d/--diffstat option, you will be prompted for each changeset
+with a diffstat summary and the changeset summary, so you can be sure
+you are sending the right changes.
+
+To configure other defaults, add a section like this to your hgrc
+file::
+
+ [email]
+ from = My Name <my@email>
+ to = recipient1, recipient2, ...
+ cc = cc1, cc2, ...
+ bcc = bcc1, bcc2, ...
+
+Then you can use the "hg email" command to mail a series of changesets
+as a patchbomb.
+
+To avoid sending patches prematurely, it is a good idea to first run
+the "email" command with the "-n" option (test only). You will be
+prompted for an email recipient address, a subject and an introductory
+message describing the patches of your patchbomb. Then when all is
+done, patchbomb messages are displayed. If the PAGER environment
+variable is set, your pager will be fired up once for each patchbomb
+message, so you can verify everything is alright.
+
+The -m/--mbox option is also very useful. Instead of previewing each
+patchbomb message in a pager or sending the messages directly, it will
+create a UNIX mailbox file with the patch emails. This mailbox file
+can be previewed with any mail user agent which supports UNIX mbox
+files, e.g. with mutt::
+
+ % mutt -R -f mbox
+
+When you are previewing the patchbomb messages, you can use ``formail``
+(a utility that is commonly installed as part of the procmail
+package), to send each message out::
+
+ % formail -s sendmail -bm -t < mbox
+
+That should be all. Now your patchbomb is on its way out.
+
+You can also either configure the method option in the email section
+to be a sendmail compatible mailer or fill out the [smtp] section so
+that the patchbomb extension can automatically send patchbombs
+directly from the commandline. See the [email] and [smtp] sections in
+hgrc(5) for details.
+'''
+
+import os, errno, socket, tempfile, cStringIO, time
+import email.MIMEMultipart, email.MIMEBase
+import email.Utils, email.Encoders, email.Generator
+from mercurial import cmdutil, commands, hg, mail, patch, util
+from mercurial.i18n import _
+from mercurial.node import bin
+
+def prompt(ui, prompt, default=None, rest=': ', empty_ok=False):
+ if not ui.interactive():
+ return default
+ if default:
+ prompt += ' [%s]' % default
+ prompt += rest
+ while True:
+ r = ui.prompt(prompt, default=default)
+ if r:
+ return r
+ if default is not None:
+ return default
+ if empty_ok:
+ return r
+ ui.warn(_('Please enter a valid value.\n'))
+
+def cdiffstat(ui, summary, patchlines):
+ s = patch.diffstat(patchlines)
+ if summary:
+ ui.write(summary, '\n')
+ ui.write(s, '\n')
+ ans = prompt(ui, _('does the diffstat above look okay? '), 'y')
+ if not ans.lower().startswith('y'):
+ raise util.Abort(_('diffstat rejected'))
+ return s
+
+def makepatch(ui, repo, patch, opts, _charsets, idx, total, patchname=None):
+
+ desc = []
+ node = None
+ body = ''
+
+ for line in patch:
+ if line.startswith('#'):
+ if line.startswith('# Node ID'):
+ node = line.split()[-1]
+ continue
+ if line.startswith('diff -r') or line.startswith('diff --git'):
+ break
+ desc.append(line)
+
+ if not patchname and not node:
+ raise ValueError
+
+ if opts.get('attach'):
+ body = ('\n'.join(desc[1:]).strip() or
+ 'Patch subject is complete summary.')
+ body += '\n\n\n'
+
+ if opts.get('plain'):
+ while patch and patch[0].startswith('# '):
+ patch.pop(0)
+ if patch:
+ patch.pop(0)
+ while patch and not patch[0].strip():
+ patch.pop(0)
+
+ if opts.get('diffstat'):
+ body += cdiffstat(ui, '\n'.join(desc), patch) + '\n\n'
+
+ if opts.get('attach') or opts.get('inline'):
+ msg = email.MIMEMultipart.MIMEMultipart()
+ if body:
+ msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
+ p = mail.mimetextpatch('\n'.join(patch), 'x-patch', opts.get('test'))
+ binnode = bin(node)
+ # if node is mq patch, it will have the patch file's name as a tag
+ if not patchname:
+ patchtags = [t for t in repo.nodetags(binnode)
+ if t.endswith('.patch') or t.endswith('.diff')]
+ if patchtags:
+ patchname = patchtags[0]
+ elif total > 1:
+ patchname = cmdutil.make_filename(repo, '%b-%n.patch',
+ binnode, seqno=idx, total=total)
+ else:
+ patchname = cmdutil.make_filename(repo, '%b.patch', binnode)
+ disposition = 'inline'
+ if opts.get('attach'):
+ disposition = 'attachment'
+ p['Content-Disposition'] = disposition + '; filename=' + patchname
+ msg.attach(p)
+ else:
+ body += '\n'.join(patch)
+ msg = mail.mimetextpatch(body, display=opts.get('test'))
+
+ flag = ' '.join(opts.get('flag'))
+ if flag:
+ flag = ' ' + flag
+
+ subj = desc[0].strip().rstrip('. ')
+ if total == 1 and not opts.get('intro'):
+ subj = '[PATCH%s] %s' % (flag, opts.get('subject') or subj)
+ else:
+ tlen = len(str(total))
+ subj = '[PATCH %0*d of %d%s] %s' % (tlen, idx, total, flag, subj)
+ msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
+ msg['X-Mercurial-Node'] = node
+ return msg, subj
+
+def patchbomb(ui, repo, *revs, **opts):
+ '''send changesets by email
+
+ By default, diffs are sent in the format generated by hg export,
+ one per message. The series starts with a "[PATCH 0 of N]"
+ introduction, which describes the series as a whole.
+
+ Each patch email has a Subject line of "[PATCH M of N] ...", using
+ the first line of the changeset description as the subject text.
+ The message contains two or three parts. First, the changeset
+ description. Next, (optionally) if the diffstat program is
+ installed and -d/--diffstat is used, the result of running
+ diffstat on the patch. Finally, the patch itself, as generated by
+ "hg export".
+
+ By default the patch is included as text in the email body for
+ easy reviewing. Using the -a/--attach option will instead create
+ an attachment for the patch. With -i/--inline an inline attachment
+ will be created.
+
+ With -o/--outgoing, emails will be generated for patches not found
+ in the destination repository (or only those which are ancestors
+ of the specified revisions if any are provided)
+
+ With -b/--bundle, changesets are selected as for --outgoing, but a
+ single email containing a binary Mercurial bundle as an attachment
+ will be sent.
+
+ Examples::
+
+ hg email -r 3000 # send patch 3000 only
+ hg email -r 3000 -r 3001 # send patches 3000 and 3001
+ hg email -r 3000:3005 # send patches 3000 through 3005
+ hg email 3000 # send patch 3000 (deprecated)
+
+ hg email -o # send all patches not in default
+ hg email -o DEST # send all patches not in DEST
+ hg email -o -r 3000 # send all ancestors of 3000 not in default
+ hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST
+
+ hg email -b # send bundle of all patches not in default
+ hg email -b DEST # send bundle of all patches not in DEST
+ hg email -b -r 3000 # bundle of all ancestors of 3000 not in default
+ hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST
+
+ Before using this command, you will need to enable email in your
+ hgrc. See the [email] section in hgrc(5) for details.
+ '''
+
+ _charsets = mail._charsets(ui)
+
+ def outgoing(dest, revs):
+ '''Return the revisions present locally but not in dest'''
+ dest = ui.expandpath(dest or 'default-push', dest or 'default')
+ revs = [repo.lookup(rev) for rev in revs]
+ other = hg.repository(cmdutil.remoteui(repo, opts), dest)
+ ui.status(_('comparing with %s\n') % dest)
+ o = repo.findoutgoing(other)
+ if not o:
+ ui.status(_("no changes found\n"))
+ return []
+ o = repo.changelog.nodesbetween(o, revs or None)[0]
+ return [str(repo.changelog.rev(r)) for r in o]
+
+ def getpatches(revs):
+ for r in cmdutil.revrange(repo, revs):
+ output = cStringIO.StringIO()
+ patch.export(repo, [r], fp=output,
+ opts=patch.diffopts(ui, opts))
+ yield output.getvalue().split('\n')
+
+ def getbundle(dest):
+ tmpdir = tempfile.mkdtemp(prefix='hg-email-bundle-')
+ tmpfn = os.path.join(tmpdir, 'bundle')
+ try:
+ commands.bundle(ui, repo, tmpfn, dest, **opts)
+ return open(tmpfn, 'rb').read()
+ finally:
+ try:
+ os.unlink(tmpfn)
+ except:
+ pass
+ os.rmdir(tmpdir)
+
+ if not (opts.get('test') or opts.get('mbox')):
+ # really sending
+ mail.validateconfig(ui)
+
+ if not (revs or opts.get('rev')
+ or opts.get('outgoing') or opts.get('bundle')
+ or opts.get('patches')):
+ raise util.Abort(_('specify at least one changeset with -r or -o'))
+
+ if opts.get('outgoing') and opts.get('bundle'):
+ raise util.Abort(_("--outgoing mode always on with --bundle;"
+ " do not re-specify --outgoing"))
+
+ if opts.get('outgoing') or opts.get('bundle'):
+ if len(revs) > 1:
+ raise util.Abort(_("too many destinations"))
+ dest = revs and revs[0] or None
+ revs = []
+
+ if opts.get('rev'):
+ if revs:
+ raise util.Abort(_('use only one form to specify the revision'))
+ revs = opts.get('rev')
+
+ if opts.get('outgoing'):
+ revs = outgoing(dest, opts.get('rev'))
+ if opts.get('bundle'):
+ opts['revs'] = revs
+
+ # start
+ if opts.get('date'):
+ start_time = util.parsedate(opts.get('date'))
+ else:
+ start_time = util.makedate()
+
+ def genmsgid(id):
+ return '<%s.%s@%s>' % (id[:20], int(start_time[0]), socket.getfqdn())
+
+ def getdescription(body, sender):
+ if opts.get('desc'):
+ body = open(opts.get('desc')).read()
+ else:
+ ui.write(_('\nWrite the introductory message for the '
+ 'patch series.\n\n'))
+ body = ui.edit(body, sender)
+ return body
+
+ def getpatchmsgs(patches, patchnames=None):
+ jumbo = []
+ msgs = []
+
+ ui.write(_('This patch series consists of %d patches.\n\n')
+ % len(patches))
+
+ name = None
+ for i, p in enumerate(patches):
+ jumbo.extend(p)
+ if patchnames:
+ name = patchnames[i]
+ msg = makepatch(ui, repo, p, opts, _charsets, i + 1,
+ len(patches), name)
+ msgs.append(msg)
+
+ if len(patches) > 1 or opts.get('intro'):
+ tlen = len(str(len(patches)))
+
+ flag = ' '.join(opts.get('flag'))
+ if flag:
+ subj = '[PATCH %0*d of %d %s] ' % (tlen, 0, len(patches), flag)
+ else:
+ subj = '[PATCH %0*d of %d] ' % (tlen, 0, len(patches))
+ subj += opts.get('subject') or prompt(ui, 'Subject:', rest=subj,
+ default='None')
+
+ body = ''
+ if opts.get('diffstat'):
+ d = cdiffstat(ui, _('Final summary:\n'), jumbo)
+ if d:
+ body = '\n' + d
+
+ body = getdescription(body, sender)
+ msg = mail.mimeencode(ui, body, _charsets, opts.get('test'))
+ msg['Subject'] = mail.headencode(ui, subj, _charsets,
+ opts.get('test'))
+
+ msgs.insert(0, (msg, subj))
+ return msgs
+
+ def getbundlemsgs(bundle):
+ subj = (opts.get('subject')
+ or prompt(ui, 'Subject:', 'A bundle for your repository'))
+
+ body = getdescription('', sender)
+ msg = email.MIMEMultipart.MIMEMultipart()
+ if body:
+ msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
+ datapart = email.MIMEBase.MIMEBase('application', 'x-mercurial-bundle')
+ datapart.set_payload(bundle)
+ bundlename = '%s.hg' % opts.get('bundlename', 'bundle')
+ datapart.add_header('Content-Disposition', 'attachment',
+ filename=bundlename)
+ email.Encoders.encode_base64(datapart)
+ msg.attach(datapart)
+ msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
+ return [(msg, subj)]
+
+ sender = (opts.get('from') or ui.config('email', 'from') or
+ ui.config('patchbomb', 'from') or
+ prompt(ui, 'From', ui.username()))
+
+ # internal option used by pbranches
+ patches = opts.get('patches')
+ if patches:
+ msgs = getpatchmsgs(patches, opts.get('patchnames'))
+ elif opts.get('bundle'):
+ msgs = getbundlemsgs(getbundle(dest))
+ else:
+ msgs = getpatchmsgs(list(getpatches(revs)))
+
+ def getaddrs(opt, prpt, default = None):
+ addrs = opts.get(opt) or (ui.config('email', opt) or
+ ui.config('patchbomb', opt) or
+ prompt(ui, prpt, default)).split(',')
+ return [mail.addressencode(ui, a.strip(), _charsets, opts.get('test'))
+ for a in addrs if a.strip()]
+
+ to = getaddrs('to', 'To')
+ cc = getaddrs('cc', 'Cc', '')
+
+ bcc = opts.get('bcc') or (ui.config('email', 'bcc') or
+ ui.config('patchbomb', 'bcc') or '').split(',')
+ bcc = [mail.addressencode(ui, a.strip(), _charsets, opts.get('test'))
+ for a in bcc if a.strip()]
+
+ ui.write('\n')
+
+ parent = opts.get('in_reply_to') or None
+ # angle brackets may be omitted, they're not semantically part of the msg-id
+ if parent is not None:
+ if not parent.startswith('<'):
+ parent = '<' + parent
+ if not parent.endswith('>'):
+ parent += '>'
+
+ first = True
+
+ sender_addr = email.Utils.parseaddr(sender)[1]
+ sender = mail.addressencode(ui, sender, _charsets, opts.get('test'))
+ sendmail = None
+ for m, subj in msgs:
+ try:
+ m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
+ except TypeError:
+ m['Message-Id'] = genmsgid('patchbomb')
+ if parent:
+ m['In-Reply-To'] = parent
+ m['References'] = parent
+ if first:
+ parent = m['Message-Id']
+ first = False
+
+ m['User-Agent'] = 'Mercurial-patchbomb/%s' % util.version()
+ m['Date'] = email.Utils.formatdate(start_time[0], localtime=True)
+
+ start_time = (start_time[0] + 1, start_time[1])
+ m['From'] = sender
+ m['To'] = ', '.join(to)
+ if cc:
+ m['Cc'] = ', '.join(cc)
+ if bcc:
+ m['Bcc'] = ', '.join(bcc)
+ if opts.get('test'):
+ ui.status(_('Displaying '), subj, ' ...\n')
+ ui.flush()
+ if 'PAGER' in os.environ:
+ fp = util.popen(os.environ['PAGER'], 'w')
+ else:
+ fp = ui
+ generator = email.Generator.Generator(fp, mangle_from_=False)
+ try:
+ generator.flatten(m, 0)
+ fp.write('\n')
+ except IOError, inst:
+ if inst.errno != errno.EPIPE:
+ raise
+ if fp is not ui:
+ fp.close()
+ elif opts.get('mbox'):
+ ui.status(_('Writing '), subj, ' ...\n')
+ fp = open(opts.get('mbox'), 'In-Reply-To' in m and 'ab+' or 'wb+')
+ generator = email.Generator.Generator(fp, mangle_from_=True)
+ date = time.ctime(start_time[0])
+ fp.write('From %s %s\n' % (sender_addr, date))
+ generator.flatten(m, 0)
+ fp.write('\n\n')
+ fp.close()
+ else:
+ if not sendmail:
+ sendmail = mail.connect(ui)
+ ui.status(_('Sending '), subj, ' ...\n')
+ # Exim does not remove the Bcc field
+ del m['Bcc']
+ fp = cStringIO.StringIO()
+ generator = email.Generator.Generator(fp, mangle_from_=False)
+ generator.flatten(m, 0)
+ sendmail(sender, to + bcc + cc, fp.getvalue())
+
+emailopts = [
+ ('a', 'attach', None, _('send patches as attachments')),
+ ('i', 'inline', None, _('send patches as inline attachments')),
+ ('', 'bcc', [], _('email addresses of blind carbon copy recipients')),
+ ('c', 'cc', [], _('email addresses of copy recipients')),
+ ('d', 'diffstat', None, _('add diffstat output to messages')),
+ ('', 'date', '', _('use the given date as the sending date')),
+ ('', 'desc', '', _('use the given file as the series description')),
+ ('f', 'from', '', _('email address of sender')),
+ ('n', 'test', None, _('print messages that would be sent')),
+ ('m', 'mbox', '',
+ _('write messages to mbox file instead of sending them')),
+ ('s', 'subject', '',
+ _('subject of first message (intro or single patch)')),
+ ('', 'in-reply-to', '',
+ _('message identifier to reply to')),
+ ('', 'flag', [], _('flags to add in subject prefixes')),
+ ('t', 'to', [], _('email addresses of recipients')),
+ ]
+
+
+cmdtable = {
+ "email":
+ (patchbomb,
+ [('g', 'git', None, _('use git extended diff format')),
+ ('', 'plain', None, _('omit hg patch header')),
+ ('o', 'outgoing', None,
+ _('send changes not found in the target repository')),
+ ('b', 'bundle', None,
+ _('send changes not in target as a binary bundle')),
+ ('', 'bundlename', 'bundle',
+ _('name of the bundle attachment file')),
+ ('r', 'rev', [], _('a revision to send')),
+ ('', 'force', None,
+ _('run even when remote repository is unrelated '
+ '(with -b/--bundle)')),
+ ('', 'base', [],
+ _('a base changeset to specify instead of a destination '
+ '(with -b/--bundle)')),
+ ('', 'intro', None,
+ _('send an introduction email for a single patch')),
+ ] + emailopts + commands.remoteopts,
+ _('hg email [OPTION]... [DEST]...'))
+}
diff --git a/sys/src/cmd/hg/hgext/purge.py b/sys/src/cmd/hg/hgext/purge.py
new file mode 100644
index 000000000..3946ad0f5
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/purge.py
@@ -0,0 +1,111 @@
+# Copyright (C) 2006 - Marco Barisione <marco@barisione.org>
+#
+# This is a small extension for Mercurial (http://mercurial.selenic.com/)
+# that removes files not known to mercurial
+#
+# This program was inspired by the "cvspurge" script contained in CVS
+# utilities (http://www.red-bean.com/cvsutils/).
+#
+# For help on the usage of "hg purge" use:
+# hg help purge
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+'''command to delete untracked files from the working directory'''
+
+from mercurial import util, commands, cmdutil
+from mercurial.i18n import _
+import os, stat
+
+def purge(ui, repo, *dirs, **opts):
+ '''removes files not tracked by Mercurial
+
+ Delete files not known to Mercurial. This is useful to test local
+ and uncommitted changes in an otherwise-clean source tree.
+
+ This means that purge will delete:
+
+ - Unknown files: files marked with "?" by "hg status"
+ - Empty directories: in fact Mercurial ignores directories unless
+ they contain files under source control management
+
+ But it will leave untouched:
+
+ - Modified and unmodified tracked files
+ - Ignored files (unless --all is specified)
+ - New files added to the repository (with "hg add")
+
+ If directories are given on the command line, only files in these
+ directories are considered.
+
+ Be careful with purge, as you could irreversibly delete some files
+ you forgot to add to the repository. If you only want to print the
+ list of files that this program would delete, use the --print
+ option.
+ '''
+ act = not opts['print']
+ eol = '\n'
+ if opts['print0']:
+ eol = '\0'
+ act = False # --print0 implies --print
+
+ def remove(remove_func, name):
+ if act:
+ try:
+ remove_func(repo.wjoin(name))
+ except OSError:
+ m = _('%s cannot be removed') % name
+ if opts['abort_on_err']:
+ raise util.Abort(m)
+ ui.warn(_('warning: %s\n') % m)
+ else:
+ ui.write('%s%s' % (name, eol))
+
+ def removefile(path):
+ try:
+ os.remove(path)
+ except OSError:
+ # read-only files cannot be unlinked under Windows
+ s = os.stat(path)
+ if (s.st_mode & stat.S_IWRITE) != 0:
+ raise
+ os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
+ os.remove(path)
+
+ directories = []
+ match = cmdutil.match(repo, dirs, opts)
+ match.dir = directories.append
+ status = repo.status(match=match, ignored=opts['all'], unknown=True)
+
+ for f in sorted(status[4] + status[5]):
+ ui.note(_('Removing file %s\n') % f)
+ remove(removefile, f)
+
+ for f in sorted(directories, reverse=True):
+ if match(f) and not os.listdir(repo.wjoin(f)):
+ ui.note(_('Removing directory %s\n') % f)
+ remove(os.rmdir, f)
+
+cmdtable = {
+ 'purge|clean':
+ (purge,
+ [('a', 'abort-on-err', None, _('abort if an error occurs')),
+ ('', 'all', None, _('purge ignored files too')),
+ ('p', 'print', None, _('print filenames instead of deleting them')),
+ ('0', 'print0', None, _('end filenames with NUL, for use with xargs'
+ ' (implies -p/--print)')),
+ ] + commands.walkopts,
+ _('hg purge [OPTION]... [DIR]...'))
+}
diff --git a/sys/src/cmd/hg/hgext/rebase.py b/sys/src/cmd/hg/hgext/rebase.py
new file mode 100644
index 000000000..a1d030087
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/rebase.py
@@ -0,0 +1,471 @@
+# rebase.py - rebasing feature for mercurial
+#
+# Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''command to move sets of revisions to a different ancestor
+
+This extension lets you rebase changesets in an existing Mercurial
+repository.
+
+For more information:
+http://mercurial.selenic.com/wiki/RebaseExtension
+'''
+
+from mercurial import util, repair, merge, cmdutil, commands, error
+from mercurial import extensions, ancestor, copies, patch
+from mercurial.commands import templateopts
+from mercurial.node import nullrev
+from mercurial.lock import release
+from mercurial.i18n import _
+import os, errno
+
+def rebasemerge(repo, rev, first=False):
+ 'return the correct ancestor'
+ oldancestor = ancestor.ancestor
+
+ def newancestor(a, b, pfunc):
+ ancestor.ancestor = oldancestor
+ if b == rev:
+ return repo[rev].parents()[0].rev()
+ return ancestor.ancestor(a, b, pfunc)
+
+ if not first:
+ ancestor.ancestor = newancestor
+ else:
+ repo.ui.debug(_("first revision, do not change ancestor\n"))
+ stats = merge.update(repo, rev, True, True, False)
+ return stats
+
+def rebase(ui, repo, **opts):
+ """move changeset (and descendants) to a different branch
+
+ Rebase uses repeated merging to graft changesets from one part of
+ history onto another. This can be useful for linearizing local
+ changes relative to a master development tree.
+
+ If a rebase is interrupted to manually resolve a merge, it can be
+ continued with --continue/-c or aborted with --abort/-a.
+ """
+ originalwd = target = None
+ external = nullrev
+ state = {}
+ skipped = set()
+
+ lock = wlock = None
+ try:
+ lock = repo.lock()
+ wlock = repo.wlock()
+
+ # Validate input and define rebasing points
+ destf = opts.get('dest', None)
+ srcf = opts.get('source', None)
+ basef = opts.get('base', None)
+ contf = opts.get('continue')
+ abortf = opts.get('abort')
+ collapsef = opts.get('collapse', False)
+ extrafn = opts.get('extrafn')
+ keepf = opts.get('keep', False)
+ keepbranchesf = opts.get('keepbranches', False)
+
+ if contf or abortf:
+ if contf and abortf:
+ raise error.ParseError('rebase',
+ _('cannot use both abort and continue'))
+ if collapsef:
+ raise error.ParseError(
+ 'rebase', _('cannot use collapse with continue or abort'))
+
+ if srcf or basef or destf:
+ raise error.ParseError('rebase',
+ _('abort and continue do not allow specifying revisions'))
+
+ (originalwd, target, state, collapsef, keepf,
+ keepbranchesf, external) = restorestatus(repo)
+ if abortf:
+ abort(repo, originalwd, target, state)
+ return
+ else:
+ if srcf and basef:
+ raise error.ParseError('rebase', _('cannot specify both a '
+ 'revision and a base'))
+ cmdutil.bail_if_changed(repo)
+ result = buildstate(repo, destf, srcf, basef, collapsef)
+ if result:
+ originalwd, target, state, external = result
+ else: # Empty state built, nothing to rebase
+ ui.status(_('nothing to rebase\n'))
+ return
+
+ if keepbranchesf:
+ if extrafn:
+ raise error.ParseError(
+ 'rebase', _('cannot use both keepbranches and extrafn'))
+ def extrafn(ctx, extra):
+ extra['branch'] = ctx.branch()
+
+ # Rebase
+ targetancestors = list(repo.changelog.ancestors(target))
+ targetancestors.append(target)
+
+ for rev in sorted(state):
+ if state[rev] == -1:
+ storestatus(repo, originalwd, target, state, collapsef, keepf,
+ keepbranchesf, external)
+ rebasenode(repo, rev, target, state, skipped, targetancestors,
+ collapsef, extrafn)
+ ui.note(_('rebase merging completed\n'))
+
+ if collapsef:
+ p1, p2 = defineparents(repo, min(state), target,
+ state, targetancestors)
+ concludenode(repo, rev, p1, external, state, collapsef,
+ last=True, skipped=skipped, extrafn=extrafn)
+
+ if 'qtip' in repo.tags():
+ updatemq(repo, state, skipped, **opts)
+
+ if not keepf:
+ # Remove no more useful revisions
+ if set(repo.changelog.descendants(min(state))) - set(state):
+ ui.warn(_("warning: new changesets detected on source branch, "
+ "not stripping\n"))
+ else:
+ repair.strip(ui, repo, repo[min(state)].node(), "strip")
+
+ clearstatus(repo)
+ ui.status(_("rebase completed\n"))
+ if os.path.exists(repo.sjoin('undo')):
+ util.unlink(repo.sjoin('undo'))
+ if skipped:
+ ui.note(_("%d revisions have been skipped\n") % len(skipped))
+ finally:
+ release(lock, wlock)
+
+def concludenode(repo, rev, p1, p2, state, collapse, last=False, skipped=None,
+ extrafn=None):
+ """Skip commit if collapsing has been required and rev is not the last
+ revision, commit otherwise
+ """
+ repo.ui.debug(_(" set parents\n"))
+ if collapse and not last:
+ repo.dirstate.setparents(repo[p1].node())
+ return None
+
+ repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
+
+ if skipped is None:
+ skipped = set()
+
+ # Commit, record the old nodeid
+ newrev = nullrev
+ try:
+ if last:
+ # we don't translate commit messages
+ commitmsg = 'Collapsed revision'
+ for rebased in state:
+ if rebased not in skipped:
+ commitmsg += '\n* %s' % repo[rebased].description()
+ commitmsg = repo.ui.edit(commitmsg, repo.ui.username())
+ else:
+ commitmsg = repo[rev].description()
+ # Commit might fail if unresolved files exist
+ extra = {'rebase_source': repo[rev].hex()}
+ if extrafn:
+ extrafn(repo[rev], extra)
+ newrev = repo.commit(text=commitmsg, user=repo[rev].user(),
+ date=repo[rev].date(), extra=extra)
+ repo.dirstate.setbranch(repo[newrev].branch())
+ return newrev
+ except util.Abort:
+ # Invalidate the previous setparents
+ repo.dirstate.invalidate()
+ raise
+
+def rebasenode(repo, rev, target, state, skipped, targetancestors, collapse,
+ extrafn):
+ 'Rebase a single revision'
+ repo.ui.debug(_("rebasing %d:%s\n") % (rev, repo[rev]))
+
+ p1, p2 = defineparents(repo, rev, target, state, targetancestors)
+
+ repo.ui.debug(_(" future parents are %d and %d\n") % (repo[p1].rev(),
+ repo[p2].rev()))
+
+ # Merge phase
+ if len(repo.parents()) != 2:
+ # Update to target and merge it with local
+ if repo['.'].rev() != repo[p1].rev():
+ repo.ui.debug(_(" update to %d:%s\n") % (repo[p1].rev(), repo[p1]))
+ merge.update(repo, p1, False, True, False)
+ else:
+ repo.ui.debug(_(" already in target\n"))
+ repo.dirstate.write()
+ repo.ui.debug(_(" merge against %d:%s\n") % (repo[rev].rev(), repo[rev]))
+ first = repo[rev].rev() == repo[min(state)].rev()
+ stats = rebasemerge(repo, rev, first)
+
+ if stats[3] > 0:
+ raise util.Abort(_('fix unresolved conflicts with hg resolve then '
+ 'run hg rebase --continue'))
+ else: # we have an interrupted rebase
+ repo.ui.debug(_('resuming interrupted rebase\n'))
+
+ # Keep track of renamed files in the revision that is going to be rebased
+ # Here we simulate the copies and renames in the source changeset
+ cop, diver = copies.copies(repo, repo[rev], repo[target], repo[p2], True)
+ m1 = repo[rev].manifest()
+ m2 = repo[target].manifest()
+ for k, v in cop.iteritems():
+ if k in m1:
+ if v in m1 or v in m2:
+ repo.dirstate.copy(v, k)
+ if v in m2 and v not in m1:
+ repo.dirstate.remove(v)
+
+ newrev = concludenode(repo, rev, p1, p2, state, collapse,
+ extrafn=extrafn)
+
+ # Update the state
+ if newrev is not None:
+ state[rev] = repo[newrev].rev()
+ else:
+ if not collapse:
+ repo.ui.note(_('no changes, revision %d skipped\n') % rev)
+ repo.ui.debug(_('next revision set to %s\n') % p1)
+ skipped.add(rev)
+ state[rev] = p1
+
+def defineparents(repo, rev, target, state, targetancestors):
+ 'Return the new parent relationship of the revision that will be rebased'
+ parents = repo[rev].parents()
+ p1 = p2 = nullrev
+
+ P1n = parents[0].rev()
+ if P1n in targetancestors:
+ p1 = target
+ elif P1n in state:
+ p1 = state[P1n]
+ else: # P1n external
+ p1 = target
+ p2 = P1n
+
+ if len(parents) == 2 and parents[1].rev() not in targetancestors:
+ P2n = parents[1].rev()
+ # interesting second parent
+ if P2n in state:
+ if p1 == target: # P1n in targetancestors or external
+ p1 = state[P2n]
+ else:
+ p2 = state[P2n]
+ else: # P2n external
+ if p2 != nullrev: # P1n external too => rev is a merged revision
+ raise util.Abort(_('cannot use revision %d as base, result '
+ 'would have 3 parents') % rev)
+ p2 = P2n
+ return p1, p2
+
+def isagitpatch(repo, patchname):
+ 'Return true if the given patch is in git format'
+ mqpatch = os.path.join(repo.mq.path, patchname)
+ for line in patch.linereader(file(mqpatch, 'rb')):
+ if line.startswith('diff --git'):
+ return True
+ return False
+
+def updatemq(repo, state, skipped, **opts):
+ 'Update rebased mq patches - finalize and then import them'
+ mqrebase = {}
+ for p in repo.mq.applied:
+ if repo[p.rev].rev() in state:
+ repo.ui.debug(_('revision %d is an mq patch (%s), finalize it.\n') %
+ (repo[p.rev].rev(), p.name))
+ mqrebase[repo[p.rev].rev()] = (p.name, isagitpatch(repo, p.name))
+
+ if mqrebase:
+ repo.mq.finish(repo, mqrebase.keys())
+
+ # We must start import from the newest revision
+ for rev in sorted(mqrebase, reverse=True):
+ if rev not in skipped:
+ repo.ui.debug(_('import mq patch %d (%s)\n')
+ % (state[rev], mqrebase[rev][0]))
+ repo.mq.qimport(repo, (), patchname=mqrebase[rev][0],
+ git=mqrebase[rev][1],rev=[str(state[rev])])
+ repo.mq.save_dirty()
+
+def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
+ external):
+ 'Store the current status to allow recovery'
+ f = repo.opener("rebasestate", "w")
+ f.write(repo[originalwd].hex() + '\n')
+ f.write(repo[target].hex() + '\n')
+ f.write(repo[external].hex() + '\n')
+ f.write('%d\n' % int(collapse))
+ f.write('%d\n' % int(keep))
+ f.write('%d\n' % int(keepbranches))
+ for d, v in state.iteritems():
+ oldrev = repo[d].hex()
+ newrev = repo[v].hex()
+ f.write("%s:%s\n" % (oldrev, newrev))
+ f.close()
+ repo.ui.debug(_('rebase status stored\n'))
+
+def clearstatus(repo):
+ 'Remove the status files'
+ if os.path.exists(repo.join("rebasestate")):
+ util.unlink(repo.join("rebasestate"))
+
+def restorestatus(repo):
+ 'Restore a previously stored status'
+ try:
+ target = None
+ collapse = False
+ external = nullrev
+ state = {}
+ f = repo.opener("rebasestate")
+ for i, l in enumerate(f.read().splitlines()):
+ if i == 0:
+ originalwd = repo[l].rev()
+ elif i == 1:
+ target = repo[l].rev()
+ elif i == 2:
+ external = repo[l].rev()
+ elif i == 3:
+ collapse = bool(int(l))
+ elif i == 4:
+ keep = bool(int(l))
+ elif i == 5:
+ keepbranches = bool(int(l))
+ else:
+ oldrev, newrev = l.split(':')
+ state[repo[oldrev].rev()] = repo[newrev].rev()
+ repo.ui.debug(_('rebase status resumed\n'))
+ return originalwd, target, state, collapse, keep, keepbranches, external
+ except IOError, err:
+ if err.errno != errno.ENOENT:
+ raise
+ raise util.Abort(_('no rebase in progress'))
+
+def abort(repo, originalwd, target, state):
+ 'Restore the repository to its original state'
+ if set(repo.changelog.descendants(target)) - set(state.values()):
+ repo.ui.warn(_("warning: new changesets detected on target branch, "
+ "not stripping\n"))
+ else:
+ # Strip from the first rebased revision
+ merge.update(repo, repo[originalwd].rev(), False, True, False)
+ rebased = filter(lambda x: x > -1, state.values())
+ if rebased:
+ strippoint = min(rebased)
+ repair.strip(repo.ui, repo, repo[strippoint].node(), "strip")
+ clearstatus(repo)
+ repo.ui.status(_('rebase aborted\n'))
+
+def buildstate(repo, dest, src, base, collapse):
+ 'Define which revisions are going to be rebased and where'
+ targetancestors = set()
+
+ if not dest:
+ # Destination defaults to the latest revision in the current branch
+ branch = repo[None].branch()
+ dest = repo[branch].rev()
+ else:
+ if 'qtip' in repo.tags() and (repo[dest].hex() in
+ [s.rev for s in repo.mq.applied]):
+ raise util.Abort(_('cannot rebase onto an applied mq patch'))
+ dest = repo[dest].rev()
+
+ if src:
+ commonbase = repo[src].ancestor(repo[dest])
+ if commonbase == repo[src]:
+ raise util.Abort(_('cannot rebase an ancestor'))
+ if commonbase == repo[dest]:
+ raise util.Abort(_('cannot rebase a descendant'))
+ source = repo[src].rev()
+ else:
+ if base:
+ cwd = repo[base].rev()
+ else:
+ cwd = repo['.'].rev()
+
+ if cwd == dest:
+ repo.ui.debug(_('already working on current\n'))
+ return None
+
+ targetancestors = set(repo.changelog.ancestors(dest))
+ if cwd in targetancestors:
+ repo.ui.debug(_('already working on the current branch\n'))
+ return None
+
+ cwdancestors = set(repo.changelog.ancestors(cwd))
+ cwdancestors.add(cwd)
+ rebasingbranch = cwdancestors - targetancestors
+ source = min(rebasingbranch)
+
+ repo.ui.debug(_('rebase onto %d starting from %d\n') % (dest, source))
+ state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
+ external = nullrev
+ if collapse:
+ if not targetancestors:
+ targetancestors = set(repo.changelog.ancestors(dest))
+ for rev in state:
+ # Check externals and fail if there are more than one
+ for p in repo[rev].parents():
+ if (p.rev() not in state and p.rev() != source
+ and p.rev() not in targetancestors):
+ if external != nullrev:
+ raise util.Abort(_('unable to collapse, there is more '
+ 'than one external parent'))
+ external = p.rev()
+
+ state[source] = nullrev
+ return repo['.'].rev(), repo[dest].rev(), state, external
+
+def pullrebase(orig, ui, repo, *args, **opts):
+ 'Call rebase after pull if the latter has been invoked with --rebase'
+ if opts.get('rebase'):
+ if opts.get('update'):
+ del opts['update']
+ ui.debug(_('--update and --rebase are not compatible, ignoring '
+ 'the update flag\n'))
+
+ cmdutil.bail_if_changed(repo)
+ revsprepull = len(repo)
+ orig(ui, repo, *args, **opts)
+ revspostpull = len(repo)
+ if revspostpull > revsprepull:
+ rebase(ui, repo, **opts)
+ branch = repo[None].branch()
+ dest = repo[branch].rev()
+ if dest != repo['.'].rev():
+ # there was nothing to rebase we force an update
+ merge.update(repo, dest, False, False, False)
+ else:
+ orig(ui, repo, *args, **opts)
+
+def uisetup(ui):
+ 'Replace pull with a decorator to provide --rebase option'
+ entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
+ entry[1].append(('', 'rebase', None,
+ _("rebase working directory to branch head"))
+)
+
+cmdtable = {
+"rebase":
+ (rebase,
+ [
+ ('s', 'source', '', _('rebase from a given revision')),
+ ('b', 'base', '', _('rebase from the base of a given revision')),
+ ('d', 'dest', '', _('rebase onto a given revision')),
+ ('', 'collapse', False, _('collapse the rebased revisions')),
+ ('', 'keep', False, _('keep original revisions')),
+ ('', 'keepbranches', False, _('keep original branches')),
+ ('c', 'continue', False, _('continue an interrupted rebase')),
+ ('a', 'abort', False, _('abort an interrupted rebase')),] +
+ templateopts,
+ _('hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] '
+ '[--keepbranches] | [-c] | [-a]')),
+}
diff --git a/sys/src/cmd/hg/hgext/record.py b/sys/src/cmd/hg/hgext/record.py
new file mode 100644
index 000000000..71a4f13c7
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/record.py
@@ -0,0 +1,551 @@
+# record.py
+#
+# Copyright 2007 Bryan O'Sullivan <bos@serpentine.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''commands to interactively select changes for commit/qrefresh'''
+
+from mercurial.i18n import gettext, _
+from mercurial import cmdutil, commands, extensions, hg, mdiff, patch
+from mercurial import util
+import copy, cStringIO, errno, operator, os, re, tempfile
+
+lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
+
+def scanpatch(fp):
+ """like patch.iterhunks, but yield different events
+
+ - ('file', [header_lines + fromfile + tofile])
+ - ('context', [context_lines])
+ - ('hunk', [hunk_lines])
+ - ('range', (-start,len, +start,len, diffp))
+ """
+ lr = patch.linereader(fp)
+
+ def scanwhile(first, p):
+ """scan lr while predicate holds"""
+ lines = [first]
+ while True:
+ line = lr.readline()
+ if not line:
+ break
+ if p(line):
+ lines.append(line)
+ else:
+ lr.push(line)
+ break
+ return lines
+
+ while True:
+ line = lr.readline()
+ if not line:
+ break
+ if line.startswith('diff --git a/'):
+ def notheader(line):
+ s = line.split(None, 1)
+ return not s or s[0] not in ('---', 'diff')
+ header = scanwhile(line, notheader)
+ fromfile = lr.readline()
+ if fromfile.startswith('---'):
+ tofile = lr.readline()
+ header += [fromfile, tofile]
+ else:
+ lr.push(fromfile)
+ yield 'file', header
+ elif line[0] == ' ':
+ yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
+ elif line[0] in '-+':
+ yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
+ else:
+ m = lines_re.match(line)
+ if m:
+ yield 'range', m.groups()
+ else:
+ raise patch.PatchError('unknown patch content: %r' % line)
+
+class header(object):
+ """patch header
+
+ XXX shoudn't we move this to mercurial/patch.py ?
+ """
+ diff_re = re.compile('diff --git a/(.*) b/(.*)$')
+ allhunks_re = re.compile('(?:index|new file|deleted file) ')
+ pretty_re = re.compile('(?:new file|deleted file) ')
+ special_re = re.compile('(?:index|new|deleted|copy|rename) ')
+
+ def __init__(self, header):
+ self.header = header
+ self.hunks = []
+
+ def binary(self):
+ for h in self.header:
+ if h.startswith('index '):
+ return True
+
+ def pretty(self, fp):
+ for h in self.header:
+ if h.startswith('index '):
+ fp.write(_('this modifies a binary file (all or nothing)\n'))
+ break
+ if self.pretty_re.match(h):
+ fp.write(h)
+ if self.binary():
+ fp.write(_('this is a binary file\n'))
+ break
+ if h.startswith('---'):
+ fp.write(_('%d hunks, %d lines changed\n') %
+ (len(self.hunks),
+ sum([h.added + h.removed for h in self.hunks])))
+ break
+ fp.write(h)
+
+ def write(self, fp):
+ fp.write(''.join(self.header))
+
+ def allhunks(self):
+ for h in self.header:
+ if self.allhunks_re.match(h):
+ return True
+
+ def files(self):
+ fromfile, tofile = self.diff_re.match(self.header[0]).groups()
+ if fromfile == tofile:
+ return [fromfile]
+ return [fromfile, tofile]
+
+ def filename(self):
+ return self.files()[-1]
+
+ def __repr__(self):
+ return '<header %s>' % (' '.join(map(repr, self.files())))
+
+ def special(self):
+ for h in self.header:
+ if self.special_re.match(h):
+ return True
+
+def countchanges(hunk):
+ """hunk -> (n+,n-)"""
+ add = len([h for h in hunk if h[0] == '+'])
+ rem = len([h for h in hunk if h[0] == '-'])
+ return add, rem
+
+class hunk(object):
+ """patch hunk
+
+ XXX shouldn't we merge this with patch.hunk ?
+ """
+ maxcontext = 3
+
+ def __init__(self, header, fromline, toline, proc, before, hunk, after):
+ def trimcontext(number, lines):
+ delta = len(lines) - self.maxcontext
+ if False and delta > 0:
+ return number + delta, lines[:self.maxcontext]
+ return number, lines
+
+ self.header = header
+ self.fromline, self.before = trimcontext(fromline, before)
+ self.toline, self.after = trimcontext(toline, after)
+ self.proc = proc
+ self.hunk = hunk
+ self.added, self.removed = countchanges(self.hunk)
+
+ def write(self, fp):
+ delta = len(self.before) + len(self.after)
+ if self.after and self.after[-1] == '\\ No newline at end of file\n':
+ delta -= 1
+ fromlen = delta + self.removed
+ tolen = delta + self.added
+ fp.write('@@ -%d,%d +%d,%d @@%s\n' %
+ (self.fromline, fromlen, self.toline, tolen,
+ self.proc and (' ' + self.proc)))
+ fp.write(''.join(self.before + self.hunk + self.after))
+
+ pretty = write
+
+ def filename(self):
+ return self.header.filename()
+
+ def __repr__(self):
+ return '<hunk %r@%d>' % (self.filename(), self.fromline)
+
+def parsepatch(fp):
+ """patch -> [] of hunks """
+ class parser(object):
+ """patch parsing state machine"""
+ def __init__(self):
+ self.fromline = 0
+ self.toline = 0
+ self.proc = ''
+ self.header = None
+ self.context = []
+ self.before = []
+ self.hunk = []
+ self.stream = []
+
+ def addrange(self, (fromstart, fromend, tostart, toend, proc)):
+ self.fromline = int(fromstart)
+ self.toline = int(tostart)
+ self.proc = proc
+
+ def addcontext(self, context):
+ if self.hunk:
+ h = hunk(self.header, self.fromline, self.toline, self.proc,
+ self.before, self.hunk, context)
+ self.header.hunks.append(h)
+ self.stream.append(h)
+ self.fromline += len(self.before) + h.removed
+ self.toline += len(self.before) + h.added
+ self.before = []
+ self.hunk = []
+ self.proc = ''
+ self.context = context
+
+ def addhunk(self, hunk):
+ if self.context:
+ self.before = self.context
+ self.context = []
+ self.hunk = hunk
+
+ def newfile(self, hdr):
+ self.addcontext([])
+ h = header(hdr)
+ self.stream.append(h)
+ self.header = h
+
+ def finished(self):
+ self.addcontext([])
+ return self.stream
+
+ transitions = {
+ 'file': {'context': addcontext,
+ 'file': newfile,
+ 'hunk': addhunk,
+ 'range': addrange},
+ 'context': {'file': newfile,
+ 'hunk': addhunk,
+ 'range': addrange},
+ 'hunk': {'context': addcontext,
+ 'file': newfile,
+ 'range': addrange},
+ 'range': {'context': addcontext,
+ 'hunk': addhunk},
+ }
+
+ p = parser()
+
+ state = 'context'
+ for newstate, data in scanpatch(fp):
+ try:
+ p.transitions[state][newstate](p, data)
+ except KeyError:
+ raise patch.PatchError('unhandled transition: %s -> %s' %
+ (state, newstate))
+ state = newstate
+ return p.finished()
+
+def filterpatch(ui, chunks):
+ """Interactively filter patch chunks into applied-only chunks"""
+ chunks = list(chunks)
+ chunks.reverse()
+ seen = set()
+ def consumefile():
+ """fetch next portion from chunks until a 'header' is seen
+ NB: header == new-file mark
+ """
+ consumed = []
+ while chunks:
+ if isinstance(chunks[-1], header):
+ break
+ else:
+ consumed.append(chunks.pop())
+ return consumed
+
+ resp_all = [None] # this two are changed from inside prompt,
+ resp_file = [None] # so can't be usual variables
+ applied = {} # 'filename' -> [] of chunks
+ def prompt(query):
+ """prompt query, and process base inputs
+
+ - y/n for the rest of file
+ - y/n for the rest
+ - ? (help)
+ - q (quit)
+
+ else, input is returned to the caller.
+ """
+ if resp_all[0] is not None:
+ return resp_all[0]
+ if resp_file[0] is not None:
+ return resp_file[0]
+ while True:
+ resps = _('[Ynsfdaq?]')
+ choices = (_('&Yes, record this change'),
+ _('&No, skip this change'),
+ _('&Skip remaining changes to this file'),
+ _('Record remaining changes to this &file'),
+ _('&Done, skip remaining changes and files'),
+ _('Record &all changes to all remaining files'),
+ _('&Quit, recording no changes'),
+ _('&?'))
+ r = ui.promptchoice("%s %s " % (query, resps), choices)
+ if r == 7: # ?
+ doc = gettext(record.__doc__)
+ c = doc.find(_('y - record this change'))
+ for l in doc[c:].splitlines():
+ if l: ui.write(l.strip(), '\n')
+ continue
+ elif r == 0: # yes
+ ret = 'y'
+ elif r == 1: # no
+ ret = 'n'
+ elif r == 2: # Skip
+ ret = resp_file[0] = 'n'
+ elif r == 3: # file (Record remaining)
+ ret = resp_file[0] = 'y'
+ elif r == 4: # done, skip remaining
+ ret = resp_all[0] = 'n'
+ elif r == 5: # all
+ ret = resp_all[0] = 'y'
+ elif r == 6: # quit
+ raise util.Abort(_('user quit'))
+ return ret
+ pos, total = 0, len(chunks) - 1
+ while chunks:
+ chunk = chunks.pop()
+ if isinstance(chunk, header):
+ # new-file mark
+ resp_file = [None]
+ fixoffset = 0
+ hdr = ''.join(chunk.header)
+ if hdr in seen:
+ consumefile()
+ continue
+ seen.add(hdr)
+ if resp_all[0] is None:
+ chunk.pretty(ui)
+ r = prompt(_('examine changes to %s?') %
+ _(' and ').join(map(repr, chunk.files())))
+ if r == _('y'):
+ applied[chunk.filename()] = [chunk]
+ if chunk.allhunks():
+ applied[chunk.filename()] += consumefile()
+ else:
+ consumefile()
+ else:
+ # new hunk
+ if resp_file[0] is None and resp_all[0] is None:
+ chunk.pretty(ui)
+ r = total == 1 and prompt(_('record this change to %r?') %
+ chunk.filename()) \
+ or prompt(_('record change %d/%d to %r?') %
+ (pos, total, chunk.filename()))
+ if r == _('y'):
+ if fixoffset:
+ chunk = copy.copy(chunk)
+ chunk.toline += fixoffset
+ applied[chunk.filename()].append(chunk)
+ else:
+ fixoffset += chunk.removed - chunk.added
+ pos = pos + 1
+ return reduce(operator.add, [h for h in applied.itervalues()
+ if h[0].special() or len(h) > 1], [])
+
+def record(ui, repo, *pats, **opts):
+ '''interactively select changes to commit
+
+ If a list of files is omitted, all changes reported by "hg status"
+ will be candidates for recording.
+
+ See 'hg help dates' for a list of formats valid for -d/--date.
+
+ You will be prompted for whether to record changes to each
+ modified file, and for files with multiple changes, for each
+ change to use. For each query, the following responses are
+ possible::
+
+ y - record this change
+ n - skip this change
+
+ s - skip remaining changes to this file
+ f - record remaining changes to this file
+
+ d - done, skip remaining changes and files
+ a - record all changes to all remaining files
+ q - quit, recording no changes
+
+ ? - display help'''
+
+ def record_committer(ui, repo, pats, opts):
+ commands.commit(ui, repo, *pats, **opts)
+
+ dorecord(ui, repo, record_committer, *pats, **opts)
+
+
+def qrecord(ui, repo, patch, *pats, **opts):
+ '''interactively record a new patch
+
+ See 'hg help qnew' & 'hg help record' for more information and
+ usage.
+ '''
+
+ try:
+ mq = extensions.find('mq')
+ except KeyError:
+ raise util.Abort(_("'mq' extension not loaded"))
+
+ def qrecord_committer(ui, repo, pats, opts):
+ mq.new(ui, repo, patch, *pats, **opts)
+
+ opts = opts.copy()
+ opts['force'] = True # always 'qnew -f'
+ dorecord(ui, repo, qrecord_committer, *pats, **opts)
+
+
+def dorecord(ui, repo, committer, *pats, **opts):
+ if not ui.interactive():
+ raise util.Abort(_('running non-interactively, use commit instead'))
+
+ def recordfunc(ui, repo, message, match, opts):
+ """This is generic record driver.
+
+ Its job is to interactively filter local changes, and accordingly
+ prepare working dir into a state, where the job can be delegated to
+ non-interactive commit command such as 'commit' or 'qrefresh'.
+
+ After the actual job is done by non-interactive command, working dir
+ state is restored to original.
+
+ In the end we'll record intresting changes, and everything else will be
+ left in place, so the user can continue his work.
+ """
+
+ changes = repo.status(match=match)[:3]
+ diffopts = mdiff.diffopts(git=True, nodates=True)
+ chunks = patch.diff(repo, changes=changes, opts=diffopts)
+ fp = cStringIO.StringIO()
+ fp.write(''.join(chunks))
+ fp.seek(0)
+
+ # 1. filter patch, so we have intending-to apply subset of it
+ chunks = filterpatch(ui, parsepatch(fp))
+ del fp
+
+ contenders = set()
+ for h in chunks:
+ try: contenders.update(set(h.files()))
+ except AttributeError: pass
+
+ changed = changes[0] + changes[1] + changes[2]
+ newfiles = [f for f in changed if f in contenders]
+ if not newfiles:
+ ui.status(_('no changes to record\n'))
+ return 0
+
+ modified = set(changes[0])
+
+ # 2. backup changed files, so we can restore them in the end
+ backups = {}
+ backupdir = repo.join('record-backups')
+ try:
+ os.mkdir(backupdir)
+ except OSError, err:
+ if err.errno != errno.EEXIST:
+ raise
+ try:
+ # backup continues
+ for f in newfiles:
+ if f not in modified:
+ continue
+ fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
+ dir=backupdir)
+ os.close(fd)
+ ui.debug(_('backup %r as %r\n') % (f, tmpname))
+ util.copyfile(repo.wjoin(f), tmpname)
+ backups[f] = tmpname
+
+ fp = cStringIO.StringIO()
+ for c in chunks:
+ if c.filename() in backups:
+ c.write(fp)
+ dopatch = fp.tell()
+ fp.seek(0)
+
+ # 3a. apply filtered patch to clean repo (clean)
+ if backups:
+ hg.revert(repo, repo.dirstate.parents()[0], backups.has_key)
+
+ # 3b. (apply)
+ if dopatch:
+ try:
+ ui.debug(_('applying patch\n'))
+ ui.debug(fp.getvalue())
+ pfiles = {}
+ patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
+ eolmode=None)
+ patch.updatedir(ui, repo, pfiles)
+ except patch.PatchError, err:
+ s = str(err)
+ if s:
+ raise util.Abort(s)
+ else:
+ raise util.Abort(_('patch failed to apply'))
+ del fp
+
+ # 4. We prepared working directory according to filtered patch.
+ # Now is the time to delegate the job to commit/qrefresh or the like!
+
+ # it is important to first chdir to repo root -- we'll call a
+ # highlevel command with list of pathnames relative to repo root
+ cwd = os.getcwd()
+ os.chdir(repo.root)
+ try:
+ committer(ui, repo, newfiles, opts)
+ finally:
+ os.chdir(cwd)
+
+ return 0
+ finally:
+ # 5. finally restore backed-up files
+ try:
+ for realname, tmpname in backups.iteritems():
+ ui.debug(_('restoring %r to %r\n') % (tmpname, realname))
+ util.copyfile(tmpname, repo.wjoin(realname))
+ os.unlink(tmpname)
+ os.rmdir(backupdir)
+ except OSError:
+ pass
+ return cmdutil.commit(ui, repo, recordfunc, pats, opts)
+
+cmdtable = {
+ "record":
+ (record,
+
+ # add commit options
+ commands.table['^commit|ci'][1],
+
+ _('hg record [OPTION]... [FILE]...')),
+}
+
+
+def extsetup():
+ try:
+ mq = extensions.find('mq')
+ except KeyError:
+ return
+
+ qcmdtable = {
+ "qrecord":
+ (qrecord,
+
+ # add qnew options, except '--force'
+ [opt for opt in mq.cmdtable['qnew'][1] if opt[1] != 'force'],
+
+ _('hg qrecord [OPTION]... PATCH [FILE]...')),
+ }
+
+ cmdtable.update(qcmdtable)
+
diff --git a/sys/src/cmd/hg/hgext/share.py b/sys/src/cmd/hg/hgext/share.py
new file mode 100644
index 000000000..e714ce0aa
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/share.py
@@ -0,0 +1,30 @@
+# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''share a common history between several working directories'''
+
+from mercurial.i18n import _
+from mercurial import hg, commands
+
+def share(ui, source, dest=None, noupdate=False):
+ """create a new shared repository (experimental)
+
+ Initialize a new repository and working directory that shares its
+ history with another repository.
+
+ NOTE: actions that change history such as rollback or moving the
+ source may confuse sharers.
+ """
+
+ return hg.share(ui, source, dest, not noupdate)
+
+cmdtable = {
+ "share":
+ (share,
+ [('U', 'noupdate', None, _('do not create a working copy'))],
+ _('[-U] SOURCE [DEST]')),
+}
+
+commands.norepo += " share"
diff --git a/sys/src/cmd/hg/hgext/transplant.py b/sys/src/cmd/hg/hgext/transplant.py
new file mode 100644
index 000000000..1d26c7efd
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/transplant.py
@@ -0,0 +1,606 @@
+# Patch transplanting extension for Mercurial
+#
+# Copyright 2006, 2007 Brendan Cully <brendan@kublai.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''command to transplant changesets from another branch
+
+This extension allows you to transplant patches from another branch.
+
+Transplanted patches are recorded in .hg/transplant/transplants, as a
+map from a changeset hash to its hash in the source repository.
+'''
+
+from mercurial.i18n import _
+import os, tempfile
+from mercurial import bundlerepo, changegroup, cmdutil, hg, merge, match
+from mercurial import patch, revlog, util, error
+
+class transplantentry(object):
+ def __init__(self, lnode, rnode):
+ self.lnode = lnode
+ self.rnode = rnode
+
+class transplants(object):
+ def __init__(self, path=None, transplantfile=None, opener=None):
+ self.path = path
+ self.transplantfile = transplantfile
+ self.opener = opener
+
+ if not opener:
+ self.opener = util.opener(self.path)
+ self.transplants = []
+ self.dirty = False
+ self.read()
+
+ def read(self):
+ abspath = os.path.join(self.path, self.transplantfile)
+ if self.transplantfile and os.path.exists(abspath):
+ for line in self.opener(self.transplantfile).read().splitlines():
+ lnode, rnode = map(revlog.bin, line.split(':'))
+ self.transplants.append(transplantentry(lnode, rnode))
+
+ def write(self):
+ if self.dirty and self.transplantfile:
+ if not os.path.isdir(self.path):
+ os.mkdir(self.path)
+ fp = self.opener(self.transplantfile, 'w')
+ for c in self.transplants:
+ l, r = map(revlog.hex, (c.lnode, c.rnode))
+ fp.write(l + ':' + r + '\n')
+ fp.close()
+ self.dirty = False
+
+ def get(self, rnode):
+ return [t for t in self.transplants if t.rnode == rnode]
+
+ def set(self, lnode, rnode):
+ self.transplants.append(transplantentry(lnode, rnode))
+ self.dirty = True
+
+ def remove(self, transplant):
+ del self.transplants[self.transplants.index(transplant)]
+ self.dirty = True
+
+class transplanter(object):
+ def __init__(self, ui, repo):
+ self.ui = ui
+ self.path = repo.join('transplant')
+ self.opener = util.opener(self.path)
+ self.transplants = transplants(self.path, 'transplants',
+ opener=self.opener)
+
+ def applied(self, repo, node, parent):
+ '''returns True if a node is already an ancestor of parent
+ or has already been transplanted'''
+ if hasnode(repo, node):
+ if node in repo.changelog.reachable(parent, stop=node):
+ return True
+ for t in self.transplants.get(node):
+ # it might have been stripped
+ if not hasnode(repo, t.lnode):
+ self.transplants.remove(t)
+ return False
+ if t.lnode in repo.changelog.reachable(parent, stop=t.lnode):
+ return True
+ return False
+
+ def apply(self, repo, source, revmap, merges, opts={}):
+ '''apply the revisions in revmap one by one in revision order'''
+ revs = sorted(revmap)
+ p1, p2 = repo.dirstate.parents()
+ pulls = []
+ diffopts = patch.diffopts(self.ui, opts)
+ diffopts.git = True
+
+ lock = wlock = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ for rev in revs:
+ node = revmap[rev]
+ revstr = '%s:%s' % (rev, revlog.short(node))
+
+ if self.applied(repo, node, p1):
+ self.ui.warn(_('skipping already applied revision %s\n') %
+ revstr)
+ continue
+
+ parents = source.changelog.parents(node)
+ if not opts.get('filter'):
+ # If the changeset parent is the same as the
+ # wdir's parent, just pull it.
+ if parents[0] == p1:
+ pulls.append(node)
+ p1 = node
+ continue
+ if pulls:
+ if source != repo:
+ repo.pull(source, heads=pulls)
+ merge.update(repo, pulls[-1], False, False, None)
+ p1, p2 = repo.dirstate.parents()
+ pulls = []
+
+ domerge = False
+ if node in merges:
+ # pulling all the merge revs at once would mean we
+ # couldn't transplant after the latest even if
+ # transplants before them fail.
+ domerge = True
+ if not hasnode(repo, node):
+ repo.pull(source, heads=[node])
+
+ if parents[1] != revlog.nullid:
+ self.ui.note(_('skipping merge changeset %s:%s\n')
+ % (rev, revlog.short(node)))
+ patchfile = None
+ else:
+ fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
+ fp = os.fdopen(fd, 'w')
+ gen = patch.diff(source, parents[0], node, opts=diffopts)
+ for chunk in gen:
+ fp.write(chunk)
+ fp.close()
+
+ del revmap[rev]
+ if patchfile or domerge:
+ try:
+ n = self.applyone(repo, node,
+ source.changelog.read(node),
+ patchfile, merge=domerge,
+ log=opts.get('log'),
+ filter=opts.get('filter'))
+ if n and domerge:
+ self.ui.status(_('%s merged at %s\n') % (revstr,
+ revlog.short(n)))
+ elif n:
+ self.ui.status(_('%s transplanted to %s\n')
+ % (revlog.short(node),
+ revlog.short(n)))
+ finally:
+ if patchfile:
+ os.unlink(patchfile)
+ if pulls:
+ repo.pull(source, heads=pulls)
+ merge.update(repo, pulls[-1], False, False, None)
+ finally:
+ self.saveseries(revmap, merges)
+ self.transplants.write()
+ lock.release()
+ wlock.release()
+
+ def filter(self, filter, changelog, patchfile):
+ '''arbitrarily rewrite changeset before applying it'''
+
+ self.ui.status(_('filtering %s\n') % patchfile)
+ user, date, msg = (changelog[1], changelog[2], changelog[4])
+
+ fd, headerfile = tempfile.mkstemp(prefix='hg-transplant-')
+ fp = os.fdopen(fd, 'w')
+ fp.write("# HG changeset patch\n")
+ fp.write("# User %s\n" % user)
+ fp.write("# Date %d %d\n" % date)
+ fp.write(changelog[4])
+ fp.close()
+
+ try:
+ util.system('%s %s %s' % (filter, util.shellquote(headerfile),
+ util.shellquote(patchfile)),
+ environ={'HGUSER': changelog[1]},
+ onerr=util.Abort, errprefix=_('filter failed'))
+ user, date, msg = self.parselog(file(headerfile))[1:4]
+ finally:
+ os.unlink(headerfile)
+
+ return (user, date, msg)
+
+ def applyone(self, repo, node, cl, patchfile, merge=False, log=False,
+ filter=None):
+ '''apply the patch in patchfile to the repository as a transplant'''
+ (manifest, user, (time, timezone), files, message) = cl[:5]
+ date = "%d %d" % (time, timezone)
+ extra = {'transplant_source': node}
+ if filter:
+ (user, date, message) = self.filter(filter, cl, patchfile)
+
+ if log:
+ # we don't translate messages inserted into commits
+ message += '\n(transplanted from %s)' % revlog.hex(node)
+
+ self.ui.status(_('applying %s\n') % revlog.short(node))
+ self.ui.note('%s %s\n%s\n' % (user, date, message))
+
+ if not patchfile and not merge:
+ raise util.Abort(_('can only omit patchfile if merging'))
+ if patchfile:
+ try:
+ files = {}
+ try:
+ patch.patch(patchfile, self.ui, cwd=repo.root,
+ files=files, eolmode=None)
+ if not files:
+ self.ui.warn(_('%s: empty changeset')
+ % revlog.hex(node))
+ return None
+ finally:
+ files = patch.updatedir(self.ui, repo, files)
+ except Exception, inst:
+ if filter:
+ os.unlink(patchfile)
+ seriespath = os.path.join(self.path, 'series')
+ if os.path.exists(seriespath):
+ os.unlink(seriespath)
+ p1 = repo.dirstate.parents()[0]
+ p2 = node
+ self.log(user, date, message, p1, p2, merge=merge)
+ self.ui.write(str(inst) + '\n')
+ raise util.Abort(_('Fix up the merge and run '
+ 'hg transplant --continue'))
+ else:
+ files = None
+ if merge:
+ p1, p2 = repo.dirstate.parents()
+ repo.dirstate.setparents(p1, node)
+ m = match.always(repo.root, '')
+ else:
+ m = match.exact(repo.root, '', files)
+
+ n = repo.commit(message, user, date, extra=extra, match=m)
+ if not merge:
+ self.transplants.set(n, node)
+
+ return n
+
+ def resume(self, repo, source, opts=None):
+ '''recover last transaction and apply remaining changesets'''
+ if os.path.exists(os.path.join(self.path, 'journal')):
+ n, node = self.recover(repo)
+ self.ui.status(_('%s transplanted as %s\n') % (revlog.short(node),
+ revlog.short(n)))
+ seriespath = os.path.join(self.path, 'series')
+ if not os.path.exists(seriespath):
+ self.transplants.write()
+ return
+ nodes, merges = self.readseries()
+ revmap = {}
+ for n in nodes:
+ revmap[source.changelog.rev(n)] = n
+ os.unlink(seriespath)
+
+ self.apply(repo, source, revmap, merges, opts)
+
+ def recover(self, repo):
+ '''commit working directory using journal metadata'''
+ node, user, date, message, parents = self.readlog()
+ merge = len(parents) == 2
+
+ if not user or not date or not message or not parents[0]:
+ raise util.Abort(_('transplant log file is corrupt'))
+
+ extra = {'transplant_source': node}
+ wlock = repo.wlock()
+ try:
+ p1, p2 = repo.dirstate.parents()
+ if p1 != parents[0]:
+ raise util.Abort(
+ _('working dir not at transplant parent %s') %
+ revlog.hex(parents[0]))
+ if merge:
+ repo.dirstate.setparents(p1, parents[1])
+ n = repo.commit(message, user, date, extra=extra)
+ if not n:
+ raise util.Abort(_('commit failed'))
+ if not merge:
+ self.transplants.set(n, node)
+ self.unlog()
+
+ return n, node
+ finally:
+ wlock.release()
+
+ def readseries(self):
+ nodes = []
+ merges = []
+ cur = nodes
+ for line in self.opener('series').read().splitlines():
+ if line.startswith('# Merges'):
+ cur = merges
+ continue
+ cur.append(revlog.bin(line))
+
+ return (nodes, merges)
+
+ def saveseries(self, revmap, merges):
+ if not revmap:
+ return
+
+ if not os.path.isdir(self.path):
+ os.mkdir(self.path)
+ series = self.opener('series', 'w')
+ for rev in sorted(revmap):
+ series.write(revlog.hex(revmap[rev]) + '\n')
+ if merges:
+ series.write('# Merges\n')
+ for m in merges:
+ series.write(revlog.hex(m) + '\n')
+ series.close()
+
+ def parselog(self, fp):
+ parents = []
+ message = []
+ node = revlog.nullid
+ inmsg = False
+ for line in fp.read().splitlines():
+ if inmsg:
+ message.append(line)
+ elif line.startswith('# User '):
+ user = line[7:]
+ elif line.startswith('# Date '):
+ date = line[7:]
+ elif line.startswith('# Node ID '):
+ node = revlog.bin(line[10:])
+ elif line.startswith('# Parent '):
+ parents.append(revlog.bin(line[9:]))
+ elif not line.startswith('#'):
+ inmsg = True
+ message.append(line)
+ return (node, user, date, '\n'.join(message), parents)
+
+ def log(self, user, date, message, p1, p2, merge=False):
+ '''journal changelog metadata for later recover'''
+
+ if not os.path.isdir(self.path):
+ os.mkdir(self.path)
+ fp = self.opener('journal', 'w')
+ fp.write('# User %s\n' % user)
+ fp.write('# Date %s\n' % date)
+ fp.write('# Node ID %s\n' % revlog.hex(p2))
+ fp.write('# Parent ' + revlog.hex(p1) + '\n')
+ if merge:
+ fp.write('# Parent ' + revlog.hex(p2) + '\n')
+ fp.write(message.rstrip() + '\n')
+ fp.close()
+
+ def readlog(self):
+ return self.parselog(self.opener('journal'))
+
+ def unlog(self):
+ '''remove changelog journal'''
+ absdst = os.path.join(self.path, 'journal')
+ if os.path.exists(absdst):
+ os.unlink(absdst)
+
+ def transplantfilter(self, repo, source, root):
+ def matchfn(node):
+ if self.applied(repo, node, root):
+ return False
+ if source.changelog.parents(node)[1] != revlog.nullid:
+ return False
+ extra = source.changelog.read(node)[5]
+ cnode = extra.get('transplant_source')
+ if cnode and self.applied(repo, cnode, root):
+ return False
+ return True
+
+ return matchfn
+
+def hasnode(repo, node):
+ try:
+ return repo.changelog.rev(node) != None
+ except error.RevlogError:
+ return False
+
+def browserevs(ui, repo, nodes, opts):
+ '''interactively transplant changesets'''
+ def browsehelp(ui):
+ ui.write('y: transplant this changeset\n'
+ 'n: skip this changeset\n'
+ 'm: merge at this changeset\n'
+ 'p: show patch\n'
+ 'c: commit selected changesets\n'
+ 'q: cancel transplant\n'
+ '?: show this help\n')
+
+ displayer = cmdutil.show_changeset(ui, repo, opts)
+ transplants = []
+ merges = []
+ for node in nodes:
+ displayer.show(repo[node])
+ action = None
+ while not action:
+ action = ui.prompt(_('apply changeset? [ynmpcq?]:'))
+ if action == '?':
+ browsehelp(ui)
+ action = None
+ elif action == 'p':
+ parent = repo.changelog.parents(node)[0]
+ for chunk in patch.diff(repo, parent, node):
+ ui.write(chunk)
+ action = None
+ elif action not in ('y', 'n', 'm', 'c', 'q'):
+ ui.write('no such option\n')
+ action = None
+ if action == 'y':
+ transplants.append(node)
+ elif action == 'm':
+ merges.append(node)
+ elif action == 'c':
+ break
+ elif action == 'q':
+ transplants = ()
+ merges = ()
+ break
+ return (transplants, merges)
+
+def transplant(ui, repo, *revs, **opts):
+ '''transplant changesets from another branch
+
+ Selected changesets will be applied on top of the current working
+ directory with the log of the original changeset. If --log is
+ specified, log messages will have a comment appended of the form::
+
+ (transplanted from CHANGESETHASH)
+
+ You can rewrite the changelog message with the --filter option.
+ Its argument will be invoked with the current changelog message as
+ $1 and the patch as $2.
+
+ If --source/-s is specified, selects changesets from the named
+ repository. If --branch/-b is specified, selects changesets from
+ the branch holding the named revision, up to that revision. If
+ --all/-a is specified, all changesets on the branch will be
+ transplanted, otherwise you will be prompted to select the
+ changesets you want.
+
+ hg transplant --branch REVISION --all will rebase the selected
+ branch (up to the named revision) onto your current working
+ directory.
+
+ You can optionally mark selected transplanted changesets as merge
+ changesets. You will not be prompted to transplant any ancestors
+ of a merged transplant, and you can merge descendants of them
+ normally instead of transplanting them.
+
+ If no merges or revisions are provided, hg transplant will start
+ an interactive changeset browser.
+
+ If a changeset application fails, you can fix the merge by hand
+ and then resume where you left off by calling hg transplant
+ --continue/-c.
+ '''
+ def getremotechanges(repo, url):
+ sourcerepo = ui.expandpath(url)
+ source = hg.repository(ui, sourcerepo)
+ common, incoming, rheads = repo.findcommonincoming(source, force=True)
+ if not incoming:
+ return (source, None, None)
+
+ bundle = None
+ if not source.local():
+ if source.capable('changegroupsubset'):
+ cg = source.changegroupsubset(incoming, rheads, 'incoming')
+ else:
+ cg = source.changegroup(incoming, 'incoming')
+ bundle = changegroup.writebundle(cg, None, 'HG10UN')
+ source = bundlerepo.bundlerepository(ui, repo.root, bundle)
+
+ return (source, incoming, bundle)
+
+ def incwalk(repo, incoming, branches, match=util.always):
+ if not branches:
+ branches=None
+ for node in repo.changelog.nodesbetween(incoming, branches)[0]:
+ if match(node):
+ yield node
+
+ def transplantwalk(repo, root, branches, match=util.always):
+ if not branches:
+ branches = repo.heads()
+ ancestors = []
+ for branch in branches:
+ ancestors.append(repo.changelog.ancestor(root, branch))
+ for node in repo.changelog.nodesbetween(ancestors, branches)[0]:
+ if match(node):
+ yield node
+
+ def checkopts(opts, revs):
+ if opts.get('continue'):
+ if filter(lambda opt: opts.get(opt), ('branch', 'all', 'merge')):
+ raise util.Abort(_('--continue is incompatible with '
+ 'branch, all or merge'))
+ return
+ if not (opts.get('source') or revs or
+ opts.get('merge') or opts.get('branch')):
+ raise util.Abort(_('no source URL, branch tag or revision '
+ 'list provided'))
+ if opts.get('all'):
+ if not opts.get('branch'):
+ raise util.Abort(_('--all requires a branch revision'))
+ if revs:
+ raise util.Abort(_('--all is incompatible with a '
+ 'revision list'))
+
+ checkopts(opts, revs)
+
+ if not opts.get('log'):
+ opts['log'] = ui.config('transplant', 'log')
+ if not opts.get('filter'):
+ opts['filter'] = ui.config('transplant', 'filter')
+
+ tp = transplanter(ui, repo)
+
+ p1, p2 = repo.dirstate.parents()
+ if len(repo) > 0 and p1 == revlog.nullid:
+ raise util.Abort(_('no revision checked out'))
+ if not opts.get('continue'):
+ if p2 != revlog.nullid:
+ raise util.Abort(_('outstanding uncommitted merges'))
+ m, a, r, d = repo.status()[:4]
+ if m or a or r or d:
+ raise util.Abort(_('outstanding local changes'))
+
+ bundle = None
+ source = opts.get('source')
+ if source:
+ (source, incoming, bundle) = getremotechanges(repo, source)
+ else:
+ source = repo
+
+ try:
+ if opts.get('continue'):
+ tp.resume(repo, source, opts)
+ return
+
+ tf=tp.transplantfilter(repo, source, p1)
+ if opts.get('prune'):
+ prune = [source.lookup(r)
+ for r in cmdutil.revrange(source, opts.get('prune'))]
+ matchfn = lambda x: tf(x) and x not in prune
+ else:
+ matchfn = tf
+ branches = map(source.lookup, opts.get('branch', ()))
+ merges = map(source.lookup, opts.get('merge', ()))
+ revmap = {}
+ if revs:
+ for r in cmdutil.revrange(source, revs):
+ revmap[int(r)] = source.lookup(r)
+ elif opts.get('all') or not merges:
+ if source != repo:
+ alltransplants = incwalk(source, incoming, branches,
+ match=matchfn)
+ else:
+ alltransplants = transplantwalk(source, p1, branches,
+ match=matchfn)
+ if opts.get('all'):
+ revs = alltransplants
+ else:
+ revs, newmerges = browserevs(ui, source, alltransplants, opts)
+ merges.extend(newmerges)
+ for r in revs:
+ revmap[source.changelog.rev(r)] = r
+ for r in merges:
+ revmap[source.changelog.rev(r)] = r
+
+ tp.apply(repo, source, revmap, merges, opts)
+ finally:
+ if bundle:
+ source.close()
+ os.unlink(bundle)
+
+cmdtable = {
+ "transplant":
+ (transplant,
+ [('s', 'source', '', _('pull patches from REPOSITORY')),
+ ('b', 'branch', [], _('pull patches from branch BRANCH')),
+ ('a', 'all', None, _('pull all changesets up to BRANCH')),
+ ('p', 'prune', [], _('skip over REV')),
+ ('m', 'merge', [], _('merge at REV')),
+ ('', 'log', None, _('append transplant info to log message')),
+ ('c', 'continue', None, _('continue last transplant session '
+ 'after repair')),
+ ('', 'filter', '', _('filter changesets through FILTER'))],
+ _('hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] '
+ '[-m REV] [REV]...'))
+}
diff --git a/sys/src/cmd/hg/hgext/win32mbcs.py b/sys/src/cmd/hg/hgext/win32mbcs.py
new file mode 100644
index 000000000..a707f053e
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/win32mbcs.py
@@ -0,0 +1,147 @@
+# win32mbcs.py -- MBCS filename support for Mercurial
+#
+# Copyright (c) 2008 Shun-ichi Goto <shunichi.goto@gmail.com>
+#
+# Version: 0.2
+# Author: Shun-ichi Goto <shunichi.goto@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+#
+
+'''allow the use of MBCS paths with problematic encodings
+
+Some MBCS encodings are not good for some path operations (i.e.
+splitting path, case conversion, etc.) with its encoded bytes. We call
+such a encoding (i.e. shift_jis and big5) as "problematic encoding".
+This extension can be used to fix the issue with those encodings by
+wrapping some functions to convert to Unicode string before path
+operation.
+
+This extension is useful for:
+
+- Japanese Windows users using shift_jis encoding.
+- Chinese Windows users using big5 encoding.
+- All users who use a repository with one of problematic encodings on
+ case-insensitive file system.
+
+This extension is not needed for:
+
+- Any user who use only ASCII chars in path.
+- Any user who do not use any of problematic encodings.
+
+Note that there are some limitations on using this extension:
+
+- You should use single encoding in one repository.
+- You should set same encoding for the repository by locale or
+ HGENCODING.
+
+Path encoding conversion are done between Unicode and
+encoding.encoding which is decided by Mercurial from current locale
+setting or HGENCODING.
+'''
+
+import os, sys
+from mercurial.i18n import _
+from mercurial import util, encoding
+
+def decode(arg):
+ if isinstance(arg, str):
+ uarg = arg.decode(encoding.encoding)
+ if arg == uarg.encode(encoding.encoding):
+ return uarg
+ raise UnicodeError("Not local encoding")
+ elif isinstance(arg, tuple):
+ return tuple(map(decode, arg))
+ elif isinstance(arg, list):
+ return map(decode, arg)
+ elif isinstance(arg, dict):
+ for k, v in arg.items():
+ arg[k] = decode(v)
+ return arg
+
+def encode(arg):
+ if isinstance(arg, unicode):
+ return arg.encode(encoding.encoding)
+ elif isinstance(arg, tuple):
+ return tuple(map(encode, arg))
+ elif isinstance(arg, list):
+ return map(encode, arg)
+ elif isinstance(arg, dict):
+ for k, v in arg.items():
+ arg[k] = encode(v)
+ return arg
+
+def appendsep(s):
+ # ensure the path ends with os.sep, appending it if necessary.
+ try:
+ us = decode(s)
+ except UnicodeError:
+ us = s
+ if us and us[-1] not in ':/\\':
+ s += os.sep
+ return s
+
+def wrapper(func, args, kwds):
+ # check argument is unicode, then call original
+ for arg in args:
+ if isinstance(arg, unicode):
+ return func(*args, **kwds)
+
+ try:
+ # convert arguments to unicode, call func, then convert back
+ return encode(func(*decode(args), **decode(kwds)))
+ except UnicodeError:
+ raise util.Abort(_("[win32mbcs] filename conversion failed with"
+ " %s encoding\n") % (encoding.encoding))
+
+def wrapperforlistdir(func, args, kwds):
+ # Ensure 'path' argument ends with os.sep to avoids
+ # misinterpreting last 0x5c of MBCS 2nd byte as path separator.
+ if args:
+ args = list(args)
+ args[0] = appendsep(args[0])
+ if kwds.has_key('path'):
+ kwds['path'] = appendsep(kwds['path'])
+ return func(*args, **kwds)
+
+def wrapname(name, wrapper):
+ module, name = name.rsplit('.', 1)
+ module = sys.modules[module]
+ func = getattr(module, name)
+ def f(*args, **kwds):
+ return wrapper(func, args, kwds)
+ try:
+ f.__name__ = func.__name__ # fail with python23
+ except Exception:
+ pass
+ setattr(module, name, f)
+
+# List of functions to be wrapped.
+# NOTE: os.path.dirname() and os.path.basename() are safe because
+# they use result of os.path.split()
+funcs = '''os.path.join os.path.split os.path.splitext
+ os.path.splitunc os.path.normpath os.path.normcase os.makedirs
+ mercurial.util.endswithsep mercurial.util.splitpath mercurial.util.checkcase
+ mercurial.util.fspath mercurial.windows.pconvert'''
+
+# codec and alias names of sjis and big5 to be faked.
+problematic_encodings = '''big5 big5-tw csbig5 big5hkscs big5-hkscs
+ hkscs cp932 932 ms932 mskanji ms-kanji shift_jis csshiftjis shiftjis
+ sjis s_jis shift_jis_2004 shiftjis2004 sjis_2004 sjis2004
+ shift_jisx0213 shiftjisx0213 sjisx0213 s_jisx0213 950 cp950 ms950 '''
+
+def reposetup(ui, repo):
+ # TODO: decide use of config section for this extension
+ if not os.path.supports_unicode_filenames:
+ ui.warn(_("[win32mbcs] cannot activate on this platform.\n"))
+ return
+
+ # fake is only for relevant environment.
+ if encoding.encoding.lower() in problematic_encodings.split():
+ for f in funcs.split():
+ wrapname(f, wrapper)
+ wrapname("mercurial.osutil.listdir", wrapperforlistdir)
+ ui.debug(_("[win32mbcs] activated with encoding: %s\n")
+ % encoding.encoding)
+
diff --git a/sys/src/cmd/hg/hgext/win32text.py b/sys/src/cmd/hg/hgext/win32text.py
new file mode 100644
index 000000000..2c64f1356
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/win32text.py
@@ -0,0 +1,158 @@
+# win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac users
+#
+# Copyright 2005, 2007-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''perform automatic newline conversion
+
+To perform automatic newline conversion, use::
+
+ [extensions]
+ hgext.win32text =
+ [encode]
+ ** = cleverencode:
+ # or ** = macencode:
+
+ [decode]
+ ** = cleverdecode:
+ # or ** = macdecode:
+
+If not doing conversion, to make sure you do not commit CRLF/CR by accident::
+
+ [hooks]
+ pretxncommit.crlf = python:hgext.win32text.forbidcrlf
+ # or pretxncommit.cr = python:hgext.win32text.forbidcr
+
+To do the same check on a server to prevent CRLF/CR from being
+pushed or pulled::
+
+ [hooks]
+ pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
+ # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
+'''
+
+from mercurial.i18n import _
+from mercurial.node import short
+from mercurial import util
+import re
+
+# regexp for single LF without CR preceding.
+re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
+
+newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
+filterstr = {'\r\n': 'clever', '\r': 'mac'}
+
+def checknewline(s, newline, ui=None, repo=None, filename=None):
+ # warn if already has 'newline' in repository.
+ # it might cause unexpected eol conversion.
+ # see issue 302:
+ # http://mercurial.selenic.com/bts/issue302
+ if newline in s and ui and filename and repo:
+ ui.warn(_('WARNING: %s already has %s line endings\n'
+ 'and does not need EOL conversion by the win32text plugin.\n'
+ 'Before your next commit, please reconsider your '
+ 'encode/decode settings in \nMercurial.ini or %s.\n') %
+ (filename, newlinestr[newline], repo.join('hgrc')))
+
+def dumbdecode(s, cmd, **kwargs):
+ checknewline(s, '\r\n', **kwargs)
+ # replace single LF to CRLF
+ return re_single_lf.sub('\\1\r\n', s)
+
+def dumbencode(s, cmd):
+ return s.replace('\r\n', '\n')
+
+def macdumbdecode(s, cmd, **kwargs):
+ checknewline(s, '\r', **kwargs)
+ return s.replace('\n', '\r')
+
+def macdumbencode(s, cmd):
+ return s.replace('\r', '\n')
+
+def cleverdecode(s, cmd, **kwargs):
+ if not util.binary(s):
+ return dumbdecode(s, cmd, **kwargs)
+ return s
+
+def cleverencode(s, cmd):
+ if not util.binary(s):
+ return dumbencode(s, cmd)
+ return s
+
+def macdecode(s, cmd, **kwargs):
+ if not util.binary(s):
+ return macdumbdecode(s, cmd, **kwargs)
+ return s
+
+def macencode(s, cmd):
+ if not util.binary(s):
+ return macdumbencode(s, cmd)
+ return s
+
+_filters = {
+ 'dumbdecode:': dumbdecode,
+ 'dumbencode:': dumbencode,
+ 'cleverdecode:': cleverdecode,
+ 'cleverencode:': cleverencode,
+ 'macdumbdecode:': macdumbdecode,
+ 'macdumbencode:': macdumbencode,
+ 'macdecode:': macdecode,
+ 'macencode:': macencode,
+ }
+
+def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
+ halt = False
+ seen = set()
+ # we try to walk changesets in reverse order from newest to
+ # oldest, so that if we see a file multiple times, we take the
+ # newest version as canonical. this prevents us from blocking a
+ # changegroup that contains an unacceptable commit followed later
+ # by a commit that fixes the problem.
+ tip = repo['tip']
+ for rev in xrange(len(repo)-1, repo[node].rev()-1, -1):
+ c = repo[rev]
+ for f in c.files():
+ if f in seen or f not in tip or f not in c:
+ continue
+ seen.add(f)
+ data = c[f].data()
+ if not util.binary(data) and newline in data:
+ if not halt:
+ ui.warn(_('Attempt to commit or push text file(s) '
+ 'using %s line endings\n') %
+ newlinestr[newline])
+ ui.warn(_('in %s: %s\n') % (short(c.node()), f))
+ halt = True
+ if halt and hooktype == 'pretxnchangegroup':
+ crlf = newlinestr[newline].lower()
+ filter = filterstr[newline]
+ ui.warn(_('\nTo prevent this mistake in your local repository,\n'
+ 'add to Mercurial.ini or .hg/hgrc:\n'
+ '\n'
+ '[hooks]\n'
+ 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
+ '\n'
+ 'and also consider adding:\n'
+ '\n'
+ '[extensions]\n'
+ 'hgext.win32text =\n'
+ '[encode]\n'
+ '** = %sencode:\n'
+ '[decode]\n'
+ '** = %sdecode:\n') % (crlf, crlf, filter, filter))
+ return halt
+
+def forbidcrlf(ui, repo, hooktype, node, **kwargs):
+ return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
+
+def forbidcr(ui, repo, hooktype, node, **kwargs):
+ return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
+
+def reposetup(ui, repo):
+ if not repo.local():
+ return
+ for name, fn in _filters.iteritems():
+ repo.adddatafilter(name, fn)
+
diff --git a/sys/src/cmd/hg/hgext/zeroconf/Zeroconf.py b/sys/src/cmd/hg/hgext/zeroconf/Zeroconf.py
new file mode 100644
index 000000000..33a345923
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/zeroconf/Zeroconf.py
@@ -0,0 +1,1573 @@
+""" Multicast DNS Service Discovery for Python, v0.12
+ Copyright (C) 2003, Paul Scott-Murphy
+
+ This module provides a framework for the use of DNS Service Discovery
+ using IP multicast. It has been tested against the JRendezvous
+ implementation from <a href="http://strangeberry.com">StrangeBerry</a>,
+ and against the mDNSResponder from Mac OS X 10.3.8.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""
+
+"""0.12 update - allow selection of binding interface
+ typo fix - Thanks A. M. Kuchlingi
+ removed all use of word 'Rendezvous' - this is an API change"""
+
+"""0.11 update - correction to comments for addListener method
+ support for new record types seen from OS X
+ - IPv6 address
+ - hostinfo
+ ignore unknown DNS record types
+ fixes to name decoding
+ works alongside other processes using port 5353 (e.g. on Mac OS X)
+ tested against Mac OS X 10.3.2's mDNSResponder
+ corrections to removal of list entries for service browser"""
+
+"""0.10 update - Jonathon Paisley contributed these corrections:
+ always multicast replies, even when query is unicast
+ correct a pointer encoding problem
+ can now write records in any order
+ traceback shown on failure
+ better TXT record parsing
+ server is now separate from name
+ can cancel a service browser
+
+ modified some unit tests to accommodate these changes"""
+
+"""0.09 update - remove all records on service unregistration
+ fix DOS security problem with readName"""
+
+"""0.08 update - changed licensing to LGPL"""
+
+"""0.07 update - faster shutdown on engine
+ pointer encoding of outgoing names
+ ServiceBrowser now works
+ new unit tests"""
+
+"""0.06 update - small improvements with unit tests
+ added defined exception types
+ new style objects
+ fixed hostname/interface problem
+ fixed socket timeout problem
+ fixed addServiceListener() typo bug
+ using select() for socket reads
+ tested on Debian unstable with Python 2.2.2"""
+
+"""0.05 update - ensure case insensitivty on domain names
+ support for unicast DNS queries"""
+
+"""0.04 update - added some unit tests
+ added __ne__ adjuncts where required
+ ensure names end in '.local.'
+ timeout on receiving socket for clean shutdown"""
+
+__author__ = "Paul Scott-Murphy"
+__email__ = "paul at scott dash murphy dot com"
+__version__ = "0.12"
+
+import string
+import time
+import struct
+import socket
+import threading
+import select
+import traceback
+
+__all__ = ["Zeroconf", "ServiceInfo", "ServiceBrowser"]
+
+# hook for threads
+
+globals()['_GLOBAL_DONE'] = 0
+
+# Some timing constants
+
+_UNREGISTER_TIME = 125
+_CHECK_TIME = 175
+_REGISTER_TIME = 225
+_LISTENER_TIME = 200
+_BROWSER_TIME = 500
+
+# Some DNS constants
+
+_MDNS_ADDR = '224.0.0.251'
+_MDNS_PORT = 5353;
+_DNS_PORT = 53;
+_DNS_TTL = 60 * 60; # one hour default TTL
+
+_MAX_MSG_TYPICAL = 1460 # unused
+_MAX_MSG_ABSOLUTE = 8972
+
+_FLAGS_QR_MASK = 0x8000 # query response mask
+_FLAGS_QR_QUERY = 0x0000 # query
+_FLAGS_QR_RESPONSE = 0x8000 # response
+
+_FLAGS_AA = 0x0400 # Authorative answer
+_FLAGS_TC = 0x0200 # Truncated
+_FLAGS_RD = 0x0100 # Recursion desired
+_FLAGS_RA = 0x8000 # Recursion available
+
+_FLAGS_Z = 0x0040 # Zero
+_FLAGS_AD = 0x0020 # Authentic data
+_FLAGS_CD = 0x0010 # Checking disabled
+
+_CLASS_IN = 1
+_CLASS_CS = 2
+_CLASS_CH = 3
+_CLASS_HS = 4
+_CLASS_NONE = 254
+_CLASS_ANY = 255
+_CLASS_MASK = 0x7FFF
+_CLASS_UNIQUE = 0x8000
+
+_TYPE_A = 1
+_TYPE_NS = 2
+_TYPE_MD = 3
+_TYPE_MF = 4
+_TYPE_CNAME = 5
+_TYPE_SOA = 6
+_TYPE_MB = 7
+_TYPE_MG = 8
+_TYPE_MR = 9
+_TYPE_NULL = 10
+_TYPE_WKS = 11
+_TYPE_PTR = 12
+_TYPE_HINFO = 13
+_TYPE_MINFO = 14
+_TYPE_MX = 15
+_TYPE_TXT = 16
+_TYPE_AAAA = 28
+_TYPE_SRV = 33
+_TYPE_ANY = 255
+
+# Mapping constants to names
+
+_CLASSES = { _CLASS_IN : "in",
+ _CLASS_CS : "cs",
+ _CLASS_CH : "ch",
+ _CLASS_HS : "hs",
+ _CLASS_NONE : "none",
+ _CLASS_ANY : "any" }
+
+_TYPES = { _TYPE_A : "a",
+ _TYPE_NS : "ns",
+ _TYPE_MD : "md",
+ _TYPE_MF : "mf",
+ _TYPE_CNAME : "cname",
+ _TYPE_SOA : "soa",
+ _TYPE_MB : "mb",
+ _TYPE_MG : "mg",
+ _TYPE_MR : "mr",
+ _TYPE_NULL : "null",
+ _TYPE_WKS : "wks",
+ _TYPE_PTR : "ptr",
+ _TYPE_HINFO : "hinfo",
+ _TYPE_MINFO : "minfo",
+ _TYPE_MX : "mx",
+ _TYPE_TXT : "txt",
+ _TYPE_AAAA : "quada",
+ _TYPE_SRV : "srv",
+ _TYPE_ANY : "any" }
+
+# utility functions
+
+def currentTimeMillis():
+ """Current system time in milliseconds"""
+ return time.time() * 1000
+
+# Exceptions
+
+class NonLocalNameException(Exception):
+ pass
+
+class NonUniqueNameException(Exception):
+ pass
+
+class NamePartTooLongException(Exception):
+ pass
+
+class AbstractMethodException(Exception):
+ pass
+
+class BadTypeInNameException(Exception):
+ pass
+
+# implementation classes
+
+class DNSEntry(object):
+ """A DNS entry"""
+
+ def __init__(self, name, type, clazz):
+ self.key = string.lower(name)
+ self.name = name
+ self.type = type
+ self.clazz = clazz & _CLASS_MASK
+ self.unique = (clazz & _CLASS_UNIQUE) != 0
+
+ def __eq__(self, other):
+ """Equality test on name, type, and class"""
+ if isinstance(other, DNSEntry):
+ return self.name == other.name and self.type == other.type and self.clazz == other.clazz
+ return 0
+
+ def __ne__(self, other):
+ """Non-equality test"""
+ return not self.__eq__(other)
+
+ def getClazz(self, clazz):
+ """Class accessor"""
+ try:
+ return _CLASSES[clazz]
+ except:
+ return "?(%s)" % (clazz)
+
+ def getType(self, type):
+ """Type accessor"""
+ try:
+ return _TYPES[type]
+ except:
+ return "?(%s)" % (type)
+
+ def toString(self, hdr, other):
+ """String representation with additional information"""
+ result = "%s[%s,%s" % (hdr, self.getType(self.type), self.getClazz(self.clazz))
+ if self.unique:
+ result += "-unique,"
+ else:
+ result += ","
+ result += self.name
+ if other is not None:
+ result += ",%s]" % (other)
+ else:
+ result += "]"
+ return result
+
+class DNSQuestion(DNSEntry):
+ """A DNS question entry"""
+
+ def __init__(self, name, type, clazz):
+ if not name.endswith(".local."):
+ raise NonLocalNameException(name)
+ DNSEntry.__init__(self, name, type, clazz)
+
+ def answeredBy(self, rec):
+ """Returns true if the question is answered by the record"""
+ return self.clazz == rec.clazz and (self.type == rec.type or self.type == _TYPE_ANY) and self.name == rec.name
+
+ def __repr__(self):
+ """String representation"""
+ return DNSEntry.toString(self, "question", None)
+
+
+class DNSRecord(DNSEntry):
+ """A DNS record - like a DNS entry, but has a TTL"""
+
+ def __init__(self, name, type, clazz, ttl):
+ DNSEntry.__init__(self, name, type, clazz)
+ self.ttl = ttl
+ self.created = currentTimeMillis()
+
+ def __eq__(self, other):
+ """Tests equality as per DNSRecord"""
+ if isinstance(other, DNSRecord):
+ return DNSEntry.__eq__(self, other)
+ return 0
+
+ def suppressedBy(self, msg):
+ """Returns true if any answer in a message can suffice for the
+ information held in this record."""
+ for record in msg.answers:
+ if self.suppressedByAnswer(record):
+ return 1
+ return 0
+
+ def suppressedByAnswer(self, other):
+ """Returns true if another record has same name, type and class,
+ and if its TTL is at least half of this record's."""
+ if self == other and other.ttl > (self.ttl / 2):
+ return 1
+ return 0
+
+ def getExpirationTime(self, percent):
+ """Returns the time at which this record will have expired
+ by a certain percentage."""
+ return self.created + (percent * self.ttl * 10)
+
+ def getRemainingTTL(self, now):
+ """Returns the remaining TTL in seconds."""
+ return max(0, (self.getExpirationTime(100) - now) / 1000)
+
+ def isExpired(self, now):
+ """Returns true if this record has expired."""
+ return self.getExpirationTime(100) <= now
+
+ def isStale(self, now):
+ """Returns true if this record is at least half way expired."""
+ return self.getExpirationTime(50) <= now
+
+ def resetTTL(self, other):
+ """Sets this record's TTL and created time to that of
+ another record."""
+ self.created = other.created
+ self.ttl = other.ttl
+
+ def write(self, out):
+ """Abstract method"""
+ raise AbstractMethodException
+
+ def toString(self, other):
+ """String representation with addtional information"""
+ arg = "%s/%s,%s" % (self.ttl, self.getRemainingTTL(currentTimeMillis()), other)
+ return DNSEntry.toString(self, "record", arg)
+
+class DNSAddress(DNSRecord):
+ """A DNS address record"""
+
+ def __init__(self, name, type, clazz, ttl, address):
+ DNSRecord.__init__(self, name, type, clazz, ttl)
+ self.address = address
+
+ def write(self, out):
+ """Used in constructing an outgoing packet"""
+ out.writeString(self.address, len(self.address))
+
+ def __eq__(self, other):
+ """Tests equality on address"""
+ if isinstance(other, DNSAddress):
+ return self.address == other.address
+ return 0
+
+ def __repr__(self):
+ """String representation"""
+ try:
+ return socket.inet_ntoa(self.address)
+ except:
+ return self.address
+
+class DNSHinfo(DNSRecord):
+ """A DNS host information record"""
+
+ def __init__(self, name, type, clazz, ttl, cpu, os):
+ DNSRecord.__init__(self, name, type, clazz, ttl)
+ self.cpu = cpu
+ self.os = os
+
+ def write(self, out):
+ """Used in constructing an outgoing packet"""
+ out.writeString(self.cpu, len(self.cpu))
+ out.writeString(self.os, len(self.os))
+
+ def __eq__(self, other):
+ """Tests equality on cpu and os"""
+ if isinstance(other, DNSHinfo):
+ return self.cpu == other.cpu and self.os == other.os
+ return 0
+
+ def __repr__(self):
+ """String representation"""
+ return self.cpu + " " + self.os
+
+class DNSPointer(DNSRecord):
+ """A DNS pointer record"""
+
+ def __init__(self, name, type, clazz, ttl, alias):
+ DNSRecord.__init__(self, name, type, clazz, ttl)
+ self.alias = alias
+
+ def write(self, out):
+ """Used in constructing an outgoing packet"""
+ out.writeName(self.alias)
+
+ def __eq__(self, other):
+ """Tests equality on alias"""
+ if isinstance(other, DNSPointer):
+ return self.alias == other.alias
+ return 0
+
+ def __repr__(self):
+ """String representation"""
+ return self.toString(self.alias)
+
+class DNSText(DNSRecord):
+ """A DNS text record"""
+
+ def __init__(self, name, type, clazz, ttl, text):
+ DNSRecord.__init__(self, name, type, clazz, ttl)
+ self.text = text
+
+ def write(self, out):
+ """Used in constructing an outgoing packet"""
+ out.writeString(self.text, len(self.text))
+
+ def __eq__(self, other):
+ """Tests equality on text"""
+ if isinstance(other, DNSText):
+ return self.text == other.text
+ return 0
+
+ def __repr__(self):
+ """String representation"""
+ if len(self.text) > 10:
+ return self.toString(self.text[:7] + "...")
+ else:
+ return self.toString(self.text)
+
+class DNSService(DNSRecord):
+ """A DNS service record"""
+
+ def __init__(self, name, type, clazz, ttl, priority, weight, port, server):
+ DNSRecord.__init__(self, name, type, clazz, ttl)
+ self.priority = priority
+ self.weight = weight
+ self.port = port
+ self.server = server
+
+ def write(self, out):
+ """Used in constructing an outgoing packet"""
+ out.writeShort(self.priority)
+ out.writeShort(self.weight)
+ out.writeShort(self.port)
+ out.writeName(self.server)
+
+ def __eq__(self, other):
+ """Tests equality on priority, weight, port and server"""
+ if isinstance(other, DNSService):
+ return self.priority == other.priority and self.weight == other.weight and self.port == other.port and self.server == other.server
+ return 0
+
+ def __repr__(self):
+ """String representation"""
+ return self.toString("%s:%s" % (self.server, self.port))
+
+class DNSIncoming(object):
+ """Object representation of an incoming DNS packet"""
+
+ def __init__(self, data):
+ """Constructor from string holding bytes of packet"""
+ self.offset = 0
+ self.data = data
+ self.questions = []
+ self.answers = []
+ self.numQuestions = 0
+ self.numAnswers = 0
+ self.numAuthorities = 0
+ self.numAdditionals = 0
+
+ self.readHeader()
+ self.readQuestions()
+ self.readOthers()
+
+ def readHeader(self):
+ """Reads header portion of packet"""
+ format = '!HHHHHH'
+ length = struct.calcsize(format)
+ info = struct.unpack(format, self.data[self.offset:self.offset+length])
+ self.offset += length
+
+ self.id = info[0]
+ self.flags = info[1]
+ self.numQuestions = info[2]
+ self.numAnswers = info[3]
+ self.numAuthorities = info[4]
+ self.numAdditionals = info[5]
+
+ def readQuestions(self):
+ """Reads questions section of packet"""
+ format = '!HH'
+ length = struct.calcsize(format)
+ for i in range(0, self.numQuestions):
+ name = self.readName()
+ info = struct.unpack(format, self.data[self.offset:self.offset+length])
+ self.offset += length
+
+ try:
+ question = DNSQuestion(name, info[0], info[1])
+ self.questions.append(question)
+ except NonLocalNameException:
+ pass
+
+ def readInt(self):
+ """Reads an integer from the packet"""
+ format = '!I'
+ length = struct.calcsize(format)
+ info = struct.unpack(format, self.data[self.offset:self.offset+length])
+ self.offset += length
+ return info[0]
+
+ def readCharacterString(self):
+ """Reads a character string from the packet"""
+ length = ord(self.data[self.offset])
+ self.offset += 1
+ return self.readString(length)
+
+ def readString(self, len):
+ """Reads a string of a given length from the packet"""
+ format = '!' + str(len) + 's'
+ length = struct.calcsize(format)
+ info = struct.unpack(format, self.data[self.offset:self.offset+length])
+ self.offset += length
+ return info[0]
+
+ def readUnsignedShort(self):
+ """Reads an unsigned short from the packet"""
+ format = '!H'
+ length = struct.calcsize(format)
+ info = struct.unpack(format, self.data[self.offset:self.offset+length])
+ self.offset += length
+ return info[0]
+
+ def readOthers(self):
+ """Reads the answers, authorities and additionals section of the packet"""
+ format = '!HHiH'
+ length = struct.calcsize(format)
+ n = self.numAnswers + self.numAuthorities + self.numAdditionals
+ for i in range(0, n):
+ domain = self.readName()
+ info = struct.unpack(format, self.data[self.offset:self.offset+length])
+ self.offset += length
+
+ rec = None
+ if info[0] == _TYPE_A:
+ rec = DNSAddress(domain, info[0], info[1], info[2], self.readString(4))
+ elif info[0] == _TYPE_CNAME or info[0] == _TYPE_PTR:
+ rec = DNSPointer(domain, info[0], info[1], info[2], self.readName())
+ elif info[0] == _TYPE_TXT:
+ rec = DNSText(domain, info[0], info[1], info[2], self.readString(info[3]))
+ elif info[0] == _TYPE_SRV:
+ rec = DNSService(domain, info[0], info[1], info[2], self.readUnsignedShort(), self.readUnsignedShort(), self.readUnsignedShort(), self.readName())
+ elif info[0] == _TYPE_HINFO:
+ rec = DNSHinfo(domain, info[0], info[1], info[2], self.readCharacterString(), self.readCharacterString())
+ elif info[0] == _TYPE_AAAA:
+ rec = DNSAddress(domain, info[0], info[1], info[2], self.readString(16))
+ else:
+ # Try to ignore types we don't know about
+ # this may mean the rest of the name is
+ # unable to be parsed, and may show errors
+ # so this is left for debugging. New types
+ # encountered need to be parsed properly.
+ #
+ #print "UNKNOWN TYPE = " + str(info[0])
+ #raise BadTypeInNameException
+ pass
+
+ if rec is not None:
+ self.answers.append(rec)
+
+ def isQuery(self):
+ """Returns true if this is a query"""
+ return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_QUERY
+
+ def isResponse(self):
+ """Returns true if this is a response"""
+ return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_RESPONSE
+
+ def readUTF(self, offset, len):
+ """Reads a UTF-8 string of a given length from the packet"""
+ result = self.data[offset:offset+len].decode('utf-8')
+ return result
+
+ def readName(self):
+ """Reads a domain name from the packet"""
+ result = ''
+ off = self.offset
+ next = -1
+ first = off
+
+ while 1:
+ len = ord(self.data[off])
+ off += 1
+ if len == 0:
+ break
+ t = len & 0xC0
+ if t == 0x00:
+ result = ''.join((result, self.readUTF(off, len) + '.'))
+ off += len
+ elif t == 0xC0:
+ if next < 0:
+ next = off + 1
+ off = ((len & 0x3F) << 8) | ord(self.data[off])
+ if off >= first:
+ raise "Bad domain name (circular) at " + str(off)
+ first = off
+ else:
+ raise "Bad domain name at " + str(off)
+
+ if next >= 0:
+ self.offset = next
+ else:
+ self.offset = off
+
+ return result
+
+
+class DNSOutgoing(object):
+ """Object representation of an outgoing packet"""
+
+ def __init__(self, flags, multicast = 1):
+ self.finished = 0
+ self.id = 0
+ self.multicast = multicast
+ self.flags = flags
+ self.names = {}
+ self.data = []
+ self.size = 12
+
+ self.questions = []
+ self.answers = []
+ self.authorities = []
+ self.additionals = []
+
+ def addQuestion(self, record):
+ """Adds a question"""
+ self.questions.append(record)
+
+ def addAnswer(self, inp, record):
+ """Adds an answer"""
+ if not record.suppressedBy(inp):
+ self.addAnswerAtTime(record, 0)
+
+ def addAnswerAtTime(self, record, now):
+ """Adds an answer if if does not expire by a certain time"""
+ if record is not None:
+ if now == 0 or not record.isExpired(now):
+ self.answers.append((record, now))
+
+ def addAuthorativeAnswer(self, record):
+ """Adds an authoritative answer"""
+ self.authorities.append(record)
+
+ def addAdditionalAnswer(self, record):
+ """Adds an additional answer"""
+ self.additionals.append(record)
+
+ def writeByte(self, value):
+ """Writes a single byte to the packet"""
+ format = '!c'
+ self.data.append(struct.pack(format, chr(value)))
+ self.size += 1
+
+ def insertShort(self, index, value):
+ """Inserts an unsigned short in a certain position in the packet"""
+ format = '!H'
+ self.data.insert(index, struct.pack(format, value))
+ self.size += 2
+
+ def writeShort(self, value):
+ """Writes an unsigned short to the packet"""
+ format = '!H'
+ self.data.append(struct.pack(format, value))
+ self.size += 2
+
+ def writeInt(self, value):
+ """Writes an unsigned integer to the packet"""
+ format = '!I'
+ self.data.append(struct.pack(format, int(value)))
+ self.size += 4
+
+ def writeString(self, value, length):
+ """Writes a string to the packet"""
+ format = '!' + str(length) + 's'
+ self.data.append(struct.pack(format, value))
+ self.size += length
+
+ def writeUTF(self, s):
+ """Writes a UTF-8 string of a given length to the packet"""
+ utfstr = s.encode('utf-8')
+ length = len(utfstr)
+ if length > 64:
+ raise NamePartTooLongException
+ self.writeByte(length)
+ self.writeString(utfstr, length)
+
+ def writeName(self, name):
+ """Writes a domain name to the packet"""
+
+ try:
+ # Find existing instance of this name in packet
+ #
+ index = self.names[name]
+ except KeyError:
+ # No record of this name already, so write it
+ # out as normal, recording the location of the name
+ # for future pointers to it.
+ #
+ self.names[name] = self.size
+ parts = name.split('.')
+ if parts[-1] == '':
+ parts = parts[:-1]
+ for part in parts:
+ self.writeUTF(part)
+ self.writeByte(0)
+ return
+
+ # An index was found, so write a pointer to it
+ #
+ self.writeByte((index >> 8) | 0xC0)
+ self.writeByte(index)
+
+ def writeQuestion(self, question):
+ """Writes a question to the packet"""
+ self.writeName(question.name)
+ self.writeShort(question.type)
+ self.writeShort(question.clazz)
+
+ def writeRecord(self, record, now):
+ """Writes a record (answer, authoritative answer, additional) to
+ the packet"""
+ self.writeName(record.name)
+ self.writeShort(record.type)
+ if record.unique and self.multicast:
+ self.writeShort(record.clazz | _CLASS_UNIQUE)
+ else:
+ self.writeShort(record.clazz)
+ if now == 0:
+ self.writeInt(record.ttl)
+ else:
+ self.writeInt(record.getRemainingTTL(now))
+ index = len(self.data)
+ # Adjust size for the short we will write before this record
+ #
+ self.size += 2
+ record.write(self)
+ self.size -= 2
+
+ length = len(''.join(self.data[index:]))
+ self.insertShort(index, length) # Here is the short we adjusted for
+
+ def packet(self):
+ """Returns a string containing the packet's bytes
+
+ No further parts should be added to the packet once this
+ is done."""
+ if not self.finished:
+ self.finished = 1
+ for question in self.questions:
+ self.writeQuestion(question)
+ for answer, time in self.answers:
+ self.writeRecord(answer, time)
+ for authority in self.authorities:
+ self.writeRecord(authority, 0)
+ for additional in self.additionals:
+ self.writeRecord(additional, 0)
+
+ self.insertShort(0, len(self.additionals))
+ self.insertShort(0, len(self.authorities))
+ self.insertShort(0, len(self.answers))
+ self.insertShort(0, len(self.questions))
+ self.insertShort(0, self.flags)
+ if self.multicast:
+ self.insertShort(0, 0)
+ else:
+ self.insertShort(0, self.id)
+ return ''.join(self.data)
+
+
+class DNSCache(object):
+ """A cache of DNS entries"""
+
+ def __init__(self):
+ self.cache = {}
+
+ def add(self, entry):
+ """Adds an entry"""
+ try:
+ list = self.cache[entry.key]
+ except:
+ list = self.cache[entry.key] = []
+ list.append(entry)
+
+ def remove(self, entry):
+ """Removes an entry"""
+ try:
+ list = self.cache[entry.key]
+ list.remove(entry)
+ except:
+ pass
+
+ def get(self, entry):
+ """Gets an entry by key. Will return None if there is no
+ matching entry."""
+ try:
+ list = self.cache[entry.key]
+ return list[list.index(entry)]
+ except:
+ return None
+
+ def getByDetails(self, name, type, clazz):
+ """Gets an entry by details. Will return None if there is
+ no matching entry."""
+ entry = DNSEntry(name, type, clazz)
+ return self.get(entry)
+
+ def entriesWithName(self, name):
+ """Returns a list of entries whose key matches the name."""
+ try:
+ return self.cache[name]
+ except:
+ return []
+
+ def entries(self):
+ """Returns a list of all entries"""
+ def add(x, y): return x+y
+ try:
+ return reduce(add, self.cache.values())
+ except:
+ return []
+
+
+class Engine(threading.Thread):
+ """An engine wraps read access to sockets, allowing objects that
+ need to receive data from sockets to be called back when the
+ sockets are ready.
+
+ A reader needs a handle_read() method, which is called when the socket
+ it is interested in is ready for reading.
+
+ Writers are not implemented here, because we only send short
+ packets.
+ """
+
+ def __init__(self, zeroconf):
+ threading.Thread.__init__(self)
+ self.zeroconf = zeroconf
+ self.readers = {} # maps socket to reader
+ self.timeout = 5
+ self.condition = threading.Condition()
+ self.start()
+
+ def run(self):
+ while not globals()['_GLOBAL_DONE']:
+ rs = self.getReaders()
+ if len(rs) == 0:
+ # No sockets to manage, but we wait for the timeout
+ # or addition of a socket
+ #
+ self.condition.acquire()
+ self.condition.wait(self.timeout)
+ self.condition.release()
+ else:
+ try:
+ rr, wr, er = select.select(rs, [], [], self.timeout)
+ for socket in rr:
+ try:
+ self.readers[socket].handle_read()
+ except:
+ traceback.print_exc()
+ except:
+ pass
+
+ def getReaders(self):
+ self.condition.acquire()
+ result = self.readers.keys()
+ self.condition.release()
+ return result
+
+ def addReader(self, reader, socket):
+ self.condition.acquire()
+ self.readers[socket] = reader
+ self.condition.notify()
+ self.condition.release()
+
+ def delReader(self, socket):
+ self.condition.acquire()
+ del(self.readers[socket])
+ self.condition.notify()
+ self.condition.release()
+
+ def notify(self):
+ self.condition.acquire()
+ self.condition.notify()
+ self.condition.release()
+
+class Listener(object):
+ """A Listener is used by this module to listen on the multicast
+ group to which DNS messages are sent, allowing the implementation
+ to cache information as it arrives.
+
+ It requires registration with an Engine object in order to have
+ the read() method called when a socket is availble for reading."""
+
+ def __init__(self, zeroconf):
+ self.zeroconf = zeroconf
+ self.zeroconf.engine.addReader(self, self.zeroconf.socket)
+
+ def handle_read(self):
+ data, (addr, port) = self.zeroconf.socket.recvfrom(_MAX_MSG_ABSOLUTE)
+ self.data = data
+ msg = DNSIncoming(data)
+ if msg.isQuery():
+ # Always multicast responses
+ #
+ if port == _MDNS_PORT:
+ self.zeroconf.handleQuery(msg, _MDNS_ADDR, _MDNS_PORT)
+ # If it's not a multicast query, reply via unicast
+ # and multicast
+ #
+ elif port == _DNS_PORT:
+ self.zeroconf.handleQuery(msg, addr, port)
+ self.zeroconf.handleQuery(msg, _MDNS_ADDR, _MDNS_PORT)
+ else:
+ self.zeroconf.handleResponse(msg)
+
+
+class Reaper(threading.Thread):
+ """A Reaper is used by this module to remove cache entries that
+ have expired."""
+
+ def __init__(self, zeroconf):
+ threading.Thread.__init__(self)
+ self.zeroconf = zeroconf
+ self.start()
+
+ def run(self):
+ while 1:
+ self.zeroconf.wait(10 * 1000)
+ if globals()['_GLOBAL_DONE']:
+ return
+ now = currentTimeMillis()
+ for record in self.zeroconf.cache.entries():
+ if record.isExpired(now):
+ self.zeroconf.updateRecord(now, record)
+ self.zeroconf.cache.remove(record)
+
+
+class ServiceBrowser(threading.Thread):
+ """Used to browse for a service of a specific type.
+
+ The listener object will have its addService() and
+ removeService() methods called when this browser
+ discovers changes in the services availability."""
+
+ def __init__(self, zeroconf, type, listener):
+ """Creates a browser for a specific type"""
+ threading.Thread.__init__(self)
+ self.zeroconf = zeroconf
+ self.type = type
+ self.listener = listener
+ self.services = {}
+ self.nextTime = currentTimeMillis()
+ self.delay = _BROWSER_TIME
+ self.list = []
+
+ self.done = 0
+
+ self.zeroconf.addListener(self, DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN))
+ self.start()
+
+ def updateRecord(self, zeroconf, now, record):
+ """Callback invoked by Zeroconf when new information arrives.
+
+ Updates information required by browser in the Zeroconf cache."""
+ if record.type == _TYPE_PTR and record.name == self.type:
+ expired = record.isExpired(now)
+ try:
+ oldrecord = self.services[record.alias.lower()]
+ if not expired:
+ oldrecord.resetTTL(record)
+ else:
+ del(self.services[record.alias.lower()])
+ callback = lambda x: self.listener.removeService(x, self.type, record.alias)
+ self.list.append(callback)
+ return
+ except:
+ if not expired:
+ self.services[record.alias.lower()] = record
+ callback = lambda x: self.listener.addService(x, self.type, record.alias)
+ self.list.append(callback)
+
+ expires = record.getExpirationTime(75)
+ if expires < self.nextTime:
+ self.nextTime = expires
+
+ def cancel(self):
+ self.done = 1
+ self.zeroconf.notifyAll()
+
+ def run(self):
+ while 1:
+ event = None
+ now = currentTimeMillis()
+ if len(self.list) == 0 and self.nextTime > now:
+ self.zeroconf.wait(self.nextTime - now)
+ if globals()['_GLOBAL_DONE'] or self.done:
+ return
+ now = currentTimeMillis()
+
+ if self.nextTime <= now:
+ out = DNSOutgoing(_FLAGS_QR_QUERY)
+ out.addQuestion(DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN))
+ for record in self.services.values():
+ if not record.isExpired(now):
+ out.addAnswerAtTime(record, now)
+ self.zeroconf.send(out)
+ self.nextTime = now + self.delay
+ self.delay = min(20 * 1000, self.delay * 2)
+
+ if len(self.list) > 0:
+ event = self.list.pop(0)
+
+ if event is not None:
+ event(self.zeroconf)
+
+
+class ServiceInfo(object):
+ """Service information"""
+
+ def __init__(self, type, name, address=None, port=None, weight=0, priority=0, properties=None, server=None):
+ """Create a service description.
+
+ type: fully qualified service type name
+ name: fully qualified service name
+ address: IP address as unsigned short, network byte order
+ port: port that the service runs on
+ weight: weight of the service
+ priority: priority of the service
+ properties: dictionary of properties (or a string holding the bytes for the text field)
+ server: fully qualified name for service host (defaults to name)"""
+
+ if not name.endswith(type):
+ raise BadTypeInNameException
+ self.type = type
+ self.name = name
+ self.address = address
+ self.port = port
+ self.weight = weight
+ self.priority = priority
+ if server:
+ self.server = server
+ else:
+ self.server = name
+ self.setProperties(properties)
+
+ def setProperties(self, properties):
+ """Sets properties and text of this info from a dictionary"""
+ if isinstance(properties, dict):
+ self.properties = properties
+ list = []
+ result = ''
+ for key in properties:
+ value = properties[key]
+ if value is None:
+ suffix = ''.encode('utf-8')
+ elif isinstance(value, str):
+ suffix = value.encode('utf-8')
+ elif isinstance(value, int):
+ if value:
+ suffix = 'true'
+ else:
+ suffix = 'false'
+ else:
+ suffix = ''.encode('utf-8')
+ list.append('='.join((key, suffix)))
+ for item in list:
+ result = ''.join((result, struct.pack('!c', chr(len(item))), item))
+ self.text = result
+ else:
+ self.text = properties
+
+ def setText(self, text):
+ """Sets properties and text given a text field"""
+ self.text = text
+ try:
+ result = {}
+ end = len(text)
+ index = 0
+ strs = []
+ while index < end:
+ length = ord(text[index])
+ index += 1
+ strs.append(text[index:index+length])
+ index += length
+
+ for s in strs:
+ eindex = s.find('=')
+ if eindex == -1:
+ # No equals sign at all
+ key = s
+ value = 0
+ else:
+ key = s[:eindex]
+ value = s[eindex+1:]
+ if value == 'true':
+ value = 1
+ elif value == 'false' or not value:
+ value = 0
+
+ # Only update non-existent properties
+ if key and result.get(key) == None:
+ result[key] = value
+
+ self.properties = result
+ except:
+ traceback.print_exc()
+ self.properties = None
+
+ def getType(self):
+ """Type accessor"""
+ return self.type
+
+ def getName(self):
+ """Name accessor"""
+ if self.type is not None and self.name.endswith("." + self.type):
+ return self.name[:len(self.name) - len(self.type) - 1]
+ return self.name
+
+ def getAddress(self):
+ """Address accessor"""
+ return self.address
+
+ def getPort(self):
+ """Port accessor"""
+ return self.port
+
+ def getPriority(self):
+ """Pirority accessor"""
+ return self.priority
+
+ def getWeight(self):
+ """Weight accessor"""
+ return self.weight
+
+ def getProperties(self):
+ """Properties accessor"""
+ return self.properties
+
+ def getText(self):
+ """Text accessor"""
+ return self.text
+
+ def getServer(self):
+ """Server accessor"""
+ return self.server
+
+ def updateRecord(self, zeroconf, now, record):
+ """Updates service information from a DNS record"""
+ if record is not None and not record.isExpired(now):
+ if record.type == _TYPE_A:
+ #if record.name == self.name:
+ if record.name == self.server:
+ self.address = record.address
+ elif record.type == _TYPE_SRV:
+ if record.name == self.name:
+ self.server = record.server
+ self.port = record.port
+ self.weight = record.weight
+ self.priority = record.priority
+ #self.address = None
+ self.updateRecord(zeroconf, now, zeroconf.cache.getByDetails(self.server, _TYPE_A, _CLASS_IN))
+ elif record.type == _TYPE_TXT:
+ if record.name == self.name:
+ self.setText(record.text)
+
+ def request(self, zeroconf, timeout):
+ """Returns true if the service could be discovered on the
+ network, and updates this object with details discovered.
+ """
+ now = currentTimeMillis()
+ delay = _LISTENER_TIME
+ next = now + delay
+ last = now + timeout
+ result = 0
+ try:
+ zeroconf.addListener(self, DNSQuestion(self.name, _TYPE_ANY, _CLASS_IN))
+ while self.server is None or self.address is None or self.text is None:
+ if last <= now:
+ return 0
+ if next <= now:
+ out = DNSOutgoing(_FLAGS_QR_QUERY)
+ out.addQuestion(DNSQuestion(self.name, _TYPE_SRV, _CLASS_IN))
+ out.addAnswerAtTime(zeroconf.cache.getByDetails(self.name, _TYPE_SRV, _CLASS_IN), now)
+ out.addQuestion(DNSQuestion(self.name, _TYPE_TXT, _CLASS_IN))
+ out.addAnswerAtTime(zeroconf.cache.getByDetails(self.name, _TYPE_TXT, _CLASS_IN), now)
+ if self.server is not None:
+ out.addQuestion(DNSQuestion(self.server, _TYPE_A, _CLASS_IN))
+ out.addAnswerAtTime(zeroconf.cache.getByDetails(self.server, _TYPE_A, _CLASS_IN), now)
+ zeroconf.send(out)
+ next = now + delay
+ delay = delay * 2
+
+ zeroconf.wait(min(next, last) - now)
+ now = currentTimeMillis()
+ result = 1
+ finally:
+ zeroconf.removeListener(self)
+
+ return result
+
+ def __eq__(self, other):
+ """Tests equality of service name"""
+ if isinstance(other, ServiceInfo):
+ return other.name == self.name
+ return 0
+
+ def __ne__(self, other):
+ """Non-equality test"""
+ return not self.__eq__(other)
+
+ def __repr__(self):
+ """String representation"""
+ result = "service[%s,%s:%s," % (self.name, socket.inet_ntoa(self.getAddress()), self.port)
+ if self.text is None:
+ result += "None"
+ else:
+ if len(self.text) < 20:
+ result += self.text
+ else:
+ result += self.text[:17] + "..."
+ result += "]"
+ return result
+
+
+class Zeroconf(object):
+ """Implementation of Zeroconf Multicast DNS Service Discovery
+
+ Supports registration, unregistration, queries and browsing.
+ """
+ def __init__(self, bindaddress=None):
+ """Creates an instance of the Zeroconf class, establishing
+ multicast communications, listening and reaping threads."""
+ globals()['_GLOBAL_DONE'] = 0
+ if bindaddress is None:
+ self.intf = socket.gethostbyname(socket.gethostname())
+ else:
+ self.intf = bindaddress
+ self.group = ('', _MDNS_PORT)
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ try:
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
+ except:
+ # SO_REUSEADDR should be equivalent to SO_REUSEPORT for
+ # multicast UDP sockets (p 731, "TCP/IP Illustrated,
+ # Volume 2"), but some BSD-derived systems require
+ # SO_REUSEPORT to be specified explicity. Also, not all
+ # versions of Python have SO_REUSEPORT available. So
+ # if you're on a BSD-based system, and haven't upgraded
+ # to Python 2.3 yet, you may find this library doesn't
+ # work as expected.
+ #
+ pass
+ self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 255)
+ self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
+ try:
+ self.socket.bind(self.group)
+ except:
+ # Some versions of linux raise an exception even though
+ # the SO_REUSE* options have been set, so ignore it
+ #
+ pass
+ #self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(self.intf) + socket.inet_aton('0.0.0.0'))
+ self.socket.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'))
+
+ self.listeners = []
+ self.browsers = []
+ self.services = {}
+ self.servicetypes = {}
+
+ self.cache = DNSCache()
+
+ self.condition = threading.Condition()
+
+ self.engine = Engine(self)
+ self.listener = Listener(self)
+ self.reaper = Reaper(self)
+
+ def isLoopback(self):
+ return self.intf.startswith("127.0.0.1")
+
+ def isLinklocal(self):
+ return self.intf.startswith("169.254.")
+
+ def wait(self, timeout):
+ """Calling thread waits for a given number of milliseconds or
+ until notified."""
+ self.condition.acquire()
+ self.condition.wait(timeout/1000)
+ self.condition.release()
+
+ def notifyAll(self):
+ """Notifies all waiting threads"""
+ self.condition.acquire()
+ self.condition.notifyAll()
+ self.condition.release()
+
+ def getServiceInfo(self, type, name, timeout=3000):
+ """Returns network's service information for a particular
+ name and type, or None if no service matches by the timeout,
+ which defaults to 3 seconds."""
+ info = ServiceInfo(type, name)
+ if info.request(self, timeout):
+ return info
+ return None
+
+ def addServiceListener(self, type, listener):
+ """Adds a listener for a particular service type. This object
+ will then have its updateRecord method called when information
+ arrives for that type."""
+ self.removeServiceListener(listener)
+ self.browsers.append(ServiceBrowser(self, type, listener))
+
+ def removeServiceListener(self, listener):
+ """Removes a listener from the set that is currently listening."""
+ for browser in self.browsers:
+ if browser.listener == listener:
+ browser.cancel()
+ del(browser)
+
+ def registerService(self, info, ttl=_DNS_TTL):
+ """Registers service information to the network with a default TTL
+ of 60 seconds. Zeroconf will then respond to requests for
+ information for that service. The name of the service may be
+ changed if needed to make it unique on the network."""
+ self.checkService(info)
+ self.services[info.name.lower()] = info
+ if self.servicetypes.has_key(info.type):
+ self.servicetypes[info.type]+=1
+ else:
+ self.servicetypes[info.type]=1
+ now = currentTimeMillis()
+ nextTime = now
+ i = 0
+ while i < 3:
+ if now < nextTime:
+ self.wait(nextTime - now)
+ now = currentTimeMillis()
+ continue
+ out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
+ out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, ttl, info.name), 0)
+ out.addAnswerAtTime(DNSService(info.name, _TYPE_SRV, _CLASS_IN, ttl, info.priority, info.weight, info.port, info.server), 0)
+ out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, _CLASS_IN, ttl, info.text), 0)
+ if info.address:
+ out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, _CLASS_IN, ttl, info.address), 0)
+ self.send(out)
+ i += 1
+ nextTime += _REGISTER_TIME
+
+ def unregisterService(self, info):
+ """Unregister a service."""
+ try:
+ del(self.services[info.name.lower()])
+ if self.servicetypes[info.type]>1:
+ self.servicetypes[info.type]-=1
+ else:
+ del self.servicetypes[info.type]
+ except:
+ pass
+ now = currentTimeMillis()
+ nextTime = now
+ i = 0
+ while i < 3:
+ if now < nextTime:
+ self.wait(nextTime - now)
+ now = currentTimeMillis()
+ continue
+ out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
+ out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, 0, info.name), 0)
+ out.addAnswerAtTime(DNSService(info.name, _TYPE_SRV, _CLASS_IN, 0, info.priority, info.weight, info.port, info.name), 0)
+ out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, _CLASS_IN, 0, info.text), 0)
+ if info.address:
+ out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, _CLASS_IN, 0, info.address), 0)
+ self.send(out)
+ i += 1
+ nextTime += _UNREGISTER_TIME
+
+ def unregisterAllServices(self):
+ """Unregister all registered services."""
+ if len(self.services) > 0:
+ now = currentTimeMillis()
+ nextTime = now
+ i = 0
+ while i < 3:
+ if now < nextTime:
+ self.wait(nextTime - now)
+ now = currentTimeMillis()
+ continue
+ out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
+ for info in self.services.values():
+ out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, 0, info.name), 0)
+ out.addAnswerAtTime(DNSService(info.name, _TYPE_SRV, _CLASS_IN, 0, info.priority, info.weight, info.port, info.server), 0)
+ out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, _CLASS_IN, 0, info.text), 0)
+ if info.address:
+ out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, _CLASS_IN, 0, info.address), 0)
+ self.send(out)
+ i += 1
+ nextTime += _UNREGISTER_TIME
+
+ def checkService(self, info):
+ """Checks the network for a unique service name, modifying the
+ ServiceInfo passed in if it is not unique."""
+ now = currentTimeMillis()
+ nextTime = now
+ i = 0
+ while i < 3:
+ for record in self.cache.entriesWithName(info.type):
+ if record.type == _TYPE_PTR and not record.isExpired(now) and record.alias == info.name:
+ if (info.name.find('.') < 0):
+ info.name = info.name + ".[" + info.address + ":" + info.port + "]." + info.type
+ self.checkService(info)
+ return
+ raise NonUniqueNameException
+ if now < nextTime:
+ self.wait(nextTime - now)
+ now = currentTimeMillis()
+ continue
+ out = DNSOutgoing(_FLAGS_QR_QUERY | _FLAGS_AA)
+ self.debug = out
+ out.addQuestion(DNSQuestion(info.type, _TYPE_PTR, _CLASS_IN))
+ out.addAuthorativeAnswer(DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, _DNS_TTL, info.name))
+ self.send(out)
+ i += 1
+ nextTime += _CHECK_TIME
+
+ def addListener(self, listener, question):
+ """Adds a listener for a given question. The listener will have
+ its updateRecord method called when information is available to
+ answer the question."""
+ now = currentTimeMillis()
+ self.listeners.append(listener)
+ if question is not None:
+ for record in self.cache.entriesWithName(question.name):
+ if question.answeredBy(record) and not record.isExpired(now):
+ listener.updateRecord(self, now, record)
+ self.notifyAll()
+
+ def removeListener(self, listener):
+ """Removes a listener."""
+ try:
+ self.listeners.remove(listener)
+ self.notifyAll()
+ except:
+ pass
+
+ def updateRecord(self, now, rec):
+ """Used to notify listeners of new information that has updated
+ a record."""
+ for listener in self.listeners:
+ listener.updateRecord(self, now, rec)
+ self.notifyAll()
+
+ def handleResponse(self, msg):
+ """Deal with incoming response packets. All answers
+ are held in the cache, and listeners are notified."""
+ now = currentTimeMillis()
+ for record in msg.answers:
+ expired = record.isExpired(now)
+ if record in self.cache.entries():
+ if expired:
+ self.cache.remove(record)
+ else:
+ entry = self.cache.get(record)
+ if entry is not None:
+ entry.resetTTL(record)
+ record = entry
+ else:
+ self.cache.add(record)
+
+ self.updateRecord(now, record)
+
+ def handleQuery(self, msg, addr, port):
+ """Deal with incoming query packets. Provides a response if
+ possible."""
+ out = None
+
+ # Support unicast client responses
+ #
+ if port != _MDNS_PORT:
+ out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA, 0)
+ for question in msg.questions:
+ out.addQuestion(question)
+
+ for question in msg.questions:
+ if question.type == _TYPE_PTR:
+ if question.name == "_services._dns-sd._udp.local.":
+ for stype in self.servicetypes.keys():
+ if out is None:
+ out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
+ out.addAnswer(msg, DNSPointer("_services._dns-sd._udp.local.", _TYPE_PTR, _CLASS_IN, _DNS_TTL, stype))
+ for service in self.services.values():
+ if question.name == service.type:
+ if out is None:
+ out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
+ out.addAnswer(msg, DNSPointer(service.type, _TYPE_PTR, _CLASS_IN, _DNS_TTL, service.name))
+ else:
+ try:
+ if out is None:
+ out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
+
+ # Answer A record queries for any service addresses we know
+ if question.type == _TYPE_A or question.type == _TYPE_ANY:
+ for service in self.services.values():
+ if service.server == question.name.lower():
+ out.addAnswer(msg, DNSAddress(question.name, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
+
+ service = self.services.get(question.name.lower(), None)
+ if not service: continue
+
+ if question.type == _TYPE_SRV or question.type == _TYPE_ANY:
+ out.addAnswer(msg, DNSService(question.name, _TYPE_SRV, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.priority, service.weight, service.port, service.server))
+ if question.type == _TYPE_TXT or question.type == _TYPE_ANY:
+ out.addAnswer(msg, DNSText(question.name, _TYPE_TXT, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.text))
+ if question.type == _TYPE_SRV:
+ out.addAdditionalAnswer(DNSAddress(service.server, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
+ except:
+ traceback.print_exc()
+
+ if out is not None and out.answers:
+ out.id = msg.id
+ self.send(out, addr, port)
+
+ def send(self, out, addr = _MDNS_ADDR, port = _MDNS_PORT):
+ """Sends an outgoing packet."""
+ # This is a quick test to see if we can parse the packets we generate
+ #temp = DNSIncoming(out.packet())
+ try:
+ self.socket.sendto(out.packet(), 0, (addr, port))
+ except:
+ # Ignore this, it may be a temporary loss of network connection
+ pass
+
+ def close(self):
+ """Ends the background threads, and prevent this instance from
+ servicing further queries."""
+ if globals()['_GLOBAL_DONE'] == 0:
+ globals()['_GLOBAL_DONE'] = 1
+ self.notifyAll()
+ self.engine.notify()
+ self.unregisterAllServices()
+ self.socket.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'))
+ self.socket.close()
+
+# Test a few module features, including service registration, service
+# query (for Zoe), and service unregistration.
+
+if __name__ == '__main__':
+ print "Multicast DNS Service Discovery for Python, version", __version__
+ r = Zeroconf()
+ print "1. Testing registration of a service..."
+ desc = {'version':'0.10','a':'test value', 'b':'another value'}
+ info = ServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local.", socket.inet_aton("127.0.0.1"), 1234, 0, 0, desc)
+ print " Registering service..."
+ r.registerService(info)
+ print " Registration done."
+ print "2. Testing query of service information..."
+ print " Getting ZOE service:", str(r.getServiceInfo("_http._tcp.local.", "ZOE._http._tcp.local."))
+ print " Query done."
+ print "3. Testing query of own service..."
+ print " Getting self:", str(r.getServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local."))
+ print " Query done."
+ print "4. Testing unregister of service information..."
+ r.unregisterService(info)
+ print " Unregister done."
+ r.close()
diff --git a/sys/src/cmd/hg/hgext/zeroconf/__init__.py b/sys/src/cmd/hg/hgext/zeroconf/__init__.py
new file mode 100644
index 000000000..a57bbf593
--- /dev/null
+++ b/sys/src/cmd/hg/hgext/zeroconf/__init__.py
@@ -0,0 +1,159 @@
+# zeroconf.py - zeroconf support for Mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''discover and advertise repositories on the local network
+
+Zeroconf enabled repositories will be announced in a network without
+the need to configure a server or a service. They can be discovered
+without knowing their actual IP address.
+
+To allow other people to discover your repository using run "hg serve"
+in your repository::
+
+ $ cd test
+ $ hg serve
+
+You can discover zeroconf enabled repositories by running "hg paths"::
+
+ $ hg paths
+ zc-test = http://example.com:8000/test
+'''
+
+import Zeroconf, socket, time, os
+from mercurial import ui
+from mercurial import extensions
+from mercurial.hgweb import hgweb_mod
+from mercurial.hgweb import hgwebdir_mod
+
+# publish
+
+server = None
+localip = None
+
+def getip():
+ # finds external-facing interface without sending any packets (Linux)
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.connect(('1.0.0.1', 0))
+ ip = s.getsockname()[0]
+ return ip
+ except:
+ pass
+
+ # Generic method, sometimes gives useless results
+ try:
+ dumbip = socket.gethostbyaddr(socket.gethostname())[2][0]
+ if not dumbip.startswith('127.') and ':' not in dumbip:
+ return dumbip
+ except socket.gaierror:
+ dumbip = '127.0.0.1'
+
+ # works elsewhere, but actually sends a packet
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.connect(('1.0.0.1', 1))
+ ip = s.getsockname()[0]
+ return ip
+ except:
+ pass
+
+ return dumbip
+
+def publish(name, desc, path, port):
+ global server, localip
+ if not server:
+ ip = getip()
+ if ip.startswith('127.'):
+ # if we have no internet connection, this can happen.
+ return
+ localip = socket.inet_aton(ip)
+ server = Zeroconf.Zeroconf(ip)
+
+ hostname = socket.gethostname().split('.')[0]
+ host = hostname + ".local"
+ name = "%s-%s" % (hostname, name)
+
+ # advertise to browsers
+ svc = Zeroconf.ServiceInfo('_http._tcp.local.',
+ name + '._http._tcp.local.',
+ server = host,
+ port = port,
+ properties = {'description': desc,
+ 'path': "/" + path},
+ address = localip, weight = 0, priority = 0)
+ server.registerService(svc)
+
+ # advertise to Mercurial clients
+ svc = Zeroconf.ServiceInfo('_hg._tcp.local.',
+ name + '._hg._tcp.local.',
+ server = host,
+ port = port,
+ properties = {'description': desc,
+ 'path': "/" + path},
+ address = localip, weight = 0, priority = 0)
+ server.registerService(svc)
+
+class hgwebzc(hgweb_mod.hgweb):
+ def __init__(self, repo, name=None):
+ super(hgwebzc, self).__init__(repo, name)
+ name = self.reponame or os.path.basename(repo.root)
+ desc = self.repo.ui.config("web", "description", name)
+ publish(name, desc, name, int(repo.ui.config("web", "port", 8000)))
+
+class hgwebdirzc(hgwebdir_mod.hgwebdir):
+ def run(self):
+ for r, p in self.repos:
+ u = self.ui.copy()
+ u.readconfig(os.path.join(p, '.hg', 'hgrc'))
+ n = os.path.basename(r)
+ publish(n, "hgweb", p, int(u.config("web", "port", 8000)))
+ return super(hgwebdirzc, self).run()
+
+# listen
+
+class listener(object):
+ def __init__(self):
+ self.found = {}
+ def removeService(self, server, type, name):
+ if repr(name) in self.found:
+ del self.found[repr(name)]
+ def addService(self, server, type, name):
+ self.found[repr(name)] = server.getServiceInfo(type, name)
+
+def getzcpaths():
+ ip = getip()
+ if ip.startswith('127.'):
+ return
+ server = Zeroconf.Zeroconf(ip)
+ l = listener()
+ Zeroconf.ServiceBrowser(server, "_hg._tcp.local.", l)
+ time.sleep(1)
+ server.close()
+ for v in l.found.values():
+ n = v.name[:v.name.index('.')]
+ n.replace(" ", "-")
+ u = "http://%s:%s%s" % (socket.inet_ntoa(v.address), v.port,
+ v.properties.get("path", "/"))
+ yield "zc-" + n, u
+
+def config(orig, self, section, key, default=None, untrusted=False):
+ if section == "paths" and key.startswith("zc-"):
+ for n, p in getzcpaths():
+ if n == key:
+ return p
+ return orig(self, section, key, default, untrusted)
+
+def configitems(orig, self, section, untrusted=False):
+ r = orig(self, section, untrusted)
+ if section == "paths":
+ r += getzcpaths()
+ return r
+
+extensions.wrapfunction(ui.ui, 'config', config)
+extensions.wrapfunction(ui.ui, 'configitems', configitems)
+hgweb_mod.hgweb = hgwebzc
+hgwebdir_mod.hgwebdir = hgwebdirzc
diff --git a/sys/src/cmd/hg/hgweb.cgi b/sys/src/cmd/hg/hgweb.cgi
new file mode 100644
index 000000000..b18eb48a9
--- /dev/null
+++ b/sys/src/cmd/hg/hgweb.cgi
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+#
+# An example CGI script to use hgweb, edit as necessary
+
+# adjust python path if not a system-wide install:
+#import sys
+#sys.path.insert(0, "/path/to/python/lib")
+
+# enable importing on demand to reduce startup time
+from mercurial import demandimport; demandimport.enable()
+
+# Uncomment to send python tracebacks to the browser if an error occurs:
+#import cgitb
+#cgitb.enable()
+
+# If you'd like to serve pages with UTF-8 instead of your default
+# locale charset, you can do so by uncommenting the following lines.
+# Note that this will cause your .hgrc files to be interpreted in
+# UTF-8 and all your repo files to be displayed using UTF-8.
+#
+#import os
+#os.environ["HGENCODING"] = "UTF-8"
+
+from mercurial.hgweb.hgweb_mod import hgweb
+import mercurial.hgweb.wsgicgi as wsgicgi
+
+application = hgweb("/path/to/repo", "repository name")
+wsgicgi.launch(application)
diff --git a/sys/src/cmd/hg/hgwebdir.cgi b/sys/src/cmd/hg/hgwebdir.cgi
new file mode 100644
index 000000000..79d86ad1f
--- /dev/null
+++ b/sys/src/cmd/hg/hgwebdir.cgi
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+#
+# An example CGI script to export multiple hgweb repos, edit as necessary
+
+# adjust python path if not a system-wide install:
+#import sys
+#sys.path.insert(0, "/path/to/python/lib")
+
+# enable importing on demand to reduce startup time
+from mercurial import demandimport; demandimport.enable()
+
+# Uncomment to send python tracebacks to the browser if an error occurs:
+#import cgitb
+#cgitb.enable()
+
+# If you'd like to serve pages with UTF-8 instead of your default
+# locale charset, you can do so by uncommenting the following lines.
+# Note that this will cause your .hgrc files to be interpreted in
+# UTF-8 and all your repo files to be displayed using UTF-8.
+#
+#import os
+#os.environ["HGENCODING"] = "UTF-8"
+
+from mercurial.hgweb.hgwebdir_mod import hgwebdir
+import mercurial.hgweb.wsgicgi as wsgicgi
+
+# The config file looks like this. You can have paths to individual
+# repos, collections of repos in a directory tree, or both.
+#
+# [paths]
+# virtual/path1 = /real/path1
+# virtual/path2 = /real/path2
+# virtual/root = /real/root/*
+# / = /real/root2/*
+# virtual/root2 = /real/root2/**
+#
+# [collections]
+# /prefix/to/strip/off = /root/of/tree/full/of/repos
+#
+# paths example:
+#
+# * First two lines mount one repository into one virtual path, like
+# '/real/path1' into 'virtual/path1'.
+#
+# * The third entry mounts every mercurial repository found in '/real/root'
+# in 'virtual/root'. This format is preferred over the [collections] one,
+# since using absolute paths as configuration keys is not supported on every
+# platform (especially on Windows).
+#
+# * The fourth entry is a special case mounting all repositories in
+# /'real/root2' in the root of the virtual directory.
+#
+# * The fifth entry recursively finds all repositories under the real root,
+# and mounts them using their relative path (to given real root) under the
+# virtual root.
+#
+# collections example: say directory tree /foo contains repos /foo/bar,
+# /foo/quux/baz. Give this config section:
+# [collections]
+# /foo = /foo
+# Then repos will list as bar and quux/baz.
+#
+# Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
+# or use a dictionary with entries like 'virtual/path': '/real/path'
+
+application = hgwebdir('hgweb.config')
+wsgicgi.launch(application)
diff --git a/sys/src/cmd/hg/i18n/da.po b/sys/src/cmd/hg/i18n/da.po
new file mode 100644
index 000000000..9be9e69fd
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/da.po
@@ -0,0 +1,9275 @@
+# Danish translations for Mercurial
+# Danske oversættelser for Mercurial
+# Copyright (C) 2009 Matt Mackall and others
+#
+# Translation dictionary:
+#
+# changeset ændring
+# commit deponere
+# merge sammenføje
+# patch rettelse
+# repo(sitory) depot
+# revision revision
+# tag mærkat
+# working directory arbejdskatalog
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial\n"
+"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
+"POT-Creation-Date: 2009-07-20 23:05+0200\n"
+"PO-Revision-Date: 2009-07-21 00:18+0200\n"
+"Last-Translator: <mg@lazybytes.net>\n"
+"Language-Team: Danish\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (standard: %s)"
+
+msgid "OPTIONS"
+msgstr "TILVALG"
+
+msgid "COMMANDS"
+msgstr "KOMMANDOER"
+
+msgid " options:\n"
+msgstr " tilvalg:\n"
+
+#, python-format
+msgid ""
+" aliases: %s\n"
+"\n"
+msgstr ""
+" aliaser %s:\n"
+"\n"
+
+msgid ""
+"hooks for controlling repository access\n"
+"\n"
+"This hook makes it possible to allow or deny write access to portions\n"
+"of a repository when receiving incoming changesets.\n"
+"\n"
+"The authorization is matched based on the local user name on the\n"
+"system where the hook runs, and not the committer of the original\n"
+"changeset (since the latter is merely informative).\n"
+"\n"
+"The acl hook is best used along with a restricted shell like hgsh,\n"
+"preventing authenticating users from doing anything other than\n"
+"pushing or pulling. The hook is not safe to use if users have\n"
+"interactive shell access, as they can then disable the hook.\n"
+"Nor is it safe if remote users share an account, because then there\n"
+"is no way to distinguish them.\n"
+"\n"
+"To use this hook, configure the acl extension in your hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.acl =\n"
+"\n"
+" [hooks]\n"
+" pretxnchangegroup.acl = python:hgext.acl.hook\n"
+"\n"
+" [acl]\n"
+" # Check whether the source of incoming changes is in this list\n"
+" # (\"serve\" == ssh or http, \"push\", \"pull\", \"bundle\")\n"
+" sources = serve\n"
+"\n"
+"The allow and deny sections take a subtree pattern as key (with a\n"
+"glob syntax by default), and a comma separated list of users as\n"
+"the corresponding value. The deny list is checked before the allow\n"
+"list is.\n"
+"\n"
+" [acl.allow]\n"
+" # If acl.allow is not present, all users are allowed by default.\n"
+" # An empty acl.allow section means no users allowed.\n"
+" docs/** = doc_writer\n"
+" .hgtags = release_engineer\n"
+"\n"
+" [acl.deny]\n"
+" # If acl.deny is not present, no users are refused by default.\n"
+" # An empty acl.deny section means all users allowed.\n"
+" glob pattern = user4, user5\n"
+" ** = user6\n"
+msgstr ""
+
+#, python-format
+msgid "acl: %s not enabled\n"
+msgstr "acl: %s er ikke slået til\n"
+
+#, python-format
+msgid "acl: %s enabled, %d entries for user %s\n"
+msgstr "acl: %s slået til, %d optegnelser for bruger %s\n"
+
+#, python-format
+msgid "config error - hook type \"%s\" cannot stop incoming changesets"
+msgstr ""
+"konfigurationsfejl - hook type \"%s\" kan ikke stoppe indgående ændringer"
+
+#, python-format
+msgid "acl: changes have source \"%s\" - skipping\n"
+msgstr "acl: ændringer har kilde \"%s\" - springer over\n"
+
+#, python-format
+msgid "acl: user %s denied on %s\n"
+msgstr "acl: bruger %s nægtet adgang til %s\n"
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr "acl: adgang nægtet til ændring %s"
+
+#, python-format
+msgid "acl: user %s not allowed on %s\n"
+msgstr "acl: bruger %s ikke tilladt på %s\n"
+
+#, python-format
+msgid "acl: allowing changeset %s\n"
+msgstr "acl: tillader ændring %s\n"
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+"Bookmarks are local movable markers to changesets. Every bookmark\n"
+"points to a changeset identified by its hash. If you commit a\n"
+"changeset that is based on a changeset that has a bookmark on it,\n"
+"the bookmark shifts to the new changeset.\n"
+"\n"
+"It is possible to use bookmark names in every revision lookup\n"
+"(e.g. hg merge, hg update).\n"
+"\n"
+"By default, when several bookmarks point to the same changeset, they\n"
+"will all move forward together. It is possible to obtain a more\n"
+"git-like experience by adding the following configuration option to\n"
+"your .hgrc:\n"
+"\n"
+" [bookmarks]\n"
+" track.current = True\n"
+"\n"
+"This will cause Mercurial to track the bookmark that you are currently\n"
+"using, and only update it. This is similar to git's approach to\n"
+"branching.\n"
+msgstr ""
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+" Bookmarks are pointers to certain commits that move when\n"
+" committing. Bookmarks are local. They can be renamed, copied and\n"
+" deleted. It is possible to use bookmark names in 'hg merge' and\n"
+" 'hg update' to merge and update respectively to a given bookmark.\n"
+"\n"
+" You can use 'hg bookmark NAME' to set a bookmark on the working\n"
+" directory's parent revision with the given name. If you specify\n"
+" a revision using -r REV (where REV may be an existing bookmark),\n"
+" the bookmark is assigned to that revision.\n"
+" "
+msgstr ""
+
+msgid "a bookmark of this name does not exist"
+msgstr "et bogmærke med dette navn findes ikke"
+
+msgid "a bookmark of the same name already exists"
+msgstr "et bogmærke med samme navn findes allerede"
+
+msgid "new bookmark name required"
+msgstr "nyt bogmærkenavn påkrævet"
+
+msgid "bookmark name required"
+msgstr "bogmærkenavn påkrævet"
+
+msgid "bookmark name cannot contain newlines"
+msgstr "bogmærkenavn kan ikke indeholde linieskift"
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr "et bogmærke kan ikke hedde det samme som en eksisterende gren"
+
+msgid "force"
+msgstr "gennemtving"
+
+msgid "revision"
+msgstr "revision"
+
+msgid "delete a given bookmark"
+msgstr "slet et givent bogmærke"
+
+msgid "rename a given bookmark"
+msgstr "omdøb et givet bogmærke"
+
+msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
+msgstr "hg bookmarks [-f] [-d] [-m NAVN] [-r REV] [NAVN]"
+
+msgid ""
+"hooks for integrating with the Bugzilla bug tracker\n"
+"\n"
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
+"bug status.\n"
+"\n"
+"The hook updates the Bugzilla database directly. Only Bugzilla\n"
+"installations using MySQL are supported.\n"
+"\n"
+"The hook relies on a Bugzilla script to send bug change notification\n"
+"emails. That script changes between Bugzilla versions; the\n"
+"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
+"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
+"be run by Mercurial as the user pushing the change; you will need to\n"
+"ensure the Bugzilla install file permissions are set appropriately.\n"
+"\n"
+"Configuring the extension:\n"
+"\n"
+" [bugzilla]\n"
+"\n"
+" host Hostname of the MySQL server holding the Bugzilla\n"
+" database.\n"
+" db Name of the Bugzilla database in MySQL. Default 'bugs'.\n"
+" user Username to use to access MySQL server. Default 'bugs'.\n"
+" password Password to use to access MySQL server.\n"
+" timeout Database connection timeout (seconds). Default 5.\n"
+" version Bugzilla version. Specify '3.0' for Bugzilla versions\n"
+" 3.0 and later, '2.18' for Bugzilla versions from 2.18\n"
+" and '2.16' for versions prior to 2.18.\n"
+" bzuser Fallback Bugzilla user name to record comments with, if\n"
+" changeset committer cannot be found as a Bugzilla user.\n"
+" bzdir Bugzilla install directory. Used by default notify.\n"
+" Default '/var/www/html/bugzilla'.\n"
+" notify The command to run to get Bugzilla to send bug change\n"
+" notification emails. Substitutes from a map with 3\n"
+" keys, 'bzdir', 'id' (bug id) and 'user' (committer\n"
+" bugzilla email). Default depends on version; from 2.18\n"
+" it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
+" %(id)s %(user)s\".\n"
+" regexp Regular expression to match bug IDs in changeset commit\n"
+" message. Must contain one \"()\" group. The default\n"
+" expression matches 'Bug 1234', 'Bug no. 1234', 'Bug\n"
+" number 1234', 'Bugs 1234,5678', 'Bug 1234 and 5678' and\n"
+" variations thereof. Matching is case insensitive.\n"
+" style The style file to use when formatting comments.\n"
+" template Template to use when formatting comments. Overrides\n"
+" style if specified. In addition to the usual Mercurial\n"
+" keywords, the extension specifies:\n"
+" {bug} The Bugzilla bug ID.\n"
+" {root} The full pathname of the Mercurial\n"
+" repository.\n"
+" {webroot} Stripped pathname of the Mercurial\n"
+" repository.\n"
+" {hgweb} Base URL for browsing Mercurial\n"
+" repositories.\n"
+" Default 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip The number of slashes to strip from the front of {root}\n"
+" to produce {webroot}. Default 0.\n"
+" usermap Path of file containing Mercurial committer ID to\n"
+" Bugzilla user ID mappings. If specified, the file\n"
+" should contain one mapping per line,\n"
+" \"committer\"=\"Bugzilla user\". See also the [usermap]\n"
+" section.\n"
+"\n"
+" [usermap]\n"
+" Any entries in this section specify mappings of Mercurial\n"
+" committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl Base URL for browsing Mercurial repositories. Reference\n"
+" from templates as {hgweb}.\n"
+"\n"
+"Activating the extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # run bugzilla hook on every change pulled or pushed in here\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Example configuration:\n"
+"\n"
+"This example configuration is for a collection of Mercurial\n"
+"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
+"installation in /opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Commits add a comment to the Bugzilla bug record of the form:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr "forbinder til %s:%s som %s, kodeord %s\n"
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr "forespørgsel: %s %s\n"
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr "fejlet forespørgsel: %s %s\n"
+
+msgid "unknown database schema"
+msgstr "ukendt databaseskema"
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr "fejl %d kender allerede til ændring %s\n"
+
+msgid "telling bugzilla to send mail:\n"
+msgstr "beder bugzilla om at sende mail:\n"
+
+#, python-format
+msgid " bug %s\n"
+msgstr " fejl %s\n"
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr "kører notificeringskommando %s\n"
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr "bugzilla notificeringskommando %s"
+
+msgid "done\n"
+msgstr "færdig\n"
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr "slår bruger %s op\n"
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr "kan ikke finde bugzilla bruger-id for %s"
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr "kan ikke finde bugzilla bruger-id for %s eller %s"
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr "bugzilla version %s ikke understøttet"
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr "python mysql-understøttelse ikke tilgængelig: %s"
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr ""
+
+#, python-format
+msgid "database error: %s"
+msgstr "databasefejl: %s"
+
+msgid "command to display child changesets"
+msgstr "kommando til at vise børne-ændringer"
+
+msgid ""
+"show the children of the given or working directory revision\n"
+"\n"
+" Print the children of the working directory's revisions. If a\n"
+" revision is given via -r/--rev, the children of that revision will\n"
+" be printed. If a file argument is given, revision in which the\n"
+" file was last changed (after the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"vis børnene til arbejdskataloget eller en given revision\n"
+"\n"
+" Udskriv arbejdskatalogets børnerevisioner. Hvis en revision er\n"
+" angivet med -r/--rev, udskrives børnene til denne revision.\n"
+" Hvis en fil er angivet, udskrives revisionen i hvilken filen sidst\n"
+" blev ændret (efter arbejdskatalogets revision eller argumentet til\n"
+" --rev, hvis givet).\n"
+" "
+
+msgid "show children of the specified revision"
+msgstr "vis børn af den givne revision"
+
+msgid "hg children [-r REV] [FILE]"
+msgstr "hg children [-r REV] [FIL]"
+
+msgid "command to display statistics about repository history"
+msgstr "kommando til at vise statistikker om depotets historie"
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr "Revision %d er en sammenføjning; ignorerer...\n"
+
+#, python-format
+msgid "generating stats: %d%%"
+msgstr "genererer statistik: %d%%"
+
+msgid ""
+"histogram of changes to the repository\n"
+"\n"
+" This command will display a histogram representing the number\n"
+" of changed lines or revisions, grouped according to the given\n"
+" template. The default template will group changes by author.\n"
+" The --dateformat option may be used to group the results by\n"
+" date instead.\n"
+"\n"
+" Statistics are based on the number of changed lines, or\n"
+" alternatively the number of matching revisions if the\n"
+" --changesets option is specified.\n"
+"\n"
+" Examples:\n"
+"\n"
+" # display count of changed lines for every committer\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # display daily activity graph\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # display activity of developers by month\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # display count of lines changed in every year\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" It is possible to map alternate email addresses to a main address\n"
+" by providing a file using the following format:\n"
+"\n"
+" <alias email> <actual email>\n"
+"\n"
+" Such a file may be specified with the --aliases option, otherwise a\n"
+" .hgchurn file will be looked for in the working directory root.\n"
+" "
+msgstr ""
+"histogram over ændringer i depotet\n"
+"\n"
+" Denne kommando vil vise et histogram som repræsenterer antallet af\n"
+" ændrede linier eller revisioner, grupperet efter en given\n"
+" skabelon. Standardskabelonen vil gruppere ændringer efter\n"
+" forfatter. Med --dateformat tilvalget kan resultaterne i stedet\n"
+" grupperes efter dato.\n"
+"\n"
+" Statistikken er basseret på antallet af ændrede linier eller\n"
+" alternativt på antallet af matchende revisioner, hvis --changesets\n"
+" tilvalget er specificeret.\n"
+"\n"
+" Eksempler:\n"
+"\n"
+" # viser antaller af ændrede linier for hver bruger\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # viser graf over daglig aktivitet\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # viser månedlig aktivitet af udviklerne\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # viser antallet af linier ændret hvert år\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" Det er muligt at afbilde alternative e-mail-adresser til\n"
+" hoved-adresser ved at bruge en fil med følgende format:\n"
+"\n"
+" <alias email> <faktisk email>\n"
+"\n"
+" En sådan fil kan angivet med --aliases tilvalget. Som standard\n"
+" bruges .hgchurn i arbejdskatalogets rod, hvis denne findes.\n"
+" "
+
+#, python-format
+msgid "assuming %i character terminal\n"
+msgstr "antager %i-tegn terminal\n"
+
+msgid "count rate for the specified revision or range"
+msgstr "lav statistik for de specificerede revisioner"
+
+msgid "count rate for revisions matching date spec"
+msgstr "lav statistik for revisioner som matcher dato specifikationen"
+
+msgid "template to group changesets"
+msgstr "skabelon for gruppering af ændringer"
+
+msgid "strftime-compatible format for grouping by date"
+msgstr "strftime-kompatibelt format til gruppering efter dato"
+
+msgid "count rate by number of changesets"
+msgstr "lav statistik efter antallet af ændringer"
+
+msgid "sort by key (default: sort by count)"
+msgstr "sorter efter nøgle (standard: sorter efter antal)"
+
+msgid "file with email aliases"
+msgstr "fil med email-aliaser"
+
+msgid "show progress"
+msgstr "vis fremskridt"
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+msgstr "hg churn [-d DATO] [-r REV] [--aliases FIL] [--progress] [FIL]"
+
+msgid ""
+"colorize output from some commands\n"
+"\n"
+"This extension modifies the status command to add color to its output\n"
+"to reflect file status, the qseries command to add color to reflect\n"
+"patch status (applied, unapplied, missing), and to diff-related\n"
+"commands to highlight additions, removals, diff headers, and trailing\n"
+"whitespace.\n"
+"\n"
+"Other effects in addition to color, like bold and underlined text, are\n"
+"also available. Effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes). This module also provides the\n"
+"render_text function, which can be used to add effects to any text.\n"
+"\n"
+"Default effects may be overridden from the .hgrc file:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' turns off all effects\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+msgstr ""
+
+msgid "when to colorize (always, auto, or never)"
+msgstr "hvornår der skal farvelægges (altid, automatisk eller aldrig)"
+
+msgid "don't colorize output"
+msgstr "farvelæg ikke output"
+
+#, python-format
+msgid "ignoring unknown color/effect %r (configured in color.%s)\n"
+msgstr ""
+
+msgid "import revisions from foreign VCS repositories into Mercurial"
+msgstr "importer revisioner fra fremmede VCS depoter ind i Mercurial"
+
+msgid ""
+"convert a foreign SCM repository to a Mercurial one.\n"
+"\n"
+" Accepted source formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Accepted destination formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (history on branches is not preserved)\n"
+"\n"
+" If no revision is given, all revisions will be converted.\n"
+" Otherwise, convert will only import up to the named revision\n"
+" (given in a format understood by the source).\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source with '-hg' appended. If the destination\n"
+" repository doesn't exist, it will be created.\n"
+"\n"
+" By default, all sources except Mercurial will use\n"
+" --branchsort. Mercurial uses --sourcesort to preserve original\n"
+" revision numbers order. Sort modes have the following effects:\n"
+" --branchsort: convert from parent to child revision when\n"
+" possible, which means branches are usually converted one after\n"
+" the other. It generates more compact repositories.\n"
+" --datesort: sort revisions by date. Converted repositories have\n"
+" good-looking changelogs but are often an order of magnitude\n"
+" larger than the same ones generated by --branchsort.\n"
+" --sourcesort: try to preserve source revisions order, only\n"
+" supported by Mercurial sources.\n"
+"\n"
+" If <REVMAP> isn't given, it will be put in a default location\n"
+" (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file\n"
+" that maps each source commit ID to the destination ID for that\n"
+" revision, like so:\n"
+" <source ID> <destination ID>\n"
+"\n"
+" If the file doesn't exist, it's automatically created. It's\n"
+" updated on each commit copied, so convert-repo can be interrupted\n"
+" and can be run repeatedly to copy new commits.\n"
+"\n"
+" The [username mapping] file is a simple text file that maps each\n"
+" source commit author to a destination commit author. It is handy\n"
+" for source SCMs that use unix logins to identify authors (eg:\n"
+" CVS). One line per author mapping and the line format is:\n"
+" srcauthor=whatever string you want\n"
+"\n"
+" The filemap is a file that allows filtering and remapping of files\n"
+" and directories. Comment lines start with '#'. Each line can\n"
+" contain one of the following directives:\n"
+"\n"
+" include path/to/file\n"
+"\n"
+" exclude path/to/file\n"
+"\n"
+" rename from/file to/file\n"
+"\n"
+" The 'include' directive causes a file, or all files under a\n"
+" directory, to be included in the destination repository, and the\n"
+" exclusion of all other files and directories not explicitly included.\n"
+" The 'exclude' directive causes files or directories to be omitted.\n"
+" The 'rename' directive renames a file or directory. To rename from\n"
+" a subdirectory into the root of the repository, use '.' as the\n"
+" path to rename to.\n"
+"\n"
+" The splicemap is a file that allows insertion of synthetic\n"
+" history, letting you specify the parents of a revision. This is\n"
+" useful if you want to e.g. give a Subversion merge two parents, or\n"
+" graft two disconnected series of history together. Each entry\n"
+" contains a key, followed by a space, followed by one or two\n"
+" comma-separated values. The key is the revision ID in the source\n"
+" revision control system whose parents should be modified (same\n"
+" format as a key in .hg/shamap). The values are the revision IDs\n"
+" (in either the source or destination revision control system) that\n"
+" should be used as the new parents for that node.\n"
+"\n"
+" The branchmap is a file that allows you to rename a branch when it is\n"
+" being brought in from whatever external repository. When used in\n"
+" conjunction with a splicemap, it allows for a powerful combination\n"
+" to help fix even the most badly mismanaged repositories and turn them\n"
+" into nicely structured Mercurial repositories. The branchmap contains\n"
+" lines of the form \"original_branch_name new_branch_name\".\n"
+" \"original_branch_name\" is the name of the branch in the source\n"
+" repository, and \"new_branch_name\" is the name of the branch is the\n"
+" destination repository. This can be used to (for instance) move code\n"
+" in one repository from \"default\" to a named branch.\n"
+"\n"
+" Mercurial Source\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (boolean)\n"
+" ignore integrity errors when reading. Use it to fix Mercurial\n"
+" repositories with missing revlogs, by converting from and to\n"
+" Mercurial.\n"
+" --config convert.hg.saverev=False (boolean)\n"
+" store original revision ID in changeset (forces target IDs to\n"
+" change)\n"
+" --config convert.hg.startrev=0 (hg revision identifier)\n"
+" convert start revision and its descendants\n"
+"\n"
+" CVS Source\n"
+" ----------\n"
+"\n"
+" CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+" to indicate the starting point of what will be converted. Direct\n"
+" access to the repository files is not needed, unless of course the\n"
+" repository is :local:. The conversion uses the top level directory\n"
+" in the sandbox to find the CVS repository, and then uses CVS rlog\n"
+" commands to find files to convert. This means that unless a\n"
+" filemap is given, all files under the starting directory will be\n"
+" converted, and that any directory reorganization in the CVS\n"
+" sandbox is ignored.\n"
+"\n"
+" Because CVS does not have changesets, it is necessary to collect\n"
+" individual commits to CVS and merge them into changesets. CVS\n"
+" source uses its internal changeset merging code by default but can\n"
+" be configured to call the external 'cvsps' program by setting:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" This option is deprecated and will be removed in Mercurial 1.4.\n"
+"\n"
+" The options shown are the defaults.\n"
+"\n"
+" Internal cvsps is selected by setting\n"
+" --config convert.cvsps=builtin\n"
+" and has a few more configurable options:\n"
+" --config convert.cvsps.cache=True (boolean)\n"
+" Set to False to disable remote log caching, for testing and\n"
+" debugging purposes.\n"
+" --config convert.cvsps.fuzz=60 (integer)\n"
+" Specify the maximum time (in seconds) that is allowed\n"
+" between commits with identical user and log message in a\n"
+" single changeset. When very large files were checked in as\n"
+" part of a changeset then the default may not be long\n"
+" enough.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will insert a dummy revision merging the branch on\n"
+" which this log message occurs to the branch indicated in\n"
+" the regex.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will add the most recent revision on the branch\n"
+" indicated in the regex as the second parent of the\n"
+" changeset.\n"
+"\n"
+" The hgext/convert/cvsps wrapper script allows the builtin\n"
+" changeset merging code to be run without doing a conversion. Its\n"
+" parameters and output are similar to that of cvsps 2.1.\n"
+"\n"
+" Subversion Source\n"
+" -----------------\n"
+"\n"
+" Subversion source detects classical trunk/branches/tags layouts.\n"
+" By default, the supplied \"svn://repo/path/\" source URL is\n"
+" converted as a single branch. If \"svn://repo/path/trunk\" exists it\n"
+" replaces the default branch. If \"svn://repo/path/branches\" exists,\n"
+" its subdirectories are listed as possible branches. If\n"
+" \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
+" converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
+" can be overridden with following options. Set them to paths\n"
+" relative to the source URL, or leave them blank to disable auto\n"
+" detection.\n"
+"\n"
+" --config convert.svn.branches=branches (directory name)\n"
+" specify the directory containing branches\n"
+" --config convert.svn.tags=tags (directory name)\n"
+" specify the directory containing tags\n"
+" --config convert.svn.trunk=trunk (directory name)\n"
+" specify the name of the trunk branch\n"
+"\n"
+" Source history can be retrieved starting at a specific revision,\n"
+" instead of being integrally converted. Only single branch\n"
+" conversions are supported.\n"
+"\n"
+" --config convert.svn.startrev=0 (svn revision number)\n"
+" specify start Subversion revision.\n"
+"\n"
+" Perforce Source\n"
+" ---------------\n"
+"\n"
+" The Perforce (P4) importer can be given a p4 depot path or a\n"
+" client specification as source. It will convert all files in the\n"
+" source to a flat Mercurial repository, ignoring labels, branches\n"
+" and integrations. Note that when a depot path is given you then\n"
+" usually should specify a target directory, because otherwise the\n"
+" target may be named ...-hg.\n"
+"\n"
+" It is possible to limit the amount of source history to be\n"
+" converted by specifying an initial Perforce revision.\n"
+"\n"
+" --config convert.p4.startrev=0 (perforce changelist number)\n"
+" specify initial Perforce revision.\n"
+"\n"
+"\n"
+" Mercurial Destination\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (boolean)\n"
+" dispatch source branches in separate clones.\n"
+" --config convert.hg.tagsbranch=default (branch name)\n"
+" tag revisions branch name\n"
+" --config convert.hg.usebranchnames=True (boolean)\n"
+" preserve branch names\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"create changeset information from CVS\n"
+"\n"
+" This command is intended as a debugging tool for the CVS to\n"
+" Mercurial converter, and can be used as a direct replacement for\n"
+" cvsps.\n"
+"\n"
+" Hg debugcvsps reads the CVS rlog for current directory (or any\n"
+" named directory) in the CVS repository, and converts the log to a\n"
+" series of changesets based on matching commit log entries and\n"
+" dates."
+msgstr ""
+
+msgid "username mapping filename"
+msgstr "brugernavnsafbildningsfilnavn"
+
+msgid "destination repository type"
+msgstr "type for destinations repository"
+
+msgid "remap file names using contents of file"
+msgstr "konverter filnavne ved brug af filindhold"
+
+msgid "import up to target revision REV"
+msgstr "importer op til revision REV"
+
+msgid "source repository type"
+msgstr "kildedepotstype"
+
+msgid "splice synthesized history into place"
+msgstr "ind-splejs syntetisk historie"
+
+msgid "change branch names while converting"
+msgstr "omdøb grene under konverteringen"
+
+msgid "try to sort changesets by branches"
+msgstr "forsøg at sortere ændringer efter gren"
+
+msgid "try to sort changesets by date"
+msgstr "forsøg at sortere ændringer efter dato"
+
+msgid "preserve source changesets order"
+msgstr "bevar kildeændringerne ordning"
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr "hg convert [TILVALG]... KILDE [MÃ…L [REV-AFBILDNING]]"
+
+msgid "only return changes on specified branches"
+msgstr "returner kun ændringer på givne grene"
+
+msgid "prefix to remove from file names"
+msgstr "præfix der skal fjernes fra filnavne"
+
+msgid "only return changes after or between specified tags"
+msgstr "returner kun ændringer efter eller mellem givne mærkater"
+
+msgid "update cvs log cache"
+msgstr "opdater cvs log cache"
+
+msgid "create new cvs log cache"
+msgstr "opret ny cvs log cache"
+
+msgid "set commit time fuzz in seconds"
+msgstr ""
+
+msgid "specify cvsroot"
+msgstr "angiv cvsroot"
+
+msgid "show parent changesets"
+msgstr "vis forældre-ændringer"
+
+msgid "show current changeset in ancestor branches"
+msgstr ""
+
+msgid "ignored for compatibility"
+msgstr "ignoreret af kompatibilitetsgrunde"
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr "hg debugcvsps [TILVALG]... [STI]..."
+
+msgid ""
+"warning: lightweight checkouts may cause conversion failures, try with a "
+"regular branch instead.\n"
+msgstr ""
+
+msgid "bzr source type could not be determined\n"
+msgstr "bzr kildetype kunne ikke bestemmes\n"
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr "%s er ikke en gyldig revision i den nuværende gren"
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr "%s er ikke længere tilgængelig i %s"
+
+#, python-format
+msgid "%s.%s symlink has no target"
+msgstr "%s.%s symbolsk lænke er ikke noget mål"
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr "kan ikke finde påkrævet værktøj \"%s\""
+
+#, python-format
+msgid "running: %s\n"
+msgstr "kører: %s\n"
+
+#, python-format
+msgid "%s error:\n"
+msgstr "%s fejl:\n"
+
+#, python-format
+msgid "syntax error in %s(%d): key/value pair expected"
+msgstr "syntaksfejl i %s(%d): nøgle/værdi-par forventet"
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr "kunne ikke åbne afbildningsfil %r: %s"
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr "%s: manglende eller usupporteret depot"
+
+#, python-format
+msgid "convert: %s\n"
+msgstr "convert: %s\n"
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr "%s: ukendt depottype"
+
+#, python-format
+msgid "unknown sort mode: %s"
+msgstr "ukendt sortering: %s"
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr "cyklus opdaget mellem %s og %s"
+
+msgid "not all revisions were sorted"
+msgstr "ikke alle revisioner blev sorteret"
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr "Skriver forfatter-afbildningsfil %s\n"
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr "Ignorerer dårlig linie i forfatter-afbildningsfil %s: %s\n"
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr "afbilder forfatter %s til %s\n"
+
+#, python-format
+msgid "overriding mapping for author %s, was %s, will be %s\n"
+msgstr "tilsidesætter afbildning for forfatter %s, var %s, vil blive %s\n"
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr "splejsede %s ind som forældre til %s\n"
+
+msgid "scanning source...\n"
+msgstr "skanner kilde...\n"
+
+msgid "sorting...\n"
+msgstr "sorterer...\n"
+
+msgid "converting...\n"
+msgstr "konverterer...\n"
+
+#, python-format
+msgid "source: %s\n"
+msgstr "kilde: %s\n"
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr "antager mål %s\n"
+
+msgid "more than one sort mode specified"
+msgstr "mere end end sorteringsmetode angivet"
+
+msgid "--sourcesort is not supported by this data source"
+msgstr "--sourcesort er ikke supporteret at denne datakilde"
+
+msgid ""
+"warning: support for external cvsps is deprecated and will be removed in "
+"Mercurial 1.4\n"
+msgstr ""
+"advarsel: support for ekstern cvsps er forældet og vil blive fjernet i "
+"Mercurial 1.4\n"
+
+#, python-format
+msgid "revision %s is not a patchset number or date"
+msgstr ""
+
+msgid "using builtin cvsps\n"
+msgstr "bruger indbygget cvsps\n"
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr "forbinder til %s\n"
+
+msgid "CVS pserver authentication failed"
+msgstr "CVS pserver godkendelse fejlede"
+
+#, python-format
+msgid ""
+"unexpected response from CVS server (expected \"Valid-requests\", but got %r)"
+msgstr "uventet svar fra CVS serveren (forventede \"Valid-requests\", men fik %r)"
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr "%d byte mangler i fjernfilen"
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr "cvs server: %s\n"
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr "ukendt CVS svar: %s"
+
+msgid "collecting CVS rlog\n"
+msgstr "samler CVS rlog\n"
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr "læser cvs log-mellemlager %s\n"
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr "mellemlager har %d lagerindgange\n"
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr "fejl ved læsning af mellemlager: %r\n"
+
+#, python-format
+msgid "running %s\n"
+msgstr "kører %s\n"
+
+#, python-format
+msgid "prefix=%r directory=%r root=%r\n"
+msgstr "præfiks=%r katalog=%r rod=%r\n"
+
+msgid "RCS file must be followed by working file"
+msgstr "RCS-fil skal efterfølges af en arbejdsfil"
+
+msgid "must have at least some revisions"
+msgstr "kan have mindst nogle revisioner"
+
+msgid "expected revision number"
+msgstr "forventede et revisionsnummer"
+
+msgid "revision must be followed by date line"
+msgstr "revision skal efterfølges af datolinje"
+
+#, python-format
+msgid "found synthetic revision in %s: %r\n"
+msgstr "fandt syntetisk revision i %s: %r\n"
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr "skriver cvs log-mellemlager %s\n"
+
+#, python-format
+msgid "%d log entries\n"
+msgstr "%d lagerindgange\n"
+
+msgid "creating changesets\n"
+msgstr "opretter ændringer\n"
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr "syntetisk ændring kan ikke have flere forældre"
+
+#, python-format
+msgid ""
+"warning: CVS commit message references non-existent branch %r:\n"
+"%s\n"
+msgstr ""
+"advarsel: CVS deponeringsbesked refererer en ikke-eksisterende gren %r:\n"
+"%s\n"
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr "%d ændringer\n"
+
+msgid "Python ElementTree module is not available"
+msgstr "Python ElementTree modulet er ikke tilstede"
+
+#, python-format
+msgid "cleaning up %s\n"
+msgstr "rydder op %s\n"
+
+msgid "internal calling inconsistency"
+msgstr "intern kaldeinkonsistens"
+
+msgid "errors in filemap"
+msgstr "fejl i filafbildning"
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr "%s:%d: %r er allerede i %s listen\n"
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr "%s:%d: ukendt direktiv %r\n"
+
+msgid "source repository doesn't support --filemap"
+msgstr "kildedepot understøtter ikke --filemap"
+
+#, python-format
+msgid "%s does not look like a GNU Arch repo"
+msgstr "%s ser ikke ud som et GNU Arch depot"
+
+msgid "cannot find a GNU Arch tool"
+msgstr "kan ikke finde GNU Arch"
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr "analyserer træ version %s...\n"
+
+#, python-format
+msgid ""
+"tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr ""
+
+#, python-format
+msgid "applying revision %s...\n"
+msgstr "anvender revision %s...\n"
+
+#, python-format
+msgid "computing changeset between %s and %s...\n"
+msgstr "beregner ændringer mellem %s og %s...\n"
+
+#, python-format
+msgid "obtaining revision %s...\n"
+msgstr "henter revision %s...\n"
+
+#, python-format
+msgid "analyzing revision %s...\n"
+msgstr "analyserer revision %s...\n"
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr "kan ikke parse cat-log af %s"
+
+#, python-format
+msgid "%s is not a local Mercurial repo"
+msgstr "%s er ikke et lokalt Mercurial depot"
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr "initialiserer mål %s depot\n"
+
+msgid "run hg sink pre-conversion action\n"
+msgstr ""
+
+msgid "run hg sink post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr "hiver fra %s ind i %s\n"
+
+msgid "filtering out empty revision\n"
+msgstr "bortfiltrerer tom revision\n"
+
+msgid "updating tags\n"
+msgstr "opdaterer mærkater\n"
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr "%s er ikke en gyldig startrevision"
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr "ignorerer: %s\n"
+
+msgid "run hg source pre-conversion action\n"
+msgstr ""
+
+msgid "run hg source post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a monotone repo"
+msgstr "%s ser ikke ud som et monotone depot"
+
+#, python-format
+msgid "copying file in renamed directory from '%s' to '%s'"
+msgstr "kopierer fil i omdøbt katalog fra '%s' til '%s'"
+
+msgid "reading p4 views\n"
+msgstr "læser p4 views\n"
+
+msgid "collecting p4 changelists\n"
+msgstr "samler p4 changelists\n"
+
+msgid "Subversion python bindings could not be loaded"
+msgstr "Subversion python bindingerne kunne ikke indlæses"
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr "fandt Subversion python bindinger %d.%d, 1.4 eller senere er påkrævet"
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr "Subversion python bindinger er for gamle, 1.4 eller senere er påkrævet"
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr "svn: revision %s er ikke et heltal"
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr "svn: startrevision %s er ikke et heltal"
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr "ingen revision fundet i modul %s"
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr "forventede at %s ville være ved %r, men fandt det ikke"
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr "fandt %s ved %r\n"
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr "ignorerer tom gren %s\n"
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr "fandt gren %s ved %d\n"
+
+msgid "svn: start revision is not supported with more than one branch"
+msgstr "svn: startrevision er ikke understøttet ved mere end en gren"
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr "svn: fandt ingen revisioner efter startrevision %d"
+
+#, python-format
+msgid "no tags found at revision %d\n"
+msgstr "ingen mærkater fundet ved revision %d\n"
+
+#, python-format
+msgid "ignoring foreign branch %r\n"
+msgstr "ignorerer fremmed gren %r\n"
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr "%s blev ikke fundet op til revision %d"
+
+#, python-format
+msgid "branch renamed from %s to %s at %d\n"
+msgstr "gren omdøbt fra %s til %s ved %d\n"
+
+#, python-format
+msgid "reparent to %s\n"
+msgstr ""
+
+#, python-format
+msgid "copied to %s from %s@%s\n"
+msgstr "kopieret til %s fra %s@%s\n"
+
+#, python-format
+msgid "gone from %s\n"
+msgstr "væk fra %s\n"
+
+#, python-format
+msgid "entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown path in revision %d: %s\n"
+msgstr "ukendt sti i revision %d: %s\n"
+
+#, python-format
+msgid "mark %s came from %s:%d\n"
+msgstr ""
+
+#, python-format
+msgid "parsing revision %d (%d changes)\n"
+msgstr "parser revision %d (%d ændringer)\n"
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr "fandt forælder til gren %s ved %d: %s\n"
+
+msgid "no copyfrom path, don't know what to do.\n"
+msgstr ""
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr "henter revisionslog for \"%s\" fra %d til %d\n"
+
+#, python-format
+msgid "revision %d has no entries\n"
+msgstr "revision %d har ikke nogen indgange\n"
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr "svn: gren har ikke nogen revision %s"
+
+#, python-format
+msgid "%r is not under %r, ignoring\n"
+msgstr "%r ikke under %r, ignorerer\n"
+
+#, python-format
+msgid "initializing svn repo %r\n"
+msgstr "initialiserer svn depot %r\n"
+
+#, python-format
+msgid "initializing svn wc %r\n"
+msgstr "initialiserer svn arbejdskatalog %r\n"
+
+msgid "unexpected svn output:\n"
+msgstr "uventet svn output:\n"
+
+msgid "unable to cope with svn output"
+msgstr "kan ikke håndtere svn output"
+
+msgid "XXX TAGS NOT IMPLEMENTED YET\n"
+msgstr ""
+
+msgid ""
+"command to allow external programs to compare revisions\n"
+"\n"
+"The `extdiff' Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working directory. The external diff\n"
+"programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare.\n"
+"\n"
+"The `extdiff' extension also allows to configure new diff commands, so\n"
+"you do not need to type \"hg extdiff -p kdiff3\" always.\n"
+"\n"
+" [extdiff]\n"
+" # add new command that runs GNU diff(1) in 'context diff' mode\n"
+" cdiff = gdiff -Nprc5\n"
+" ## or the old way:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # add new command called vdiff, runs kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # add new command called meld, runs meld (no need to name twice)\n"
+" meld =\n"
+"\n"
+" # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+" # (see http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Non English user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" "
+"in\n"
+" # your .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"You can use -I/-X and list of file or directory names like normal \"hg\n"
+"diff\" command. The `extdiff' extension makes snapshots of only needed\n"
+"files, so running the external diff program will actually be pretty\n"
+"fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr "laver øjebliksbillede af %d filer fra rev %s\n"
+
+#, python-format
+msgid "making snapshot of %d files from working directory\n"
+msgstr "laver øjebliksbillede af %d filer fra arbejdskataloget\n"
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr "kan ikke angive --rev og --change på samme tid"
+
+#, python-format
+msgid "running %r in %s\n"
+msgstr "kører %r i %s\n"
+
+#, python-format
+msgid "file changed while diffing. Overwriting: %s (src: %s)\n"
+msgstr ""
+
+msgid "cleaning up temp directory\n"
+msgstr "rydder midlertidigt katalog op\n"
+
+msgid ""
+"use external program to diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files, using\n"
+" an external program. The default program used is diff, with\n"
+" default options \"-Npru\".\n"
+"\n"
+" To select a different program, use the -p/--program option. The\n"
+" program will be passed the names of two directories to compare. To\n"
+" pass additional options to the program, use -o/--option. These\n"
+" will be passed before the names of the directories to compare.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent."
+msgstr ""
+
+msgid "comparison program to run"
+msgstr "sammenligningsprogram der skal køres"
+
+msgid "pass option to comparison program"
+msgstr "videregiv argument til sammenligningsprogram"
+
+msgid "change made by revision"
+msgstr "ændring lavet i revision"
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr "hg extdiff [TILVALG]... [FIL]..."
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr "hg %s [TILVALG]... [FIL]..."
+
+msgid "pull, update and merge in one command"
+msgstr "træk, opdater og sammenføj i en kommando"
+
+msgid ""
+"pull changes from a remote repository, merge new changes if needed.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository.\n"
+"\n"
+" If the pulled changes add a new branch head, the head is\n"
+" automatically merged, and the result of the merge is committed.\n"
+" Otherwise, the working directory is updated to include the new\n"
+" changes.\n"
+"\n"
+" When a merge occurs, the newly pulled changes are assumed to be\n"
+" \"authoritative\". The head of the new changes is used as the first\n"
+" parent, with local changes as the second. To switch the merge\n"
+" order, use --switch-parent.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid ""
+"working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+"arbejdskataloget er ikke ved gren-spidsen (brug \"hg update\" for at hente "
+"gren-spidsen)"
+
+msgid "outstanding uncommitted merge"
+msgstr "udestående udeponeret sammenføjning"
+
+msgid "outstanding uncommitted changes"
+msgstr "udestående udeponeret ændringer"
+
+msgid "working directory is missing some files"
+msgstr "arbejdskataloget mangler nogle filer"
+
+msgid ""
+"multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr ""
+"flere hoveder i denne gren (brug \"hg heads .\" og \"hg merge\" for at "
+"sammenføje)"
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr "hiver fra %s\n"
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+"sammenføjer ikke med %d andre nye gren-hoveder (brug \"hg heads .\" og \"hg "
+"merge\" for at sammenføje dem)\n"
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr "opdaterer til %d:%s\n"
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr "sammenføjer med %d:%s\n"
+
+#, python-format
+msgid "Automated merge with %s"
+msgstr "Automatisk sammenføjning med %s"
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr "ny ændring %d:%s fletter fjernændringer sammen med lokale\n"
+
+msgid "a specific revision you would like to pull"
+msgstr "en bestemt revision som du gerne vil hive ned"
+
+msgid "edit commit message"
+msgstr "rediger deponeringsbesked"
+
+msgid "edit commit message (DEPRECATED)"
+msgstr "rediger deponeringsbesked (FORÆLDET)"
+
+msgid "switch parents when merging"
+msgstr "ombyt forældre ved sammenføjning"
+
+msgid "hg fetch [SOURCE]"
+msgstr "hg fetch [KILDE]"
+
+msgid "commands to sign and verify changesets"
+msgstr "kommandoer til at underskrive og verificere ændringer"
+
+msgid "error while verifying signature"
+msgstr "fejl ved verifikation af underskrift"
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr "%s DÃ¥rlig underskrift fra \"%s\"\n"
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr "%s Bemærk: underskriften er udløbet (underskrevet af \"%s\")\n"
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr "%s Bemærk: denne nøgle er udløbet (underskrevet af \"%s\")\n"
+
+msgid "list signed changesets"
+msgstr "vis underskrevne ændringer"
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr "%s:%d knude findes ikke\n"
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr "verificer alle underskrifter der måtte være for en given revision"
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr "Ingen gyldig signatur for %s\n"
+
+msgid ""
+"add a signature for the current or given revision\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"tilføj en underskrift til den aktuelle eller en given revision\n"
+"\n"
+" Hvis der ikke angives en revision, så bruges forældren til\n"
+" arbejdskataloget, eller tip, hvis der ikke er hentet en revision.\n"
+"\n"
+" Se 'hg help dates' for en liste af gyldige formater til -d/--date.\n"
+" "
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr "udeponeret sammenføjning - angiv venligst en specifik revision"
+
+msgid "Error while signing"
+msgstr "Fejl ved underskrivning"
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+"arbejdskopien af .hgsigs er ændret (deponer venligst .hgsigs manuelt eller "
+"brug --force)"
+
+#, python-format
+msgid "Added signature for changeset %s"
+msgstr "Tilføjede underskrift af ændring %s"
+
+msgid "unknown signature version"
+msgstr "ukendt underskrift-version"
+
+msgid "make the signature local"
+msgstr "lav underskriften lokal"
+
+msgid "sign even if the sigfile is modified"
+msgstr "underskriv selv hvis signaturfilen er ændret"
+
+msgid "do not commit the sigfile after signing"
+msgstr "deponer ikke signaturfilen efter underskrivning"
+
+msgid "the key id to sign with"
+msgstr "nøgle ID der skal underskrives med"
+
+msgid "commit message"
+msgstr "deponeringsbesked"
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr "hg sign [TILVALG]... [REVISION]..."
+
+msgid "hg sigcheck REVISION"
+msgstr "hg sigcheck REVISION"
+
+msgid "hg sigs"
+msgstr "hg sigs"
+
+msgid ""
+"command to view revision graphs from a shell\n"
+"\n"
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ASCII representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+
+#, python-format
+msgid "--graph option is incompatible with --%s"
+msgstr "--graph tilvalget er ikke kompatibelt med --%s"
+
+msgid ""
+"show revision history alongside an ASCII revision graph\n"
+"\n"
+" Print a revision history alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr "sammenligner med %s\n"
+
+msgid "no changes found\n"
+msgstr "fandt ingen ændringer\n"
+
+msgid "show the revision DAG"
+msgstr "vis revisionsgrafen"
+
+msgid "limit number of changes displayed"
+msgstr "begræns antaln viste ændringer"
+
+msgid "show patch"
+msgstr "vis rettelse"
+
+msgid "show the specified revision or range"
+msgstr "vis den angivne revision eller interval"
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr "hg glog [TILVALG]... [FIL]"
+
+msgid ""
+"hooks for integrating with the CIA.vc notification service\n"
+"\n"
+"This is meant to be run as a changegroup or incoming hook.\n"
+"To configure it, set the following options in your hgrc:\n"
+"\n"
+"[cia]\n"
+"# your registered CIA user name\n"
+"user = foo\n"
+"# the name of the project in CIA\n"
+"project = foo\n"
+"# the module (subproject) (optional)\n"
+"#module = foo\n"
+"# Append a diffstat to the log message (optional)\n"
+"#diffstat = False\n"
+"# Template to use for log messages (optional)\n"
+"#template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"# Style to use (optional)\n"
+"#style = foo\n"
+"# The URL of the CIA notification service (optional)\n"
+"# You can use mailto: URLs to send by email, eg\n"
+"# mailto:cia@cia.vc\n"
+"# Make sure to set email.from if you do this.\n"
+"#url = http://cia.vc/\n"
+"# print message instead of sending it (optional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# one of these:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# If you want hyperlinks (optional)\n"
+"baseurl = http://server/path/to/repo\n"
+msgstr ""
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr "hgcia: sender opdatering til %s\n"
+
+msgid "email.from must be defined when sending by email"
+msgstr "email.from skal være defineret ved afsendelse af email"
+
+msgid "cia: no user specified"
+msgstr "cia: ingen bruger angivet"
+
+msgid "cia: no project specified"
+msgstr "cia: intet project angivet"
+
+msgid ""
+"browse the repository in a graphical way\n"
+"\n"
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not\n"
+"distributed with Mercurial.)\n"
+"\n"
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to Mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and the extension is shipped in the hgext\n"
+"repository, and needs to be enabled.\n"
+"\n"
+"The hg view command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can specify\n"
+"the path to hgk in your .hgrc file:\n"
+"\n"
+" [hgk]\n"
+" path=/location/of/hgk\n"
+"\n"
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions."
+msgstr ""
+
+msgid "diff trees from two commits"
+msgstr ""
+
+msgid "output common ancestor information"
+msgstr "udskriv information om fælles forfar"
+
+msgid "cat a specific revision"
+msgstr "udskriv en bestemt revision"
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr ""
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr ""
+
+msgid "parse given revisions"
+msgstr ""
+
+msgid "print revisions"
+msgstr "udskriv revisioner"
+
+msgid "print extension options"
+msgstr "udskriv udvidelses valgmuligheder"
+
+msgid "start interactive history viewer"
+msgstr "start interaktiv historievisning"
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr "hg view [-l GRÆNSE] [REV-INTERVAL]"
+
+msgid "generate patch"
+msgstr "generer rettelse"
+
+msgid "recursive"
+msgstr "rekursiv"
+
+msgid "pretty"
+msgstr "pæn"
+
+msgid "stdin"
+msgstr "standardinddata"
+
+msgid "detect copies"
+msgstr "detekter kopier"
+
+msgid "search"
+msgstr "søg"
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr "hg git-diff-tree [TILVALG]... KNUDE1 KNUDE2 [FIL]..."
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr "hg debug-cat-file [TILVALG ]... TYPE FIL"
+
+msgid "hg debug-config"
+msgstr "hg debug-config"
+
+msgid "hg debug-merge-base REV REV"
+msgstr "hg debug-merge-base REV REV"
+
+msgid "ignored"
+msgstr "Ignoreret"
+
+msgid "hg debug-rev-parse REV"
+msgstr "hg debug-rev-parse REV"
+
+msgid "header"
+msgstr ""
+
+msgid "topo-order"
+msgstr "topologisk ordning"
+
+msgid "parents"
+msgstr "forældre"
+
+msgid "max-count"
+msgstr ""
+
+msgid "hg debug-rev-list [OPTION]... REV..."
+msgstr "hg debug-rev-list [TILVALG]... REV..."
+
+msgid ""
+"syntax highlighting for hgweb (requires Pygments)\n"
+"\n"
+"It depends on the Pygments syntax highlighting library:\n"
+"http://pygments.org/\n"
+"\n"
+"There is a single configuration option:\n"
+"\n"
+"[web]\n"
+"pygments_style = <style>\n"
+"\n"
+"The default is 'colorful'.\n"
+msgstr ""
+"syntaksfarvelægning til hgweb (kræver Pygments)\n"
+"\n"
+"Det afhænger af Pygments biblioteket til syntaksfarvelægning:\n"
+"http://pygments.org/\n"
+"\n"
+"Der er en enkelt konfigurationsmulighed:\n"
+"\n"
+"[web]\n"
+"pygments_style = <stil>\n"
+"\n"
+"Standardstilen er 'colorful'.\n"
+"\n"
+
+msgid "accelerate status report using Linux's inotify service"
+msgstr "accelerer statusreporter ved brug af Linux's inotify service"
+
+msgid "start an inotify server for this repository"
+msgstr "start en inotify server for dette depot"
+
+msgid ""
+"debugging information for inotify extension\n"
+"\n"
+" Prints the list of directories being watched by the inotify server.\n"
+" "
+msgstr ""
+"fejlsøgningsinformation til inotify udvidelsen\n"
+"\n"
+" Udskriver listen af kataloger som bliver overvåget af inotify\n"
+" serveren.\n"
+" "
+
+msgid "directories being watched:\n"
+msgstr "kataloger som bliver overvåget:\n"
+
+msgid "run server in background"
+msgstr "kører serveren i baggrunden"
+
+msgid "used internally by daemon mode"
+msgstr "brugt internt i daemon mode"
+
+msgid "minutes to sit idle before exiting"
+msgstr "antal minutter der skal ventes i tomgang før afslutning"
+
+msgid "name of file to write process ID to"
+msgstr "navn på fil at skrive process ID til"
+
+msgid "hg inserve [OPTION]..."
+msgstr "hg inserve [TILVALG]..."
+
+msgid "(found dead inotify server socket; removing it)\n"
+msgstr "(fandt død inotify server sokkel; fjerner den)\n"
+
+msgid "(starting inotify server)\n"
+msgstr "(starter inotify server)\n"
+
+#, python-format
+msgid "could not start inotify server: %s\n"
+msgstr "kunne ikke starte inotify server: %s\n"
+
+#, python-format
+msgid "could not talk to new inotify server: %s\n"
+msgstr "kunne ikke snakke med ny inotify server: %s\n"
+
+msgid "(inotify server not running)\n"
+msgstr "(inotify server kører ikke)\n"
+
+#, python-format
+msgid "failed to contact inotify server: %s\n"
+msgstr "kontakt med inotify server miskykkedes: %s\n"
+
+msgid "received empty answer from inotify server"
+msgstr "modtog tomt svar fra inotify server"
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr "(inotify: modtog svar fra inkompatibel server version %d)\n"
+
+#, python-format
+msgid "(inotify: received '%s' response when expecting '%s')\n"
+msgstr "(inotify: modtog '%s' svar når '%s' blev forventet)\n"
+
+msgid "this system does not seem to support inotify"
+msgstr "dette system ser ikke ud til at understøtte inotify"
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr ""
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr ""
+
+msgid "*** counting directories: "
+msgstr "*** tæller kataloger: "
+
+#, python-format
+msgid "found %d\n"
+msgstr "fandt %d\n"
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr ""
+
+#, python-format
+msgid "*** echo %d > %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr ""
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr ""
+
+#, python-format
+msgid "watching %r\n"
+msgstr "overvåget %r\n"
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr "overvåger kataloger under %r\n"
+
+#, python-format
+msgid "status: %r dir(%d) -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s dirstate reload\n"
+msgstr ""
+
+#, python-format
+msgid "%s end dirstate reload\n"
+msgstr ""
+
+msgid "rescanning due to .hgignore change\n"
+msgstr "genskanner på grund af .hgignore ændring\n"
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr "%s hændelse: oprettede %s\n"
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr "%s hændelse: slettede %s\n"
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr "%s hændelse: ændrede %s\n"
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr "filsystem indeholdende %s blev afmonteret\n"
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr ""
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr ""
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr ""
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr ""
+
+#, python-format
+msgid "could not start server: %s"
+msgstr "kunne ikke starte server: %s"
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr "svarer forespørgsel for %r\n"
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr "modtog forespørgsel fra inkompatibel klient version %d\n"
+
+#, python-format
+msgid "unrecognized query type: %s\n"
+msgstr "genkendte ikke forespørgselstype: %s\n"
+
+msgid "finished setup\n"
+msgstr "afsluttede opsætning\n"
+
+msgid ""
+"expand expressions into changelog and summaries\n"
+"\n"
+"This extension allows the use of a special syntax in summaries,\n"
+"which will be automatically expanded into links or any other\n"
+"arbitrary expression, much like InterWiki does.\n"
+"\n"
+"A few example patterns (link to bug tracking, etc.) that may\n"
+"be used in your hgrc:\n"
+"\n"
+" [interhg]\n"
+" issues = s!issue(\\d+)!<a href=\"http://bts/issue\\1\">issue\\1</a>!\n"
+" bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2\">\\1</a>!"
+"i\n"
+" boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr "interhg: ugyldigt mønster for %s: %s\n"
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr "interhg: ugyldig regexp for %s: %s\n"
+
+msgid ""
+"expand keywords in tracked files\n"
+"\n"
+"This extension expands RCS/CVS-like or self-customized $Keywords$ in\n"
+"tracked text files selected by your configuration.\n"
+"\n"
+"Keywords are only expanded in local repositories and not stored in the\n"
+"change history. The mechanism can be regarded as a convenience for the\n"
+"current user or for archive distribution.\n"
+"\n"
+"Configuration is done in the [keyword] and [keywordmaps] sections of\n"
+"hgrc files.\n"
+"\n"
+"Example:\n"
+"\n"
+" [keyword]\n"
+" # expand keywords in every python file except those matching \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Note: the more specific you are in your filename patterns\n"
+" the less you lose speed in huge repositories.\n"
+"\n"
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run \"hg kwdemo\".\n"
+"\n"
+"An additional date template filter {date|utcdate} is provided.\n"
+"\n"
+"The default template mappings (view with \"hg kwdemo -d\") can be\n"
+"replaced with customized keywords and templates. Again, run \"hg\n"
+"kwdemo\" to control the results of your config changes.\n"
+"\n"
+"Before changing/disabling active keywords, run \"hg kwshrink\" to avoid\n"
+"the risk of inadvertently storing expanded keywords in the change\n"
+"history.\n"
+"\n"
+"To force expansion after enabling it, or a configuration change, run\n"
+"\"hg kwexpand\".\n"
+"\n"
+"Also, when committing with the record extension or using mq's qrecord,\n"
+"be aware that keywords cannot be updated. Again, run \"hg kwexpand\" on\n"
+"the files in question to update keyword expansions after all changes\n"
+"have been checked in.\n"
+"\n"
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map\n"
+"\"Log = {desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s expanding keywords\n"
+msgstr "overskriver %s og udvider nøgleord\n"
+
+#, python-format
+msgid "overwriting %s shrinking keywords\n"
+msgstr "overskriver %s og formindsker nøgleord\n"
+
+msgid "[keyword] patterns cannot match"
+msgstr "[keyword] mønstre kan ikke matche"
+
+msgid "no [keyword] patterns configured"
+msgstr "ingen [keyword] mønstre konfigureret"
+
+msgid ""
+"print [keywordmaps] configuration and an expansion example\n"
+"\n"
+" Show current, custom, or default keyword template maps and their\n"
+" expansions.\n"
+"\n"
+" Extend current configuration by specifying maps as arguments and\n"
+" optionally by reading from an additional hgrc file.\n"
+"\n"
+" Override current keyword template maps with \"default\" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "creating temporary repository at %s\n"
+msgstr "opretter midlertidigt depot ved %s\n"
+
+#, python-format
+msgid ""
+"\n"
+"\tconfig using %s keyword template maps\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"%s keywords written to %s:\n"
+msgstr "\n%s nøgleord skrevet til %s:\n"
+
+msgid "unhooked all commit hooks\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"\t%s keywords expanded%s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"removing temporary repository %s\n"
+msgstr ""
+"\n"
+"fjerner midlertidigt depot %s\n"
+
+msgid ""
+"expand keywords in the working directory\n"
+"\n"
+" Run after (re)enabling keyword expansion.\n"
+"\n"
+" kwexpand refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid ""
+"show files configured for keyword expansion\n"
+"\n"
+" List which files in the working directory are matched by the\n"
+" [keyword] configuration patterns.\n"
+"\n"
+" Useful to prevent inadvertent keyword expansion and to speed up\n"
+" execution by including only files that are actual candidates\n"
+" for expansion.\n"
+"\n"
+" See \"hg help keyword\" on how to construct patterns both for\n"
+" inclusion and exclusion of files.\n"
+"\n"
+" Use -u/--untracked to list untracked files as well.\n"
+"\n"
+" With -a/--all and -v/--verbose the codes used to show the status\n"
+" of files are:\n"
+" K = keyword expansion candidate\n"
+" k = keyword expansion candidate (untracked)\n"
+" I = ignored\n"
+" i = ignored (untracked)\n"
+" "
+msgstr ""
+
+msgid ""
+"revert expanded keywords in the working directory\n"
+"\n"
+" Run before changing/disabling active keywords or if you experience\n"
+" problems with \"hg import\" or \"hg merge\".\n"
+"\n"
+" kwshrink refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid "show default keyword template maps"
+msgstr "vis standard keyword skabelon-afbildninger"
+
+msgid "read maps from rcfile"
+msgstr ""
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr ""
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr "hg kwexpand [TILVALG]... [FIL]..."
+
+msgid "show keyword status flags of all files"
+msgstr "vis keyword status for alle filer"
+
+msgid "show files excluded from expansion"
+msgstr "vis filer ekskluderet fra ekspansion"
+
+msgid "additionally show untracked files"
+msgstr "vis også ikke-fulgte filer"
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr "hg kwfiles [TILVALG]... [FIL]..."
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr "hg kwshrink [TILVALG]... [FIL]..."
+
+msgid ""
+"manage a stack of patches\n"
+"\n"
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches).\n"
+"\n"
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets.\n"
+"\n"
+"Common tasks (use \"hg help command\" for more details):\n"
+"\n"
+"prepare repository to work with patches qinit\n"
+"create new patch qnew\n"
+"import existing patch qimport\n"
+"\n"
+"print patch series qseries\n"
+"print applied patches qapplied\n"
+"print name of top applied patch qtop\n"
+"\n"
+"add known patch to applied stack qpush\n"
+"remove patch from applied stack qpop\n"
+"refresh contents of top applied patch qrefresh\n"
+msgstr ""
+"håndter en stak af rettelser\n"
+"\n"
+"Denne udvidelse lader dig arbejde med en stak af rettelser (patches) i\n"
+"et Mercurial repository. Den håndterer to stakke af rettelser - alle\n"
+"kendte rettelser og alle anvendte rettelser (en delmængde af de kendte\n"
+"rettelser).\n"
+"\n"
+"Kendte rettelser er repræsenteret som rettelse-filer i .hg/patches\n"
+"biblioteket. Anvendte rettelser er både rettelse-filer og Mercurial\n"
+"ændringer.\n"
+"\n"
+"Almindelige opgaver (brug \"hg help kommado\" for flere detaljer):\n"
+"\n"
+"forbered repository til at arbejde med rettelser qinit\n"
+"opret ny rettelse qnew\n"
+"importer eksisterende rettelse qimport\n"
+"\n"
+"list rettelse-serien qseries\n"
+"list anvendte rettelser qapplied\n"
+"list navnet på den øverste rettelse qtop\n"
+"\n"
+"anvend og put rettelse på stakken qpush\n"
+"fjern rettelse fra stakken qpop\n"
+"genopfrisk indholdet af den øverste rettelse qrefresh\n"
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr "%s findes mere end én gang i %s"
+
+msgid "guard cannot be an empty string"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr ""
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr ""
+
+#, python-format
+msgid "active guards: %s\n"
+msgstr ""
+
+#, python-format
+msgid "guard %r too short"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr ""
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr ""
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr "rettelsen %s kunne ikke anvendes"
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr "rettelsen virkede ikke, sammenføjer %s\n"
+
+#, python-format
+msgid "update returned %d"
+msgstr "opdatering returnerede %d"
+
+msgid "repo commit failed"
+msgstr "deponering fejlede"
+
+#, python-format
+msgid "unable to read %s"
+msgstr "ikke i stand til at læse %s"
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr "rettelsen %s findes ikke\n"
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr "rettelsen %s er ikke anvendt\n"
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr "rettelse fejlede, kan ikke fortsætte (prøv -v)\n"
+
+#, python-format
+msgid "applying %s\n"
+msgstr "anvender %s\n"
+
+#, python-format
+msgid "unable to read %s\n"
+msgstr "kan ikke læse %s\n"
+
+#, python-format
+msgid "imported patch %s\n"
+msgstr "importeret rettelse %s\n"
+
+#, python-format
+msgid ""
+"\n"
+"imported patch %s"
+msgstr ""
+"\n"
+"importeret rettelse %s"
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr "rettelsen %s er tom\n"
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr "rettelse fejlede, afvisninger efter efterladt i arbejdskataloget\n"
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr ""
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr "kan ikke slette revision %d ovenover anvendte rettelser"
+
+#, python-format
+msgid "patch %s finalized without changeset message\n"
+msgstr "rettelsen %s er færdiggjort uden en ændringsbesked\n"
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr "qdelete kræver mindst en revision eller navnet på en rettelse"
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr "kan ikke slette den anvendte rettelse %s"
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr "rettelsen %s er ikke i series filen"
+
+msgid "no patches applied"
+msgstr "ingen rettelser anvendt"
+
+msgid "working directory revision is not qtip"
+msgstr "arbejdskatalogets revision er ikke qtip"
+
+msgid "local changes found, refresh first"
+msgstr "lokale ændringer fundet, genopfrisk først"
+
+msgid "local changes found"
+msgstr "lokale ændringer fundet"
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr "\"%s\" kan ikke bruges som navnet på en rettelse"
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr "rettelsen \"%s\" findes allerede"
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr "fejl ved sletning af %s\n"
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr "rettelsen \"%s\" er tvetydigt:\n"
+
+#, python-format
+msgid "patch %s not in series"
+msgstr ""
+
+msgid "(working directory not at a head)\n"
+msgstr "(arbejdskatalog er ikke ved et hoved)\n"
+
+msgid "no patches in series\n"
+msgstr "ingen patches i serien\n"
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr ""
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr ""
+
+#, python-format
+msgid "guarded by %r"
+msgstr ""
+
+msgid "no matching guards"
+msgstr ""
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr "kan ikke skubbe '%s' - %s\n"
+
+msgid "all patches are currently applied\n"
+msgstr "alle rettelser er i øjeblikket anvendt\n"
+
+msgid "patch series already fully applied\n"
+msgstr "serien af rettelser er allerede anvendt fuldt ud\n"
+
+msgid "cleaning up working directory..."
+msgstr "rydder op i arbejdskataloget..."
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr ""
+
+#, python-format
+msgid "now at: %s\n"
+msgstr "nu ved: %s\n"
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr "rettelsen %s er ikke anvendt"
+
+msgid "no patches applied\n"
+msgstr "ingen rettelser anvendt\n"
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr "qpop: %s er allerede ved toppen\n"
+
+msgid "qpop: forcing dirstate update\n"
+msgstr ""
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr ""
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr ""
+
+msgid "deletions found between repo revs"
+msgstr ""
+
+msgid "patch queue now empty\n"
+msgstr "køen af rettelser er nu tom\n"
+
+msgid "cannot refresh a revision with children"
+msgstr ""
+
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to "
+"recover)\n"
+msgstr ""
+
+msgid "patch queue directory already exists"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr "rettelsen %s er ikke i series filen"
+
+msgid "No saved patch data found\n"
+msgstr ""
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr "genopretter status: %s\n"
+
+msgid "save entry has children, leaving it alone\n"
+msgstr ""
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr ""
+
+msgid "queue directory updating\n"
+msgstr ""
+
+msgid "Unable to load queue repository\n"
+msgstr ""
+
+msgid "save: no patches applied, exiting\n"
+msgstr ""
+
+msgid "status is already saved\n"
+msgstr ""
+
+msgid "hg patches saved state"
+msgstr ""
+
+msgid "repo commit failed\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr "rettelse %s er allerede i series-filen"
+
+msgid "option \"-r\" not valid when importing files"
+msgstr "tilvalg \"-r\" er ikke gyldigt når filer bliver importeret"
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr "tilvalg \"-n\" er ikke gyldigt når flere rettelser bliver importeret"
+
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr "revision %d er roden for mere end en gren"
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr "revision %d er allerede håndteret"
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr ""
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr ""
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr "kan ikke importere sammenføjningsrevision %d"
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr ""
+
+msgid "-e is incompatible with import from -"
+msgstr "-e er ikke kompatibelt med importering fra -"
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr "rettelsen %s eksisterer ikke"
+
+msgid "need --name to import a patch from -"
+msgstr "har brug for --name for at importere rettelse fra -"
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr "tilføjer %s til series filen\n"
+
+msgid ""
+"remove patches from queue\n"
+"\n"
+" The patches must not be applied, and at least one patch is required. "
+"With\n"
+" -k/--keep, the patch files are preserved in the patch directory.\n"
+"\n"
+" To stop managing a patch and move it into permanent history,\n"
+" use the qfinish command."
+msgstr ""
+
+msgid "print the patches already applied"
+msgstr "udskriver rettelserne som allerede er anvendt"
+
+msgid "print the patches not yet applied"
+msgstr "udskriver rettelserne som ikke er anvendt endnu"
+
+msgid ""
+"import a patch\n"
+"\n"
+" The patch is inserted into the series after the last applied\n"
+" patch. If no patches have been applied, qimport prepends the patch\n"
+" to the series.\n"
+"\n"
+" The patch will have the same name as its source file unless you\n"
+" give it a new one with -n/--name.\n"
+"\n"
+" You can register an existing patch inside the patch directory with\n"
+" the -e/--existing flag.\n"
+"\n"
+" With -f/--force, an existing patch of the same name will be\n"
+" overwritten.\n"
+"\n"
+" An existing changeset may be placed under mq control with -r/--rev\n"
+" (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+" With -g/--git, patches imported with --rev will use the git diff\n"
+" format. See the diffs help topic for information on why this is\n"
+" important for preserving rename/copy information and permission\n"
+" changes.\n"
+"\n"
+" To import a patch from standard input, pass - as the patch file.\n"
+" When importing from standard input, a patch name must be specified\n"
+" using the --name flag.\n"
+" "
+msgstr ""
+"importer en patch\n"
+"\n"
+" Patchen sættes ind i serien efter den sidste anvendte patch. Hvis\n"
+" der ikker er anvendt nogen patches, indsætter qimport patches\n"
+" først i serien.\n"
+"\n"
+" Patchen vil have samme navn som dens kildefil, med mindre du\n"
+" angiver et nyt med -n/--name.\n"
+"\n"
+" Du kan registrere en eksisterende patch inden i patch kataloget\n"
+" med -e/--existing tilvalget.\n"
+"\n"
+" Med -f/--force vil en allerede eksisterende patch med samme navn\n"
+" blive overskrevet.\n"
+"\n"
+" En eksisterende ændrin kan blive sat under mq kontrol med -r/--rev\n"
+" (e.g. qimport --rev tip -n patch vil sætte tip under mq kontrol).\n"
+" Med -g/--git vil patches importeret med --rev bruge git diff\n"
+" formatet. Se 'hg help diffs' for mere information om hvorfor dette\n"
+" er vigtigt for at bevare omdøbnings/kopierings-information og\n"
+" ændriner i rettigheder.\n"
+"\n"
+" Brug - som patch filnavn for at importere en patch fra standard\n"
+" indput. NÃ¥r der importeres fra standard indput skal der angivet et\n"
+" patchnavn med --name tilvalget.\n"
+" "
+
+msgid ""
+"init a new queue repository\n"
+"\n"
+" The queue repository is unversioned by default. If\n"
+" -c/--create-repo is specified, qinit will create a separate nested\n"
+" repository for patches (qinit -c may also be run later to convert\n"
+" an unversioned patch repository into a versioned one). You can use\n"
+" qcommit to commit changes to this queue repository."
+msgstr ""
+"opret et nyt kø-depot\n"
+"\n"
+" Kø-depotet er uversioneret som standard. Hvis -c/--create-repo\n"
+" bruges, så vil qinit oprettet et separat indlejret depot til\n"
+" patches (qinit -c kan også bruges senere for at konvertere et\n"
+" uversioneret patch depot til et versioneret et). Du kan bruge\n"
+" qcommit for at deponere ændringer i dette kø-depot."
+
+msgid ""
+"clone main and patch repository at same time\n"
+"\n"
+" If source is local, destination will have no patches applied. If\n"
+" source is remote, this command can not check if patches are\n"
+" applied in source, so cannot guarantee that patches are not\n"
+" applied in destination. If you clone remote repository, be sure\n"
+" before that it has no patches applied.\n"
+"\n"
+" Source patch repository is looked for in <src>/.hg/patches by\n"
+" default. Use -p <url> to change.\n"
+"\n"
+" The patch directory must be a nested Mercurial repository, as\n"
+" would be created by qinit -c.\n"
+" "
+msgstr ""
+
+msgid "versioned patch repository not found (see qinit -c)"
+msgstr "versionsstyret depot til rettelser blev ikke fundet (se qinit -c)"
+
+msgid "cloning main repository\n"
+msgstr "kloner hoveddepot\n"
+
+msgid "cloning patch repository\n"
+msgstr "kloner depotet til rettelser\n"
+
+msgid "stripping applied patches from destination repository\n"
+msgstr ""
+
+msgid "updating destination repository\n"
+msgstr ""
+
+msgid "commit changes in the queue repository"
+msgstr ""
+
+msgid "print the entire series file"
+msgstr "udskriver hele series filen"
+
+msgid "print the name of the current patch"
+msgstr "udskriver navnet på den nuværende rettelse"
+
+msgid "print the name of the next patch"
+msgstr "udskriver navnet på den næste rettelse"
+
+msgid "all patches applied\n"
+msgstr "alle rettelser er anvendt\n"
+
+msgid "print the name of the previous patch"
+msgstr "udskriver navnet på den forgående rettelse"
+
+msgid "only one patch applied\n"
+msgstr "kun én rettelse er anvendt\n"
+
+msgid ""
+"create a new patch\n"
+"\n"
+" qnew creates a new patch on top of the currently-applied patch (if\n"
+" any). It will refuse to run if there are any outstanding changes\n"
+" unless -f/--force is specified, in which case the patch will be\n"
+" initialized with them. You may also use -I/--include,\n"
+" -X/--exclude, and/or a list of files after the patch name to add\n"
+" only changes to matching files to the new patch, leaving the rest\n"
+" as uncommitted modifications.\n"
+"\n"
+" -u/--user and -d/--date can be used to set the (given) user and\n"
+" date, respectively. -U/--currentuser and -D/--currentdate set user\n"
+" to current user and date to current date.\n"
+"\n"
+" -e/--edit, -m/--message or -l/--logfile set the patch header as\n"
+" well as the commit message. If none is specified, the header is\n"
+" empty and the commit message is '[mq]: PATCH'.\n"
+"\n"
+" Use the -g/--git option to keep the patch in the git extended diff\n"
+" format. Read the diffs help topic for more information on why this\n"
+" is important for preserving permission changes and copy/rename\n"
+" information.\n"
+" "
+msgstr ""
+
+msgid ""
+"update the current patch\n"
+"\n"
+" If any file patterns are provided, the refreshed patch will\n"
+" contain only the modifications that match those patterns; the\n"
+" remaining modifications will remain in the working directory.\n"
+"\n"
+" If -s/--short is specified, files currently included in the patch\n"
+" will be refreshed just like matched files and remain in the patch.\n"
+"\n"
+" hg add/remove/copy/rename work as usual, though you might want to\n"
+" use git-style patches (-g/--git or [diff] git=1) to track copies\n"
+" and renames. See the diffs help topic for more information on the\n"
+" git diff format.\n"
+" "
+msgstr ""
+"opdater den aktuelle patch\n"
+"\n"
+" Hvis der angives filer, så vil den opdaterede patch kun indeholde\n"
+" modifikationer som matcher disse filer; de andre ændringer vil\n"
+" forblive i arbejdskataloget.\n"
+"\n"
+" Hvis -s/--short angivet, så vil filer som allerede er i patches\n"
+" blive opdateret ligesom matchede filer og forblive i patchen.\n"
+"\n"
+" hg add/remove/copy/rename virker som sædvanlig, dog vil du måske\n"
+" bruge git-patches (-g/--git eller [diff] git=1) for at følge\n"
+" kopier og omdøbninger. Se 'hg help diffs' for mere information om\n"
+" git diff formatet.\n"
+" "
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr "tilvalg \"-e\" er inkompatibelt med \"-m\" eller \"-l\""
+
+msgid ""
+"diff of the current patch and subsequent modifications\n"
+"\n"
+" Shows a diff which includes the current patch as well as any\n"
+" changes which have been made in the working directory since the\n"
+" last refresh (thus showing what the current patch would become\n"
+" after a qrefresh).\n"
+"\n"
+" Use 'hg diff' if you only want to see the changes made since the\n"
+" last qrefresh, or 'hg export qtip' if you want to see changes made\n"
+" by the current patch without including changes made since the\n"
+" qrefresh.\n"
+" "
+msgstr ""
+"forskelle mellem den nuværende patch og efterfølgende modifikationer\n"
+"\n"
+" Viser forskelle fra den nuværende patch og eventuelle\n"
+" efterfølgende ændringer i arbejdskataloget siden sidste refresh\n"
+" (dermed ser man hvad den nuværende patch vil blive efter en\n"
+" qrefresh)\n"
+"\n"
+" Brug 'hg diff' hvis du kun vil se ændringer lavet siden den sidste\n"
+" qrefresh, eller 'hg export qtip' hvis du vil se ændringer lavet af\n"
+" den nuværende patch uden at inkludere ændringer lavet siden\n"
+" qrefresh.\n"
+" "
+
+msgid ""
+"fold the named patches into the current patch\n"
+"\n"
+" Patches must not yet be applied. Each patch will be successively\n"
+" applied to the current patch in the order given. If all the\n"
+" patches apply successfully, the current patch will be refreshed\n"
+" with the new cumulative patch, and the folded patches will be\n"
+" deleted. With -k/--keep, the folded patch files will not be\n"
+" removed afterwards.\n"
+"\n"
+" The header for each folded patch will be concatenated with the\n"
+" current patch header, separated by a line of '* * *'."
+msgstr ""
+
+msgid "qfold requires at least one patch name"
+msgstr "qfold kræver navnet på mindst én rettelse"
+
+msgid "No patches applied"
+msgstr "Der er ikke anvendt nogen rettelser"
+
+#, python-format
+msgid "Skipping already folded patch %s"
+msgstr ""
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "Error folding patch %s"
+msgstr ""
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr ""
+
+msgid ""
+"set or print guards for a patch\n"
+"\n"
+" Guards control whether a patch can be pushed. A patch with no\n"
+" guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+" pushed only if the qselect command has activated it. A patch with\n"
+" a negative guard (\"-foo\") is never pushed if the qselect command\n"
+" has activated it.\n"
+"\n"
+" With no arguments, print the currently active guards.\n"
+" With arguments, set guards for the named patch.\n"
+" NOTE: Specifying negative guards now requires '--'.\n"
+"\n"
+" To set guards on another patch:\n"
+" hg qguard -- other.patch +2.6.17 -stable\n"
+" "
+msgstr ""
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr "kan ikke blande -l/--list med tilvalg eller argumenter"
+
+msgid "no patch to work with"
+msgstr "ingen rettelse at arbejde med"
+
+#, python-format
+msgid "no patch named %s"
+msgstr "ingen patch ved navn %s"
+
+msgid "print the header of the topmost or specified patch"
+msgstr ""
+
+msgid ""
+"push the next patch onto the stack\n"
+"\n"
+" When -f/--force is applied, all local changes in patched files\n"
+" will be lost.\n"
+" "
+msgstr ""
+"skub den næste rettelse på stakken\n"
+"\n"
+" Når -f/--force er angivet, så vil alle lokale ændringer i de\n"
+" rettede filer gå tabt.\n"
+" "
+
+msgid "no saved queues found, please use -n\n"
+msgstr "fandt ingen gemte køer, brug venligst -r\n"
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr "sammenføjer med kø ved: %s\n"
+
+msgid ""
+"pop the current patch off the stack\n"
+"\n"
+" By default, pops off the top of the patch stack. If given a patch\n"
+" name, keeps popping off patches until the named patch is at the\n"
+" top of the stack.\n"
+" "
+msgstr ""
+"fjern den aktuelle rettelse fra stakken\n"
+"\n"
+" Som standard fjernes toppen af stakken. Hvis der angives en\n"
+" rettelse, så vil der blive fjernet rettelser indtil den angivne\n"
+" rettelse er på toppen af stakken.\n"
+" "
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr "bruger rettelse-kø: %s\n"
+
+msgid ""
+"rename a patch\n"
+"\n"
+" With one argument, renames the current patch to PATCH1.\n"
+" With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+"omdøb en rettelse\n"
+"\n"
+" Med et argument omdøbes den nuværende rettelse til RETTELSE1. Med\n"
+" to argumenter omdøbes RETTELSE1 til RETTELSE2."
+
+#, python-format
+msgid "%s already exists"
+msgstr "%s eksisterer allerede"
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr "En rettelse ved navn %s eksisterer allerede i serien"
+
+msgid "restore the queue state saved by a revision"
+msgstr ""
+
+msgid "save current queue state"
+msgstr "gem tilstanden for den nuværende kø"
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr "målet %s eksisterer og er ikke et katalog"
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr "målet %s eksisterer, brug -f for at gennemtvinge"
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr "kopier %s til %s\n"
+
+msgid ""
+"strip a revision and all its descendants from the repository\n"
+"\n"
+" If one of the working directory's parent revisions is stripped, the\n"
+" working directory will be updated to the parent of the stripped\n"
+" revision.\n"
+" "
+msgstr ""
+"strip en revision og alle dens efterkommere fra depotet\n"
+"\n"
+" Hvis en af arbejdskatalogets forælder-revisioner bliver strippet,\n"
+" så vil arbejdskataloget blive opdateret til forældren af den\n"
+" strippede revision.\n"
+" "
+
+msgid ""
+"set or print guarded patches to push\n"
+"\n"
+" Use the qguard command to set or print guards on patch, then use\n"
+" qselect to tell mq which guards to use. A patch will be pushed if\n"
+" it has no guards or any positive guards match the currently\n"
+" selected guard, but will not be pushed if any negative guards\n"
+" match the current guard. For example:\n"
+"\n"
+" qguard foo.patch -stable (negative guard)\n"
+" qguard bar.patch +stable (positive guard)\n"
+" qselect stable\n"
+"\n"
+" This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+" it has a negative match) but push bar.patch (because it has a\n"
+" positive match).\n"
+"\n"
+" With no arguments, prints the currently active guards.\n"
+" With one argument, sets the active guard.\n"
+"\n"
+" Use -n/--none to deactivate guards (no other arguments needed).\n"
+" When no guards are active, patches with positive guards are\n"
+" skipped and patches with negative guards are pushed.\n"
+"\n"
+" qselect can change the guards on applied patches. It does not pop\n"
+" guarded patches by default. Use --pop to pop back to the last\n"
+" applied patch that is not guarded. Use --reapply (which implies\n"
+" --pop) to push back to the current patch afterwards, but skip\n"
+" guarded patches.\n"
+"\n"
+" Use -s/--series to print a list of all guards in the series file\n"
+" (no other arguments needed). Use -v for more information."
+msgstr ""
+
+msgid "guards deactivated\n"
+msgstr ""
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr ""
+
+msgid "guards in series file:\n"
+msgstr ""
+
+msgid "no guards in series file\n"
+msgstr ""
+
+msgid "active guards:\n"
+msgstr ""
+
+msgid "no active guards\n"
+msgstr ""
+
+msgid "popping guarded patches\n"
+msgstr ""
+
+msgid "reapplying unguarded patches\n"
+msgstr ""
+
+msgid ""
+"move applied patches into repository history\n"
+"\n"
+" Finishes the specified revisions (corresponding to applied\n"
+" patches) by moving them out of mq control into regular repository\n"
+" history.\n"
+"\n"
+" Accepts a revision range or the -a/--applied option. If --applied\n"
+" is specified, all applied mq revisions are removed from mq\n"
+" control. Otherwise, the given revisions must be at the base of the\n"
+" stack of applied patches.\n"
+"\n"
+" This can be especially useful if your changes have been applied to\n"
+" an upstream repository, or if you are about to push your changes\n"
+" to upstream.\n"
+" "
+msgstr ""
+
+msgid "no revisions specified"
+msgstr "ingen revisioner specificeret"
+
+msgid "cannot commit over an applied mq patch"
+msgstr "kan ikke deponere henover en anvendt mq rettelse"
+
+msgid "source has mq patches applied"
+msgstr "målet har mq rettelser anvendt"
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr ""
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr "Mærkaten %s overstyrer mq rettelse med samme navn\n"
+
+msgid "cannot import over an applied patch"
+msgstr "kan ikke importere henover en anvendt rettelse"
+
+msgid "print first line of patch header"
+msgstr ""
+
+msgid "hg qapplied [-s] [PATCH]"
+msgstr "hg qapplied [-s] [RETTELSE]"
+
+msgid "use pull protocol to copy metadata"
+msgstr "brug træk-protokol til at kopiere metadata"
+
+msgid "do not update the new working directories"
+msgstr "undlad at opdatere det nye arbejdskatalog"
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr "brug ukomprimeret overførsel (hurtig over LAN)"
+
+msgid "location of source patch repository"
+msgstr "placering af kilde rettelse-depotet"
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr "hg qclone [TILVALG]... KILDE [MÃ…L]"
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr "hg qcommit [TILVALG]... [FIL]..."
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr "hg qdiff [TILVALG]... [FIL]..."
+
+msgid "keep patch file"
+msgstr ""
+
+msgid "stop managing a revision (DEPRECATED)"
+msgstr ""
+
+msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
+msgstr "hg qdelete [-k] [-r REV]... [RETTELSE]..."
+
+msgid "edit patch header"
+msgstr ""
+
+msgid "keep folded patch files"
+msgstr ""
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr "hg qfold [-e] [-k] [-m TEKST] [-l FIL] RETTELSE..."
+
+msgid "overwrite any local changes"
+msgstr "overskrive eventuelle lokale ændringer"
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr "hg qgoto [TILVALG]... RETTELSE"
+
+msgid "list all patches and guards"
+msgstr ""
+
+msgid "drop all guards"
+msgstr ""
+
+msgid "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+msgstr "hg qguard [-l] [-n] -- [RETTELSE] [+VAGT]... [-VAGT]..."
+
+msgid "hg qheader [PATCH]"
+msgstr "hg qheader [RETTELSE]"
+
+msgid "import file in patch directory"
+msgstr ""
+
+msgid "name of patch file"
+msgstr "navn på rettelse"
+
+msgid "overwrite existing files"
+msgstr "overskriv eksisterende filer"
+
+msgid "place existing revisions under mq control"
+msgstr "placer eksisterende revisioner under mq-kontrol"
+
+msgid "use git extended diff format"
+msgstr "brug git udvidet diff-format"
+
+msgid "qpush after importing"
+msgstr "qpush efter import"
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr "hg qimport [-e] [-n NAVN] [-f] [-g] [-P] [-r REV]... FIL..."
+
+msgid "create queue repository"
+msgstr "opret kø-repository"
+
+msgid "hg qinit [-c]"
+msgstr "hg qinit [-c]"
+
+msgid "import uncommitted changes into patch"
+msgstr ""
+
+msgid "add \"From: <current user>\" to patch"
+msgstr "tilføj \"From: <aktuel bruger>\" til rettelsen"
+
+msgid "add \"From: <given user>\" to patch"
+msgstr "tilføj \"From: <given bruger>\" til rettelsen"
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr "tilføj \"Date: <aktuel dato>\" til rettelsen"
+
+msgid "add \"Date: <given date>\" to patch"
+msgstr "tilføj \"Date: <given dato>\" til rettelsen"
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+msgstr "hg qnew [-e] [-m TEKST] [-l FIL] [-f] RETTELSE [FIL]..."
+
+msgid "hg qnext [-s]"
+msgstr "hg qnext [-s]"
+
+msgid "hg qprev [-s]"
+msgstr "hg qprev [-s]"
+
+msgid "pop all patches"
+msgstr "fjern alle rettelser"
+
+msgid "queue name to pop"
+msgstr ""
+
+msgid "forget any local changes"
+msgstr "glem eventuelle lokale ændringer"
+
+msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+msgstr "hg qpop [-a] [-n NAVN] [-f] [RETTELSE | INDEKS]"
+
+msgid "apply if the patch has rejects"
+msgstr ""
+
+msgid "list patch name in commit text"
+msgstr ""
+
+msgid "apply all patches"
+msgstr "anvend alle rettelser"
+
+msgid "merge from another queue"
+msgstr ""
+
+msgid "merge queue name"
+msgstr ""
+
+msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+msgstr "hg qpush [-f] [-l] [-a] [-m] [-n NAVN] [RETTELSE | INDEKS]"
+
+msgid "refresh only files already in the patch and specified files"
+msgstr ""
+
+msgid "add/update \"From: <current user>\" in patch"
+msgstr "tilføj/opdater \"From: <aktuel bruger>\" i rettelsen"
+
+msgid "add/update \"From: <given user>\" in patch"
+msgstr "tilføj/opdater \"From: <given bruger>\" i rettelsen"
+
+msgid "update \"Date: <current date>\" in patch (if present)"
+msgstr "opdater \"Date: <aktuel dato>\" i rettelsen (hvis tilstede)"
+
+msgid "update \"Date: <given date>\" in patch (if present)"
+msgstr "opdater \"Date: <given dato>\" i rettelsen (hvis tilstede)"
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr "hg qrefresh [-I] [-X] [-e] [-m TEKST] [-l FIL] [-s] [FIL]..."
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr "hg qrename RETTELSE1 [RETTELSE2]"
+
+msgid "delete save entry"
+msgstr ""
+
+msgid "update queue working directory"
+msgstr ""
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr "hg qrestore [-d] [-u] REV"
+
+msgid "copy patch directory"
+msgstr ""
+
+msgid "copy directory name"
+msgstr ""
+
+msgid "clear queue status file"
+msgstr ""
+
+msgid "force copy"
+msgstr ""
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr "hg qsave [-m TEKST] [-l FIL] [-c] [-n NAVN] [-e] [-f]"
+
+msgid "disable all guards"
+msgstr ""
+
+msgid "list all guards in series file"
+msgstr ""
+
+msgid "pop to before first guarded applied patch"
+msgstr ""
+
+msgid "pop, then reapply patches"
+msgstr ""
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr "hg qselect [TILVALG]... [VAGT]..."
+
+msgid "print patches not in series"
+msgstr ""
+
+msgid "hg qseries [-ms]"
+msgstr "hg qseries [-ms]"
+
+msgid "force removal with local changes"
+msgstr ""
+
+msgid "bundle unrelated changesets"
+msgstr ""
+
+msgid "no backups"
+msgstr "ingen backupper"
+
+msgid "hg strip [-f] [-b] [-n] REV"
+msgstr "hg strip [-f] [-b] [-n] REV"
+
+msgid "hg qtop [-s]"
+msgstr "hg qtop [-s]"
+
+msgid "hg qunapplied [-s] [PATCH]"
+msgstr "hg qunapplied [-s] [RETTELSE]"
+
+msgid "finish all applied changesets"
+msgstr "afslut alle anvendte ændringer"
+
+msgid "hg qfinish [-a] [REV]..."
+msgstr "hg qfinish [-a] [REV]..."
+
+msgid ""
+"hooks for sending email notifications at commit/push time\n"
+"\n"
+"Subscriptions can be managed through hgrc. Default mode is to print\n"
+"messages to stdout, for testing and configuring.\n"
+"\n"
+"To use, configure notify extension and enable in hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # one email for each incoming changeset\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # batch emails when many changesets incoming at one time\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # config items go in here\n"
+"\n"
+" config items:\n"
+"\n"
+" REQUIRED:\n"
+" config = /path/to/file # file containing subscriptions\n"
+"\n"
+" OPTIONAL:\n"
+" test = True # print messages to stdout for testing\n"
+" strip = 3 # number of slashes to strip for url paths\n"
+" domain = example.com # domain to use if committer missing domain\n"
+" style = ... # style file to use when formatting email\n"
+" template = ... # template to use when formatting email\n"
+" incoming = ... # template to use when run as incoming hook\n"
+" changegroup = ... # template when run as changegroup hook\n"
+" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n"
+" maxsubject = 67 # truncate subject line longer than this\n"
+" diffstat = True # add a diffstat before the diff content\n"
+" sources = serve # notify if source of incoming changes in this "
+"list\n"
+" # (serve == ssh or http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # email address to send as if none given\n"
+" [web]\n"
+" baseurl = http://hgserver/... # root of hg web site for browsing commits\n"
+"\n"
+" notify config file has same format as regular hgrc. it has two\n"
+" sections so you can express subscriptions in whatever way is handier\n"
+" for you.\n"
+"\n"
+" [usersubs]\n"
+" # key is subscriber email, value is \",\"-separated list of glob "
+"patterns\n"
+" user@host = pattern\n"
+"\n"
+" [reposubs]\n"
+" # key is glob pattern, value is \",\"-separated list of subscriber "
+"emails\n"
+" pattern = user@host\n"
+"\n"
+" glob patterns are matched against path to repository root.\n"
+"\n"
+" if you like, you can put notify config file in repository that users\n"
+" can push changes to, they can manage their own subscriptions."
+msgstr ""
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr "%s: %d nye ændringer"
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr "notify: sender %d abonnenter %d ændringer\n"
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "notify: no subscribers to repository %s\n"
+msgstr "notify: ingen abonnementer til depot %s\n"
+
+#, python-format
+msgid "notify: changes have source \"%s\" - skipping\n"
+msgstr "notify: ændringer har kilde \"%s\" - springer over\n"
+
+msgid ""
+"browse command output with an external pager\n"
+"\n"
+"To set the pager that should be used, set the application variable:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"If no pager is set, the pager extensions uses the environment variable\n"
+"$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.\n"
+"\n"
+"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
+"setting:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"You can also enable the pager only for certain commands using\n"
+"pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"If pager.attend is present, pager.ignore will be ignored.\n"
+"\n"
+"To ignore global commands like \"hg version\" or \"hg help\", you have to\n"
+"specify them in the global .hgrc\n"
+msgstr ""
+
+msgid ""
+"interpret suffixes to refer to ancestor revisions\n"
+"\n"
+"This extension allows you to use git-style suffixes to refer to the\n"
+"ancestors of a specific revision.\n"
+"\n"
+"For example, if you can refer to a revision as \"foo\", then:\n"
+"\n"
+"- foo^N = Nth parent of foo\n"
+" foo^0 = foo\n"
+" foo^1 = first parent of foo\n"
+" foo^2 = second parent of foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nth first grandparent of foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = first parent of foo\n"
+" foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
+msgstr ""
+
+msgid ""
+"command to send changesets as (a series of) patch emails\n"
+"\n"
+"The series is started off with a \"[PATCH 0 of N]\" introduction, which\n"
+"describes the series as a whole.\n"
+"\n"
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using the\n"
+"first line of the changeset description as the subject text. The\n"
+"message contains two or three body parts:\n"
+"\n"
+" The changeset description.\n"
+"\n"
+" [Optional] The result of running diffstat on the patch.\n"
+"\n"
+" The patch itself, as generated by \"hg export\".\n"
+"\n"
+"Each message refers to the first in the series using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in threaded\n"
+"mail and news readers, and in mail archives.\n"
+"\n"
+"With the -d/--diffstat option, you will be prompted for each changeset\n"
+"with a diffstat summary and the changeset summary, so you can be sure\n"
+"you are sending the right changes.\n"
+"\n"
+"To configure other defaults, add a section like this to your hgrc\n"
+"file:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Then you can use the \"hg email\" command to mail a series of changesets\n"
+"as a patchbomb.\n"
+"\n"
+"To avoid sending patches prematurely, it is a good idea to first run\n"
+"the \"email\" command with the \"-n\" option (test only). You will be\n"
+"prompted for an email recipient address, a subject and an introductory\n"
+"message describing the patches of your patchbomb. Then when all is\n"
+"done, patchbomb messages are displayed. If the PAGER environment\n"
+"variable is set, your pager will be fired up once for each patchbomb\n"
+"message, so you can verify everything is alright.\n"
+"\n"
+"The -m/--mbox option is also very useful. Instead of previewing each\n"
+"patchbomb message in a pager or sending the messages directly, it will\n"
+"create a UNIX mailbox file with the patch emails. This mailbox file\n"
+"can be previewed with any mail user agent which supports UNIX mbox\n"
+"files, e.g. with mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"When you are previewing the patchbomb messages, you can use `formail'\n"
+"(a utility that is commonly installed as part of the procmail\n"
+"package), to send each message out:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"That should be all. Now your patchbomb is on its way out.\n"
+"\n"
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatible mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs\n"
+"directly from the commandline. See the [email] and [smtp] sections in\n"
+"hgrc(5) for details."
+msgstr ""
+
+msgid "Please enter a valid value.\n"
+msgstr "Angiv venligst en gyldig værdi.\n"
+
+msgid "does the diffstat above look okay? "
+msgstr ""
+
+msgid "diffstat rejected"
+msgstr "diffstat afvist"
+
+msgid ""
+"send changesets by email\n"
+"\n"
+" By default, diffs are sent in the format generated by hg export,\n"
+" one per message. The series starts with a \"[PATCH 0 of N]\"\n"
+" introduction, which describes the series as a whole.\n"
+"\n"
+" Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+" the first line of the changeset description as the subject text.\n"
+" The message contains two or three parts. First, the changeset\n"
+" description. Next, (optionally) if the diffstat program is\n"
+" installed and -d/--diffstat is used, the result of running\n"
+" diffstat on the patch. Finally, the patch itself, as generated by\n"
+" \"hg export\".\n"
+"\n"
+" By default the patch is included as text in the email body for\n"
+" easy reviewing. Using the -a/--attach option will instead create\n"
+" an attachment for the patch. With -i/--inline an inline attachment\n"
+" will be created.\n"
+"\n"
+" With -o/--outgoing, emails will be generated for patches not found\n"
+" in the destination repository (or only those which are ancestors\n"
+" of the specified revisions if any are provided)\n"
+"\n"
+" With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+" single email containing a binary Mercurial bundle as an attachment\n"
+" will be sent.\n"
+"\n"
+" Examples:\n"
+"\n"
+" hg email -r 3000 # send patch 3000 only\n"
+" hg email -r 3000 -r 3001 # send patches 3000 and 3001\n"
+" hg email -r 3000:3005 # send patches 3000 through 3005\n"
+" hg email 3000 # send patch 3000 (deprecated)\n"
+"\n"
+" hg email -o # send all patches not in default\n"
+" hg email -o DEST # send all patches not in DEST\n"
+" hg email -o -r 3000 # send all ancestors of 3000 not in default\n"
+" hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST\n"
+"\n"
+" hg email -b # send bundle of all patches not in default\n"
+" hg email -b DEST # send bundle of all patches not in DEST\n"
+" hg email -b -r 3000 # bundle of all ancestors of 3000 not in "
+"default\n"
+" hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST\n"
+"\n"
+" Before using this command, you will need to enable email in your\n"
+" hgrc. See the [email] section in hgrc(5) for details.\n"
+" "
+msgstr ""
+
+msgid "specify at least one changeset with -r or -o"
+msgstr "angiv mindst en ændring med -r eller -o"
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr ""
+
+msgid "too many destinations"
+msgstr "for mange destinationer"
+
+msgid "use only one form to specify the revision"
+msgstr ""
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series.\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"This patch series consists of %d patches.\n"
+"\n"
+msgstr ""
+
+msgid "Final summary:\n"
+msgstr ""
+
+msgid "Displaying "
+msgstr "Viser "
+
+msgid "Writing "
+msgstr "Skriver "
+
+msgid "Sending "
+msgstr "Sender "
+
+msgid "send patches as attachments"
+msgstr "send rettelser som vedhæftede filer"
+
+msgid "send patches as inline attachments"
+msgstr "send rettelser som integreret tekst"
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr ""
+
+msgid "email addresses of copy recipients"
+msgstr ""
+
+msgid "add diffstat output to messages"
+msgstr "tilføj diffstat resultat til beskeder"
+
+msgid "use the given date as the sending date"
+msgstr ""
+
+msgid "use the given file as the series description"
+msgstr ""
+
+msgid "email address of sender"
+msgstr ""
+
+msgid "print messages that would be sent"
+msgstr ""
+
+msgid "write messages to mbox file instead of sending them"
+msgstr ""
+
+msgid "subject of first message (intro or single patch)"
+msgstr ""
+
+msgid "message identifier to reply to"
+msgstr ""
+
+msgid "email addresses of recipients"
+msgstr ""
+
+msgid "omit hg patch header"
+msgstr ""
+
+msgid "send changes not found in the target repository"
+msgstr ""
+
+msgid "send changes not in target as a binary bundle"
+msgstr ""
+
+msgid "name of the bundle attachment file"
+msgstr ""
+
+msgid "a revision to send"
+msgstr ""
+
+msgid "run even when remote repository is unrelated (with -b/--bundle)"
+msgstr "kør selv hvis fjerndepotet er urelateret (med -b/--bundle)"
+
+msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
+msgstr ""
+
+msgid "send an introduction email for a single patch"
+msgstr ""
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr "hg email [TILVALG]... [MÃ…L]..."
+
+msgid "command to delete untracked files from the working directory"
+msgstr "kommando til at slette filer fra arbejdskataloget som ikke følges"
+
+msgid ""
+"removes files not tracked by Mercurial\n"
+"\n"
+" Delete files not known to Mercurial. This is useful to test local\n"
+" and uncommitted changes in an otherwise-clean source tree.\n"
+"\n"
+" This means that purge will delete:\n"
+" - Unknown files: files marked with \"?\" by \"hg status\"\n"
+" - Empty directories: in fact Mercurial ignores directories unless\n"
+" they contain files under source control management\n"
+" But it will leave untouched:\n"
+" - Modified and unmodified tracked files\n"
+" - Ignored files (unless --all is specified)\n"
+" - New files added to the repository (with \"hg add\")\n"
+"\n"
+" If directories are given on the command line, only files in these\n"
+" directories are considered.\n"
+"\n"
+" Be careful with purge, as you could irreversibly delete some files\n"
+" you forgot to add to the repository. If you only want to print the\n"
+" list of files that this program would delete, use the --print\n"
+" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr "%s kan ikke slettes"
+
+#, python-format
+msgid "warning: %s\n"
+msgstr "advarsel: %s\n"
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr "Fjerner fil %s\n"
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr "Fjerner katalog %s\n"
+
+msgid "abort if an error occurs"
+msgstr "afbryd hvis der opstår en fejl"
+
+msgid "purge ignored files too"
+msgstr "udrens også ignorerede filer"
+
+msgid "print filenames instead of deleting them"
+msgstr "udskriv filnavne i stedet for at slette dem"
+
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr "afslut filnavne med NUL, for brug med xargs (medfører -p/--print)"
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr "hg purge [TILVALG]... [KATALOG]..."
+
+msgid ""
+"command to move sets of revisions to a different ancestor\n"
+"\n"
+"This extension lets you rebase changesets in an existing Mercurial\n"
+"repository.\n"
+"\n"
+"For more information:\n"
+"http://mercurial.selenic.com/wiki/RebaseProject\n"
+msgstr ""
+
+msgid "first revision, do not change ancestor\n"
+msgstr ""
+
+msgid ""
+"move changeset (and descendants) to a different branch\n"
+"\n"
+" Rebase uses repeated merging to graft changesets from one part of\n"
+" history onto another. This can be useful for linearizing local\n"
+" changes relative to a master development tree.\n"
+"\n"
+" If a rebase is interrupted to manually resolve a merge, it can be\n"
+" continued with --continue/-c or aborted with --abort/-a.\n"
+" "
+msgstr ""
+
+msgid "cannot use both abort and continue"
+msgstr ""
+
+msgid "cannot use collapse with continue or abort"
+msgstr ""
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr ""
+
+msgid "cannot specify both a revision and a base"
+msgstr ""
+
+msgid "nothing to rebase\n"
+msgstr ""
+
+msgid "cannot use both keepbranches and extrafn"
+msgstr ""
+
+msgid "rebase merging completed\n"
+msgstr ""
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr ""
+
+msgid "rebase completed\n"
+msgstr ""
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr ""
+
+msgid " set parents\n"
+msgstr ""
+
+#, python-format
+msgid "rebasing %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid " future parents are %d and %d\n"
+msgstr ""
+
+#, python-format
+msgid " update to %d:%s\n"
+msgstr " opdater til %d:%s\n"
+
+msgid " already in target\n"
+msgstr ""
+
+#, python-format
+msgid " merge against %d:%s\n"
+msgstr ""
+
+msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgstr ""
+
+msgid "resuming interrupted rebase\n"
+msgstr ""
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr ""
+
+#, python-format
+msgid "next revision set to %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr ""
+
+#, python-format
+msgid "revision %d is an mq patch (%s), finalize it.\n"
+msgstr ""
+
+#, python-format
+msgid "import mq patch %d (%s)\n"
+msgstr ""
+
+msgid "rebase status stored\n"
+msgstr ""
+
+msgid "rebase status resumed\n"
+msgstr ""
+
+msgid "no rebase in progress"
+msgstr ""
+
+msgid "warning: new changesets detected on target branch, not stripping\n"
+msgstr ""
+
+msgid "rebase aborted\n"
+msgstr ""
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr ""
+
+msgid "cannot rebase an ancestor"
+msgstr ""
+
+msgid "cannot rebase a descendant"
+msgstr ""
+
+msgid "already working on current\n"
+msgstr ""
+
+msgid "already working on the current branch\n"
+msgstr ""
+
+#, python-format
+msgid "rebase onto %d starting from %d\n"
+msgstr ""
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr ""
+
+msgid "--update and --rebase are not compatible, ignoring the update flag\n"
+msgstr ""
+
+msgid "rebase working directory to branch head"
+msgstr ""
+
+msgid "rebase from a given revision"
+msgstr ""
+
+msgid "rebase from the base of a given revision"
+msgstr ""
+
+msgid "rebase onto a given revision"
+msgstr ""
+
+msgid "collapse the rebased revisions"
+msgstr ""
+
+msgid "keep original revisions"
+msgstr ""
+
+msgid "keep original branches"
+msgstr ""
+
+msgid "continue an interrupted rebase"
+msgstr ""
+
+msgid "abort an interrupted rebase"
+msgstr ""
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+msgstr ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+
+msgid "commands to interactively select changes for commit/qrefresh"
+msgstr ""
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr "dette ændrer en binær fil (alt eller intet)\n"
+
+msgid "this is a binary file\n"
+msgstr "dette er en binær fil\n"
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr "%d stumper, %d linjer ændret\n"
+
+msgid "[Ynsfdaq?]"
+msgstr ""
+
+msgid "&Yes, record this change"
+msgstr ""
+
+msgid "&No, skip this change"
+msgstr ""
+
+msgid "&Skip remaining changes to this file"
+msgstr ""
+
+msgid "Record remaining changes to this &file"
+msgstr ""
+
+msgid "&Done, skip remaining changes and files"
+msgstr ""
+
+msgid "Record &all changes to all remaining files"
+msgstr ""
+
+msgid "&Quit, recording no changes"
+msgstr ""
+
+msgid "&?"
+msgstr ""
+
+msgid "y"
+msgstr ""
+
+msgid "?"
+msgstr ""
+
+msgid "y - record this change"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "f"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "a"
+msgstr ""
+
+msgid "q"
+msgstr ""
+
+msgid "user quit"
+msgstr "user quit"
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr "undersøg ændringer i %s?"
+
+msgid " and "
+msgstr " og "
+
+#, python-format
+msgid "record this change to %r?"
+msgstr "optag denne ændring i %r?"
+
+#, python-format
+msgid "record change %d/%d to %r?"
+msgstr "optag ændring %d/%d i %r?"
+
+msgid ""
+"interactively select changes to commit\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be candidates for recording.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" You will be prompted for whether to record changes to each\n"
+" modified file, and for files with multiple changes, for each\n"
+" change to use. For each query, the following responses are\n"
+" possible:\n"
+"\n"
+" y - record this change\n"
+" n - skip this change\n"
+"\n"
+" s - skip remaining changes to this file\n"
+" f - record remaining changes to this file\n"
+"\n"
+" d - done, skip remaining changes and files\n"
+" a - record all changes to all remaining files\n"
+" q - quit, recording no changes\n"
+"\n"
+" ? - display help"
+msgstr ""
+
+msgid "'mq' extension not loaded"
+msgstr ""
+
+msgid "running non-interactively, use commit instead"
+msgstr ""
+
+msgid "no changes to record\n"
+msgstr ""
+
+#, python-format
+msgid "backup %r as %r\n"
+msgstr "sikkerhedskopier %r som %r\n"
+
+msgid "applying patch\n"
+msgstr "tilføjer rettelse\n"
+
+msgid "patch failed to apply"
+msgstr "rettelse kunne ikke tilføjes"
+
+#, python-format
+msgid "restoring %r to %r\n"
+msgstr "gendanner %r som %r\n"
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr "hg record [TILVALG]... [FIL]..."
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr "hg qrecord [TILVALG]... RETTELSE [FIL]..."
+
+msgid "share a common history between several working directories"
+msgstr ""
+
+msgid ""
+"create a new shared repository (experimental)\n"
+"\n"
+" Initialize a new repository and working directory that shares its\n"
+" history with another repository.\n"
+"\n"
+" NOTE: actions that change history such as rollback or moving the\n"
+" source may confuse sharers.\n"
+" "
+msgstr ""
+
+msgid "do not create a working copy"
+msgstr "opret ikke en arbejdskopi"
+
+msgid "[-U] SOURCE [DEST]"
+msgstr ""
+
+msgid ""
+"command to transplant changesets from another branch\n"
+"\n"
+"This extension allows you to transplant patches from another branch.\n"
+"\n"
+"Transplanted patches are recorded in .hg/transplant/transplants, as a\n"
+"map from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr ""
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr "%s transplanteret til %s\n"
+
+#, python-format
+msgid "filtering %s\n"
+msgstr "filtrerer %s\n"
+
+msgid "filter failed"
+msgstr "filter fejlede"
+
+msgid "can only omit patchfile if merging"
+msgstr ""
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr "%s: tom ændring"
+
+msgid "Fix up the merge and run hg transplant --continue"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr "%s transplanteret som %s\n"
+
+msgid "transplant log file is corrupt"
+msgstr ""
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr ""
+
+msgid "commit failed"
+msgstr "deponering fejlede"
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr ""
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+" Selected changesets will be applied on top of the current working\n"
+" directory with the log of the original changeset. If --log is\n"
+" specified, log messages will have a comment appended of the form:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" You can rewrite the changelog message with the --filter option.\n"
+" Its argument will be invoked with the current changelog message as\n"
+" $1 and the patch as $2.\n"
+"\n"
+" If --source/-s is specified, selects changesets from the named\n"
+" repository. If --branch/-b is specified, selects changesets from\n"
+" the branch holding the named revision, up to that revision. If\n"
+" --all/-a is specified, all changesets on the branch will be\n"
+" transplanted, otherwise you will be prompted to select the\n"
+" changesets you want.\n"
+"\n"
+" hg transplant --branch REVISION --all will rebase the selected\n"
+" branch (up to the named revision) onto your current working\n"
+" directory.\n"
+"\n"
+" You can optionally mark selected transplanted changesets as merge\n"
+" changesets. You will not be prompted to transplant any ancestors\n"
+" of a merged transplant, and you can merge descendants of them\n"
+" normally instead of transplanting them.\n"
+"\n"
+" If no merges or revisions are provided, hg transplant will start\n"
+" an interactive changeset browser.\n"
+"\n"
+" If a changeset application fails, you can fix the merge by hand\n"
+" and then resume where you left off by calling hg transplant\n"
+" --continue/-c.\n"
+" "
+msgstr ""
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr "--continue er inkompatibelt med branch, all eller merge"
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr ""
+
+msgid "--all requires a branch revision"
+msgstr ""
+
+msgid "--all is incompatible with a revision list"
+msgstr "--all er inkompatibelt med en revisionsliste"
+
+msgid "no revision checked out"
+msgstr ""
+
+msgid "outstanding uncommitted merges"
+msgstr "udestående udeponeret sammenføjning"
+
+msgid "outstanding local changes"
+msgstr "udestående lokale ændringer"
+
+msgid "pull patches from REPOSITORY"
+msgstr "hiv rettelser fra DEPOT"
+
+msgid "pull patches from branch BRANCH"
+msgstr "hiv rettelser fra gren GREN"
+
+msgid "pull all changesets up to BRANCH"
+msgstr "his alle ændringer indtil GREN"
+
+msgid "skip over REV"
+msgstr "spring over REV"
+
+msgid "merge at REV"
+msgstr "sammenføj ved REV"
+
+msgid "append transplant info to log message"
+msgstr ""
+
+msgid "continue last transplant session after repair"
+msgstr ""
+
+msgid "filter changesets through FILTER"
+msgstr "filtrer ændringer igennem FILTER"
+
+msgid ""
+"hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr "hg transplant [-s DEPOT] [-b GREN [-a]] [-p REV] [-m REV] [REV]..."
+
+msgid ""
+"allow the use of MBCS paths with problematic encodings\n"
+"\n"
+"Some MBCS encodings are not good for some path operations (i.e.\n"
+"splitting path, case conversion, etc.) with its encoded bytes. We call\n"
+"such a encoding (i.e. shift_jis and big5) as \"problematic encoding\".\n"
+"This extension can be used to fix the issue with those encodings by\n"
+"wrapping some functions to convert to Unicode string before path\n"
+"operation.\n"
+"\n"
+"This extension is useful for:\n"
+" * Japanese Windows users using shift_jis encoding.\n"
+" * Chinese Windows users using big5 encoding.\n"
+" * All users who use a repository with one of problematic encodings on\n"
+" case-insensitive file system.\n"
+"\n"
+"This extension is not needed for:\n"
+" * Any user who use only ASCII chars in path.\n"
+" * Any user who do not use any of problematic encodings.\n"
+"\n"
+"Note that there are some limitations on using this extension:\n"
+" * You should use single encoding in one repository.\n"
+" * You should set same encoding for the repository by locale or\n"
+" HGENCODING.\n"
+"\n"
+"Path encoding conversion are done between Unicode and\n"
+"encoding.encoding which is decided by Mercurial from current locale\n"
+"setting or HGENCODING.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] filename conversion fail with %s encoding\n"
+msgstr ""
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] activated with encoding: %s\n"
+msgstr ""
+
+msgid ""
+"perform automatic newline conversion\n"
+"\n"
+"To perform automatic newline conversion, use:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = cleverencode:\n"
+"# or ** = macencode:\n"
+"\n"
+"[decode]\n"
+"** = cleverdecode:\n"
+"# or ** = macdecode:\n"
+"\n"
+"If not doing conversion, to make sure you do not commit CRLF/CR by "
+"accident:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxncommit.cr = python:hgext.win32text.forbidcr\n"
+"\n"
+"To do the same check on a server to prevent CRLF/CR from being\n"
+"pushed or pulled:\n"
+"\n"
+"[hooks]\n"
+"pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxnchangegroup.cr = python:hgext.win32text.forbidcr\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr ""
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"and also consider adding:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+
+msgid ""
+"discover and advertise repositories on the local network\n"
+"\n"
+"Zeroconf enabled repositories will be announced in a network without\n"
+"the need to configure a server or a service. They can be discovered\n"
+"without knowing their actual IP address.\n"
+"\n"
+"To allow other people to discover your repository using run \"hg serve\"\n"
+"in your repository.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"You can discover zeroconf enabled repositories by running \"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+msgstr ""
+
+msgid "archive prefix contains illegal components"
+msgstr "depotpræfix indeholder ugyldige komponenter"
+
+msgid "cannot give prefix when archiving to files"
+msgstr "kan ikke give præfix ved arkivering til filer"
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr "ukendt depottype '%s'"
+
+msgid "invalid changegroup"
+msgstr ""
+
+msgid "unknown parent"
+msgstr "ukendt forælder"
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr "integritetstjek fejlede på %s:%d"
+
+#, python-format
+msgid "%s: not a Mercurial bundle file"
+msgstr "%s er ikke en Mercurial bundle fil"
+
+#, python-format
+msgid "%s: unknown bundle version"
+msgstr "%s: ukendt bundle version"
+
+#, python-format
+msgid "%s: unknown bundle compression type"
+msgstr "%s: ukendt bundle kompressionstype"
+
+msgid "cannot create new bundle repository"
+msgstr ""
+
+#, python-format
+msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgstr "for tidlig EOF ved læsning af chunk (fik %d bytes, forventede %d)"
+
+msgid "empty username"
+msgstr "tomt brugernavn"
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr "brugernavn %s indeholder et linieskift"
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr ""
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr "kan ikke læse deponeringsbesked '%s': %s"
+
+msgid "limit must be a positive integer"
+msgstr ""
+
+msgid "limit must be positive"
+msgstr ""
+
+msgid "too many revisions specified"
+msgstr "der er specificeret for mange revisioner"
+
+#, python-format
+msgid "invalid format spec '%%%s' in output filename"
+msgstr ""
+
+#, python-format
+msgid "adding %s\n"
+msgstr "tilføjer %s\n"
+
+#, python-format
+msgid "removing %s\n"
+msgstr "fjerner %s\n"
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr "noterer fjernelse af %s som en omdøbning til %s (%d%% lighed)\n"
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr "%s: kopierer ikke - filen er ikke versionsstyret\n"
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr "%s: kopierer ikke - filen er markeret til sletning\n"
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr "%s: overskriver ikke - %s kolliderer med %s\n"
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr "%s: overskriver ikke - filen eksisterer\n"
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr "%s: slettet i arbejdskopien\n"
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr "%s: kan ikke kopiere - %s\n"
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr "flytter %s til %s\n"
+
+#, python-format
+msgid "copying %s to %s\n"
+msgstr "kopierer %s til %s\n"
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+"%s er endnu ikke comitted, så der vil ikke blive gemt kopieringsdata for %"
+"s.\n"
+
+msgid "no source or destination specified"
+msgstr "ingen kilde eller destination angivet"
+
+msgid "no destination specified"
+msgstr "ingen destination angivet"
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr ""
+"destinationen skal være en eksisterende mappe når der angivet flere kilder"
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr "destinationen %s er ikke en mappe"
+
+msgid "no files to copy"
+msgstr "ingen filer at kopiere"
+
+msgid "(consider using --after)\n"
+msgstr "(overvej at bruge --after)\n"
+
+#, python-format
+msgid "changeset: %d:%s\n"
+msgstr "ændring: %d:%s\n"
+
+#, python-format
+msgid "branch: %s\n"
+msgstr "gren: %s\n"
+
+#, python-format
+msgid "tag: %s\n"
+msgstr "mærkat: %s\n"
+
+#, python-format
+msgid "parent: %d:%s\n"
+msgstr "forælder: %d:%s\n"
+
+#, python-format
+msgid "manifest: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "user: %s\n"
+msgstr "bruger: %s\n"
+
+#, python-format
+msgid "date: %s\n"
+msgstr "dato: %s\n"
+
+msgid "files+:"
+msgstr "filer+:"
+
+msgid "files-:"
+msgstr "filer-:"
+
+msgid "files:"
+msgstr "filer:"
+
+#, python-format
+msgid "files: %s\n"
+msgstr "filer: %s\n"
+
+#, python-format
+msgid "copies: %s\n"
+msgstr "kopier: %s\n"
+
+#, python-format
+msgid "extra: %s=%s\n"
+msgstr "ekstra: %s=%s\n"
+
+msgid "description:\n"
+msgstr "beskrivelse:\n"
+
+#, python-format
+msgid "summary: %s\n"
+msgstr "uddrag: %s\n"
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr ""
+
+#, python-format
+msgid "%s: %s"
+msgstr ""
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr ""
+
+msgid "revision matching date not found"
+msgstr ""
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "%s:%s copy source revision cannot be found!\n"
+msgstr ""
+
+msgid "can only follow copies/renames for explicit filenames"
+msgstr ""
+
+msgid "HG: Enter commit message. Lines beginning with 'HG:' are removed."
+msgstr ""
+"HG: Skriv deponeringsbesked. Linier som starter med 'HG:' bliver fjernet."
+
+msgid "HG: Leave message empty to abort commit."
+msgstr "HG: Efterlad beskeden tom for at afbryde deponeringen."
+
+#, python-format
+msgid "HG: user: %s"
+msgstr "HG: bruger: %s"
+
+msgid "HG: branch merge"
+msgstr "HG: gren-sammenføjning"
+
+#, python-format
+msgid "HG: branch '%s'"
+msgstr "HG: gren '%s'"
+
+#, python-format
+msgid "HG: subrepo %s"
+msgstr "HG: underdepot %s"
+
+#, python-format
+msgid "HG: added %s"
+msgstr "HG: tilføjet %s"
+
+#, python-format
+msgid "HG: changed %s"
+msgstr "HG: ændret %s"
+
+#, python-format
+msgid "HG: removed %s"
+msgstr "HG: fjernet %s"
+
+msgid "HG: no files changed"
+msgstr "HG: ingen filændringer"
+
+msgid "empty commit message"
+msgstr "tom deponeringsbesked"
+
+msgid ""
+"add the specified files on the next commit\n"
+"\n"
+" Schedule files to be version controlled and added to the\n"
+" repository.\n"
+"\n"
+" The files will be added to the repository at the next commit. To\n"
+" undo an add before that, see hg forget.\n"
+"\n"
+" If no names are given, add all files to the repository.\n"
+" "
+msgstr ""
+"tilføj de angivne filer ved næste deponering\n"
+"\n"
+" Opskriv filer til at blive versionsstyret og tilføjet til depotet.\n"
+"\n"
+" Filerne vil bliver tilføjet til depotet ved næste deponering. For\n"
+" at omgøre en tilføjelse før det, se hg forget.\n"
+"\n"
+" Hvis der ikke er angivet nogen navne tilføjes alle filer til\n"
+" depotet.\n"
+" "
+
+msgid ""
+"add all new files, delete all missing files\n"
+"\n"
+" Add all new files and remove all missing files from the\n"
+" repository.\n"
+"\n"
+" New files are ignored if they match any of the patterns in\n"
+" .hgignore. As with add, these changes take effect at the next\n"
+" commit.\n"
+"\n"
+" Use the -s/--similarity option to detect renamed files. With a\n"
+" parameter > 0, this compares every removed file with every added\n"
+" file and records those similar enough as renames. This option\n"
+" takes a percentage between 0 (disabled) and 100 (files must be\n"
+" identical) as its parameter. Detecting renamed files this way can\n"
+" be expensive.\n"
+" "
+msgstr ""
+
+msgid "similarity must be a number"
+msgstr ""
+
+msgid "similarity must be between 0 and 100"
+msgstr ""
+
+msgid ""
+"show changeset information by line for each file\n"
+"\n"
+" List changes in files, showing the revision id responsible for\n"
+" each line\n"
+"\n"
+" This command is useful for discovering when a change was made and\n"
+" by whom.\n"
+"\n"
+" Without the -a/--text option, annotate will avoid processing files\n"
+" it detects as binary. With -a, annotate will annotate the file\n"
+" anyway, although the results will probably be neither useful\n"
+" nor desirable.\n"
+" "
+msgstr ""
+"vis information om ændringer pr linie for hver fil\n"
+"\n"
+" Vis ændringer i filer ved at vise revisions ID'et som er\n"
+" ansvarligt for hver linie\n"
+"\n"
+" Denne kommando er nyttig til at opdage hvornår en ændring blev\n"
+" foretaget og af hvem.\n"
+"\n"
+" Uden -a/--text tilvalget vil annotate undgå at behandle filer som\n"
+" den detekterer som binære. Med -a vil annotate generere en\n"
+" annotering alligevel, selvom resultatet sandsynligvis vil være\n"
+" hverken brugbart eller ønskværdigt.\n"
+" "
+
+msgid "at least one filename or pattern is required"
+msgstr ""
+
+msgid "at least one of -n/-c is required for -l"
+msgstr ""
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr "%s: binær fil\n"
+
+msgid ""
+"create an unversioned archive of a repository revision\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use -r/--rev to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use -t/--type. Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see 'hg help export' for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use -p/--prefix to specify a format string for the\n"
+" prefix. The default is the basename of the archive, with suffixes\n"
+" removed.\n"
+" "
+msgstr ""
+
+msgid "no working directory: please specify a revision"
+msgstr "intet arbejdskatalog: angive venligst en revision"
+
+msgid "repository root cannot be destination"
+msgstr ""
+
+msgid "cannot archive plain files to stdout"
+msgstr ""
+
+msgid ""
+"reverse effect of earlier changeset\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you backout a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head.\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by hand.\n"
+" The result of this merge is not committed, as with a normal merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"omgør effekten af tidligere ændringer\n"
+"\n"
+" Deponerer de omgjorte ændringer som en ny ændring. Den nye ændring\n"
+" er et barn af den omgjorte ændring.\n"
+"\n"
+" Hvis du omgør en ændring som ikke er spidsen, så vil et der blive\n"
+" lavet et nyt hoved. Dette hoved vil være den nye spids og du bør\n"
+" sammenføje denne omgjorte ændring med et andet hoved (det\n"
+" nuværende hoved som standard).\n"
+"\n"
+" Med --merge tilvalget vil forælderen til arbejdskataloget blive\n"
+" husket og det nye hoved vil blive sammenføjet med denne ændring\n"
+" bagefter. Dette sparer dig for at lave sammenføjningen selv.\n"
+" Resultatet af denne sammenføjning er ikke lagt i depot, som ved en\n"
+" normal sammenføjning.\n"
+"\n"
+" Se 'hg help dates' for en liste af gyldige formater til -d/--date.\n"
+" "
+
+msgid "please specify just one revision"
+msgstr "angiv venligst kun en revision"
+
+msgid "please specify a revision to backout"
+msgstr "angiv venligst en revision der skal omgøres"
+
+msgid "cannot backout change on a different branch"
+msgstr "kan ikke omgøre en ændring på en anden gren"
+
+msgid "cannot backout a change with no parents"
+msgstr "kan ikke omgøre en ændring uden forældre"
+
+msgid "cannot backout a merge changeset without --parent"
+msgstr "kan ikke omgøre en sammenføjning uden --parent"
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr "%s er ikke forælder til %s"
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr ""
+
+#, python-format
+msgid "Backed out changeset %s"
+msgstr ""
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr "ændring %s bakker ændring %s ud\n"
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr "sammenføjer med ændring %s\n"
+
+msgid "the backout changeset is a new head - do not forget to merge\n"
+msgstr ""
+
+msgid "(use \"backout --merge\" if you want to auto-merge)\n"
+msgstr ""
+
+msgid ""
+"subdivision search of changesets\n"
+"\n"
+" This command helps to find changesets which introduce problems. To\n"
+" use, mark the earliest changeset you know exhibits the problem as\n"
+" bad, then mark the latest changeset which is free from the problem\n"
+" as good. Bisect will update your working directory to a revision\n"
+" for testing (unless the -U/--noupdate option is specified). Once\n"
+" you have performed tests, mark the working directory as good or\n"
+" bad, and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command, it will be used for automatic bisection.\n"
+" Its exit status will be used to mark revisions as good or bad:\n"
+" status 0 means good, 125 means to skip the revision, 127\n"
+" (command not found) will abort the bisection, and any other\n"
+" non-zero exit status means the revision is bad.\n"
+" "
+msgstr ""
+
+msgid "The first good revision is:\n"
+msgstr "Den første gode revision er:\n"
+
+msgid "The first bad revision is:\n"
+msgstr "Den første dårlige revision er:\n"
+
+msgid "Due to skipped revisions, the first good revision could be any of:\n"
+msgstr ""
+"På grund af oversprungne revisioner kan den første gode revision være en "
+"hvilken som helst af:\n"
+
+msgid "Due to skipped revisions, the first bad revision could be any of:\n"
+msgstr ""
+"På grund af oversprungne revisioner kan den første dårlige revision være en "
+"hvilken som helst af:\n"
+
+msgid "cannot bisect (no known good revisions)"
+msgstr ""
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr ""
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr ""
+
+msgid "incompatible arguments"
+msgstr "inkompatible argumenter"
+
+#, python-format
+msgid "cannot find executable: %s"
+msgstr "kan ikke finde program: %s"
+
+#, python-format
+msgid "failed to execute %s"
+msgstr ""
+
+#, python-format
+msgid "%s killed"
+msgstr "%s dræbt"
+
+#, python-format
+msgid "Changeset %d:%s: %s\n"
+msgstr "Ændring %d:%s: %s\n"
+
+#, python-format
+msgid "Testing changeset %s:%s (%s changesets remaining, ~%s tests)\n"
+msgstr "Tester ændring %s:%s (%s ændringer tilbage, ~%s test)\n"
+
+msgid ""
+"set or show the current branch name\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch will not exist\n"
+" in the repository until the next commit). Standard practice\n"
+" recommends that primary development take place on the 'default'\n"
+" branch.\n"
+"\n"
+" Unless -f/--force is specified, branch will not let you set a\n"
+" branch name that already exists, even if it's inactive.\n"
+"\n"
+" Use -C/--clean to reset the working directory branch to that of\n"
+" the parent of the working directory, negating a previous branch\n"
+" change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch. Use\n"
+" 'hg commit --close-branch' to mark this branch as closed.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr ""
+
+msgid "a branch of the same name already exists (use --force to override)"
+msgstr ""
+"en gren ved samme navn eksisterer allerede (brug --force for at gennemtvinge)"
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr "markerede arbejdskataloget som gren %s\n"
+
+msgid ""
+"list repository named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If -c/--closed is specified, also list branches which have\n"
+" been marked closed (see hg commit --close-branch).\n"
+"\n"
+" If -a/--active is specified, only show active branches. A branch\n"
+" is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+"vis navngivne grene i depotet\n"
+"\n"
+" Viser depotets navngivne grene og indikerer hvilke der er\n"
+" inaktive. Hvis -c/--closed er angivet, så vises lukkede grene også\n"
+" (se hg commit --close-branch).\n"
+"\n"
+" Hvis -a/--active er angivet, da vises kun aktive grene. En gren er\n"
+" anses for at være aktiv hvis den indeholder depothoveder.\n"
+"\n"
+" Brug kommandoen 'hg update' for at skifte til en eksisterende\n"
+" gren.\n"
+" "
+
+msgid ""
+"create a changegroup file\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" -a/--all (or --base null).\n"
+"\n"
+" You can change compression method with the -t/--type option.\n"
+" The available compression methods are: none, bzip2, and\n"
+" gzip (by default, bundles are compressed using bzip2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means\n"
+" and applied to another repository with the unbundle or pull\n"
+" command. This is useful when direct push and pull are not\n"
+" available or when exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+msgstr ""
+
+msgid "--base is incompatible with specifying a destination"
+msgstr ""
+
+msgid "unknown bundle type specified with --type"
+msgstr ""
+
+msgid ""
+"output the current or given revision of files\n"
+"\n"
+" Print the specified files as they were at the given revision. If\n"
+" no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repository root\n"
+" %p root-relative path name of file being printed\n"
+" "
+msgstr ""
+
+msgid ""
+"make a copy of an existing repository\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" If you use the -r/--rev option to clone up to a specific revision,\n"
+" no subsequent revisions (including subsequent tags) will be\n"
+" present in the cloned repository. This option implies --pull, even\n"
+" on local repositories.\n"
+"\n"
+" By default, clone will check out the head of the 'default' branch.\n"
+" If the -U/--noupdate option is used, the new clone will contain\n"
+" only a repository (.hg) and no working copy (the working copy\n"
+" parent is the null revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Please see 'hg help urls' for important details about ssh:// URLs.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" "
+msgstr ""
+"lav en kopi af et eksisterende depot\n"
+"\n"
+" Lav en kopi af et eksisterende depot i en ny mappe.\n"
+"\n"
+" Hvis der ikke angivet et navn til destinationen, så bruges\n"
+" grundnavnet for kilden.\n"
+"\n"
+" Placeringen af kilden tilføjes til det nye depots .hg/hgrc fil som\n"
+" den nye standard for fremtidige kald til 'hg pull'.\n"
+"\n"
+" Hvis du bruger -r/--rev tilvalget for at klone op til en specifik\n"
+" revision, så vil ingen efterfølgende revisioner (inklusiv\n"
+" efterfølgende mærkater) findes i det klonede depot. Denne\n"
+" valgmulighed medfører --pull, selv ved lokale depoter.\n"
+"\n"
+" Som udgangspunkt vil clone hente hovedet af 'default' grenen. Hvis\n"
+" -U/--noupdate tilvalget bruges vil den nye klon kun indeholde et\n"
+" depot (.hg) og intet arbejdskatalog (arbejdskatalogets forælder er\n"
+" sat til nul revisionen).\n"
+"\n"
+" Se 'hg help urls' for detaljer om gyldige formatter for kilden.\n"
+"\n"
+" Det er muligt at specificere en ssh:// URL som destination, men\n"
+" der vil ikke bliver oprettet nogen .hg/hgrc fil eller noget\n"
+" arbejdskatalog på den anden side. Se venligst 'hg help urls' for\n"
+" vigtige detaljer om ssh:// URLer.\n"
+"\n"
+" Af effektivitetsgrunde bruges hårde lænker ved kloning når kilden\n"
+" og destinationen er på det samme filsystem (bemærk at dette kun\n"
+" gælder for depotdata og ikke for de udhentede filer). Nogle\n"
+" filsystemer, såsom AFS, implementerer ikke hårde lænker korrekt,\n"
+" men rapporterer ingen fejl. I disse tilfælde skal --pull bruges\n"
+" for at undgå hårde lænker.\n"
+"\n"
+" I nogle tilfælde kan man klone depoter og udhentede filer med\n"
+"\n"
+" $ cp -al DEPOT DEPOTKLON\n"
+"\n"
+" Dette er den hurtigste måde at klone på, men det er ikke altid\n"
+" sikkert. Operationen er ikke atomisk (det er op til dig at sikre\n"
+" at DEPOT ikke bliver modificeret undervejs) og du skal selv sørge\n"
+" for at din tekstbehandler bryder hårde lænker (Emacs og de fleste\n"
+" Linux Kernel værktøjer gør det). Dette er desuden ikke kompatibelt\n"
+" med visse udvidelser som placerer deres metadata under .hg mappen,\n"
+" såsom mq.\n"
+"\n"
+" "
+
+msgid ""
+"commit the specified files or all outstanding changes\n"
+"\n"
+" Commit changes to the given files into the repository. Unlike a\n"
+" centralized RCS, this operation is a local operation. See hg push\n"
+" for a way to actively distribute your changes.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" filenames or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is\n"
+" started to prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"lægger de specificerede filer eller alle udestående ændringer i depot\n"
+"\n"
+" Deponerer ændringer i de angivne filer ind i depotet. Dette er en\n"
+" lokal operation, i modsætning til et centraliseret RCS. Se hg push\n"
+" for en måde til aktivt distribuere dine ændringer.\n"
+"\n"
+" Hvis en liste af filer udelades vil alle ændringer rapporteret af\n"
+" \"hg status\" blive deponeret.\n"
+"\n"
+" Hvis du deponerer resultatet af en sammenføjning, undlad da at\n"
+" angive filnavne eller -I/-X filtre.\n"
+"\n"
+" Hvis der ikke angives en deponeringsbesked, så starten den\n"
+" konfigurerede editor for at bede dig om en besked.\n"
+"\n"
+" Se 'hg help dates' for en liste af gyldige formater til -d/--date.\n"
+" "
+
+msgid "nothing changed\n"
+msgstr "ingen ændringer\n"
+
+msgid "created new head\n"
+msgstr "lavede et nyt hoved\n"
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr "deponerede ændring %d:%s\n"
+
+msgid ""
+"mark files as copied for the next commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr ""
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr "Der er intet Mercurial depot her (.hg ikke fundet)"
+
+msgid "either two or three arguments required"
+msgstr "kræver enten to eller tre argumenter"
+
+msgid "returns the completion list associated with the given command"
+msgstr ""
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr ""
+
+msgid "validate the correctness of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr ""
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr ""
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr ""
+
+msgid ""
+"show combined config settings from all hgrc files\n"
+"\n"
+" With no arguments, print names and values of all config items.\n"
+"\n"
+" With one argument of the form section.name, print just the value\n"
+" of that config item.\n"
+"\n"
+" With multiple arguments, print names and values of all config\n"
+" items with matching section names.\n"
+"\n"
+" With --debug, the source (filename and line number) is printed\n"
+" for each config item.\n"
+" "
+msgstr ""
+
+msgid "only one config item permitted"
+msgstr ""
+
+msgid ""
+"manually set the parents of the current working directory\n"
+"\n"
+" This is useful for writing repository conversion tools, but should\n"
+" be used with care.\n"
+" "
+msgstr ""
+
+msgid "show the contents of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr "kopi: %s -> %s\n"
+
+msgid "dump the contents of a data file revision"
+msgstr ""
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr "ugyldig revisionsidentification %s"
+
+msgid "parse and display a date"
+msgstr ""
+
+msgid "dump the contents of an index file"
+msgstr ""
+
+msgid "dump an index DAG as a graphviz dot file"
+msgstr ""
+
+msgid "test Mercurial installation"
+msgstr "test Mercurial installationen"
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr ""
+
+msgid " (check that your locale is properly set)\n"
+msgstr ""
+
+msgid "Checking extensions...\n"
+msgstr ""
+
+msgid " One or more extensions could not be found"
+msgstr ""
+
+msgid " (check that you compiled the extensions)\n"
+msgstr ""
+
+msgid "Checking templates...\n"
+msgstr ""
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr ""
+
+msgid "Checking patch...\n"
+msgstr ""
+
+msgid " patch call failed:\n"
+msgstr ""
+
+msgid " unexpected patch output!\n"
+msgstr ""
+
+msgid " patch test failed!\n"
+msgstr ""
+
+msgid ""
+" (Current patch tool may be incompatible with patch, or misconfigured. "
+"Please check your .hgrc file)\n"
+msgstr ""
+
+msgid ""
+" Internal patcher failure, please report this error to http://mercurial."
+"selenic.com/bts/\n"
+msgstr ""
+
+msgid "Checking commit editor...\n"
+msgstr ""
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr ""
+
+msgid " (specify a commit editor in your .hgrc file)\n"
+msgstr ""
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr ""
+
+msgid "Checking username...\n"
+msgstr ""
+
+msgid " (specify a username in your .hgrc file)\n"
+msgstr ""
+
+msgid "No problems detected\n"
+msgstr "Fandt ingen problemer\n"
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr ""
+
+msgid "dump rename information"
+msgstr ""
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr "%s omdøbt fra %s:%s\n"
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr "%s ikke omdøbt\n"
+
+msgid "show how files match on given patterns"
+msgstr ""
+
+msgid ""
+"diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a/--text option, diff will avoid generating diffs of\n"
+" files it detects as binary. With -a, diff will generate a diff\n"
+" anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. For more information, read 'hg help diffs'.\n"
+" "
+msgstr ""
+"find ændringer i hele depotet (eller udvalgte filer)\n"
+"\n"
+" Vis ændringer mellem revisioner for de udvalgte filer.\n"
+"\n"
+" Ændringerne mellem filerne vises i unified diff-formatet.\n"
+"\n"
+" BEMÆRK: diff kan generere overraskende resultater for\n"
+" sammenføjninger, idet den som udgangspunkt vil sammenligne med\n"
+" arbejdskatalogets første forælder, hvis der ikke angivet en\n"
+" revision.\n"
+"\n"
+" Når der gives to revisioner som argumenter, så vises ændringer\n"
+" mellem disse. Hvis der kun angives en revision, så sammenlignes\n"
+" denne revision med arbejdskataloget, og når der ikke angives nogen\n"
+" revisioner, så sammenlignes arbejdskataloget med dennes forælder.\n"
+"\n"
+" Uden -a/--text tilvalget vil diff undgå at generere ændringer for\n"
+" filer som den detekterer som binære. Med -a vil diff generere\n"
+" ændringer alligevel, sandsynligvis med uønskede resultater.\n"
+"\n"
+" Brug -g/--git tilvalget for at generere ændringer i det udvidede\n"
+" git diff-format. For mere information, læs hg help diffs.\n"
+" "
+
+msgid ""
+"dump the header and diffs for one or more changesets\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a/--text option, export will avoid generating diffs\n"
+" of files it detects as binary. With -a, export will generate a\n"
+" diff anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. See 'hg help diffs' for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the\n"
+" second parent. It can be useful to review a merge.\n"
+" "
+msgstr ""
+"dump hovedet og ændringerne for en eller flere ændringer\n"
+"\n"
+" Udskriv ændrings-hovedet og ændringerne for en eller flere\n"
+" revisioner.\n"
+"\n"
+" Informationen som vises i ændrings-hovedet er: forfatter,\n"
+" ændringshash, forældrene og deponeringsbeskeden.\n"
+"\n"
+" BEMÆRK: export kan generere uventet diff uddata for\n"
+" sammenføjningsændringer idet den kun vil sammenligne\n"
+" sammenføjningsændringen med dennes første forælder.\n"
+"\n"
+" Uddata kan gemmes i en fil, og filnavnet er givet ved en\n"
+" format-streng. Formatteringsreglerne er som følger:\n"
+"\n"
+" %% litteral % tegn\n"
+" %H ændringshash (40 byte heksadecimal)\n"
+" %N antallet af rettelser som bliver genereret\n"
+" %R revisionnummer for ændringen\n"
+" %b grundnavn for det eksporterede depot\n"
+" %h kortform ændringshash (12 byte heksadecimal)\n"
+" %n nul-fyldt sekvensnummer, startende ved 1\n"
+" %r nul-fyldt revisionsnummer for ændringen\n"
+"\n"
+" Uden -a/--text tilvalget vil annotate undgå at behandle filer som\n"
+" den detekterer som binære. Med -a vil annotate generere en\n"
+" annotering alligevel, sandsynligvis med et uønsket resultat.\n"
+"\n"
+" Brug -g/--git tilvalget for at generere ændringer i det udvidede\n"
+" git diff-format. Se 'hg help diffs' for mere information.\n"
+"\n"
+" Med --switch-parent tilvalget vil ændringerne blive beregnet i\n"
+" forhold til den anden forælder. Dette kan være nyttigt til at\n"
+" gennemse en sammenføjning.\n"
+" "
+
+msgid "export requires at least one changeset"
+msgstr ""
+
+msgid "exporting patches:\n"
+msgstr ""
+
+msgid "exporting patch:\n"
+msgstr ""
+
+msgid ""
+"forget the specified files on the next commit\n"
+"\n"
+" Mark the specified files so they will no longer be tracked\n"
+" after the next commit.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history, and it does not delete them from the\n"
+" working directory.\n"
+"\n"
+" To undo a forget before the next commit, see hg add.\n"
+" "
+msgstr ""
+"glem de angivne filer ved næste deponering\n"
+"\n"
+" Marker de angivne filer sådan at de ikke længere vil fulgt ved\n"
+" næste deponering.\n"
+"\n"
+" Dette fjerner kun filerne fra den aktuelle gren, ikke fra hele\n"
+" projektets historie, og det sletter dem heller ikke fra\n"
+" arbejdskataloget.\n"
+"\n"
+" For at omgøre forget før næste deponering, se hg add.\n"
+" "
+
+msgid "no files specified"
+msgstr "ingen filer angivet"
+
+#, python-format
+msgid "not removing %s: file is already untracked\n"
+msgstr "fjerner ikke %s: filen følges ikke\n"
+
+msgid ""
+"search for a pattern in specified files and revisions\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which a\n"
+" match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr "grep: ugyldigt søgemønster: %s\n"
+
+msgid ""
+"show current repository heads or show branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" If one or more REV is given, the \"branch heads\" will be shown for\n"
+" the named branch associated with that revision. The name of the\n"
+" branch is called the revision's branch tag.\n"
+"\n"
+" Branch heads are revisions on a given named branch that do not have\n"
+" any descendants on the same branch. A branch head could be a true head\n"
+" or it could be the last changeset on a branch before a new branch\n"
+" was created. If none of the branch heads are true heads, the branch\n"
+" is considered inactive. If -c/--closed is specified, also show branch\n"
+" heads marked closed (see hg commit --close-branch).\n"
+"\n"
+" If STARTREV is specified only those heads (or branch heads) that\n"
+" are descendants of STARTREV will be displayed.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "no open branch heads on branch %s\n"
+msgstr "ingen åbne gren-hoveder på gren %s\n"
+
+#, python-format
+msgid "no changes on branch %s containing %s are reachable from %s\n"
+msgstr "ingen ændringer på gren %s som indeholder %s kan nås fra %s\n"
+
+#, python-format
+msgid "no changes on branch %s are reachable from %s\n"
+msgstr "ingen ændringer på gren %s kan nås fra %s\n"
+
+msgid ""
+"show help for a given topic or a help overview\n"
+"\n"
+" With no arguments, print a list of commands with short help messages.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that\n"
+" topic."
+msgstr ""
+
+msgid "global options:"
+msgstr "globale indstillinger:"
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr "brug \"hg help\" for den fulde liste af kommandoer"
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr ""
+"brug \"hg help\" for den fulde liste af kommandoer eller \"hg -v\" for "
+"detaljer"
+
+#, python-format
+msgid "use \"hg -v help%s\" to show aliases and global options"
+msgstr "brug \"hg -v help%s\" for at vise aliaser og globale valgmuligheder"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "brug \"hg -v help %s\" for at vise globale valgmuligheder"
+
+msgid ""
+"list of commands:\n"
+"\n"
+msgstr ""
+"liste af kommandoer:\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"aliasser: %s\n"
+
+msgid "(no help text available)"
+msgstr "(ingen hjælpetekst tilgængelig)"
+
+msgid "options:\n"
+msgstr "valgmuligheder:\n"
+
+msgid "no commands defined\n"
+msgstr "ingen kommandoer defineret\n"
+
+msgid "enabled extensions:"
+msgstr "aktiverede udvidelser:"
+
+msgid "no help text available"
+msgstr "ingen hjælpetekst tilgængelig"
+
+#, python-format
+msgid "%s extension - %s\n"
+msgstr "%s udvidelse - %s\n"
+
+msgid "Mercurial Distributed SCM\n"
+msgstr "Mercurial Distribueret SCM\n"
+
+msgid ""
+"basic commands:\n"
+"\n"
+msgstr ""
+"basale kommandoer:\n"
+"\n"
+
+msgid ""
+"\n"
+"additional help topics:\n"
+"\n"
+msgstr ""
+"\n"
+"yderligere hjælpeemner:\n"
+"\n"
+
+msgid ""
+"identify the working copy or specified revision\n"
+"\n"
+" With no revision, print a summary of the current state of the\n"
+" repository.\n"
+"\n"
+" Specifying a path to a repository root or Mercurial bundle will\n"
+" cause lookup to operate on that repository/bundle.\n"
+"\n"
+" This summary identifies the repository state using one or two\n"
+" parent hash identifiers, followed by a \"+\" if there are\n"
+" uncommitted changes in the working directory, a list of tags for\n"
+" this revision and a branch name for non-default branches.\n"
+" "
+msgstr ""
+
+msgid ""
+"import an ordered set of patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f/--force flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (to use the body part, it must have type\n"
+" text/plain or text/x-patch). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and\n"
+" description from patch override values from message headers and\n"
+" body. Values given on command line with -m/--message and -u/--user\n"
+" override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory to\n"
+" the parent of each patch before applying it, and will abort if the\n"
+" resulting changeset has a different ID than the one recorded in\n"
+" the patch. This may happen due to character set problems or other\n"
+" deficiencies in the text patch format.\n"
+"\n"
+" With -s/--similarity, hg will attempt to discover renames and\n"
+" copies in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use \"-\" as the patch name. If\n"
+" a URL is specified, the patch will be downloaded from it.\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "applying patch from stdin\n"
+msgstr "anvender rettelse fra standardinddata\n"
+
+msgid "no diffs found"
+msgstr "fandt ingen ændringer"
+
+#, python-format
+msgid ""
+"message:\n"
+"%s\n"
+msgstr ""
+"meddelse:\n"
+"%s\n"
+
+msgid "not a Mercurial patch"
+msgstr "ikke en Mercurial patch"
+
+msgid "patch is damaged or loses information"
+msgstr "rettelsen er beskadiget eller mister information"
+
+msgid ""
+"show new changesets found in source\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would have been pulled\n"
+" if a pull at the time you issued this command.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the\n"
+" changesets twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+msgstr ""
+
+msgid ""
+"create a new repository in the given directory\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it will be created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"opret et nyt depot i det givne katalog\n"
+"\n"
+" Initialiser et nyt depot i det givne katalog. Hvis det givne\n"
+" katalog ikke findes vil det blive oprettet.\n"
+"\n"
+" Hvis intet katalog er angivet vil det nuværende katalog bliver\n"
+" anvendt.\n"
+"\n"
+" Det er muligt at angive en ssh:// URL som destination.\n"
+" Se 'hg help urls' for mere information.\n"
+" "
+
+msgid ""
+"locate files matching specific patterns\n"
+"\n"
+" Print files under Mercurial control in the working directory whose\n"
+" names match the given patterns.\n"
+"\n"
+" By default, this command searches all directories in the working\n"
+" directory. To search just the current directory and its\n"
+" subdirectories, use \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints the names\n"
+" of all files under Mercurial control in the working directory.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the -0 option to both this command and \"xargs\". This\n"
+" will avoid the problem of \"xargs\" treating single filenames that\n"
+" contain whitespace as multiple filenames.\n"
+" "
+msgstr ""
+
+msgid ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a filename to follow history across\n"
+" renames and copies. --follow without a filename will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command prints revision number and changeset id,\n"
+" tags, non-trivial parents, user, date and time, and a summary for\n"
+" each commit. When the -v/--verbose switch is used, the list of\n"
+" changed files and full commit message are shown.\n"
+"\n"
+" NOTE: log -p/--patch may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, only files different from BOTH parents\n"
+" will appear in files:.\n"
+" "
+msgstr ""
+"vis revisionhistorik for hele depotet eller udvalgte filer\n"
+"\n"
+" Viser revisionshistorikken for de angivne filer eller hele\n"
+" projektet.\n"
+"\n"
+" Filhistorik vises uden at følge omdøbninger eller kopieringer.\n"
+" Brug -f/--follow med et filnavn for at følge historien hen over\n"
+" omdøbninger og kopieringer. --follow uden et filnavn vil kun vise\n"
+" forfædre eller efterkommere af startrevisionen. --follow-first\n"
+" følger kun den første forældre for sammenføjningsrevisioner.\n"
+"\n"
+" Hvis der ikke angives et revisionsinterval, da bruges tip:0 som\n"
+" standard, med mindre --follow er brugt, i hvilket tilfælde\n"
+" arbejdskatalogets forælder bruges som startrevision.\n"
+"\n"
+" Se 'hg help dates' for en liste af gyldige formater til -d/--date.\n"
+"\n"
+" Som standard udskriver denne kommando revisionsnummer og ændrings\n"
+" ID, mærkater, ikke-trivielle forældre, bruger, dato og tid, og et\n"
+" uddrag for hver ændring. Når -v/--verbose tilvalget bruges vises\n"
+" listen af ændrede filer og den fulde deponeringsbesked.\n"
+"\n"
+" BEMÆRK: log -p/--patch kan generere uventet diff output for\n"
+" sammenføjningsændringer idet den kun sammenligner ændringen med\n"
+" dennes første forælder. Ydermere vises kun filer som er\n"
+" forskellige fra BEGGE forældre i files:.\n"
+" "
+
+msgid ""
+"output the current or given revision of the project manifest\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the first parent of the working directory\n"
+" is used, or the null revision if no revision is checked out.\n"
+"\n"
+" With -v, print file permissions, symlink and executable bits.\n"
+" With --debug, print file revision hashes.\n"
+" "
+msgstr ""
+
+msgid ""
+"merge working directory with another revision\n"
+"\n"
+" The current working directory is updated with all changes made in\n"
+" the requested revision since the last common predecessor revision.\n"
+"\n"
+" Files that changed between either parent are marked as changed for\n"
+" the next commit and a commit must be performed before any further\n"
+" updates to the repository are allowed. The next commit will have\n"
+" two parents.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other\n"
+" head, the other head is merged with by default. Otherwise, an\n"
+" explicit revision with which to merge with must be provided.\n"
+" "
+msgstr ""
+"sammenføj arbejdskataloget med en anden revision\n"
+"\n"
+" Det nuværende arbejdskatalog opdateres med alle ændringer lavet i\n"
+" den ønskede revision siden den sidste fælles foregående revision.\n"
+"\n"
+" Filer som ændrede sig i forhold til en af forældrene bliver\n"
+" markeret som ændret med hensyn til næste deponering, og en\n"
+" deponering skal laves før yderligere opdateringer er tilladt. Den\n"
+" næste deponerede ændring får to forældre.\n"
+"\n"
+" Hvis ingen revision angives og arbejdskatalogets forælder er en\n"
+" hovedrevision og den nuværende gren indeholder præcis et andet\n"
+" hoved, så sammenføjes der med dette hoved som standard. Ellers\n"
+" skal en eksplicit revision angives.\n"
+" "
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr ""
+"gren '%s' har %d hoveder - sammenføj venligst med en eksplicit revision"
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr "gren '%s' har et hoved - sammenføj venligst med en eksplicit revision"
+
+msgid "there is nothing to merge"
+msgstr "der er ikke noget at sammenføje"
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr "%s - brug \"hg update\" istedet"
+
+msgid ""
+"working dir not at a head rev - use \"hg update\" or merge with an explicit "
+"rev"
+msgstr ""
+"arbejdskataloget er ikke ved en hovedrevision - brug \"hg update\" eller "
+"sammenføj med en eksplicit revision"
+
+msgid ""
+"show changesets not found in destination\n"
+"\n"
+" Show changesets not found in the specified destination repository\n"
+" or the default push location. These are the changesets that would\n"
+" be pushed if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+msgstr ""
+
+msgid ""
+"show the parents of the working directory or revision\n"
+"\n"
+" Print the working directory's parent revisions. If a revision is\n"
+" given via -r/--rev, the parent of that revision will be printed.\n"
+" If a file argument is given, the revision in which the file was\n"
+" last changed (before the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"vis forældrene til arbejdskataloget eller en revision\n"
+"\n"
+" Udskriv arbejdskatalogets forældrerevisioner. Hvis en revision\n"
+" angivet med -r/--rev, så udskrives forældren til denne revision.\n"
+" Hvis en fil er angivet, udskrives revisionen i hvilken filen sidst\n"
+" blev ændret (før arbejdskatalogets revision eller argumentet til\n"
+" --rev, hvis givet).\n"
+" "
+
+msgid "can only specify an explicit filename"
+msgstr ""
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr "'%s' ikke fundet i manifest!"
+
+msgid ""
+"show aliases for remote repositories\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given,\n"
+" show definition of all available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+msgid "not found!\n"
+msgstr "ikke fundet!\n"
+
+msgid "not updating, since new heads added\n"
+msgstr "opdaterer ikke idet nye hoveder er tilføjet\n"
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr "(kør 'hg heads' for at se hoveder, 'hg merge' for at sammenføje)\n"
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr "(kør 'hg update' for at få en arbejdskopi)\n"
+
+msgid ""
+"pull changes from the specified source\n"
+"\n"
+" Pull changes from a remote repository to a local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to a local repository (the current one unless\n"
+" -R is specified). By default, this does not update the copy of the\n"
+" project in the working directory.\n"
+"\n"
+" Use hg incoming if you want to see what would have been added by a\n"
+" pull at the time you issued this command. If you then decide to\n"
+" added those changes to the repository, you should use pull -r X\n"
+" where X is the last changeset listed by hg incoming.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"hent ændringer fra den angivne kilde\n"
+"\n"
+" Hiver ændringer fra et fjert depot til et lokalt.\n"
+"\n"
+" Dette finder alle ændringer fra depotet på den specificerede sti\n"
+" eller URL og tilføjer dem til et lokalt depot (det nuværende depot\n"
+" med mindre -R er angivet). Som standard opdateres arbejdskataloget\n"
+" ikke.\n"
+"\n"
+" Brug hg incoming for at se hvad der ville være blevet tilføjet på\n"
+" det tidspunkt du udførte kommandoen. Hvis du derefter beslutter at\n"
+" tilføje disse ændringer til depotet, så bør du bruge pull -r X\n"
+" hvor X er den sidste ændring nævnt af hg incoming.\n"
+"\n"
+" Hvis KILDE udelades, så bruges 'default' stien.\n"
+" Se 'hg help urls' for mere information.\n"
+" "
+
+msgid ""
+"push changes to the specified destination\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It moves changes from\n"
+" the current repository to a different one. If the destination is\n"
+" local this is identical to a pull in that directory from the\n"
+" current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" user forgot to pull and merge before pushing.\n"
+"\n"
+" If -r/--rev is used, the named revision and all its ancestors will\n"
+" be pushed to the remote repository.\n"
+"\n"
+" Please see 'hg help urls' for important details about ssh://\n"
+" URLs. If DESTINATION is omitted, a default path will be used.\n"
+" "
+msgstr ""
+"skub ændringer til den angivne destination\n"
+"\n"
+" Skubber ændringer fra det lokale depot til den givne destination.\n"
+"\n"
+" Dette er den symmetriske operation for pull. Den flytter ændringer\n"
+" fra det nuværende depot til et andet. Hvis destinationen er lokal,\n"
+" så er dette identisk til et pull i destinationen af det nuværende\n"
+" depot.\n"
+"\n"
+" Som standard vil push nægte af køre hvis den detekterer at den vil\n"
+" øge antallet af hoveder i destinationen. Dette indikerer normalt\n"
+" at brugeren har glemt at hente og sammenføje ændringerne før\n"
+" skubningen.\n"
+"\n"
+" Hvis -r/--rev bruges, så vil den navngivne revision og alle dets\n"
+" forfædre bliver skubbet til det andet depot.\n"
+"\n"
+" Se venligst 'hg help urls' for vigtige detaljer om ssh:// URL'er.\n"
+" Hvis DESTINATION udelades vil en standard sti blive brugt.\n"
+" "
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr "skubber til %s\n"
+
+msgid ""
+"roll back an interrupted transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an\n"
+" interrupted operation. It should only be necessary when Mercurial\n"
+" suggests it.\n"
+" "
+msgstr ""
+
+msgid ""
+"remove the specified files on the next commit\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history. -A/--after can be used to remove only\n"
+" files that have already been deleted, -f/--force can be used to\n"
+" force deletion, and -Af can be used to remove files from the next\n"
+" revision without deleting them from the working directory.\n"
+"\n"
+" The following table details the behavior of remove for different\n"
+" file states (columns) and option combinations (rows). The file\n"
+" states are Added [A], Clean [C], Modified [M] and Missing [!]\n"
+" (as reported by hg status). The actions are Warn, Remove (from\n"
+" branch) and Delete (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+msgstr ""
+"fjern de angivne filer ved næste deponering\n"
+"\n"
+" Planlæg de angivne filer til sletning fra depotet.\n"
+"\n"
+" Dette fjerner kun filerne fra den nuværende gren, ikke fra hele\n"
+" projektets historie. -A/--after kan bruges til kun at fjerne filer\n"
+" som allerede er slettet, -f/--force kan bruges for at gennemtvinge\n"
+" en sletning, og -Af kan bruges til at fjerne filer fra næste\n"
+" revision uden at slette dem fra arbejdskataloget.\n"
+"\n"
+" Den følgende tabel viser opførslen af remove for forskellige\n"
+" filtilstande (søjler) og kombinationer af tilvalg (rækker). Mulige\n"
+" filtilstande er tilføjet [A], ren [C], ændret [M] og manglende [!]\n"
+" (som rapporteret af hg status). Handlingerne er Warn, Remove (fra\n"
+" gren) og Delete (fra disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" Denne kommando planlægger filerne til at blive fjernet ved næste\n"
+" deponering. For at omgøre en fjernelse før det, se hg revert.\n"
+" "
+
+#, python-format
+msgid "not removing %s: file is untracked\n"
+msgstr "fjerner ikke %s: filen følges ikke\n"
+
+#, python-format
+msgid "not removing %s: file %s (use -f to force removal)\n"
+msgstr "fjerner ikke %s: filen %s (brug -f for at forcere fjernelsen)\n"
+
+msgid "still exists"
+msgstr "eksisterer stadig"
+
+msgid "is modified"
+msgstr "er modificeret"
+
+msgid "has been marked for add"
+msgstr "er markeret som tilføjet"
+
+msgid ""
+"rename files; equivalent of copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If dest\n"
+" is a directory, copies are put in that directory. If dest is a\n"
+" file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid ""
+"retry file merges from a merge or update\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a/--all switch.\n"
+"\n"
+" If a conflict is resolved manually, please note that the changes\n"
+" will be overwritten if the merge is retried with resolve. The\n"
+" -m/--mark switch should be used to mark the file as resolved.\n"
+"\n"
+" This command also allows listing resolved files and manually\n"
+" indicating whether or not files are resolved. All files must be\n"
+" marked as resolved before a commit is permitted.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+msgstr ""
+
+msgid "too many options specified"
+msgstr "der er angivet for mange tilvalg"
+
+msgid "can't specify --all and patterns"
+msgstr "kan ikke angive --all og mønstre"
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr ""
+"ingen filer eller mapper specificeret; brug --all for at gen-sammenføje alle "
+"filerne"
+
+msgid ""
+"restore individual files or directories to an earlier state\n"
+"\n"
+" (Use update -r to check out earlier revisions, revert does not\n"
+" change the working directory parents.)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r/--rev option, revert the given files or directories\n"
+" to their contents as of a specific revision. This can be helpful\n"
+" to \"roll back\" some or all of an earlier change. See 'hg help\n"
+" dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable mode\n"
+" of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+msgstr ""
+
+msgid "you can't specify a revision and a date"
+msgstr "du kan ikke specificeret en revision og en dato"
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr ""
+"ingen filer eller mapper specificeret; brug --all for at føre hele repo'et "
+"tilbage"
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr "glemmer %s\n"
+
+#, python-format
+msgid "reverting %s\n"
+msgstr "fører %s tilbage\n"
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr "usletter %s\n"
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr "gemmer nuværende version af %s som %s\n"
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr "filen er ikke håndteret: %s\n"
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr "%s behøver ingen ændringer\n"
+
+msgid ""
+"roll back the last transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time. This command does not alter\n"
+" the working directory.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+msgstr ""
+
+msgid ""
+"print the root (top) of the current working directory\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+msgstr ""
+
+msgid ""
+"export the repository via HTTP\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+" files.\n"
+" "
+msgstr ""
+"eksporter depotet via HTTP\n"
+"\n"
+" Start en lokal HTTP depotbrowser og pull-server.\n"
+"\n"
+" Som standard logger serveren forespørgsler til stdout og fejl til\n"
+" stderr. Brug -A/--accesslog og -E/--errorlog tilvalgene for at\n"
+" logge til filer.\n"
+" "
+
+#, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr "lytter på http://%s%s/%s (bundet til %s:%d)\n"
+
+msgid ""
+"show changed files in the working directory\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" the source of a copy/move operation, are not listed unless\n"
+" -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.\n"
+" Unless options described with \"show only ...\" are given, the\n"
+" options -mardu are used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/--ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the differences between them are\n"
+" shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = missing (deleted by non-hg command, but still tracked)\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = origin of the previous file listed as A (added)\n"
+" "
+msgstr ""
+"vis ændrede filer i arbejdskataloget\n"
+"\n"
+" Vis status for filer i depotet. Hvis der angivet navne, så vil kun\n"
+" disse filer blive vist. Filer som er rene eller ignorerede eller\n"
+" kilden i en kopierings/flytnings operation vises ikke med mindre\n"
+" -c/--clear, -i/--ignored, -C/--copies eller -A/--all er angivet.\n"
+" Med mindre tilvalgene beskrevet med \"vis kun ...\" bruges, så\n"
+" bruges -mardu tilvalgene.\n"
+"\n"
+" Tilvalget -q/--quiet skjuler filer som ikke bliver fulgt (ukendte\n"
+" eller ignorerede filer) med mindre disse eksplicit vælges med\n"
+" -u/--unknown eller -i/--ignored.\n"
+"\n"
+" BEMÆRK: status kan tilsyneladende være forskellig fra diff hvis\n"
+" rettigheder er blevet ændret eller hvis en sammenføjning har\n"
+" fundet sted. Det normale diff-format rapporterer ikke ændringer i\n"
+" rettigheder og diff rapporterer kun ænringer relativt til en\n"
+" sammenføjningsforældre.\n"
+"\n"
+" Hvis der angivet en revision bruges denne som en basisrevision.\n"
+" Hvis der angives to revisioner, da vises forskellene mellem dem.\n"
+"\n"
+" Koderne som bruges til at vise status for filerne er:\n"
+" M = ændret\n"
+" A = tilføjet\n"
+" R = fjernet\n"
+" C = ren\n"
+" ! = mangler (slettet af en ikke-hg kommando, men følges stadig)\n"
+" ? = følges ikke\n"
+" I = ignoreret\n"
+" = den foregående fil markeret som A (tilføjet) stammer herfra\n"
+" "
+
+msgid ""
+"add one or more tags for the current or given revision\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is\n"
+" used, or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "tag names must be unique"
+msgstr "mærkatnavne skal være unikke"
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr "navnet '%s' er reserveret"
+
+msgid "--rev and --remove are incompatible"
+msgstr "--rev og --remove er inkompatible"
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr "mærkaten '%s' eksisterer ikke"
+
+#, python-format
+msgid "tag '%s' is not a global tag"
+msgstr "mærkaten '%s' er ikke en global mærkat"
+
+#, python-format
+msgid "tag '%s' is not a local tag"
+msgstr "mærkaten '%s' er ikke en lokal mærkat"
+
+#, python-format
+msgid "Removed tag %s"
+msgstr "Mærke %s er fjernet"
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr "mærkaten '%s' eksisterer allerede (brug -f for at gennemtvinge)"
+
+#, python-format
+msgid "Added tag %s for changeset %s"
+msgstr "Tilføjede mærkat %s til ændring %s"
+
+msgid ""
+"list repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose\n"
+" switch is used, a third column \"local\" is printed for local tags.\n"
+" "
+msgstr ""
+"vis depotmærkater\n"
+"\n"
+" Viser både normale og lokale mærkater. Når -v/--verbose flaget\n"
+" bruges, udskrives en tredje kolonne \"local\" for lokale mærkater.\n"
+" "
+
+msgid ""
+"show the tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the changeset\n"
+" most recently added to the repository (and therefore the most\n"
+" recently changed head).\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+msgstr ""
+
+msgid ""
+"apply one or more changegroup files\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+msgstr ""
+
+msgid ""
+"update working directory\n"
+"\n"
+" Update the repository's working directory to the specified\n"
+" revision, or the tip of the current branch if none is specified.\n"
+" Use null as the revision to remove the working copy (like 'hg\n"
+" clone -U').\n"
+"\n"
+" When the working directory contains no uncommitted changes, it\n"
+" will be replaced by the state of the requested revision from the\n"
+" repository. When the requested revision is on a different branch,\n"
+" the working directory will additionally be switched to that\n"
+" branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C/--clean to\n"
+" discard them, forcibly replacing the state of the working\n"
+" directory with the requested revision. Alternately, use -c/--check\n"
+" to abort.\n"
+"\n"
+" When there are uncommitted changes and option -C/--clean is not\n"
+" used, and the parent revision and requested revision are on the\n"
+" same branch, and one of them is an ancestor of the other, then the\n"
+" new working directory will contain the requested revision merged\n"
+" with the uncommitted changes. Otherwise, the update will fail with\n"
+" a suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use\n"
+" revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"opdater arbejdskataloget\n"
+"\n"
+" Opdater depotets arbejdskatalog til den angivne revision, eller\n"
+" spidsen af den nuværende gren hvis ingen revision er angivet. Brug\n"
+" null som revision for at fjerne arbejdskataloget (ligesom 'hg\n"
+" clone -U').\n"
+"\n"
+" Hvis arbejdskataloget ikke indeholder nogen ikke-deponerede\n"
+" ændringer, da vil det blive erstattet af den ønskede revision fra\n"
+" depotet. Hvis den ønskede revision er på en anden gren, så vil\n"
+" arbejdskataloget yderligere blive skiftet til denne gren.\n"
+"\n"
+" Hvis der er ikke-deponerede ændringer kan -C/--clean tilvalget\n"
+" bruges for at kassere dem og sætte tilstanden af arbejdskataloget\n"
+" lig tilstanden i den ønskede revision. Alternativt, brug\n"
+" -c/--check for at afbryde.\n"
+"\n"
+" Hvis der er ikke-deponerede ændringer, og -C/--clean tilvalget\n"
+" ikke bruges, og forældrerevisionen og den ønskede revision begge\n"
+" er på samme gren, og en af dem er en forfar til den anden, så vil\n"
+" det nye arbejdskatalog indeholde den ønskede revision sammenføjet\n"
+" med de ikke-deponerede ændringer. Ellers vil opdateringen fejle\n"
+" med et forslag til at bruge 'merge' eller 'update -C' i stedet.\n"
+"\n"
+" Hvis du vil opdatere blot en enkelt fil til en ældre revision,\n"
+" brug da revert.\n"
+"\n"
+" Se 'hg help dates' for en liste af gyldige formater til -d/--date.\n"
+" "
+
+msgid "uncommitted local changes"
+msgstr "udeponerede lokale ændringer"
+
+msgid ""
+"verify the integrity of the repository\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+msgstr ""
+
+msgid "output version and copyright information"
+msgstr "udskriv version- og copyrightinformation"
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr "Mercurial Distribueret SCM (version %s)\n"
+
+msgid ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+
+msgid "repository root directory or symbolic path name"
+msgstr "depotrodfolder eller symbolsk stinavn"
+
+msgid "change working directory"
+msgstr "skift arbejdskatalog"
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr "spørg ikke, antag alle svar er 'ja'"
+
+msgid "suppress output"
+msgstr "undertryk output"
+
+msgid "enable additional output"
+msgstr "aktiver yderlig output"
+
+msgid "set/override config option"
+msgstr "sæt/overskriv konfigurationopsætning"
+
+msgid "enable debugging output"
+msgstr "aktiver fejlsøgningsinformation"
+
+msgid "start debugger"
+msgstr "start fejlsøgningsprogram"
+
+msgid "set the charset encoding"
+msgstr "angiv tegnkodningen"
+
+msgid "set the charset encoding mode"
+msgstr "angiv tegnkodningstilstand"
+
+msgid "print traceback on exception"
+msgstr "udskriv traceback ved exception"
+
+msgid "time how long the command takes"
+msgstr "tag tid på hvor lang tid kommandoen tager"
+
+msgid "print command execution profile"
+msgstr ""
+
+msgid "output version information and exit"
+msgstr "udskriv versionsinformation og afslut"
+
+msgid "display help and exit"
+msgstr "vis hjælp og afslut"
+
+msgid "do not perform actions, just print output"
+msgstr "udfør ingen handlinger, udskriv kun outputttet"
+
+msgid "specify ssh command to use"
+msgstr "specificer ssh kommandoen som skal bruges"
+
+msgid "specify hg command to run on the remote side"
+msgstr "angiv hg kommando som skal udføres på fjernsystemet"
+
+msgid "include names matching the given patterns"
+msgstr "inkluder navne som matcher det givne mønster"
+
+msgid "exclude names matching the given patterns"
+msgstr "ekskluder navne som matcher det givne mønster"
+
+msgid "use <text> as commit message"
+msgstr "brug <tekst> som deponeringsbesked"
+
+msgid "read commit message from <file>"
+msgstr "læs deponeringsbeskeden fra <fil>"
+
+msgid "record datecode as commit date"
+msgstr "noter dato som integrationsdato"
+
+msgid "record the specified user as committer"
+msgstr ""
+
+msgid "display using template map file"
+msgstr "vis med skabelon-fil"
+
+msgid "display with template"
+msgstr "vis med skabelon"
+
+msgid "do not show merges"
+msgstr "vis ikke sammenføjninger"
+
+msgid "treat all files as text"
+msgstr "behandl alle filer som tekst"
+
+msgid "don't include dates in diff headers"
+msgstr "inkluder ikke datoer i diff-hoveder"
+
+msgid "show which function each change is in"
+msgstr "vis hvilken funktion hver ændring er i"
+
+msgid "ignore white space when comparing lines"
+msgstr "ignorer blanktegn når linier sammenlignes"
+
+msgid "ignore changes in the amount of white space"
+msgstr "ignorer ændringer i mængden af blanktegn"
+
+msgid "ignore changes whose lines are all blank"
+msgstr "ignorer ændringer hvis linier alle er blanke"
+
+msgid "number of lines of context to show"
+msgstr "antal linier kontekst der skal vises"
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr "gæt omdøbte filer ud fra enshed (0<=s<=100)"
+
+msgid "[OPTION]... [FILE]..."
+msgstr "[TILVALG]... [FIL]..."
+
+msgid "annotate the specified revision"
+msgstr "annotér den angivne revision"
+
+msgid "follow file copies and renames"
+msgstr "følg kopier og omdøbninger"
+
+msgid "list the author (long with -v)"
+msgstr "vis forfatteren (lang med -v)"
+
+msgid "list the date (short with -q)"
+msgstr "vis datoen (kort med -q)"
+
+msgid "list the revision number (default)"
+msgstr "vis revisionsnummeret (standard)"
+
+msgid "list the changeset"
+msgstr "vis ændringen"
+
+msgid "show line number at the first appearance"
+msgstr "vil linienummeret for den første forekomst"
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FIL..."
+
+msgid "do not pass files through decoders"
+msgstr "kør ikke filerne igennem dekodere"
+
+msgid "directory prefix for files in archive"
+msgstr "katalogpræfiks for filerne i arkivet"
+
+msgid "revision to distribute"
+msgstr "revision som skal distribueres"
+
+msgid "type of distribution to create"
+msgstr "distributionstype der skal oprettes"
+
+msgid "[OPTION]... DEST"
+msgstr "[TILVALG]... MÃ…L"
+
+msgid "merge with old dirstate parent after backout"
+msgstr ""
+
+msgid "parent to choose when backing out merge"
+msgstr ""
+
+msgid "revision to backout"
+msgstr "revision som skal bakkes ud"
+
+msgid "[OPTION]... [-r] REV"
+msgstr "[TILVALG]... [-r] REV"
+
+msgid "reset bisect state"
+msgstr "nulstil bisect"
+
+msgid "mark changeset good"
+msgstr "marker ændring som god"
+
+msgid "mark changeset bad"
+msgstr "marker ændring som dårlig"
+
+msgid "skip testing changeset"
+msgstr "spring testen af denne ændring over"
+
+msgid "use command to check changeset state"
+msgstr "brug kommando for at kontrollere tilstanden af ændringen"
+
+msgid "do not update to target"
+msgstr "undlad at opdatere til målet"
+
+msgid "[-gbsr] [-c CMD] [REV]"
+msgstr "[-gbsr] [-c KOMMANDO] [REV]"
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr ""
+
+msgid "reset branch name to parent branch name"
+msgstr ""
+
+msgid "[-fC] [NAME]"
+msgstr "[-fC] [NAVN]"
+
+msgid "show only branches that have unmerged heads"
+msgstr "vil kun grene som har usammenføjne hoveder"
+
+msgid "show normal and closed heads"
+msgstr "vis normale og lukkede hoveder"
+
+msgid "[-a]"
+msgstr "[-a]"
+
+msgid "run even when remote repository is unrelated"
+msgstr "kør selv hvis fjerndepotet er urelateret"
+
+msgid "a changeset up to which you would like to bundle"
+msgstr ""
+
+msgid "a base changeset to specify instead of a destination"
+msgstr ""
+
+msgid "bundle all changesets in the repository"
+msgstr ""
+
+msgid "bundle compression type to use"
+msgstr ""
+
+msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr "[-f] [-a] [-r REV]... [--base REV]... FIL [MÃ…L]"
+
+msgid "print output to file with formatted name"
+msgstr ""
+
+msgid "print the given revision"
+msgstr "udskriv den angivne revision"
+
+msgid "apply any matching decode filter"
+msgstr ""
+
+msgid "[OPTION]... FILE..."
+msgstr "[TILVALG]... FIL..."
+
+msgid "the clone will only contain a repository (no working copy)"
+msgstr "klonen vil kun indeholde et depot (intet arbejdsbibliotek)"
+
+msgid "a changeset you would like to have after cloning"
+msgstr "en ændringer du gerne vil have efter kloningen"
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr "[TILVALG]... KILDE [MÃ…L]"
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr "marker nye/manglende filer som tilføjede/fjernede før deponering"
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr "marker en gren som lukket, skuler den fra listen af grene"
+
+msgid "record a copy that has already occurred"
+msgstr ""
+
+msgid "forcibly copy over an existing managed file"
+msgstr ""
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr "[TILVALG]... [KILDE]... MÃ…L"
+
+msgid "[INDEX] REV1 REV2"
+msgstr "[INDEKS] REV1 REV2"
+
+msgid "[COMMAND]"
+msgstr "[KOMMANDO]"
+
+msgid "show the command options"
+msgstr "vis kommando-flag"
+
+msgid "[-o] CMD"
+msgstr "[-o] KOMMANDO"
+
+msgid "try extended date formats"
+msgstr "prøv udvidede datoformater"
+
+msgid "[-e] DATE [RANGE]"
+msgstr "[-e] DATO [INTERVAL]"
+
+msgid "FILE REV"
+msgstr "FIL REV"
+
+msgid "[PATH]"
+msgstr "[STI]"
+
+msgid "FILE"
+msgstr "FIL"
+
+msgid "revision to rebuild to"
+msgstr "revision til hvilken der skal gendannes til"
+
+msgid "[-r REV] [REV]"
+msgstr "[-r REV] [REV]"
+
+msgid "revision to debug"
+msgstr "revision der skal fejlsøges"
+
+msgid "[-r REV] FILE"
+msgstr "[-r REV] FIL"
+
+msgid "REV1 [REV2]"
+msgstr "REV1 [REV2]"
+
+msgid "do not display the saved mtime"
+msgstr "vis ikke den gemte mtime"
+
+msgid "[OPTION]..."
+msgstr "[TILVALG]..."
+
+msgid "revision to check"
+msgstr "revision som skal undersøges"
+
+msgid "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+msgstr "[TILVALG]... [-r REV1 [-r REV2]] [FIL]..."
+
+msgid "diff against the second parent"
+msgstr ""
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr "[TILVALG]... [-o UDFILSPECIFIKATION] REV..."
+
+msgid "end fields with NUL"
+msgstr "afslut felter med NUL"
+
+msgid "print all revisions that match"
+msgstr "udskriv alle revisioner som matcher"
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr ""
+
+msgid "ignore case when matching"
+msgstr ""
+
+msgid "print only filenames and revisions that match"
+msgstr "udskriv kun filnavne og revisioner som matcher"
+
+msgid "print matching line numbers"
+msgstr "udskriv matchende linienumre"
+
+msgid "search in given revision range"
+msgstr "søg i det angivne interval"
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr "[TILVALG]... MØNSTER [FIL]..."
+
+msgid "show only heads which are descendants of REV"
+msgstr "vis kun hoveder som er efterkommere af REV"
+
+msgid "show only the active heads from open branches"
+msgstr "vis kun aktive hoveder fra åbne grene"
+
+msgid "[-r STARTREV] [REV]..."
+msgstr "[-r STARTREV] [REV]..."
+
+msgid "[TOPIC]"
+msgstr "[EMNE]"
+
+msgid "identify the specified revision"
+msgstr "identificer den angivne revision"
+
+msgid "show local revision number"
+msgstr "vis lokalt revisionsnummer"
+
+msgid "show global revision id"
+msgstr "vis globalt revisionsnummer"
+
+msgid "show branch"
+msgstr "vis gren"
+
+msgid "show tags"
+msgstr "vis mærkater"
+
+msgid "[-nibt] [-r REV] [SOURCE]"
+msgstr "[-nibt] [-r REV] [KILDE]"
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr ""
+
+msgid "base path"
+msgstr ""
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr "spring kontrollen for udeponerede ændringer over"
+
+msgid "don't commit, just update the working directory"
+msgstr "deponer ikke, opdater blot arbejdskataloget"
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr "anvend rettelse på den knude hvorfra den var genereret"
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr ""
+
+msgid "[OPTION]... PATCH..."
+msgstr "[TILVALG]... RETTELSE..."
+
+msgid "show newest record first"
+msgstr "vis nyeste postering først"
+
+msgid "file to store the bundles into"
+msgstr "fil hvor bundterne skal gemmes"
+
+msgid "a specific revision up to which you would like to pull"
+msgstr "en specifik revision hvortil du gerne vil trække"
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILNAVN] [KILDE]"
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-e KOMMANDO] [--remotecmd KOMMANDO] [MÃ…L]"
+
+msgid "search the repository as it stood at REV"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr "afslut filnavne med NUL, til brug med xargs"
+
+msgid "print complete paths from the filesystem root"
+msgstr "udskriv fulde stier fra filsystemets rod"
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr "[TILVALG]... [MØNSTER]..."
+
+msgid "only follow the first parent of merge changesets"
+msgstr "følg kun den første forælder for sammenføjningsændringer"
+
+msgid "show revisions matching date spec"
+msgstr "vis revisioner som matcher datoangivelsen"
+
+msgid "show copied files"
+msgstr "vis kopierede filer"
+
+msgid "do case-insensitive search for a keyword"
+msgstr "lav søgning efter nøgleord uden forskel på små/store bogstaver"
+
+msgid "include revisions where files were removed"
+msgstr "inkluder revisioner hvor filer blev slettet"
+
+msgid "show only merges"
+msgstr "vis kun sammenføjninger"
+
+msgid "revisions committed by user"
+msgstr "revisioner deponeret af bruger"
+
+msgid "show only changesets within the given named branch"
+msgstr "vis kun ændringer på den angivne navngivne gren"
+
+msgid "do not display revision or any of its ancestors"
+msgstr "vis ikke revision eller nogen af den forfædre"
+
+msgid "[OPTION]... [FILE]"
+msgstr "[TILVALG]... [FIL]"
+
+msgid "revision to display"
+msgstr "revision der skal vises"
+
+msgid "[-r REV]"
+msgstr "[-r REV]"
+
+msgid "force a merge with outstanding changes"
+msgstr ""
+
+msgid "revision to merge"
+msgstr "revision der skal sammenføjes"
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr ""
+
+msgid "[-f] [[-r] REV]"
+msgstr "[-f] [[-r] REV]"
+
+msgid "a specific revision up to which you would like to push"
+msgstr ""
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr "[-M] [-p] [-n] [-f] [-r REV]... [MÃ…L]"
+
+msgid "show parents from the specified revision"
+msgstr "vis forældre for den angivne revision"
+
+msgid "[-r REV] [FILE]"
+msgstr "[-r REV] [FIL]"
+
+msgid "[NAME]"
+msgstr "[NAVN]"
+
+msgid "update to new tip if changesets were pulled"
+msgstr "opdater til den nye spids hvis ændringer blev trukket ned"
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr "[-u] [-f] [-r REV]... [-e KOMMANDO] [--remotecmd KOMMANDO] [KILDE]"
+
+msgid "force push"
+msgstr "gennemtving skubning"
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-f] [-r REV]... [-e KOMMANDO] [--remotecmd KOMMANDO] [MÃ…L]"
+
+msgid "record delete for missing files"
+msgstr ""
+
+msgid "remove (and delete) file even if added or modified"
+msgstr "fjern (og slet) fil selv hvis tilføjet eller ændret"
+
+msgid "record a rename that has already occurred"
+msgstr ""
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr "[TILVALG]... KILDE... MÃ…L"
+
+msgid "remerge all unresolved files"
+msgstr "gen-sammenføj alle uløste filer"
+
+msgid "list state of files needing merge"
+msgstr "vis tilstand af filer som har brug for sammenføjning"
+
+msgid "mark files as resolved"
+msgstr "marker filer som løste"
+
+msgid "unmark files as resolved"
+msgstr "marker filer som uløste"
+
+msgid "revert all changes when no arguments given"
+msgstr "før alle ændringer tilbage når inget argument angives"
+
+msgid "tipmost revision matching date"
+msgstr ""
+
+msgid "revision to revert to"
+msgstr "revision der skal føres tilbage til"
+
+msgid "do not save backup copies of files"
+msgstr "gem ikke sikkerhedskopier af filer"
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr "[TILVALG]... [-r REV] [NAVN]..."
+
+msgid "name of access log file to write to"
+msgstr "navn på adgangslogfilen der skrives til"
+
+msgid "name of error log file to write to"
+msgstr "navn på fejlllog fil der skrives til"
+
+msgid "port to listen on (default: 8000)"
+msgstr "port der skal lyttes på (standard: 8000)"
+
+msgid "address to listen on (default: all interfaces)"
+msgstr "adresse der skal lyttes til (standard: alle grænseflader)"
+
+msgid "prefix path to serve from (default: server root)"
+msgstr "prefiks sti at udstille fra (default: server-rod)"
+
+msgid "name to show in web pages (default: working directory)"
+msgstr "navn der skal vises på websider (standard: arbejdskatalog)"
+
+msgid "name of the webdir config file (serve more than one repository)"
+msgstr "navn på webdir konfigurationsfil (serve mere end et depot)"
+
+msgid "for remote clients"
+msgstr "for fjernklienter"
+
+msgid "web templates to use"
+msgstr "web-skabelon"
+
+msgid "template style to use"
+msgstr "skabelon-stil"
+
+msgid "use IPv6 in addition to IPv4"
+msgstr "brug IPv6 og IPv4"
+
+msgid "SSL certificate file"
+msgstr "SSL certifikatfil"
+
+msgid "show untrusted configuration options"
+msgstr "vis ikke-betroede konfigurationsværdier"
+
+msgid "[-u] [NAME]..."
+msgstr "[-u] [NAVN]..."
+
+msgid "show status of all files"
+msgstr "vis status på alle filer"
+
+msgid "show only modified files"
+msgstr "vis kun ændrede filer"
+
+msgid "show only added files"
+msgstr "vis kun tilføjede filer"
+
+msgid "show only removed files"
+msgstr "vis kun fjernede filer"
+
+msgid "show only deleted (but tracked) files"
+msgstr "vis kun slettede (men kendte) filer"
+
+msgid "show only files without changes"
+msgstr "vis kun filer unden ændringer"
+
+msgid "show only unknown (not tracked) files"
+msgstr "vis kun ukendte filer"
+
+msgid "show only ignored files"
+msgstr "vis kun ignorerede filer"
+
+msgid "hide status prefix"
+msgstr "skjul statuspræfix"
+
+msgid "show source of copied files"
+msgstr "vis kilder for kopierede filer"
+
+msgid "show difference from revision"
+msgstr "vis forskelle fra revision"
+
+msgid "replace existing tag"
+msgstr "erstat eksisterende mærkat"
+
+msgid "make the tag local"
+msgstr "gør mærkaten lokal"
+
+msgid "revision to tag"
+msgstr "revision der skal mærkes"
+
+msgid "remove a tag"
+msgstr "fjern en mærkat"
+
+msgid "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr "[-l] [-m TEKST] [-d DATO] [-u BRUGER] [-r REV] NAVN..."
+
+msgid "[-p]"
+msgstr "[-p]"
+
+msgid "update to new tip if changesets were unbundled"
+msgstr "opdater til ny spids hvis ændringer blev pakket ud"
+
+msgid "[-u] FILE..."
+msgstr "[-u] FIL..."
+
+msgid "overwrite locally modified files (no backup)"
+msgstr "overskrev lokalt modificerede filer (uden sikkerhedskopi)"
+
+msgid "check for uncommitted changes"
+msgstr "kontroller for udeponerede ændringer"
+
+msgid "[-C] [-d DATE] [[-r] REV]"
+msgstr "[-C] [-d DATO] [[-r] REV]"
+
+#, python-format
+msgid "config error at %s:%d: '%s'"
+msgstr "konfigurationsfejl på %s:%d: '%s'"
+
+msgid "not found in manifest"
+msgstr "blev ikke fundet i manifest"
+
+msgid "branch name not in UTF-8!"
+msgstr "grennavn er ikke i UTF-8!"
+
+#, python-format
+msgid " searching for copies back to rev %d\n"
+msgstr " søger efter kopier tilbage til revision %d\n"
+
+#, python-format
+msgid ""
+" unmatched files in local:\n"
+" %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" unmatched files in other:\n"
+" %s\n"
+msgstr ""
+
+msgid " all copies found (* = to merge, ! = divergent):\n"
+msgstr ""
+
+msgid " checking for directory renames\n"
+msgstr " undersøger katalogomdøbninger\n"
+
+#, python-format
+msgid " dir %s -> %s\n"
+msgstr " katalog %s -> %s\n"
+
+#, python-format
+msgid " file %s -> %s\n"
+msgstr " fil %s -> %s\n"
+
+msgid "working directory state appears damaged!"
+msgstr "arbejdskatalogtilstand virker beskadiget!"
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr "'\\n' og '\\r' må ikke forekomme i filnavne: %r"
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr "katalog %r er allerede i dirstate"
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr ""
+
+#, python-format
+msgid "not in dirstate: %s\n"
+msgstr "ikke i dirstate: %s\n"
+
+msgid "unknown"
+msgstr "ukendt"
+
+msgid "character device"
+msgstr "tegn-specialfil"
+
+msgid "block device"
+msgstr "blok-specialfil"
+
+msgid "fifo"
+msgstr "fifo"
+
+msgid "socket"
+msgstr "sokkel"
+
+msgid "directory"
+msgstr "katalog"
+
+#, python-format
+msgid "unsupported file type (type is %s)"
+msgstr "usupporteret filtype (typen er %s)"
+
+#, python-format
+msgid "abort: %s\n"
+msgstr "afbrudt: %s\n"
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+" %s\n"
+msgstr ""
+"hg: kommandoen '%s' is tvetydig:\n"
+" %s\n"
+
+#, python-format
+msgid "hg: %s\n"
+msgstr "hg: %s\n"
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr "tiden løb ud ved vent på lås holdt af %s"
+
+#, python-format
+msgid "lock held by %s"
+msgstr "lås holdt af %s"
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr "afbrudt: %s: %s\n"
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr "afbrudt: kunne ikke låse %s: %s\n"
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr "hg %s: %s\n"
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr "afbrudt: %s!\n"
+
+#, python-format
+msgid "abort: %s"
+msgstr "afbrudt: %s"
+
+msgid " empty string\n"
+msgstr " tom streng\n"
+
+msgid "killed!\n"
+msgstr "dræbt!\n"
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr "hg: ukendt kommando '%s'\n"
+
+#, python-format
+msgid "abort: could not import module %s!\n"
+msgstr "afbrudt: kunne ikke importere modul %s!\n"
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr "(glemte du at kompilere udvidelserne?)\n"
+
+msgid "(is your Python install correct?)\n"
+msgstr "(er din Python installeret korrekt?)\n"
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr "afbrudt: fejl: %s\n"
+
+msgid "broken pipe\n"
+msgstr "afbrudt pipe\n"
+
+msgid "interrupted!\n"
+msgstr "standset!\n"
+
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+"\n"
+"afbrudt pipe\n"
+
+msgid "abort: out of memory\n"
+msgstr "afbrudt: løbet tør for hukommelse\n"
+
+msgid "** unknown exception encountered, details follow\n"
+msgstr "** der opstod en ukendt fejl, detaljer følger\n"
+
+msgid "** report bug details to http://mercurial.selenic.com/bts/\n"
+msgstr "** angiv fejldetaljer på http://mercurial.selenic.com/bts/\n"
+
+msgid "** or mercurial@selenic.com\n"
+msgstr "** eller mercurial@selenic.com\n"
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr "** Mercurial Distributed SCM (version %s)\n"
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr "** Udvidelser indlæst: %s\n"
+
+#, python-format
+msgid "no definition for alias '%s'\n"
+msgstr "ingen definition for alias '%s'\n"
+
+#, python-format
+msgid "alias '%s' resolves to unknown command '%s'\n"
+msgstr "alias '%s' oversætter til ukendt kommando '%s'\n"
+
+#, python-format
+msgid "alias '%s' resolves to ambiguous command '%s'\n"
+msgstr "alias '%s' oversætter til tvetydig kommando '%s'\n"
+
+#, python-format
+msgid "alias '%s' shadows command\n"
+msgstr "alias '%s' skygger for en kommando\n"
+
+#, python-format
+msgid "malformed --config option: %s"
+msgstr "misdannet --config tilvalg: %s"
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr "udvidelse '%s' overskriver kommandoer: %s\n"
+
+msgid "Option --config may not be abbreviated!"
+msgstr "Tilvalget --config må ikke forkortes!"
+
+msgid "Option --cwd may not be abbreviated!"
+msgstr "Tilvalget --cwd må ikke forkortes!"
+
+msgid ""
+"Option -R has to be separated from other options (e.g. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr ""
+"Tilvalget -R skal adskilles fra andre tilvalg (fx ikke -qR) og --repository "
+"må kun forkortes som --repo!"
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr ""
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr "depot '%s' er ikke lokalt"
+
+msgid "invalid arguments"
+msgstr "ugyldige parametre"
+
+#, python-format
+msgid "unrecognized profiling format '%s' - Ignored\n"
+msgstr "profileringsformat '%s' ikke genkendt - Ignoreret\n"
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+"lsprof er ikke tilgængelig - installer fra http://codespeak.net/svn/user/"
+"arigo/hack/misc/lsprof/"
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr "*** import af udvidelse %s fra %s fejlede: %s\n"
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr "*** import af udvidelse %s fejlede: %s\n"
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr "kunne ikke finde sammenføjningsværktøj %s\n"
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr "værktøj %s kan ikke håndtere symbolske lænker\n"
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr "værktøj %s kan ikke håndtere binære filer\n"
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr "værktøj %s kræver et GUI\n"
+
+#, python-format
+msgid "picked tool '%s' for %s (binary %s symlink %s)\n"
+msgstr "valgte værktøj '%s' til %s (binær %s symbolsk link %s)\n"
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+
+msgid "&Local"
+msgstr ""
+
+msgid "&Other"
+msgstr ""
+
+msgid "l"
+msgstr "l"
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr "føjer %s og %s sammen til %s\n"
+
+#, python-format
+msgid "merging %s\n"
+msgstr "sammenføjer %s\n"
+
+#, python-format
+msgid "my %s other %s ancestor %s\n"
+msgstr "min %s anden %s forfar %s\n"
+
+msgid " premerge successful\n"
+msgstr "præ-sammenføjning succesfuld\n"
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+
+msgid "&No"
+msgstr ""
+
+msgid "&Yes"
+msgstr ""
+
+msgid "n"
+msgstr ""
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr "sammenføjning af %s fejlede!\n"
+
+#, python-format
+msgid "Inconsistent state, %s:%s is good and bad"
+msgstr ""
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial has the ability to add new features through the use of\n"
+" extensions. Extensions may add new commands, add options to\n"
+" existing commands, change the default behavior of commands, or\n"
+" implement hooks.\n"
+"\n"
+" Extensions are not loaded by default for a variety of reasons:\n"
+" they can increase startup overhead; they may be meant for\n"
+" advanced usage only; they may provide potentially dangerous\n"
+" abilities (such as letting you destroy or modify history); they\n"
+" might not be ready for prime time; or they may alter some\n"
+" usual behaviors of stock Mercurial. It is thus up to the user to\n"
+" activate extensions as needed.\n"
+"\n"
+" To enable the \"foo\" extension, either shipped with Mercurial\n"
+" or in the Python search path, create an entry for it in your\n"
+" hgrc, like this:\n"
+"\n"
+" [extensions]\n"
+" foo =\n"
+"\n"
+" You may also specify the full path to an extension:\n"
+"\n"
+" [extensions]\n"
+" myfeature = ~/.hgext/myfeature.py\n"
+"\n"
+" To explicitly disable an extension enabled in an hgrc of broader\n"
+" scope, prepend its path with !:\n"
+"\n"
+" [extensions]\n"
+" # disabling extension bar residing in /path/to/extension/bar.py\n"
+" hgext.bar = !/path/to/extension/bar.py\n"
+" # ditto, but no path was supplied for extension baz\n"
+" hgext.baz = !\n"
+" "
+msgstr ""
+
+msgid "disabled extensions:"
+msgstr "deaktiverede udvidelser:"
+
+msgid "Date Formats"
+msgstr "Datoformater"
+
+msgid ""
+"\n"
+" Some commands allow the user to specify a date, e.g.:\n"
+" * backout, commit, import, tag: Specify the commit date.\n"
+" * log, revert, update: Select revision(s) by date.\n"
+"\n"
+" Many date formats are valid. Here are some examples:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n"
+" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n"
+" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n"
+" \"Dec 6\" (midnight)\n"
+" \"13:18\" (today assumed)\n"
+" \"3:39\" (3:39AM assumed)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Lastly, there is Mercurial's internal format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" This is the internal representation format for dates. unixtime is\n"
+" the number of seconds since the epoch (1970-01-01 00:00 UTC).\n"
+" offset is the offset of the local timezone, in seconds west of UTC\n"
+" (negative if the timezone is east of UTC).\n"
+"\n"
+" The log command also accepts date ranges:\n"
+"\n"
+" \"<{datetime}\" - at or before a given date/time\n"
+" \">{datetime}\" - on or after a given date/time\n"
+" \"{datetime} to {datetime}\" - a date range, inclusive\n"
+" \"-{days}\" - within a given number of days of today\n"
+" "
+msgstr ""
+"\n"
+" Nogle kommandoer tillader brugeren at specificere en dato, f.eks.:\n"
+" * backout, commit, import, tag: specificer commit-datoen.\n"
+" * log, revert, update: vælg revisioner efter dato.\n"
+"\n"
+" Der er mange gyldige datoformater. Her er nogle eksempler:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (antager lokal tidszone)\n"
+" \"Dec 6 13:18 -0600\" (antager år, tidszone er angivet)\n"
+" \"Dec 6 13:18 UTC\" (UTC og GMT er aliaser for +0000)\n"
+" \"Dec 6\" (midnat)\n"
+" \"13:18\" (antager dags dato)\n"
+" \"3:39\"\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (6. dec. 2006)\n"
+"\n"
+" Endelig er der Mercurials interne format:\n"
+"\n"
+" \"1165432709 0\" (Ons 6. dec. 13:18:29 2006 UTC)\n"
+"\n"
+" Dette er den interne repræsentation af datoer. unixtime er\n"
+" antallet af sekunder siden begyndelsen af epoken (1970-01-01 00:00\n"
+" UTC). offset er den lokale tidszone, angivet i antal sekunder vest\n"
+" for UTC (negativ hvis tidszonen er øst for UTC).\n"
+"\n"
+" Kommandoen log accepterer også datointervaller:\n"
+"\n"
+" \"<{date}\" - på eller før den angivne dato/tidspunkt\n"
+" \">{date}\" - på eller efter den angivne dato/tidspunkt\n"
+" \"{date} to {date}\" - et datointerval, inklusiv endepunkterne\n"
+" \"-{days}\" - indenfor et angivet antal dage, fra dags dato\n"
+" "
+
+msgid "File Name Patterns"
+msgstr "Mønstre for filnavne"
+
+msgid ""
+"\n"
+" Mercurial accepts several notations for identifying one or more\n"
+" files at a time.\n"
+"\n"
+" By default, Mercurial treats filenames as shell-style extended\n"
+" glob patterns.\n"
+"\n"
+" Alternate pattern notations must be specified explicitly.\n"
+"\n"
+" To use a plain path name without any pattern matching, start it\n"
+" with \"path:\". These path names must completely match starting at\n"
+" the current repository root.\n"
+"\n"
+" To use an extended glob, start a name with \"glob:\". Globs are\n"
+" rooted at the current directory; a glob such as \"*.c\" will only\n"
+" match files in the current directory ending with \".c\".\n"
+"\n"
+" The supported glob syntax extensions are \"**\" to match any string\n"
+" across path separators and \"{a,b}\" to mean \"a or b\".\n"
+"\n"
+" To use a Perl/Python regular expression, start a name with \"re:\".\n"
+" Regexp pattern matching is anchored at the root of the repository.\n"
+"\n"
+" Plain examples:\n"
+"\n"
+" path:foo/bar a name bar in a directory named foo in the root of\n"
+" the repository\n"
+" path:path:name a file or directory named \"path:name\"\n"
+"\n"
+" Glob examples:\n"
+"\n"
+" glob:*.c any name ending in \".c\" in the current directory\n"
+" *.c any name ending in \".c\" in the current directory\n"
+" **.c any name ending in \".c\" in any subdirectory of the\n"
+" current directory including itself.\n"
+" foo/*.c any name ending in \".c\" in the directory foo\n"
+" foo/**.c any name ending in \".c\" in any subdirectory of foo\n"
+" including itself.\n"
+"\n"
+" Regexp examples:\n"
+"\n"
+" re:.*\\.c$ any name ending in \".c\", anywhere in the repository\n"
+"\n"
+" "
+msgstr ""
+
+msgid "Environment Variables"
+msgstr "Miljøvariable"
+
+msgid ""
+"\n"
+"HG::\n"
+" Path to the 'hg' executable, automatically passed when running\n"
+" hooks, extensions or external tools. If unset or empty, this is\n"
+" the hg executable's name if it's frozen, or an executable named\n"
+" 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+" Windows) is searched.\n"
+"\n"
+"HGEDITOR::\n"
+" This is the name of the editor to run when committing. See EDITOR.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" This overrides the default locale setting detected by Mercurial.\n"
+" This setting is used to convert data including usernames,\n"
+" changeset descriptions, tag names, and branches. This setting can\n"
+" be overridden with the --encoding command-line option.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" This sets Mercurial's behavior for handling unknown characters\n"
+" while transcoding user input. The default is \"strict\", which\n"
+" causes Mercurial to abort if it can't map a character. Other\n"
+" settings include \"replace\", which replaces unknown characters, and\n"
+" \"ignore\", which drops them. This setting can be overridden with\n"
+" the --encodingmode command-line option.\n"
+"\n"
+"HGMERGE::\n"
+" An executable to use for resolving merge conflicts. The program\n"
+" will be executed with three arguments: local file, remote file,\n"
+" ancestor file.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" A list of files or directories to search for hgrc files. Item\n"
+" separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
+" platform default search path is used. If empty, only the .hg/hgrc\n"
+" from the current repository is read.\n"
+"\n"
+" For each element in HGRCPATH:\n"
+" * if it's a directory, all files ending with .rc are added\n"
+" * otherwise, the file itself will be added\n"
+"\n"
+"HGUSER::\n"
+" This is the string used as the author of a commit. If not set,\n"
+" available values will be considered in this order:\n"
+"\n"
+" * HGUSER (deprecated)\n"
+" * hgrc files from the HGRCPATH\n"
+" * EMAIL\n"
+" * interactive prompt\n"
+" * LOGNAME (with '@hostname' appended)\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"LOGNAME::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"VISUAL::\n"
+" This is the name of the editor to use when committing. See EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Sometimes Mercurial needs to open a text file in an editor for a\n"
+" user to modify, for example when writing commit messages. The\n"
+" editor it uses is determined by looking at the environment\n"
+" variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+" non-empty one is chosen. If all of them are empty, the editor\n"
+" defaults to 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" This is used by Python to find imported modules and may need to be\n"
+" set appropriately if this Mercurial is not installed system-wide.\n"
+" "
+msgstr ""
+
+msgid "Specifying Single Revisions"
+msgstr "Angivning af en enkelt revision"
+
+msgid ""
+"\n"
+" Mercurial supports several ways to specify individual revisions.\n"
+"\n"
+" A plain integer is treated as a revision number. Negative integers\n"
+" are treated as topological offsets from the tip, with -1 denoting\n"
+" the tip. As such, negative numbers are only useful if you've\n"
+" memorized your local tree numbers and want to save typing a single\n"
+" digit. This editor suggests copy and paste.\n"
+"\n"
+" A 40-digit hexadecimal string is treated as a unique revision\n"
+" identifier.\n"
+"\n"
+" A hexadecimal string less than 40 characters long is treated as a\n"
+" unique revision identifier, and referred to as a short-form\n"
+" identifier. A short-form identifier is only valid if it is the\n"
+" prefix of exactly one full-length identifier.\n"
+"\n"
+" Any other string is treated as a tag name, which is a symbolic\n"
+" name associated with a revision identifier. Tag names may not\n"
+" contain the \":\" character.\n"
+"\n"
+" The reserved name \"tip\" is a special tag that always identifies\n"
+" the most recent revision.\n"
+"\n"
+" The reserved name \"null\" indicates the null revision. This is the\n"
+" revision of an empty repository, and the parent of revision 0.\n"
+"\n"
+" The reserved name \".\" indicates the working directory parent. If\n"
+" no working directory is checked out, it is equivalent to null. If\n"
+" an uncommitted merge is in progress, \".\" is the revision of the\n"
+" first parent.\n"
+" "
+msgstr ""
+
+msgid "Specifying Multiple Revisions"
+msgstr "Angivning af flere revisioner"
+
+msgid ""
+"\n"
+" When Mercurial accepts more than one revision, they may be\n"
+" specified individually, or provided as a topologically continuous\n"
+" range, separated by the \":\" character.\n"
+"\n"
+" The syntax of range notation is [BEGIN]:[END], where BEGIN and END\n"
+" are revision identifiers. Both BEGIN and END are optional. If\n"
+" BEGIN is not specified, it defaults to revision number 0. If END\n"
+" is not specified, it defaults to the tip. The range \":\" thus means\n"
+" \"all revisions\".\n"
+"\n"
+" If BEGIN is greater than END, revisions are treated in reverse\n"
+" order.\n"
+"\n"
+" A range acts as a closed interval. This means that a range of 3:5\n"
+" gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+" "
+msgstr ""
+
+msgid "Diff Formats"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial's default format for showing changes between two\n"
+" versions of a file is compatible with the unified format of GNU\n"
+" diff, which can be used by GNU patch and many other standard\n"
+" tools.\n"
+"\n"
+" While this standard format is often enough, it does not encode the\n"
+" following information:\n"
+"\n"
+" - executable status and other permission bits\n"
+" - copy or rename information\n"
+" - changes in binary files\n"
+" - creation or deletion of empty files\n"
+"\n"
+" Mercurial also supports the extended diff format from the git VCS\n"
+" which addresses these limitations. The git diff format is not\n"
+" produced by default because a few widespread tools still do not\n"
+" understand this format.\n"
+"\n"
+" This means that when generating diffs from a Mercurial repository\n"
+" (e.g. with \"hg export\"), you should be careful about things like\n"
+" file copies and renames or other things mentioned above, because\n"
+" when applying a standard diff to a different repository, this\n"
+" extra information is lost. Mercurial's internal operations (like\n"
+" push and pull) are not affected by this, because they use an\n"
+" internal binary format for communicating changes.\n"
+"\n"
+" To make Mercurial produce the git extended diff format, use the\n"
+" --git option available for many commands, or set 'git = True' in\n"
+" the [diff] section of your hgrc. You do not need to set this\n"
+" option when importing diffs in this format or using them in the mq\n"
+" extension.\n"
+" "
+msgstr ""
+
+msgid "Template Usage"
+msgstr "Brug af skabeloner"
+
+msgid ""
+"\n"
+" Mercurial allows you to customize output of commands through\n"
+" templates. You can either pass in a template from the command\n"
+" line, via the --template option, or select an existing\n"
+" template-style (--style).\n"
+"\n"
+" You can customize output for any \"log-like\" command: log,\n"
+" outgoing, incoming, tip, parents, heads and glog.\n"
+"\n"
+" Three styles are packaged with Mercurial: default (the style used\n"
+" when no explicit preference is passed), compact and changelog.\n"
+" Usage:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" A template is a piece of text, with markup to invoke variable\n"
+" expansion:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings in curly braces are called keywords. The availability of\n"
+" keywords depends on the exact context of the templater. These\n"
+" keywords are usually available for templating a log-like command:\n"
+"\n"
+" - author: String. The unmodified author of the changeset.\n"
+" - branches: String. The name of the branch on which the changeset\n"
+" was committed. Will be empty if the branch name was default.\n"
+" - date: Date information. The date when the changeset was committed.\n"
+" - desc: String. The text of the changeset description.\n"
+" - diffstat: String. Statistics of changes with the following\n"
+" format: \"modified files: +added/-removed lines\"\n"
+" - files: List of strings. All files modified, added, or removed by\n"
+" this changeset.\n"
+" - file_adds: List of strings. Files added by this changeset.\n"
+" - file_mods: List of strings. Files modified by this changeset.\n"
+" - file_dels: List of strings. Files removed by this changeset.\n"
+" - node: String. The changeset identification hash, as a\n"
+" 40-character hexadecimal string.\n"
+" - parents: List of strings. The parents of the changeset.\n"
+" - rev: Integer. The repository-local changeset revision number.\n"
+" - tags: List of strings. Any tags associated with the changeset.\n"
+"\n"
+" The \"date\" keyword does not produce human-readable output. If you\n"
+" want to use a date in your output, you can use a filter to process\n"
+" it. Filters are functions which return a string based on the input\n"
+" variable. You can also use a chain of filters to get the desired\n"
+" output:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" List of filters:\n"
+"\n"
+" - addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
+" every line except the last.\n"
+" - age: Date. Returns a human-readable date/time difference between\n"
+" the given date/time and the current date/time.\n"
+" - basename: Any text. Treats the text as a path, and returns the\n"
+" last component of the path after splitting by the path\n"
+" separator (ignoring trailing separators). For example,\n"
+" \"foo/bar/baz\" becomes \"baz\" and \"foo/bar//\" becomes \"bar"
+"\".\n"
+" - stripdir: Treat the text as path and strip a directory level, if\n"
+" possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\".\n"
+" - date: Date. Returns a date in a Unix date format, including\n"
+" the timezone: \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - domain: Any text. Finds the first string that looks like an\n"
+" email address, and extracts just the domain component.\n"
+" Example: 'User <user@example.com>' becomes 'example.com'.\n"
+" - email: Any text. Extracts the first string that looks like an\n"
+" email address. Example: 'User <user@example.com>' becomes\n"
+" 'user@example.com'.\n"
+" - escape: Any text. Replaces the special XML/XHTML characters \"&\",\n"
+" \"<\" and \">\" with XML entities.\n"
+" - fill68: Any text. Wraps the text to fit in 68 columns.\n"
+" - fill76: Any text. Wraps the text to fit in 76 columns.\n"
+" - firstline: Any text. Returns the first line of text.\n"
+" - nonempty: Any text. Returns '(none)' if the string is empty.\n"
+" - hgdate: Date. Returns the date as a pair of numbers:\n"
+" \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
+" - isodate: Date. Returns the date in ISO 8601 format.\n"
+" - localdate: Date. Converts a date to local date.\n"
+" - obfuscate: Any text. Returns the input text rendered as a\n"
+" sequence of XML entities.\n"
+" - person: Any text. Returns the text before an email address.\n"
+" - rfc822date: Date. Returns a date using the same format used\n"
+" in email headers.\n"
+" - short: Changeset hash. Returns the short form of a changeset\n"
+" hash, i.e. a 12-byte hexadecimal string.\n"
+" - shortdate: Date. Returns a date like \"2006-09-18\".\n"
+" - strip: Any text. Strips all leading and trailing whitespace.\n"
+" - tabindent: Any text. Returns the text, with every line except\n"
+" the first starting with a tab character.\n"
+" - urlescape: Any text. Escapes all \"special\" characters. For\n"
+" example, \"foo bar\" becomes \"foo%20bar\".\n"
+" - user: Any text. Returns the user portion of an email address.\n"
+" "
+msgstr ""
+
+msgid "URL Paths"
+msgstr "URL-stier"
+
+msgid ""
+"\n"
+" Valid URLs are of the form:\n"
+"\n"
+" local/filesystem/path[#revision]\n"
+" file://local/filesystem/path[#revision]\n"
+" http://[user[:pass]@]host[:port]/[path][#revision]\n"
+" https://[user[:pass]@]host[:port]/[path][#revision]\n"
+" ssh://[user[:pass]@]host[:port]/[path][#revision]\n"
+"\n"
+" Paths in the local filesystem can either point to Mercurial\n"
+" repositories or to bundle files (as created by 'hg bundle' or\n"
+" 'hg incoming --bundle').\n"
+"\n"
+" An optional identifier after # indicates a particular branch, tag,\n"
+" or changeset to use from the remote repository. See also 'hg help\n"
+" revisions'.\n"
+"\n"
+" Some features, such as pushing to http:// and https:// URLs are\n"
+" only possible if the feature is explicitly enabled on the remote\n"
+" Mercurial server.\n"
+"\n"
+" Some notes about using SSH with Mercurial:\n"
+" - SSH requires an accessible shell account on the destination\n"
+" machine and a copy of hg in the remote path or specified with as\n"
+" remotecmd.\n"
+" - path is relative to the remote user's home directory by default.\n"
+" Use an extra slash at the start of a path to specify an absolute "
+"path:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial doesn't use its own compression via SSH; the right\n"
+" thing to do is to configure it in your ~/.ssh/config, e.g.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternatively specify \"ssh -C\" as your ssh command in your hgrc\n"
+" or with the --ssh command line option.\n"
+"\n"
+" These URLs can all be stored in your hgrc with path aliases under\n"
+" the [paths] section like so:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" You can then use the alias for any command that uses a URL (for\n"
+" example 'hg pull alias1' would pull from the 'alias1' path).\n"
+"\n"
+" Two path aliases are special because they are used as defaults\n"
+" when you do not provide the URL to a command:\n"
+"\n"
+" default:\n"
+" When you create a repository with hg clone, the clone command\n"
+" saves the location of the source repository as the new\n"
+" repository's 'default' path. This is then used when you omit\n"
+" path from push- and pull-like commands (including incoming and\n"
+" outgoing).\n"
+"\n"
+" default-push:\n"
+" The push command will look for a path named 'default-push', and\n"
+" prefer it over 'default' if both are defined.\n"
+" "
+msgstr ""
+
+msgid "Using additional features"
+msgstr "Brug af yderligere funktioner"
+
+msgid "can only share local repositories"
+msgstr "kan kun dele lokale depoter"
+
+msgid "destination already exists"
+msgstr "destinationen eksisterer allerede"
+
+msgid "updating working directory\n"
+msgstr "opdaterer arbejdskatalog\n"
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr "målkatalog: %s\n"
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr "målet '%s' eksisterer allerede"
+
+#, python-format
+msgid "destination '%s' is not empty"
+msgstr "målet '%s' er ikke tomt"
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr ""
+
+msgid "clone from remote to remote not supported"
+msgstr "kloning fra fjerndepot til fjerndepot er ikke understøttet"
+
+msgid "updated"
+msgstr "opdateret"
+
+msgid "merged"
+msgstr "sammenføjet"
+
+msgid "removed"
+msgstr "fjernet"
+
+msgid "unresolved"
+msgstr "uløst"
+
+#, python-format
+msgid "%d files %s"
+msgstr "%d filer %s"
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr "brug 'hg resolve' for at prøve at sammenføje uløste filer igen\n"
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to "
+"abandon\n"
+msgstr ""
+"brug 'hg resolve' for at prøve at sammenføje uløste filer igen eller 'hg up "
+"--clean' for at opgive\n"
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr "(grensammenføjning, glem ikke at deponere)\n"
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr "fejl ved læsning af %s/.hg/hgrc: %s\n"
+
+msgid "SSL support is unavailable"
+msgstr "understøttelse for SSL er ikke tilstede"
+
+msgid "IPv6 is not available on this system"
+msgstr "IPv6 er ikke til rådighed på dette system"
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr "kan ikke starte server på '%s:%d': %s"
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook failed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr ""
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook %s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr ""
+
+msgid "connection ended unexpectedly"
+msgstr "forbindelsen blev uventet afsluttet"
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr "ikke-understøttet URL-komponent: \"%s\""
+
+#, python-format
+msgid "using %s\n"
+msgstr "bruger %s\n"
+
+#, python-format
+msgid "capabilities: %s\n"
+msgstr "kapaciteter: %s\n"
+
+msgid "operation not supported over http"
+msgstr "operationen understøttes ikke over http"
+
+#, python-format
+msgid "sending %s command\n"
+msgstr "sender %s kommando\n"
+
+#, python-format
+msgid "sending %s bytes\n"
+msgstr "sender %s bytes\n"
+
+msgid "authorization failed"
+msgstr "autorisation fejlede"
+
+#, python-format
+msgid "http error while sending %s command\n"
+msgstr "http-fejl mens %s kommandoen blev sendt\n"
+
+msgid "http error, possibly caused by proxy setting"
+msgstr "http-fejl, skyldes muligvis proxy-indstillinger"
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr "den rigtige URL er %s\n"
+
+#, python-format
+msgid "requested URL: '%s'\n"
+msgstr "forespurgt URL: '%s'\n"
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr "'%s' ser ikke ud til at være et hg depot"
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr "'%s' sendte ødelagt Content-Type header (%s)"
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr "'%s' bruger nyere protokol %s"
+
+msgid "look up remote revision"
+msgstr ""
+
+msgid "unexpected response:"
+msgstr "uventet svar:"
+
+msgid "look up remote changes"
+msgstr ""
+
+msgid "push failed (unexpected response):"
+msgstr "skub fejlede (uventet svar):"
+
+#, python-format
+msgid "push failed: %s"
+msgstr "skub fejlede: %s"
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr "Python support for SSL og HTTPS er ikke installeret"
+
+msgid "cannot create new http repository"
+msgstr "kan ikke lave nyt http depot"
+
+#, python-format
+msgid "%s: ignoring invalid syntax '%s'\n"
+msgstr "%s: ignorerer ugyldig syntaks '%s'\n"
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr "springer ulæselig ignorefil '%s' over: %s\n"
+
+#, python-format
+msgid "repository %s not found"
+msgstr "depotet %s blev ikke fundet"
+
+#, python-format
+msgid "repository %s already exists"
+msgstr "depotet %s eksisterer allerede"
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr "betingelse '%s' er ikke understøttet"
+
+#, python-format
+msgid ".hg/sharedpath points to nonexistent directory %s"
+msgstr ".hg/sharedpath peger på et ikke-eksisterende katalog %s"
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr "%r kan ikke bruges i et mærkatnavnet"
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr "arbejdskopien af .hgtags er ændret (deponer venligst .hgtags manuelt)"
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr "%s, linie %s: %s\n"
+
+msgid "cannot parse entry"
+msgstr ""
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr "knude '%s' er ikke korrekt formet"
+
+#, python-format
+msgid "working directory has unknown parent '%s'!"
+msgstr "arbejdsbiblioteket har ukendt forældre '%s'!"
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr "ukendt revision '%s'"
+
+#, python-format
+msgid "filtering %s through %s\n"
+msgstr "filtrerer %s gennem %s\n"
+
+msgid "journal already exists - run hg recover"
+msgstr "journalen eksisterer allerede -- kør hg recover"
+
+msgid "rolling back interrupted transaction\n"
+msgstr "ruller afbrudt transaktion tilbage\n"
+
+msgid "no interrupted transaction available\n"
+msgstr "ingen afbrudt transaktion tilgængelig\n"
+
+msgid "rolling back last transaction\n"
+msgstr "ruller sidste transaktion tilbage\n"
+
+#, python-format
+msgid "Named branch could not be reset, current branch still is: %s\n"
+msgstr ""
+"Navngiven gren kunne ikke nulstilles, den nuværende gren er stadig: %s\n"
+
+msgid "no rollback information available\n"
+msgstr "ingen tilbagerulningsinformation til stede\n"
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr "venter på lås af %s holdt af %r\n"
+
+#, python-format
+msgid "repository %s"
+msgstr "depot %s"
+
+#, python-format
+msgid "working directory of %s"
+msgstr "arbejdskatalog for %s"
+
+#, python-format
+msgid " %s: searching for copy revision for %s\n"
+msgstr ""
+
+#, python-format
+msgid " %s: copy %s:%s\n"
+msgstr ""
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr ""
+
+msgid "file not found!"
+msgstr "filen blev ikke fundet!"
+
+msgid "no match under directory!"
+msgstr "ingen træffer under kataloget!"
+
+msgid "file not tracked!"
+msgstr "filen følges ikke!"
+
+msgid "unresolved merge conflicts (see hg resolve)"
+msgstr "uløste sammenføjningskonflikter (se hg resolve)"
+
+#, python-format
+msgid "committing subrepository %s\n"
+msgstr "deponerer underdepot %s\n"
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr "problem ved deponering %s!\n"
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr "%s eksisterer ikke!\n"
+
+#, python-format
+msgid ""
+"%s: files over 10MB may cause memory and performance problems\n"
+"(use 'hg revert %s' to unadd the file)\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr ""
+"%s ikke tilføjet: i øjeblikket understøttes kun filer og symbolske lænker\n"
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr "%s følges allerede!\n"
+
+#, python-format
+msgid "%s not added!\n"
+msgstr "%s ikke tilføjet!\n"
+
+#, python-format
+msgid "%s still exists!\n"
+msgstr "%s eksisterer stadig!\n"
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr "%s følges ikke\n"
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr "%s ikke fjernet!\n"
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr "kopiering fejlede: %s er ikke en fil eller en symbolsk længe\n"
+
+msgid "searching for changes\n"
+msgstr "leder efter ændringer\n"
+
+#, python-format
+msgid "examining %s:%s\n"
+msgstr "undersøger %s:%s\n"
+
+msgid "branch already found\n"
+msgstr "gren er allerede fundet\n"
+
+#, python-format
+msgid "found incomplete branch %s:%s\n"
+msgstr "fandt ukomplet gren %s:%s\n"
+
+#, python-format
+msgid "found new changeset %s\n"
+msgstr "fandt ny ændring %s\n"
+
+#, python-format
+msgid "request %d: %s\n"
+msgstr "forespørgsel %d: %s\n"
+
+#, python-format
+msgid "received %s:%s\n"
+msgstr "modtog %s:%s\n"
+
+#, python-format
+msgid "narrowing %d:%d %s\n"
+msgstr "indskrænker %d:%d %s\n"
+
+#, python-format
+msgid "found new branch changeset %s\n"
+msgstr "fandt ny forgreningsændring %s\n"
+
+#, python-format
+msgid "narrowed branch search to %s:%s\n"
+msgstr "indskrænker forgreningssøgning til %s:%s\n"
+
+msgid "already have changeset "
+msgstr "har allerede ændringen "
+
+msgid "warning: repository is unrelated\n"
+msgstr "advarsel: depotet er urelateret\n"
+
+msgid "repository is unrelated"
+msgstr "depotet er urelateret"
+
+msgid "found new changesets starting at "
+msgstr "fandt nye ændringer startende ved "
+
+#, python-format
+msgid "%d total queries\n"
+msgstr "%d forespørgsler i alt\n"
+
+msgid "common changesets up to "
+msgstr "fælles ændringer op til "
+
+msgid "requesting all changes\n"
+msgstr "anmoder om alle ændringer\n"
+
+msgid ""
+"Partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr ""
+
+#, python-format
+msgid "abort: push creates new remote branch '%s'!\n"
+msgstr "afbrudt: skub laver ny gren '%s' i fjerndepotet!\n"
+
+msgid "abort: push creates new remote heads!\n"
+msgstr "afbrudt: skub laver nye fjern-hoveder!\n"
+
+msgid "(did you forget to merge? use push -f to force)\n"
+msgstr "(glemte du at sammenføje? brug push -f for at gennemtvinge)\n"
+
+msgid "note: unsynced remote changes!\n"
+msgstr ""
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr "fandt %d ændringer\n"
+
+msgid "list of changesets:\n"
+msgstr "liste af ændringer:\n"
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr "tom eller manglende revlog for %s"
+
+#, python-format
+msgid "add changeset %s\n"
+msgstr "tilføj ændring %s\n"
+
+msgid "adding changesets\n"
+msgstr "tilføjer ændringer\n"
+
+msgid "received changelog group is empty"
+msgstr "modtagen changelog-gruppe er tom"
+
+msgid "adding manifests\n"
+msgstr "tilføjer manifester\n"
+
+msgid "adding file changes\n"
+msgstr "tilføjer filændringer\n"
+
+#, python-format
+msgid "adding %s revisions\n"
+msgstr "tilføjer %s ændringer\n"
+
+msgid "received file revlog group is empty"
+msgstr ""
+
+#, python-format
+msgid " (%+d heads)"
+msgstr " (%+d hoveder)"
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr "tilføjede %d ændringer med %d ændringer i %d filer%s\n"
+
+msgid "updating the branch cache\n"
+msgstr ""
+
+msgid "Unexpected response from remote server:"
+msgstr "Uventet svar fra fjernserver:"
+
+msgid "operation forbidden by server"
+msgstr "operationen er forbudt af serveren"
+
+msgid "locking the remote repository failed"
+msgstr "låsning af fjerndepotet fejlede"
+
+msgid "the server sent an unknown error code"
+msgstr ""
+
+msgid "streaming all changes\n"
+msgstr ""
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr "%d filer at overføre, %s data\n"
+
+#, python-format
+msgid "adding %s (%s)\n"
+msgstr "tilføjer %s (%s)\n"
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr "overførte %s i %.1f sekunder (%s/sek)\n"
+
+msgid "no [smtp]host in hgrc - cannot send mail"
+msgstr ""
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr ""
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr "kan ikke bruge TLS: Python SSL support er ikke installeret"
+
+msgid "(using tls)\n"
+msgstr "(bruger tsl)\n"
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr "(autentificerer til mailserver som %s)\n"
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr "sender post: %s\n"
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr ""
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr ""
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr "ugyldig e-post-adresse: %s"
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr "ugyldig lokal adresse: %s"
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr "kunne ikke fjerne %s fra manifest"
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr ""
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr ""
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr ""
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+
+msgid "&None"
+msgstr ""
+
+msgid "E&xec"
+msgstr ""
+
+msgid "Sym&link"
+msgstr ""
+
+msgid "resolving manifests\n"
+msgstr "løser manifester\n"
+
+#, python-format
+msgid " overwrite %s partial %s\n"
+msgstr ""
+
+#, python-format
+msgid " ancestor %s local %s remote %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+msgid "&Changed"
+msgstr ""
+
+msgid "&Delete"
+msgstr ""
+
+msgid "c"
+msgstr ""
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+
+msgid "&Deleted"
+msgstr ""
+
+#, python-format
+msgid "preserving %s for resolve of %s\n"
+msgstr "bevarer %s til løsning af %s\n"
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr "opdatering kunne ikke fjerne %s: %s!\n"
+
+#, python-format
+msgid "getting %s\n"
+msgstr "henter %s\n"
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr "henter %s til %s\n"
+
+#, python-format
+msgid "warning: detected divergent renames of %s to:\n"
+msgstr ""
+
+#, python-format
+msgid "branch %s not found"
+msgstr "gren %s blev ikke fundet"
+
+msgid "can't merge with ancestor"
+msgstr "kan ikke sammenføje med forfader"
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr "intet at sammenføje (brug 'hg update' eller kontroller 'hg heads')"
+
+msgid "outstanding uncommitted changes (use 'hg status' to list changes)"
+msgstr ""
+"udestående ikke-deponerede ændringer (brug 'hg status' for at se ændringer)"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C' to discard changes)"
+msgstr ""
+"krydser grene (brug 'hg merge' eller 'hg update -C' for at kassere "
+"ændringerne)"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C')"
+msgstr "krydser grene (brug 'hg merge' eller 'hg update -C')"
+
+msgid "crosses named branches (use 'hg update -C' to discard changes)"
+msgstr ""
+"krydser navngivne grene (brug 'hg update -C' for at kassere ændringerne)"
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr "kan ikke oprette %s: destinationen findes allerede"
+
+#, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr "kan ikke oprette %s: ikke i stand til at oprette biblioteket"
+
+#, python-format
+msgid "found patch at byte %d\n"
+msgstr ""
+
+msgid "patch generated by hg export\n"
+msgstr "rettelse genereret af hg export\n"
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr "kan ikke finde '%s' til retning\n"
+
+#, python-format
+msgid "patching file %s\n"
+msgstr "retter fil %s\n"
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr ""
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr "filen %s eksisterer allerede\n"
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d line).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d lines).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr ""
+
+msgid "could not extract binary patch"
+msgstr ""
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr "binær rettelse er %d byte, ikke %d"
+
+#, python-format
+msgid "unable to strip away %d dirs from %s"
+msgstr "kan ikke strippe %d kataloger fra %s"
+
+msgid "undefined source and destination files"
+msgstr ""
+
+#, python-format
+msgid "malformed patch %s %s"
+msgstr ""
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr ""
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr "patch kommando fejlede: %s"
+
+#, python-format
+msgid "Unsupported line endings type: %s"
+msgstr "Linieendelse %s understøttes ikke"
+
+#, python-format
+msgid "no valid hunks found; trying with %r instead\n"
+msgstr ""
+
+#, python-format
+msgid "exited with status %d"
+msgstr "afsluttede med status %d"
+
+#, python-format
+msgid "killed by signal %d"
+msgstr "dræbt af signal %d"
+
+#, python-format
+msgid "stopped by signal %d"
+msgstr "stoppet af signal %d"
+
+msgid "invalid exit code"
+msgstr "ugyldig returkode"
+
+#, python-format
+msgid "saving bundle to %s\n"
+msgstr "gemmer bundt i %s\n"
+
+msgid "adding branch\n"
+msgstr "tilføjer gren\n"
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr "kan ikke %s: fjerdepotet understøtter ikke %r egenskaben"
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr "ukendt kompressionstype %r"
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr "indeks %s ukendt flag %#04x for format v0"
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr "indeks %s ukendt flag %#04x for revlogng"
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr "indeks %s ukendt format %d"
+
+#, python-format
+msgid "index %s is corrupted"
+msgstr "indeks %s er ødelagt"
+
+msgid "no node"
+msgstr ""
+
+msgid "ambiguous identifier"
+msgstr ""
+
+msgid "no match found"
+msgstr ""
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr ""
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr "%s ikke fundet i transaktionen"
+
+msgid "unknown base"
+msgstr ""
+
+msgid "consistency error adding group"
+msgstr "konsistensfejl ved tilføjelse af gruppe"
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr "%s ser ud som en binær fil."
+
+msgid "can only specify two labels."
+msgstr ""
+
+msgid "warning: conflicts during merge.\n"
+msgstr "advarsel: konflikter ved sammenføjning.\n"
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr ""
+
+msgid "could not create remote repo"
+msgstr "kunne ikke oprette fjerndepot"
+
+msgid "remote: "
+msgstr "fjernsystem: "
+
+msgid "no suitable response from remote hg"
+msgstr "intet brugbart svar fra fjernsystemets hg"
+
+#, python-format
+msgid "push refused: %s"
+msgstr "skub afvist: %s"
+
+msgid "unsynced changes"
+msgstr ""
+
+msgid "cannot lock static-http repository"
+msgstr "kan ikke låse static-http depot"
+
+msgid "cannot create new static-http repository"
+msgstr "kan ikke oprette nyt static-http depot"
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr ""
+
+msgid "scanning\n"
+msgstr "skanner\n"
+
+#, python-format
+msgid "%d files, %d bytes to transfer\n"
+msgstr "%d filer, skal overføre %d byte\n"
+
+#, python-format
+msgid "sending %s (%d bytes)\n"
+msgstr "sender %s (%d byte)\n"
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?"
+msgstr ""
+
+msgid "&Remote"
+msgstr ""
+
+msgid "r"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed subrepository %s which remote removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid ""
+" remote changed subrepository %s which local removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid "removing subrepo %s\n"
+msgstr "fjerner underdepot %s\n"
+
+#, python-format
+msgid "pulling subrepo %s\n"
+msgstr "hiver fra underdepot %s\n"
+
+#, python-format
+msgid "pushing subrepo %s\n"
+msgstr "skubber til underdepot %s\n"
+
+msgid "unmatched quotes"
+msgstr ""
+
+#, python-format
+msgid "error expanding '%s%%%s'"
+msgstr "fejl ved ekspansion af '%s%%%s'"
+
+#, python-format
+msgid "unknown filter '%s'"
+msgstr "ukendt filter '%s'"
+
+#, python-format
+msgid "style not found: %s"
+msgstr ""
+
+#, python-format
+msgid "template file %s: %s"
+msgstr "skabelon-fil %s: %s"
+
+msgid "cannot use transaction when it is already committed/aborted"
+msgstr ""
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr "kunne ikke trunkere %s\n"
+
+msgid "transaction abort!\n"
+msgstr "transaktionen er afbrudt!\n"
+
+msgid "rollback completed\n"
+msgstr "tilbagerulning gennemført\n"
+
+msgid "rollback failed - please run hg recover\n"
+msgstr "tilbagerulning fejlede - kør venligst hg recover\n"
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr "Stoler ikke på filen %s fra ubetroet bruger %s, gruppe %s\n"
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr "Ignoreret: %s\n"
+
+#, python-format
+msgid "ignoring untrusted configuration option %s.%s = %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s.%s not a boolean ('%s')"
+msgstr "%s.%s er ikke en sandhedsværdi ('%s')"
+
+msgid "enter a commit username:"
+msgstr "angiv et deponeringsbrugernavn:"
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr "Fandt intet brugernavn, bruger '%s' istedet\n"
+
+msgid "Please specify a username."
+msgstr "Angiv venligst et brugernavn."
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr "brugernavn %s indeholder et linieskift\n"
+
+msgid "unrecognized response\n"
+msgstr "svar ikke genkendt\n"
+
+msgid "response expected"
+msgstr "svar forventet"
+
+msgid "password: "
+msgstr "kodeord: "
+
+msgid "edit failed"
+msgstr "redigering fejlede"
+
+msgid "http authorization required"
+msgstr ""
+
+msgid "http authorization required\n"
+msgstr ""
+
+#, python-format
+msgid "realm: %s\n"
+msgstr "realm: %s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "bruger: %s\n"
+
+msgid "user:"
+msgstr "bruger:"
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr "http godkendelse: bruger %s, kodeord %s\n"
+
+#, python-format
+msgid "proxying through http://%s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr "kommandoen '%s' fejlede: %s"
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr "stien indeholder ugyldig komponent: %s"
+
+#, python-format
+msgid "path %r is inside repo %r"
+msgstr "stien %r er inde i repo %r"
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr "stien %r følger symbolsk link %r"
+
+msgid "Hardlinks not supported"
+msgstr "Hardlinks er ikke supporteret"
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr "kunne ikke lave et symbolsk link til %r: %s"
+
+#, python-format
+msgid "invalid date: %r "
+msgstr "ugyldig dato: %r "
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr "dato overskrider 32 bit: %d"
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr "umuligt tidszone: %d"
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr "ugyldig datospecifikation: %s"
+
+#, python-format
+msgid "%.0f GB"
+msgstr "%.0f GB"
+
+#, python-format
+msgid "%.1f GB"
+msgstr "%.1f GB"
+
+#, python-format
+msgid "%.2f GB"
+msgstr "%.2f GB"
+
+#, python-format
+msgid "%.0f MB"
+msgstr "%.0f MB"
+
+#, python-format
+msgid "%.1f MB"
+msgstr "%.1f MB"
+
+#, python-format
+msgid "%.2f MB"
+msgstr "%.2f MB"
+
+#, python-format
+msgid "%.0f KB"
+msgstr "%.0f KB"
+
+#, python-format
+msgid "%.1f KB"
+msgstr "%.1f KB"
+
+#, python-format
+msgid "%.2f KB"
+msgstr "%.2f KB"
+
+#, python-format
+msgid "%.0f bytes"
+msgstr "%.0f byte"
+
+msgid "cannot verify bundle or remote repos"
+msgstr "kan ikke verificere bundt eller fjerndepoter"
+
+msgid "interrupted"
+msgstr "afbrudt"
+
+#, python-format
+msgid "empty or missing %s"
+msgstr "tom eller manglende %s"
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr "datalænge er %d byte forkert"
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr "indekset indeholder %d ekstra byte"
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr "advarsel: '%s' bruger revlog format 1"
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr "advarsel: '%s' bruger revlog format 0"
+
+#, python-format
+msgid "rev %d points to nonexistent changeset %d"
+msgstr "rev %d peger på ikke eksisterende ændring %d"
+
+#, python-format
+msgid "rev %d points to unexpected changeset %d"
+msgstr "rev %d peger på uventet ændring %d"
+
+#, python-format
+msgid " (expected %s)"
+msgstr " (forventede %s)"
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr "ukendt forælder 1 %s til %s"
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr "ukendt forælder 2 %s til %s"
+
+#, python-format
+msgid "checking parents of %s"
+msgstr "kontrollerer forældre til %s"
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr "duplikeret revision %d (%d)"
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr "depotet bruger revlog format %d\n"
+
+msgid "checking changesets\n"
+msgstr "kontrollerer ændringer\n"
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr "udpakker ændring %s"
+
+msgid "checking manifests\n"
+msgstr "kontrollerer manifester\n"
+
+#, python-format
+msgid "%s not in changesets"
+msgstr "%s ikke i ændringer"
+
+msgid "file without name in manifest"
+msgstr "fil uden navn i manifest"
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr "læser manifestforskel %s"
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr "krydstjekker filer i ændringer og manifester\n"
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr "ændring refererer til et ukendt manifest %s"
+
+msgid "in changeset but not in manifest"
+msgstr "i ændring men ikke i manifest"
+
+msgid "in manifest but not in changeset"
+msgstr "i manifest men ikke i ændring"
+
+msgid "checking files\n"
+msgstr "kontrollerer filer\n"
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr "kan ikke dekode filnavn '%s'"
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr "beskadiget revlog! (%s)"
+
+msgid "missing revlog!"
+msgstr "manglende revlog!"
+
+#, python-format
+msgid "%s not in manifests"
+msgstr ""
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr "udpakket størrelse er %s, forventede %s"
+
+#, python-format
+msgid "unpacking %s"
+msgstr "udpakker %s"
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "checking rename of %s"
+msgstr "kontrollerer omdøbning af %s"
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr ""
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr "advarsel: forældreløs revlog '%s'"
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr "%d filer, %d ændringer, ialt %d revisioner\n"
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr "fandt %d advarsler!\n"
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr "fandt %d integritetsfejl!\n"
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr "(første beskadigede ændring er tilsyneladende %d)\n"
+
+msgid "user name not available - set USERNAME environment variable"
+msgstr "der er ikke noget brugernavn - sæt USERNAME miljøvariabel"
diff --git a/sys/src/cmd/hg/i18n/de.po b/sys/src/cmd/hg/i18n/de.po
new file mode 100644
index 000000000..3a2999252
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/de.po
@@ -0,0 +1,9685 @@
+# German translations for Mercurial
+# Deutsche Übersetzungen für Mercurial
+# Copyright (C) 2009 Matt Mackall and others
+#
+# Übersetzungen
+# =============
+# branch Zweig/Verzweigung
+# bundle Bündel
+# change Änderung
+# changeset Änderungssatz
+# check out auschecken
+# commit Version
+# commit (v) übertragen
+# deprecated veraltet
+# hook Aktion
+# merge zusammenführen
+# notation Schreibweise
+# repository Projektarchiv
+#
+# Die Koordination der Übersetzung erfolgt auf http://bitbucket.org/tobidope/mercurial-german-translation
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial\n"
+"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
+"POT-Creation-Date: 2009-06-08 07:35+0200\n"
+"PO-Revision-Date: 2009-04-22 08:04+0200\n"
+"Last-Translator: Tobias Bell <tobias.bell@gmail.com>\n"
+"Language-Team: German (Tobias Bell, Fabian Kreutz, Lutz Horn)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (Standard: %s)"
+
+msgid "OPTIONS"
+msgstr "OPTIONEN"
+
+msgid "COMMANDS"
+msgstr "BEFEHLE"
+
+msgid " options:\n"
+msgstr " Optionen:\n"
+
+#, python-format
+msgid ""
+" aliases: %s\n"
+"\n"
+msgstr ""
+" Aliase: %s\n"
+"\n"
+
+#, python-format
+msgid "acl: %s not enabled\n"
+msgstr "acl: %s nicht aktiviert\n"
+
+#, python-format
+msgid "acl: %s enabled, %d entries for user %s\n"
+msgstr "acl: %s aktiviert, %d Einträge für Nutzer %s\n"
+
+#, python-format
+msgid "config error - hook type \"%s\" cannot stop incoming changesets"
+msgstr ""
+"Konfigurationsfehler - Aktionstyp \"%s\" kann hereinkommende Änderungssätze\n"
+"nicht stoppen"
+
+#, python-format
+msgid "acl: changes have source \"%s\" - skipping\n"
+msgstr "acl: Änderungen haben die Quelle \"%s\" - überspringe\n"
+
+#, python-format
+msgid "acl: user %s denied on %s\n"
+msgstr "acl: Benutzer %s nicht berechtigt für %s\n"
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr "acl: Zugriff verweigert auf die Version %s"
+
+#, python-format
+msgid "acl: user %s not allowed on %s\n"
+msgstr "acl: Benutzer %s hat keinen Zugriff auf %s\n"
+
+#, python-format
+msgid "acl: allowing changeset %s\n"
+msgstr "acl: Gestatte Version %s\n"
+
+msgid ""
+"mercurial bookmarks\n"
+"\n"
+"Mercurial bookmarks are local moveable pointers to changesets. Every\n"
+"bookmark points to a changeset identified by its hash. If you commit a\n"
+"changeset that is based on a changeset that has a bookmark on it, the\n"
+"bookmark is forwarded to the new changeset.\n"
+"\n"
+"It is possible to use bookmark names in every revision lookup (e.g. hg\n"
+"merge, hg update).\n"
+"\n"
+"The bookmark extension offers the possiblity to have a more git-like\n"
+"experience by adding the following configuration option to your .hgrc:\n"
+"\n"
+"[bookmarks]\n"
+"track.current = True\n"
+"\n"
+"This will cause bookmarks to track the bookmark that you are currently\n"
+"on, and just updates it. This is similar to git's approach of\n"
+"branching.\n"
+msgstr ""
+"Mercurial-Lesezeichen\n"
+"\n"
+"Mercurial-Lesezeichen sind lokale, bewegliche Zeiger auf Änderungssätze.\n"
+"Jedes Lesezeichen bezeichnet einen Änderungssatz identifiziert durch seine\n"
+"Prüfsumme. Wenn ein Änderungssatz, der auf einem anderen Änderungssatz mit\n"
+"einem Lesezeichen basiert, übernommen wird, so wird das Lesezeichen auf den\n"
+"neuen Satz verschoben.\n"
+"\n"
+"Ein Lesezeichenname kann für jede Form von Revisionssuche (z.B. hg merge,\n"
+"hg update) verwendet werden.\n"
+"\n"
+"Durch diese Erweiterung ist eine eher git-ähnliche Arbeitsform möglich,\n"
+"indem die folgende Konfigurationsoption in die .hgrc eingefügt wird:\n"
+"\n"
+"[bookmarks]\n"
+"track.current = True\n"
+"\n"
+"Dadurch wird das Lesezeichen bei Aktualisierungen automatisch verschoben.\n"
+"Dies entspricht gits Form von Verzweigungen (branching).\n"
+
+#, fuzzy
+msgid ""
+"mercurial bookmarks\n"
+"\n"
+" Bookmarks are pointers to certain commits that move when\n"
+" commiting. Bookmarks are local. They can be renamed, copied and\n"
+" deleted. It is possible to use bookmark names in 'hg merge' and\n"
+" 'hg update' to update to a given bookmark.\n"
+"\n"
+" You can use 'hg bookmark NAME' to set a bookmark on the working\n"
+" directory's parent revision with the given name. If you specify\n"
+" a revision using -r REV (where REV may be an existing bookmark),\n"
+" the bookmark is assigned to that revision.\n"
+" "
+msgstr ""
+"Mercurial Lesezeichen\n"
+"\n"
+" Lesezeichen sind Zeiger auf bestimmte Versionen, die mitwandern,\n"
+" wenn eine neuen Version erzeugt wird. Lesezeichen sind nur lokal.\n"
+" Sie können umbenannt, kopiert und gelöscht werden. Es ist möglich\n"
+" Lesezeichen bei 'hg merge' und 'hg update' zu nutzen, um auf das\n"
+" angegebene Lesezeichen zu aktualisieren.\n"
+"\n"
+" Du kannst 'hg bookmark NAME' aufrufen, um ein Lesezeichen mit dem\n"
+" angegeben Namen auf der aktuellen Spitze (tip) zu setzen. Bei Angabe "
+"einer\n"
+" Revision mit -r REV (REV kann ein vorhandenes Lesezeichen sein) wird "
+"das\n"
+" Lesezeichen auf dieser Revision gesetzt.\n"
+" "
+
+msgid "a bookmark of this name does not exist"
+msgstr "Es existiert kein Lesezeichen mit diesem Namen"
+
+msgid "a bookmark of the same name already exists"
+msgstr "Ein Lesezeichen mit diesem Namen existiert bereits"
+
+msgid "new bookmark name required"
+msgstr "Ein neuer Name für das Lesezeichen muss übergeben werden"
+
+msgid "bookmark name required"
+msgstr "Ein Name für das Lesezeichen muss übergeben werden"
+
+msgid "bookmark name cannot contain newlines"
+msgstr "Ein Lesezeichenname darf keine Zeilenumbrüche enthalten"
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr ""
+"Ein Lesezeichen darf nicht denselben Namen wie ein existierender Zweig haben"
+
+msgid "force"
+msgstr "erzwinge"
+
+msgid "revision"
+msgstr "Revision"
+
+msgid "delete a given bookmark"
+msgstr "Löscht ein gegebenes Lesezeichen"
+
+msgid "rename a given bookmark"
+msgstr "Benennt ein gegebenes Lesezeichen um"
+
+msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
+msgstr ""
+
+msgid ""
+"Bugzilla integration\n"
+"\n"
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
+"bug status.\n"
+"\n"
+"The hook updates the Bugzilla database directly. Only Bugzilla\n"
+"installations using MySQL are supported.\n"
+"\n"
+"The hook relies on a Bugzilla script to send bug change notification\n"
+"emails. That script changes between Bugzilla versions; the\n"
+"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
+"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
+"be run by Mercurial as the user pushing the change; you will need to\n"
+"ensure the Bugzilla install file permissions are set appropriately.\n"
+"\n"
+"Configuring the extension:\n"
+"\n"
+" [bugzilla]\n"
+"\n"
+" host Hostname of the MySQL server holding the Bugzilla\n"
+" database.\n"
+" db Name of the Bugzilla database in MySQL. Default 'bugs'.\n"
+" user Username to use to access MySQL server. Default 'bugs'.\n"
+" password Password to use to access MySQL server.\n"
+" timeout Database connection timeout (seconds). Default 5.\n"
+" version Bugzilla version. Specify '3.0' for Bugzilla versions\n"
+" 3.0 and later, '2.18' for Bugzilla versions from 2.18\n"
+" and '2.16' for versions prior to 2.18.\n"
+" bzuser Fallback Bugzilla user name to record comments with, if\n"
+" changeset committer cannot be found as a Bugzilla user.\n"
+" bzdir Bugzilla install directory. Used by default notify.\n"
+" Default '/var/www/html/bugzilla'.\n"
+" notify The command to run to get Bugzilla to send bug change\n"
+" notification emails. Substitutes from a map with 3\n"
+" keys, 'bzdir', 'id' (bug id) and 'user' (committer\n"
+" bugzilla email). Default depends on version; from 2.18\n"
+" it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
+" %(id)s %(user)s\".\n"
+" regexp Regular expression to match bug IDs in changeset commit\n"
+" message. Must contain one \"()\" group. The default\n"
+" expression matches 'Bug 1234', 'Bug no. 1234', 'Bug\n"
+" number 1234', 'Bugs 1234,5678', 'Bug 1234 and 5678' and\n"
+" variations thereof. Matching is case insensitive.\n"
+" style The style file to use when formatting comments.\n"
+" template Template to use when formatting comments. Overrides\n"
+" style if specified. In addition to the usual Mercurial\n"
+" keywords, the extension specifies:\n"
+" {bug} The Bugzilla bug ID.\n"
+" {root} The full pathname of the Mercurial\n"
+" repository.\n"
+" {webroot} Stripped pathname of the Mercurial\n"
+" repository.\n"
+" {hgweb} Base URL for browsing Mercurial\n"
+" repositories.\n"
+" Default 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip The number of slashes to strip from the front of {root}\n"
+" to produce {webroot}. Default 0.\n"
+" usermap Path of file containing Mercurial committer ID to\n"
+" Bugzilla user ID mappings. If specified, the file\n"
+" should contain one mapping per line,\n"
+" \"committer\"=\"Bugzilla user\". See also the [usermap]\n"
+" section.\n"
+"\n"
+" [usermap]\n"
+" Any entries in this section specify mappings of Mercurial\n"
+" committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl Base URL for browsing Mercurial repositories. Reference\n"
+" from templates as {hgweb}.\n"
+"\n"
+"Activating the extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # run bugzilla hook on every change pulled or pushed in here\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Example configuration:\n"
+"\n"
+"This example configuration is for a collection of Mercurial\n"
+"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
+"installation in /opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Commits add a comment to the Bugzilla bug record of the form:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr "Verbinde mit %s:%s als %s, Passwort %s\n"
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr ""
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr ""
+
+msgid "unknown database schema"
+msgstr ""
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr ""
+
+msgid "telling bugzilla to send mail:\n"
+msgstr ""
+
+#, python-format
+msgid " bug %s\n"
+msgstr ""
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr ""
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr ""
+
+msgid "done\n"
+msgstr "erledigt\n"
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr ""
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr ""
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr ""
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr ""
+
+#, python-format
+msgid "database error: %s"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"show the children of the given or working directory revision\n"
+"\n"
+" Print the children of the working directory's revisions. If a\n"
+" revision is given via -r/--rev, the children of that revision will\n"
+" be printed. If a file argument is given, revision in which the\n"
+" file was last changed (after the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"Zeigt die Kinder der übergebenen Revision oder des Arbeitsverzeichnisses an\n"
+"\n"
+" Zeigt die Kinder der Revision des Arbeitsverzeichnisses an.\n"
+" Wenn eine Revision durch --rev angegeben wird, werden die Kinder dieser\n"
+" Revision angezeigt. Wenn eine Datei als Argument angegeben wird, zeige "
+"die\n"
+" Revision an, in der die Datei zuletzt geändert wurde (nachfolgend der\n"
+" Revision des Arbeitsverzeichnisses oder wenn angegeben dem Argument von\n"
+" --rev).\n"
+" "
+
+msgid "show children of the specified revision"
+msgstr "Zeigt die Kinder der übergebenen Revision"
+
+msgid "hg children [-r REV] [FILE]"
+msgstr "hg children [-r REV] [DATEI]"
+
+msgid "command to show certain statistics about revision history"
+msgstr ""
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr "Revision %d ist eine Zusammenführung, wird ignoriert...\n"
+
+#, python-format
+msgid "generating stats: %d%%"
+msgstr ""
+
+msgid ""
+"graph count of revisions grouped by template\n"
+"\n"
+" Will graph count of changed lines or revisions grouped by template\n"
+" or alternatively by date, if dateformat is used. In this case it\n"
+" will override template.\n"
+"\n"
+" By default statistics are counted for number of changed lines.\n"
+"\n"
+" Examples:\n"
+"\n"
+" # display count of changed lines for every committer\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # display daily activity graph\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # display activity of developers by month\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # display count of lines changed in every year\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" The map file format used to specify aliases is fairly simple:\n"
+"\n"
+" <alias email> <actual email>\n"
+"\n"
+" By default .hgchurn in the working directory root will be used, if\n"
+" it exists. Use the --aliases option to override this.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "assuming %i character terminal\n"
+msgstr ""
+
+msgid "count rate for the specified revision or range"
+msgstr ""
+
+msgid "count rate for revisions matching date spec"
+msgstr "Zeigt Revisionen passend zur Datums-Spezifikation"
+
+msgid "template to group changesets"
+msgstr ""
+
+msgid "strftime-compatible format for grouping by date"
+msgstr ""
+
+msgid "count rate by number of changesets"
+msgstr ""
+
+msgid "sort by key (default: sort by count)"
+msgstr ""
+
+msgid "file with email aliases"
+msgstr ""
+
+msgid "show progress"
+msgstr ""
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+msgstr ""
+
+msgid ""
+"add color output to status, qseries, and diff-related commands\n"
+"\n"
+"This extension modifies the status command to add color to its output\n"
+"to reflect file status, the qseries command to add color to reflect\n"
+"patch status (applied, unapplied, missing), and to diff-related\n"
+"commands to highlight additions, removals, diff headers, and trailing\n"
+"whitespace.\n"
+"\n"
+"Other effects in addition to color, like bold and underlined text, are\n"
+"also available. Effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes). This module also provides the\n"
+"render_text function, which can be used to add effects to any text.\n"
+"\n"
+"To enable this extension, add this to your .hgrc file:\n"
+"[extensions]\n"
+"color =\n"
+"\n"
+"Default effects may be overridden from the .hgrc file:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' turns off all effects\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+msgstr ""
+
+msgid "when to colorize (always, auto, or never)"
+msgstr "Wann soll eingefärbt werden (always, auto oder never)"
+
+msgid "don't colorize output"
+msgstr "Keine Färbung der Ausgabe"
+
+msgid "converting foreign VCS repositories to Mercurial"
+msgstr ""
+
+msgid ""
+"convert a foreign SCM repository to a Mercurial one.\n"
+"\n"
+" Accepted source formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Accepted destination formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (history on branches is not preserved)\n"
+"\n"
+" If no revision is given, all revisions will be converted.\n"
+" Otherwise, convert will only import up to the named revision\n"
+" (given in a format understood by the source).\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source with '-hg' appended. If the destination\n"
+" repository doesn't exist, it will be created.\n"
+"\n"
+" By default, all sources except Mercurial will use\n"
+" --branchsort. Mercurial uses --sourcesort to preserve original\n"
+" revision numbers order. Sort modes have the following effects:\n"
+" --branchsort: convert from parent to child revision when\n"
+" possible, which means branches are usually converted one after\n"
+" the other. It generates more compact repositories.\n"
+" --datesort: sort revisions by date. Converted repositories have\n"
+" good-looking changelogs but are often an order of magnitude\n"
+" larger than the same ones generated by --branchsort.\n"
+" --sourcesort: try to preserve source revisions order, only\n"
+" supported by Mercurial sources.\n"
+"\n"
+" If <REVMAP> isn't given, it will be put in a default location\n"
+" (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file\n"
+" that maps each source commit ID to the destination ID for that\n"
+" revision, like so:\n"
+" <source ID> <destination ID>\n"
+"\n"
+" If the file doesn't exist, it's automatically created. It's\n"
+" updated on each commit copied, so convert-repo can be interrupted\n"
+" and can be run repeatedly to copy new commits.\n"
+"\n"
+" The [username mapping] file is a simple text file that maps each\n"
+" source commit author to a destination commit author. It is handy\n"
+" for source SCMs that use unix logins to identify authors (eg:\n"
+" CVS). One line per author mapping and the line format is:\n"
+" srcauthor=whatever string you want\n"
+"\n"
+" The filemap is a file that allows filtering and remapping of files\n"
+" and directories. Comment lines start with '#'. Each line can\n"
+" contain one of the following directives:\n"
+"\n"
+" include path/to/file\n"
+"\n"
+" exclude path/to/file\n"
+"\n"
+" rename from/file to/file\n"
+"\n"
+" The 'include' directive causes a file, or all files under a\n"
+" directory, to be included in the destination repository, and the\n"
+" exclusion of all other files and directories not explicitly included.\n"
+" The 'exclude' directive causes files or directories to be omitted.\n"
+" The 'rename' directive renames a file or directory. To rename from\n"
+" a subdirectory into the root of the repository, use '.' as the\n"
+" path to rename to.\n"
+"\n"
+" The splicemap is a file that allows insertion of synthetic\n"
+" history, letting you specify the parents of a revision. This is\n"
+" useful if you want to e.g. give a Subversion merge two parents, or\n"
+" graft two disconnected series of history together. Each entry\n"
+" contains a key, followed by a space, followed by one or two\n"
+" comma-separated values. The key is the revision ID in the source\n"
+" revision control system whose parents should be modified (same\n"
+" format as a key in .hg/shamap). The values are the revision IDs\n"
+" (in either the source or destination revision control system) that\n"
+" should be used as the new parents for that node.\n"
+"\n"
+" The branchmap is a file that allows you to rename a branch when it is\n"
+" being brought in from whatever external repository. When used in\n"
+" conjunction with a splicemap, it allows for a powerful combination\n"
+" to help fix even the most badly mismanaged repositories and turn them\n"
+" into nicely structured Mercurial repositories. The branchmap contains\n"
+" lines of the form \"original_branch_name new_branch_name\".\n"
+" \"original_branch_name\" is the name of the branch in the source\n"
+" repository, and \"new_branch_name\" is the name of the branch is the\n"
+" destination repository. This can be used to (for instance) move code\n"
+" in one repository from \"default\" to a named branch.\n"
+"\n"
+" Mercurial Source\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (boolean)\n"
+" ignore integrity errors when reading. Use it to fix Mercurial\n"
+" repositories with missing revlogs, by converting from and to\n"
+" Mercurial.\n"
+" --config convert.hg.saverev=False (boolean)\n"
+" store original revision ID in changeset (forces target IDs to\n"
+" change)\n"
+" --config convert.hg.startrev=0 (hg revision identifier)\n"
+" convert start revision and its descendants\n"
+"\n"
+" CVS Source\n"
+" ----------\n"
+"\n"
+" CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+" to indicate the starting point of what will be converted. Direct\n"
+" access to the repository files is not needed, unless of course the\n"
+" repository is :local:. The conversion uses the top level directory\n"
+" in the sandbox to find the CVS repository, and then uses CVS rlog\n"
+" commands to find files to convert. This means that unless a\n"
+" filemap is given, all files under the starting directory will be\n"
+" converted, and that any directory reorganization in the CVS\n"
+" sandbox is ignored.\n"
+"\n"
+" Because CVS does not have changesets, it is necessary to collect\n"
+" individual commits to CVS and merge them into changesets. CVS\n"
+" source uses its internal changeset merging code by default but can\n"
+" be configured to call the external 'cvsps' program by setting:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" This option is deprecated and will be removed in Mercurial 1.4.\n"
+"\n"
+" The options shown are the defaults.\n"
+"\n"
+" Internal cvsps is selected by setting\n"
+" --config convert.cvsps=builtin\n"
+" and has a few more configurable options:\n"
+" --config convert.cvsps.cache=True (boolean)\n"
+" Set to False to disable remote log caching, for testing and\n"
+" debugging purposes.\n"
+" --config convert.cvsps.fuzz=60 (integer)\n"
+" Specify the maximum time (in seconds) that is allowed\n"
+" between commits with identical user and log message in a\n"
+" single changeset. When very large files were checked in as\n"
+" part of a changeset then the default may not be long\n"
+" enough.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will insert a dummy revision merging the branch on\n"
+" which this log message occurs to the branch indicated in\n"
+" the regex.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will add the most recent revision on the branch\n"
+" indicated in the regex as the second parent of the\n"
+" changeset.\n"
+"\n"
+" The hgext/convert/cvsps wrapper script allows the builtin\n"
+" changeset merging code to be run without doing a conversion. Its\n"
+" parameters and output are similar to that of cvsps 2.1.\n"
+"\n"
+" Subversion Source\n"
+" -----------------\n"
+"\n"
+" Subversion source detects classical trunk/branches/tags layouts.\n"
+" By default, the supplied \"svn://repo/path/\" source URL is\n"
+" converted as a single branch. If \"svn://repo/path/trunk\" exists it\n"
+" replaces the default branch. If \"svn://repo/path/branches\" exists,\n"
+" its subdirectories are listed as possible branches. If\n"
+" \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
+" converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
+" can be overridden with following options. Set them to paths\n"
+" relative to the source URL, or leave them blank to disable auto\n"
+" detection.\n"
+"\n"
+" --config convert.svn.branches=branches (directory name)\n"
+" specify the directory containing branches\n"
+" --config convert.svn.tags=tags (directory name)\n"
+" specify the directory containing tags\n"
+" --config convert.svn.trunk=trunk (directory name)\n"
+" specify the name of the trunk branch\n"
+"\n"
+" Source history can be retrieved starting at a specific revision,\n"
+" instead of being integrally converted. Only single branch\n"
+" conversions are supported.\n"
+"\n"
+" --config convert.svn.startrev=0 (svn revision number)\n"
+" specify start Subversion revision.\n"
+"\n"
+" Perforce Source\n"
+" ---------------\n"
+"\n"
+" The Perforce (P4) importer can be given a p4 depot path or a\n"
+" client specification as source. It will convert all files in the\n"
+" source to a flat Mercurial repository, ignoring labels, branches\n"
+" and integrations. Note that when a depot path is given you then\n"
+" usually should specify a target directory, because otherwise the\n"
+" target may be named ...-hg.\n"
+"\n"
+" It is possible to limit the amount of source history to be\n"
+" converted by specifying an initial Perforce revision.\n"
+"\n"
+" --config convert.p4.startrev=0 (perforce changelist number)\n"
+" specify initial Perforce revision.\n"
+"\n"
+"\n"
+" Mercurial Destination\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (boolean)\n"
+" dispatch source branches in separate clones.\n"
+" --config convert.hg.tagsbranch=default (branch name)\n"
+" tag revisions branch name\n"
+" --config convert.hg.usebranchnames=True (boolean)\n"
+" preserve branch names\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"create changeset information from CVS\n"
+"\n"
+" This command is intended as a debugging tool for the CVS to\n"
+" Mercurial converter, and can be used as a direct replacement for\n"
+" cvsps.\n"
+"\n"
+" Hg debugcvsps reads the CVS rlog for current directory (or any\n"
+" named directory) in the CVS repository, and converts the log to a\n"
+" series of changesets based on matching commit log entries and\n"
+" dates."
+msgstr ""
+
+msgid "username mapping filename"
+msgstr ""
+
+msgid "destination repository type"
+msgstr ""
+
+msgid "remap file names using contents of file"
+msgstr ""
+
+msgid "import up to target revision REV"
+msgstr ""
+
+msgid "source repository type"
+msgstr ""
+
+msgid "splice synthesized history into place"
+msgstr ""
+
+msgid "change branch names while converting"
+msgstr ""
+
+msgid "try to sort changesets by branches"
+msgstr ""
+
+msgid "try to sort changesets by date"
+msgstr ""
+
+msgid "preserve source changesets order"
+msgstr ""
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr ""
+
+msgid "only return changes on specified branches"
+msgstr ""
+
+msgid "prefix to remove from file names"
+msgstr ""
+
+msgid "only return changes after or between specified tags"
+msgstr ""
+
+msgid "update cvs log cache"
+msgstr ""
+
+msgid "create new cvs log cache"
+msgstr ""
+
+msgid "set commit time fuzz in seconds"
+msgstr ""
+
+msgid "specify cvsroot"
+msgstr ""
+
+msgid "show parent changesets"
+msgstr ""
+
+msgid "show current changeset in ancestor branches"
+msgstr ""
+
+msgid "ignored for compatibility"
+msgstr ""
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr ""
+
+msgid ""
+"warning: lightweight checkouts may cause conversion failures, try with a "
+"regular branch instead.\n"
+msgstr ""
+
+msgid "bzr source type could not be determined\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr ""
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr ""
+
+#, python-format
+msgid "%s.%s symlink has no target"
+msgstr ""
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr ""
+
+#, python-format
+msgid "running: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s error:\n"
+msgstr ""
+
+#, python-format
+msgid "%s %s"
+msgstr ""
+
+#, python-format
+msgid "syntax error in %s(%d): key/value pair expected"
+msgstr ""
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr ""
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr ""
+
+#, python-format
+msgid "convert: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr ""
+
+#, python-format
+msgid "unknown sort mode: %s"
+msgstr "Unbekannter Sortiermodus: %s"
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr ""
+
+msgid "not all revisions were sorted"
+msgstr ""
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "overriding mapping for author %s, was %s, will be %s\n"
+msgstr ""
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr ""
+
+msgid "scanning source...\n"
+msgstr ""
+
+msgid "sorting...\n"
+msgstr ""
+
+msgid "converting...\n"
+msgstr ""
+
+#, python-format
+msgid "source: %s\n"
+msgstr ""
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr ""
+
+msgid "more than one sort mode specified"
+msgstr "Mehr als ein Sortiermodus angegeben"
+
+msgid "--sourcesort is not supported by this data source"
+msgstr ""
+
+msgid ""
+"warning: support for external cvsps is deprecated and will be removed in "
+"Mercurial 1.4\n"
+msgstr ""
+
+#, python-format
+msgid "revision %s is not a patchset number or date"
+msgstr ""
+
+msgid "using builtin cvsps\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr ""
+
+msgid "CVS pserver authentication failed"
+msgstr ""
+
+msgid "server sucks"
+msgstr ""
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr ""
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr ""
+
+msgid "collecting CVS rlog\n"
+msgstr ""
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr ""
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr ""
+
+#, python-format
+msgid "running %s\n"
+msgstr ""
+
+#, python-format
+msgid "prefix=%r directory=%r root=%r\n"
+msgstr ""
+
+msgid "RCS file must be followed by working file"
+msgstr ""
+
+msgid "must have at least some revisions"
+msgstr ""
+
+msgid "expected revision number"
+msgstr ""
+
+msgid "revision must be followed by date line"
+msgstr ""
+
+#, python-format
+msgid "found synthetic revision in %s: %r\n"
+msgstr "Synthetische Revision gefundein in %s: %r\n"
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "%d log entries\n"
+msgstr ""
+
+msgid "creating changesets\n"
+msgstr ""
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: CVS commit message references non-existent branch %r:\n"
+"%s\n"
+msgstr ""
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr ""
+
+msgid "Python ElementTree module is not available"
+msgstr ""
+
+#, python-format
+msgid "cleaning up %s\n"
+msgstr ""
+
+msgid "internal calling inconsistency"
+msgstr ""
+
+msgid "errors in filemap"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr ""
+
+msgid "source repository doesn't support --filemap"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a GNU Arch repo"
+msgstr ""
+
+msgid "cannot find a GNU Arch tool"
+msgstr ""
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr ""
+
+#, python-format
+msgid "applying revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "computing changeset between %s and %s...\n"
+msgstr ""
+
+#, python-format
+msgid "obtaining revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "analyzing revision %s...\n"
+msgstr "Analysiere Revision %s...\n"
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr ""
+
+#, python-format
+msgid "%s is not a local Mercurial repo"
+msgstr ""
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr ""
+
+msgid "run hg sink pre-conversion action\n"
+msgstr ""
+
+msgid "run hg sink post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr ""
+
+msgid "filtering out empty revision\n"
+msgstr "Leere Revision wird ausgefiltert\n"
+
+msgid "updating tags\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr ""
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr ""
+
+msgid "run hg source pre-conversion action\n"
+msgstr ""
+
+msgid "run hg source post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a monotone repo"
+msgstr ""
+
+#, python-format
+msgid "copying file in renamed directory from '%s' to '%s'"
+msgstr ""
+
+msgid "reading p4 views\n"
+msgstr ""
+
+msgid "collecting p4 changelists\n"
+msgstr ""
+
+msgid "Subversion python bindings could not be loaded"
+msgstr ""
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr ""
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr ""
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr ""
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr ""
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr ""
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr ""
+
+msgid "svn: start revision is not supported with more than one branch"
+msgstr ""
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr ""
+
+#, python-format
+msgid "no tags found at revision %d\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring foreign branch %r\n"
+msgstr ""
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr ""
+
+#, python-format
+msgid "branch renamed from %s to %s at %d\n"
+msgstr ""
+
+#, python-format
+msgid "reparent to %s\n"
+msgstr ""
+
+#, python-format
+msgid "copied to %s from %s@%s\n"
+msgstr ""
+
+#, python-format
+msgid "gone from %s\n"
+msgstr ""
+
+#, python-format
+msgid "found parent directory %s\n"
+msgstr ""
+
+#, python-format
+msgid "base, entry %s %s\n"
+msgstr ""
+
+msgid "munge-o-matic\n"
+msgstr ""
+
+#, python-format
+msgid "info: %s %s %s %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown path in revision %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mark %s came from %s:%d\n"
+msgstr ""
+
+#, python-format
+msgid "parsing revision %d (%d changes)\n"
+msgstr ""
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr ""
+
+msgid "no copyfrom path, don't know what to do.\n"
+msgstr ""
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "skipping blacklisted revision %d\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d has no entries\n"
+msgstr ""
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr ""
+
+#, python-format
+msgid "%r is not under %r, ignoring\n"
+msgstr ""
+
+#, python-format
+msgid "initializing svn repo %r\n"
+msgstr ""
+
+#, python-format
+msgid "initializing svn wc %r\n"
+msgstr ""
+
+msgid "unexpected svn output:\n"
+msgstr ""
+
+msgid "unable to cope with svn output"
+msgstr ""
+
+msgid "XXX TAGS NOT IMPLEMENTED YET\n"
+msgstr ""
+
+msgid ""
+"\n"
+"The `extdiff' Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working directory. The external diff\n"
+"programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare.\n"
+"\n"
+"To enable this extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.extdiff =\n"
+"\n"
+"The `extdiff' extension also allows to configure new diff commands, so\n"
+"you do not need to type \"hg extdiff -p kdiff3\" always.\n"
+"\n"
+" [extdiff]\n"
+" # add new command that runs GNU diff(1) in 'context diff' mode\n"
+" cdiff = gdiff -Nprc5\n"
+" ## or the old way:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # add new command called vdiff, runs kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # add new command called meld, runs meld (no need to name twice)\n"
+" meld =\n"
+"\n"
+" # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+" # (see http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Non English user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" "
+"in\n"
+" # your .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"You can use -I/-X and list of file or directory names like normal \"hg\n"
+"diff\" command. The `extdiff' extension makes snapshots of only needed\n"
+"files, so running the external diff program will actually be pretty\n"
+"fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from working directory\n"
+msgstr ""
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr "--rev und --change können nicht gleichzeitig angegeben werden"
+
+#, python-format
+msgid "running %r in %s\n"
+msgstr ""
+
+#, python-format
+msgid "file changed while diffing. Overwriting: %s (src: %s)\n"
+msgstr ""
+
+msgid "cleaning up temp directory\n"
+msgstr ""
+
+msgid ""
+"use external program to diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files, using\n"
+" an external program. The default program used is diff, with\n"
+" default options \"-Npru\".\n"
+"\n"
+" To select a different program, use the -p/--program option. The\n"
+" program will be passed the names of two directories to compare. To\n"
+" pass additional options to the program, use -o/--option. These\n"
+" will be passed before the names of the directories to compare.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent."
+msgstr ""
+
+msgid "comparison program to run"
+msgstr ""
+
+msgid "pass option to comparison program"
+msgstr ""
+
+msgid "change made by revision"
+msgstr "Von dieser Revision erzeugte Änderungen"
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr ""
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "pulling, updating and merging in one command"
+msgstr "Hole, aktualisiere und führe zusammen in einem Befehl"
+
+msgid ""
+"pull changes from a remote repository, merge new changes if needed.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository.\n"
+"\n"
+" If the pulled changes add a new branch head, the head is\n"
+" automatically merged, and the result of the merge is committed.\n"
+" Otherwise, the working directory is updated to include the new\n"
+" changes.\n"
+"\n"
+" When a merge occurs, the newly pulled changes are assumed to be\n"
+" \"authoritative\". The head of the new changes is used as the first\n"
+" parent, with local changes as the second. To switch the merge\n"
+" order, use --switch-parent.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"Holt Änderungen aus einem entfernten Projektarchiv, führt neue Änderungen "
+"zusammen wenn nötig.\n"
+"\n"
+" Dies selektiert alle Änderungen des Projektarchivs am angegebenen Pfad\n"
+" oder der URL und fügt sie dem lokalen Projektarchiv hinzu.\n"
+"\n"
+" Wenn die geholten Änderungen einen neuen Zweigkopf erzeugen, wird "
+"dieser\n"
+" Kopf automatisch zusammengeführt, und das Resultat der Zusammenführung\n"
+" wird eine neue Version. Andernfalls wird das Arbeitsverzeichnis mit den\n"
+" geholten Änderungen aktualisiert.\n"
+"\n"
+" Sollte eine Zusammenführung ausgelöst werden, gelten die neu geholten\n"
+" Änderungen als \"führend\"· Der Kopf der neuen Änderungen wird als\n"
+" erste Vorgängerversion genutzt, die lokalen Änderungen darauffolgend.\n"
+" Um die Reihenfolge der Zusammenführung zu ändern kann --switch-parent\n"
+" genutzt werden.\n"
+"\n"
+" Siehe 'hg help dates' für eine Liste gültiger Datumsformate für -d/--"
+"date.\n"
+" "
+
+msgid ""
+"working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+"Arbeitsverzeichnis ist nicht Spitze (tip) des Zweiges (nutze 'hg update' um\n"
+"auf die Zweigspitze zu wechseln)"
+
+msgid "outstanding uncommitted merge"
+msgstr "Ausstehende nicht versionierte Zusammenführung"
+
+msgid "outstanding uncommitted changes"
+msgstr "Ausstehende nicht versionierte Änderungen"
+
+msgid "working directory is missing some files"
+msgstr "Im Arbeitsverzeichnis fehlen Dateien"
+
+msgid ""
+"multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr ""
+"Mehrere Kopfversionen in diesem Zweig (Nutze \"hg heads .\" und \"hg merge"
+"\"\n"
+"um zusammenzuführen)"
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr "Hole von %s\n"
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+"Das andere Projektarchiv unterstützt keine Revisionsabfragen, daher kann "
+"keine Revision angegeben werden."
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+"Führe %d andere neue Zweigköpfe nicht zusammen (Nutze \"hg heads .\" und "
+"\"hg merge\" um sie zusammenzuführen)\n"
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr "Aktualisiere auf %d:%s\n"
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr "Führe zusammen mit %d:%s\n"
+
+#, python-format
+msgid "Automated merge with %s"
+msgstr "Automatisierte Zusammenführung mit %s"
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr ""
+"Neuer Änderungssatz %d:%s führt entfernte Änderungen mit lokalen zusammen\n"
+
+msgid "a specific revision you would like to pull"
+msgstr "Revision die geholt werden soll"
+
+msgid "edit commit message"
+msgstr "Editiere Versionsmeldung"
+
+msgid "edit commit message (DEPRECATED)"
+msgstr "Editiere Versionsmeldung (VERALTET)"
+
+msgid "switch parents when merging"
+msgstr "Vertauscht Vorgänger bei Zusammenführung"
+
+msgid "hg fetch [SOURCE]"
+msgstr "hg fetch [QUELLE]"
+
+msgid "error while verifying signature"
+msgstr ""
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr ""
+
+msgid "list signed changesets"
+msgstr ""
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr ""
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr ""
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr ""
+
+msgid ""
+"add a signature for the current or given revision\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr "Nicht versionierte Zusammenführung - bitte gib eine Revision an"
+
+msgid "Error while signing"
+msgstr ""
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+
+#, python-format
+msgid "Added signature for changeset %s"
+msgstr ""
+
+msgid "unknown signature version"
+msgstr ""
+
+msgid "make the signature local"
+msgstr ""
+
+msgid "sign even if the sigfile is modified"
+msgstr ""
+
+msgid "do not commit the sigfile after signing"
+msgstr ""
+
+msgid "the key id to sign with"
+msgstr ""
+
+msgid "commit message"
+msgstr ""
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr ""
+
+msgid "hg sigcheck REVISION"
+msgstr ""
+
+msgid "hg sigs"
+msgstr ""
+
+msgid ""
+"show revision graphs in terminal windows\n"
+"\n"
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ASCII representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+
+#, python-format
+msgid "--graph option is incompatible with --%s"
+msgstr ""
+
+msgid ""
+"show revision history alongside an ASCII revision graph\n"
+"\n"
+" Print a revision history alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr "Vergleiche mit %s\n"
+
+msgid "no changes found\n"
+msgstr "Keine Änderungen gefunden\n"
+
+msgid "show the revision DAG"
+msgstr ""
+
+msgid "limit number of changes displayed"
+msgstr "Begrenzt die Anzahl der angezeigten Änderungen"
+
+msgid "show patch"
+msgstr "Patch anzeigen"
+
+msgid "show the specified revision or range"
+msgstr "Zeigt die angegebene Revision oder Revisionsfolge"
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr ""
+
+msgid ""
+"CIA notification\n"
+"\n"
+"This is meant to be run as a changegroup or incoming hook.\n"
+"To configure it, set the following options in your hgrc:\n"
+"\n"
+"[cia]\n"
+"# your registered CIA user name\n"
+"user = foo\n"
+"# the name of the project in CIA\n"
+"project = foo\n"
+"# the module (subproject) (optional)\n"
+"#module = foo\n"
+"# Append a diffstat to the log message (optional)\n"
+"#diffstat = False\n"
+"# Template to use for log messages (optional)\n"
+"#template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"# Style to use (optional)\n"
+"#style = foo\n"
+"# The URL of the CIA notification service (optional)\n"
+"# You can use mailto: URLs to send by email, eg\n"
+"# mailto:cia@cia.vc\n"
+"# Make sure to set email.from if you do this.\n"
+"#url = http://cia.vc/\n"
+"# print message instead of sending it (optional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# one of these:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# If you want hyperlinks (optional)\n"
+"baseurl = http://server/path/to/repo\n"
+msgstr ""
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr ""
+
+msgid "email.from must be defined when sending by email"
+msgstr ""
+
+msgid "cia: no user specified"
+msgstr ""
+
+msgid "cia: no project specified"
+msgstr ""
+
+msgid ""
+"browsing the repository in a graphical way\n"
+"\n"
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not\n"
+"distributed with Mercurial.)\n"
+"\n"
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and hgk.py can be found in the hgext directory.\n"
+"\n"
+"To load the hgext.py extension, add it to your .hgrc file (you have to\n"
+"use your global $HOME/.hgrc file, not one in a repository). You can\n"
+"specify an absolute path:\n"
+"\n"
+" [extensions]\n"
+" hgk=/usr/local/lib/hgk.py\n"
+"\n"
+"Mercurial can also scan the default python library path for a file\n"
+"named 'hgk.py' if you set hgk empty:\n"
+"\n"
+" [extensions]\n"
+" hgk=\n"
+"\n"
+"The hg view command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can specify\n"
+"the path to hgk in your .hgrc file:\n"
+"\n"
+" [hgk]\n"
+" path=/location/of/hgk\n"
+"\n"
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions."
+msgstr ""
+
+msgid "diff trees from two commits"
+msgstr ""
+
+msgid "output common ancestor information"
+msgstr ""
+
+msgid "cat a specific revision"
+msgstr ""
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr ""
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr ""
+
+msgid "parse given revisions"
+msgstr ""
+
+msgid "print revisions"
+msgstr ""
+
+msgid "print extension options"
+msgstr ""
+
+msgid "start interactive history viewer"
+msgstr ""
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr ""
+
+msgid "generate patch"
+msgstr ""
+
+msgid "recursive"
+msgstr ""
+
+msgid "pretty"
+msgstr ""
+
+msgid "stdin"
+msgstr ""
+
+msgid "detect copies"
+msgstr ""
+
+msgid "search"
+msgstr ""
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr ""
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr ""
+
+msgid "hg debug-config"
+msgstr ""
+
+msgid "hg debug-merge-base node node"
+msgstr ""
+
+msgid "ignored"
+msgstr ""
+
+msgid "hg debug-rev-parse REV"
+msgstr ""
+
+msgid "header"
+msgstr ""
+
+msgid "topo-order"
+msgstr ""
+
+msgid "parents"
+msgstr ""
+
+msgid "max-count"
+msgstr ""
+
+msgid "hg debug-rev-list [options] revs"
+msgstr ""
+
+msgid ""
+"syntax highlighting in hgweb, based on Pygments\n"
+"\n"
+"It depends on the Pygments syntax highlighting library:\n"
+"http://pygments.org/\n"
+"\n"
+"To enable the extension add this to hgrc:\n"
+"\n"
+"[extensions]\n"
+"hgext.highlight =\n"
+"\n"
+"There is a single configuration option:\n"
+"\n"
+"[web]\n"
+"pygments_style = <style>\n"
+"\n"
+"The default is 'colorful'.\n"
+"\n"
+"-- Adam Hupp <adam@hupp.org>\n"
+msgstr ""
+
+msgid "inotify-based status acceleration for Linux systems\n"
+msgstr ""
+
+msgid "start an inotify server for this repository"
+msgstr ""
+
+msgid ""
+"debugging information for inotify extension\n"
+"\n"
+" Prints the list of directories being watched by the inotify server.\n"
+" "
+msgstr ""
+
+msgid "directories being watched:\n"
+msgstr "Überwachte Verzeichnisse:\n"
+
+msgid "run server in background"
+msgstr "Server im Hintergrund ausführen"
+
+msgid "used internally by daemon mode"
+msgstr "Wird intern im Server-Modus genutzt"
+
+msgid "minutes to sit idle before exiting"
+msgstr ""
+
+msgid "name of file to write process ID to"
+msgstr "Dateiname für Prozess-ID"
+
+msgid "hg inserve [OPT]..."
+msgstr ""
+
+msgid "(found dead inotify server socket; removing it)\n"
+msgstr ""
+
+msgid "(starting inotify server)\n"
+msgstr ""
+
+#, python-format
+msgid "could not start inotify server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "could not talk to new inotify server: %s\n"
+msgstr ""
+
+msgid "(inotify server not running)\n"
+msgstr ""
+
+#, python-format
+msgid "failed to contact inotify server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received '%s' response when expecting '%s')\n"
+msgstr ""
+
+msgid "this system does not seem to support inotify"
+msgstr ""
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr ""
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr ""
+
+msgid "*** counting directories: "
+msgstr ""
+
+#, python-format
+msgid "found %d\n"
+msgstr ""
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr ""
+
+#, python-format
+msgid "*** echo %d > %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr ""
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr ""
+
+#, python-format
+msgid "watching %r\n"
+msgstr ""
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r dir(%d) -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s dirstate reload\n"
+msgstr ""
+
+#, python-format
+msgid "%s end dirstate reload\n"
+msgstr ""
+
+msgid "rescanning due to .hgignore change\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr ""
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr ""
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr ""
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr ""
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr ""
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr ""
+
+#, python-format
+msgid "could not start server: %s"
+msgstr ""
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr ""
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr ""
+
+#, python-format
+msgid "unrecognized query type: %s\n"
+msgstr "Unbekannte Abfrageart: %s\n"
+
+msgid "finished setup\n"
+msgstr ""
+
+msgid "polling: no timeout\n"
+msgstr ""
+
+#, python-format
+msgid "polling: %sms timeout\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr ""
+
+msgid ""
+"keyword expansion in local repositories\n"
+"\n"
+"This extension expands RCS/CVS-like or self-customized $Keywords$ in\n"
+"tracked text files selected by your configuration.\n"
+"\n"
+"Keywords are only expanded in local repositories and not stored in the\n"
+"change history. The mechanism can be regarded as a convenience for the\n"
+"current user or for archive distribution.\n"
+"\n"
+"Configuration is done in the [keyword] and [keywordmaps] sections of\n"
+"hgrc files.\n"
+"\n"
+"Example:\n"
+"\n"
+" [keyword]\n"
+" # expand keywords in every python file except those matching \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Note: the more specific you are in your filename patterns\n"
+" the less you lose speed in huge repositories.\n"
+"\n"
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run \"hg kwdemo\".\n"
+"\n"
+"An additional date template filter {date|utcdate} is provided.\n"
+"\n"
+"The default template mappings (view with \"hg kwdemo -d\") can be\n"
+"replaced with customized keywords and templates. Again, run \"hg\n"
+"kwdemo\" to control the results of your config changes.\n"
+"\n"
+"Before changing/disabling active keywords, run \"hg kwshrink\" to avoid\n"
+"the risk of inadvertently storing expanded keywords in the change\n"
+"history.\n"
+"\n"
+"To force expansion after enabling it, or a configuration change, run\n"
+"\"hg kwexpand\".\n"
+"\n"
+"Also, when committing with the record extension or using mq's qrecord,\n"
+"be aware that keywords cannot be updated. Again, run \"hg kwexpand\" on\n"
+"the files in question to update keyword expansions after all changes\n"
+"have been checked in.\n"
+"\n"
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map\n"
+"\"Log = {desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s expanding keywords\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s shrinking keywords\n"
+msgstr ""
+
+msgid "[keyword] patterns cannot match"
+msgstr ""
+
+msgid "no [keyword] patterns configured"
+msgstr ""
+
+msgid ""
+"print [keywordmaps] configuration and an expansion example\n"
+"\n"
+" Show current, custom, or default keyword template maps and their\n"
+" expansion.\n"
+"\n"
+" Extend current configuration by specifying maps as arguments and\n"
+" optionally by reading from an additional hgrc file.\n"
+"\n"
+" Override current keyword template maps with \"default\" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"\t%s\n"
+msgstr ""
+
+#, python-format
+msgid "creating temporary repository at %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"%s keywords written to %s:\n"
+msgstr ""
+
+msgid "unhooked all commit hooks\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"removing temporary repository %s\n"
+msgstr ""
+
+msgid ""
+"expand keywords in working directory\n"
+"\n"
+" Run after (re)enabling keyword expansion.\n"
+"\n"
+" kwexpand refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid ""
+"print files currently configured for keyword expansion\n"
+"\n"
+" Crosscheck which files in working directory are potential targets\n"
+" for keyword expansion. That is, files matched by [keyword] config\n"
+" patterns but not symlinks.\n"
+" "
+msgstr ""
+
+msgid ""
+"revert expanded keywords in working directory\n"
+"\n"
+" Run before changing/disabling active keywords or if you experience\n"
+" problems with \"hg import\" or \"hg merge\".\n"
+"\n"
+" kwshrink refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid "show default keyword template maps"
+msgstr ""
+
+msgid "read maps from rcfile"
+msgstr ""
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr ""
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "show keyword status flags of all files"
+msgstr ""
+
+msgid "show files excluded from expansion"
+msgstr ""
+
+msgid "additionally show untracked files"
+msgstr ""
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr ""
+
+msgid ""
+"patch management and development\n"
+"\n"
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches).\n"
+"\n"
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets.\n"
+"\n"
+"Common tasks (use \"hg help command\" for more details):\n"
+"\n"
+"prepare repository to work with patches qinit\n"
+"create new patch qnew\n"
+"import existing patch qimport\n"
+"\n"
+"print patch series qseries\n"
+"print applied patches qapplied\n"
+"print name of top applied patch qtop\n"
+"\n"
+"add known patch to applied stack qpush\n"
+"remove patch from applied stack qpop\n"
+"refresh contents of top applied patch qrefresh\n"
+msgstr ""
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr ""
+
+msgid "guard cannot be an empty string"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr ""
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr ""
+
+#, python-format
+msgid "active guards: %s\n"
+msgstr ""
+
+#, python-format
+msgid "guard %r too short"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr ""
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr ""
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "update returned %d"
+msgstr ""
+
+msgid "repo commit failed"
+msgstr ""
+
+#, python-format
+msgid "unable to read %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr ""
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr ""
+
+#, python-format
+msgid "applying %s\n"
+msgstr "Wende %s an\n"
+
+#, python-format
+msgid "Unable to read %s\n"
+msgstr ""
+
+#, python-format
+msgid "imported patch %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"imported patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr ""
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr ""
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr ""
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr ""
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr ""
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr ""
+
+msgid "no patches applied"
+msgstr ""
+
+msgid "working directory revision is not qtip"
+msgstr ""
+
+msgid "local changes found, refresh first"
+msgstr ""
+
+msgid "local changes found"
+msgstr ""
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr ""
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr ""
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series"
+msgstr ""
+
+msgid "(working directory not at a head)\n"
+msgstr "(Arbeitsverzeichnis ist keine Kopfversion)\n"
+
+msgid "no patches in series\n"
+msgstr ""
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr ""
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr ""
+
+#, python-format
+msgid "guarded by %r"
+msgstr ""
+
+msgid "no matching guards"
+msgstr ""
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr ""
+
+msgid "all patches are currently applied\n"
+msgstr ""
+
+msgid "patch series already fully applied\n"
+msgstr ""
+
+msgid "cleaning up working directory..."
+msgstr ""
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr ""
+
+#, python-format
+msgid "now at: %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr ""
+
+msgid "no patches applied\n"
+msgstr ""
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr ""
+
+msgid "qpop: forcing dirstate update\n"
+msgstr ""
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr ""
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr ""
+
+msgid "deletions found between repo revs"
+msgstr ""
+
+msgid "patch queue now empty\n"
+msgstr ""
+
+msgid "cannot refresh a revision with children"
+msgstr ""
+
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to "
+"recover)\n"
+msgstr ""
+
+msgid "patch queue directory already exists"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr ""
+
+msgid "No saved patch data found\n"
+msgstr ""
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr ""
+
+msgid "save entry has children, leaving it alone\n"
+msgstr ""
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr ""
+
+msgid "queue directory updating\n"
+msgstr ""
+
+msgid "Unable to load queue repository\n"
+msgstr ""
+
+msgid "save: no patches applied, exiting\n"
+msgstr ""
+
+msgid "status is already saved\n"
+msgstr ""
+
+msgid "hg patches saved state"
+msgstr ""
+
+msgid "repo commit failed\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr ""
+
+msgid "option \"-r\" not valid when importing files"
+msgstr ""
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr ""
+
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr ""
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr ""
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr ""
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr ""
+
+msgid "-e is incompatible with import from -"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr ""
+
+msgid "need --name to import a patch from -"
+msgstr ""
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr ""
+
+msgid ""
+"remove patches from queue\n"
+"\n"
+" The patches must not be applied, unless they are arguments to the\n"
+" -r/--rev parameter. At least one patch or revision is required.\n"
+"\n"
+" With --rev, mq will stop managing the named revisions (converting\n"
+" them to regular mercurial changesets). The qfinish command should\n"
+" be used as an alternative for qdelete -r, as the latter option is\n"
+" deprecated.\n"
+"\n"
+" With -k/--keep, the patch files are preserved in the patch\n"
+" directory."
+msgstr ""
+
+msgid "print the patches already applied"
+msgstr ""
+
+msgid "print the patches not yet applied"
+msgstr ""
+
+msgid ""
+"import a patch\n"
+"\n"
+" The patch is inserted into the series after the last applied\n"
+" patch. If no patches have been applied, qimport prepends the patch\n"
+" to the series.\n"
+"\n"
+" The patch will have the same name as its source file unless you\n"
+" give it a new one with -n/--name.\n"
+"\n"
+" You can register an existing patch inside the patch directory with\n"
+" the -e/--existing flag.\n"
+"\n"
+" With -f/--force, an existing patch of the same name will be\n"
+" overwritten.\n"
+"\n"
+" An existing changeset may be placed under mq control with -r/--rev\n"
+" (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+" With -g/--git, patches imported with --rev will use the git diff\n"
+" format. See the diffs help topic for information on why this is\n"
+" important for preserving rename/copy information and permission\n"
+" changes.\n"
+"\n"
+" To import a patch from standard input, pass - as the patch file.\n"
+" When importing from standard input, a patch name must be specified\n"
+" using the --name flag.\n"
+" "
+msgstr ""
+
+msgid ""
+"init a new queue repository\n"
+"\n"
+" The queue repository is unversioned by default. If\n"
+" -c/--create-repo is specified, qinit will create a separate nested\n"
+" repository for patches (qinit -c may also be run later to convert\n"
+" an unversioned patch repository into a versioned one). You can use\n"
+" qcommit to commit changes to this queue repository."
+msgstr ""
+
+msgid ""
+"clone main and patch repository at same time\n"
+"\n"
+" If source is local, destination will have no patches applied. If\n"
+" source is remote, this command can not check if patches are\n"
+" applied in source, so cannot guarantee that patches are not\n"
+" applied in destination. If you clone remote repository, be sure\n"
+" before that it has no patches applied.\n"
+"\n"
+" Source patch repository is looked for in <src>/.hg/patches by\n"
+" default. Use -p <url> to change.\n"
+"\n"
+" The patch directory must be a nested mercurial repository, as\n"
+" would be created by qinit -c.\n"
+" "
+msgstr ""
+
+msgid "versioned patch repository not found (see qinit -c)"
+msgstr ""
+
+msgid "cloning main repository\n"
+msgstr ""
+
+msgid "cloning patch repository\n"
+msgstr "Klone Patch-Archiv\n"
+
+msgid "stripping applied patches from destination repository\n"
+msgstr ""
+
+msgid "updating destination repository\n"
+msgstr "Aktualisiere Zielarchiv\n"
+
+msgid "commit changes in the queue repository"
+msgstr ""
+
+msgid "print the entire series file"
+msgstr ""
+
+msgid "print the name of the current patch"
+msgstr ""
+
+msgid "print the name of the next patch"
+msgstr ""
+
+msgid "all patches applied\n"
+msgstr ""
+
+msgid "print the name of the previous patch"
+msgstr ""
+
+msgid "only one patch applied\n"
+msgstr ""
+
+msgid ""
+"create a new patch\n"
+"\n"
+" qnew creates a new patch on top of the currently-applied patch (if\n"
+" any). It will refuse to run if there are any outstanding changes\n"
+" unless -f/--force is specified, in which case the patch will be\n"
+" initialized with them. You may also use -I/--include,\n"
+" -X/--exclude, and/or a list of files after the patch name to add\n"
+" only changes to matching files to the new patch, leaving the rest\n"
+" as uncommitted modifications.\n"
+"\n"
+" -u/--user and -d/--date can be used to set the (given) user and\n"
+" date, respectively. -U/--currentuser and -D/--currentdate set user\n"
+" to current user and date to current date.\n"
+"\n"
+" -e/--edit, -m/--message or -l/--logfile set the patch header as\n"
+" well as the commit message. If none is specified, the header is\n"
+" empty and the commit message is '[mq]: PATCH'.\n"
+"\n"
+" Use the -g/--git option to keep the patch in the git extended diff\n"
+" format. Read the diffs help topic for more information on why this\n"
+" is important for preserving permission changes and copy/rename\n"
+" information.\n"
+" "
+msgstr ""
+
+msgid ""
+"update the current patch\n"
+"\n"
+" If any file patterns are provided, the refreshed patch will\n"
+" contain only the modifications that match those patterns; the\n"
+" remaining modifications will remain in the working directory.\n"
+"\n"
+" If -s/--short is specified, files currently included in the patch\n"
+" will be refreshed just like matched files and remain in the patch.\n"
+"\n"
+" hg add/remove/copy/rename work as usual, though you might want to\n"
+" use git-style patches (-g/--git or [diff] git=1) to track copies\n"
+" and renames. See the diffs help topic for more information on the\n"
+" git diff format.\n"
+" "
+msgstr ""
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr ""
+
+msgid ""
+"diff of the current patch and subsequent modifications\n"
+"\n"
+" Shows a diff which includes the current patch as well as any\n"
+" changes which have been made in the working directory since the\n"
+" last refresh (thus showing what the current patch would become\n"
+" after a qrefresh).\n"
+"\n"
+" Use 'hg diff' if you only want to see the changes made since the\n"
+" last qrefresh, or 'hg export qtip' if you want to see changes made\n"
+" by the current patch without including changes made since the\n"
+" qrefresh.\n"
+" "
+msgstr ""
+
+msgid ""
+"fold the named patches into the current patch\n"
+"\n"
+" Patches must not yet be applied. Each patch will be successively\n"
+" applied to the current patch in the order given. If all the\n"
+" patches apply successfully, the current patch will be refreshed\n"
+" with the new cumulative patch, and the folded patches will be\n"
+" deleted. With -k/--keep, the folded patch files will not be\n"
+" removed afterwards.\n"
+"\n"
+" The header for each folded patch will be concatenated with the\n"
+" current patch header, separated by a line of '* * *'."
+msgstr ""
+
+msgid "qfold requires at least one patch name"
+msgstr ""
+
+msgid "No patches applied"
+msgstr ""
+
+#, python-format
+msgid "Skipping already folded patch %s"
+msgstr ""
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "Error folding patch %s"
+msgstr ""
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr ""
+
+msgid ""
+"set or print guards for a patch\n"
+"\n"
+" Guards control whether a patch can be pushed. A patch with no\n"
+" guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+" pushed only if the qselect command has activated it. A patch with\n"
+" a negative guard (\"-foo\") is never pushed if the qselect command\n"
+" has activated it.\n"
+"\n"
+" With no arguments, print the currently active guards.\n"
+" With arguments, set guards for the named patch.\n"
+" NOTE: Specifying negative guards now requires '--'.\n"
+"\n"
+" To set guards on another patch:\n"
+" hg qguard -- other.patch +2.6.17 -stable\n"
+" "
+msgstr ""
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr ""
+
+msgid "no patch to work with"
+msgstr ""
+
+#, python-format
+msgid "no patch named %s"
+msgstr ""
+
+msgid "print the header of the topmost or specified patch"
+msgstr ""
+
+msgid ""
+"push the next patch onto the stack\n"
+"\n"
+" When -f/--force is applied, all local changes in patched files\n"
+" will be lost.\n"
+" "
+msgstr ""
+
+msgid "no saved queues found, please use -n\n"
+msgstr ""
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr ""
+
+msgid ""
+"pop the current patch off the stack\n"
+"\n"
+" By default, pops off the top of the patch stack. If given a patch\n"
+" name, keeps popping off patches until the named patch is at the\n"
+" top of the stack.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr ""
+
+msgid ""
+"rename a patch\n"
+"\n"
+" With one argument, renames the current patch to PATCH1.\n"
+" With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+
+#, python-format
+msgid "%s already exists"
+msgstr ""
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr ""
+
+msgid "restore the queue state saved by a revision"
+msgstr ""
+
+msgid "save current queue state"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr ""
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr ""
+
+msgid ""
+"strip a revision and all its descendants from the repository\n"
+"\n"
+" If one of the working directory's parent revisions is stripped, the\n"
+" working directory will be updated to the parent of the stripped\n"
+" revision.\n"
+" "
+msgstr ""
+
+msgid ""
+"set or print guarded patches to push\n"
+"\n"
+" Use the qguard command to set or print guards on patch, then use\n"
+" qselect to tell mq which guards to use. A patch will be pushed if\n"
+" it has no guards or any positive guards match the currently\n"
+" selected guard, but will not be pushed if any negative guards\n"
+" match the current guard. For example:\n"
+"\n"
+" qguard foo.patch -stable (negative guard)\n"
+" qguard bar.patch +stable (positive guard)\n"
+" qselect stable\n"
+"\n"
+" This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+" it has a negative match) but push bar.patch (because it has a\n"
+" positive match).\n"
+"\n"
+" With no arguments, prints the currently active guards.\n"
+" With one argument, sets the active guard.\n"
+"\n"
+" Use -n/--none to deactivate guards (no other arguments needed).\n"
+" When no guards are active, patches with positive guards are\n"
+" skipped and patches with negative guards are pushed.\n"
+"\n"
+" qselect can change the guards on applied patches. It does not pop\n"
+" guarded patches by default. Use --pop to pop back to the last\n"
+" applied patch that is not guarded. Use --reapply (which implies\n"
+" --pop) to push back to the current patch afterwards, but skip\n"
+" guarded patches.\n"
+"\n"
+" Use -s/--series to print a list of all guards in the series file\n"
+" (no other arguments needed). Use -v for more information."
+msgstr ""
+
+msgid "guards deactivated\n"
+msgstr ""
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr ""
+
+msgid "guards in series file:\n"
+msgstr ""
+
+msgid "no guards in series file\n"
+msgstr ""
+
+msgid "active guards:\n"
+msgstr ""
+
+msgid "no active guards\n"
+msgstr ""
+
+msgid "popping guarded patches\n"
+msgstr ""
+
+msgid "reapplying unguarded patches\n"
+msgstr ""
+
+msgid ""
+"move applied patches into repository history\n"
+"\n"
+" Finishes the specified revisions (corresponding to applied\n"
+" patches) by moving them out of mq control into regular repository\n"
+" history.\n"
+"\n"
+" Accepts a revision range or the -a/--applied option. If --applied\n"
+" is specified, all applied mq revisions are removed from mq\n"
+" control. Otherwise, the given revisions must be at the base of the\n"
+" stack of applied patches.\n"
+"\n"
+" This can be especially useful if your changes have been applied to\n"
+" an upstream repository, or if you are about to push your changes\n"
+" to upstream.\n"
+" "
+msgstr ""
+
+msgid "no revisions specified"
+msgstr ""
+
+msgid "cannot commit over an applied mq patch"
+msgstr ""
+
+msgid "source has mq patches applied"
+msgstr ""
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr ""
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr ""
+
+msgid "cannot import over an applied patch"
+msgstr ""
+
+msgid "print first line of patch header"
+msgstr ""
+
+msgid "hg qapplied [-s] [PATCH]"
+msgstr ""
+
+msgid "use pull protocol to copy metadata"
+msgstr "Nutzt das 'Pull'-Protokoll um Metadaten zu kopieren"
+
+msgid "do not update the new working directories"
+msgstr ""
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr "Nutzt unkomprimierte Übertragung (schnell im LAN)"
+
+msgid "location of source patch repository"
+msgstr ""
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr ""
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "keep patch file"
+msgstr ""
+
+msgid "stop managing a revision"
+msgstr ""
+
+msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
+msgstr ""
+
+msgid "edit patch header"
+msgstr ""
+
+msgid "keep folded patch files"
+msgstr ""
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr ""
+
+msgid "overwrite any local changes"
+msgstr ""
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr ""
+
+msgid "list all patches and guards"
+msgstr ""
+
+msgid "drop all guards"
+msgstr ""
+
+msgid "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+msgstr ""
+
+msgid "hg qheader [PATCH]"
+msgstr ""
+
+msgid "import file in patch directory"
+msgstr ""
+
+msgid "patch file name"
+msgstr ""
+
+msgid "overwrite existing files"
+msgstr ""
+
+msgid "place existing revisions under mq control"
+msgstr ""
+
+msgid "use git extended diff format"
+msgstr "Verwende git-erweitertes diff-Format"
+
+msgid "qpush after importing"
+msgstr ""
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... DATEI..."
+
+msgid "create queue repository"
+msgstr ""
+
+msgid "hg qinit [-c]"
+msgstr ""
+
+msgid "import uncommitted changes into patch"
+msgstr ""
+
+msgid "add \"From: <current user>\" to patch"
+msgstr ""
+
+msgid "add \"From: <given user>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <given date>\" to patch"
+msgstr ""
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+msgstr ""
+
+msgid "hg qnext [-s]"
+msgstr ""
+
+msgid "hg qprev [-s]"
+msgstr ""
+
+msgid "pop all patches"
+msgstr ""
+
+msgid "queue name to pop"
+msgstr ""
+
+msgid "forget any local changes"
+msgstr ""
+
+msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+msgstr ""
+
+msgid "apply if the patch has rejects"
+msgstr ""
+
+msgid "list patch name in commit text"
+msgstr ""
+
+msgid "apply all patches"
+msgstr ""
+
+msgid "merge from another queue"
+msgstr ""
+
+msgid "merge queue name"
+msgstr ""
+
+msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+msgstr ""
+
+msgid "refresh only files already in the patch and specified files"
+msgstr ""
+
+msgid "add/update \"From: <current user>\" in patch"
+msgstr ""
+
+msgid "add/update \"From: <given user>\" in patch"
+msgstr ""
+
+msgid "update \"Date: <current date>\" in patch (if present)"
+msgstr ""
+
+msgid "update \"Date: <given date>\" in patch (if present)"
+msgstr ""
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr ""
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr ""
+
+msgid "delete save entry"
+msgstr ""
+
+msgid "update queue working directory"
+msgstr ""
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr ""
+
+msgid "copy patch directory"
+msgstr ""
+
+msgid "copy directory name"
+msgstr ""
+
+msgid "clear queue status file"
+msgstr ""
+
+msgid "force copy"
+msgstr ""
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr ""
+
+msgid "disable all guards"
+msgstr ""
+
+msgid "list all guards in series file"
+msgstr ""
+
+msgid "pop to before first guarded applied patch"
+msgstr ""
+
+msgid "pop, then reapply patches"
+msgstr ""
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr ""
+
+msgid "print patches not in series"
+msgstr ""
+
+msgid "hg qseries [-ms]"
+msgstr ""
+
+msgid "force removal with local changes"
+msgstr ""
+
+msgid "bundle unrelated changesets"
+msgstr ""
+
+msgid "no backups"
+msgstr ""
+
+msgid "hg strip [-f] [-b] [-n] REV"
+msgstr ""
+
+msgid "hg qtop [-s]"
+msgstr ""
+
+msgid "hg qunapplied [-s] [PATCH]"
+msgstr ""
+
+msgid "finish all applied changesets"
+msgstr ""
+
+msgid "hg qfinish [-a] [REV...]"
+msgstr ""
+
+msgid ""
+"hook extension to email notifications on commits/pushes\n"
+"\n"
+"Subscriptions can be managed through hgrc. Default mode is to print\n"
+"messages to stdout, for testing and configuring.\n"
+"\n"
+"To use, configure notify extension and enable in hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # one email for each incoming changeset\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # batch emails when many changesets incoming at one time\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # config items go in here\n"
+"\n"
+" config items:\n"
+"\n"
+" REQUIRED:\n"
+" config = /path/to/file # file containing subscriptions\n"
+"\n"
+" OPTIONAL:\n"
+" test = True # print messages to stdout for testing\n"
+" strip = 3 # number of slashes to strip for url paths\n"
+" domain = example.com # domain to use if committer missing domain\n"
+" style = ... # style file to use when formatting email\n"
+" template = ... # template to use when formatting email\n"
+" incoming = ... # template to use when run as incoming hook\n"
+" changegroup = ... # template when run as changegroup hook\n"
+" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n"
+" maxsubject = 67 # truncate subject line longer than this\n"
+" diffstat = True # add a diffstat before the diff content\n"
+" sources = serve # notify if source of incoming changes in this "
+"list\n"
+" # (serve == ssh or http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # email address to send as if none given\n"
+" [web]\n"
+" baseurl = http://hgserver/... # root of hg web site for browsing commits\n"
+"\n"
+" notify config file has same format as regular hgrc. it has two\n"
+" sections so you can express subscriptions in whatever way is handier\n"
+" for you.\n"
+"\n"
+" [usersubs]\n"
+" # key is subscriber email, value is \",\"-separated list of glob "
+"patterns\n"
+" user@host = pattern\n"
+"\n"
+" [reposubs]\n"
+" # key is glob pattern, value is \",\"-separated list of subscriber "
+"emails\n"
+" pattern = user@host\n"
+"\n"
+" glob patterns are matched against path to repository root.\n"
+"\n"
+" if you like, you can put notify config file in repository that users\n"
+" can push changes to, they can manage their own subscriptions."
+msgstr ""
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr ""
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "notify: no subscribers to repository %s\n"
+msgstr ""
+
+#, python-format
+msgid "notify: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+msgid ""
+"browse command output with external pager\n"
+"\n"
+"To set the pager that should be used, set the application variable:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"If no pager is set, the pager extensions uses the environment variable\n"
+"$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.\n"
+"\n"
+"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
+"setting:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"You can also enable the pager only for certain commands using\n"
+"pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"If pager.attend is present, pager.ignore will be ignored.\n"
+"\n"
+"To ignore global commands like \"hg version\" or \"hg help\", you have to\n"
+"specify them in the global .hgrc\n"
+msgstr ""
+
+msgid ""
+"use suffixes to refer to ancestor revisions\n"
+"\n"
+"This extension allows you to use git-style suffixes to refer to the\n"
+"ancestors of a specific revision.\n"
+"\n"
+"For example, if you can refer to a revision as \"foo\", then:\n"
+"\n"
+"- foo^N = Nth parent of foo\n"
+" foo^0 = foo\n"
+" foo^1 = first parent of foo\n"
+" foo^2 = second parent of foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nth first grandparent of foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = first parent of foo\n"
+" foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
+msgstr ""
+
+msgid ""
+"sending Mercurial changesets as a series of patch emails\n"
+"\n"
+"The series is started off with a \"[PATCH 0 of N]\" introduction, which\n"
+"describes the series as a whole.\n"
+"\n"
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using the\n"
+"first line of the changeset description as the subject text. The\n"
+"message contains two or three body parts:\n"
+"\n"
+" The changeset description.\n"
+"\n"
+" [Optional] The result of running diffstat on the patch.\n"
+"\n"
+" The patch itself, as generated by \"hg export\".\n"
+"\n"
+"Each message refers to the first in the series using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in threaded\n"
+"mail and news readers, and in mail archives.\n"
+"\n"
+"With the -d/--diffstat option, you will be prompted for each changeset\n"
+"with a diffstat summary and the changeset summary, so you can be sure\n"
+"you are sending the right changes.\n"
+"\n"
+"To enable this extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.patchbomb =\n"
+"\n"
+"To configure other defaults, add a section like this to your hgrc\n"
+"file:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Then you can use the \"hg email\" command to mail a series of changesets\n"
+"as a patchbomb.\n"
+"\n"
+"To avoid sending patches prematurely, it is a good idea to first run\n"
+"the \"email\" command with the \"-n\" option (test only). You will be\n"
+"prompted for an email recipient address, a subject and an introductory\n"
+"message describing the patches of your patchbomb. Then when all is\n"
+"done, patchbomb messages are displayed. If the PAGER environment\n"
+"variable is set, your pager will be fired up once for each patchbomb\n"
+"message, so you can verify everything is alright.\n"
+"\n"
+"The -m/--mbox option is also very useful. Instead of previewing each\n"
+"patchbomb message in a pager or sending the messages directly, it will\n"
+"create a UNIX mailbox file with the patch emails. This mailbox file\n"
+"can be previewed with any mail user agent which supports UNIX mbox\n"
+"files, e.g. with mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"When you are previewing the patchbomb messages, you can use `formail'\n"
+"(a utility that is commonly installed as part of the procmail\n"
+"package), to send each message out:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"That should be all. Now your patchbomb is on its way out.\n"
+"\n"
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatible mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs\n"
+"directly from the commandline. See the [email] and [smtp] sections in\n"
+"hgrc(5) for details."
+msgstr ""
+
+msgid "Please enter a valid value.\n"
+msgstr ""
+
+msgid "does the diffstat above look okay? "
+msgstr ""
+
+msgid "diffstat rejected"
+msgstr ""
+
+msgid ""
+"send changesets by email\n"
+"\n"
+" By default, diffs are sent in the format generated by hg export,\n"
+" one per message. The series starts with a \"[PATCH 0 of N]\"\n"
+" introduction, which describes the series as a whole.\n"
+"\n"
+" Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+" the first line of the changeset description as the subject text.\n"
+" The message contains two or three parts. First, the changeset\n"
+" description. Next, (optionally) if the diffstat program is\n"
+" installed and -d/--diffstat is used, the result of running\n"
+" diffstat on the patch. Finally, the patch itself, as generated by\n"
+" \"hg export\".\n"
+"\n"
+" By default the patch is included as text in the email body for\n"
+" easy reviewing. Using the -a/--attach option will instead create\n"
+" an attachment for the patch. With -i/--inline an inline attachment\n"
+" will be created.\n"
+"\n"
+" With -o/--outgoing, emails will be generated for patches not found\n"
+" in the destination repository (or only those which are ancestors\n"
+" of the specified revisions if any are provided)\n"
+"\n"
+" With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+" single email containing a binary Mercurial bundle as an attachment\n"
+" will be sent.\n"
+"\n"
+" Examples:\n"
+"\n"
+" hg email -r 3000 # send patch 3000 only\n"
+" hg email -r 3000 -r 3001 # send patches 3000 and 3001\n"
+" hg email -r 3000:3005 # send patches 3000 through 3005\n"
+" hg email 3000 # send patch 3000 (deprecated)\n"
+"\n"
+" hg email -o # send all patches not in default\n"
+" hg email -o DEST # send all patches not in DEST\n"
+" hg email -o -r 3000 # send all ancestors of 3000 not in default\n"
+" hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST\n"
+"\n"
+" hg email -b # send bundle of all patches not in default\n"
+" hg email -b DEST # send bundle of all patches not in DEST\n"
+" hg email -b -r 3000 # bundle of all ancestors of 3000 not in "
+"default\n"
+" hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST\n"
+"\n"
+" Before using this command, you will need to enable email in your\n"
+" hgrc. See the [email] section in hgrc(5) for details.\n"
+" "
+msgstr ""
+
+msgid "specify at least one changeset with -r or -o"
+msgstr ""
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr ""
+
+msgid "too many destinations"
+msgstr ""
+
+msgid "use only one form to specify the revision"
+msgstr ""
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series.\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"This patch series consists of %d patches.\n"
+"\n"
+msgstr ""
+
+msgid "Final summary:\n"
+msgstr ""
+
+msgid "Displaying "
+msgstr ""
+
+msgid "Writing "
+msgstr ""
+
+msgid "Sending "
+msgstr ""
+
+msgid "send patches as attachments"
+msgstr ""
+
+msgid "send patches as inline attachments"
+msgstr ""
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr ""
+
+msgid "email addresses of copy recipients"
+msgstr ""
+
+msgid "add diffstat output to messages"
+msgstr ""
+
+msgid "use the given date as the sending date"
+msgstr ""
+
+msgid "use the given file as the series description"
+msgstr ""
+
+msgid "email address of sender"
+msgstr ""
+
+msgid "print messages that would be sent"
+msgstr ""
+
+msgid "write messages to mbox file instead of sending them"
+msgstr ""
+
+msgid "subject of first message (intro or single patch)"
+msgstr ""
+
+msgid "message identifier to reply to"
+msgstr ""
+
+msgid "email addresses of recipients"
+msgstr ""
+
+msgid "omit hg patch header"
+msgstr ""
+
+msgid "send changes not found in the target repository"
+msgstr ""
+
+msgid "send changes not in target as a binary bundle"
+msgstr ""
+
+msgid "file name of the bundle attachment"
+msgstr ""
+
+msgid "a revision to send"
+msgstr ""
+
+msgid "run even when remote repository is unrelated (with -b/--bundle)"
+msgstr ""
+"Auch ausführen wenn das entfernte Archiv keinen Bezug hat (mit -b/--bundle)"
+
+msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
+msgstr ""
+
+msgid "send an introduction email for a single patch"
+msgstr ""
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr ""
+
+msgid ""
+"removes files not tracked by Mercurial\n"
+"\n"
+" Delete files not known to Mercurial. This is useful to test local\n"
+" and uncommitted changes in an otherwise-clean source tree.\n"
+"\n"
+" This means that purge will delete:\n"
+" - Unknown files: files marked with \"?\" by \"hg status\"\n"
+" - Empty directories: in fact Mercurial ignores directories unless\n"
+" they contain files under source control management\n"
+" But it will leave untouched:\n"
+" - Modified and unmodified tracked files\n"
+" - Ignored files (unless --all is specified)\n"
+" - New files added to the repository (with \"hg add\")\n"
+"\n"
+" If directories are given on the command line, only files in these\n"
+" directories are considered.\n"
+"\n"
+" Be careful with purge, as you could irreversibly delete some files\n"
+" you forgot to add to the repository. If you only want to print the\n"
+" list of files that this program would delete, use the --print\n"
+" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s\n"
+msgstr ""
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr ""
+
+msgid "abort if an error occurs"
+msgstr ""
+
+msgid "purge ignored files too"
+msgstr ""
+
+msgid "print the file names instead of deleting them"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr ""
+"Beendet Dateinamen mit NUL zur Nutzung mit xargs (implizert -p/--print)"
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr ""
+
+msgid ""
+"move sets of revisions to a different ancestor\n"
+"\n"
+"This extension lets you rebase changesets in an existing Mercurial\n"
+"repository.\n"
+"\n"
+"For more information:\n"
+"http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject\n"
+msgstr ""
+
+msgid "first revision, do not change ancestor\n"
+msgstr "Erste Revision, ändere den Vorgänger nicht\n"
+
+#, fuzzy
+msgid ""
+"move changeset (and descendants) to a different branch\n"
+"\n"
+" Rebase uses repeated merging to graft changesets from one part of\n"
+" history onto another. This can be useful for linearizing local\n"
+" changes relative to a master development tree.\n"
+"\n"
+" If a rebase is interrupted to manually resolve a merge, it can be\n"
+" continued with --continue/-c or aborted with --abort/-a.\n"
+" "
+msgstr ""
+"Verschiebt Versionen (und ihre Nachfolger) auf einen abweichenden Zweig\n"
+"\n"
+" Rebase nutzt wiederholtes Zusammenführen um Versionen von einem Teil "
+"der\n"
+" Versionshistorie auf einen anderen zu pfropfen. Dies ist nützlich, um\n"
+" lokale Änderungen abhängig von einem Hauptentwicklunszweig zu\n"
+" linearisieren.\n"
+"\n"
+" Sollte ein Rebase unterbrochen werden, um manuell eine Zusammenführung\n"
+" auszuführen, kann er mit --continue wieder aufgenommen oder mit --abort\n"
+" abgebrochen werden.\n"
+" "
+
+msgid "cannot use both abort and continue"
+msgstr "abort und continue können nicht gleichzeitig genutzt werden"
+
+msgid "cannot use collapse with continue or abort"
+msgstr "collapse kann nicht mit continue oder abort genutzt werden"
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr "abort und continue erlauben die Angabe einer Revision nicht"
+
+msgid "cannot specify both a revision and a base"
+msgstr "Es können nicht revision und base gleichzeitig angegeben werden"
+
+msgid "nothing to rebase\n"
+msgstr "Kein Rebase nötig\n"
+
+msgid "cannot use both keepbranches and extrafn"
+msgstr "keepbranches und extrafn können nicht gleichzeitig genutzt werden"
+
+msgid "rebase merging completed\n"
+msgstr "Zusammenführungen des Rebase abgeschlossen\n"
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr "Warnung: Neue Änderungssätze auf Quellzweig gefunden, lösche nicht\n"
+
+msgid "rebase completed\n"
+msgstr "Rebase abgeschlossen\n"
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr "%d Revisionen wurden übersprungen\n"
+
+msgid " set parents\n"
+msgstr " setzt die Vorgänger\n"
+
+#, python-format
+msgid "rebasing %d:%s\n"
+msgstr "Rebase von %d:%s\n"
+
+#, python-format
+msgid " future parents are %d and %d\n"
+msgstr " die zukünftigen Vorgänger sind %d und %d\n"
+
+#, python-format
+msgid " update to %d:%s\n"
+msgstr " aktualisiert auf %d:%s\n"
+
+msgid " already in target\n"
+msgstr " bereits auf Ziel\n"
+
+#, python-format
+msgid " merge against %d:%s\n"
+msgstr " Zusammenführung zwischen %d:%s\n"
+
+msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgstr ""
+"Behebe ungelöste Konflikte mit hg resolve, dann führe hg rebase --continue "
+"aus"
+
+msgid "resuming interrupted rebase\n"
+msgstr "Nehme unterbrochenen Rebase wieder auf\n"
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr "keine Änderungen, Revision %d übersprungen\n"
+
+#, python-format
+msgid "next revision set to %s\n"
+msgstr "nächste Revision auf %s gesetzt\n"
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr ""
+"Revision %d kann nicht als Basis genutzt werden, das Ergebnis hätte 3 "
+"Vorgänger"
+
+#, python-format
+msgid "revision %d is an mq patch (%s), finalize it.\n"
+msgstr "Revision %d ist ein MQ-Patch (%s) und muss finalisiert werden.\n"
+
+#, python-format
+msgid "import mq patch %d (%s)\n"
+msgstr "Importiere MQ Patch %d (%s)\n"
+
+msgid "rebase status stored\n"
+msgstr "Rebase-Zustand gesichert\n"
+
+msgid "rebase status resumed\n"
+msgstr "Rebase-Zustand wieder aufgenommen\n"
+
+msgid "no rebase in progress"
+msgstr "Kein vorheriger Rebase zur Wiederaufnahme"
+
+msgid "warning: new changesets detected on target branch, not stripping\n"
+msgstr "Warnung: Neue Änderungssätze auf Zielzweig gefunden, lösche nicht\n"
+
+msgid "rebase aborted\n"
+msgstr "Rebase abgebrochen\n"
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr "Rebase kann auf einem angewandten MQ-Patch nicht aufsetzen"
+
+msgid "cannot rebase an ancestor"
+msgstr "Kann Rebase nicht auf einem Vorläufer ausführen"
+
+msgid "cannot rebase a descendant"
+msgstr "Kann Rebase nicht auf einem Nachfolger ausführen"
+
+msgid "already working on current\n"
+msgstr "Arbeite bereits auf der aktuellen Version\n"
+
+msgid "already working on the current branch\n"
+msgstr "Arbeite bereits auf dem aktuellen Zweig\n"
+
+#, python-format
+msgid "rebase onto %d starting from %d\n"
+msgstr "Rebase auf %d beginnend bei %d\n"
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr ""
+"Zusammenfalten nicht möglich, es gibt mehr als einen externen Vorgänger"
+
+msgid "--update and --rebase are not compatible, ignoring the update flag\n"
+msgstr "--update und --rebase sind nicht kompatibel, ignoriere --update\n"
+
+msgid "rebase working directory to branch head"
+msgstr "Führt Rebase zu einem Zweigkopf auf dem Arbeitsverzeichnis aus"
+
+msgid "rebase from a given revision"
+msgstr "Rebase ab einer angegebenen Revision"
+
+msgid "rebase from the base of a given revision"
+msgstr "Rebase ab der Basis einer angegebenen Revision"
+
+msgid "rebase onto a given revision"
+msgstr "Rebase der angegebene Revision"
+
+msgid "collapse the rebased revisions"
+msgstr "Faltet die erzeugten Revisionen nach dem Rebase zusammen"
+
+msgid "keep original revisions"
+msgstr "Behält die ursprünglichen Revisionen"
+
+msgid "keep original branches"
+msgstr "Behält die ursprünglichen Zweige"
+
+msgid "continue an interrupted rebase"
+msgstr "Führt einen unterbrochenen Rebase fort"
+
+msgid "abort an interrupted rebase"
+msgstr "Bricht einen unterbrochenen Rebase ab"
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+msgstr ""
+
+# Nicht übersetzen
+msgid "interactive change selection during commit or qrefresh"
+msgstr ""
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr "Dies modifiziert eine Binärdatei (alles oder nicht)\n"
+
+msgid "this is a binary file\n"
+msgstr "Dies ist eine Binärdatei\n"
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr "%d Hunks, %d Zeilen geändert\n"
+
+msgid "[Ynsfdaq?]"
+msgstr ""
+
+msgid "&Yes, record this change"
+msgstr "&Yes - übernimmt diese Änderung"
+
+msgid "&No, skip this change"
+msgstr "&No, überspringt diese Änderung"
+
+msgid "&Skip remaining changes to this file"
+msgstr ""
+
+msgid "Record remaining changes to this &file"
+msgstr ""
+
+msgid "&Done, skip remaining changes and files"
+msgstr ""
+
+msgid "Record &all changes to all remaining files"
+msgstr "Übernimmt &alle Änderungen aller restlichen Dateien"
+
+msgid "&Quit, recording no changes"
+msgstr "&Quit, übernimmt keine Änderungen"
+
+msgid "&?"
+msgstr ""
+
+msgid "y"
+msgstr ""
+
+msgid "?"
+msgstr ""
+
+msgid "y - record this change"
+msgstr "y - übernimmt diese Änderung"
+
+msgid "s"
+msgstr ""
+
+msgid "f"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "a"
+msgstr ""
+
+msgid "q"
+msgstr ""
+
+msgid "user quit"
+msgstr "Abbruch durch Benutzer"
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr "Überprüfe Änderungen an %s?"
+
+msgid " and "
+msgstr " und "
+
+#, python-format
+msgid "record this change to %r?"
+msgstr "Übernehme die Änderung an %r?"
+
+#, python-format
+msgid "record change %d/%d to %r?"
+msgstr "Übernehme die Änderung %d/%d an %r?"
+
+msgid ""
+"interactively select changes to commit\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be candidates for recording.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" You will be prompted for whether to record changes to each\n"
+" modified file, and for files with multiple changes, for each\n"
+" change to use. For each query, the following responses are\n"
+" possible:\n"
+"\n"
+" y - record this change\n"
+" n - skip this change\n"
+"\n"
+" s - skip remaining changes to this file\n"
+" f - record remaining changes to this file\n"
+"\n"
+" d - done, skip remaining changes and files\n"
+" a - record all changes to all remaining files\n"
+" q - quit, recording no changes\n"
+"\n"
+" ? - display help"
+msgstr ""
+"Interaktive Auswahl von Änderungen zur Übernahme ins Archiv\n"
+"\n"
+" Falls keine Liste von Dateien übergeben wird, gelten alle von\n"
+" \"hg status\" gemeldeten Änderungen als Kandidaten für 'record'.\n"
+"\n"
+" Siehe 'hg help dates' für eine Liste aller gültigen Formate für -d/--\n"
+"\n"
+" Es erfolgt eine Abfrage für jede Datei, ob Änderungen übernommen\n"
+" werden sollen, bei Dateien mit mehreren Änderungen für jede einzelne\n"
+" Änderung. Folgenden Antworten sind bei jeder Anfrage möglich:\n"
+"\n"
+" y - übernimmt diese Änderung\n"
+" n - überspringt diese Änderung\n"
+"\n"
+" s - überspringt verbleibende Änderungen dieser Datei\n"
+" f - übernimmt verbleibende Änderungen dieser Datei\n"
+"\n"
+" d - fertig, überspringt verbleibende Änderungen und Dateien\n"
+" a - übernimmt alle Änderungen aller verbleibenden Dateien\n"
+" q - beendet ohne Änderungen zu übernehmen\n"
+"\n"
+" ? - zeigt Hilfe an"
+
+msgid "'mq' extension not loaded"
+msgstr "'mq' Erweiterung nicht geladen"
+
+msgid "running non-interactively, use commit instead"
+msgstr "Nicht-interaktive Ausführung, nutze stattdessen 'commit'"
+
+msgid "no changes to record\n"
+msgstr "Keine Änderungen zu übernehmen\n"
+
+#, python-format
+msgid "backup %r as %r\n"
+msgstr "Sichere %r unter %r\n"
+
+msgid "applying patch\n"
+msgstr "Wende Patch an\n"
+
+msgid "patch failed to apply"
+msgstr "Patch schlug fehl"
+
+#, python-format
+msgid "restoring %r to %r\n"
+msgstr "Wiederherstellung: %r nach %r\n"
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr "hg record [OPTION]... [DATEI]..."
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr "hg qrecord [OPTION]... PATCH [DATEI]..."
+
+msgid ""
+"patch transplanting tool\n"
+"\n"
+"This extension allows you to transplant patches from another branch.\n"
+"\n"
+"Transplanted patches are recorded in .hg/transplant/transplants, as a\n"
+"map from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr ""
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr ""
+
+#, python-format
+msgid "filtering %s\n"
+msgstr ""
+
+msgid "filter failed"
+msgstr ""
+
+msgid "can only omit patchfile if merging"
+msgstr ""
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr ""
+
+msgid "Fix up the merge and run hg transplant --continue"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr ""
+
+msgid "transplant log file is corrupt"
+msgstr ""
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr ""
+
+msgid "commit failed"
+msgstr ""
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr ""
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+" Selected changesets will be applied on top of the current working\n"
+" directory with the log of the original changeset. If --log is\n"
+" specified, log messages will have a comment appended of the form:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" You can rewrite the changelog message with the --filter option.\n"
+" Its argument will be invoked with the current changelog message as\n"
+" $1 and the patch as $2.\n"
+"\n"
+" If --source/-s is specified, selects changesets from the named\n"
+" repository. If --branch/-b is specified, selects changesets from\n"
+" the branch holding the named revision, up to that revision. If\n"
+" --all/-a is specified, all changesets on the branch will be\n"
+" transplanted, otherwise you will be prompted to select the\n"
+" changesets you want.\n"
+"\n"
+" hg transplant --branch REVISION --all will rebase the selected\n"
+" branch (up to the named revision) onto your current working\n"
+" directory.\n"
+"\n"
+" You can optionally mark selected transplanted changesets as merge\n"
+" changesets. You will not be prompted to transplant any ancestors\n"
+" of a merged transplant, and you can merge descendants of them\n"
+" normally instead of transplanting them.\n"
+"\n"
+" If no merges or revisions are provided, hg transplant will start\n"
+" an interactive changeset browser.\n"
+"\n"
+" If a changeset application fails, you can fix the merge by hand\n"
+" and then resume where you left off by calling hg transplant\n"
+" --continue/-c.\n"
+" "
+msgstr ""
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr ""
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr ""
+
+msgid "--all requires a branch revision"
+msgstr ""
+
+msgid "--all is incompatible with a revision list"
+msgstr ""
+
+msgid "no revision checked out"
+msgstr ""
+
+msgid "outstanding uncommitted merges"
+msgstr ""
+
+msgid "outstanding local changes"
+msgstr ""
+
+msgid "pull patches from REPOSITORY"
+msgstr ""
+
+msgid "pull patches from branch BRANCH"
+msgstr ""
+
+msgid "pull all changesets up to BRANCH"
+msgstr ""
+
+msgid "skip over REV"
+msgstr ""
+
+msgid "merge at REV"
+msgstr ""
+
+msgid "append transplant info to log message"
+msgstr ""
+
+msgid "continue last transplant session after repair"
+msgstr ""
+
+msgid "filter changesets through FILTER"
+msgstr ""
+
+msgid ""
+"hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr ""
+
+msgid ""
+"allow to use MBCS path with problematic encoding.\n"
+"\n"
+"Some MBCS encodings are not good for some path operations (i.e.\n"
+"splitting path, case conversion, etc.) with its encoded bytes. We call\n"
+"such a encoding (i.e. shift_jis and big5) as \"problematic encoding\".\n"
+"This extension can be used to fix the issue with those encodings by\n"
+"wrapping some functions to convert to Unicode string before path\n"
+"operation.\n"
+"\n"
+"This extension is useful for:\n"
+" * Japanese Windows users using shift_jis encoding.\n"
+" * Chinese Windows users using big5 encoding.\n"
+" * All users who use a repository with one of problematic encodings on\n"
+" case-insensitive file system.\n"
+"\n"
+"This extension is not needed for:\n"
+" * Any user who use only ASCII chars in path.\n"
+" * Any user who do not use any of problematic encodings.\n"
+"\n"
+"Note that there are some limitations on using this extension:\n"
+" * You should use single encoding in one repository.\n"
+" * You should set same encoding for the repository by locale or\n"
+" HGENCODING.\n"
+"\n"
+"To use this extension, enable the extension in .hg/hgrc or ~/.hgrc:\n"
+"\n"
+" [extensions]\n"
+" hgext.win32mbcs =\n"
+"\n"
+"Path encoding conversion are done between Unicode and\n"
+"encoding.encoding which is decided by mercurial from current locale\n"
+"setting or HGENCODING.\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] filename conversion fail with %s encoding\n"
+msgstr ""
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] activated with encoding: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr ""
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"and also consider adding:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+
+msgid ""
+"zeroconf support for mercurial repositories\n"
+"\n"
+"Zeroconf enabled repositories will be announced in a network without\n"
+"the need to configure a server or a service. They can be discovered\n"
+"without knowing their actual IP address.\n"
+"\n"
+"To use the zeroconf extension add the following entry to your hgrc\n"
+"file:\n"
+"\n"
+"[extensions]\n"
+"hgext.zeroconf =\n"
+"\n"
+"To allow other people to discover your repository using run \"hg serve\"\n"
+"in your repository.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"You can discover zeroconf enabled repositories by running \"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+msgstr ""
+
+msgid "archive prefix contains illegal components"
+msgstr "Präfix des Archivs enthält nicht zulässige Komponenten"
+
+msgid "cannot give prefix when archiving to files"
+msgstr "Bei Archivierung in Dateien kann kein Präfix angegeben werden"
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr "Unbekannter Archivtyp '%s'"
+
+msgid "invalid changegroup"
+msgstr ""
+
+msgid "unknown parent"
+msgstr "Unbekannte Vorgängerversion"
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr "Integritätsprüfung fehlgeschlagen bei %s:%d"
+
+#, python-format
+msgid "%s: not a Mercurial bundle file"
+msgstr "%s: keine Mercurial Bündeldatei"
+
+#, python-format
+msgid "%s: unknown bundle version"
+msgstr "%s: unbekannte Bündelversion"
+
+#, python-format
+msgid "%s: unknown bundle compression type"
+msgstr "%s: unbekannte Kompressionsmethode des Bündels"
+
+msgid "cannot create new bundle repository"
+msgstr "Neues Bündelarchiv kann nicht erzeugt werden"
+
+#, python-format
+msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgstr "vorzeitiges Dateiende beim Lesen (%d Byte erhalten, %d erwartet)"
+
+msgid "empty username"
+msgstr "Leerere Benutzername"
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr "Benutzername %s enthält einen Zeilenumbruch"
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr "Optionen --message und --logfile schließen sich gegenseitig aus"
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr "Kann Versionsmeldung '%s' nicht lesen: %s"
+
+msgid "limit must be a positive integer"
+msgstr "Log-Grenzwert `limit` muss eine positive Ganzzahl sein"
+
+msgid "limit must be positive"
+msgstr "Log-Grenzwert `limit` muss positiv sein"
+
+msgid "too many revisions specified"
+msgstr "Zu viele Revisionen angegeben"
+
+#, python-format
+msgid "invalid format spec '%%%s' in output file name"
+msgstr "Ungültiges Format '%%%s' für den Namen der Ausgabedatei"
+
+#, python-format
+msgid "adding %s\n"
+msgstr "Füge %s hinzu\n"
+
+#, python-format
+msgid "removing %s\n"
+msgstr "Entferne %s\n"
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr ""
+"Interpretiere die Entfernung von %s als Umbenennung in %s (%d%% ähnlich)\n"
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr "%s kann nicht kopiert werden - steht nicht unter Versionskontrolle\n"
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr "%s: wird nicht kopiert - ist bereits als zu entfernen markiert\n"
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr "%s: kann nicht kopiert werden - %s wird von %s blockiert\n"
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr "%s: kann nicht kopiert werden - Datei existiert bereits\n"
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr "%s: kann nicht kopiert werden - Arbeitskopie ist gelöscht\n"
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr "%s: kann nicht kopiert werden - %s\n"
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr "Verschiebe %s nach %s\n"
+
+#, python-format
+msgid "copying %s to %s\n"
+msgstr "Kopiere %s nach %s\n"
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+"%s ist nicht im Archiv, daher gilt %s als neu hinzugefügt (nicht als "
+"kopiert).\n"
+
+msgid "no source or destination specified"
+msgstr "Weder Quelle noch Ziel angegeben"
+
+msgid "no destination specified"
+msgstr "Kein Ziel angegeben"
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr "Bei mehreren Quelldateien muss das Ziel ein Verzeichnis sein"
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr "Ziel %s ist kein Verzeichnis"
+
+msgid "no files to copy"
+msgstr "Keine Dateien zu kopieren"
+
+msgid "(consider using --after)\n"
+msgstr "(erwäge die Option --after)\n"
+
+#, python-format
+msgid "changeset: %d:%s\n"
+msgstr "Änderung: %d:%s\n"
+
+#, python-format
+msgid "branch: %s\n"
+msgstr "Zweig: %s\n"
+
+#, python-format
+msgid "tag: %s\n"
+msgstr "Marke: %s\n"
+
+#, python-format
+msgid "parent: %d:%s\n"
+msgstr "Vorgänger: %d:%s\n"
+
+#, python-format
+msgid "manifest: %d:%s\n"
+msgstr "Manifest: %d:%s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "Nutzer: %s\n"
+
+#, python-format
+msgid "date: %s\n"
+msgstr "Datum: %s\n"
+
+msgid "files+:"
+msgstr "Dateien+:"
+
+msgid "files-:"
+msgstr "Dateien-:"
+
+msgid "files:"
+msgstr "Dateien:"
+
+#, python-format
+msgid "files: %s\n"
+msgstr "Dateien: %s\n"
+
+#, python-format
+msgid "copies: %s\n"
+msgstr "Kopien: %s\n"
+
+#, python-format
+msgid "extra: %s=%s\n"
+msgstr "Extra: %s=%s\n"
+
+msgid "description:\n"
+msgstr "Beschreibung:\n"
+
+#, python-format
+msgid "summary: %s\n"
+msgstr "Zusammenfassung: %s\n"
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr "%s: kein Schlüsselwort '%s'"
+
+#, python-format
+msgid "%s: %s"
+msgstr ""
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr "Gefundene Revision %s vom %s\n"
+
+msgid "revision matching date not found"
+msgstr "Keine zum Datum passende Revision gefunden"
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr "Kann fehlender Datei nicht folgen: \"%s\""
+
+#, python-format
+msgid "%s:%s copy source revision cannot be found!\n"
+msgstr "%s:%s Revision des Originals nicht gefunden!\n"
+
+msgid "can only follow copies/renames for explicit file names"
+msgstr ""
+"Kopien/Umbenennungen können nur zu expliziten Dateinamen verfolgt werden"
+
+msgid "HG: Enter commit message. Lines beginning with 'HG:' are removed."
+msgstr ""
+"HG: Bitte gib eine Versions-Meldung ein. Zeilen beginnend mit 'HG:' werden "
+"entfernt."
+
+msgid "HG: Leave message empty to abort commit."
+msgstr ""
+
+#, python-format
+msgid "HG: user: %s"
+msgstr "HG: Benutzer: %s"
+
+msgid "HG: branch merge"
+msgstr ""
+
+#, python-format
+msgid "HG: branch '%s'"
+msgstr ""
+
+#, python-format
+msgid "HG: added %s"
+msgstr ""
+
+#, python-format
+msgid "HG: changed %s"
+msgstr "HG: Geändert %s"
+
+#, python-format
+msgid "HG: removed %s"
+msgstr "HG: entfernt %s"
+
+msgid "HG: no files changed"
+msgstr "HG: Keine Dateiänderungen"
+
+msgid "empty commit message"
+msgstr "Leere Versions-Meldung"
+
+msgid ""
+"add the specified files on the next commit\n"
+"\n"
+" Schedule files to be version controlled and added to the\n"
+" repository.\n"
+"\n"
+" The files will be added to the repository at the next commit. To\n"
+" undo an add before that, see hg revert.\n"
+"\n"
+" If no names are given, add all files to the repository.\n"
+" "
+msgstr ""
+"Fügt die angegebenen Dateien der nächsten Version hinzu\n"
+"\n"
+" Merkt Dateien zur Versionskontrolle im Projektarchiv vor.\n"
+"\n"
+" Die Dateien werden dem Projektarchiv beim nächsten Übernehmen (commit)\n"
+" hinzugefügt. Um diese Aktion vorher rückgängig zu machen, siehe hg "
+"revert.\n"
+"\n"
+" Wenn keine Namen angegeben sind, füge alle Dateien dem Projektarchiv\n"
+" hinzu.\n"
+" "
+
+msgid ""
+"add all new files, delete all missing files\n"
+"\n"
+" Add all new files and remove all missing files from the\n"
+" repository.\n"
+"\n"
+" New files are ignored if they match any of the patterns in\n"
+" .hgignore. As with add, these changes take effect at the next\n"
+" commit.\n"
+"\n"
+" Use the -s/--similarity option to detect renamed files. With a\n"
+" parameter > 0, this compares every removed file with every added\n"
+" file and records those similar enough as renames. This option\n"
+" takes a percentage between 0 (disabled) and 100 (files must be\n"
+" identical) as its parameter. Detecting renamed files this way can\n"
+" be expensive.\n"
+" "
+msgstr ""
+"Fügt alle neuen Dateien hinzu, löscht alle fehlenden Dateien\n"
+"\n"
+" Füge alle neuen Dateien hinzu und lösche alle fehlenden Dateien aus\n"
+" dem Projektarchiv.\n"
+"\n"
+" Neue Dateien werden ignoriert, wenn sie einem der Muster aus .hgignore\n"
+" entsprechen. Genau wie add, wirken diese Änderungen erst beim nächsten\n"
+" Übernehmen (commit).\n"
+"\n"
+" Nutze die Option -s um umbenannte Dateien zu entdecken. Mit einem\n"
+" Parameter > 0 wird jede entfernte Datei mit jeder hinzugefügten "
+"verglichen\n"
+" und bei genügender Ähnlichkeit als Umbenennung markiert. Diese Option\n"
+" erwartet eine Prozentangabe zwischen 0 (deaktiviert) und 100 (Dateien\n"
+" müssen identisch sein) als Parameter. Umbenennungen auf diese Weise zu\n"
+" erkennen, kann aufwändig sein.\n"
+" "
+
+msgid "similarity must be a number"
+msgstr "similarity muss eine Zahl sein"
+
+msgid "similarity must be between 0 and 100"
+msgstr "similarity muss zwischen 0 und 100 liegen"
+
+msgid ""
+"show changeset information per file line\n"
+"\n"
+" List changes in files, showing the revision id responsible for\n"
+" each line\n"
+"\n"
+" This command is useful to discover who did a change or when a\n"
+" change took place.\n"
+"\n"
+" Without the -a/--text option, annotate will avoid processing files\n"
+" it detects as binary. With -a, annotate will generate an\n"
+" annotation anyway, probably with undesirable results.\n"
+" "
+msgstr ""
+"Zeigt Änderungssatz (changeset) Informationen pro Dateizeile an\n"
+"\n"
+" Listet Änderungen in Dateien mit der zugehörigen Revisions-Id für jede\n"
+" Zeile auf\n"
+"\n"
+" Dieser Befehl ist nützlich, um herauszufinden wer eine Änderung gemacht\n"
+" hat oder wann eine Änderung stattgefunden hat.\n"
+"\n"
+" Ohne die Option -a wird die Verarbeitung von Binärdateien vermieden.\n"
+" Mit -a werden auch solche Dateien verarbeitet, wahrscheinlich mit "
+"unerwünschtem\n"
+" Ergebnis.\n"
+" "
+
+msgid "at least one file name or pattern required"
+msgstr "Zumindest ein Dateiname oder Muster benötigt"
+
+msgid "at least one of -n/-c is required for -l"
+msgstr "Zumindest -n oder -c werden für -l benötigt"
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr "%s: Binärdatei\n"
+
+msgid ""
+"create unversioned archive of a repository revision\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use -r/--rev to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use -t/--type. Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see 'hg help export' for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use -p/--prefix to specify a format string for the\n"
+" prefix. The default is the basename of the archive, with suffixes\n"
+" removed.\n"
+" "
+msgstr ""
+"Erzeugt ein unversioniertes Archiv einer Projektarchiv-Revision\n"
+"\n"
+" Standardmäßig wird die Vorgängerversion der im Arbeitsverzeichnis "
+"gefundenen\n"
+" verwendet. Eine andere Reversion kann mit \"-r\" angegeben werden.\n"
+"\n"
+" Um den Typ des Archivs anzugeben, nutze \"-t\". Gültige\n"
+" Typen sind:\n"
+"\n"
+" \"files\" (Standard): ein Verzeichnis voller Dateien\n"
+" \"tar\": tar Archiv, unkomprimiert\n"
+" \"tbz2\": tar Archiv, komprimiert mit bzip2\n"
+" \"tgz\": tar Archiv, komprimiert mit gzip\n"
+" \"uzip\": zip Archiv, unkomprimiert\n"
+" \"zip\": zip Archiv, komprimiert mit deflate\n"
+"\n"
+" Der exakte Name des Zielarchivs oder -verzeichnises wird mit\n"
+" einem Format-String angegeben; siehe 'hg help export' für Details.\n"
+"\n"
+" Jedem Element des Archivs wird ein Verzeichnis-Präfix vorangestellt.\n"
+" Nutze -p/--prefix um eine Format-String für das Präfix anzugeben.\n"
+" Als Standard wird der Dateiname des Archive ohne Dateiendung genutzt.\n"
+" "
+
+msgid "no working directory: please specify a revision"
+msgstr "Kein Arbeitsverzeichnis: Bitte gib eine Revision an"
+
+msgid "repository root cannot be destination"
+msgstr "Projektarchiv-Wurzel kann nicht als Ziel angegeben werden"
+
+msgid "cannot archive plain files to stdout"
+msgstr ""
+"Ungepacktes Archiv kann nicht auf der Standardausgabe ausgegeben werden"
+
+msgid ""
+"reverse effect of earlier changeset\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you back out a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head (current one by default).\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by hand.\n"
+" The result of this merge is not committed, as with a normal merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"Macht einen vorangegangen Änderungssatzes rückgängig\n"
+"\n"
+" Bereits vollzogene Änderungen werden noch einmal rückwärts angewendet\n"
+" und als neuer Änderungssatz (als Kind des rückgängig gemachten) "
+"übernommen.\n"
+"\n"
+" Soll ein anderer Änderungssatz als die Spitze (tip) zurückgezogen "
+"werden,\n"
+" so wird ein neuer Kopf erzeugt und dieser ist die neue Spitze.\n"
+"\n"
+" Die dadurch notwendige Zusammenführung kann durch die Option --merge\n"
+" automatisch mit der Vorgängerversion des Arbeitsverzeichnisses "
+"durchgeführt\n"
+" werden. Das Resultat dieser Zusammenführung wird wie üblich nicht "
+"sofort\n"
+" übernommen, sondern existiert als lokale Änderung.\n"
+"\n"
+" Siehe 'hg help dates' für eine Liste gültiger Formate für -d/--date.\n"
+" "
+
+msgid "please specify just one revision"
+msgstr "Bitte nur eine Revision angeben"
+
+msgid "please specify a revision to backout"
+msgstr "Bitte eine Revision, die zurückgezogen werden soll, angeben"
+
+msgid "cannot back out change on a different branch"
+msgstr "Kann die Änderung auf einem abweichenden Zweig nicht rückgängig machen"
+
+msgid "cannot back out a change with no parents"
+msgstr "Kann eine Änderung ohne Vorgängerversion nicht rückgängig machen"
+
+msgid "cannot back out a merge changeset without --parent"
+msgstr "Kann eine Zusammenführung nicht ohne --parent rückgängig machen"
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr "%s ist kein Vorgänger von %s"
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr "Kann mit --parent nur Zusammenführung rückgängig machen"
+
+#, python-format
+msgid "Backed out changeset %s"
+msgstr "Änderungssatz %s wurde rückgängig gemacht"
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr "Änderungssatz %s macht Änderungssatz %s rückgängig\n"
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr "Führe mit Änderungssatz %s zusammen\n"
+
+msgid "the backout changeset is a new head - do not forget to merge\n"
+msgstr "Neuen Kopf erstellt - Zusammenführung nicht vergessen\n"
+
+msgid "(use \"backout --merge\" if you want to auto-merge)\n"
+msgstr "(nutze \"backout --merge\" für eine automatische Zusammenführung)\n"
+
+msgid ""
+"subdivision search of changesets\n"
+"\n"
+" This command helps to find changesets which introduce problems. To\n"
+" use, mark the earliest changeset you know exhibits the problem as\n"
+" bad, then mark the latest changeset which is free from the problem\n"
+" as good. Bisect will update your working directory to a revision\n"
+" for testing (unless the -U/--noupdate option is specified). Once\n"
+" you have performed tests, mark the working directory as bad or\n"
+" good and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command it will be used for automatic bisection.\n"
+" Its exit status will be used as flag to mark revision as bad or\n"
+" good. In case exit status is 0 the revision is marked as good, 125\n"
+" - skipped, 127 (command not found) - bisection will be aborted;\n"
+" any other status bigger than 0 will mark revision as bad.\n"
+" "
+msgstr ""
+"Binäre Suche von Änderungssätzen\n"
+"\n"
+" Dieser Befehl hilft Änderungssätze zu finden, die Probleme eingeführt "
+"haben.\n"
+" Dies geschieht, indem eine Revision nach der anderen geladen und "
+"getestet\n"
+" wird, bis zwei aufeinanderfolgende Revisionen ohne und mit Fehler\n"
+" gefunden wurden. Das Laden geschieht wie bei einer binären Suche, indem\n"
+" das Intervall der in Frage kommenden Revisionen immer halbiert wird.\n"
+"\n"
+" Als Startintervall muss zunächst die letzte als 'gut' bekannte und die\n"
+" erste 'schlechte' Revision markiert werden. Das Arbeitsverzeichnis wird\n"
+" dadurch auf eine Revision zum Testen gebracht (es sei denn, die Option\n"
+" --noupdate ist angegeben). Mit -g (Test erfolgreich = gute Revision) "
+"und\n"
+" -b (Fehler gefunden = schlechte Revision) wird diese dann markiert und "
+"die\n"
+" nächste geladen, bzw. das Ziel (die Problemrevision) gemeldet.\n"
+"\n"
+" Die Markierung kann automatisch durch einem Testprogramm (Option -c) "
+"statt-\n"
+" finden. Ein Rückgabewert von 0 bedeutet dabei Erfolg, 125 Überspringen\n"
+" (wie manuell Option -s), 127 Abbruch und jeder andere positive Wert\n"
+" Fehler (schlechte Revision).\n"
+" "
+
+msgid "The first good revision is:\n"
+msgstr "Die erste gute Revision ist:\n"
+
+msgid "The first bad revision is:\n"
+msgstr "Die erste schlechte Revision ist:\n"
+
+msgid "Due to skipped revisions, the first good revision could be any of:\n"
+msgstr ""
+"Aufgrund übersprungener Revisionen könnte die erste gute Revision\n"
+"eine der folgenden sein:\n"
+
+msgid "Due to skipped revisions, the first bad revision could be any of:\n"
+msgstr ""
+"Aufgrund übersprungener Revisionen könnte die erste schlechte Revision\n"
+"eine der folgenden sein:\n"
+
+msgid "cannot bisect (no known good revisions)"
+msgstr "Kann Suche nicht starten (keine bekannte gute Revision)"
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr "Kann Suche nicht starten (keine bekannte schlechte Revision)"
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr "(Die Syntax 'hg bisect <cmd>' ist veraltet)\n"
+
+msgid "incompatible arguments"
+msgstr "Inkompatible Argumente"
+
+#, python-format
+msgid "failed to execute %s"
+msgstr "Fehler bei der Ausführung von %s"
+
+#, python-format
+msgid "%s killed"
+msgstr "%s gestorben"
+
+#, python-format
+msgid "Changeset %s: %s\n"
+msgstr "Änderungssatz %s: %s\n"
+
+#, python-format
+msgid "Testing changeset %s:%s (%s changesets remaining, ~%s tests)\n"
+msgstr "Teste Änderungssatz %s:%s (%s Änderungssätze verbleiben, ~%s Tests)\n"
+
+msgid ""
+"set or show the current branch name\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch does not exist\n"
+" in the repository until the next commit). It is recommended to use\n"
+" the 'default' branch as your primary development branch.\n"
+"\n"
+" Unless -f/--force is specified, branch will not let you set a\n"
+" branch name that shadows an existing branch.\n"
+"\n"
+" Use -C/--clean to reset the working directory branch to that of\n"
+" the parent of the working directory, negating a previous branch\n"
+" change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+"Setzt oder zeigt den Namen des aktuellen Zweigs\n"
+"\n"
+" Ohne Parameter wird der Name des aktuellen Zweiges angezeigt. Mit einem\n"
+" Parameter wird der Zweigname des Arbeitsverzeichnisses gesetzt. Der\n"
+" Zweig existiert nicht im Projektarchiv und muss erst übernommen werden.\n"
+" Es wird empfohlen den 'default'-Zweig als Hauptentwicklungszweig zu\n"
+" nutzen.\n"
+"\n"
+" Außer bei Angabe von --force lässt 'hg branch' nicht zu, einen Namen zu\n"
+" vergeben, der einen existierenden Zweig überdeckt.\n"
+"\n"
+" Nutze --clean um den neuen Namen rückgängig zu machen. Die Arbeitskopie\n"
+" hat dann wieder den selben Namen wie der Vorgänger im Projektarchiv.\n"
+"\n"
+" Um auf einen anderen (existierenden) Zweig zu wechseln, siehe 'hg "
+"update'.\n"
+" "
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr "Setze Arbeitsverzeichnis auf Zweig %s zurück\n"
+
+msgid "a branch of the same name already exists (use --force to override)"
+msgstr "Ein Zweig mit diesem Namen existiert bereits (--force zum Erzwingen)"
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr "Arbeitsverzeichnis wurde als Zweig %s markiert\n"
+
+msgid ""
+"list repository named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If active is specified, only show active branches.\n"
+"\n"
+" A branch is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+"Zeigt alle benannten Zweige des Projektarchiv an\n"
+"\n"
+" Listet die benannten Zweige des Projektarchiv auf und zeigt an, welche\n"
+" inaktiv sind. Mit der Option -a werden nur aktive Zweige ausgegeben.\n"
+"\n"
+" Ein Zweig gilt als aktiv, wenn er Köpfe des Projektarchivs enthält.\n"
+"\n"
+" Um auf einen anderen (existierenden) Zweig zu wechseln, siehe 'hg "
+"update'.\n"
+" "
+
+msgid ""
+"create a changegroup file\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" -a/--all (or --base null). To change the compression method\n"
+" applied, use the -t/--type option (by default, bundles are\n"
+" compressed using bz2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means\n"
+" and applied to another repository with the unbundle or pull\n"
+" command. This is useful when direct push and pull are not\n"
+" available or when exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+msgstr ""
+"Erzeugt eine Datei mit Änderungsgruppen\n"
+"\n"
+" Erzeuge eine gepackte Datei der Änderungsgruppen, die alle Änderungs-\n"
+" sätze enthält, die in einem anderen Archiv nicht vorhanden sind.\n"
+"\n"
+" Falls kein Zielarchiv angegeben ist, wird angenommen, dass das Ziel\n"
+" alle Knoten enthält, die durch einen oder mehrere --base Parameter\n"
+" angegeben wurden. Um ein Bündel aller Änderungssätze zu erzeugen, nutze\n"
+" --all (oder --base null). Die angewendete Kompressionsmethode kann mit\n"
+" der Option -t gewählt werden (standardmäßig bz2).\n"
+"\n"
+" Die Bündeldatei kann mit üblichen Mitteln transportiert und auf ein "
+"anderes\n"
+" Archiv mit dem 'unbundle' oder 'pull'-Befehl angewandt werden.\n"
+" Dies ist nützlich wenn ein direktes Schieben oder Herunterladen von\n"
+" Änderungen nicht verfügbar ist oder der Export eines kompletten Archivs\n"
+" unerwünscht ist.\n"
+"\n"
+" Die Anwendung von Bündeln bewahrt die Inhalte aller Änderungssätze,\n"
+" Berechtigungen, Kopier/Umbennungs-Informationen und die "
+"Revisionshistorie.\n"
+" "
+
+msgid "--base is incompatible with specifying a destination"
+msgstr "Bei Nutzung von --base kann kein Zielarchiv angegeben werden"
+
+msgid "unknown bundle type specified with --type"
+msgstr "Unbekannter Bündeltyp mit --type angegeben"
+
+msgid ""
+"output the current or given revision of files\n"
+"\n"
+" Print the specified files as they were at the given revision. If\n"
+" no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repository root\n"
+" %p root-relative path name of file being printed\n"
+" "
+msgstr ""
+"Gibt den Inhalt von Dateien in der aktuellen oder angegebenen Revision aus\n"
+"\n"
+" Gibt die angegebenen Dateien aus, wie sie zur gegebenen Revision waren.\n"
+" Wenn keine Revision angegeben wird, wird die Vorgängerversion des\n"
+" Arbeitsverzeichnisses genutzt. Ansonsten die Spitze, falls keine\n"
+" Revision geladen ist.\n"
+"\n"
+" Die Ausgabe kann in eine Datei erfolgen. In diesem Fall wird der Name\n"
+" der Datei mit einem Formatstring vorgegeben. Die Formatierungsregeln "
+"sind\n"
+" analog des 'export'-Befehls mit folgenden Ergänzungen:\n"
+"\n"
+" %s Dateiname der ausgegebenen Datei\n"
+" %d Verzeichnisname der Datei oder '.' in der Wurzel des Archivs\n"
+" %p Pfad und Dateiname relativ zur Archiv-Wurzel\n"
+" "
+
+msgid ""
+"make a copy of an existing repository\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" If you use the -r/--rev option to clone up to a specific revision,\n"
+" no subsequent revisions (including subsequent tags) will be\n"
+" present in the cloned repository. This option implies --pull, even\n"
+" on local repositories.\n"
+"\n"
+" By default, clone will check out the head of the 'default' branch.\n"
+" If the -U/--noupdate option is used, the new clone will contain\n"
+" only a repository (.hg) and no working copy (the working copy\n"
+" parent is the null revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Look at the help text for URLs for important details about ssh://\n"
+" URLs.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" "
+msgstr ""
+"Erzeugt eine Kopie eines bestehenden Projektarchivs\n"
+"\n"
+" Kopiert ein bestehendes Projektarchiv in ein neues Verzeichnis.\n"
+"\n"
+" Wird kein Zielverzeichnis angegeben, wird der Basisname der Quelle "
+"genutzt.\n"
+"\n"
+" Die Adresse der Quelle wird der .hg/hgrc Datei des neuen Archivs\n"
+" als Standard für entfernte Aktionen (pull/push) hinzugefügt.\n"
+"\n"
+" Wenn die -r Option zum klonen bis zu einer bestimmten Revision genutzt\n"
+" wird, werden keine Folgeversionen (oder Marken) im geklonten Archiv\n"
+" vorhanden sein. Diese Option impliziert --pull, auch bei lokalen "
+"Archiven.\n"
+"\n"
+" Standardmäßig wird clone die Kopfversion des 'default'-Zweiges zum\n"
+" Arbeitsverzeichnis machen. Bei Nutzung der -U Option wird der Klon zwar\n"
+" das Projektarchiv enthalten (.hg) aber keine Arbeitskopie laden (die\n"
+" Vorgängerversion der Arbeitskopie ist die 'null'-Revision).\n"
+"\n"
+" Siehe 'hg help urls' für Details gültiger Quellformate.\n"
+"\n"
+" Es ist möglich eine ssh:// URL als Ziel anzugeben, aber es werden weder\n"
+" .hg/hgrc noch Arbeitsverzeichnis auf der entfernten Seite angelegt.\n"
+" Wichtige Details zu URLs mit ssh:// finden sich unter 'hg help urls'.\n"
+"\n"
+" Aus Effizienzgründen werden 'hardlinks' für das Klonen genutzt, wann "
+"immer\n"
+" Quelle und Ziel auf dem selben Dateisystem sind (dies gilt nur für die\n"
+" Daten des Archivs, nicht für die Arbeitskopie). Einige Dateisyteme wie\n"
+" etwa AFS, implementieren 'hardlinks' fehlerhaft, erzeugen dabei aber "
+"keine\n"
+" Fehlermeldung. In diesen Fällen muss die --pull Option genutzt werden,\n"
+" um das Erzeugen von 'hardlinks' zu vermeiden.\n"
+"\n"
+" In einigen Fällen können Archiv und Arbeitskopie unter Nutzung\n"
+" von 'hardlinks' kopiert werden mit\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" Dies ist der schnellste Weg zu klonen, aber nicht immer sicher.\n"
+" Diese Operation ist nicht atomar (das Archiv darf während der Operation\n"
+" nicht modifiziert wird) und es muss sichergestellt werden, dass der\n"
+" genutzte Editor 'hardlinks' auflöst (vim, emacs und die meisten Linux\n"
+" Kernel Tools tun dies). Außerdem ist dies inkompatibel mit einigen\n"
+" Erweiterungen, die Metadaten unter dem .hg Verzeichnis ablegen, z.B. "
+"mq.\n"
+"\n"
+" "
+
+msgid ""
+"commit the specified files or all outstanding changes\n"
+"\n"
+" Commit changes to the given files into the repository. Unlike a\n"
+" centralized RCS, this operation is a local operation. See hg push\n"
+" for means to actively distribute your changes.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" file names or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is\n"
+" started to prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"Übernimmt Änderungen der angegebenen Dateien oder alle ausstehenden "
+"Änderungen ins Archiv\n"
+"\n"
+" Übernimmt Änderungen der angegebenen Dateien ins Archiv. Anders als\n"
+" bei zentralen Versionsverwaltungssystem ist dies eine lokale Operation.\n"
+" Vergleiche hg push für Wege zur aktiven Verteilung der Änderungen.\n"
+"\n"
+" Sollten keine Dateien übergeben werden, werden alle von 'hg status'\n"
+" angezeigten Änderungen Bestandteil der neuen Revision.\n"
+"\n"
+" Wenn das Ergebnis einer Zusammenführung übernommen werden soll, dürfen\n"
+" keine Dateinamen oder -I/-X Filter angegeben werden.\n"
+"\n"
+" Wenn keine Versionsmeldung mit der Option -m angegeben wird, wird der\n"
+" konfigurierte Editor für eine interaktive Eingabe gestartet.\n"
+"\n"
+" Siehe 'hg help dates' für eine Liste aller gültigen Formate für -d/--"
+"date.\n"
+" "
+
+msgid "created new head\n"
+msgstr "neuer Kopf erzeugt\n"
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr "Änderungssatz %d erzeugt:%s\n"
+
+msgid ""
+"mark files as copied for the next commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" stand in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+"Markiert Dateien als Kopien bereits übernommener Dateien\n"
+"\n"
+" Markiert das Ziel als Kopie der Quelle, so dass es die Versionshistorie "
+"der\n"
+" Quelle bis zu diesem Zeitpunkt teilt. Wenn mehrere Quellen angegeben "
+"sind,\n"
+" muss das Ziel ein Verzeichnis sein.\n"
+"\n"
+" Normalerweise kopiert dieser Befehl auch den Inhalt der Datei(en) wie "
+"sie\n"
+" im Arbeitsverzeichnis vorliegt. Existiert das Ziel jedoch schon, so "
+"kann\n"
+" dieses durch Angabe der Option --after/-A als Kopie nachträglich "
+"markiert\n"
+" werden.\n"
+"\n"
+" Die neue Datei wird wie üblich nicht sofort übernommen, sondern "
+"existiert\n"
+" als lokale Änderung im Arbeitsverzeichnis. Sie kann durch \"hg revert"
+"\"\n"
+" rückgängig gemacht werden.\n"
+" "
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr "Finde die Vorgängerversion zweier Revisionen im angegebenen Index"
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr "Es gibt hier kein Mercurial-Archiv (.hg nicht vorhanden)"
+
+msgid "either two or three arguments required"
+msgstr "Entweder zwei oder drei Parameter angeben"
+
+msgid "returns the completion list associated with the given command"
+msgstr "Listet mögliche Befehle zu gegebener Abkürzung auf"
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr ""
+"Markiert aktuellen Status als Änderungen seit gegebener Revision\n"
+"\n"
+" Interpretiert das Arbeitsverzeichnis als lokale Änderung seit der "
+"gegebenen\n"
+" Revision. Die Vorgängerversion ist die gegebene und die Änderungen "
+"aller\n"
+" Versionen seit dem (oder bis dahin) sind vorgemerkt und können als neue\n"
+" Revision (und Kopf) übernommen werden.\n"
+" "
+
+msgid "validate the correctness of the current dirstate"
+msgstr "Prüft die Richtigkeit der bisher vorgemerkten Änderungen"
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr "%s ist in Status %s, aber nicht in Manifest 1\n"
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr "%s ist in Status %s, aber auch in Manifest 1\n"
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr "%s ist in Status %s, aber in keinem Manifest\n"
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr "%s im Manifest 1, aber aufgeführt im Status %s"
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr ".hg/dirstate inkonsistent mit dem Manifest des aktuellen Vorgängers"
+
+#, fuzzy
+msgid ""
+"show combined config settings from all hgrc files\n"
+"\n"
+" With no arguments, print names and values of all config items.\n"
+"\n"
+" With one argument of the form section.name, print just the value\n"
+" of that config item.\n"
+"\n"
+" With multiple arguments, print names and values of all config\n"
+" items with matching section names.\n"
+"\n"
+" With the --debug flag, the source (filename and line number) is\n"
+" printed for each config item.\n"
+" "
+msgstr ""
+"Zeigt die kombinierten Konfigurationswerte aller hgrc-Dateien an\n"
+"\n"
+" Ohne Argumente werden die Namen und Werte aller Konfigurationseinträge\n"
+" angezeigt.\n"
+"\n"
+" Mit einem Argument der Form sektion.name wird nur der Wert dieses\n"
+" Konfigurationseintrages angezeigt.\n"
+"\n"
+" Mit mehreren Argumenten werden die Namen und Werte aller passenden\n"
+" Konfigurationseinträge angezeigt."
+
+msgid "only one config item permitted"
+msgstr "Nur ein Konfigurationseintrag ist erlaubt"
+
+msgid ""
+"manually set the parents of the current working directory\n"
+"\n"
+" This is useful for writing repository conversion tools, but should\n"
+" be used with care.\n"
+" "
+msgstr ""
+"Setzt die Vorgängerversionen des Arbeitsverzeichnisses manuell\n"
+"\n"
+" Die kann für externe Konversionswerkzeuge nützlich sein, sollte aber "
+"mit\n"
+" großer Vorsicht angewendet werden.\n"
+" "
+
+msgid "show the contents of the current dirstate"
+msgstr ""
+"Zeigt die interne Repräsentation der aktuellen Änderungen (dirstate) an"
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr "Kopiere: %s -> %s\n"
+
+msgid "dump the contents of a data file revision"
+msgstr ""
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr ""
+
+msgid "parse and display a date"
+msgstr "Liest ein Datum ein und gibt es wieder aus"
+
+msgid "dump the contents of an index file"
+msgstr ""
+
+msgid "dump an index DAG as a .dot file"
+msgstr ""
+
+msgid "test Mercurial installation"
+msgstr "Tested die Mercurial Installation"
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr "Prüfe Kodierung (%s)...\n"
+
+msgid " (check that your locale is properly set)\n"
+msgstr " (Stelle sicher, dass locale richtig gesetzt ist!)\n"
+
+msgid "Checking extensions...\n"
+msgstr "Prüfe Erweiterungen...\n"
+
+msgid " One or more extensions could not be found"
+msgstr " Eine oder mehrere Erweiterungen nicht gefunden"
+
+msgid " (check that you compiled the extensions)\n"
+msgstr " (Stelle sicher, dass die Erweiterungen compiliert wurden!)\n"
+
+msgid "Checking templates...\n"
+msgstr "Prüfe Vorlagen...\n"
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr "(Vorlagen scheinen falsch installiert worden zu sein)\n"
+
+msgid "Checking patch...\n"
+msgstr "Prüfe patch...\n"
+
+msgid " patch call failed:\n"
+msgstr " Aufruf von patch gescheitert:\n"
+
+msgid " unexpected patch output!\n"
+msgstr " Unerwartete Ausgabe von patch\n"
+
+msgid " patch test failed!\n"
+msgstr " patch Test gescheitert\n"
+
+msgid ""
+" (Current patch tool may be incompatible with patch, or misconfigured. "
+"Please check your .hgrc file)\n"
+msgstr ""
+" (Aktuelles patch Werkzeug könnte mit patch inkompatibel or fehlkonfiguriert "
+"sein. Prüfe die .hgrc Datei!)\n"
+
+msgid ""
+" Internal patcher failure, please report this error to http://www.selenic."
+"com/mercurial/bts\n"
+msgstr ""
+"Fehlschlag des internen patch Werkzeugs. Bitte melden Sie diesen Fehler bei "
+"http://www.selenic.com/mercurial/bts\n"
+
+msgid "Checking commit editor...\n"
+msgstr "Prüfe Editor für Versionsmeldungen...\n"
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr " Kein Editor für Versionsmeldungen angegeben und vi nicht im PATH\n"
+
+msgid " (specify a commit editor in your .hgrc file)\n"
+msgstr " (Gib einen Editor in der .hgrc Datei an!)\n"
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr " Kann Editor '%s' nicht im PATH finden\n"
+
+msgid "Checking username...\n"
+msgstr "Prüfe Benutzernamen...\n"
+
+msgid " (specify a username in your .hgrc file)\n"
+msgstr " (Gib einen Benutzernamen in der .hgrc Datei an!)\n"
+
+msgid "No problems detected\n"
+msgstr "Keine Probleme gefunden\n"
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr "%s Probleme gefunden. Erwäge die obigen Lösungsvorschläge!\n"
+
+msgid "dump rename information"
+msgstr ""
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr "%s umbenannt von %s:%s\n"
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr "%s ist nicht unbenannt\n"
+
+msgid "show how files match on given patterns"
+msgstr ""
+
+msgid ""
+"diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a/--text option, diff will avoid generating diffs of\n"
+" files it detects as binary. With -a, diff will generate a diff\n"
+" anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. For more information, read 'hg help diffs'.\n"
+" "
+msgstr ""
+"Zeigt Änderungen des Projektarchiv oder angegebener Dateien an\n"
+"\n"
+" Zeigt Unterschiede von Dateien zwischen Revisionen im unified-diff-\n"
+" Format an.\n"
+"\n"
+" HINWEIS: diff kann bei Zusammenführungen unerwartete Resultate "
+"anzeigen,\n"
+" da es nur mit einer (der ersten wenn keine Revision angegeben ist)\n"
+" Vorgängerversion vergleicht.\n"
+"\n"
+" Bei Angabe zweier Revisionen als Parameter werden Unterschiede\n"
+" zwischen diesen beiden angezeigt. Wenn nur eine Revision angegeben\n"
+" wurde, wird diese mit dem Arbeitsverzeichnis verglichen. Sollte keine\n"
+" Revision angegeben worden sein, wird das Arbeitsverzeichnis mit der\n"
+" Vorgängerversion verglichen.\n"
+"\n"
+" Ohne die Option -a vermeidet export den Vergleich von binären Dateien.\n"
+" Mit -a wird der Vergleich in jedem Fall durchgeführt, wahrscheinlich "
+"mit\n"
+" unerwünschtem Resultat.\n"
+"\n"
+" Nutze die Option --git um Vergleiche im git-erweiterten diff-Format zu\n"
+" erzeugen. Zur weiteren Information ist \"hg help diff\" "
+"aufschlussreich.\n"
+" "
+
+msgid ""
+"dump the header and diffs for one or more changesets\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a/--text option, export will avoid generating diffs\n"
+" of files it detects as binary. With -a, export will generate a\n"
+" diff anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. Read the diffs help topic for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the\n"
+" second parent. It can be useful to review a merge.\n"
+" "
+msgstr ""
+"Gibt Kopfzeilen und Änderungsverlauf einer oder mehrerer Versionen aus\n"
+"\n"
+" Die angezeigten Daten in den Kopfzeilen sind: Autor,\n"
+" Änderungssatz-Prüfsumme, Vorgängerversion und Versionsmeldung.\n"
+"\n"
+" HINWEIS: export kann bei Zusammenführungen unerwartete Resultate "
+"anzeigen,\n"
+" da es nur mit einer (der ersten es sei denn --switch-parent ist "
+"angegeben)\n"
+" Vorgängerversion vergleicht.\n"
+"\n"
+" Die Ausgabe kann in eine Datei erfolgen (Option -o). In diesem Fall "
+"wird\n"
+" der Name für jede ausgegebene Revision anhand einer Formatangabe "
+"erzeugt:\n"
+"\n"
+" %% literales \"%\" Zeichen\n"
+" %H Prüfsumme des Änderungssatzes (40 Byte hexadezimal)\n"
+" %N Anzahl der generierten Patches\n"
+" %R Revisionnummer des Änderungssatzes\n"
+" %b Basisname des exportierten Archivs\n"
+" %h Kurzform der Prüfsumme des Änderungssatzes (12 Byte hexadezimal)\n"
+" %n laufende Nummer mit führenden Nullen, beginnend bei 1\n"
+" %r Revisionsnummer mit führenden Nullen\n"
+"\n"
+" Ohne die Option -a vermeidet export den Vergleich von binären Dateien.\n"
+" Mit -a wird der Vergleich in jedem Fall durchgeführt, wahrscheinlich "
+"mit\n"
+" unerwünschtem Resultat.\n"
+"\n"
+" Nutze die Option --git um Vergleiche im git-erweiterten diff-Format zu\n"
+" erzeugen. Zur weiteren Information ist \"hg help diff\" "
+"aufschlussreich.\n"
+" "
+
+msgid "export requires at least one changeset"
+msgstr "export benötigt zumindest eine Versionsangabe"
+
+msgid "exporting patches:\n"
+msgstr "Exportiere Patches:\n"
+
+msgid "exporting patch:\n"
+msgstr "Exportiere Patch:\n"
+
+msgid ""
+"search for a pattern in specified files and revisions\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which a\n"
+" match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+msgstr ""
+"Sucht ein Muster in angegebenen Dateien und Revisionen\n"
+"\n"
+" Durchsucht Dateien in der Versionshistorie nach einem gegebenen Muster.\n"
+"\n"
+" Dieser Befehl unterscheidet sich von Unix grep, da es Reguläre "
+"Ausdrücke\n"
+" in Python/Perl Format erwartet und ausserdem nur die übernommenen "
+"Revisionen\n"
+" im Archiv durchsucht, nicht jedoch das Arbeitsverzeichnis.\n"
+"\n"
+" Standardmäßig gibt grep den Dateinamen und die jüngste Revision einer "
+"Datei\n"
+" aus, die das Suchmuster enthält. Mit der Option --all werden "
+"stattdessen\n"
+" alle Revisionen ausgegeben, in der das Muster hinzugefügt (\"+\") oder\n"
+" entfernt (\"-\") wurde.\n"
+" "
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr "grep: Ungültiges Suchmuster: %s\n"
+
+msgid ""
+"show current repository heads or show branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" If branch or revisions names are given this will show the heads of\n"
+" the specified branches or the branches those revisions are tagged\n"
+" with.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" Branch heads are changesets that have a given branch tag, but have\n"
+" no child changesets with that tag. They are usually where\n"
+" development on the given branch takes place.\n"
+" "
+msgstr ""
+"Zeigt die Köpfe des Archivs oder von Entwicklungszweigen\n"
+"\n"
+" Ohne Argumente werden alle Kopfversionen angezeigt\n"
+"\n"
+" Wenn Zweig- oder Revisionsnamen angegeben werden, werden die Köpfe\n"
+" dieser Zweige oder der Zweige, mit denen die Revisionen markiert\n"
+" wurden, angezeigt.\n"
+"\n"
+" Die \"Köpfe\" eines Archivs sind Änderungssätze, die keine\n"
+" Folgeversion haben. Hier findet typischerweise die Entwicklung statt\n"
+" und diese Versionen sind normalerweise Ziel von Aktualisierungen oder\n"
+" Zusammenführungen.\n"
+"\n"
+" Köpfe von Zweigen sind Versionen mit einem Zweignamen, die aber\n"
+" keine Folgeversionen dieses Namens haben. Hier findet typischerweise\n"
+" die Entwicklung dieses Zweiges statt.\n"
+" "
+
+#, python-format
+msgid "no changes on branch %s containing %s are reachable from %s\n"
+msgstr ""
+"Keine Änderungen auf dem Zweig %s, die %s enthalten, sind von %s erreichbar\n"
+
+#, python-format
+msgid "no changes on branch %s are reachable from %s\n"
+msgstr "Keine Änderungen auf dem Zweig %s sind von %s erreichbar\n"
+
+msgid ""
+"show help for a given topic or a help overview\n"
+"\n"
+" With no arguments, print a list of commands and short help.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that\n"
+" topic."
+msgstr ""
+"Zeigt die Hilfe für ein gegebenes Thema oder eine Hilfsübersicht\n"
+"\n"
+" Ohne Parameter wird eine Liste aller Befehle mit Kurzhilfe angezeigt.\n"
+"\n"
+" Bei Angabe eines Themas, einer Erweiterung oder eines Befehls wird\n"
+" detaillierte Hilfe zu diesem Thema angezeigt."
+
+msgid "global options:"
+msgstr "Globale Optionen:"
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr "Nutze \"hg help\" für eine Liste aller Befehle"
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr ""
+"Nutze \"hg help\" für eine Liste aller Befehle oder \"hg -v\" für Details"
+
+#, python-format
+msgid "use \"hg -v help%s\" to show aliases and global options"
+msgstr "Nutze \"hg -v help%s\" um Aliase und globale Optionen anzuzeigen"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "Nutze \"hg -v help %s\" um globale Optionen anzuzeigen"
+
+msgid ""
+"list of commands:\n"
+"\n"
+msgstr ""
+"Liste der Befehle:\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"Aliase: %s\n"
+
+msgid "(no help text available)"
+msgstr "(keine Hilfe verfügbar)"
+
+msgid "options:\n"
+msgstr "Optionen:\n"
+
+msgid "no commands defined\n"
+msgstr "keine Befehle definiert\n"
+
+msgid ""
+"\n"
+"enabled extensions:\n"
+"\n"
+msgstr ""
+"\n"
+"Aktive Erweiterungen:\n"
+"\n"
+
+#, python-format
+msgid " %s %s\n"
+msgstr ""
+
+msgid "no help text available"
+msgstr "keine Hilfe verfügbar"
+
+#, python-format
+msgid "%s extension - %s\n"
+msgstr "%s Erweiterung - %s\n"
+
+msgid "Mercurial Distributed SCM\n"
+msgstr ""
+
+msgid ""
+"basic commands:\n"
+"\n"
+msgstr ""
+"Grundlegende Befehle:\n"
+"\n"
+
+msgid ""
+"\n"
+"additional help topics:\n"
+"\n"
+msgstr ""
+"\n"
+"Zusätzliche Hilfethemen:\n"
+"\n"
+
+msgid ""
+"identify the working copy or specified revision\n"
+"\n"
+" With no revision, print a summary of the current state of the\n"
+" repository.\n"
+"\n"
+" With a path, do a lookup in another repository.\n"
+"\n"
+" This summary identifies the repository state using one or two\n"
+" parent hash identifiers, followed by a \"+\" if there are\n"
+" uncommitted changes in the working directory, a list of tags for\n"
+" this revision and a branch name for non-default branches.\n"
+" "
+msgstr ""
+"Beschreibt die Arbeitskopie oder die angegebene Revision\n"
+"\n"
+" Ohne Revision wird eine Zusammenfassung des aktuellen Status des\n"
+" Projektarchivs angezeigt.\n"
+"\n"
+" Mit einem Pfad wird eine Abfrage auf ein anderes Archiv ausgeführt.\n"
+"\n"
+" Die Zusammenfassung beschreibt den Zustand des Projektarchivs unter\n"
+" Nutzung von ein oder zwei Prüfsummenbezeichnern, gefolgt von einem \"+"
+"\"\n"
+" falls unversionierte Änderungen im Arbeitsverzeichnis vorliegen. Zudem\n"
+" werden eine Liste von Tags dieser Revision ausgegeben und der Zweigname\n"
+" falls nicht der 'default'-Zweig vorliegt.\n"
+" "
+
+msgid ""
+"import an ordered set of patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f/--force flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (body part must be type text/plain or\n"
+" text/x-patch to be used). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and\n"
+" description from patch override values from message headers and\n"
+" body. Values given on command line with -m/--message and -u/--user\n"
+" override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory to\n"
+" the parent of each patch before applying it, and will abort if the\n"
+" resulting changeset has a different ID than the one recorded in\n"
+" the patch. This may happen due to character set problems or other\n"
+" deficiencies in the text patch format.\n"
+"\n"
+" With -s/--similarity, hg will attempt to discover renames and\n"
+" copies in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use patch name \"-\". See 'hg\n"
+" help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"Importiert eine Liste von Patches\n"
+"\n"
+" Wendet die angegebenen Patches nacheinander an und übernimmt die "
+"Änderungen\n"
+" ins Archiv (es sei denn die Option --no-commit ist angegeben).\n"
+"\n"
+" Falls aktuell lokale Änderungen im Arbeitsverzeichnis vorliegen, bricht\n"
+" der Befehl ohne die Option -f/--force ab.\n"
+"\n"
+" Patches können direkt aus Emails importiert werden, sogar wenn sie in\n"
+" einem Anhang (Mime Typ text/plain oder text/x-patch) vorliegen. Die\n"
+" Absender- und Betreffszeile, sowie alle text/plain Abschnitte vor dem "
+"Patch\n"
+" werden als Benutzername bzw. Versionsmeldung bei der Übernahme "
+"verwendet.\n"
+"\n"
+" Falls der einzulesende Patch von \"hg export\" erzeugt wurde, werden\n"
+" Benutzername und Versionsmeldung aus dem Patch und nicht aus der Email\n"
+" verwendet. Die Optionen -m und -u überschreiben aber auch diese "
+"Angaben.\n"
+"\n"
+" Mit der Option --exact wird das Arbeitsverzeichnis vor jedem Patch auf\n"
+" dessen Vorgängerversion gebracht. Nach Anwendung wird geprüft, ob der\n"
+" neue Änderungssatz die gleiche Prüfsumme aufweist, wie der Patch. Falls\n"
+" dies nicht so ist (im Falle von inkompatiblen Zeichensätzen oder "
+"anderen\n"
+" Problemen mit dem Patch Format), wird die Operation abgebrochen.\n"
+"\n"
+" Mit der Option --similarity werden Umbenennungen und Kopien auf gleiche\n"
+" Weise wie mit dem Befehl \"hg addremove\" erkannt.\n"
+"\n"
+" Um einen Patch von der Standardeingabe zu lesen, kann der Dateiname \"-"
+"\"\n"
+" verwendet werden. Siehe 'hg help dates' für eine Liste aller gültigen\n"
+" Formate für -d/--date.\n"
+" "
+
+msgid "applying patch from stdin\n"
+msgstr "Wende Patch von der Standardeingabe an\n"
+
+msgid "no diffs found"
+msgstr "Keine Diffs gefunden"
+
+#, python-format
+msgid ""
+"message:\n"
+"%s\n"
+msgstr ""
+"Meldung:\n"
+"%s\n"
+
+msgid "not a mercurial patch"
+msgstr "Kein Mercurial Patch"
+
+msgid "patch is damaged or loses information"
+msgstr "Prüfsumme stimmt nicht überein: Patch korrumpiert"
+
+msgid ""
+"show new changesets found in source\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would be pulled if a\n"
+" pull was requested.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the\n"
+" changesets twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+msgstr ""
+"Zeigt neue Revisionen in einer externen Quelle an\n"
+"\n"
+" Zeigt alle neuen Änderungen an, die durch ein \"hg pull\" vom "
+"angegebenen\n"
+" Pfad/URL oder dem 'default'-Pfad geholt werden würden. Diese "
+"Änderungssätze\n"
+" würden geholt, wenn 'hg pull' ausgeführt würde.\n"
+"\n"
+" Für entfernte Archive sorgt die Option --bundle dafür, dass die "
+"Änderungen\n"
+" bei einem folgenden \"hg pull\" nicht ein zweites Mal geholt werden.\n"
+"\n"
+" Siehe \"hg help pull\" für gültige Angaben für die Quelle.\n"
+" "
+
+msgid ""
+"create a new repository in the given directory\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it is created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"Erzeugt ein neues Projektarchiv im angegebenen Verzeichnis\n"
+"\n"
+" Initialisiert ein neues Archiv im angegebenen Verzeichnis. Sollte das\n"
+" angegebene Verzeichnis nicht existieren, wird es angelegt.\n"
+"\n"
+" Ist kein Zielverzeichnis angegeben, wird das aktuelle genutzt.\n"
+"\n"
+" Es ist möglich eine ssh:// URL als Ziel anzugeben.\n"
+" Siehe 'hg help urls' für mehr Informationen.\n"
+" "
+
+msgid ""
+"locate files matching specific patterns\n"
+"\n"
+" Print all files under Mercurial control whose names match the\n"
+" given patterns.\n"
+"\n"
+" This command searches the entire repository by default. To search\n"
+" just the current directory and its subdirectories, use\n"
+" \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints all file\n"
+" names.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the -0 option to both this command and \"xargs\". This\n"
+" will avoid the problem of \"xargs\" treating single filenames that\n"
+" contain white space as multiple filenames.\n"
+" "
+msgstr ""
+"Suche Dateien mit bestimmtem Namen\n"
+"\n"
+" Gibt alle Dateien im Projektarchiv aus, deren Namen auf ein angegebenes\n"
+" Muster passen.\n"
+"\n"
+" Standardmäßig wird das gesamte Archiv durchsucht. Um die Suche auf das\n"
+" aktuelle Verzeichnis und Unterverzeichnisse zu begrenzen, verwende\n"
+" \"--include .\".\n"
+"\n"
+" Ohne angegebenes Suchmuster werden alle Dateinamen ausgegeben.\n"
+"\n"
+" Um die Ausgabe besser in Verbindung mit \"xargs\" verwenden zu können,\n"
+" sollte die Option \"-0\" (Null) in beiden Befehle angegeben werden.\n"
+" Dadurch werden die Dateinamen mit einem Null-Byte getrennt, was "
+"Probleme\n"
+" mit Leerzeichen in Dateinamen vermeidet.\n"
+" "
+
+msgid ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a file name to follow history across\n"
+" renames and copies. --follow without a file name will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command outputs: changeset id and hash, tags,\n"
+" non-trivial parents, user, date and time, and a summary for each\n"
+" commit. When the -v/--verbose switch is used, the list of changed\n"
+" files and full commit message is shown.\n"
+"\n"
+" NOTE: log -p/--patch may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, the files: list will only reflect files\n"
+" that are different from BOTH parents.\n"
+"\n"
+" "
+msgstr ""
+"Zeigt die Revisionshistorie des Archivs oder von Dateien an\n"
+"\n"
+" Gibt die Revisionshistorie der angegeben Dateien oder des ganzen\n"
+" Projektes aus.\n"
+"\n"
+" Die Dateihistorie wird angezeigt ohne der Umbenennungs- oder Kopier-\n"
+" historie zu folgen. Bei Angabe von -f/--follow mit einem Dateinamen\n"
+" wird die Historie über Kopien und Umbenennungen hinweg verfolgt.\n"
+" --follow ohne Dateinamen wird nur Vorläufer und Nachfolger ab der\n"
+" Startrevision anzeigen. --follow-first folgt nur dem ersten Vorgänger\n"
+" einer Zusammenführungsversion.\n"
+"\n"
+" Solle kein Revisionsbereich angegeben sein, wird tip:0 angenommen, "
+"außer\n"
+" --follow wurde angegeben. In diesem Fall wird die Vorgängerversion des\n"
+" Arbeitsverzeichnis als Startversion genommen.\n"
+"\n"
+" Siehe 'hg help dates' für eine Liste gültiger Formate für -d/--date.\n"
+"\n"
+" Standardmäßig wird folgendes ausgegeben: Änderungssatz-Id und\n"
+" Prüfsumme, Marken, nicht triviale Vorgängerversionen, Nutzer,\n"
+" Datum und Zeit und eine Zusammenfassung für jede Version. Bei Angabe\n"
+" des -v/--verbose Schalters, wird eine Liste aller geänderten Dateien\n"
+" und die komplette Versionsmeldung angezeigt.\n"
+"\n"
+" HINWEIS: log -p kann ein unerwartetes Diff für "
+"Zusammenführungsversionen\n"
+" erzeugen, da es standardmäßig die Zusammenführungsversion mit der "
+"ersten\n"
+" Vorgängerversion vergleicht. Auch in der Dateiliste werden nur Dateien\n"
+" berücksichtigt, die zu BEIDEN Vorgängernversionen verschieden sind.\n"
+"\n"
+" "
+
+#, fuzzy
+msgid ""
+"output the current or given revision of the project manifest\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the first parent of the working directory\n"
+" is used, or the null revision if none is checked out.\n"
+"\n"
+" With -v flag, print file permissions, symlink and executable bits.\n"
+" With --debug flag, print file revision hashes.\n"
+" "
+msgstr ""
+"Gibt das Manifest der angegebenen oder aktuellen Revision aus.\n"
+"\n"
+" Gibt eine Liste aller Dateien unter Versionskontrolle für die "
+"angegebene\n"
+" Revision aus. Wenn keine Revision angegeben wird, wird die erste\n"
+" Vorgängerversion des Arbeitsverzeichnis genutzt oder die Spitze (tip)\n"
+" falls keine Revision ausgecheckt ist.\n"
+"\n"
+" Mit dem Schalter -v werden zusätzlich zum Dateinamen auch die Rechte "
+"und\n"
+" der Dateityp (Verknüpfung/ausführbar) ausgegeben. Mit --debug auch noch\n"
+" die Prüfsumme.\n"
+" "
+
+msgid ""
+"merge working directory with another revision\n"
+"\n"
+" The contents of the current working directory is updated with all\n"
+" changes made in the requested revision since the last common\n"
+" predecessor revision.\n"
+"\n"
+" Files that changed between either parent are marked as changed for\n"
+" the next commit and a commit must be performed before any further\n"
+" updates are allowed. The next commit has two parents.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other\n"
+" head, the other head is merged with by default. Otherwise, an\n"
+" explicit revision to merge with must be provided.\n"
+" "
+msgstr ""
+"Führt das Arbeitsverzeichnis mit einer anderen Revision zusammen\n"
+"\n"
+" Wendet die Änderungen der angegebenen Revision (seit einem gemeinsamen\n"
+" Vorfahr) im Arbeitsverzeichnis an.\n"
+"\n"
+" Dateien, die in sich in einer der beiden Vorgängerversionen änderten\n"
+" werden als verändert markiert und es muss 'hg commit' ausgeführt bevor\n"
+" weitere Änderungen durchgeführt werden dürfen. Nach dem Übernehmen hat\n"
+" die neue Revision zwei Vorfahren.\n"
+"\n"
+" Wenn keine Revision angegeben wird und der Vorgänger des Arbeits-\n"
+" verzeichnisses eine Kopfversion eines Zweiges mit genau zwei Köpfen "
+"ist,\n"
+" dann wird der andere Kopf für die Zusammenführung verwendet.\n"
+" Bei mehr oder weniger als zwei Köpfen im Zweig muss eine andere "
+"Revision\n"
+" explizit angegeben werden.\n"
+" "
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr "Zweig '%s' hat %d Köpfe - Bitte wähle eine explizite Revision"
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr "Zweig '%s' hat einen Kopf - Bitte wähle eine explizite Revision"
+
+msgid "there is nothing to merge"
+msgstr "Es gibt nichts zum Zusammenführen"
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr "%s - Nutze \"hg update\" stattdessen"
+
+msgid ""
+"working dir not at a head rev - use \"hg update\" or merge with an explicit "
+"rev"
+msgstr ""
+"Arbeitsverzeichnis ist keine Kopfversion - Nutze \"hg update\" oder gib eine "
+"explizite Revision an"
+
+msgid ""
+"show changesets not found in destination\n"
+"\n"
+" Show changesets not found in the specified destination repository\n"
+" or the default push location. These are the changesets that would\n"
+" be pushed if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+msgstr ""
+"Zeigt Änderungssätze, die nicht im Zielarchiv sind\n"
+"\n"
+" Zeigt alle Änderungssätze des lokalen Archivs, die nicht im angegebenen\n"
+" Zielarchiv oder dem Standardziel vorhanden sind. Dies sind genau jene,\n"
+" die durch ein 'hg push' übertragen werden würden.\n"
+"\n"
+" Siehe Hilfe zu 'pull' für das Format der Zieladresse.\n"
+" "
+
+msgid ""
+"show the parents of the working directory or revision\n"
+"\n"
+" Print the working directory's parent revisions. If a revision is\n"
+" given via -r/--rev, the parent of that revision will be printed.\n"
+" If a file argument is given, revision in which the file was last\n"
+" changed (before the working directory revision or the argument to\n"
+" --rev if given) is printed.\n"
+" "
+msgstr ""
+"Zeigt die Vorgänger des Arbeitsverzeichnisses oder einer Revision\n"
+"\n"
+" Gibt die Vorgängerversion(en) des Arbeitsverzeichnisses aus. Bei\n"
+" Angabe einer Revision via --rev, werden die Vorgänger dieser\n"
+" Version ausgegeben. Bei Angabe einer Datei wird die Version\n"
+" ausgegeben, in der diese Datei zuletzt geändert wurde (noch vor der\n"
+" Version des Arbeitsverzeichnisses oder dem Argument zu --rev falls\n"
+" angegeben).\n"
+" "
+
+msgid "can only specify an explicit file name"
+msgstr "Ein expliziter Dateiname muss angegeben werden"
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr "'%s' nicht im Manifest gefunden!"
+
+msgid ""
+"show aliases for remote repositories\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given,\n"
+" show definition of available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"Zeigt Adresse für Aliasnamen von entfernten Projektarchiven an\n"
+"\n"
+" Zeigt die Adressdefinition des Kurznamens NAME an. Wenn kein Name "
+"gegeben\n"
+" ist, werden alle Alias-Definitionen angezeigt.\n"
+"\n"
+" Kurznamen für entfernte Archive werden im Abschnitt [paths] der Dateien\n"
+" /etc/mercurial/hgrc und $HOME/.hgrc definiert. Wenn der Befehl in einem\n"
+" Projektarchiv ausgeführt wird, wird auch die .hg/hgrc durchsucht.\n"
+"\n"
+" Siehe auch 'hg help urls' für das Format von Adressangaben.\n"
+" "
+
+msgid "not found!\n"
+msgstr "nicht gefunden!\n"
+
+msgid "not updating, since new heads added\n"
+msgstr "Aktualisierung nicht durchgeführt, da neue Köpfe hingefügt wurden\n"
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr ""
+"(\"hg heads\" zeigt alle Köpfe, nutze \"hg merge\" um sie zusammenzuführen)\n"
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr "(führe \"hg update\" aus, um ein Arbeitsverzeichnis zu erstellen)\n"
+
+msgid ""
+"pull changes from the specified source\n"
+"\n"
+" Pull changes from a remote repository to the local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository. By default, this\n"
+" does not update the copy of the project in the working directory.\n"
+"\n"
+" Use hg incoming if you want to see what will be added by the next\n"
+" pull without actually adding the changes to the repository.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"Holt Änderungen aus dem angegebenen Projektarchiv\n"
+"\n"
+" Überträgt Änderungen aus einem entfernten Archiv in das lokale.\n"
+"\n"
+" Dabei werden alle Änderungen vom Archiv am angegebenen Pfad oder\n"
+" URL gesucht und dem lokalen Archiv hinzugefügt. Standardmäßig\n"
+" wird die Kopie des Projektes im Arbeitsverzeichnis nicht aktualisiert.\n"
+"\n"
+" Um zu sehen, was beim nächsten 'pull' geholt würde, ohne dem Archiv\n"
+" tatsächlich Änderungen hinzuzufügen, nutze hg incoming.\n"
+"\n"
+" Beim Weglassen der QUELLE wird standardmäßig der 'default'-Pfad "
+"genutzt.\n"
+" Siehe Hilfe zu 'paths' zu Pfad-Kurznamen und 'urls' für erlaubte\n"
+" Formate für die Quellangabe.\n"
+" "
+
+msgid ""
+"push changes to the specified destination\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It moves changes from\n"
+" the current repository to a different one. If the destination is\n"
+" local this is identical to a pull in that directory from the\n"
+" current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" the client has forgotten to pull and merge before pushing.\n"
+"\n"
+" If -r/--rev is used, the named revision and all its ancestors will\n"
+" be pushed to the remote repository.\n"
+"\n"
+" Look at the help text for URLs for important details about ssh://\n"
+" URLs. If DESTINATION is omitted, a default path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"Überträgt lokale Änderungen in das angegebene Ziel\n"
+"\n"
+" Dies ist das Gegenteil der 'pull' Operation. Die lokalen Änderungen\n"
+" des aktuellen Archivs werden in ein anderes übertragen. Bei lokalem\n"
+" Ziel ist diese Aktion identisch zu einem 'hg pull' von diesem Archiv "
+"zum\n"
+" aktuellen.\n"
+"\n"
+" Im Regelfall wird \"hg push\" die Ausführung verweigern, wenn das\n"
+" Resultat die Anzahl der Kopfversionen im entfernten Archiv erhöht, da\n"
+" dies normalerweise bedeutet, dass der Nutzer vergessen hat vor der "
+"Über-\n"
+" tragung die entfernten Änderungen zu holen und zusammenzuführen.\n"
+"\n"
+" Bei Nutzung von -r wird die benannte Revision mit allen Vorgängern in\n"
+" das entfernte Archiv übertragen.\n"
+"\n"
+" Für wichtige Details zu ssh://-URLS kann die URL-Hilfe zu Rate gezogen\n"
+" werden. Beim Weglassen des ZIELs wird standardmäßig der 'default'-Pfad\n"
+" genutzt. Weitere Hilfe gibt unter 'hg help urls'.\n"
+" "
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr "Übertrage nach %s\n"
+
+msgid ""
+"roll back an interrupted transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an\n"
+" interrupted operation. It should only be necessary when Mercurial\n"
+" suggests it.\n"
+" "
+msgstr ""
+"Setzt eine unterbrochene Transaktion zurück\n"
+"\n"
+" Setzt ein unterbrochenes Übernehmen (commit) oder Abholen (pull) "
+"zurück.\n"
+"\n"
+" Der ungültige Status durch die Unterbrechung wird repariert. Dies "
+"sollte\n"
+" nur dann nötig sein, wenn eine Meldung von Mercurial es vorschlägt.\n"
+" "
+
+msgid ""
+"remove the specified files on the next commit\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history. -A/--after can be used to remove only\n"
+" files that have already been deleted, -f/--force can be used to\n"
+" force deletion, and -Af can be used to remove files from the next\n"
+" revision without deleting them.\n"
+"\n"
+" The following table details the behavior of remove for different\n"
+" file states (columns) and option combinations (rows). The file\n"
+" states are Added, Clean, Modified and Missing (as reported by hg\n"
+" status). The actions are Warn, Remove (from branch) and Delete\n"
+" (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+msgstr ""
+"Entfernt die angegebenen Dateien in der nächsten Version\n"
+"\n"
+" Merkt die benannten Dateien für die Entfernung aus dem Archiv vor.\n"
+"\n"
+" Dabei werden nur Dateien aus dem aktuellen Zweig gelöscht, nicht aus "
+"der\n"
+" gesamten Projekthistorie. Option -A kann genutzt werden, um Dateien zu\n"
+" entfernen, die bereits gelöscht wurden, -f kann genutzt werden, um die\n"
+" Löschung zu erzwingen. -AF entfernt Dateien aus der nächsten Revision,\n"
+" ohne sie zu löschen\n"
+"\n"
+" Die folgende Tabelle beschreibt detailliert das Verhalten von 'remove'\n"
+" für unterschiedliche Dateizustände (Spalten) und Optionskombinationen\n"
+" (Reihen). Die Dateizustände sind Hinzugefügt (A), Unverändert (C),\n"
+" Verändert (M) und Fehlend (!) (wie von 'hg status' angezeigt). Die\n"
+" Aktionen sind Warnen, Entfernen (aus dem Zweig) und Löschen\n"
+" (von der Festplatte).\n"
+"\n"
+" A C M !\n"
+" keine W EL W E\n"
+" -f E EL EL E\n"
+" -A W W W E\n"
+" -Af E E E E\n"
+"\n"
+" Die Dateien werden im Projektarchiv beim nächsten Übernehmen (commit)\n"
+" entfernt. Um diese Aktion vorher rückgängig zu machen, siehe 'hg "
+"revert'.\n"
+" "
+
+msgid "no files specified"
+msgstr "Keine Dateien angegeben"
+
+#, python-format
+msgid "not removing %s: file is untracked\n"
+msgstr "Entferne %s nicht: Datei ist nicht versioniert\n"
+
+#, python-format
+msgid "not removing %s: file %s (use -f to force removal)\n"
+msgstr "Entferne nicht %s: Datei %s (Nutze -f um Entfernung zu erzwingen)\n"
+
+msgid "still exists"
+msgstr "Existiert immernoch"
+
+msgid "is modified"
+msgstr "Ist modifiziert"
+
+msgid "has been marked for add"
+msgstr "Wurde als hinzugefügt markiert"
+
+msgid ""
+"rename files; equivalent of copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If dest\n"
+" is a directory, copies are put in that directory. If dest is a\n"
+" file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+"Benennt Dateien um; äquivalent zu \"copy\" und \"remove\"\n"
+"\n"
+" Erstellt das Ziel als neue Datei mit der Versionshistorie der Quelle.\n"
+" Die Quelle wird ausserdem als gelöscht markiert. Wenn mehrere Quellen\n"
+" angegeben sind, muss das Ziel ein Verzeichnis sein.\n"
+"\n"
+" Normalerweise kopiert dieser Befehl auch den Inhalt der Datei wie sie\n"
+" im Arbeitsverzeichnis vorliegt. Existiert das Ziel jedoch schon, so "
+"kann\n"
+" dieses durch Angabe der Option --after/-A als Kopie nachträglich "
+"markiert\n"
+" werden.\n"
+"\n"
+" Die neue Datei wird wie üblich nicht sofort übernommen, sondern "
+"existiert\n"
+" als lokale Änderung im Arbeitsverzeichnis. Die Umbenennung kann durch\n"
+" \"hg revert\" rückgängig gemacht werden.\n"
+" "
+
+msgid ""
+"retry file merges from a merge or update\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a/--all switch.\n"
+"\n"
+" If a conflict is resolved manually, please note that the changes\n"
+" will be overwritten if the merge is retried with resolve. The\n"
+" -m/--mark switch should be used to mark the file as resolved.\n"
+"\n"
+" This command will also allow listing resolved files and manually\n"
+" marking and unmarking files as resolved. All files must be marked\n"
+" as resolved before the new commits are permitted.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+msgstr ""
+"Wiederholt eine Dateizusammenführung oder Aktualisierung\n"
+"\n"
+" Der Prozess, zwei Versionen automatisch zusammenzuführen (nach "
+"expliziter\n"
+" Zusammenführung oder nach Aktualisierung mit lokalen Änderungen), wird\n"
+" erneut auf die ursprünglichen Versionen angewendet. Dies macht manuelle\n"
+" Versuche, den Konflikt zu lösen, rückgängig.\n"
+" Mit der Option -a/--all wird dies an allen markierten Dateien "
+"ausgeführt.\n"
+"\n"
+" Nach der automatischen Zusammenführung werden Konflikte intern markiert\n"
+" und erlauben kein Übernehmen der Änderungen, bis sie mit der Option\n"
+" -m/--mark als aufgelöst markiert werden.\n"
+"\n"
+" Der aktuelle Status wird mit -l/--list angezeigt. Die dabei verwendeten\n"
+" Zeichen bedeuten:\n"
+" U = noch konfliktbehaftet (unresolved)\n"
+" R = konfliktfrei (resolved)\n"
+" "
+
+msgid "too many options specified"
+msgstr "Zuviele Optionen angegeben"
+
+msgid "can't specify --all and patterns"
+msgstr "Verwende nicht --all gleichzeitig mit einem Dateimuster"
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr "Keine Dateien oder Verzeichnisse angegeben; nutze --all für alle"
+
+#, fuzzy
+msgid ""
+"restore individual files or directories to an earlier state\n"
+"\n"
+" (Use update -r to check out earlier revisions, revert does not\n"
+" change the working directory parents.)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r/--rev option, revert the given files or directories\n"
+" to their contents as of a specific revision. This can be helpful\n"
+" to \"roll back\" some or all of an earlier change. See 'hg help\n"
+" dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable mode\n"
+" of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+msgstr ""
+"Setzt gegebene Dateien oder Verzeichnisse auf frühere Version zurück\n"
+"\n"
+" (Im Gegensatz zu 'update -r' verändert 'revert' nicht die Angabe der\n"
+" Vorgängerversion des Arbeitsverzeichnisses)\n"
+"\n"
+" Ohne gegebene Revision wird der Inhalt der benannten Dateien oder\n"
+" Verzeichnisse auf die Vorgängerversion zurückgesetzt. Die betroffenen\n"
+" Dateien gelten danach wieder als unmodifiziert und nicht übernommene\n"
+" Hinzufügungen, Entfernungen, Kopien und Umbenennungen werden vergessen.\n"
+" Falls das Arbeitsverzeichnis zwei Vorgänger hat, muss eine Revision\n"
+" explizit angegeben werden.\n"
+"\n"
+" Mit der -r/--rev Option werden die Dateien oder Verzeichnisse auf die\n"
+" gegebene Revision zurückgesetzt. Auf diese Weise können ungewollte\n"
+" Änderungen rückgängig gemacht werden. Die betroffenen Dateien gelten "
+"dann\n"
+" als modifiziert (seit dem Vorgänger) und müssen per 'commit' als neue\n"
+" Revision übernommen werden. Siehe auch 'hg help dates' für erlaubte "
+"Formate\n"
+" der -d/--date Option.\n"
+"\n"
+" Eine gelöschte Datei wird wieder hergestellt. Wurde die Ausführbarkeit\n"
+" einer Datei verändert, wird auch dieser Wert zurückgesetzt.\n"
+"\n"
+" Nur die angegebenen Dateien und Verzeichnisse werden zurückgesetzt. "
+"Ohne\n"
+" Angabe werden keine Dateien verändert.\n"
+"\n"
+" Modifizierte Dateien werden vor der Änderung mit der Endung .orig\n"
+" gespeichert. Um dieses Backup zu verhindern, verwende --no-backup.\n"
+" "
+
+msgid "you can't specify a revision and a date"
+msgstr "ungültige Angabe von Revision und Datum gleichzeitig"
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr ""
+"keine Dateien oder Verzeichnisse angegeben; nutze --all um das gesamte "
+"Arbeitsverzeichnis zurückzusetzen"
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr "vergesse: %s\n"
+
+#, python-format
+msgid "reverting %s\n"
+msgstr "setze zurück: %s\n"
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr "stelle wieder her: %s\n"
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr "speichere aktuelle Version von %s als %s\n"
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr "Datei nicht unter Versionskontrolle: %s\n"
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr "keine Änderungen notwendig für %s\n"
+
+msgid ""
+"roll back the last transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+msgstr ""
+"Rollt die letzte Transaktion zurück\n"
+"\n"
+" Dieser Befehl muss mit Vorsicht verwendet werden. Es gibt keine ver-\n"
+" schachtelten Transaktionen und ein Rückrollen kann selber nicht "
+"rückgängig\n"
+" gemacht werden. Der aktuelle Status (dirstate) im .hg Verzeichnis wird\n"
+" auf die letzte Transaktion zurückgesetzt. Neuere Änderungen gehen damit\n"
+" verloren.\n"
+"\n"
+" Transaktionen werden verwendet um den Effekt aller Befehle, die "
+"Änderungs-\n"
+" sätze erstellen oder verteilen, zu kapseln. Die folgenden Befehle\n"
+" werden durch Transaktionen geschützt:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (mit diesem Archiv als Ziel)\n"
+" unbundle\n"
+"\n"
+" Dieser Befehl ist nicht für öffentliche Archive gedacht. Sobald "
+"Änderungen\n"
+" für Andere sichtbar sind ist ein Zurückrollen unnütz, da jemand sie "
+"bereits\n"
+" zu sich übertragen haben könnte. Weiterhin entsteht eine "
+"Wettlaufsituation,\n"
+" wenn beispielsweise ein Zurückrollen ausgeführt wird, während jemand "
+"anders\n"
+" ein 'pull' ausführt.\n"
+" "
+
+msgid ""
+"print the root (top) of the current working directory\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+msgstr ""
+"Gibt die Wurzel (top) des aktuellen Arbeitsverzeichnisses aus\n"
+"\n"
+" Gibt das Wurzelverzeichnis des aktuellen Arbeitsverzeichnisses aus.\n"
+" "
+
+#, fuzzy
+msgid ""
+"export the repository via HTTP\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+" files.\n"
+" "
+msgstr ""
+"Exportiert das Projektarchiv via HTTP\n"
+"\n"
+" Startet einen lokalen HTTP Archivbrowser und einen Pull-Server.\n"
+"\n"
+" Standardmäßig schreibt der Server Zugriffe auf die Standardausgabe\n"
+" und Fehler auf die Standardfehlerausgabe. Nutze die '-A' und '-E'\n"
+" Optionen, um die Ausgabe in Dateien umzulenken.\n"
+" "
+
+#, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr "Höre auf http://%s%s/%s (gebunden an %s:%d)\n"
+
+msgid ""
+"show changed files in the working directory\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" source of a copy/move operation, are not listed unless -c/--clean,\n"
+" -i/--ignored, -C/--copies or -A/--all is given. Unless options\n"
+" described with \"show only ...\" are given, the options -mardu are\n"
+" used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/--ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the difference between them is shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = missing (deleted by non-hg command, but still tracked)\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = the previous added file was copied from here\n"
+" "
+msgstr ""
+"Zeigt geänderte Dateien im Arbeitsverzeichnis\n"
+"\n"
+" Zeigt den Status von Dateien im Archiv an. Wenn eine Name übergeben\n"
+" wird, werden nur zutreffende Dateien angezeigt. Es werden keine Dateien\n"
+" angezeigt die unverändert, ignoriert oder Quelle einer Kopier/"
+"Verschiebe\n"
+" Operation sind, es sei denn -c (unverändert), -i (ignoriert), -C "
+"(Kopien)\n"
+" order -A wurde angegeben. Außer bei Angabe von Optionen, die mit "
+"\"Zeigt\n"
+" nur ...\" beschrieben werden, werden die Optionen -mardu genutzt.\n"
+"\n"
+" Die Option -q/--quiet blendet unüberwachte (unbekannte und ignorierte)\n"
+" Dateien aus, es sei denn sie werden explizit mit -u/--unknown oder \n"
+" -i/--ignored angefordert.\n"
+"\n"
+" HINWEIS: Der Status kann sich vom Diff unterscheiden, wenn sich\n"
+" Berechtigungen geändert haben oder eine Zusammenführung aufgetreten\n"
+" ist. Das Standard-Diff-Format zeigt keine Berechtigungsänderungen an "
+"und\n"
+" 'diff' zeigt nur Änderungen relativ zu einer Vorgängerversion einer\n"
+" Zusammenführung an.\n"
+"\n"
+" Bei Angabe einer Revision wird diese als Basisrevision genutzt.\n"
+" Bei Angabe zweier Revisionen werden die Unterschiede zwischen diesen\n"
+" beiden gezeigt.\n"
+"\n"
+" Die Kürzel zur Angabe des Status einer Datei sind:\n"
+" M = modifiziert\n"
+" A = hinzugefügt (added)\n"
+" R = entfernt (removed)\n"
+" C = unverändert (clean)\n"
+" ! = verschwunden (nicht durch einen hg-Befehl gelöscht, aber immer\n"
+" noch überwacht)\n"
+" ? = nicht überwacht\n"
+" I = ignoriert\n"
+" = die zuvor hinzugefügt Datei wurde von hier kopiert\n"
+" "
+
+msgid ""
+"add one or more tags for the current or given revision\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is\n"
+" used, or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"Setze ein oder mehrere Etiketten für die aktuelle oder gegebene Revision\n"
+"\n"
+" Benennt eine bestimmte Revision mit <name>.\n"
+"\n"
+" Etiketten sind nützlich um somit benannte Revisionen später in "
+"Vergleichen\n"
+" zu verwenden, in der Historie dorthin zurückzugehen oder wichtige "
+"Zweig-\n"
+" stellen zu markieren.\n"
+"\n"
+" Wenn keine Revision angegeben ist, wird der Vorgänger des Arbeits-\n"
+" verzeichnisses (oder - falls keines existiert - die Spitze) benannt.\n"
+"\n"
+" Um die Versionskontrolle, Verteilung und Zusammenführung von Etiketten\n"
+" möglich zu machen, werden sie in einer Datei '.hgtags' gespeichert, "
+"welche\n"
+" zusammen mit den anderen Projektdateien überwacht wird und manuell be-\n"
+" arbeitet werden kann. Lokale Etiketten (nicht mit anderen Archiven "
+"geteilt)\n"
+" liegen in der Datei .hg/localtags.\n"
+"\n"
+" Siehe auch 'hg help dates' für erlaubte Formate der -d/--date Option.\n"
+" "
+
+msgid "tag names must be unique"
+msgstr "Etikettnamen müssen einzigartig sein"
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr "der name '%s' ist reserviert"
+
+msgid "--rev and --remove are incompatible"
+msgstr "Die Optionen --rev und --remove sind inkompatibel"
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr "Etikett '%s' existiert nicht"
+
+#, python-format
+msgid "tag '%s' is not a global tag"
+msgstr "Etikett '%s' ist nicht global"
+
+#, python-format
+msgid "tag '%s' is not a local tag"
+msgstr "Etikett '%s' ist nicht lokal"
+
+#, python-format
+msgid "Removed tag %s"
+msgstr "Etikett %s entfernt"
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr "Etikett '%s' exitiert bereitsi; erzwinge mit -f/--force"
+
+#, python-format
+msgid "Added tag %s for changeset %s"
+msgstr "Etikett %s für Änderungssatz %s hinzugefügt"
+
+msgid ""
+"list repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose\n"
+" switch is used, a third column \"local\" is printed for local tags.\n"
+" "
+msgstr ""
+"Liste alle Etiketten des Archivs auf\n"
+"\n"
+" Listet sowohl globale wie auch lokale Etiketten auf. Mit dem Schalter -"
+"v/\n"
+" --verbose werden lokale in einer dritten Spalte als solche markiert.\n"
+" "
+
+msgid ""
+"show the tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the most\n"
+" recently added changeset in the repository, the most recently\n"
+" changed head.\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+msgstr ""
+"Zeigt die zuletzt übernommene Revision\n"
+"\n"
+" Die Spitze (tip) bezeichnet den zuletzt hinzugefügten Änderungssatz und\n"
+" damit den zuletzt geänderten Kopf.\n"
+"\n"
+" Nach einem Übernehmen mit commit wird die neue Revision die Spitze. "
+"Nach\n"
+" einem Holen mit pull wird die Spitze des anderen Archives übernommen.\n"
+" Als Etikettname ist 'tip' ein Spezialfall und kann nicht umbenannt oder\n"
+" manuell einem anderen Änderungssatz angehängt werden.\n"
+" "
+
+msgid ""
+"apply one or more changegroup files\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+msgstr ""
+"Wendet eine oder mehrere Änderungsgruppendateien an\n"
+"\n"
+" Die angegebenen Dateien müssen komprimierte Änderungsgruppen enthalten,\n"
+" wie sie durch den Befehl 'bundle' erzeugt werden\n"
+" "
+
+#, fuzzy
+msgid ""
+"update working directory\n"
+"\n"
+" Update the repository's working directory to the specified\n"
+" revision, or the tip of the current branch if none is specified.\n"
+" Use null as the revision to remove the working copy (like 'hg\n"
+" clone -U').\n"
+"\n"
+" When the working directory contains no uncommitted changes, it\n"
+" will be replaced by the state of the requested revision from the\n"
+" repository. When the requested revision is on a different branch,\n"
+" the working directory will additionally be switched to that\n"
+" branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C/--clean to\n"
+" discard them, forcibly replacing the state of the working\n"
+" directory with the requested revision.\n"
+"\n"
+" When there are uncommitted changes and option -C/--clean is not\n"
+" used, and the parent revision and requested revision are on the\n"
+" same branch, and one of them is an ancestor of the other, then the\n"
+" new working directory will contain the requested revision merged\n"
+" with the uncommitted changes. Otherwise, the update will fail with\n"
+" a suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use\n"
+" revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"Aktualisiert das Arbeitsverzeichnis\n"
+"\n"
+" Hebt das Arbeitsverzeichnis auf die angegebene Revision oder die\n"
+" Spitze des aktuellen Zweiges an, falls keine angegeben wurde.\n"
+" Bei der Verwendung von null als Revision wird die Arbeitskopie entfernt\n"
+" (wie 'hg clone -U').\n"
+"\n"
+" Wenn das Arbeitsverzeichnis keine unversionierten Änderungen enthält,\n"
+" wird es durch den Zustand der angeforderten Revision ersetzt. Sollte\n"
+" die angeforderte Revision aus einem anderen Zweig sein, wird das\n"
+" Arbeitsverzeichnis zusätzlich auf diesen Zweig umgestellt.\n"
+"\n"
+" Sollten unversionierte Änderungen vorliegen, muss -C genutzt werden,\n"
+" um sie zwangsweise mit dem Zustand des Arbeitsverzeichnis der\n"
+" angeforderten Revision zu ersetzen.\n"
+"\n"
+" Sollten unversionierte Änderungen vorliegen, -C nicht genutzt werden "
+"und\n"
+" die Vorgängerversion und die angeforderte Version sind auf dem selben\n"
+" Zweig und eine ist Vorläufer der anderen, dann wird das neue\n"
+" Arbeitsverzeichnis die angeforderte Revision in einer Zusammenführung\n"
+" mit den unversionierten Änderungen enthalten. Anderenfalls wird "
+"'update'\n"
+" fehlschlagen mit einem Hinweis 'merge' oder 'update -C' stattdessen zu\n"
+" nutzen.\n"
+"\n"
+" Sollte nur eine Datei auf eine ältere Revision angehoben werden, kann\n"
+" 'revert' genutzt werden.\n"
+"\n"
+" Siehe 'hg help dates' für eine Liste gültiger Formate für -d/--date.\n"
+" "
+
+msgid ""
+"verify the integrity of the repository\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+msgstr ""
+"Prüft die Integrität des Projektarchivs\n"
+"\n"
+" Führt eine umfassende Prüfung des aktuellen Proektarchivs durch, "
+"rechnet\n"
+" alle Prüfsummen in Historie, Manifest und überwachten Dateien nach.\n"
+" Auch die Integrität von Referenzen und Indizes wird geprüft.\n"
+" "
+
+msgid "output version and copyright information"
+msgstr "Gibt Version und Copyright Information aus"
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr ""
+
+msgid ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> und andere\n"
+"Dies ist freie Software; siehe Quellen für Kopierbestimmungen. Es besteht\n"
+"KEINE Gewährleistung für das Programm, nicht einmal der Marktreife oder der\n"
+"Verwendbarkeit für einen bestimmten Zweck.\n"
+
+msgid "repository root directory or symbolic path name"
+msgstr "Wurzel des Archivs oder symbolischer Pfadname"
+
+msgid "change working directory"
+msgstr "Wechselt das Arbeitsverzeichnis"
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr "Keine Abfragen, nimmt 'ja' für jede Nachfrage an"
+
+msgid "suppress output"
+msgstr "Unterdrückt Ausgabe"
+
+msgid "enable additional output"
+msgstr "Ausgabe weiterer Informationen"
+
+msgid "set/override config option"
+msgstr "Setzt/überschreibt Konfigurationsoptionen"
+
+msgid "enable debugging output"
+msgstr "Aktiviert Debugausgaben"
+
+msgid "start debugger"
+msgstr "Startet den Debugger"
+
+msgid "set the charset encoding"
+msgstr "Setzt die Zeichenkodierung"
+
+msgid "set the charset encoding mode"
+msgstr "Setzt den Modus der Zeichenkodierung"
+
+msgid "print traceback on exception"
+msgstr "Gibt die Aufrufhierarchie einer Ausnahmebedingung aus"
+
+msgid "time how long the command takes"
+msgstr "Gibt die Dauer des Befehls aus"
+
+msgid "print command execution profile"
+msgstr "Gibt das Ausführungsprofil des Befehls aus"
+
+msgid "output version information and exit"
+msgstr "Gibt Versionsinformation aus und beendet sich"
+
+msgid "display help and exit"
+msgstr "Gibt Hilfe aus und beendet sich"
+
+msgid "do not perform actions, just print output"
+msgstr "Führt die Aktionen nicht aus, sondern zeigt nur die Ausgabe"
+
+msgid "specify ssh command to use"
+msgstr "Spezifiziert den zu nutzenden SSH-Befehl"
+
+msgid "specify hg command to run on the remote side"
+msgstr "Spezifiziert den hg-Befehl, der entfernt ausgeführt wird"
+
+msgid "include names matching the given patterns"
+msgstr "Namen hinzufügen, die auf das angegebene Muster passen"
+
+msgid "exclude names matching the given patterns"
+msgstr "Namen ausschließen, die auf das angegebene Muster passen"
+
+msgid "use <text> as commit message"
+msgstr "Nutzt <text> als Versionsmeldung"
+
+msgid "read commit message from <file>"
+msgstr "Liest Versionsmeldung aus <datei>"
+
+msgid "record datecode as commit date"
+msgstr "Protokolliert Datumscode als Versionsdatum"
+
+msgid "record the specified user as committer"
+msgstr "Protokolliert den angegebenen Nutzer als Versionsersteller"
+
+msgid "display using template map file"
+msgstr "Anzeige unter Nutzung der Vorlagenzuordnungsdatei"
+
+msgid "display with template"
+msgstr "Anzeige mit Vorlage"
+
+msgid "do not show merges"
+msgstr "Zeigt keine Zusammenführungen"
+
+msgid "treat all files as text"
+msgstr "Behandelt alle Dateien als Text"
+
+msgid "don't include dates in diff headers"
+msgstr "Fügt Datum nicht im Kopf des Diff an"
+
+msgid "show which function each change is in"
+msgstr "Zeigt die Funktion, in der die Änderung passiert ist"
+
+msgid "ignore white space when comparing lines"
+msgstr "Ignoriert Leerzeichen beim Vergleich von Zeilen"
+
+msgid "ignore changes in the amount of white space"
+msgstr "Ignoriert Änderungen bei der Anzahl von Leerzeichen"
+
+msgid "ignore changes whose lines are all blank"
+msgstr "Ignoriert Änderungen, die nur aus Leerzeilen bestehen"
+
+msgid "number of lines of context to show"
+msgstr "Anzahl der anzuzeigenden Kontextzeilen"
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr "Bewertet ähnliche Dateien (0<=s<=100) als Umbenennung"
+
+msgid "[OPTION]... [FILE]..."
+msgstr "[OPTION]... [DATEI]..."
+
+msgid "annotate the specified revision"
+msgstr "Annotiert die angegebene Revision"
+
+msgid "follow file copies and renames"
+msgstr "Folgt Dateikopien und Umbenennungen"
+
+msgid "list the author (long with -v)"
+msgstr "Listet den Autor auf (lang mit -v)"
+
+msgid "list the date (short with -q)"
+msgstr "Listet das Datum auf (kurz mit -q)"
+
+msgid "list the revision number (default)"
+msgstr "Listet die Revisionsnummer auf (Standard)"
+
+msgid "list the changeset"
+msgstr "Listet den Änderungssatz auf"
+
+msgid "show line number at the first appearance"
+msgstr "Zeigt die Zeilennummer beim ersten Auftreten "
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] DATEI..."
+
+msgid "do not pass files through decoders"
+msgstr "Dateien nicht dekodieren"
+
+msgid "directory prefix for files in archive"
+msgstr "Verzeichnisprefix für Dateien im Archiv"
+
+msgid "revision to distribute"
+msgstr "zu verteilende Revision"
+
+msgid "type of distribution to create"
+msgstr "zu erstellender Distributionstyp"
+
+msgid "[OPTION]... DEST"
+msgstr "[OPTION]... ZIEL"
+
+msgid "merge with old dirstate parent after backout"
+msgstr "Führt mit Vorgänger im Status vor Rücknahme zusammen"
+
+msgid "parent to choose when backing out merge"
+msgstr "Wählt einen Vorgänger bei Rücknahme einer Zusammenführung"
+
+msgid "revision to backout"
+msgstr "Die Zurückzunehmende Revision"
+
+msgid "[OPTION]... [-r] REV"
+msgstr ""
+
+msgid "reset bisect state"
+msgstr "Setzt Status der Suche zurück"
+
+msgid "mark changeset good"
+msgstr "Markiert Änderungssatz als fehlerfrei"
+
+msgid "mark changeset bad"
+msgstr "Markiert Änderungssatz als fehlerbehaftet"
+
+msgid "skip testing changeset"
+msgstr "Überspringt das Testen dieses Änderungssatzes"
+
+msgid "use command to check changeset state"
+msgstr "Nutzt eine Programm um den Fehlerstatus zu bestimmen"
+
+msgid "do not update to target"
+msgstr "Führe keine Aktualisierung der Dateien durch"
+
+msgid "[-gbsr] [-c CMD] [REV]"
+msgstr "[-gbsr] [-c PROGRAMM] [REV]"
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr "Setzt Zweignamen, selbst wenn es bestehenden Zweig verschattet"
+
+msgid "reset branch name to parent branch name"
+msgstr "Setzt Zweignamen zum Namen des Vorgängers zurück"
+
+msgid "[-fC] [NAME]"
+msgstr ""
+
+msgid "show only branches that have unmerged heads"
+msgstr "Zeigt nur Zweige mit mehreren Köpfen"
+
+msgid "[-a]"
+msgstr ""
+
+msgid "run even when remote repository is unrelated"
+msgstr "Auch ausführen wenn das entfernte Archiv keinen Bezug hat"
+
+msgid "a changeset up to which you would like to bundle"
+msgstr "Der Änderungssatz bis zu dem gruppiert werden soll"
+
+msgid "a base changeset to specify instead of a destination"
+msgstr "Ein Basisänderungssatz anstelle eines Ziels"
+
+msgid "bundle all changesets in the repository"
+msgstr "Gruppiert alle Änderungssätze des Archivs"
+
+msgid "bundle compression type to use"
+msgstr "Kompressionstyp für die Ausgabedatei"
+
+msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr "[-f] [-a] [-r REV]... [--base REV]... DATEI [ZIEL]"
+
+msgid "print output to file with formatted name"
+msgstr "Schreibt Ausgabe in Datei mit formatiertem Namen"
+
+msgid "print the given revision"
+msgstr "Gibt die gegebene Revision aus"
+
+msgid "apply any matching decode filter"
+msgstr "Führt alle passenden Dekodier-Filter aus"
+
+msgid "[OPTION]... FILE..."
+msgstr "[OPTION]... DATEI..."
+
+msgid "the clone will only contain a repository (no working copy)"
+msgstr "Der Klon wird nur das Archiv enthalten (keine Arbeitskopie)"
+
+msgid "a changeset you would like to have after cloning"
+msgstr "Der Änderungssatz, der nach dem Klonen vorhanden sein soll"
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr "[OPTION]... QUELLE [ZIEL]"
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr "Markiert neue/fehlende Dateien als hinzugefügt/entfernt"
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr "Markiert einen Zweig als beendet und blendet ihn in der Zweigliste aus"
+
+msgid "record a copy that has already occurred"
+msgstr "Identifiziert eine Kopie, die bereits stattgefunden hat"
+
+msgid "forcibly copy over an existing managed file"
+msgstr "Erzwingt ein Überschreiben des Kopierziels"
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr "[OPTION]... [QUELLE]... ZIEL"
+
+msgid "[INDEX] REV1 REV2"
+msgstr ""
+
+msgid "[COMMAND]"
+msgstr "[BEFEHL]"
+
+msgid "show the command options"
+msgstr "Zeigt alle Optionen des Befehls"
+
+msgid "[-o] CMD"
+msgstr "[-o] BEFEHL"
+
+msgid "try extended date formats"
+msgstr "Erlaubt erweiterte Datumsformate"
+
+msgid "[-e] DATE [RANGE]"
+msgstr "[-e] DATUM [PRÜFDATUM]"
+
+msgid "FILE REV"
+msgstr "DATEI REV"
+
+msgid "[PATH]"
+msgstr "[PFAD]"
+
+msgid "FILE"
+msgstr "DATEI"
+
+msgid "revision to rebuild to"
+msgstr "Basisrevision für die Änderungen"
+
+msgid "[-r REV] [REV]"
+msgstr ""
+
+msgid "revision to debug"
+msgstr ""
+
+msgid "[-r REV] FILE"
+msgstr "[-r REV] DATEI"
+
+msgid "REV1 [REV2]"
+msgstr ""
+
+msgid "do not display the saved mtime"
+msgstr "Zeigt gespeicherte Modifikationszeit nicht an"
+
+msgid "[OPTION]..."
+msgstr ""
+
+msgid "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+msgstr "[OPTION]... [-r REV1 [-r REV2]] [DATEI]..."
+
+msgid "diff against the second parent"
+msgstr "Vergleicht mit der zweiten Vorgängerversion"
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr "[OPTION]... [-o DATEINAMENMUSTER] REV..."
+
+msgid "end fields with NUL"
+msgstr "Trennt Einträge mit NULL statt Leerzeichen"
+
+msgid "print all revisions that match"
+msgstr "Zeigt alle zutreffenden Revisionen"
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr ""
+"Folgt der Versionshistorie oder Dateihistorie über Kopien und Umbenennungen "
+"hinweg"
+
+msgid "ignore case when matching"
+msgstr "Ignoriert Groß- und Kleinschreibung"
+
+msgid "print only filenames and revisions that match"
+msgstr "Zeigt nur zutreffende Dateinamen und Revisionen"
+
+msgid "print matching line numbers"
+msgstr "Zeigt zutreffende Zeilennummern"
+
+msgid "search in given revision range"
+msgstr "Sucht in gegebenem Revisionsintervall"
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr "[OPTION]... MUSTER [DATEI]..."
+
+msgid "show only heads which are descendants of REV"
+msgstr "Zeigt nur Köpfe, die Nachkommen dieser Revision sind"
+
+msgid "show only the active heads from open branches"
+msgstr "Zeigt nur aktive Köpfe von offenen Zweigen"
+
+msgid "show normal and closed heads"
+msgstr "Zeigt normale und abgeschlossene Kopfversionen"
+
+msgid "[-r REV] [REV]..."
+msgstr ""
+
+msgid "[TOPIC]"
+msgstr "[THEMA]"
+
+msgid "identify the specified revision"
+msgstr "Identifiziert die angegebene Revision"
+
+msgid "show local revision number"
+msgstr "Zeigt die lokale Revisionsnummer"
+
+msgid "show global revision id"
+msgstr "Zeigt die globale Revisions-ID"
+
+msgid "show branch"
+msgstr "Zeigt gegebenen Zweig"
+
+msgid "show tags"
+msgstr "Zeigt Etiketten"
+
+msgid "[-nibt] [-r REV] [SOURCE]"
+msgstr "[-nibt] [-r REV] [QUELLE]"
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr ""
+"Entfernt führende Verzeichnisnamen. Dies hat dieselbe Bedeutung wie die "
+"gleichnamige Option von patch"
+
+msgid "base path"
+msgstr "Basispfad"
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr "Erzwingt trotz lokaler Änderungen im Arbeitsverzeichnis"
+
+msgid "don't commit, just update the working directory"
+msgstr "Kein Übernehmen, nur Aktualisierung des Arbeitsverzeichnisses"
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr "Wendet patch auf die Knoten an, von denen er erstellt wurde"
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr ""
+
+msgid "[OPTION]... PATCH..."
+msgstr ""
+
+msgid "show newest record first"
+msgstr "Zeigt neuste Änderung zuerst"
+
+msgid "file to store the bundles into"
+msgstr "Dateiname zum Zwischenspeichern"
+
+msgid "a specific revision up to which you would like to pull"
+msgstr "eine bestimmte Revision bis zu der geholt werden soll"
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr "[-p] [-n] [-M] [-f] [-r REV]... [--bundle DATEINAME] [QUELLE]"
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr ""
+
+msgid "search the repository as it stood at REV"
+msgstr "Durchsucht nur die Revision REV"
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr "Beendet Dateinamen mit NUL zur Nutzung mit xargs"
+
+msgid "print complete paths from the filesystem root"
+msgstr "Gibt absolute Dateinamen aus"
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr "[OPTION]... [MUSTER]..."
+
+msgid "only follow the first parent of merge changesets"
+msgstr "Folgt nur dem ersten Vorgänger einer Zusammenführungsversion"
+
+msgid "show revisions matching date spec"
+msgstr "Zeigt Revisionen passend zur Datums-Spezifikation"
+
+msgid "show copied files"
+msgstr "Zeigt kopierte Dateien"
+
+msgid "do case-insensitive search for a keyword"
+msgstr "Sucht unabhängig von Groß- und Kleinschreibung ein Stichwort"
+
+msgid "include revisions where files were removed"
+msgstr "Revisionen hinzufügen, in denen Dateien entfernt wurden"
+
+msgid "show only merges"
+msgstr "Zeigt nur Zusammenführungen"
+
+msgid "revisions committed by user"
+msgstr "Revisionen erzeugt vom Nutzer"
+
+msgid "show only changesets within the given named branch"
+msgstr "Zeigt nur Änderungssätze innerhalb des angegebenen Zweigs"
+
+msgid "do not display revision or any of its ancestors"
+msgstr "Gibt weder diese Revision noch ihre Nachfolger aus"
+
+msgid "[OPTION]... [FILE]"
+msgstr "[OPTION]... [DATEI]"
+
+msgid "revision to display"
+msgstr "Auszugebende Revision"
+
+msgid "[-r REV]"
+msgstr ""
+
+msgid "force a merge with outstanding changes"
+msgstr "Erzwingt eine Zusammenführung mit den ausstehenden Änderungen"
+
+msgid "revision to merge"
+msgstr "Zusammenzuführende Revision"
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr ""
+
+msgid "[-f] [[-r] REV]"
+msgstr ""
+
+msgid "a specific revision up to which you would like to push"
+msgstr "eine bestimmte Revision bis zu der ausgeliefert werden soll"
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr "[-M] [-p] [-n] [-f] [-r REV]... [ZIEL]"
+
+msgid "show parents from the specified revision"
+msgstr "Zeigt die Vorgänger der angegeben Revision"
+
+msgid "[-r REV] [FILE]"
+msgstr "[-r REV] [DATEI]"
+
+msgid "[NAME]"
+msgstr ""
+
+msgid "update to new tip if changesets were pulled"
+msgstr "Auf die neue Spitze (tip) anheben, falls Änderungssätze geholt wurden"
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [QUELLE]"
+
+msgid "force push"
+msgstr "Erzwingt Auslieferung"
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [ZIEL]"
+
+msgid "record delete for missing files"
+msgstr "Protokolliert die Löschung fehlender Dateien"
+
+msgid "remove (and delete) file even if added or modified"
+msgstr "Entfernt (und löscht) Datei sogar wenn hinzugefügt oder modifiziert"
+
+msgid "record a rename that has already occurred"
+msgstr ""
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr "[OPTION]... QUELLE... ZIEL"
+
+msgid "remerge all unresolved files"
+msgstr "Wiederhole automatische Zusammenführung"
+
+msgid "list state of files needing merge"
+msgstr "Zeigt Dateien, deren automatische Zusammenführung fehlschlug"
+
+msgid "mark files as resolved"
+msgstr "Markiert eine Datei als konfliktfrei"
+
+msgid "unmark files as resolved"
+msgstr "Markiert eine Datei als konfliktbehaftet"
+
+msgid "revert all changes when no arguments given"
+msgstr "Nimmt alle lokalen Änderungen zurück (ohne andere Parameter)"
+
+msgid "tipmost revision matching date"
+msgstr "der Spitze (tip) nächste Revision mit passendem Datum"
+
+msgid "revision to revert to"
+msgstr "Revision, bis zu der Änderungen zurückgenommen werden"
+
+msgid "do not save backup copies of files"
+msgstr "Keine Sicherheitskopien (.orig) anlegen"
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr ""
+
+msgid "name of access log file to write to"
+msgstr "Name der Zugriffs-Logdatei"
+
+msgid "name of error log file to write to"
+msgstr "Name der Fehler-Logdatei"
+
+msgid "port to listen on (default: 8000)"
+msgstr "Port auf dem gehorcht wird (Standard: 8000)"
+
+msgid "address to listen on (default: all interfaces)"
+msgstr "Adresse auf der gehorcht wird (Standard: alle Schnittstellen)"
+
+msgid "prefix path to serve from (default: server root)"
+msgstr "Pfadpräfix von dem ausgeliefert wird (Standard: Serverwurzel '/')"
+
+msgid "name to show in web pages (default: working directory)"
+msgstr ""
+"Name der auf der Webseite angezeigt wird (Standard: Arbeitsverzeichnis)"
+
+msgid "name of the webdir config file (serve more than one repository)"
+msgstr "Name der webdir-Konfigurationsdatei (mehr als ein Archiv ausliefern)"
+
+msgid "for remote clients"
+msgstr "für entfernte Klienten"
+
+msgid "web templates to use"
+msgstr "Zu nutzende Web-Vorlagen"
+
+msgid "template style to use"
+msgstr "Zu verwendender Stil"
+
+msgid "use IPv6 in addition to IPv4"
+msgstr "Nutzt IPv6 zusätzlich zu IPv4"
+
+msgid "SSL certificate file"
+msgstr "SSL Zertifikatsdatei"
+
+msgid "show untrusted configuration options"
+msgstr ""
+
+msgid "[-u] [NAME]..."
+msgstr ""
+
+msgid "show status of all files"
+msgstr "Zeigt den Status aller Dateien"
+
+msgid "show only modified files"
+msgstr "Zeigt nur modifizierte Dateien"
+
+msgid "show only added files"
+msgstr "Zeigt nur hinzugefügte Dateien"
+
+msgid "show only removed files"
+msgstr "Zeigt nur entfernte Dateien"
+
+msgid "show only deleted (but tracked) files"
+msgstr "Zeigt nur gelöschte (aber überwachte) Dateien"
+
+msgid "show only files without changes"
+msgstr "Zeigt nur Dateien ohne Änderungen"
+
+msgid "show only unknown (not tracked) files"
+msgstr "Zeigt nur unbekannte (nicht überwachte) Dateien"
+
+msgid "show only ignored files"
+msgstr "Zeigt nur ignorierte Dateien"
+
+msgid "hide status prefix"
+msgstr "Verdeckt den Status-Präfix"
+
+msgid "show source of copied files"
+msgstr "Zeigt die Quelle von kopierten Dateien"
+
+msgid "show difference from revision"
+msgstr "Zeigt die Differenz zu einer Revision"
+
+msgid "replace existing tag"
+msgstr "Ersetzt bereits gesetztes Etikett"
+
+msgid "make the tag local"
+msgstr "Etikett wird nur lokal gesetzt"
+
+msgid "revision to tag"
+msgstr "Zu etikettierende Revision"
+
+msgid "remove a tag"
+msgstr "Entfernt ein Etikett"
+
+msgid "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr "[-l] [-m TEXT] [-d DATUM] [-u BENUTZER] [-r REV] NAME..."
+
+msgid "[-p]"
+msgstr ""
+
+msgid "update to new tip if changesets were unbundled"
+msgstr "Aktualisiert das Arbeitsverzeichnis auf die neue Spitze"
+
+msgid "[-u] FILE..."
+msgstr "[-u] DATEI..."
+
+msgid "overwrite locally modified files (no backup)"
+msgstr "Überschreibt lokale Modifikationen von Dateien (keine Sicherung)"
+
+msgid "[-C] [-d DATE] [[-r] REV]"
+msgstr "[-C] [-d DATUM] [[-r] REV]"
+
+#, python-format
+msgid "config error at %s:%d: '%s'"
+msgstr ""
+
+msgid "not found in manifest"
+msgstr "nicht im Manifest gefunden"
+
+msgid "branch name not in UTF-8!"
+msgstr "Name der Verzweigung nicht in UTF-8!"
+
+#, python-format
+msgid " searching for copies back to rev %d\n"
+msgstr " suche Kopien in Revisionen bis %d\n"
+
+#, python-format
+msgid ""
+" unmatched files in local:\n"
+" %s\n"
+msgstr ""
+" Dateien nur in lokaler Version:\n"
+" %s\n"
+
+#, python-format
+msgid ""
+" unmatched files in other:\n"
+" %s\n"
+msgstr ""
+" Dateien nur in anderer Version:\n"
+" %s\n"
+
+msgid " all copies found (* = to merge, ! = divergent):\n"
+msgstr " alle Kopien gefunden (* = zusammenzuführen, ! = abweichend):\n"
+
+msgid " checking for directory renames\n"
+msgstr " suche Umbenennungen von Verzeichnissen\n"
+
+#, python-format
+msgid " dir %s -> %s\n"
+msgstr " Verzeichnis %s -> %s\n"
+
+#, python-format
+msgid " file %s -> %s\n"
+msgstr " Datei %s -> %s\n"
+
+msgid "working directory state appears damaged!"
+msgstr "Status des Arbeitsverzeichnis scheint beschädigt zu sein!"
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr "'\\n' und '\\r' sind nicht in Dateinamen erlaubt: %r"
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr "Verzeichnis %r ist bereits im dirstate"
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr "Datei %r im dirstate steht im Konflikt mit %r"
+
+#, python-format
+msgid "not in dirstate: %s\n"
+msgstr "nicht im dirstate: %s\n"
+
+msgid "unknown"
+msgstr "Unbekannt"
+
+msgid "character device"
+msgstr "Zeichenorientiertes Gerät"
+
+msgid "block device"
+msgstr "Blockorientiertes Gerät"
+
+msgid "fifo"
+msgstr "FIFO"
+
+msgid "socket"
+msgstr "Sockel"
+
+msgid "directory"
+msgstr "Verzeichnis"
+
+#, python-format
+msgid "unsupported file type (type is %s)"
+msgstr "nicht unterstützter Dateityp (Typ %s)"
+
+#, python-format
+msgid "abort: %s\n"
+msgstr "Abbruch: %s\n"
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+" %s\n"
+msgstr ""
+"hg: Kommando '%s' ist mehrdeutig:\n"
+" %s\n"
+
+#, python-format
+msgid "hg: %s\n"
+msgstr ""
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr "Zeitüberschreitung beim Warten auf %s"
+
+#, python-format
+msgid "lock held by %s"
+msgstr "Zur Zeit von %s reserviert"
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr "Abbruch: %s: %s\n"
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr "Abbruch: Kann %s nicht reservieren: %s\n"
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr "Abbruch: %s!\n"
+
+#, python-format
+msgid "abort: %s"
+msgstr "Abbruch: %s"
+
+msgid " empty string\n"
+msgstr " leere Zeichenkette\n"
+
+msgid "killed!\n"
+msgstr " getötet!\n"
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr "hg: unbekanntes Kommando '%s'\n"
+
+#, python-format
+msgid "abort: could not import module %s!\n"
+msgstr "Abbruch: Kann Modul %s nicht importieren!\n"
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr "(Erweiterungen nicht compiliert?)\n"
+
+msgid "(is your Python install correct?)\n"
+msgstr "(Python Installation korrekt?)\n"
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr "Abbruch: Fehler: %s\n"
+
+msgid "broken pipe\n"
+msgstr "Datenübergabe unterbrochen\n"
+
+msgid "interrupted!\n"
+msgstr "unterbrochen!\n"
+
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+"\n"
+"Datenübergabe unterbrochen\n"
+
+msgid "abort: out of memory\n"
+msgstr "Abbruch: Unzureichender Speicherplatz\n"
+
+msgid "** unknown exception encountered, details follow\n"
+msgstr "** Unbekannter Fehler, Details folgen\n"
+
+msgid "** report bug details to http://www.selenic.com/mercurial/bts\n"
+msgstr "** Problemdetails bitte bei http://www.selenic.com/mercurial/bts\n"
+
+msgid "** or mercurial@selenic.com\n"
+msgstr "** oder mercurial@selenic.com melden\n"
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr ""
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr "** Erweiterungen geladen: %s\n"
+
+#, python-format
+msgid "no definition for alias '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' resolves to unknown command '%s'\n"
+msgstr "Alias '%s' verweist auf unbekannten Befehl '%s'\n"
+
+#, python-format
+msgid "alias '%s' resolves to ambiguous command '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' shadows command\n"
+msgstr "Alias '%s' verdeckt einen Befehl\n"
+
+#, python-format
+msgid "malformed --config option: %s"
+msgstr "missgebildete --config Option: %s"
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr "Erweiterung '%s' überschreibt die Kommandos: %s\n"
+
+msgid "Option --config may not be abbreviated!"
+msgstr "Option --config kann nicht abgekürzt werden!"
+
+msgid "Option --cwd may not be abbreviated!"
+msgstr "Option --cwd kann nicht abgekürzt werden!"
+
+msgid ""
+"Option -R has to be separated from other options (i.e. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr ""
+"Option -R muss von anderen Optionen getrennt werden (also z.B. nicht -qR) "
+"und --repository kann nur als --repo abgekürzt werden!"
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr ""
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr "Projektarchiv '%s' is nicht lokal"
+
+msgid "invalid arguments"
+msgstr "ungültige Parameter"
+
+#, python-format
+msgid "unrecognized profiling format '%s' - Ignored\n"
+msgstr ""
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr ""
+
+#, python-format
+msgid "picked tool '%s' for %s (binary %s symlink %s)\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+
+msgid "&Local"
+msgstr ""
+
+msgid "&Other"
+msgstr ""
+
+msgid "l"
+msgstr ""
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "my %s other %s ancestor %s\n"
+msgstr ""
+
+msgid " premerge successful\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+
+msgid "&No"
+msgstr ""
+
+msgid "&Yes"
+msgstr ""
+
+msgid "n"
+msgstr ""
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr ""
+
+#, python-format
+msgid "Inconsistent state, %s:%s is good and bad"
+msgstr ""
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr ""
+
+msgid "Date Formats"
+msgstr "Datumsformate"
+
+msgid ""
+"\n"
+" Some commands allow the user to specify a date, e.g.:\n"
+" * backout, commit, import, tag: Specify the commit date.\n"
+" * log, revert, update: Select revision(s) by date.\n"
+"\n"
+" Many date formats are valid. Here are some examples:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n"
+" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n"
+" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n"
+" \"Dec 6\" (midnight)\n"
+" \"13:18\" (today assumed)\n"
+" \"3:39\" (3:39AM assumed)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Lastly, there is Mercurial's internal format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" This is the internal representation format for dates. unixtime is\n"
+" the number of seconds since the epoch (1970-01-01 00:00 UTC).\n"
+" offset is the offset of the local timezone, in seconds west of UTC\n"
+" (negative if the timezone is east of UTC).\n"
+"\n"
+" The log command also accepts date ranges:\n"
+"\n"
+" \"<{datetime}\" - at or before a given date/time\n"
+" \">{datetime}\" - on or after a given date/time\n"
+" \"{datetime} to {datetime}\" - a date range, inclusive\n"
+" \"-{days}\" - within a given number of days of today\n"
+" "
+msgstr ""
+"\n"
+" Einige Befehle erlauben dem Benuter ein Datum anzugeben, z.B.:\n"
+" * backout, commit, import, tag: Angabe des Versionsdatums.\n"
+" * log, revert, update: Selektion von Revisionen anhand ihres Datums.\n"
+"\n"
+" Viele Datumsformate sind erlaubt. Hier einige Beispiele:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (Lokale Zeitzone angenommen)\n"
+" \"Dec 6 13:18 -0600\" (Jahr angenommen, Zeitverschiebung angegeben)\n"
+" \"Dec 6 13:18 UTC\" (UTC und GMT sind Aliase für +0000)\n"
+" \"Dec 6\" (Mitternacht)\n"
+" \"13:18\" (Heute angenommen)\n"
+" \"3:39\" (3:39 morgens angenommen)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Schließlich gibt es Mercurials internes Format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" Dies ist das internationale Darstellungsformat für Daten. Die Unixzeit "
+"(unixtime) ist\n"
+" die Anzahl von Sekunden seit der UNIX Epoche (1970-01-01 00:00 UTC). "
+"Abgesetzt davon\n"
+" steht die Verschiebung zur lokalen Zeitzone in Sekunden westlich der UTC "
+"(negativ\n"
+" wenn die Zeitzone östlich der UTC ist).\n"
+"\n"
+" Der log-Befehl akkzeptiert auch Datumsbereiche:\n"
+"\n"
+" \"<{datetime}\" - an oder vor einem/r angegebenen Datum/Uhrzeit\n"
+" \">{datetime}\" - zu oder nach einem/r angegebenen Datum/Uhrzeit\n"
+" \"{datetime} to {datetime}\" - ein Datumsbereich, inklusive\n"
+" \"-{tage}\" - innerhalb der angegebenen Anzahl von Tagen vor dem "
+"heutigen Tag\n"
+" "
+
+msgid "File Name Patterns"
+msgstr "Dateimuster"
+
+msgid ""
+"\n"
+" Mercurial accepts several notations for identifying one or more\n"
+" files at a time.\n"
+"\n"
+" By default, Mercurial treats filenames as shell-style extended\n"
+" glob patterns.\n"
+"\n"
+" Alternate pattern notations must be specified explicitly.\n"
+"\n"
+" To use a plain path name without any pattern matching, start it\n"
+" with \"path:\". These path names must completely match starting at\n"
+" the current repository root.\n"
+"\n"
+" To use an extended glob, start a name with \"glob:\". Globs are\n"
+" rooted at the current directory; a glob such as \"*.c\" will only\n"
+" match files in the current directory ending with \".c\".\n"
+"\n"
+" The supported glob syntax extensions are \"**\" to match any string\n"
+" across path separators and \"{a,b}\" to mean \"a or b\".\n"
+"\n"
+" To use a Perl/Python regular expression, start a name with \"re:\".\n"
+" Regexp pattern matching is anchored at the root of the repository.\n"
+"\n"
+" Plain examples:\n"
+"\n"
+" path:foo/bar a name bar in a directory named foo in the root of\n"
+" the repository\n"
+" path:path:name a file or directory named \"path:name\"\n"
+"\n"
+" Glob examples:\n"
+"\n"
+" glob:*.c any name ending in \".c\" in the current directory\n"
+" *.c any name ending in \".c\" in the current directory\n"
+" **.c any name ending in \".c\" in any subdirectory of the\n"
+" current directory including itself.\n"
+" foo/*.c any name ending in \".c\" in the directory foo\n"
+" foo/**.c any name ending in \".c\" in any subdirectory of foo\n"
+" including itself.\n"
+"\n"
+" Regexp examples:\n"
+"\n"
+" re:.*\\.c$ any name ending in \".c\", anywhere in the repository\n"
+"\n"
+" "
+msgstr ""
+"\n"
+" Mercurial akkzeptiert verschiedene Schreibweisen zur Identifikation "
+"einer oder\n"
+" mehrerer Dateien gleichzeitig.\n"
+"\n"
+" Standardmäßig behandelt Mercurial Dateinamen wie erweiterte \"Glob\"-"
+"Muster der\n"
+" Shell (shell-style extended glob patterns).\n"
+"\n"
+" Andere Schreibweisen von Mustern müssen explizit angegeben werden.\n"
+"\n"
+" Um einen Dateipfad ohne Mustererkennung zu suchen, beginne mit\n"
+" \"path:\". Dies Pfadnamen müssen komplett übereinstimmen beginnend ab\n"
+" der aktuellen Wurzel des Projektarchivs.\n"
+"\n"
+" Um erweiterete Glob-Muster zu nutzen, muss das Muster mit \"glob:\" "
+"beginnen.\n"
+" Globs sind am aktuellen Verzeichnis verankert; ein Glob-Muster wie \"*.c"
+"\" stimmt nur\n"
+" mit Dateien im aktuellen Verzeichnis überein, die mit \".c\" enden.\n"
+"\n"
+" Die unterstützen Erweiterungen der Glob-Syntax sind \"**\" zur "
+"Übereinstimmung mit\n"
+" Zeichenketten über Pfadtrenner hinweg und \"{a,b}\" in der Bedeutung \"a "
+"oder b\".\n"
+"\n"
+" Zur Nutzung von regulären Ausdrücken (Perl/Python) beginne einen Namen "
+"mit \"re:\".\n"
+" Erkennung mit regulären Ausdrücken wird an der Wurzel des Projektarchivs "
+"verankert.\n"
+"\n"
+" Pfad-Beispiele:\n"
+"\n"
+" path:foo/bar eine Datei bar in einem Verzeichnis foo an der Basis des\n"
+" des Projektarchivs\n"
+" path:path:name eine Datei oder eine Verzeichnis mit dem Namen \"path:name"
+"\"\n"
+"\n"
+" Glob-Beispiele:\n"
+"\n"
+" glob:*.c jeder Name endend mit \".c\" im aktuellen Verzeichnis\n"
+" *.c jeder Name endend mit \".c\" im aktuellen Verzeichnis\n"
+" **.c jeder Name endend mit \".c\" im aktuellen Verzeichnis "
+"und\n"
+" jedem Unterverzeichnis\n"
+" foo/*.c jeder Name endend mit \".c\" im Verzeichnis foo\n"
+" foo/**.c jeder Name endend mit \".c\" im Verzeichnis foo und "
+"jedem\n"
+" Unterverzeichnis.\n"
+"\n"
+" Reguläre Ausdrücke Beispiele::\n"
+"\n"
+" re:.*\\.c$ jeder Name endend mit \".c\" überall im Projektarchiv\n"
+"\n"
+" "
+
+msgid "Environment Variables"
+msgstr "Umgebungsvariablen"
+
+msgid ""
+"\n"
+"HG::\n"
+" Path to the 'hg' executable, automatically passed when running\n"
+" hooks, extensions or external tools. If unset or empty, this is\n"
+" the hg executable's name if it's frozen, or an executable named\n"
+" 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+" Windows) is searched.\n"
+"\n"
+"HGEDITOR::\n"
+" This is the name of the editor to run when committing. See EDITOR.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" This overrides the default locale setting detected by Mercurial.\n"
+" This setting is used to convert data including usernames,\n"
+" changeset descriptions, tag names, and branches. This setting can\n"
+" be overridden with the --encoding command-line option.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" This sets Mercurial's behavior for handling unknown characters\n"
+" while transcoding user input. The default is \"strict\", which\n"
+" causes Mercurial to abort if it can't map a character. Other\n"
+" settings include \"replace\", which replaces unknown characters, and\n"
+" \"ignore\", which drops them. This setting can be overridden with\n"
+" the --encodingmode command-line option.\n"
+"\n"
+"HGMERGE::\n"
+" An executable to use for resolving merge conflicts. The program\n"
+" will be executed with three arguments: local file, remote file,\n"
+" ancestor file.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" A list of files or directories to search for hgrc files. Item\n"
+" separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
+" platform default search path is used. If empty, only the .hg/hgrc\n"
+" from the current repository is read.\n"
+"\n"
+" For each element in HGRCPATH:\n"
+" * if it's a directory, all files ending with .rc are added\n"
+" * otherwise, the file itself will be added\n"
+"\n"
+"HGUSER::\n"
+" This is the string used as the author of a commit. If not set,\n"
+" available values will be considered in this order:\n"
+"\n"
+" * HGUSER (deprecated)\n"
+" * hgrc files from the HGRCPATH\n"
+" * EMAIL\n"
+" * interactive prompt\n"
+" * LOGNAME (with '@hostname' appended)\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"LOGNAME::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"VISUAL::\n"
+" This is the name of the editor to use when committing. See EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Sometimes Mercurial needs to open a text file in an editor for a\n"
+" user to modify, for example when writing commit messages. The\n"
+" editor it uses is determined by looking at the environment\n"
+" variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+" non-empty one is chosen. If all of them are empty, the editor\n"
+" defaults to 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" This is used by Python to find imported modules and may need to be\n"
+" set appropriately if this Mercurial is not installed system-wide.\n"
+" "
+msgstr ""
+
+msgid "Specifying Single Revisions"
+msgstr "Angabe Einzelner Revisionen"
+
+msgid ""
+"\n"
+" Mercurial supports several ways to specify individual revisions.\n"
+"\n"
+" A plain integer is treated as a revision number. Negative integers\n"
+" are treated as topological offsets from the tip, with -1 denoting\n"
+" the tip. As such, negative numbers are only useful if you've\n"
+" memorized your local tree numbers and want to save typing a single\n"
+" digit. This editor suggests copy and paste.\n"
+"\n"
+" A 40-digit hexadecimal string is treated as a unique revision\n"
+" identifier.\n"
+"\n"
+" A hexadecimal string less than 40 characters long is treated as a\n"
+" unique revision identifier, and referred to as a short-form\n"
+" identifier. A short-form identifier is only valid if it is the\n"
+" prefix of exactly one full-length identifier.\n"
+"\n"
+" Any other string is treated as a tag name, which is a symbolic\n"
+" name associated with a revision identifier. Tag names may not\n"
+" contain the \":\" character.\n"
+"\n"
+" The reserved name \"tip\" is a special tag that always identifies\n"
+" the most recent revision.\n"
+"\n"
+" The reserved name \"null\" indicates the null revision. This is the\n"
+" revision of an empty repository, and the parent of revision 0.\n"
+"\n"
+" The reserved name \".\" indicates the working directory parent. If\n"
+" no working directory is checked out, it is equivalent to null. If\n"
+" an uncommitted merge is in progress, \".\" is the revision of the\n"
+" first parent.\n"
+" "
+msgstr ""
+"\n"
+" Mercurial unterstützt mehrere Arten individuelle Revisionen anzugeben\n"
+"\n"
+" Eine einfache Ganzzahl wird als Revisionsnummer behandelt. Negative\n"
+" Zahlen beschreiben den topologischen Abstand von der Spitze (tip), "
+"wobei\n"
+" -1 die Spitze selbst ist. Daher sind negative Zahlen nur dann nützlich,\n"
+" wenn man sich die lokalen Revisionsnummern einprägt und das Tippen "
+"einer\n"
+" Zahl sparen möchte. Der Verfasser empfiehlt 'copy and paste'.\n"
+"\n"
+" Eine 40-stellige Hexadezimalzahl gilt als eindeutiger Identifikator\n"
+" einer Revision.\n"
+"\n"
+" Eine Hexadezimalzahl mit weniger als 40 Zeichen gilt als eindeutiger\n"
+" Identifikator und wird als Kurzform des Identifikators bezeichnet.\n"
+" Die Kurzform ist nur dann gültig, wenn sie Präfix exakt einer Langform\n"
+" eines Identifikators ist.\n"
+"\n"
+" Jede andere Zeichenfolge wird als Name einer Marke (tag) behandelt.\n"
+" Dieser symbolische Name verweist auf einen Revisionsidentifikator. "
+"Namen\n"
+" von Marken dürfen das Zeichen \":\" nicht enthalten.\n"
+"\n"
+" Der reservierte Name \"tip\" ist eine spezielle Marke die immer auf die\n"
+" jüngste Revision verweist.\n"
+"\n"
+" Der reservierte Name \"null\" bezeichnet die null-Revision. Sie ist die\n"
+" Revision eines leeren Projektarchivs und der Vorgänger der Version 0.\n"
+"\n"
+" Der reservierte Name \".\" bezeichnete die Vorgängerversion des\n"
+" Arbeitsverzeichnisses. Falls kein Check-Out des Arbeitsverzeichnisses\n"
+" vorliegt ist er äquivalent zu null. Falls eine nicht versionierte\n"
+" Zusammenführung in Bearbeitung ist, bezeichnet \".\" die Revision des\n"
+" ersten Vorgängers.\n"
+" "
+
+msgid "Specifying Multiple Revisions"
+msgstr "Angabe Mehrerer Revisionen"
+
+msgid ""
+"\n"
+" When Mercurial accepts more than one revision, they may be\n"
+" specified individually, or provided as a topologically continuous\n"
+" range, separated by the \":\" character.\n"
+"\n"
+" The syntax of range notation is [BEGIN]:[END], where BEGIN and END\n"
+" are revision identifiers. Both BEGIN and END are optional. If\n"
+" BEGIN is not specified, it defaults to revision number 0. If END\n"
+" is not specified, it defaults to the tip. The range \":\" thus means\n"
+" \"all revisions\".\n"
+"\n"
+" If BEGIN is greater than END, revisions are treated in reverse\n"
+" order.\n"
+"\n"
+" A range acts as a closed interval. This means that a range of 3:5\n"
+" gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+" "
+msgstr ""
+"\n"
+" Wenn Mercurial mehr als eine Revision annimmt, können sie\n"
+" einzeln angegeben werden oder als topologisch kontinuierlicher\n"
+" Bereich getrennt durch das \":\" Zeichen.\n"
+"\n"
+" Die Syntax der Bereichs-Notation ist [ANFANG]:[ENDE], wobei ANFANG und\n"
+" ENDE Revisions-Identifikatoren sind. Sowohl ANFANG als auch ENDE sind\n"
+" optional. Sollte ANFANG nicht angegeben werden, wird standardmäßig die\n"
+" die Revisionsnummer 0 angenommen. Wenn ENDE nicht angegeben wird, wird\n"
+" standardmäßig tip genommen. Der Bereich \":\" bedeute daher\n"
+" \"alle Revisionen\".\n"
+"\n"
+" Wenn ANFANG größer als ENDE ist, werden die Revisionen in umgekehrter\n"
+" Reihenfolge betrachtet.\n"
+"\n"
+" Ein Bereich fungiert als geschlossenes Intervall . Das heißt, dass\n"
+" der Bereich 3:5 die Revisionen 3, 4 und 5 enthält. Ebenso enthält der\n"
+" Bereich 9:6 die Revisionen 9, 8, 7 und 6.\n"
+" "
+
+msgid "Diff Formats"
+msgstr "Diff-Formate"
+
+msgid ""
+"\n"
+" Mercurial's default format for showing changes between two\n"
+" versions of a file is compatible with the unified format of GNU\n"
+" diff, which can be used by GNU patch and many other standard\n"
+" tools.\n"
+"\n"
+" While this standard format is often enough, it does not encode the\n"
+" following information:\n"
+"\n"
+" - executable status and other permission bits\n"
+" - copy or rename information\n"
+" - changes in binary files\n"
+" - creation or deletion of empty files\n"
+"\n"
+" Mercurial also supports the extended diff format from the git VCS\n"
+" which addresses these limitations. The git diff format is not\n"
+" produced by default because a few widespread tools still do not\n"
+" understand this format.\n"
+"\n"
+" This means that when generating diffs from a Mercurial repository\n"
+" (e.g. with \"hg export\"), you should be careful about things like\n"
+" file copies and renames or other things mentioned above, because\n"
+" when applying a standard diff to a different repository, this\n"
+" extra information is lost. Mercurial's internal operations (like\n"
+" push and pull) are not affected by this, because they use an\n"
+" internal binary format for communicating changes.\n"
+"\n"
+" To make Mercurial produce the git extended diff format, use the\n"
+" --git option available for many commands, or set 'git = True' in\n"
+" the [diff] section of your hgrc. You do not need to set this\n"
+" option when importing diffs in this format or using them in the mq\n"
+" extension.\n"
+" "
+msgstr ""
+
+msgid "Template Usage"
+msgstr "Nutzung von Vorlagen"
+
+msgid ""
+"\n"
+" Mercurial allows you to customize output of commands through\n"
+" templates. You can either pass in a template from the command\n"
+" line, via the --template option, or select an existing\n"
+" template-style (--style).\n"
+"\n"
+" You can customize output for any \"log-like\" command: log,\n"
+" outgoing, incoming, tip, parents, heads and glog.\n"
+"\n"
+" Three styles are packaged with Mercurial: default (the style used\n"
+" when no explicit preference is passed), compact and changelog.\n"
+" Usage:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" A template is a piece of text, with markup to invoke variable\n"
+" expansion:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings in curly braces are called keywords. The availability of\n"
+" keywords depends on the exact context of the templater. These\n"
+" keywords are usually available for templating a log-like command:\n"
+"\n"
+" - author: String. The unmodified author of the changeset.\n"
+" - branches: String. The name of the branch on which the changeset\n"
+" was committed. Will be empty if the branch name was default.\n"
+" - date: Date information. The date when the changeset was committed.\n"
+" - desc: String. The text of the changeset description.\n"
+" - diffstat: String. Statistics of changes with the following\n"
+" format: \"modified files: +added/-removed lines\"\n"
+" - files: List of strings. All files modified, added, or removed by\n"
+" this changeset.\n"
+" - file_adds: List of strings. Files added by this changeset.\n"
+" - file_mods: List of strings. Files modified by this changeset.\n"
+" - file_dels: List of strings. Files removed by this changeset.\n"
+" - node: String. The changeset identification hash, as a\n"
+" 40-character hexadecimal string.\n"
+" - parents: List of strings. The parents of the changeset.\n"
+" - rev: Integer. The repository-local changeset revision number.\n"
+" - tags: List of strings. Any tags associated with the changeset.\n"
+"\n"
+" The \"date\" keyword does not produce human-readable output. If you\n"
+" want to use a date in your output, you can use a filter to process\n"
+" it. Filters are functions which return a string based on the input\n"
+" variable. You can also use a chain of filters to get the desired\n"
+" output:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" List of filters:\n"
+"\n"
+" - addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
+" every line except the last.\n"
+" - age: Date. Returns a human-readable date/time difference between\n"
+" the given date/time and the current date/time.\n"
+" - basename: Any text. Treats the text as a path, and returns the\n"
+" last component of the path after splitting by the path\n"
+" separator (ignoring trailing separators). For example,\n"
+" \"foo/bar/baz\" becomes \"baz\" and \"foo/bar//\" becomes \"bar"
+"\".\n"
+" - stripdir: Treat the text as path and strip a directory level, if\n"
+" possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\".\n"
+" - date: Date. Returns a date in a Unix date format, including\n"
+" the timezone: \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - domain: Any text. Finds the first string that looks like an\n"
+" email address, and extracts just the domain component.\n"
+" Example: 'User <user@example.com>' becomes 'example.com'.\n"
+" - email: Any text. Extracts the first string that looks like an\n"
+" email address. Example: 'User <user@example.com>' becomes\n"
+" 'user@example.com'.\n"
+" - escape: Any text. Replaces the special XML/XHTML characters \"&\",\n"
+" \"<\" and \">\" with XML entities.\n"
+" - fill68: Any text. Wraps the text to fit in 68 columns.\n"
+" - fill76: Any text. Wraps the text to fit in 76 columns.\n"
+" - firstline: Any text. Returns the first line of text.\n"
+" - nonempty: Any text. Returns '(none)' if the string is empty.\n"
+" - hgdate: Date. Returns the date as a pair of numbers:\n"
+" \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
+" - isodate: Date. Returns the date in ISO 8601 format.\n"
+" - localdate: Date. Converts a date to local date.\n"
+" - obfuscate: Any text. Returns the input text rendered as a\n"
+" sequence of XML entities.\n"
+" - person: Any text. Returns the text before an email address.\n"
+" - rfc822date: Date. Returns a date using the same format used\n"
+" in email headers.\n"
+" - short: Changeset hash. Returns the short form of a changeset\n"
+" hash, i.e. a 12-byte hexadecimal string.\n"
+" - shortdate: Date. Returns a date like \"2006-09-18\".\n"
+" - strip: Any text. Strips all leading and trailing whitespace.\n"
+" - tabindent: Any text. Returns the text, with every line except\n"
+" the first starting with a tab character.\n"
+" - urlescape: Any text. Escapes all \"special\" characters. For\n"
+" example, \"foo bar\" becomes \"foo%20bar\".\n"
+" - user: Any text. Returns the user portion of an email address.\n"
+" "
+msgstr ""
+
+msgid "URL Paths"
+msgstr "URL-Pfade"
+
+msgid ""
+"\n"
+" Valid URLs are of the form:\n"
+"\n"
+" local/filesystem/path (or file://local/filesystem/path)\n"
+" http://[user[:pass]@]host[:port]/[path]\n"
+" https://[user[:pass]@]host[:port]/[path]\n"
+" ssh://[user[:pass]@]host[:port]/[path]\n"
+"\n"
+" Paths in the local filesystem can either point to Mercurial\n"
+" repositories or to bundle files (as created by 'hg bundle' or\n"
+" 'hg incoming --bundle').\n"
+"\n"
+" An optional identifier after # indicates a particular branch, tag,\n"
+" or changeset to use from the remote repository.\n"
+"\n"
+" Some features, such as pushing to http:// and https:// URLs are\n"
+" only possible if the feature is explicitly enabled on the remote\n"
+" Mercurial server.\n"
+"\n"
+" Some notes about using SSH with Mercurial:\n"
+" - SSH requires an accessible shell account on the destination\n"
+" machine and a copy of hg in the remote path or specified with as\n"
+" remotecmd.\n"
+" - path is relative to the remote user's home directory by default.\n"
+" Use an extra slash at the start of a path to specify an absolute "
+"path:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial doesn't use its own compression via SSH; the right\n"
+" thing to do is to configure it in your ~/.ssh/config, e.g.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternatively specify \"ssh -C\" as your ssh command in your hgrc\n"
+" or with the --ssh command line option.\n"
+"\n"
+" These URLs can all be stored in your hgrc with path aliases under\n"
+" the [paths] section like so:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" You can then use the alias for any command that uses a URL (for\n"
+" example 'hg pull alias1' would pull from the 'alias1' path).\n"
+"\n"
+" Two path aliases are special because they are used as defaults\n"
+" when you do not provide the URL to a command:\n"
+"\n"
+" default:\n"
+" When you create a repository with hg clone, the clone command\n"
+" saves the location of the source repository as the new\n"
+" repository's 'default' path. This is then used when you omit\n"
+" path from push- and pull-like commands (including incoming and\n"
+" outgoing).\n"
+"\n"
+" default-push:\n"
+" The push command will look for a path named 'default-push', and\n"
+" prefer it over 'default' if both are defined.\n"
+" "
+msgstr ""
+"\n"
+" Gültige URLs haben folgende Form:\n"
+"\n"
+" lokales/dateisystem/pfad (oder file://lokales/dateisystem/pfad)\n"
+" http://[nutzer[:pass]@]host[:port]/[pfad]\n"
+" https://[nutzer[:pass]@]host[:port]/[pfad]\n"
+" ssh://[nutzer[:pass]@]host[:port]/[pfad]\n"
+"\n"
+" Pfade im lokalen Dateisystem können auf ein Mercurial-Archiv oder\n"
+" Bündeldateien verweisen (wie sie von 'hg bundle' oder\n"
+" 'hg incoming --bundle' erzeugt werden).\n"
+"\n"
+" Ein optionaler Bezeichner nach # verweist auf einen bestimmten Zweig, "
+"Tag\n"
+" oder Änderungssatz des anderen Projektarchivs.\n"
+"\n"
+" Einige Funktionen, wie das Ausliefern an http:// und https:// URLs, "
+"sind\n"
+" nur mögliche wenn diese Funktionen explizit auf dem entfernten\n"
+" Mercurial-Server aktiviert sind.\n"
+"\n"
+" Einige Hinweise zur Nutzung von SSH mit Mercurial:\n"
+" - SSH benötigt einen nutzbaren Shell-Zugang auf der Zielmaschine und\n"
+" eine Kopie von hg im Pfad der entfernten Maschine oder in der "
+"Konfiguration\n"
+" remotecmd angegeben.\n"
+" - Der Pfad ist standardmäßig relativ vom Home-Verzeichnis des "
+"entfernten\n"
+" Nutzer. Nutze einen zusätzlichen Schrägstrich um einen absoluen Pfad\n"
+" anzugeben:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial nutzt nicht eigene Kompressionsmechanismen über SSH:\n"
+" Hier sollte man die Kompression über ~/.ssh/config aktivieren, z.B.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternativ kann \"ssh -C\" als dein SSH-Befehl in der hgrc oder\n"
+" mit der --ssh Befehlszeilenoption angegeben werden.\n"
+"\n"
+" Diese URLs können alle in deiner hgrc als Aliase unter der Sektion\n"
+" [paths] abgelegt werden:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" Diese Aliase können dann bei jedem Befehl genutzt werden der URLs nutzt\n"
+" (beispielsweise 'hg pull alias1' würde vom 'alias1' Pfad "
+"herunterladen).\n"
+"\n"
+" Es gibt zwei besondere Pfad-Aliase, die standardmäßig genutzt\n"
+" werden wenn einem Befehl keine URL übergeben wurde:\n"
+"\n"
+" default:\n"
+" Bei Erstellung eines Projektarchivs mit hg clone, sichert der clone\n"
+" Befehl die Herkunft des Quellarchivs als 'default'-Pfad des neuen\n"
+" Archivs. Dieser Pfad wird immer dann genutzt, wenn bei 'push' oder\n"
+" 'pull'-ähnlichen Befehlen der Pfad nicht angegeben wurde (auch bei\n"
+" 'incoming' oder 'outgoing').\n"
+"\n"
+" default-push:\n"
+" Der 'push'-Befehl sucht nach dem 'default-push'-Alias und zieht\n"
+" diesen dem 'default'-Alias vor, wenn beide definiert sind.\n"
+" "
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr "Zielverzeichnis: %s\n"
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr "Ziel '%s' existiert bereits"
+
+#, python-format
+msgid "destination '%s' is not empty"
+msgstr "Ziel %s ist nicht leer"
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr ""
+"Quellarchiv unterstützt keine Revisions-Abfragen und lässt daher das Klonen "
+"bis zu einer Revision nicht zu"
+
+msgid "clone from remote to remote not supported"
+msgstr "Klonen von entferntem Archiv zu entferntem Archiv nicht möglich"
+
+msgid "updating working directory\n"
+msgstr "Aktualisiere Arbeitsverzeichnis\n"
+
+msgid "updated"
+msgstr "aktualisiert"
+
+msgid "merged"
+msgstr "zusammengeführt"
+
+msgid "removed"
+msgstr "entfernt"
+
+msgid "unresolved"
+msgstr "ungelöst"
+
+#, python-format
+msgid "%d files %s"
+msgstr "%d Dateien %s"
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr "Verwende 'hg resolve', um die Zusammenführung erneut zu versuchen\n"
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to "
+"abandon\n"
+msgstr ""
+"Nutze 'hg resolve', um nicht aufgelöste Zusammenführungen zu wiederholen "
+"oder\n"
+"'hg up --clean' um abzubrechen\n"
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr "(Zweig-Zusammenführung, vergesse nicht 'hg commit' auszuführen)\n"
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr ""
+
+msgid "SSL support is unavailable"
+msgstr ""
+
+msgid "IPv6 is not available on this system"
+msgstr ""
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr ""
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook failed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr ""
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook %s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr ""
+
+msgid "connection ended unexpectedly"
+msgstr ""
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "using %s\n"
+msgstr ""
+
+#, python-format
+msgid "capabilities: %s\n"
+msgstr ""
+
+msgid "operation not supported over http"
+msgstr ""
+
+#, python-format
+msgid "sending %s command\n"
+msgstr ""
+
+#, python-format
+msgid "sending %s bytes\n"
+msgstr ""
+
+msgid "authorization failed"
+msgstr ""
+
+#, python-format
+msgid "http error while sending %s command\n"
+msgstr ""
+
+msgid "http error, possibly caused by proxy setting"
+msgstr ""
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr ""
+
+#, python-format
+msgid "requested URL: '%s'\n"
+msgstr "Angeforderte URL: '%s'\n"
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr ""
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr ""
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr ""
+
+msgid "look up remote revision"
+msgstr ""
+
+msgid "unexpected response:"
+msgstr ""
+
+msgid "look up remote changes"
+msgstr ""
+
+msgid "push failed (unexpected response):"
+msgstr "push fehlgeschlagen (Unerwartete Antwort)"
+
+#, python-format
+msgid "push failed: %s"
+msgstr "push fehlgeschlagen: %s"
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr "Python Unterstützung für SSL und HTTPS ist nicht installiert"
+
+msgid "cannot create new http repository"
+msgstr "Kann neues HTTP-Projektarchiv nicht erzeugen"
+
+#, python-format
+msgid "%s: ignoring invalid syntax '%s'\n"
+msgstr "%s: Ignoriere ungültige Syntax '%s'\n"
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr "Überspringe nicht lesbares ignore file '%s': %s\n"
+
+#, python-format
+msgid "repository %s not found"
+msgstr "Projektarchiv %s nicht gefunden"
+
+#, python-format
+msgid "repository %s already exists"
+msgstr "Projektarchiv %s existiert bereits"
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr "Anforderung '%s' nicht unterstützt"
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr "%r kann nicht als Name für tag genutzt werden"
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr ""
+"Arbeitskopie von .hgtags wurde geändert (Bitte .hgtags manuell versionieren)"
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr "%s, Zeile %s: %s\n"
+
+msgid "cannot parse entry"
+msgstr "Kann Eintrag nicht parsen"
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr "Knoten '%s' ist fehlerhaft"
+
+#, python-format
+msgid "tag '%s' refers to unknown node"
+msgstr "Tag '%s' verweist auf unbekannten Knoten"
+
+#, python-format
+msgid "working directory has unknown parent '%s'!"
+msgstr "Arbeitsverzeichnis hat unbekannte Vaterversion '%s'!"
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr "Unbekannte Revision '%s'"
+
+#, python-format
+msgid "filtering %s through %s\n"
+msgstr "Filtere %s bis %s\n"
+
+msgid "journal already exists - run hg recover"
+msgstr "Journal existiert bereits - führe hg recover aus"
+
+msgid "rolling back interrupted transaction\n"
+msgstr "Setze unterbrochene Transaktion zurück\n"
+
+msgid "no interrupted transaction available\n"
+msgstr "Keine unterbrochene Transaktion vorhanden\n"
+
+msgid "rolling back last transaction\n"
+msgstr "Setze letzte Transaktion zurück\n"
+
+#, python-format
+msgid "Named branch could not be reset, current branch still is: %s\n"
+msgstr ""
+"Benannter Zweig konnte nicht zurückgesetzt werden, aktueller Zweig ist: %s\n"
+
+msgid "no rollback information available\n"
+msgstr "Keine rollback-Information verfügbar\n"
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr "Warte auf Sperre auf %s gehalten von %r\n"
+
+#, python-format
+msgid "repository %s"
+msgstr "Projektarchiv %s"
+
+#, python-format
+msgid "working directory of %s"
+msgstr "Arbeitsverzeichnis von %s"
+
+#, python-format
+msgid " %s: searching for copy revision for %s\n"
+msgstr " %s: Suche kopierte Revision für %s\n"
+
+#, python-format
+msgid " %s: copy %s:%s\n"
+msgstr " %s: kopiere %s:%s\n"
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr ""
+"Eine Zusammenführung kann nicht teilweise versioniert werden (Gib keine "
+"Dateien oder Muster an)"
+
+msgid "file not found!"
+msgstr "Datei nicht gefunden!"
+
+msgid "no match under directory!"
+msgstr "Kein Treffer unterhalb des Verzeichnisses!"
+
+msgid "file not tracked!"
+msgstr "Datei wird nicht nachverfolgt!"
+
+msgid "nothing changed\n"
+msgstr "Keine Änderung\n"
+
+msgid "unresolved merge conflicts (see hg resolve)"
+msgstr "Ungelöster Zusammenführungs-Konflikt (siehe hg resolve)"
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr "Problem bei Erstellen der neuen Version von %s!\n"
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr "%s existiert nicht!\n"
+
+#, python-format
+msgid ""
+"%s: files over 10MB may cause memory and performance problems\n"
+"(use 'hg revert %s' to unadd the file)\n"
+msgstr ""
+"%s: Dateien über 10MB können Speicher- und Performance-Probleme auslösen\n"
+"(Nutze 'hg revert %s' um die Datei zu entfernen)\n"
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr ""
+"%s nicht hinzugefügt: Nur Dateien und symbolische Verknüpfungen werden\n"
+"zur Zeit unterstützt\n"
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr "%s ist bereits versioniert!\n"
+
+#, python-format
+msgid "%s not added!\n"
+msgstr "%s nicht hinzugefügt!\n"
+
+#, python-format
+msgid "%s still exists!\n"
+msgstr "%s existiert noch!\n"
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr "%s nicht versioniert!\n"
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr "%s nicht entfernt!\n"
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr ""
+"Kopieren fehlgeschlagen: %s ist keine Datei oder eine symbolische "
+"Verknüpfung\n"
+
+msgid "searching for changes\n"
+msgstr "Suche nach Änderungen\n"
+
+#, python-format
+msgid "examining %s:%s\n"
+msgstr "Untersuche %s:%s\n"
+
+msgid "branch already found\n"
+msgstr "Zweig bereits gefunden\n"
+
+#, python-format
+msgid "found incomplete branch %s:%s\n"
+msgstr "Unvollständiger Zweig gefunden %s:%s\n"
+
+#, python-format
+msgid "found new changeset %s\n"
+msgstr "Neue Änderungssätze gefunden %s\n"
+
+#, python-format
+msgid "request %d: %s\n"
+msgstr "Angefordert %d: %s\n"
+
+#, python-format
+msgid "received %s:%s\n"
+msgstr "Erhalten %s:%s\n"
+
+#, python-format
+msgid "narrowing %d:%d %s\n"
+msgstr "Verringere %d:%d %s\n"
+
+#, python-format
+msgid "found new branch changeset %s\n"
+msgstr "Neue Zweigversion gefunden %s\n"
+
+#, python-format
+msgid "narrowed branch search to %s:%s\n"
+msgstr "Zweig-Suche verringert auf %s:%s\n"
+
+msgid "already have changeset "
+msgstr "Änderungssatz bereits vorhanden "
+
+msgid "warning: repository is unrelated\n"
+msgstr "Warnung: Projektarchiv steht in keinem Zusammenhang\n"
+
+msgid "repository is unrelated"
+msgstr "Projektarchiv steht in keinem Zusammenhang"
+
+msgid "found new changesets starting at "
+msgstr "Neue Änderungssätze gefunden ab"
+
+#, python-format
+msgid "%d total queries\n"
+msgstr "%d Abfragen insgesamt\n"
+
+msgid "common changesets up to "
+msgstr "Gemeinsame Änderungssätze bis zu"
+
+msgid "requesting all changes\n"
+msgstr "Fordere alle Änderungen an\n"
+
+msgid ""
+"Partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr ""
+"Teilweise Holen kann nicht ausgeführt werden, da das andere Projektarchiv "
+"keine Teilmengen von Änderungsgruppen unterstützt."
+
+#, python-format
+msgid "abort: push creates new remote branch '%s'!\n"
+msgstr "Abbruch: Ausliefern erzeugt neuen entfernten Zweig '%s'!\n"
+
+msgid "abort: push creates new remote heads!\n"
+msgstr "Abbruch: Ausliefern erzeugt neue entfernte Köpfe!\n"
+
+msgid "(did you forget to merge? use push -f to force)\n"
+msgstr "(Hast du vergessen zusammenzuführen? Nutze push -f um zu erzwingen)\n"
+
+msgid "note: unsynced remote changes!\n"
+msgstr "Hinweis: Nicht synchronisierte entfernte Änderungen!\n"
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr "%d Änderungssätze gefunden\n"
+
+msgid "list of changesets:\n"
+msgstr "Liste der Änderungssätze:\n"
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr "Leeres oder fehlendes Revlog für %s"
+
+#, python-format
+msgid "add changeset %s\n"
+msgstr "Füge Änderungssatz hinzu %s\n"
+
+msgid "adding changesets\n"
+msgstr "Füge Änderungssätze hinzu\n"
+
+msgid "received changelog group is empty"
+msgstr "Erhaltene changelog group ist leer"
+
+msgid "adding manifests\n"
+msgstr "Füge Manifeste hinzu\n"
+
+msgid "adding file changes\n"
+msgstr "Füge Dateiänderungen hinzu\n"
+
+#, python-format
+msgid "adding %s revisions\n"
+msgstr "Füge %s Revisionen hinzu\n"
+
+msgid "received file revlog group is empty"
+msgstr "Erhaltene Datei revlog group ist leer"
+
+#, python-format
+msgid " (%+d heads)"
+msgstr " (%+d Köpfe)"
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr "Fügte %d Änderungssätze mit %d Änderungen zu %d Dateien%s hinzu\n"
+
+msgid "updating the branch cache\n"
+msgstr "Aktualisiere den Zweig-Cache\n"
+
+msgid "Unexpected response from remote server:"
+msgstr ""
+
+msgid "operation forbidden by server"
+msgstr ""
+
+msgid "locking the remote repository failed"
+msgstr ""
+
+msgid "the server sent an unknown error code"
+msgstr ""
+
+msgid "streaming all changes\n"
+msgstr ""
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr ""
+
+#, python-format
+msgid "adding %s (%s)\n"
+msgstr ""
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr ""
+
+msgid "no [smtp]host in hgrc - cannot send mail"
+msgstr ""
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr ""
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr ""
+
+msgid "(using tls)\n"
+msgstr ""
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr ""
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr ""
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr ""
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr ""
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr ""
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr ""
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr ""
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr ""
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr ""
+
+msgid "resolving manifests\n"
+msgstr ""
+
+#, python-format
+msgid " overwrite %s partial %s\n"
+msgstr ""
+
+#, python-format
+msgid " ancestor %s local %s remote %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+
+msgid "&None"
+msgstr "&Nichts"
+
+msgid "E&xec"
+msgstr ""
+
+msgid "Sym&link"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+msgid "&Changed"
+msgstr ""
+
+msgid "&Delete"
+msgstr ""
+
+msgid "c"
+msgstr ""
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+
+msgid "&Deleted"
+msgstr ""
+
+#, python-format
+msgid "preserving %s for resolve of %s\n"
+msgstr ""
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "warning: detected divergent renames of %s to:\n"
+msgstr ""
+
+#, python-format
+msgid "branch %s not found"
+msgstr ""
+
+msgid "can't merge with ancestor"
+msgstr ""
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr ""
+
+msgid "outstanding uncommitted changes (use 'hg status' to list changes)"
+msgstr ""
+"Ausstehende nicht versionierte Änderungen (Nutze 'hg status' zur Auflistung "
+"der Änderungen)"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C' to discard changes)"
+msgstr ""
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C')"
+msgstr ""
+
+msgid "crosses named branches (use 'hg update -C' to discard changes)"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr ""
+
+#, python-format
+msgid "found patch at byte %d\n"
+msgstr ""
+
+msgid "patch generated by hg export\n"
+msgstr ""
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr ""
+
+#, python-format
+msgid "patching file %s\n"
+msgstr ""
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr ""
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d line).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d lines).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr ""
+
+msgid "could not extract binary patch"
+msgstr ""
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr ""
+
+#, python-format
+msgid "unable to strip away %d dirs from %s"
+msgstr ""
+
+msgid "undefined source and destination files"
+msgstr ""
+
+#, python-format
+msgid "malformed patch %s %s"
+msgstr ""
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr ""
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr ""
+
+#, python-format
+msgid "no valid hunks found; trying with %r instead\n"
+msgstr ""
+
+#, python-format
+msgid "exited with status %d"
+msgstr ""
+
+#, python-format
+msgid "killed by signal %d"
+msgstr ""
+
+#, python-format
+msgid "stopped by signal %d"
+msgstr ""
+
+msgid "invalid exit code"
+msgstr ""
+
+#, python-format
+msgid "saving bundle to %s\n"
+msgstr ""
+
+msgid "adding branch\n"
+msgstr ""
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr ""
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr ""
+
+#, python-format
+msgid "index %s is corrupted"
+msgstr ""
+
+msgid "no node"
+msgstr ""
+
+msgid "ambiguous identifier"
+msgstr ""
+
+msgid "no match found"
+msgstr ""
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr ""
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr ""
+
+msgid "unknown base"
+msgstr ""
+
+msgid "consistency error adding group"
+msgstr ""
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr ""
+
+msgid "can only specify two labels."
+msgstr ""
+
+msgid "warning: conflicts during merge.\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr ""
+
+msgid "could not create remote repo"
+msgstr ""
+
+msgid "remote: "
+msgstr ""
+
+msgid "no suitable response from remote hg"
+msgstr ""
+
+#, python-format
+msgid "push refused: %s"
+msgstr ""
+
+msgid "unsynced changes"
+msgstr ""
+
+msgid "cannot lock static-http repository"
+msgstr ""
+
+msgid "cannot create new static-http repository"
+msgstr ""
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr ""
+
+msgid "scanning\n"
+msgstr ""
+
+#, python-format
+msgid "%d files, %d bytes to transfer\n"
+msgstr ""
+
+#, python-format
+msgid "sending %s (%d bytes)\n"
+msgstr ""
+
+msgid "unmatched quotes"
+msgstr ""
+
+#, python-format
+msgid "error expanding '%s%%%s'"
+msgstr "Fehler bei Auflösung von '%s%%%s'"
+
+#, python-format
+msgid "unknown filter '%s'"
+msgstr "Unbekannter Filter '%s'"
+
+#, python-format
+msgid "style not found: %s"
+msgstr ""
+
+#, python-format
+msgid "template file %s: %s"
+msgstr ""
+
+msgid "cannot use transaction when it is already committed/aborted"
+msgstr ""
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr ""
+
+msgid "transaction abort!\n"
+msgstr ""
+
+msgid "rollback completed\n"
+msgstr ""
+
+msgid "rollback failed - please run hg recover\n"
+msgstr "Rücksetzen fehlgeschlagen - bitte führe hg recover aus\n"
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr "Nicht vertrauenswürdige Datei %s vom Nutzer %s, Gruppe %s\n"
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr "Ignoriere: %s\n"
+
+#, python-format
+msgid "ignoring untrusted configuration option %s.%s = %s\n"
+msgstr "Ignoriere nicht vertrauenswürdigen Konfigurationseintrag %s.%s = %s\n"
+
+#, python-format
+msgid "%s.%s not a boolean ('%s')"
+msgstr "%s.%s ist kein bool'scher Wert ('%s')"
+
+msgid "enter a commit username:"
+msgstr "Gib einen Benutzernamen für die Version ein:"
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr "Kein Benutzername gefunden, nutze %s stattdessen\n"
+
+msgid "Please specify a username."
+msgstr "Gib einen Benutzernamen an."
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr "Benutzername %s enthält einen Zeilenumbruch\n"
+
+msgid "unrecognized response\n"
+msgstr "Unbekannte Antwort\n"
+
+msgid "response expected"
+msgstr "Antwort erwartet"
+
+msgid "password: "
+msgstr "Passwort: "
+
+msgid "edit failed"
+msgstr "Bearbeiten fehlgeschlagen"
+
+msgid "http authorization required"
+msgstr "HTTP-Autorisation benötigt"
+
+msgid "http authorization required\n"
+msgstr "HTTP-Autorisation benötigt\n"
+
+#, python-format
+msgid "realm: %s\n"
+msgstr "Bereich: %s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "Benutzer: %s\n"
+
+msgid "user:"
+msgstr "Benutzer:"
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr "HTTP Auth: Benutzer %s, Passwort%s\n"
+
+#, python-format
+msgid "proxying through http://%s:%s\n"
+msgstr "Verwende Proxy http://%s:%s\n"
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr "Befehl '%s' fehlgeschlagen: %s"
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr "Pfad enthält illegalen Teil: %s"
+
+#, python-format
+msgid "path %r is inside repo %r"
+msgstr "Pfad %r ist innerhalb des Archivs %r"
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr "Pfad %r überschreitet symbolische Verknüpfung %r"
+
+msgid "Hardlinks not supported"
+msgstr "Hardlinks nicht unterstützt"
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr "Konnte symbolische Verknüpfung auf %r nicht erzeugen: %s"
+
+#, python-format
+msgid "invalid date: %r "
+msgstr "Ungültiges Datum: %r "
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr "Datum überschreitet 32 Bit: %d"
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr "Unmögliche Zeitzonen Verschiebung: %d"
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr "Ungültige Angabe des Tages: %s"
+
+#, python-format
+msgid "%.0f GB"
+msgstr ""
+
+#, python-format
+msgid "%.1f GB"
+msgstr ""
+
+#, python-format
+msgid "%.2f GB"
+msgstr ""
+
+#, python-format
+msgid "%.0f MB"
+msgstr ""
+
+#, python-format
+msgid "%.1f MB"
+msgstr ""
+
+#, python-format
+msgid "%.2f MB"
+msgstr ""
+
+#, python-format
+msgid "%.0f KB"
+msgstr ""
+
+#, python-format
+msgid "%.1f KB"
+msgstr ""
+
+#, python-format
+msgid "%.2f KB"
+msgstr ""
+
+#, python-format
+msgid "%.0f bytes"
+msgstr "%.0f Byte"
+
+msgid "cannot verify bundle or remote repos"
+msgstr ""
+
+msgid "interrupted"
+msgstr ""
+
+#, python-format
+msgid "empty or missing %s"
+msgstr ""
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr ""
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to nonexistent changeset %d"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to unexpected changeset %d"
+msgstr ""
+
+#, python-format
+msgid " (expected %s)"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "checking parents of %s"
+msgstr ""
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr ""
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr ""
+
+msgid "checking changesets\n"
+msgstr ""
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr ""
+
+msgid "checking manifests\n"
+msgstr ""
+
+#, python-format
+msgid "%s not in changesets"
+msgstr "%s nicht in den Änderungssätzen vorhanden"
+
+msgid "file without name in manifest"
+msgstr ""
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr ""
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr ""
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr ""
+
+msgid "in changeset but not in manifest"
+msgstr ""
+
+msgid "in manifest but not in changeset"
+msgstr ""
+
+msgid "checking files\n"
+msgstr ""
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr ""
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr ""
+
+msgid "missing revlog!"
+msgstr ""
+
+#, python-format
+msgid "%s not in manifests"
+msgstr ""
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr ""
+
+#, python-format
+msgid "unpacking %s"
+msgstr "entpacke %s"
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s"
+msgstr ""
+
+#, python-format
+msgid "checking rename of %s"
+msgstr ""
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr ""
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr ""
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr ""
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr ""
+
+msgid "user name not available - set USERNAME environment variable"
+msgstr ""
diff --git a/sys/src/cmd/hg/i18n/el.po b/sys/src/cmd/hg/i18n/el.po
new file mode 100644
index 000000000..29d0cc1bf
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/el.po
@@ -0,0 +1,8779 @@
+# Greek translations for Mercurial
+# Ελληνική μετάφÏαση των μηνυμάτων του Mercurial
+#
+# Copyright (C) 2009 Matt Mackall και άλλοι
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial\n"
+"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
+"POT-Creation-Date: 2009-06-21 04:21+0300\n"
+"PO-Revision-Date: 2009-02-13 16:27+0200\n"
+"Last-Translator: <keramida@ceid.upatras.gr>\n"
+"Language-Team: Greek\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (Ï€ÏοκαθοÏισμένο: %s)"
+
+msgid "OPTIONS"
+msgstr "ΕΠΙΛΟΓΕΣ"
+
+msgid "COMMANDS"
+msgstr "ΕÎΤΟΛΕΣ"
+
+msgid " options:\n"
+msgstr " επιλογές:\n"
+
+#, python-format
+msgid ""
+" aliases: %s\n"
+"\n"
+msgstr ""
+" ψευδώνυμα: %s\n"
+"\n"
+
+#, python-format
+msgid "acl: %s not enabled\n"
+msgstr "acl: %s ανενεÏγό\n"
+
+#, python-format
+msgid "acl: %s enabled, %d entries for user %s\n"
+msgstr "acl: %s ενεÏγό, %d εγγÏαφές για τον χÏήστη %s\n"
+
+#, python-format
+msgid "config error - hook type \"%s\" cannot stop incoming changesets"
+msgstr ""
+"Ï€Ïόβλημα Ïυθμίσεων - το hook \"%s\" δε μποÏεί να εμποδίσει εισεÏχόμενες "
+"αλλαγές"
+
+#, python-format
+msgid "acl: changes have source \"%s\" - skipping\n"
+msgstr "acl: αλλαγές από \"%s\" - εξαίÏεση αλλαγών\n"
+
+#, python-format
+msgid "acl: user %s denied on %s\n"
+msgstr "acl: ο χÏήστης %s δεν επιτÏέπεται να κάνει αλλαγές στο %s\n"
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr "acl: η Ï€Ïόσβαση για την αλλαγή %s δεν επιτÏέπεται"
+
+#, python-format
+msgid "acl: user %s not allowed on %s\n"
+msgstr "acl: ο χÏήστης %s δεν επιτÏέπεται στο %s\n"
+
+#, python-format
+msgid "acl: allowing changeset %s\n"
+msgstr "acl: αποδοχή αλλαγής %s\n"
+
+msgid ""
+"Mercurial bookmarks\n"
+"\n"
+"Mercurial bookmarks are local moveable pointers to changesets. Every\n"
+"bookmark points to a changeset identified by its hash. If you commit a\n"
+"changeset that is based on a changeset that has a bookmark on it, the\n"
+"bookmark is forwarded to the new changeset.\n"
+"\n"
+"It is possible to use bookmark names in every revision lookup (e.g. hg\n"
+"merge, hg update).\n"
+"\n"
+"The bookmark extension offers the possiblity to have a more git-like\n"
+"experience by adding the following configuration option to your .hgrc:\n"
+"\n"
+"[bookmarks]\n"
+"track.current = True\n"
+"\n"
+"This will cause bookmarks to track the bookmark that you are currently\n"
+"on, and just updates it. This is similar to git's approach to\n"
+"branching.\n"
+msgstr ""
+
+msgid ""
+"Mercurial bookmarks\n"
+"\n"
+" Bookmarks are pointers to certain commits that move when\n"
+" commiting. Bookmarks are local. They can be renamed, copied and\n"
+" deleted. It is possible to use bookmark names in 'hg merge' and\n"
+" 'hg update' to merge and update respectively to a given bookmark.\n"
+"\n"
+" You can use 'hg bookmark NAME' to set a bookmark on the working\n"
+" directory's parent revision with the given name. If you specify\n"
+" a revision using -r REV (where REV may be an existing bookmark),\n"
+" the bookmark is assigned to that revision.\n"
+" "
+msgstr ""
+
+msgid "a bookmark of this name does not exist"
+msgstr "δεν υπάÏχει σελιδοδείκτης με αυτό το όνομα"
+
+msgid "a bookmark of the same name already exists"
+msgstr "υπάÏχει ήδη σελιδοδείκτης με αυτό το όνομα"
+
+msgid "new bookmark name required"
+msgstr "απαιτείται ένα όνομα νέου σελιδοδείκτη"
+
+msgid "bookmark name required"
+msgstr "απαιτείται όνομα σελιδοδείκτη"
+
+msgid "bookmark name cannot contain newlines"
+msgstr ""
+"το όνομα ενός σελιδοδείκτη δεν επιτÏέπεται να πεÏιέχει χαÏακτήÏεςαλλαγής "
+"γÏαμμής"
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr ""
+"οι σελιδοδείκτες δεν επιτÏέπεται να έχουν το όνομα ενός υπάÏχοντος κλάδου"
+
+msgid "force"
+msgstr ""
+
+msgid "revision"
+msgstr "αλλαγή"
+
+msgid "delete a given bookmark"
+msgstr "διαγÏαφή ενός σελιδοδείκτη"
+
+msgid "rename a given bookmark"
+msgstr "μετονομασία ενός σελιδοδείκτη"
+
+#, fuzzy
+msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
+msgstr "hg bookmarks [-d] [-m ΟÎΟΜΑ] [-r ΟÎΟΜΑ] [ΟÎΟΜΑ]"
+
+msgid ""
+"Bugzilla integration\n"
+"\n"
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
+"bug status.\n"
+"\n"
+"The hook updates the Bugzilla database directly. Only Bugzilla\n"
+"installations using MySQL are supported.\n"
+"\n"
+"The hook relies on a Bugzilla script to send bug change notification\n"
+"emails. That script changes between Bugzilla versions; the\n"
+"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
+"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
+"be run by Mercurial as the user pushing the change; you will need to\n"
+"ensure the Bugzilla install file permissions are set appropriately.\n"
+"\n"
+"Configuring the extension:\n"
+"\n"
+" [bugzilla]\n"
+"\n"
+" host Hostname of the MySQL server holding the Bugzilla\n"
+" database.\n"
+" db Name of the Bugzilla database in MySQL. Default 'bugs'.\n"
+" user Username to use to access MySQL server. Default 'bugs'.\n"
+" password Password to use to access MySQL server.\n"
+" timeout Database connection timeout (seconds). Default 5.\n"
+" version Bugzilla version. Specify '3.0' for Bugzilla versions\n"
+" 3.0 and later, '2.18' for Bugzilla versions from 2.18\n"
+" and '2.16' for versions prior to 2.18.\n"
+" bzuser Fallback Bugzilla user name to record comments with, if\n"
+" changeset committer cannot be found as a Bugzilla user.\n"
+" bzdir Bugzilla install directory. Used by default notify.\n"
+" Default '/var/www/html/bugzilla'.\n"
+" notify The command to run to get Bugzilla to send bug change\n"
+" notification emails. Substitutes from a map with 3\n"
+" keys, 'bzdir', 'id' (bug id) and 'user' (committer\n"
+" bugzilla email). Default depends on version; from 2.18\n"
+" it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
+" %(id)s %(user)s\".\n"
+" regexp Regular expression to match bug IDs in changeset commit\n"
+" message. Must contain one \"()\" group. The default\n"
+" expression matches 'Bug 1234', 'Bug no. 1234', 'Bug\n"
+" number 1234', 'Bugs 1234,5678', 'Bug 1234 and 5678' and\n"
+" variations thereof. Matching is case insensitive.\n"
+" style The style file to use when formatting comments.\n"
+" template Template to use when formatting comments. Overrides\n"
+" style if specified. In addition to the usual Mercurial\n"
+" keywords, the extension specifies:\n"
+" {bug} The Bugzilla bug ID.\n"
+" {root} The full pathname of the Mercurial\n"
+" repository.\n"
+" {webroot} Stripped pathname of the Mercurial\n"
+" repository.\n"
+" {hgweb} Base URL for browsing Mercurial\n"
+" repositories.\n"
+" Default 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip The number of slashes to strip from the front of {root}\n"
+" to produce {webroot}. Default 0.\n"
+" usermap Path of file containing Mercurial committer ID to\n"
+" Bugzilla user ID mappings. If specified, the file\n"
+" should contain one mapping per line,\n"
+" \"committer\"=\"Bugzilla user\". See also the [usermap]\n"
+" section.\n"
+"\n"
+" [usermap]\n"
+" Any entries in this section specify mappings of Mercurial\n"
+" committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl Base URL for browsing Mercurial repositories. Reference\n"
+" from templates as {hgweb}.\n"
+"\n"
+"Activating the extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # run bugzilla hook on every change pulled or pushed in here\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Example configuration:\n"
+"\n"
+"This example configuration is for a collection of Mercurial\n"
+"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
+"installation in /opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Commits add a comment to the Bugzilla bug record of the form:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr "σÏνδεση στο %s:%s ως %s, κωδικός %s\n"
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr "αίτηση: %s %s\n"
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr "αποτυχία αίτησης: %s %s\n"
+
+msgid "unknown database schema"
+msgstr "άγνωστο σχήμα βάσης"
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr "το Ï€Ïόβλημα %d έχει ενημεÏωθεί ήδη για την αλλαγή %s\n"
+
+msgid "telling bugzilla to send mail:\n"
+msgstr ""
+
+#, python-format
+msgid " bug %s\n"
+msgstr " Ï€Ïόβλημα %s\n"
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr ""
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr ""
+
+msgid "done\n"
+msgstr "ολοκληÏώθηκε\n"
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr "αναζήτηση χÏήστη %s\n"
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr "δε βÏέθηκε χÏήστης bugzilla με το αναγνωÏιστικό %s"
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr "δε βÏέθηκε χÏήστης bugzilla με το αναγνωÏιστικό %s ή %s"
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr "η έκδοση %s του bugzilla δεν υποστηÏίζεται"
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr "δεν έχει εγκατασταθεί η υποστήÏιξη mysql για την python: %s"
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr "τα hooks Ï„Ïπου %s δεν πεÏνοÏν αναγνωÏιστικό αλλαγής"
+
+#, python-format
+msgid "database error: %s"
+msgstr "σφάλμα βάσης δεδομένων: %s"
+
+msgid ""
+"show the children of the given or working directory revision\n"
+"\n"
+" Print the children of the working directory's revisions. If a\n"
+" revision is given via -r/--rev, the children of that revision will\n"
+" be printed. If a file argument is given, revision in which the\n"
+" file was last changed (after the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid "show children of the specified revision"
+msgstr "lav statistik for de specificerede revisioner"
+
+msgid "hg children [-r REV] [FILE]"
+msgstr "hg children [-r ΕΚΔΟΣΗ] [ΑΡΧΕΙΟ]"
+
+msgid "command to show certain statistics about revision history"
+msgstr ""
+"εντολή η οποία δείχνει κάποια στατιστικά για το ιστοÏικό του αποθετηÏίου"
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr ""
+
+#, python-format
+msgid "generating stats: %d%%"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"histogram of changes to the repository\n"
+"\n"
+" This command will display a histogram representing the number\n"
+" of changed lines or revisions, grouped according to the given\n"
+" template. The default template will group changes by author.\n"
+" The --dateformat option may be used to group the results by\n"
+" date instead.\n"
+"\n"
+" Statistics are based on the number of changed lines, or\n"
+" alternatively the number of matching revisions if the\n"
+" --changesets option is specified.\n"
+"\n"
+" Examples:\n"
+"\n"
+" # display count of changed lines for every committer\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # display daily activity graph\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # display activity of developers by month\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # display count of lines changed in every year\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" It is possible to map alternate email addresses to a main address\n"
+" by providing a file using the following format:\n"
+" \n"
+" <alias email> <actual email>\n"
+"\n"
+" Such a file may be specified with the --aliases option, otherwise a\n"
+" .hgchurn file will be looked for in the working directory root.\n"
+" "
+msgstr ""
+"plot antallet af revisioner grupperet efter et mønster\n"
+"\n"
+" Plotter antallet af ændrede linier eller antallet af revisioner\n"
+" grupperet efter et mønster eller alternativt efter dato, hvis\n"
+" dateformat bruges. I så tilfælde bruges mønstret ikke.\n"
+"\n"
+" Som udgangspunkt laves der statistik over antallet af ændrede\n"
+" linier.\n"
+"\n"
+" Eksempler:\n"
+"\n"
+" # viser antaller af ændrede linier for hver bruger\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # viser graf over daglig aktivitet\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # viser månedlig aktivitet af udviklerne\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # viser antallet af linier ændret hvert år\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" Formatet for map-filen er rimelig simpelt:\n"
+"\n"
+" <alias email> <faktisk email>"
+
+#, python-format
+msgid "assuming %i character terminal\n"
+msgstr ""
+
+msgid "count rate for the specified revision or range"
+msgstr ""
+
+#, fuzzy
+msgid "count rate for revisions matching date spec"
+msgstr ""
+
+msgid "template to group changesets"
+msgstr ""
+
+msgid "strftime-compatible format for grouping by date"
+msgstr ""
+
+msgid "count rate by number of changesets"
+msgstr ""
+
+msgid "sort by key (default: sort by count)"
+msgstr ""
+
+msgid "file with email aliases"
+msgstr ""
+
+msgid "show progress"
+msgstr ""
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+msgstr ""
+
+msgid ""
+"add color output to status, qseries, and diff-related commands\n"
+"\n"
+"This extension modifies the status command to add color to its output\n"
+"to reflect file status, the qseries command to add color to reflect\n"
+"patch status (applied, unapplied, missing), and to diff-related\n"
+"commands to highlight additions, removals, diff headers, and trailing\n"
+"whitespace.\n"
+"\n"
+"Other effects in addition to color, like bold and underlined text, are\n"
+"also available. Effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes). This module also provides the\n"
+"render_text function, which can be used to add effects to any text.\n"
+"\n"
+"To enable this extension, add this to your .hgrc file:\n"
+"[extensions]\n"
+"color =\n"
+"\n"
+"Default effects may be overridden from the .hgrc file:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' turns off all effects\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+msgstr ""
+
+msgid "when to colorize (always, auto, or never)"
+msgstr ""
+
+msgid "don't colorize output"
+msgstr ""
+
+msgid "converting foreign VCS repositories to Mercurial"
+msgstr ""
+
+msgid ""
+"convert a foreign SCM repository to a Mercurial one.\n"
+"\n"
+" Accepted source formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Accepted destination formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (history on branches is not preserved)\n"
+"\n"
+" If no revision is given, all revisions will be converted.\n"
+" Otherwise, convert will only import up to the named revision\n"
+" (given in a format understood by the source).\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source with '-hg' appended. If the destination\n"
+" repository doesn't exist, it will be created.\n"
+"\n"
+" By default, all sources except Mercurial will use\n"
+" --branchsort. Mercurial uses --sourcesort to preserve original\n"
+" revision numbers order. Sort modes have the following effects:\n"
+" --branchsort: convert from parent to child revision when\n"
+" possible, which means branches are usually converted one after\n"
+" the other. It generates more compact repositories.\n"
+" --datesort: sort revisions by date. Converted repositories have\n"
+" good-looking changelogs but are often an order of magnitude\n"
+" larger than the same ones generated by --branchsort.\n"
+" --sourcesort: try to preserve source revisions order, only\n"
+" supported by Mercurial sources.\n"
+"\n"
+" If <REVMAP> isn't given, it will be put in a default location\n"
+" (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file\n"
+" that maps each source commit ID to the destination ID for that\n"
+" revision, like so:\n"
+" <source ID> <destination ID>\n"
+"\n"
+" If the file doesn't exist, it's automatically created. It's\n"
+" updated on each commit copied, so convert-repo can be interrupted\n"
+" and can be run repeatedly to copy new commits.\n"
+"\n"
+" The [username mapping] file is a simple text file that maps each\n"
+" source commit author to a destination commit author. It is handy\n"
+" for source SCMs that use unix logins to identify authors (eg:\n"
+" CVS). One line per author mapping and the line format is:\n"
+" srcauthor=whatever string you want\n"
+"\n"
+" The filemap is a file that allows filtering and remapping of files\n"
+" and directories. Comment lines start with '#'. Each line can\n"
+" contain one of the following directives:\n"
+"\n"
+" include path/to/file\n"
+"\n"
+" exclude path/to/file\n"
+"\n"
+" rename from/file to/file\n"
+"\n"
+" The 'include' directive causes a file, or all files under a\n"
+" directory, to be included in the destination repository, and the\n"
+" exclusion of all other files and directories not explicitly included.\n"
+" The 'exclude' directive causes files or directories to be omitted.\n"
+" The 'rename' directive renames a file or directory. To rename from\n"
+" a subdirectory into the root of the repository, use '.' as the\n"
+" path to rename to.\n"
+"\n"
+" The splicemap is a file that allows insertion of synthetic\n"
+" history, letting you specify the parents of a revision. This is\n"
+" useful if you want to e.g. give a Subversion merge two parents, or\n"
+" graft two disconnected series of history together. Each entry\n"
+" contains a key, followed by a space, followed by one or two\n"
+" comma-separated values. The key is the revision ID in the source\n"
+" revision control system whose parents should be modified (same\n"
+" format as a key in .hg/shamap). The values are the revision IDs\n"
+" (in either the source or destination revision control system) that\n"
+" should be used as the new parents for that node.\n"
+"\n"
+" The branchmap is a file that allows you to rename a branch when it is\n"
+" being brought in from whatever external repository. When used in\n"
+" conjunction with a splicemap, it allows for a powerful combination\n"
+" to help fix even the most badly mismanaged repositories and turn them\n"
+" into nicely structured Mercurial repositories. The branchmap contains\n"
+" lines of the form \"original_branch_name new_branch_name\".\n"
+" \"original_branch_name\" is the name of the branch in the source\n"
+" repository, and \"new_branch_name\" is the name of the branch is the\n"
+" destination repository. This can be used to (for instance) move code\n"
+" in one repository from \"default\" to a named branch.\n"
+"\n"
+" Mercurial Source\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (boolean)\n"
+" ignore integrity errors when reading. Use it to fix Mercurial\n"
+" repositories with missing revlogs, by converting from and to\n"
+" Mercurial.\n"
+" --config convert.hg.saverev=False (boolean)\n"
+" store original revision ID in changeset (forces target IDs to\n"
+" change)\n"
+" --config convert.hg.startrev=0 (hg revision identifier)\n"
+" convert start revision and its descendants\n"
+"\n"
+" CVS Source\n"
+" ----------\n"
+"\n"
+" CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+" to indicate the starting point of what will be converted. Direct\n"
+" access to the repository files is not needed, unless of course the\n"
+" repository is :local:. The conversion uses the top level directory\n"
+" in the sandbox to find the CVS repository, and then uses CVS rlog\n"
+" commands to find files to convert. This means that unless a\n"
+" filemap is given, all files under the starting directory will be\n"
+" converted, and that any directory reorganization in the CVS\n"
+" sandbox is ignored.\n"
+"\n"
+" Because CVS does not have changesets, it is necessary to collect\n"
+" individual commits to CVS and merge them into changesets. CVS\n"
+" source uses its internal changeset merging code by default but can\n"
+" be configured to call the external 'cvsps' program by setting:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" This option is deprecated and will be removed in Mercurial 1.4.\n"
+"\n"
+" The options shown are the defaults.\n"
+"\n"
+" Internal cvsps is selected by setting\n"
+" --config convert.cvsps=builtin\n"
+" and has a few more configurable options:\n"
+" --config convert.cvsps.cache=True (boolean)\n"
+" Set to False to disable remote log caching, for testing and\n"
+" debugging purposes.\n"
+" --config convert.cvsps.fuzz=60 (integer)\n"
+" Specify the maximum time (in seconds) that is allowed\n"
+" between commits with identical user and log message in a\n"
+" single changeset. When very large files were checked in as\n"
+" part of a changeset then the default may not be long\n"
+" enough.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will insert a dummy revision merging the branch on\n"
+" which this log message occurs to the branch indicated in\n"
+" the regex.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will add the most recent revision on the branch\n"
+" indicated in the regex as the second parent of the\n"
+" changeset.\n"
+"\n"
+" The hgext/convert/cvsps wrapper script allows the builtin\n"
+" changeset merging code to be run without doing a conversion. Its\n"
+" parameters and output are similar to that of cvsps 2.1.\n"
+"\n"
+" Subversion Source\n"
+" -----------------\n"
+"\n"
+" Subversion source detects classical trunk/branches/tags layouts.\n"
+" By default, the supplied \"svn://repo/path/\" source URL is\n"
+" converted as a single branch. If \"svn://repo/path/trunk\" exists it\n"
+" replaces the default branch. If \"svn://repo/path/branches\" exists,\n"
+" its subdirectories are listed as possible branches. If\n"
+" \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
+" converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
+" can be overridden with following options. Set them to paths\n"
+" relative to the source URL, or leave them blank to disable auto\n"
+" detection.\n"
+"\n"
+" --config convert.svn.branches=branches (directory name)\n"
+" specify the directory containing branches\n"
+" --config convert.svn.tags=tags (directory name)\n"
+" specify the directory containing tags\n"
+" --config convert.svn.trunk=trunk (directory name)\n"
+" specify the name of the trunk branch\n"
+"\n"
+" Source history can be retrieved starting at a specific revision,\n"
+" instead of being integrally converted. Only single branch\n"
+" conversions are supported.\n"
+"\n"
+" --config convert.svn.startrev=0 (svn revision number)\n"
+" specify start Subversion revision.\n"
+"\n"
+" Perforce Source\n"
+" ---------------\n"
+"\n"
+" The Perforce (P4) importer can be given a p4 depot path or a\n"
+" client specification as source. It will convert all files in the\n"
+" source to a flat Mercurial repository, ignoring labels, branches\n"
+" and integrations. Note that when a depot path is given you then\n"
+" usually should specify a target directory, because otherwise the\n"
+" target may be named ...-hg.\n"
+"\n"
+" It is possible to limit the amount of source history to be\n"
+" converted by specifying an initial Perforce revision.\n"
+"\n"
+" --config convert.p4.startrev=0 (perforce changelist number)\n"
+" specify initial Perforce revision.\n"
+"\n"
+"\n"
+" Mercurial Destination\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (boolean)\n"
+" dispatch source branches in separate clones.\n"
+" --config convert.hg.tagsbranch=default (branch name)\n"
+" tag revisions branch name\n"
+" --config convert.hg.usebranchnames=True (boolean)\n"
+" preserve branch names\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"create changeset information from CVS\n"
+"\n"
+" This command is intended as a debugging tool for the CVS to\n"
+" Mercurial converter, and can be used as a direct replacement for\n"
+" cvsps.\n"
+"\n"
+" Hg debugcvsps reads the CVS rlog for current directory (or any\n"
+" named directory) in the CVS repository, and converts the log to a\n"
+" series of changesets based on matching commit log entries and\n"
+" dates."
+msgstr ""
+
+msgid "username mapping filename"
+msgstr ""
+
+msgid "destination repository type"
+msgstr ""
+
+msgid "remap file names using contents of file"
+msgstr ""
+
+msgid "import up to target revision REV"
+msgstr ""
+
+msgid "source repository type"
+msgstr ""
+
+msgid "splice synthesized history into place"
+msgstr ""
+
+msgid "change branch names while converting"
+msgstr ""
+
+msgid "try to sort changesets by branches"
+msgstr ""
+
+msgid "try to sort changesets by date"
+msgstr ""
+
+msgid "preserve source changesets order"
+msgstr ""
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr ""
+
+msgid "only return changes on specified branches"
+msgstr ""
+
+msgid "prefix to remove from file names"
+msgstr ""
+
+msgid "only return changes after or between specified tags"
+msgstr ""
+
+msgid "update cvs log cache"
+msgstr ""
+
+msgid "create new cvs log cache"
+msgstr ""
+
+msgid "set commit time fuzz in seconds"
+msgstr ""
+
+msgid "specify cvsroot"
+msgstr ""
+
+msgid "show parent changesets"
+msgstr ""
+
+msgid "show current changeset in ancestor branches"
+msgstr ""
+
+msgid "ignored for compatibility"
+msgstr ""
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr ""
+
+msgid ""
+"warning: lightweight checkouts may cause conversion failures, try with a "
+"regular branch instead.\n"
+msgstr ""
+
+msgid "bzr source type could not be determined\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr ""
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr ""
+
+#, python-format
+msgid "%s.%s symlink has no target"
+msgstr ""
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr ""
+
+#, python-format
+msgid "running: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s error:\n"
+msgstr ""
+
+#, python-format
+msgid "%s %s"
+msgstr ""
+
+#, python-format
+msgid "syntax error in %s(%d): key/value pair expected"
+msgstr ""
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr ""
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr ""
+
+#, python-format
+msgid "convert: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "unknown sort mode: %s"
+msgstr ""
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr ""
+
+msgid "not all revisions were sorted"
+msgstr ""
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "overriding mapping for author %s, was %s, will be %s\n"
+msgstr ""
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr ""
+
+msgid "scanning source...\n"
+msgstr ""
+
+msgid "sorting...\n"
+msgstr ""
+
+msgid "converting...\n"
+msgstr ""
+
+#, python-format
+msgid "source: %s\n"
+msgstr ""
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr ""
+
+msgid "more than one sort mode specified"
+msgstr ""
+
+msgid "--sourcesort is not supported by this data source"
+msgstr ""
+
+msgid ""
+"warning: support for external cvsps is deprecated and will be removed in "
+"Mercurial 1.4\n"
+msgstr ""
+
+#, python-format
+msgid "revision %s is not a patchset number or date"
+msgstr ""
+
+msgid "using builtin cvsps\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr ""
+
+msgid "CVS pserver authentication failed"
+msgstr ""
+
+msgid "server sucks"
+msgstr ""
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr ""
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr ""
+
+msgid "collecting CVS rlog\n"
+msgstr ""
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr ""
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr ""
+
+#, python-format
+msgid "running %s\n"
+msgstr "εκτέλεση %s\n"
+
+#, python-format
+msgid "prefix=%r directory=%r root=%r\n"
+msgstr "Ï€Ïόθεμα=%r κατάλογος=%r αÏχικός-κατάλογος=%r\n"
+
+msgid "RCS file must be followed by working file"
+msgstr "το αÏχείο RCS Ï€Ïέπει να ακολουθείται από ένα αÏχείο εÏγασίας"
+
+msgid "must have at least some revisions"
+msgstr "Ï€Ïέπει να υπάÏχουν κάποιες εκδόσεις αÏχείων"
+
+msgid "expected revision number"
+msgstr "αναμένεται αÏιθμός έκδοσης αÏχείου"
+
+msgid "revision must be followed by date line"
+msgstr "η έκδοση αÏχείου Ï€Ïέπει να ακολουθείται από γÏαμμή ημεÏομηνίας"
+
+#, fuzzy, python-format
+msgid "found synthetic revision in %s: %r\n"
+msgstr ""
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr "αποθήκευση Ï€ÏοσωÏÎ¹Î½Î¿Ï Î±Î½Ï„Î¹Î³Ïάφου cvs log %s\n"
+
+#, python-format
+msgid "%d log entries\n"
+msgstr "%d εκδόσεις αÏχείων\n"
+
+msgid "creating changesets\n"
+msgstr "δημιουÏγία αλλαγών\n"
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: CVS commit message references non-existent branch %r:\n"
+"%s\n"
+msgstr ""
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr "%d αλλαγές\n"
+
+msgid "Python ElementTree module is not available"
+msgstr "δεν είναι διαθέσιμο το άÏθÏωμα ElementTree της Python"
+
+#, python-format
+msgid "cleaning up %s\n"
+msgstr "καθαÏισμός %s\n"
+
+msgid "internal calling inconsistency"
+msgstr "εσωτεÏικό Ï€Ïόβλημα κλήσης"
+
+msgid "errors in filemap"
+msgstr "λάθη στο filemap"
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr "%s:%d: η εγγÏαφή %r υπάÏχει ήδη στη λίστα %s\n"
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr "%s:%d: άγνωστη εντολή %r\n"
+
+msgid "source repository doesn't support --filemap"
+msgstr "το αποθετήÏιο πηγής δεν υποστηÏίζει την επιλογή --filemap"
+
+#, python-format
+msgid "%s does not look like a GNU Arch repo"
+msgstr "το %s δε φαίνεται να είναι αποθετήÏιο Arch"
+
+msgid "cannot find a GNU Arch tool"
+msgstr "δεν είναι διαθέσιμο το εÏγαλείο GNU Arch"
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr "ανάλυση καταλόγου αÏχείων για την έκδοση %s...\n"
+
+#, python-format
+msgid ""
+"tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr ""
+"η ανάλυση καταλόγου διακόπηκε επειδή πεÏιέχει αναφοÏά στην συλλογή αÏχείων %"
+"s, η οποία δεν υπάÏχει ή δεν είναι διαθέσιμη...\n"
+
+#, python-format
+msgid "applying revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "computing changeset between %s and %s...\n"
+msgstr ""
+
+#, python-format
+msgid "obtaining revision %s...\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "analyzing revision %s...\n"
+msgstr "ανάλυση καταλόγου αÏχείων για την έκδοση %s...\n"
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr ""
+
+#, python-format
+msgid "%s is not a local Mercurial repo"
+msgstr ""
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr ""
+
+msgid "run hg sink pre-conversion action\n"
+msgstr ""
+
+msgid "run hg sink post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr ""
+
+msgid "filtering out empty revision\n"
+msgstr ""
+
+msgid "updating tags\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr ""
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr ""
+
+msgid "run hg source pre-conversion action\n"
+msgstr ""
+
+msgid "run hg source post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a monotone repo"
+msgstr ""
+
+#, python-format
+msgid "copying file in renamed directory from '%s' to '%s'"
+msgstr ""
+
+#, fuzzy
+msgid "reading p4 views\n"
+msgstr "καθαÏισμός %s\n"
+
+#, fuzzy
+msgid "collecting p4 changelists\n"
+msgstr "δημιουÏγία αλλαγών\n"
+
+msgid "Subversion python bindings could not be loaded"
+msgstr ""
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr ""
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr ""
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr ""
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr ""
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr ""
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr ""
+
+msgid "svn: start revision is not supported with more than one branch"
+msgstr ""
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr ""
+
+#, python-format
+msgid "no tags found at revision %d\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring foreign branch %r\n"
+msgstr ""
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr ""
+
+#, python-format
+msgid "branch renamed from %s to %s at %d\n"
+msgstr ""
+
+#, python-format
+msgid "reparent to %s\n"
+msgstr ""
+
+#, python-format
+msgid "copied to %s from %s@%s\n"
+msgstr ""
+
+#, python-format
+msgid "gone from %s\n"
+msgstr ""
+
+#, python-format
+msgid "found parent directory %s\n"
+msgstr ""
+
+#, python-format
+msgid "base, entry %s %s\n"
+msgstr ""
+
+msgid "munge-o-matic\n"
+msgstr ""
+
+#, python-format
+msgid "info: %s %s %s %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown path in revision %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mark %s came from %s:%d\n"
+msgstr ""
+
+#, python-format
+msgid "parsing revision %d (%d changes)\n"
+msgstr ""
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr ""
+
+msgid "no copyfrom path, don't know what to do.\n"
+msgstr ""
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "skipping blacklisted revision %d\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d has no entries\n"
+msgstr ""
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr ""
+
+#, python-format
+msgid "%r is not under %r, ignoring\n"
+msgstr ""
+
+#, python-format
+msgid "initializing svn repo %r\n"
+msgstr ""
+
+#, python-format
+msgid "initializing svn wc %r\n"
+msgstr ""
+
+msgid "unexpected svn output:\n"
+msgstr ""
+
+msgid "unable to cope with svn output"
+msgstr ""
+
+msgid "XXX TAGS NOT IMPLEMENTED YET\n"
+msgstr ""
+
+msgid ""
+"\n"
+"The `extdiff' Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working directory. The external diff\n"
+"programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare.\n"
+"\n"
+"To enable this extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.extdiff =\n"
+"\n"
+"The `extdiff' extension also allows to configure new diff commands, so\n"
+"you do not need to type \"hg extdiff -p kdiff3\" always.\n"
+"\n"
+" [extdiff]\n"
+" # add new command that runs GNU diff(1) in 'context diff' mode\n"
+" cdiff = gdiff -Nprc5\n"
+" ## or the old way:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # add new command called vdiff, runs kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # add new command called meld, runs meld (no need to name twice)\n"
+" meld =\n"
+"\n"
+" # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+" # (see http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Non English user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" "
+"in\n"
+" # your .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"You can use -I/-X and list of file or directory names like normal \"hg\n"
+"diff\" command. The `extdiff' extension makes snapshots of only needed\n"
+"files, so running the external diff program will actually be pretty\n"
+"fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from working directory\n"
+msgstr ""
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr ""
+
+#, python-format
+msgid "running %r in %s\n"
+msgstr ""
+
+#, python-format
+msgid "file changed while diffing. Overwriting: %s (src: %s)\n"
+msgstr ""
+
+msgid "cleaning up temp directory\n"
+msgstr ""
+
+msgid ""
+"use external program to diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files, using\n"
+" an external program. The default program used is diff, with\n"
+" default options \"-Npru\".\n"
+"\n"
+" To select a different program, use the -p/--program option. The\n"
+" program will be passed the names of two directories to compare. To\n"
+" pass additional options to the program, use -o/--option. These\n"
+" will be passed before the names of the directories to compare.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent."
+msgstr ""
+
+msgid "comparison program to run"
+msgstr ""
+
+msgid "pass option to comparison program"
+msgstr ""
+
+msgid "change made by revision"
+msgstr ""
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr ""
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "pulling, updating and merging in one command"
+msgstr ""
+
+msgid ""
+"pull changes from a remote repository, merge new changes if needed.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository.\n"
+"\n"
+" If the pulled changes add a new branch head, the head is\n"
+" automatically merged, and the result of the merge is committed.\n"
+" Otherwise, the working directory is updated to include the new\n"
+" changes.\n"
+"\n"
+" When a merge occurs, the newly pulled changes are assumed to be\n"
+" \"authoritative\". The head of the new changes is used as the first\n"
+" parent, with local changes as the second. To switch the merge\n"
+" order, use --switch-parent.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid ""
+"working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+
+msgid "outstanding uncommitted merge"
+msgstr ""
+
+msgid "outstanding uncommitted changes"
+msgstr "υπάÏχουν τοπικές αλλαγές ακόμη"
+
+msgid "working directory is missing some files"
+msgstr "λείπουν οÏισμένα αÏχεία από το χώÏο εÏγασίας"
+
+msgid ""
+"multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr ""
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "Automated merge with %s"
+msgstr ""
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr ""
+
+msgid "a specific revision you would like to pull"
+msgstr ""
+
+msgid "edit commit message"
+msgstr ""
+
+msgid "edit commit message (DEPRECATED)"
+msgstr ""
+
+msgid "switch parents when merging"
+msgstr ""
+
+msgid "hg fetch [SOURCE]"
+msgstr ""
+
+msgid "error while verifying signature"
+msgstr ""
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr ""
+
+msgid "list signed changesets"
+msgstr ""
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr ""
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr ""
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr ""
+
+msgid ""
+"add a signature for the current or given revision\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr ""
+
+msgid "Error while signing"
+msgstr ""
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+
+#, python-format
+msgid "Added signature for changeset %s"
+msgstr ""
+
+msgid "unknown signature version"
+msgstr ""
+
+msgid "make the signature local"
+msgstr ""
+
+msgid "sign even if the sigfile is modified"
+msgstr ""
+
+msgid "do not commit the sigfile after signing"
+msgstr ""
+
+msgid "the key id to sign with"
+msgstr ""
+
+msgid "commit message"
+msgstr ""
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr ""
+
+msgid "hg sigcheck REVISION"
+msgstr ""
+
+msgid "hg sigs"
+msgstr ""
+
+msgid ""
+"show revision graphs in terminal windows\n"
+"\n"
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ASCII representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+
+#, python-format
+msgid "--graph option is incompatible with --%s"
+msgstr ""
+
+msgid ""
+"show revision history alongside an ASCII revision graph\n"
+"\n"
+" Print a revision history alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr "σÏγκÏιση με %s\n"
+
+msgid "no changes found\n"
+msgstr "δεν υπάÏχουν αλλαγές\n"
+
+msgid "show the revision DAG"
+msgstr ""
+
+msgid "limit number of changes displayed"
+msgstr ""
+
+msgid "show patch"
+msgstr "Ï€Ïοβολή patch"
+
+msgid "show the specified revision or range"
+msgstr ""
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr ""
+
+msgid ""
+"CIA notification\n"
+"\n"
+"This is meant to be run as a changegroup or incoming hook.\n"
+"To configure it, set the following options in your hgrc:\n"
+"\n"
+"[cia]\n"
+"# your registered CIA user name\n"
+"user = foo\n"
+"# the name of the project in CIA\n"
+"project = foo\n"
+"# the module (subproject) (optional)\n"
+"#module = foo\n"
+"# Append a diffstat to the log message (optional)\n"
+"#diffstat = False\n"
+"# Template to use for log messages (optional)\n"
+"#template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"# Style to use (optional)\n"
+"#style = foo\n"
+"# The URL of the CIA notification service (optional)\n"
+"# You can use mailto: URLs to send by email, eg\n"
+"# mailto:cia@cia.vc\n"
+"# Make sure to set email.from if you do this.\n"
+"#url = http://cia.vc/\n"
+"# print message instead of sending it (optional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# one of these:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# If you want hyperlinks (optional)\n"
+"baseurl = http://server/path/to/repo\n"
+msgstr ""
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr ""
+
+msgid "email.from must be defined when sending by email"
+msgstr ""
+
+msgid "cia: no user specified"
+msgstr ""
+
+msgid "cia: no project specified"
+msgstr ""
+
+msgid ""
+"browsing the repository in a graphical way\n"
+"\n"
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not\n"
+"distributed with Mercurial.)\n"
+"\n"
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to Mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and hgk.py can be found in the hgext directory.\n"
+"\n"
+"To load the hgext.py extension, add it to your .hgrc file (you have to\n"
+"use your global $HOME/.hgrc file, not one in a repository). You can\n"
+"specify an absolute path:\n"
+"\n"
+" [extensions]\n"
+" hgk=/usr/local/lib/hgk.py\n"
+"\n"
+"Mercurial can also scan the default python library path for a file\n"
+"named 'hgk.py' if you set hgk empty:\n"
+"\n"
+" [extensions]\n"
+" hgk=\n"
+"\n"
+"The hg view command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can specify\n"
+"the path to hgk in your .hgrc file:\n"
+"\n"
+" [hgk]\n"
+" path=/location/of/hgk\n"
+"\n"
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions."
+msgstr ""
+
+msgid "diff trees from two commits"
+msgstr ""
+
+msgid "output common ancestor information"
+msgstr ""
+
+msgid "cat a specific revision"
+msgstr ""
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr ""
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr ""
+
+msgid "parse given revisions"
+msgstr ""
+
+msgid "print revisions"
+msgstr ""
+
+msgid "print extension options"
+msgstr ""
+
+msgid "start interactive history viewer"
+msgstr ""
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr ""
+
+msgid "generate patch"
+msgstr ""
+
+msgid "recursive"
+msgstr ""
+
+msgid "pretty"
+msgstr ""
+
+msgid "stdin"
+msgstr ""
+
+msgid "detect copies"
+msgstr ""
+
+msgid "search"
+msgstr ""
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr ""
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr ""
+
+msgid "hg debug-config"
+msgstr ""
+
+msgid "hg debug-merge-base node node"
+msgstr ""
+
+msgid "ignored"
+msgstr ""
+
+msgid "hg debug-rev-parse REV"
+msgstr ""
+
+msgid "header"
+msgstr ""
+
+msgid "topo-order"
+msgstr ""
+
+msgid "parents"
+msgstr ""
+
+msgid "max-count"
+msgstr ""
+
+msgid "hg debug-rev-list [options] revs"
+msgstr ""
+
+msgid ""
+"syntax highlighting in hgweb, based on Pygments\n"
+"\n"
+"It depends on the Pygments syntax highlighting library:\n"
+"http://pygments.org/\n"
+"\n"
+"To enable the extension add this to hgrc:\n"
+"\n"
+"[extensions]\n"
+"hgext.highlight =\n"
+"\n"
+"There is a single configuration option:\n"
+"\n"
+"[web]\n"
+"pygments_style = <style>\n"
+"\n"
+"The default is 'colorful'.\n"
+"\n"
+"-- Adam Hupp <adam@hupp.org>\n"
+msgstr ""
+
+msgid "inotify-based status acceleration for Linux systems\n"
+msgstr ""
+
+msgid "start an inotify server for this repository"
+msgstr ""
+
+msgid ""
+"debugging information for inotify extension\n"
+"\n"
+" Prints the list of directories being watched by the inotify server.\n"
+" "
+msgstr ""
+
+msgid "directories being watched:\n"
+msgstr ""
+
+msgid "run server in background"
+msgstr ""
+
+msgid "used internally by daemon mode"
+msgstr ""
+
+msgid "minutes to sit idle before exiting"
+msgstr ""
+
+msgid "name of file to write process ID to"
+msgstr ""
+
+msgid "hg inserve [OPT]..."
+msgstr ""
+
+msgid "(found dead inotify server socket; removing it)\n"
+msgstr ""
+
+msgid "(starting inotify server)\n"
+msgstr ""
+
+#, python-format
+msgid "could not start inotify server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "could not talk to new inotify server: %s\n"
+msgstr ""
+
+msgid "(inotify server not running)\n"
+msgstr ""
+
+#, python-format
+msgid "failed to contact inotify server: %s\n"
+msgstr ""
+
+msgid "received empty answer from inotify server"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received '%s' response when expecting '%s')\n"
+msgstr ""
+
+msgid "this system does not seem to support inotify"
+msgstr ""
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr ""
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr ""
+
+msgid "*** counting directories: "
+msgstr ""
+
+#, python-format
+msgid "found %d\n"
+msgstr ""
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr ""
+
+#, python-format
+msgid "*** echo %d > %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr ""
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr ""
+
+#, python-format
+msgid "watching %r\n"
+msgstr ""
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r dir(%d) -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s dirstate reload\n"
+msgstr ""
+
+#, python-format
+msgid "%s end dirstate reload\n"
+msgstr ""
+
+msgid "rescanning due to .hgignore change\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr ""
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr ""
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr ""
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr ""
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr ""
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr ""
+
+#, python-format
+msgid "could not start server: %s"
+msgstr ""
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr ""
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr ""
+
+#, python-format
+msgid "unrecognized query type: %s\n"
+msgstr ""
+
+msgid "finished setup\n"
+msgstr ""
+
+msgid ""
+"expand expressions into changelog and summaries\n"
+"\n"
+"This extension allows the use of a special syntax in summaries,\n"
+"which will be automatically expanded into links or any other\n"
+"arbitrary expression, much like InterWiki does.\n"
+"\n"
+"To enable this extension, add the following lines to your hgrc:\n"
+"\n"
+" [extensions]\n"
+" interhg =\n"
+"\n"
+"A few example patterns (link to bug tracking, etc.):\n"
+"\n"
+" [interhg]\n"
+" issues = s!issue(\\d+)!<a href=\"http://bts/issue\\1\">issue\\1</a>!\n"
+" bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2\">\\1</a>!"
+"i\n"
+" boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr ""
+
+msgid ""
+"keyword expansion in tracked files\n"
+"\n"
+"This extension expands RCS/CVS-like or self-customized $Keywords$ in\n"
+"tracked text files selected by your configuration.\n"
+"\n"
+"Keywords are only expanded in local repositories and not stored in the\n"
+"change history. The mechanism can be regarded as a convenience for the\n"
+"current user or for archive distribution.\n"
+"\n"
+"Configuration is done in the [keyword] and [keywordmaps] sections of\n"
+"hgrc files.\n"
+"\n"
+"Example:\n"
+"\n"
+" [keyword]\n"
+" # expand keywords in every python file except those matching \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Note: the more specific you are in your filename patterns\n"
+" the less you lose speed in huge repositories.\n"
+"\n"
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run \"hg kwdemo\".\n"
+"\n"
+"An additional date template filter {date|utcdate} is provided.\n"
+"\n"
+"The default template mappings (view with \"hg kwdemo -d\") can be\n"
+"replaced with customized keywords and templates. Again, run \"hg\n"
+"kwdemo\" to control the results of your config changes.\n"
+"\n"
+"Before changing/disabling active keywords, run \"hg kwshrink\" to avoid\n"
+"the risk of inadvertently storing expanded keywords in the change\n"
+"history.\n"
+"\n"
+"To force expansion after enabling it, or a configuration change, run\n"
+"\"hg kwexpand\".\n"
+"\n"
+"Also, when committing with the record extension or using mq's qrecord,\n"
+"be aware that keywords cannot be updated. Again, run \"hg kwexpand\" on\n"
+"the files in question to update keyword expansions after all changes\n"
+"have been checked in.\n"
+"\n"
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map\n"
+"\"Log = {desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s expanding keywords\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s shrinking keywords\n"
+msgstr ""
+
+msgid "[keyword] patterns cannot match"
+msgstr ""
+
+msgid "no [keyword] patterns configured"
+msgstr ""
+
+msgid ""
+"print [keywordmaps] configuration and an expansion example\n"
+"\n"
+" Show current, custom, or default keyword template maps and their\n"
+" expansions.\n"
+"\n"
+" Extend current configuration by specifying maps as arguments and\n"
+" optionally by reading from an additional hgrc file.\n"
+"\n"
+" Override current keyword template maps with \"default\" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"\t%s\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "creating temporary repository at %s\n"
+msgstr "δημιουÏγία αποθετηÏίου για το queue"
+
+#, python-format
+msgid ""
+"\n"
+"%s keywords written to %s:\n"
+msgstr ""
+
+msgid "unhooked all commit hooks\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"removing temporary repository %s\n"
+msgstr ""
+
+msgid ""
+"expand keywords in the working directory\n"
+"\n"
+" Run after (re)enabling keyword expansion.\n"
+"\n"
+" kwexpand refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid ""
+"print files currently configured for keyword expansion\n"
+"\n"
+" Crosscheck which files in working directory are potential targets\n"
+" for keyword expansion. That is, files matched by [keyword] config\n"
+" patterns but not symlinks.\n"
+" "
+msgstr ""
+
+msgid ""
+"revert expanded keywords in the working directory\n"
+"\n"
+" Run before changing/disabling active keywords or if you experience\n"
+" problems with \"hg import\" or \"hg merge\".\n"
+"\n"
+" kwshrink refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid "show default keyword template maps"
+msgstr ""
+
+msgid "read maps from rcfile"
+msgstr ""
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr ""
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "show keyword status flags of all files"
+msgstr ""
+
+msgid "show files excluded from expansion"
+msgstr ""
+
+msgid "additionally show untracked files"
+msgstr ""
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr ""
+
+#, fuzzy
+msgid ""
+"patch management and development\n"
+"\n"
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches).\n"
+"\n"
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets.\n"
+"\n"
+"Common tasks (use \"hg help command\" for more details):\n"
+"\n"
+"prepare repository to work with patches qinit\n"
+"create new patch qnew\n"
+"import existing patch qimport\n"
+"\n"
+"print patch series qseries\n"
+"print applied patches qapplied\n"
+"print name of top applied patch qtop\n"
+"\n"
+"add known patch to applied stack qpush\n"
+"remove patch from applied stack qpop\n"
+"refresh contents of top applied patch qrefresh\n"
+msgstr ""
+"udvikling og håndtering af patches\n"
+"\n"
+"Denne udvidelse lader dig arbejde med en stak af patches i et\n"
+"Mercurial repository. Den håndterer to stakke af patches - alle kendte\n"
+"patches og alle anvendte patches (en delmængde af de kendte patches).\n"
+"\n"
+"Kendte patches er repræsenteret som patch-filer i .hg/patches\n"
+"biblioteket. Anvendte patches er både patch-filer og Mercurial\n"
+"ændringer.\n"
+"\n"
+"Almindelige opgaver (brug \"hg help kommado\" for flere detaljer):\n"
+"\n"
+"forbered repository til at arbejde med patches qinit\n"
+"opret ny patch qnew\n"
+"importer eksisterende patch qimport\n"
+"\n"
+"list patch-serien qseries\n"
+"list anvendte patches qapplied\n"
+"list navnet på den øverste patch qtop\n"
+"\n"
+"anvend og put patch på stakken qpush\n"
+"fjern patch fra stakken qpop\n"
+"genopfrisk indholdet af den øverste patch qrefresh\n"
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr ""
+
+msgid "guard cannot be an empty string"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr ""
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr ""
+
+#, python-format
+msgid "active guards: %s\n"
+msgstr ""
+
+#, python-format
+msgid "guard %r too short"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr ""
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr ""
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "update returned %d"
+msgstr ""
+
+msgid "repo commit failed"
+msgstr ""
+
+#, python-format
+msgid "unable to read %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr ""
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr ""
+
+#, python-format
+msgid "applying %s\n"
+msgstr ""
+
+#, python-format
+msgid "Unable to read %s\n"
+msgstr ""
+
+#, python-format
+msgid "imported patch %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"imported patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr ""
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr ""
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr ""
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr ""
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr ""
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr ""
+
+msgid "no patches applied"
+msgstr ""
+
+msgid "working directory revision is not qtip"
+msgstr ""
+
+msgid "local changes found, refresh first"
+msgstr ""
+
+msgid "local changes found"
+msgstr ""
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr ""
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr ""
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series"
+msgstr ""
+
+#, fuzzy
+msgid "(working directory not at a head)\n"
+msgstr "χώÏος εÏγασίας του %s"
+
+msgid "no patches in series\n"
+msgstr ""
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr ""
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr ""
+
+#, python-format
+msgid "guarded by %r"
+msgstr ""
+
+msgid "no matching guards"
+msgstr ""
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr ""
+
+msgid "all patches are currently applied\n"
+msgstr ""
+
+msgid "patch series already fully applied\n"
+msgstr ""
+
+msgid "cleaning up working directory..."
+msgstr ""
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr ""
+
+#, python-format
+msgid "now at: %s\n"
+msgstr "τώÏα στο: %s\n"
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr ""
+
+msgid "no patches applied\n"
+msgstr ""
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr ""
+
+msgid "qpop: forcing dirstate update\n"
+msgstr ""
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr ""
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr ""
+
+msgid "deletions found between repo revs"
+msgstr ""
+
+msgid "patch queue now empty\n"
+msgstr ""
+
+msgid "cannot refresh a revision with children"
+msgstr ""
+
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to "
+"recover)\n"
+msgstr ""
+
+msgid "patch queue directory already exists"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr ""
+
+msgid "No saved patch data found\n"
+msgstr ""
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr ""
+
+msgid "save entry has children, leaving it alone\n"
+msgstr ""
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr ""
+
+msgid "queue directory updating\n"
+msgstr ""
+
+msgid "Unable to load queue repository\n"
+msgstr ""
+
+msgid "save: no patches applied, exiting\n"
+msgstr ""
+
+msgid "status is already saved\n"
+msgstr ""
+
+msgid "hg patches saved state"
+msgstr ""
+
+msgid "repo commit failed\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr ""
+
+msgid "option \"-r\" not valid when importing files"
+msgstr ""
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr ""
+
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr ""
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr ""
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr ""
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr ""
+
+msgid "-e is incompatible with import from -"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr ""
+
+msgid "need --name to import a patch from -"
+msgstr ""
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr ""
+
+msgid ""
+"remove patches from queue\n"
+"\n"
+" The patches must not be applied, unless they are arguments to the\n"
+" -r/--rev parameter. At least one patch or revision is required.\n"
+"\n"
+" With --rev, mq will stop managing the named revisions (converting\n"
+" them to regular Mercurial changesets). The qfinish command should\n"
+" be used as an alternative for qdelete -r, as the latter option is\n"
+" deprecated.\n"
+"\n"
+" With -k/--keep, the patch files are preserved in the patch\n"
+" directory."
+msgstr ""
+
+msgid "print the patches already applied"
+msgstr ""
+
+msgid "print the patches not yet applied"
+msgstr ""
+
+msgid ""
+"import a patch\n"
+"\n"
+" The patch is inserted into the series after the last applied\n"
+" patch. If no patches have been applied, qimport prepends the patch\n"
+" to the series.\n"
+"\n"
+" The patch will have the same name as its source file unless you\n"
+" give it a new one with -n/--name.\n"
+"\n"
+" You can register an existing patch inside the patch directory with\n"
+" the -e/--existing flag.\n"
+"\n"
+" With -f/--force, an existing patch of the same name will be\n"
+" overwritten.\n"
+"\n"
+" An existing changeset may be placed under mq control with -r/--rev\n"
+" (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+" With -g/--git, patches imported with --rev will use the git diff\n"
+" format. See the diffs help topic for information on why this is\n"
+" important for preserving rename/copy information and permission\n"
+" changes.\n"
+"\n"
+" To import a patch from standard input, pass - as the patch file.\n"
+" When importing from standard input, a patch name must be specified\n"
+" using the --name flag.\n"
+" "
+msgstr ""
+
+msgid ""
+"init a new queue repository\n"
+"\n"
+" The queue repository is unversioned by default. If\n"
+" -c/--create-repo is specified, qinit will create a separate nested\n"
+" repository for patches (qinit -c may also be run later to convert\n"
+" an unversioned patch repository into a versioned one). You can use\n"
+" qcommit to commit changes to this queue repository."
+msgstr ""
+
+msgid ""
+"clone main and patch repository at same time\n"
+"\n"
+" If source is local, destination will have no patches applied. If\n"
+" source is remote, this command can not check if patches are\n"
+" applied in source, so cannot guarantee that patches are not\n"
+" applied in destination. If you clone remote repository, be sure\n"
+" before that it has no patches applied.\n"
+"\n"
+" Source patch repository is looked for in <src>/.hg/patches by\n"
+" default. Use -p <url> to change.\n"
+"\n"
+" The patch directory must be a nested Mercurial repository, as\n"
+" would be created by qinit -c.\n"
+" "
+msgstr ""
+
+msgid "versioned patch repository not found (see qinit -c)"
+msgstr ""
+
+#, fuzzy
+msgid "cloning main repository\n"
+msgstr ""
+
+#, fuzzy
+msgid "cloning patch repository\n"
+msgstr "δε μποÏεί να δημιουÏγηθεί ένα νέο αποθετήÏιο μέσω http"
+
+msgid "stripping applied patches from destination repository\n"
+msgstr ""
+
+#, fuzzy
+msgid "updating destination repository\n"
+msgstr ""
+
+msgid "commit changes in the queue repository"
+msgstr ""
+
+msgid "print the entire series file"
+msgstr ""
+
+msgid "print the name of the current patch"
+msgstr ""
+
+msgid "print the name of the next patch"
+msgstr ""
+
+msgid "all patches applied\n"
+msgstr "όλα τα patches έχουν εφαÏμοστεί\n"
+
+msgid "print the name of the previous patch"
+msgstr "Ï€Ïοβολή του ονόματος του Ï€ÏοηγοÏμενου patch"
+
+msgid "only one patch applied\n"
+msgstr "μόνο ένα patch έχει εφαÏμοστεί\n"
+
+msgid ""
+"create a new patch\n"
+"\n"
+" qnew creates a new patch on top of the currently-applied patch (if\n"
+" any). It will refuse to run if there are any outstanding changes\n"
+" unless -f/--force is specified, in which case the patch will be\n"
+" initialized with them. You may also use -I/--include,\n"
+" -X/--exclude, and/or a list of files after the patch name to add\n"
+" only changes to matching files to the new patch, leaving the rest\n"
+" as uncommitted modifications.\n"
+"\n"
+" -u/--user and -d/--date can be used to set the (given) user and\n"
+" date, respectively. -U/--currentuser and -D/--currentdate set user\n"
+" to current user and date to current date.\n"
+"\n"
+" -e/--edit, -m/--message or -l/--logfile set the patch header as\n"
+" well as the commit message. If none is specified, the header is\n"
+" empty and the commit message is '[mq]: PATCH'.\n"
+"\n"
+" Use the -g/--git option to keep the patch in the git extended diff\n"
+" format. Read the diffs help topic for more information on why this\n"
+" is important for preserving permission changes and copy/rename\n"
+" information.\n"
+" "
+msgstr ""
+
+msgid ""
+"update the current patch\n"
+"\n"
+" If any file patterns are provided, the refreshed patch will\n"
+" contain only the modifications that match those patterns; the\n"
+" remaining modifications will remain in the working directory.\n"
+"\n"
+" If -s/--short is specified, files currently included in the patch\n"
+" will be refreshed just like matched files and remain in the patch.\n"
+"\n"
+" hg add/remove/copy/rename work as usual, though you might want to\n"
+" use git-style patches (-g/--git or [diff] git=1) to track copies\n"
+" and renames. See the diffs help topic for more information on the\n"
+" git diff format.\n"
+" "
+msgstr ""
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr ""
+
+msgid ""
+"diff of the current patch and subsequent modifications\n"
+"\n"
+" Shows a diff which includes the current patch as well as any\n"
+" changes which have been made in the working directory since the\n"
+" last refresh (thus showing what the current patch would become\n"
+" after a qrefresh).\n"
+"\n"
+" Use 'hg diff' if you only want to see the changes made since the\n"
+" last qrefresh, or 'hg export qtip' if you want to see changes made\n"
+" by the current patch without including changes made since the\n"
+" qrefresh.\n"
+" "
+msgstr ""
+
+msgid ""
+"fold the named patches into the current patch\n"
+"\n"
+" Patches must not yet be applied. Each patch will be successively\n"
+" applied to the current patch in the order given. If all the\n"
+" patches apply successfully, the current patch will be refreshed\n"
+" with the new cumulative patch, and the folded patches will be\n"
+" deleted. With -k/--keep, the folded patch files will not be\n"
+" removed afterwards.\n"
+"\n"
+" The header for each folded patch will be concatenated with the\n"
+" current patch header, separated by a line of '* * *'."
+msgstr ""
+
+msgid "qfold requires at least one patch name"
+msgstr ""
+
+msgid "No patches applied"
+msgstr ""
+
+#, python-format
+msgid "Skipping already folded patch %s"
+msgstr ""
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "Error folding patch %s"
+msgstr ""
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr ""
+
+msgid ""
+"set or print guards for a patch\n"
+"\n"
+" Guards control whether a patch can be pushed. A patch with no\n"
+" guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+" pushed only if the qselect command has activated it. A patch with\n"
+" a negative guard (\"-foo\") is never pushed if the qselect command\n"
+" has activated it.\n"
+"\n"
+" With no arguments, print the currently active guards.\n"
+" With arguments, set guards for the named patch.\n"
+" NOTE: Specifying negative guards now requires '--'.\n"
+"\n"
+" To set guards on another patch:\n"
+" hg qguard -- other.patch +2.6.17 -stable\n"
+" "
+msgstr ""
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr ""
+
+msgid "no patch to work with"
+msgstr ""
+
+#, python-format
+msgid "no patch named %s"
+msgstr ""
+
+msgid "print the header of the topmost or specified patch"
+msgstr ""
+
+msgid ""
+"push the next patch onto the stack\n"
+"\n"
+" When -f/--force is applied, all local changes in patched files\n"
+" will be lost.\n"
+" "
+msgstr ""
+
+msgid "no saved queues found, please use -n\n"
+msgstr ""
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr ""
+
+msgid ""
+"pop the current patch off the stack\n"
+"\n"
+" By default, pops off the top of the patch stack. If given a patch\n"
+" name, keeps popping off patches until the named patch is at the\n"
+" top of the stack.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr ""
+
+msgid ""
+"rename a patch\n"
+"\n"
+" With one argument, renames the current patch to PATCH1.\n"
+" With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+
+#, python-format
+msgid "%s already exists"
+msgstr ""
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr ""
+
+msgid "restore the queue state saved by a revision"
+msgstr ""
+
+msgid "save current queue state"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr ""
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr ""
+
+msgid ""
+"strip a revision and all its descendants from the repository\n"
+"\n"
+" If one of the working directory's parent revisions is stripped, the\n"
+" working directory will be updated to the parent of the stripped\n"
+" revision.\n"
+" "
+msgstr ""
+
+msgid ""
+"set or print guarded patches to push\n"
+"\n"
+" Use the qguard command to set or print guards on patch, then use\n"
+" qselect to tell mq which guards to use. A patch will be pushed if\n"
+" it has no guards or any positive guards match the currently\n"
+" selected guard, but will not be pushed if any negative guards\n"
+" match the current guard. For example:\n"
+"\n"
+" qguard foo.patch -stable (negative guard)\n"
+" qguard bar.patch +stable (positive guard)\n"
+" qselect stable\n"
+"\n"
+" This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+" it has a negative match) but push bar.patch (because it has a\n"
+" positive match).\n"
+"\n"
+" With no arguments, prints the currently active guards.\n"
+" With one argument, sets the active guard.\n"
+"\n"
+" Use -n/--none to deactivate guards (no other arguments needed).\n"
+" When no guards are active, patches with positive guards are\n"
+" skipped and patches with negative guards are pushed.\n"
+"\n"
+" qselect can change the guards on applied patches. It does not pop\n"
+" guarded patches by default. Use --pop to pop back to the last\n"
+" applied patch that is not guarded. Use --reapply (which implies\n"
+" --pop) to push back to the current patch afterwards, but skip\n"
+" guarded patches.\n"
+"\n"
+" Use -s/--series to print a list of all guards in the series file\n"
+" (no other arguments needed). Use -v for more information."
+msgstr ""
+
+msgid "guards deactivated\n"
+msgstr ""
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr ""
+
+msgid "guards in series file:\n"
+msgstr ""
+
+msgid "no guards in series file\n"
+msgstr ""
+
+msgid "active guards:\n"
+msgstr ""
+
+msgid "no active guards\n"
+msgstr ""
+
+msgid "popping guarded patches\n"
+msgstr ""
+
+msgid "reapplying unguarded patches\n"
+msgstr ""
+
+msgid ""
+"move applied patches into repository history\n"
+"\n"
+" Finishes the specified revisions (corresponding to applied\n"
+" patches) by moving them out of mq control into regular repository\n"
+" history.\n"
+"\n"
+" Accepts a revision range or the -a/--applied option. If --applied\n"
+" is specified, all applied mq revisions are removed from mq\n"
+" control. Otherwise, the given revisions must be at the base of the\n"
+" stack of applied patches.\n"
+"\n"
+" This can be especially useful if your changes have been applied to\n"
+" an upstream repository, or if you are about to push your changes\n"
+" to upstream.\n"
+" "
+msgstr ""
+
+msgid "no revisions specified"
+msgstr ""
+
+msgid "cannot commit over an applied mq patch"
+msgstr ""
+
+msgid "source has mq patches applied"
+msgstr ""
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr ""
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr ""
+
+msgid "cannot import over an applied patch"
+msgstr ""
+
+msgid "print first line of patch header"
+msgstr ""
+
+msgid "hg qapplied [-s] [PATCH]"
+msgstr ""
+
+msgid "use pull protocol to copy metadata"
+msgstr ""
+
+msgid "do not update the new working directories"
+msgstr ""
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr ""
+
+#, fuzzy
+msgid "location of source patch repository"
+msgstr "δε μποÏεί να δημιουÏγηθεί ένα νέο αποθετήÏιο μέσω http"
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr ""
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "keep patch file"
+msgstr ""
+
+msgid "stop managing a revision"
+msgstr ""
+
+msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
+msgstr ""
+
+msgid "edit patch header"
+msgstr ""
+
+msgid "keep folded patch files"
+msgstr ""
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr ""
+
+msgid "overwrite any local changes"
+msgstr ""
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr ""
+
+msgid "list all patches and guards"
+msgstr ""
+
+msgid "drop all guards"
+msgstr ""
+
+msgid "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+msgstr ""
+
+msgid "hg qheader [PATCH]"
+msgstr ""
+
+msgid "import file in patch directory"
+msgstr ""
+
+#, fuzzy
+msgid "name of patch file"
+msgstr ""
+
+msgid "overwrite existing files"
+msgstr ""
+
+msgid "place existing revisions under mq control"
+msgstr ""
+
+msgid "use git extended diff format"
+msgstr "χÏήση των επεκτάσεων του git για τα αÏχεία diff"
+
+msgid "qpush after importing"
+msgstr ""
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr ""
+
+msgid "create queue repository"
+msgstr "δημιουÏγία αποθετηÏίου για το queue"
+
+msgid "hg qinit [-c]"
+msgstr ""
+
+msgid "import uncommitted changes into patch"
+msgstr "ενσωμάτωση τοπικών αλλαγών στο patch"
+
+msgid "add \"From: <current user>\" to patch"
+msgstr ""
+
+msgid "add \"From: <given user>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <given date>\" to patch"
+msgstr ""
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+msgstr ""
+
+msgid "hg qnext [-s]"
+msgstr ""
+
+msgid "hg qprev [-s]"
+msgstr ""
+
+msgid "pop all patches"
+msgstr "αφαίÏεση όλων των patches"
+
+msgid "queue name to pop"
+msgstr ""
+
+msgid "forget any local changes"
+msgstr "ακÏÏωση όλων των τοπικών αλλαγών"
+
+msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+msgstr ""
+
+msgid "apply if the patch has rejects"
+msgstr ""
+
+msgid "list patch name in commit text"
+msgstr ""
+
+msgid "apply all patches"
+msgstr ""
+
+msgid "merge from another queue"
+msgstr ""
+
+msgid "merge queue name"
+msgstr ""
+
+msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+msgstr ""
+
+msgid "refresh only files already in the patch and specified files"
+msgstr ""
+
+msgid "add/update \"From: <current user>\" in patch"
+msgstr ""
+
+msgid "add/update \"From: <given user>\" in patch"
+msgstr ""
+
+msgid "update \"Date: <current date>\" in patch (if present)"
+msgstr ""
+
+msgid "update \"Date: <given date>\" in patch (if present)"
+msgstr ""
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr ""
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr ""
+
+msgid "delete save entry"
+msgstr ""
+
+#, fuzzy
+msgid "update queue working directory"
+msgstr "χώÏος εÏγασίας του %s"
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr ""
+
+msgid "copy patch directory"
+msgstr ""
+
+msgid "copy directory name"
+msgstr ""
+
+msgid "clear queue status file"
+msgstr ""
+
+msgid "force copy"
+msgstr ""
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr ""
+
+msgid "disable all guards"
+msgstr ""
+
+msgid "list all guards in series file"
+msgstr ""
+
+msgid "pop to before first guarded applied patch"
+msgstr ""
+
+msgid "pop, then reapply patches"
+msgstr ""
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr ""
+
+msgid "print patches not in series"
+msgstr ""
+
+msgid "hg qseries [-ms]"
+msgstr ""
+
+msgid "force removal with local changes"
+msgstr ""
+
+msgid "bundle unrelated changesets"
+msgstr ""
+
+msgid "no backups"
+msgstr ""
+
+msgid "hg strip [-f] [-b] [-n] REV"
+msgstr ""
+
+msgid "hg qtop [-s]"
+msgstr ""
+
+msgid "hg qunapplied [-s] [PATCH]"
+msgstr ""
+
+msgid "finish all applied changesets"
+msgstr ""
+
+msgid "hg qfinish [-a] [REV...]"
+msgstr ""
+
+msgid ""
+"hook extension to email notifications on commits/pushes\n"
+"\n"
+"Subscriptions can be managed through hgrc. Default mode is to print\n"
+"messages to stdout, for testing and configuring.\n"
+"\n"
+"To use, configure notify extension and enable in hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # one email for each incoming changeset\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # batch emails when many changesets incoming at one time\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # config items go in here\n"
+"\n"
+" config items:\n"
+"\n"
+" REQUIRED:\n"
+" config = /path/to/file # file containing subscriptions\n"
+"\n"
+" OPTIONAL:\n"
+" test = True # print messages to stdout for testing\n"
+" strip = 3 # number of slashes to strip for url paths\n"
+" domain = example.com # domain to use if committer missing domain\n"
+" style = ... # style file to use when formatting email\n"
+" template = ... # template to use when formatting email\n"
+" incoming = ... # template to use when run as incoming hook\n"
+" changegroup = ... # template when run as changegroup hook\n"
+" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n"
+" maxsubject = 67 # truncate subject line longer than this\n"
+" diffstat = True # add a diffstat before the diff content\n"
+" sources = serve # notify if source of incoming changes in this "
+"list\n"
+" # (serve == ssh or http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # email address to send as if none given\n"
+" [web]\n"
+" baseurl = http://hgserver/... # root of hg web site for browsing commits\n"
+"\n"
+" notify config file has same format as regular hgrc. it has two\n"
+" sections so you can express subscriptions in whatever way is handier\n"
+" for you.\n"
+"\n"
+" [usersubs]\n"
+" # key is subscriber email, value is \",\"-separated list of glob "
+"patterns\n"
+" user@host = pattern\n"
+"\n"
+" [reposubs]\n"
+" # key is glob pattern, value is \",\"-separated list of subscriber "
+"emails\n"
+" pattern = user@host\n"
+"\n"
+" glob patterns are matched against path to repository root.\n"
+"\n"
+" if you like, you can put notify config file in repository that users\n"
+" can push changes to, they can manage their own subscriptions."
+msgstr ""
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr ""
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "notify: no subscribers to repository %s\n"
+msgstr ""
+
+#, python-format
+msgid "notify: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+msgid ""
+"browse command output with external pager\n"
+"\n"
+"To set the pager that should be used, set the application variable:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"If no pager is set, the pager extensions uses the environment variable\n"
+"$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.\n"
+"\n"
+"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
+"setting:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"You can also enable the pager only for certain commands using\n"
+"pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"If pager.attend is present, pager.ignore will be ignored.\n"
+"\n"
+"To ignore global commands like \"hg version\" or \"hg help\", you have to\n"
+"specify them in the global .hgrc\n"
+msgstr ""
+
+msgid ""
+"use suffixes to refer to ancestor revisions\n"
+"\n"
+"This extension allows you to use git-style suffixes to refer to the\n"
+"ancestors of a specific revision.\n"
+"\n"
+"For example, if you can refer to a revision as \"foo\", then:\n"
+"\n"
+"- foo^N = Nth parent of foo\n"
+" foo^0 = foo\n"
+" foo^1 = first parent of foo\n"
+" foo^2 = second parent of foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nth first grandparent of foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = first parent of foo\n"
+" foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
+msgstr ""
+
+msgid ""
+"sending Mercurial changesets as a series of patch emails\n"
+"\n"
+"The series is started off with a \"[PATCH 0 of N]\" introduction, which\n"
+"describes the series as a whole.\n"
+"\n"
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using the\n"
+"first line of the changeset description as the subject text. The\n"
+"message contains two or three body parts:\n"
+"\n"
+" The changeset description.\n"
+"\n"
+" [Optional] The result of running diffstat on the patch.\n"
+"\n"
+" The patch itself, as generated by \"hg export\".\n"
+"\n"
+"Each message refers to the first in the series using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in threaded\n"
+"mail and news readers, and in mail archives.\n"
+"\n"
+"With the -d/--diffstat option, you will be prompted for each changeset\n"
+"with a diffstat summary and the changeset summary, so you can be sure\n"
+"you are sending the right changes.\n"
+"\n"
+"To enable this extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.patchbomb =\n"
+"\n"
+"To configure other defaults, add a section like this to your hgrc\n"
+"file:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Then you can use the \"hg email\" command to mail a series of changesets\n"
+"as a patchbomb.\n"
+"\n"
+"To avoid sending patches prematurely, it is a good idea to first run\n"
+"the \"email\" command with the \"-n\" option (test only). You will be\n"
+"prompted for an email recipient address, a subject and an introductory\n"
+"message describing the patches of your patchbomb. Then when all is\n"
+"done, patchbomb messages are displayed. If the PAGER environment\n"
+"variable is set, your pager will be fired up once for each patchbomb\n"
+"message, so you can verify everything is alright.\n"
+"\n"
+"The -m/--mbox option is also very useful. Instead of previewing each\n"
+"patchbomb message in a pager or sending the messages directly, it will\n"
+"create a UNIX mailbox file with the patch emails. This mailbox file\n"
+"can be previewed with any mail user agent which supports UNIX mbox\n"
+"files, e.g. with mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"When you are previewing the patchbomb messages, you can use `formail'\n"
+"(a utility that is commonly installed as part of the procmail\n"
+"package), to send each message out:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"That should be all. Now your patchbomb is on its way out.\n"
+"\n"
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatible mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs\n"
+"directly from the commandline. See the [email] and [smtp] sections in\n"
+"hgrc(5) for details."
+msgstr ""
+
+msgid "Please enter a valid value.\n"
+msgstr ""
+
+msgid "does the diffstat above look okay? "
+msgstr ""
+
+msgid "diffstat rejected"
+msgstr ""
+
+msgid ""
+"send changesets by email\n"
+"\n"
+" By default, diffs are sent in the format generated by hg export,\n"
+" one per message. The series starts with a \"[PATCH 0 of N]\"\n"
+" introduction, which describes the series as a whole.\n"
+"\n"
+" Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+" the first line of the changeset description as the subject text.\n"
+" The message contains two or three parts. First, the changeset\n"
+" description. Next, (optionally) if the diffstat program is\n"
+" installed and -d/--diffstat is used, the result of running\n"
+" diffstat on the patch. Finally, the patch itself, as generated by\n"
+" \"hg export\".\n"
+"\n"
+" By default the patch is included as text in the email body for\n"
+" easy reviewing. Using the -a/--attach option will instead create\n"
+" an attachment for the patch. With -i/--inline an inline attachment\n"
+" will be created.\n"
+"\n"
+" With -o/--outgoing, emails will be generated for patches not found\n"
+" in the destination repository (or only those which are ancestors\n"
+" of the specified revisions if any are provided)\n"
+"\n"
+" With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+" single email containing a binary Mercurial bundle as an attachment\n"
+" will be sent.\n"
+"\n"
+" Examples:\n"
+"\n"
+" hg email -r 3000 # send patch 3000 only\n"
+" hg email -r 3000 -r 3001 # send patches 3000 and 3001\n"
+" hg email -r 3000:3005 # send patches 3000 through 3005\n"
+" hg email 3000 # send patch 3000 (deprecated)\n"
+"\n"
+" hg email -o # send all patches not in default\n"
+" hg email -o DEST # send all patches not in DEST\n"
+" hg email -o -r 3000 # send all ancestors of 3000 not in default\n"
+" hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST\n"
+"\n"
+" hg email -b # send bundle of all patches not in default\n"
+" hg email -b DEST # send bundle of all patches not in DEST\n"
+" hg email -b -r 3000 # bundle of all ancestors of 3000 not in "
+"default\n"
+" hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST\n"
+"\n"
+" Before using this command, you will need to enable email in your\n"
+" hgrc. See the [email] section in hgrc(5) for details.\n"
+" "
+msgstr ""
+
+msgid "specify at least one changeset with -r or -o"
+msgstr "οÏίστε τουλάχιστον μια αλλαγή με -r ή -o"
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr ""
+
+msgid "too many destinations"
+msgstr "Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î¿Ï‚ αÏιθμός παÏαληπτών"
+
+msgid "use only one form to specify the revision"
+msgstr ""
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series.\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"This patch series consists of %d patches.\n"
+"\n"
+msgstr ""
+
+msgid "Final summary:\n"
+msgstr ""
+
+msgid "Displaying "
+msgstr ""
+
+msgid "Writing "
+msgstr ""
+
+msgid "Sending "
+msgstr ""
+
+msgid "send patches as attachments"
+msgstr ""
+
+msgid "send patches as inline attachments"
+msgstr ""
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr ""
+
+msgid "email addresses of copy recipients"
+msgstr ""
+
+msgid "add diffstat output to messages"
+msgstr ""
+
+msgid "use the given date as the sending date"
+msgstr ""
+
+msgid "use the given file as the series description"
+msgstr ""
+
+msgid "email address of sender"
+msgstr ""
+
+msgid "print messages that would be sent"
+msgstr ""
+
+msgid "write messages to mbox file instead of sending them"
+msgstr ""
+
+msgid "subject of first message (intro or single patch)"
+msgstr ""
+
+msgid "message identifier to reply to"
+msgstr ""
+
+msgid "email addresses of recipients"
+msgstr ""
+
+msgid "omit hg patch header"
+msgstr ""
+
+msgid "send changes not found in the target repository"
+msgstr ""
+
+msgid "send changes not in target as a binary bundle"
+msgstr ""
+
+msgid "name of the bundle attachment file"
+msgstr ""
+
+msgid "a revision to send"
+msgstr ""
+
+msgid "run even when remote repository is unrelated (with -b/--bundle)"
+msgstr ""
+
+msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
+msgstr ""
+
+msgid "send an introduction email for a single patch"
+msgstr ""
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr ""
+
+msgid ""
+"removes files not tracked by Mercurial\n"
+"\n"
+" Delete files not known to Mercurial. This is useful to test local\n"
+" and uncommitted changes in an otherwise-clean source tree.\n"
+"\n"
+" This means that purge will delete:\n"
+" - Unknown files: files marked with \"?\" by \"hg status\"\n"
+" - Empty directories: in fact Mercurial ignores directories unless\n"
+" they contain files under source control management\n"
+" But it will leave untouched:\n"
+" - Modified and unmodified tracked files\n"
+" - Ignored files (unless --all is specified)\n"
+" - New files added to the repository (with \"hg add\")\n"
+"\n"
+" If directories are given on the command line, only files in these\n"
+" directories are considered.\n"
+"\n"
+" Be careful with purge, as you could irreversibly delete some files\n"
+" you forgot to add to the repository. If you only want to print the\n"
+" list of files that this program would delete, use the --print\n"
+" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s\n"
+msgstr ""
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr ""
+
+msgid "abort if an error occurs"
+msgstr ""
+
+msgid "purge ignored files too"
+msgstr ""
+
+msgid "print filenames instead of deleting them"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr ""
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr ""
+
+msgid ""
+"move sets of revisions to a different ancestor\n"
+"\n"
+"This extension lets you rebase changesets in an existing Mercurial\n"
+"repository.\n"
+"\n"
+"For more information:\n"
+"http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject\n"
+msgstr ""
+
+msgid "first revision, do not change ancestor\n"
+msgstr ""
+
+msgid ""
+"move changeset (and descendants) to a different branch\n"
+"\n"
+" Rebase uses repeated merging to graft changesets from one part of\n"
+" history onto another. This can be useful for linearizing local\n"
+" changes relative to a master development tree.\n"
+"\n"
+" If a rebase is interrupted to manually resolve a merge, it can be\n"
+" continued with --continue/-c or aborted with --abort/-a.\n"
+" "
+msgstr ""
+
+msgid "cannot use both abort and continue"
+msgstr ""
+
+msgid "cannot use collapse with continue or abort"
+msgstr ""
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr ""
+
+msgid "cannot specify both a revision and a base"
+msgstr ""
+
+msgid "nothing to rebase\n"
+msgstr ""
+
+msgid "cannot use both keepbranches and extrafn"
+msgstr ""
+
+msgid "rebase merging completed\n"
+msgstr ""
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr ""
+
+msgid "rebase completed\n"
+msgstr ""
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr ""
+
+msgid " set parents\n"
+msgstr ""
+
+#, python-format
+msgid "rebasing %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid " future parents are %d and %d\n"
+msgstr ""
+
+#, python-format
+msgid " update to %d:%s\n"
+msgstr " ενημέÏωση σε %d:%s\n"
+
+msgid " already in target\n"
+msgstr ""
+
+#, python-format
+msgid " merge against %d:%s\n"
+msgstr ""
+
+msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgstr ""
+
+msgid "resuming interrupted rebase\n"
+msgstr ""
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr ""
+
+#, python-format
+msgid "next revision set to %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr ""
+
+#, python-format
+msgid "revision %d is an mq patch (%s), finalize it.\n"
+msgstr ""
+
+#, python-format
+msgid "import mq patch %d (%s)\n"
+msgstr ""
+
+msgid "rebase status stored\n"
+msgstr ""
+
+msgid "rebase status resumed\n"
+msgstr ""
+
+msgid "no rebase in progress"
+msgstr ""
+
+msgid "warning: new changesets detected on target branch, not stripping\n"
+msgstr ""
+
+msgid "rebase aborted\n"
+msgstr ""
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr ""
+
+msgid "cannot rebase an ancestor"
+msgstr ""
+
+msgid "cannot rebase a descendant"
+msgstr ""
+
+msgid "already working on current\n"
+msgstr ""
+
+msgid "already working on the current branch\n"
+msgstr ""
+
+#, python-format
+msgid "rebase onto %d starting from %d\n"
+msgstr ""
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr ""
+
+msgid "--update and --rebase are not compatible, ignoring the update flag\n"
+msgstr ""
+
+msgid "rebase working directory to branch head"
+msgstr ""
+
+msgid "rebase from a given revision"
+msgstr ""
+
+msgid "rebase from the base of a given revision"
+msgstr ""
+
+msgid "rebase onto a given revision"
+msgstr ""
+
+msgid "collapse the rebased revisions"
+msgstr ""
+
+msgid "keep original revisions"
+msgstr ""
+
+msgid "keep original branches"
+msgstr ""
+
+msgid "continue an interrupted rebase"
+msgstr ""
+
+msgid "abort an interrupted rebase"
+msgstr ""
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+msgstr ""
+
+msgid "interactive change selection during commit or qrefresh"
+msgstr ""
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr ""
+
+msgid "this is a binary file\n"
+msgstr ""
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr ""
+
+msgid "[Ynsfdaq?]"
+msgstr ""
+
+msgid "&Yes, record this change"
+msgstr ""
+
+msgid "&No, skip this change"
+msgstr ""
+
+msgid "&Skip remaining changes to this file"
+msgstr ""
+
+msgid "Record remaining changes to this &file"
+msgstr ""
+
+msgid "&Done, skip remaining changes and files"
+msgstr ""
+
+msgid "Record &all changes to all remaining files"
+msgstr ""
+
+#, fuzzy
+msgid "&Quit, recording no changes"
+msgstr ""
+
+msgid "&?"
+msgstr ""
+
+msgid "y"
+msgstr ""
+
+msgid "?"
+msgstr ""
+
+msgid "y - record this change"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "f"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "a"
+msgstr ""
+
+msgid "q"
+msgstr ""
+
+msgid "user quit"
+msgstr ""
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr ""
+
+msgid " and "
+msgstr ""
+
+#, python-format
+msgid "record this change to %r?"
+msgstr ""
+
+#, python-format
+msgid "record change %d/%d to %r?"
+msgstr ""
+
+msgid ""
+"interactively select changes to commit\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be candidates for recording.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" You will be prompted for whether to record changes to each\n"
+" modified file, and for files with multiple changes, for each\n"
+" change to use. For each query, the following responses are\n"
+" possible:\n"
+"\n"
+" y - record this change\n"
+" n - skip this change\n"
+"\n"
+" s - skip remaining changes to this file\n"
+" f - record remaining changes to this file\n"
+"\n"
+" d - done, skip remaining changes and files\n"
+" a - record all changes to all remaining files\n"
+" q - quit, recording no changes\n"
+"\n"
+" ? - display help"
+msgstr ""
+
+msgid "'mq' extension not loaded"
+msgstr ""
+
+msgid "running non-interactively, use commit instead"
+msgstr ""
+
+msgid "no changes to record\n"
+msgstr ""
+
+#, python-format
+msgid "backup %r as %r\n"
+msgstr ""
+
+msgid "applying patch\n"
+msgstr ""
+
+msgid "patch failed to apply"
+msgstr ""
+
+#, python-format
+msgid "restoring %r to %r\n"
+msgstr ""
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr ""
+
+msgid ""
+"create a new shared repository (experimental)\n"
+"\n"
+" Initialize a new repository and working directory that shares its\n"
+" history with another repository.\n"
+"\n"
+" NOTE: actions that change history such as rollback or moving the\n"
+" source may confuse sharers.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid "do not create a working copy"
+msgstr "(δώστε 'hg update' για να εξάγετε αντίγÏαφο εÏγασίας)\n"
+
+msgid "[-U] SOURCE [DEST]"
+msgstr ""
+
+msgid ""
+"patch transplanting tool\n"
+"\n"
+"This extension allows you to transplant patches from another branch.\n"
+"\n"
+"Transplanted patches are recorded in .hg/transplant/transplants, as a\n"
+"map from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr ""
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr ""
+
+#, python-format
+msgid "filtering %s\n"
+msgstr ""
+
+msgid "filter failed"
+msgstr ""
+
+msgid "can only omit patchfile if merging"
+msgstr ""
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr ""
+
+msgid "Fix up the merge and run hg transplant --continue"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr ""
+
+msgid "transplant log file is corrupt"
+msgstr ""
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr ""
+
+msgid "commit failed"
+msgstr ""
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr ""
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+" Selected changesets will be applied on top of the current working\n"
+" directory with the log of the original changeset. If --log is\n"
+" specified, log messages will have a comment appended of the form:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" You can rewrite the changelog message with the --filter option.\n"
+" Its argument will be invoked with the current changelog message as\n"
+" $1 and the patch as $2.\n"
+"\n"
+" If --source/-s is specified, selects changesets from the named\n"
+" repository. If --branch/-b is specified, selects changesets from\n"
+" the branch holding the named revision, up to that revision. If\n"
+" --all/-a is specified, all changesets on the branch will be\n"
+" transplanted, otherwise you will be prompted to select the\n"
+" changesets you want.\n"
+"\n"
+" hg transplant --branch REVISION --all will rebase the selected\n"
+" branch (up to the named revision) onto your current working\n"
+" directory.\n"
+"\n"
+" You can optionally mark selected transplanted changesets as merge\n"
+" changesets. You will not be prompted to transplant any ancestors\n"
+" of a merged transplant, and you can merge descendants of them\n"
+" normally instead of transplanting them.\n"
+"\n"
+" If no merges or revisions are provided, hg transplant will start\n"
+" an interactive changeset browser.\n"
+"\n"
+" If a changeset application fails, you can fix the merge by hand\n"
+" and then resume where you left off by calling hg transplant\n"
+" --continue/-c.\n"
+" "
+msgstr ""
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr ""
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr ""
+
+msgid "--all requires a branch revision"
+msgstr ""
+
+msgid "--all is incompatible with a revision list"
+msgstr ""
+
+msgid "no revision checked out"
+msgstr ""
+
+msgid "outstanding uncommitted merges"
+msgstr ""
+
+msgid "outstanding local changes"
+msgstr ""
+
+msgid "pull patches from REPOSITORY"
+msgstr ""
+
+msgid "pull patches from branch BRANCH"
+msgstr ""
+
+msgid "pull all changesets up to BRANCH"
+msgstr ""
+
+msgid "skip over REV"
+msgstr ""
+
+msgid "merge at REV"
+msgstr ""
+
+msgid "append transplant info to log message"
+msgstr ""
+
+msgid "continue last transplant session after repair"
+msgstr ""
+
+msgid "filter changesets through FILTER"
+msgstr ""
+
+msgid ""
+"hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr ""
+
+msgid ""
+"allow to use MBCS path with problematic encoding.\n"
+"\n"
+"Some MBCS encodings are not good for some path operations (i.e.\n"
+"splitting path, case conversion, etc.) with its encoded bytes. We call\n"
+"such a encoding (i.e. shift_jis and big5) as \"problematic encoding\".\n"
+"This extension can be used to fix the issue with those encodings by\n"
+"wrapping some functions to convert to Unicode string before path\n"
+"operation.\n"
+"\n"
+"This extension is useful for:\n"
+" * Japanese Windows users using shift_jis encoding.\n"
+" * Chinese Windows users using big5 encoding.\n"
+" * All users who use a repository with one of problematic encodings on\n"
+" case-insensitive file system.\n"
+"\n"
+"This extension is not needed for:\n"
+" * Any user who use only ASCII chars in path.\n"
+" * Any user who do not use any of problematic encodings.\n"
+"\n"
+"Note that there are some limitations on using this extension:\n"
+" * You should use single encoding in one repository.\n"
+" * You should set same encoding for the repository by locale or\n"
+" HGENCODING.\n"
+"\n"
+"To use this extension, enable the extension in .hg/hgrc or ~/.hgrc:\n"
+"\n"
+" [extensions]\n"
+" hgext.win32mbcs =\n"
+"\n"
+"Path encoding conversion are done between Unicode and\n"
+"encoding.encoding which is decided by Mercurial from current locale\n"
+"setting or HGENCODING.\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] filename conversion fail with %s encoding\n"
+msgstr ""
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] activated with encoding: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr ""
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"and also consider adding:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+
+msgid ""
+"zeroconf support for Mercurial repositories\n"
+"\n"
+"Zeroconf enabled repositories will be announced in a network without\n"
+"the need to configure a server or a service. They can be discovered\n"
+"without knowing their actual IP address.\n"
+"\n"
+"To use the zeroconf extension add the following entry to your hgrc\n"
+"file:\n"
+"\n"
+"[extensions]\n"
+"hgext.zeroconf =\n"
+"\n"
+"To allow other people to discover your repository using run \"hg serve\"\n"
+"in your repository.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"You can discover zeroconf enabled repositories by running \"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+msgstr ""
+
+msgid "archive prefix contains illegal components"
+msgstr ""
+
+msgid "cannot give prefix when archiving to files"
+msgstr ""
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr ""
+
+msgid "invalid changegroup"
+msgstr ""
+
+msgid "unknown parent"
+msgstr ""
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr ""
+
+#, python-format
+msgid "%s: not a Mercurial bundle file"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle version"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle compression type"
+msgstr ""
+
+msgid "cannot create new bundle repository"
+msgstr ""
+
+#, python-format
+msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgstr ""
+
+#, fuzzy
+msgid "empty username"
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr ""
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr ""
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr ""
+
+msgid "limit must be a positive integer"
+msgstr ""
+
+msgid "limit must be positive"
+msgstr ""
+
+msgid "too many revisions specified"
+msgstr ""
+
+#, python-format
+msgid "invalid format spec '%%%s' in output filename"
+msgstr ""
+
+#, python-format
+msgid "adding %s\n"
+msgstr "Ï€Ïοσθήκη του %s\n"
+
+#, python-format
+msgid "removing %s\n"
+msgstr "αφαίÏεση του %s\n"
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr ""
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr ""
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr ""
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr "μετακίνηση του %s στο %s\n"
+
+#, fuzzy, python-format
+msgid "copying %s to %s\n"
+msgstr "μετακίνηση του %s στο %s\n"
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+"%s er endnu ikke comitted, så der vil ikke blive gemt kopieringsdata for %"
+"s.\n"
+
+msgid "no source or destination specified"
+msgstr ""
+
+msgid "no destination specified"
+msgstr ""
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr ""
+"destinationen skal være en eksisterende mappe når der angivet flere kilder"
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr ""
+
+msgid "no files to copy"
+msgstr ""
+
+msgid "(consider using --after)\n"
+msgstr ""
+
+#, python-format
+msgid "changeset: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "branch: %s\n"
+msgstr ""
+
+#, python-format
+msgid "tag: %s\n"
+msgstr ""
+
+#, python-format
+msgid "parent: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "manifest: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "user: %s\n"
+msgstr ""
+
+#, python-format
+msgid "date: %s\n"
+msgstr ""
+
+msgid "files+:"
+msgstr ""
+
+msgid "files-:"
+msgstr ""
+
+msgid "files:"
+msgstr ""
+
+#, python-format
+msgid "files: %s\n"
+msgstr ""
+
+#, python-format
+msgid "copies: %s\n"
+msgstr ""
+
+#, python-format
+msgid "extra: %s=%s\n"
+msgstr ""
+
+msgid "description:\n"
+msgstr ""
+
+#, python-format
+msgid "summary: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr ""
+
+#, python-format
+msgid "%s: %s"
+msgstr ""
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr ""
+
+msgid "revision matching date not found"
+msgstr ""
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "%s:%s copy source revision cannot be found!\n"
+msgstr ""
+
+msgid "can only follow copies/renames for explicit filenames"
+msgstr ""
+
+msgid "HG: Enter commit message. Lines beginning with 'HG:' are removed."
+msgstr ""
+
+msgid "HG: Leave message empty to abort commit."
+msgstr ""
+
+#, python-format
+msgid "HG: user: %s"
+msgstr ""
+
+msgid "HG: branch merge"
+msgstr ""
+
+#, python-format
+msgid "HG: branch '%s'"
+msgstr ""
+
+#, python-format
+msgid "HG: added %s"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "HG: changed %s"
+msgstr "Ï€Ïοσθήκη αλλαγής %s\n"
+
+#, fuzzy, python-format
+msgid "HG: removed %s"
+msgstr ""
+
+msgid "HG: no files changed"
+msgstr ""
+
+msgid "empty commit message"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"add the specified files on the next commit\n"
+"\n"
+" Schedule files to be version controlled and added to the\n"
+" repository.\n"
+"\n"
+" The files will be added to the repository at the next commit. To\n"
+" undo an add before that, see hg revert.\n"
+"\n"
+" If no names are given, add all files to the repository.\n"
+" "
+msgstr ""
+"tilføj de angivne filer ved næste commit\n"
+"\n"
+" Opskriv filer til at blive versionsstyret og tilføjet til\n"
+" repository'et.\n"
+"\n"
+" Filerne vil bliver tilføjet til repository'et ved næste commit.\n"
+" For at omgøre en tilføjelse før det, se hg revert.\n"
+"\n"
+" Hvis der ikke er angivet nogen navne tilføjes alle filer i\n"
+" repository'et.\n"
+" "
+
+msgid ""
+"add all new files, delete all missing files\n"
+"\n"
+" Add all new files and remove all missing files from the\n"
+" repository.\n"
+"\n"
+" New files are ignored if they match any of the patterns in\n"
+" .hgignore. As with add, these changes take effect at the next\n"
+" commit.\n"
+"\n"
+" Use the -s/--similarity option to detect renamed files. With a\n"
+" parameter > 0, this compares every removed file with every added\n"
+" file and records those similar enough as renames. This option\n"
+" takes a percentage between 0 (disabled) and 100 (files must be\n"
+" identical) as its parameter. Detecting renamed files this way can\n"
+" be expensive.\n"
+" "
+msgstr ""
+
+msgid "similarity must be a number"
+msgstr ""
+
+msgid "similarity must be between 0 and 100"
+msgstr ""
+
+msgid ""
+"show changeset information by line for each file\n"
+"\n"
+" List changes in files, showing the revision id responsible for\n"
+" each line\n"
+"\n"
+" This command is useful for discovering when a change was made and\n"
+" by whom.\n"
+"\n"
+" Without the -a/--text option, annotate will avoid processing files\n"
+" it detects as binary. With -a, annotate will annotate the file\n"
+" anyway, although the results will probably be neither useful\n"
+" nor desirable.\n"
+" "
+msgstr ""
+
+msgid "at least one filename or pattern is required"
+msgstr ""
+
+msgid "at least one of -n/-c is required for -l"
+msgstr ""
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr ""
+
+msgid ""
+"create an unversioned archive of a repository revision\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use -r/--rev to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use -t/--type. Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see 'hg help export' for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use -p/--prefix to specify a format string for the\n"
+" prefix. The default is the basename of the archive, with suffixes\n"
+" removed.\n"
+" "
+msgstr ""
+
+msgid "no working directory: please specify a revision"
+msgstr ""
+
+msgid "repository root cannot be destination"
+msgstr ""
+
+msgid "cannot archive plain files to stdout"
+msgstr ""
+
+msgid ""
+"reverse effect of earlier changeset\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you backout a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head.\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by hand.\n"
+" The result of this merge is not committed, as with a normal merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "please specify just one revision"
+msgstr "παÏακαλώ οÏίστε μόνο μία αλλαγή"
+
+msgid "please specify a revision to backout"
+msgstr ""
+
+msgid "cannot backout change on a different branch"
+msgstr ""
+
+msgid "cannot backout a change with no parents"
+msgstr ""
+
+msgid "cannot backout a merge changeset without --parent"
+msgstr ""
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr "η αλλαγή %s δεν είναι γονική αλλαγή της %s"
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr ""
+
+#, python-format
+msgid "Backed out changeset %s"
+msgstr ""
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr ""
+
+msgid "the backout changeset is a new head - do not forget to merge\n"
+msgstr ""
+
+msgid "(use \"backout --merge\" if you want to auto-merge)\n"
+msgstr ""
+
+msgid ""
+"subdivision search of changesets\n"
+"\n"
+" This command helps to find changesets which introduce problems. To\n"
+" use, mark the earliest changeset you know exhibits the problem as\n"
+" bad, then mark the latest changeset which is free from the problem\n"
+" as good. Bisect will update your working directory to a revision\n"
+" for testing (unless the -U/--noupdate option is specified). Once\n"
+" you have performed tests, mark the working directory as good or\n"
+" bad, and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command, it will be used for automatic bisection.\n"
+" Its exit status will be used to mark revisions as good or bad:\n"
+" status 0 means good, 125 means to skip the revision, 127\n"
+" (command not found) will abort the bisection, and any other\n"
+" non-zero exit status means the revision is bad.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid "The first good revision is:\n"
+msgstr "Η Ï€Ïώτη %s αλλαγή είναι:\n"
+
+#, fuzzy
+msgid "The first bad revision is:\n"
+msgstr "Η Ï€Ïώτη %s αλλαγή είναι:\n"
+
+msgid "Due to skipped revisions, the first good revision could be any of:\n"
+msgstr ""
+
+msgid "Due to skipped revisions, the first bad revision could be any of:\n"
+msgstr ""
+
+msgid "cannot bisect (no known good revisions)"
+msgstr ""
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr ""
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr ""
+
+msgid "incompatible arguments"
+msgstr ""
+
+#, python-format
+msgid "cannot find executable: %s"
+msgstr ""
+
+#, python-format
+msgid "failed to execute %s"
+msgstr ""
+
+#, python-format
+msgid "%s killed"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "Changeset %d:%s: %s\n"
+msgstr "Αλλαγή: %s: %s\n"
+
+#, python-format
+msgid "Testing changeset %s:%s (%s changesets remaining, ~%s tests)\n"
+msgstr ""
+
+msgid ""
+"set or show the current branch name\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch will not exist\n"
+" in the repository until the next commit). Standard practice\n"
+" recommends that primary development take place on the 'default'\n"
+" branch.\n"
+"\n"
+" Unless -f/--force is specified, branch will not let you set a\n"
+" branch name that already exists, even if it's inactive.\n"
+"\n"
+" Use -C/--clean to reset the working directory branch to that of\n"
+" the parent of the working directory, negating a previous branch\n"
+" change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr ""
+
+msgid "a branch of the same name already exists (use --force to override)"
+msgstr ""
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr ""
+
+msgid ""
+"list repository named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If active is specified, only show active branches.\n"
+"\n"
+" A branch is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+
+msgid ""
+"create a changegroup file\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" -a/--all (or --base null). To change the compression method\n"
+" applied, use the -t/--type option (by default, bundles are\n"
+" compressed using bz2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means\n"
+" and applied to another repository with the unbundle or pull\n"
+" command. This is useful when direct push and pull are not\n"
+" available or when exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+msgstr ""
+
+msgid "--base is incompatible with specifying a destination"
+msgstr ""
+
+msgid "unknown bundle type specified with --type"
+msgstr ""
+
+msgid ""
+"output the current or given revision of files\n"
+"\n"
+" Print the specified files as they were at the given revision. If\n"
+" no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repository root\n"
+" %p root-relative path name of file being printed\n"
+" "
+msgstr ""
+
+msgid ""
+"make a copy of an existing repository\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" If you use the -r/--rev option to clone up to a specific revision,\n"
+" no subsequent revisions (including subsequent tags) will be\n"
+" present in the cloned repository. This option implies --pull, even\n"
+" on local repositories.\n"
+"\n"
+" By default, clone will check out the head of the 'default' branch.\n"
+" If the -U/--noupdate option is used, the new clone will contain\n"
+" only a repository (.hg) and no working copy (the working copy\n"
+" parent is the null revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Please see 'hg help urls' for important details about ssh:// URLs.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"commit the specified files or all outstanding changes\n"
+"\n"
+" Commit changes to the given files into the repository. Unlike a\n"
+" centralized RCS, this operation is a local operation. See hg push\n"
+" for a way to actively distribute your changes.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" filenames or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is\n"
+" started to prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "created new head\n"
+msgstr "δημιουÏγήθηκε νέο παÏακλάδι\n"
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr "αποθηκεÏθηκε η αλλαγή %d:%s\n"
+
+msgid ""
+"mark files as copied for the next commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr ""
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr "Δεν υπάÏχει αποθετήÏιο Mercurial εδώ (δε βÏέθηκε υποκατάλογος .hg)"
+
+msgid "either two or three arguments required"
+msgstr "απαιτοÏνται είτε δÏο ή Ï„Ïία οÏίσματα"
+
+msgid "returns the completion list associated with the given command"
+msgstr ""
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr ""
+
+msgid "validate the correctness of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr ""
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr ""
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr ""
+
+msgid ""
+"show combined config settings from all hgrc files\n"
+"\n"
+" With no arguments, print names and values of all config items.\n"
+"\n"
+" With one argument of the form section.name, print just the value\n"
+" of that config item.\n"
+"\n"
+" With multiple arguments, print names and values of all config\n"
+" items with matching section names.\n"
+"\n"
+" With --debug, the source (filename and line number) is printed\n"
+" for each config item.\n"
+" "
+msgstr ""
+
+msgid "only one config item permitted"
+msgstr ""
+
+msgid ""
+"manually set the parents of the current working directory\n"
+"\n"
+" This is useful for writing repository conversion tools, but should\n"
+" be used with care.\n"
+" "
+msgstr ""
+
+msgid "show the contents of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr "αντιγÏαφή: %s -> %s\n"
+
+msgid "dump the contents of a data file revision"
+msgstr ""
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr "μη έγκυÏο όνομα αλλαγής: %s"
+
+msgid "parse and display a date"
+msgstr ""
+
+msgid "dump the contents of an index file"
+msgstr ""
+
+msgid "dump an index DAG as a graphviz dot file"
+msgstr ""
+
+msgid "test Mercurial installation"
+msgstr ""
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr ""
+
+msgid " (check that your locale is properly set)\n"
+msgstr ""
+
+msgid "Checking extensions...\n"
+msgstr ""
+
+msgid " One or more extensions could not be found"
+msgstr ""
+
+msgid " (check that you compiled the extensions)\n"
+msgstr ""
+
+msgid "Checking templates...\n"
+msgstr ""
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr ""
+
+msgid "Checking patch...\n"
+msgstr ""
+
+msgid " patch call failed:\n"
+msgstr ""
+
+msgid " unexpected patch output!\n"
+msgstr ""
+
+msgid " patch test failed!\n"
+msgstr ""
+
+msgid ""
+" (Current patch tool may be incompatible with patch, or misconfigured. "
+"Please check your .hgrc file)\n"
+msgstr ""
+
+msgid ""
+" Internal patcher failure, please report this error to http://www.selenic."
+"com/mercurial/bts\n"
+msgstr ""
+
+msgid "Checking commit editor...\n"
+msgstr ""
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr ""
+
+msgid " (specify a commit editor in your .hgrc file)\n"
+msgstr ""
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr ""
+
+msgid "Checking username...\n"
+msgstr ""
+
+msgid " (specify a username in your .hgrc file)\n"
+msgstr ""
+
+msgid "No problems detected\n"
+msgstr "Δε βÏέθηκε κανένα Ï€Ïόβλημα\n"
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr ""
+
+msgid "dump rename information"
+msgstr ""
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr "το %s μετονομάστηκε από το %s:%s\n"
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr "το %s δε μετονομάστηκε\n"
+
+msgid "show how files match on given patterns"
+msgstr ""
+
+msgid ""
+"diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a/--text option, diff will avoid generating diffs of\n"
+" files it detects as binary. With -a, diff will generate a diff\n"
+" anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. For more information, read 'hg help diffs'.\n"
+" "
+msgstr ""
+
+msgid ""
+"dump the header and diffs for one or more changesets\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a/--text option, export will avoid generating diffs\n"
+" of files it detects as binary. With -a, export will generate a\n"
+" diff anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. See 'hg help diffs' for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the\n"
+" second parent. It can be useful to review a merge.\n"
+" "
+msgstr ""
+
+msgid "export requires at least one changeset"
+msgstr ""
+
+msgid "exporting patches:\n"
+msgstr ""
+
+msgid "exporting patch:\n"
+msgstr ""
+
+msgid ""
+"search for a pattern in specified files and revisions\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which a\n"
+" match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr ""
+
+msgid ""
+"show current repository heads or show branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" If one or more REV is given, the \"branch heads\" will be shown for\n"
+" the named branch associated with that revision. The name of the\n"
+" branch is called the revision's branch tag.\n"
+"\n"
+" Branch heads are revisions on a given named branch that do not have\n"
+" any children on the same branch. A branch head could be a true head\n"
+" or it could be the last changeset on a branch before a new branch\n"
+" was created. If none of the branch heads are true heads, the branch\n"
+" is considered inactive.\n"
+"\n"
+" If STARTREV is specified only those heads (or branch heads) that\n"
+" are descendants of STARTREV will be displayed.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "no open branch heads on branch %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes on branch %s containing %s are reachable from %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes on branch %s are reachable from %s\n"
+msgstr ""
+
+msgid ""
+"show help for a given topic or a help overview\n"
+"\n"
+" With no arguments, print a list of commands with short help messages.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that\n"
+" topic."
+msgstr ""
+
+msgid "global options:"
+msgstr ""
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr "δείτε τη βοήθεια \"hg help\" για την πλήÏη λίστα εντολών"
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr ""
+"brug \"hg help\" for den fulde liste af kommandoer eller \"hg -v\" for "
+"detaljer"
+
+#, python-format
+msgid "use \"hg -v help%s\" to show aliases and global options"
+msgstr ""
+"δώστε \"hg -v help%s\" για τη λίστα εικονικών εντολών και κεντÏικών επιλογών"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "δώστε \"hg -v help %s\" για τη λίστα κεντÏικών επιλογών"
+
+msgid ""
+"list of commands:\n"
+"\n"
+msgstr ""
+"λίστα εντολών:\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"εικονικές εντολές %s:\n"
+
+msgid "(no help text available)"
+msgstr "(δεν υπάÏχει κείμενο βοήθειας)"
+
+msgid "options:\n"
+msgstr "επιλογές:\n"
+
+msgid "no commands defined\n"
+msgstr "δεν έχει οÏιστεί καμία εντολή\n"
+
+msgid ""
+"\n"
+"enabled extensions:\n"
+"\n"
+msgstr ""
+"\n"
+"ενεÏγές επεκτάσεις:\n"
+"\n"
+
+#, python-format
+msgid " %s %s\n"
+msgstr ""
+
+msgid "no help text available"
+msgstr "δεν υπάÏχει κείμενο βοήθειας"
+
+#, python-format
+msgid "%s extension - %s\n"
+msgstr ""
+
+msgid "Mercurial Distributed SCM\n"
+msgstr "Mercurial Κατανεμημένο SCM\n"
+
+msgid ""
+"basic commands:\n"
+"\n"
+msgstr ""
+"βασικές εντολές:\n"
+"\n"
+
+msgid ""
+"\n"
+"additional help topics:\n"
+"\n"
+msgstr ""
+"\n"
+"πεÏισσότεÏα θέματα βοήθειας:\n"
+"\n"
+
+msgid ""
+"identify the working copy or specified revision\n"
+"\n"
+" With no revision, print a summary of the current state of the\n"
+" repository.\n"
+"\n"
+" Specifying a path to a repository root or Mercurial bundle will\n"
+" cause lookup to operate on that repository/bundle.\n"
+"\n"
+" This summary identifies the repository state using one or two\n"
+" parent hash identifiers, followed by a \"+\" if there are\n"
+" uncommitted changes in the working directory, a list of tags for\n"
+" this revision and a branch name for non-default branches.\n"
+" "
+msgstr ""
+
+msgid ""
+"import an ordered set of patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f/--force flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (to use the body part, it must have type\n"
+" text/plain or text/x-patch). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and\n"
+" description from patch override values from message headers and\n"
+" body. Values given on command line with -m/--message and -u/--user\n"
+" override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory to\n"
+" the parent of each patch before applying it, and will abort if the\n"
+" resulting changeset has a different ID than the one recorded in\n"
+" the patch. This may happen due to character set problems or other\n"
+" deficiencies in the text patch format.\n"
+"\n"
+" With -s/--similarity, hg will attempt to discover renames and\n"
+" copies in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use \"-\" as the patch name.\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "applying patch from stdin\n"
+msgstr ""
+
+msgid "no diffs found"
+msgstr ""
+
+#, python-format
+msgid ""
+"message:\n"
+"%s\n"
+msgstr ""
+"meddelse:\n"
+"%s\n"
+
+msgid "not a Mercurial patch"
+msgstr ""
+
+msgid "patch is damaged or loses information"
+msgstr ""
+
+msgid ""
+"show new changesets found in source\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would have been pulled\n"
+" if a pull at the time you issued this command.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the\n"
+" changesets twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+msgstr ""
+
+msgid ""
+"create a new repository in the given directory\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it will be created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+msgid ""
+"locate files matching specific patterns\n"
+"\n"
+" Print files under Mercurial control in the working directory whose\n"
+" names match the given patterns.\n"
+"\n"
+" By default, this command searches all directories in the working\n"
+" directory. To search just the current directory and its\n"
+" subdirectories, use \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints the names\n"
+" of all files under Mercurial control in the working directory.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the -0 option to both this command and \"xargs\". This\n"
+" will avoid the problem of \"xargs\" treating single filenames that\n"
+" contain whitespace as multiple filenames.\n"
+" "
+msgstr ""
+
+msgid ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a filename to follow history across\n"
+" renames and copies. --follow without a filename will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command prints revision number and changeset id,\n"
+" tags, non-trivial parents, user, date and time, and a summary for\n"
+" each commit. When the -v/--verbose switch is used, the list of\n"
+" changed files and full commit message are shown.\n"
+"\n"
+" NOTE: log -p/--patch may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, only files different from BOTH parents\n"
+" will appear in files:.\n"
+" "
+msgstr ""
+
+msgid ""
+"output the current or given revision of the project manifest\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the first parent of the working directory\n"
+" is used, or the null revision if no revision is checked out.\n"
+"\n"
+" With -v, print file permissions, symlink and executable bits.\n"
+" With --debug, print file revision hashes.\n"
+" "
+msgstr ""
+
+msgid ""
+"merge working directory with another revision\n"
+"\n"
+" The current working directory is updated with all changes made in\n"
+" the requested revision since the last common predecessor revision.\n"
+"\n"
+" Files that changed between either parent are marked as changed for\n"
+" the next commit and a commit must be performed before any further\n"
+" updates to the repository are allowed. The next commit will have\n"
+" two parents.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other\n"
+" head, the other head is merged with by default. Otherwise, an\n"
+" explicit revision with which to merge with must be provided.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr ""
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr ""
+
+msgid "there is nothing to merge"
+msgstr ""
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr "%s - δώστε \"hg update\" καλÏτεÏα"
+
+msgid ""
+"working dir not at a head rev - use \"hg update\" or merge with an explicit "
+"rev"
+msgstr ""
+
+msgid ""
+"show changesets not found in destination\n"
+"\n"
+" Show changesets not found in the specified destination repository\n"
+" or the default push location. These are the changesets that would\n"
+" be pushed if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+msgstr ""
+
+msgid ""
+"show the parents of the working directory or revision\n"
+"\n"
+" Print the working directory's parent revisions. If a revision is\n"
+" given via -r/--rev, the parent of that revision will be printed.\n"
+" If a file argument is given, the revision in which the file was\n"
+" last changed (before the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+
+msgid "can only specify an explicit filename"
+msgstr ""
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr ""
+
+msgid ""
+"show aliases for remote repositories\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given,\n"
+" show definition of all available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+msgid "not found!\n"
+msgstr "δε βÏέθηκε!\n"
+
+msgid "not updating, since new heads added\n"
+msgstr "δεν εξάγεται κάποια αλλαγή, επειδή δημιουÏγήθηκε νέο παÏακλάδι\n"
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr ""
+"(δώστε 'hg heads' για να δείτε τα παÏακλάδια, 'hg merge' για συγχώνευση)\n"
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr "(δώστε 'hg update' για να εξάγετε αντίγÏαφο εÏγασίας)\n"
+
+msgid ""
+"pull changes from the specified source\n"
+"\n"
+" Pull changes from a remote repository to a local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to a local repository (the current one unless\n"
+" -R is specified). By default, this does not update the copy of the\n"
+" project in the working directory.\n"
+"\n"
+" Use hg incoming if you want to see what would have been added by a\n"
+" pull at the time you issued this command. If you then decide to\n"
+" added those changes to the repository, you should use pull -r X\n"
+" where X is the last changeset listed by hg incoming.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+msgid ""
+"push changes to the specified destination\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It moves changes from\n"
+" the current repository to a different one. If the destination is\n"
+" local this is identical to a pull in that directory from the\n"
+" current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" user forgot to pull and merge before pushing.\n"
+"\n"
+" If -r/--rev is used, the named revision and all its ancestors will\n"
+" be pushed to the remote repository.\n"
+"\n"
+" Please see 'hg help urls' for important details about ssh://\n"
+" URLs. If DESTINATION is omitted, a default path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr ""
+
+msgid ""
+"roll back an interrupted transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an\n"
+" interrupted operation. It should only be necessary when Mercurial\n"
+" suggests it.\n"
+" "
+msgstr ""
+
+msgid ""
+"remove the specified files on the next commit\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history. -A/--after can be used to remove only\n"
+" files that have already been deleted, -f/--force can be used to\n"
+" force deletion, and -Af can be used to remove files from the next\n"
+" revision without deleting them from the working directory.\n"
+"\n"
+" The following table details the behavior of remove for different\n"
+" file states (columns) and option combinations (rows). The file\n"
+" states are Added [A], Clean [C], Modified [M] and Missing [!]\n"
+" (as reported by hg status). The actions are Warn, Remove (from\n"
+" branch) and Delete (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid "no files specified"
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file is untracked\n"
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file %s (use -f to force removal)\n"
+msgstr ""
+
+msgid "still exists"
+msgstr "υπάÏχει ακόμη"
+
+msgid "is modified"
+msgstr "έχει Ï„Ïοποποιηθεί"
+
+msgid "has been marked for add"
+msgstr "έχει σημειωθεί για Ï€Ïοσθήκη"
+
+msgid ""
+"rename files; equivalent of copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If dest\n"
+" is a directory, copies are put in that directory. If dest is a\n"
+" file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid ""
+"retry file merges from a merge or update\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a/--all switch.\n"
+"\n"
+" If a conflict is resolved manually, please note that the changes\n"
+" will be overwritten if the merge is retried with resolve. The\n"
+" -m/--mark switch should be used to mark the file as resolved.\n"
+"\n"
+" This command also allows listing resolved files and manually\n"
+" indicating whether or not files are resolved. All files must be\n"
+" marked as resolved before a commit is permitted.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+msgstr ""
+
+msgid "too many options specified"
+msgstr ""
+
+msgid "can't specify --all and patterns"
+msgstr ""
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr ""
+"ingen filer eller mapper specificeret; brug --all for at gen-sammenføje alle "
+"filerne"
+
+msgid ""
+"restore individual files or directories to an earlier state\n"
+"\n"
+" (Use update -r to check out earlier revisions, revert does not\n"
+" change the working directory parents.)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r/--rev option, revert the given files or directories\n"
+" to their contents as of a specific revision. This can be helpful\n"
+" to \"roll back\" some or all of an earlier change. See 'hg help\n"
+" dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable mode\n"
+" of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+msgstr ""
+
+msgid "you can't specify a revision and a date"
+msgstr "δεν επιτÏέπεται η χÏήση αλλαγής και ημεÏομηνίας ταυτόχÏονα"
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr ""
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr ""
+
+#, python-format
+msgid "reverting %s\n"
+msgstr "επαναφοÏά %s\n"
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr "επανάκτηση %s\n"
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr ""
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr ""
+
+msgid ""
+"roll back the last transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+msgstr ""
+
+msgid ""
+"print the root (top) of the current working directory\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+msgstr ""
+
+msgid ""
+"export the repository via HTTP\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+" files.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr ""
+
+msgid ""
+"show changed files in the working directory\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" the source of a copy/move operation, are not listed unless\n"
+" -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.\n"
+" Unless options described with \"show only ...\" are given, the\n"
+" options -mardu are used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/--ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the differences between them are\n"
+" shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = missing (deleted by non-hg command, but still tracked)\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = origin of the previous file listed as A (added)\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"add one or more tags for the current or given revision\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is\n"
+" used, or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"Ï€Ïοσθήκη μιας ή πεÏισσότεÏων ετικετών για την Ï„Ïέχουσα ή κάποια άλλη έκδοση\n"
+"\n"
+" Ονομασία μιας συγκεκÏιμένης αλλαγής με ένα νέο <όνομα>.\n"
+"\n"
+" Οι ετικέτες μποÏοÏν να χÏησιμοποιηθοÏν ως συμβολικά ονόματα των αλλαγών\n"
+" ενός αποθετηÏίου και είναι Ï€Î¿Î»Ï Ï‡Ïήσιμες για την Ï€Ïοβολή των διαφοÏών\n"
+" Î¼ÎµÏ„Î±Î¾Ï Î´Ïο σημαντικών εκδόσεων, για να επιστÏέφει κανείς σε πιο παλιές\n"
+" εκδόσεις ή για την καταγÏαφή της αÏχής ενός κλάδου, του σημείου στο\n"
+" οποίο έγινε μια επίσημη έκδοση, κλπ.\n"
+"\n"
+" Οταν δεν έχει οÏιστεί συγκεκÏιμένη αλλαγή, τότε η νέα ετικέτα τίθεται\n"
+" στη γονική αλλαγή του χώÏου εÏγασίας, ή στο tip όταν δεν υπάÏχουν στο\n"
+" χώÏο εÏγασίας τα αÏχεία κάποιας έκδοσης.\n"
+"\n"
+" Για να διατηÏείται το ιστοÏικό των ετικετών, να διανέμονται σε άλλους\n"
+" κλώνους του αποθετηÏίου και να μποÏεί να γίνει συγχώνευσή τους, όλες\n"
+" οι ετικέτες αποθηκεÏονται σε ένα αÏχείο με το όνομα \".hgtags\", το\n"
+" οποίο συντηÏείται όπως και κάθε άλλο αÏχείο του αποθετηÏίου και μποÏεί\n"
+" να το επεξεÏγαστεί κανείς ως απλό αÏχείο κειμένου αν χÏειαστεί. Το\n"
+" αÏχείο '.hg/localtags' χÏησιμοποιείται για τις τοπικές ετικέτες\n"
+" (αυτές που δε διανέμονται σε άλλους κλώνους του αποθετηÏίου).\n"
+"\n"
+" Δείτε επίσης: 'hg help dates' για μια λίστα μοÏφών ημεÏομηνίας τις\n"
+" οποίες δέχονται οι επιλογές -d/--date.\n"
+" "
+
+msgid "tag names must be unique"
+msgstr ""
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr ""
+
+msgid "--rev and --remove are incompatible"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' is not a global tag"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' is not a local tag"
+msgstr ""
+
+#, python-format
+msgid "Removed tag %s"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr ""
+
+#, python-format
+msgid "Added tag %s for changeset %s"
+msgstr ""
+
+msgid ""
+"list repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose\n"
+" switch is used, a third column \"local\" is printed for local tags.\n"
+" "
+msgstr ""
+
+msgid ""
+"show the tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the changeset\n"
+" most recently added to the repository (and therefore the most\n"
+" recently changed head).\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+msgstr ""
+
+msgid ""
+"apply one or more changegroup files\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+msgstr ""
+
+msgid ""
+"update working directory\n"
+"\n"
+" Update the repository's working directory to the specified\n"
+" revision, or the tip of the current branch if none is specified.\n"
+" Use null as the revision to remove the working copy (like 'hg\n"
+" clone -U').\n"
+"\n"
+" When the working directory contains no uncommitted changes, it\n"
+" will be replaced by the state of the requested revision from the\n"
+" repository. When the requested revision is on a different branch,\n"
+" the working directory will additionally be switched to that\n"
+" branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C/--clean to\n"
+" discard them, forcibly replacing the state of the working\n"
+" directory with the requested revision.\n"
+"\n"
+" When there are uncommitted changes and option -C/--clean is not\n"
+" used, and the parent revision and requested revision are on the\n"
+" same branch, and one of them is an ancestor of the other, then the\n"
+" new working directory will contain the requested revision merged\n"
+" with the uncommitted changes. Otherwise, the update will fail with\n"
+" a suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use\n"
+" revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid ""
+"verify the integrity of the repository\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+msgstr ""
+
+msgid "output version and copyright information"
+msgstr ""
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr "Mercurial Κατανεμημένο SCM (version %s)\n"
+
+msgid ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+
+msgid "repository root directory or symbolic path name"
+msgstr ""
+
+msgid "change working directory"
+msgstr ""
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr ""
+
+msgid "suppress output"
+msgstr ""
+
+msgid "enable additional output"
+msgstr ""
+
+msgid "set/override config option"
+msgstr ""
+
+msgid "enable debugging output"
+msgstr ""
+
+msgid "start debugger"
+msgstr ""
+
+msgid "set the charset encoding"
+msgstr ""
+
+msgid "set the charset encoding mode"
+msgstr ""
+
+msgid "print traceback on exception"
+msgstr ""
+
+msgid "time how long the command takes"
+msgstr ""
+
+msgid "print command execution profile"
+msgstr ""
+
+msgid "output version information and exit"
+msgstr ""
+
+msgid "display help and exit"
+msgstr ""
+
+msgid "do not perform actions, just print output"
+msgstr ""
+
+msgid "specify ssh command to use"
+msgstr ""
+
+msgid "specify hg command to run on the remote side"
+msgstr ""
+
+msgid "include names matching the given patterns"
+msgstr ""
+
+msgid "exclude names matching the given patterns"
+msgstr ""
+
+msgid "use <text> as commit message"
+msgstr ""
+
+msgid "read commit message from <file>"
+msgstr ""
+
+msgid "record datecode as commit date"
+msgstr ""
+
+msgid "record the specified user as committer"
+msgstr ""
+
+msgid "display using template map file"
+msgstr ""
+
+msgid "display with template"
+msgstr ""
+
+msgid "do not show merges"
+msgstr ""
+
+msgid "treat all files as text"
+msgstr ""
+
+msgid "don't include dates in diff headers"
+msgstr ""
+
+msgid "show which function each change is in"
+msgstr ""
+
+msgid "ignore white space when comparing lines"
+msgstr ""
+
+msgid "ignore changes in the amount of white space"
+msgstr ""
+
+msgid "ignore changes whose lines are all blank"
+msgstr ""
+
+msgid "number of lines of context to show"
+msgstr ""
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr ""
+
+msgid "[OPTION]... [FILE]..."
+msgstr ""
+
+msgid "annotate the specified revision"
+msgstr ""
+
+msgid "follow file copies and renames"
+msgstr ""
+
+msgid "list the author (long with -v)"
+msgstr ""
+
+msgid "list the date (short with -q)"
+msgstr ""
+
+msgid "list the revision number (default)"
+msgstr ""
+
+msgid "list the changeset"
+msgstr ""
+
+msgid "show line number at the first appearance"
+msgstr ""
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr ""
+
+msgid "do not pass files through decoders"
+msgstr ""
+
+msgid "directory prefix for files in archive"
+msgstr ""
+
+msgid "revision to distribute"
+msgstr ""
+
+msgid "type of distribution to create"
+msgstr ""
+
+msgid "[OPTION]... DEST"
+msgstr ""
+
+msgid "merge with old dirstate parent after backout"
+msgstr ""
+
+msgid "parent to choose when backing out merge"
+msgstr ""
+
+msgid "revision to backout"
+msgstr ""
+
+msgid "[OPTION]... [-r] REV"
+msgstr ""
+
+msgid "reset bisect state"
+msgstr ""
+
+msgid "mark changeset good"
+msgstr ""
+
+msgid "mark changeset bad"
+msgstr ""
+
+msgid "skip testing changeset"
+msgstr ""
+
+msgid "use command to check changeset state"
+msgstr ""
+
+msgid "do not update to target"
+msgstr ""
+
+msgid "[-gbsr] [-c CMD] [REV]"
+msgstr ""
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr ""
+
+msgid "reset branch name to parent branch name"
+msgstr ""
+
+msgid "[-fC] [NAME]"
+msgstr ""
+
+msgid "show only branches that have unmerged heads"
+msgstr ""
+
+msgid "[-a]"
+msgstr ""
+
+msgid "run even when remote repository is unrelated"
+msgstr ""
+
+msgid "a changeset up to which you would like to bundle"
+msgstr ""
+
+msgid "a base changeset to specify instead of a destination"
+msgstr ""
+
+msgid "bundle all changesets in the repository"
+msgstr ""
+
+msgid "bundle compression type to use"
+msgstr ""
+
+msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr ""
+
+msgid "print output to file with formatted name"
+msgstr ""
+
+msgid "print the given revision"
+msgstr ""
+
+msgid "apply any matching decode filter"
+msgstr ""
+
+msgid "[OPTION]... FILE..."
+msgstr ""
+
+msgid "the clone will only contain a repository (no working copy)"
+msgstr ""
+
+msgid "a changeset you would like to have after cloning"
+msgstr ""
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr ""
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr ""
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr ""
+
+msgid "record a copy that has already occurred"
+msgstr ""
+
+msgid "forcibly copy over an existing managed file"
+msgstr ""
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr ""
+
+msgid "[INDEX] REV1 REV2"
+msgstr ""
+
+#, fuzzy
+msgid "[COMMAND]"
+msgstr "ΕÎΤΟΛΕΣ"
+
+msgid "show the command options"
+msgstr ""
+
+msgid "[-o] CMD"
+msgstr ""
+
+msgid "try extended date formats"
+msgstr ""
+
+msgid "[-e] DATE [RANGE]"
+msgstr ""
+
+msgid "FILE REV"
+msgstr ""
+
+msgid "[PATH]"
+msgstr ""
+
+msgid "FILE"
+msgstr ""
+
+msgid "revision to rebuild to"
+msgstr ""
+
+msgid "[-r REV] [REV]"
+msgstr ""
+
+msgid "revision to debug"
+msgstr ""
+
+msgid "[-r REV] FILE"
+msgstr ""
+
+msgid "REV1 [REV2]"
+msgstr ""
+
+msgid "do not display the saved mtime"
+msgstr ""
+
+msgid "[OPTION]..."
+msgstr ""
+
+#, fuzzy
+msgid "revision to check"
+msgstr "αλλαγή"
+
+msgid "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+msgstr ""
+
+msgid "diff against the second parent"
+msgstr ""
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr ""
+
+msgid "end fields with NUL"
+msgstr ""
+
+msgid "print all revisions that match"
+msgstr ""
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr ""
+
+msgid "ignore case when matching"
+msgstr ""
+
+msgid "print only filenames and revisions that match"
+msgstr ""
+
+msgid "print matching line numbers"
+msgstr ""
+
+msgid "search in given revision range"
+msgstr ""
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr ""
+
+msgid "show only heads which are descendants of REV"
+msgstr ""
+
+msgid "show only the active heads from open branches"
+msgstr ""
+
+msgid "show normal and closed heads"
+msgstr ""
+
+msgid "[-r STARTREV] [REV]..."
+msgstr ""
+
+msgid "[TOPIC]"
+msgstr ""
+
+#, fuzzy
+msgid "identify the specified revision"
+msgstr ""
+
+msgid "show local revision number"
+msgstr ""
+
+msgid "show global revision id"
+msgstr ""
+
+msgid "show branch"
+msgstr ""
+
+msgid "show tags"
+msgstr ""
+
+msgid "[-nibt] [-r REV] [SOURCE]"
+msgstr ""
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr ""
+
+msgid "base path"
+msgstr ""
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr ""
+
+msgid "don't commit, just update the working directory"
+msgstr ""
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr ""
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr ""
+
+msgid "[OPTION]... PATCH..."
+msgstr ""
+
+msgid "show newest record first"
+msgstr ""
+
+msgid "file to store the bundles into"
+msgstr ""
+
+msgid "a specific revision up to which you would like to pull"
+msgstr ""
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr ""
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr ""
+
+msgid "search the repository as it stood at REV"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr ""
+
+msgid "print complete paths from the filesystem root"
+msgstr ""
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr ""
+
+msgid "only follow the first parent of merge changesets"
+msgstr ""
+
+#, fuzzy
+msgid "show revisions matching date spec"
+msgstr ""
+
+msgid "show copied files"
+msgstr ""
+
+msgid "do case-insensitive search for a keyword"
+msgstr ""
+
+msgid "include revisions where files were removed"
+msgstr ""
+
+msgid "show only merges"
+msgstr ""
+
+msgid "revisions committed by user"
+msgstr ""
+
+msgid "show only changesets within the given named branch"
+msgstr ""
+
+msgid "do not display revision or any of its ancestors"
+msgstr ""
+
+msgid "[OPTION]... [FILE]"
+msgstr ""
+
+msgid "revision to display"
+msgstr ""
+
+msgid "[-r REV]"
+msgstr ""
+
+msgid "force a merge with outstanding changes"
+msgstr ""
+
+msgid "revision to merge"
+msgstr ""
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr ""
+
+msgid "[-f] [[-r] REV]"
+msgstr ""
+
+msgid "a specific revision up to which you would like to push"
+msgstr ""
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr ""
+
+#, fuzzy
+msgid "show parents from the specified revision"
+msgstr ""
+
+#, fuzzy
+msgid "[-r REV] [FILE]"
+msgstr "[-r ΕΚΔΟΣΗ] [ΑΡΧΕΙΟ]"
+
+msgid "[NAME]"
+msgstr ""
+
+msgid "update to new tip if changesets were pulled"
+msgstr ""
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr ""
+
+msgid "force push"
+msgstr ""
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr ""
+
+msgid "record delete for missing files"
+msgstr ""
+
+msgid "remove (and delete) file even if added or modified"
+msgstr ""
+
+msgid "record a rename that has already occurred"
+msgstr ""
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr ""
+
+msgid "remerge all unresolved files"
+msgstr ""
+
+msgid "list state of files needing merge"
+msgstr ""
+
+msgid "mark files as resolved"
+msgstr ""
+
+msgid "unmark files as resolved"
+msgstr ""
+
+msgid "revert all changes when no arguments given"
+msgstr ""
+
+msgid "tipmost revision matching date"
+msgstr ""
+
+msgid "revision to revert to"
+msgstr ""
+
+msgid "do not save backup copies of files"
+msgstr ""
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr ""
+
+msgid "name of access log file to write to"
+msgstr ""
+
+msgid "name of error log file to write to"
+msgstr ""
+
+msgid "port to listen on (default: 8000)"
+msgstr ""
+
+msgid "address to listen on (default: all interfaces)"
+msgstr ""
+
+msgid "prefix path to serve from (default: server root)"
+msgstr ""
+
+msgid "name to show in web pages (default: working directory)"
+msgstr ""
+
+msgid "name of the webdir config file (serve more than one repository)"
+msgstr ""
+
+msgid "for remote clients"
+msgstr ""
+
+msgid "web templates to use"
+msgstr ""
+
+msgid "template style to use"
+msgstr ""
+
+msgid "use IPv6 in addition to IPv4"
+msgstr ""
+
+msgid "SSL certificate file"
+msgstr ""
+
+msgid "show untrusted configuration options"
+msgstr ""
+
+msgid "[-u] [NAME]..."
+msgstr ""
+
+msgid "show status of all files"
+msgstr ""
+
+msgid "show only modified files"
+msgstr ""
+
+msgid "show only added files"
+msgstr ""
+
+msgid "show only removed files"
+msgstr ""
+
+msgid "show only deleted (but tracked) files"
+msgstr ""
+
+msgid "show only files without changes"
+msgstr ""
+
+msgid "show only unknown (not tracked) files"
+msgstr ""
+
+msgid "show only ignored files"
+msgstr ""
+
+msgid "hide status prefix"
+msgstr ""
+
+msgid "show source of copied files"
+msgstr ""
+
+msgid "show difference from revision"
+msgstr ""
+
+msgid "replace existing tag"
+msgstr ""
+
+msgid "make the tag local"
+msgstr ""
+
+msgid "revision to tag"
+msgstr ""
+
+msgid "remove a tag"
+msgstr ""
+
+msgid "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr ""
+
+msgid "[-p]"
+msgstr ""
+
+msgid "update to new tip if changesets were unbundled"
+msgstr ""
+
+msgid "[-u] FILE..."
+msgstr ""
+
+msgid "overwrite locally modified files (no backup)"
+msgstr ""
+
+msgid "[-C] [-d DATE] [[-r] REV]"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "config error at %s:%d: '%s'"
+msgstr ""
+
+msgid "not found in manifest"
+msgstr ""
+
+msgid "branch name not in UTF-8!"
+msgstr ""
+
+#, python-format
+msgid " searching for copies back to rev %d\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" unmatched files in local:\n"
+" %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" unmatched files in other:\n"
+" %s\n"
+msgstr ""
+
+msgid " all copies found (* = to merge, ! = divergent):\n"
+msgstr ""
+
+msgid " checking for directory renames\n"
+msgstr ""
+
+#, python-format
+msgid " dir %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid " file %s -> %s\n"
+msgstr ""
+
+#, fuzzy
+msgid "working directory state appears damaged!"
+msgstr "χώÏος εÏγασίας του %s"
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr ""
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr ""
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr ""
+
+#, python-format
+msgid "not in dirstate: %s\n"
+msgstr ""
+
+msgid "unknown"
+msgstr ""
+
+msgid "character device"
+msgstr ""
+
+msgid "block device"
+msgstr ""
+
+msgid "fifo"
+msgstr ""
+
+msgid "socket"
+msgstr ""
+
+msgid "directory"
+msgstr ""
+
+#, python-format
+msgid "unsupported file type (type is %s)"
+msgstr ""
+
+#, python-format
+msgid "abort: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+" %s\n"
+msgstr ""
+"hg: kommandoen '%s' is tvetydig:\n"
+" %s\n"
+
+#, python-format
+msgid "hg: %s\n"
+msgstr ""
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr ""
+
+#, python-format
+msgid "lock held by %s"
+msgstr ""
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr ""
+
+#, python-format
+msgid "abort: %s"
+msgstr ""
+
+msgid " empty string\n"
+msgstr ""
+
+msgid "killed!\n"
+msgstr ""
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "abort: could not import module %s!\n"
+msgstr ""
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr ""
+
+msgid "(is your Python install correct?)\n"
+msgstr ""
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr ""
+
+msgid "broken pipe\n"
+msgstr ""
+
+msgid "interrupted!\n"
+msgstr ""
+
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+
+msgid "abort: out of memory\n"
+msgstr ""
+
+msgid "** unknown exception encountered, details follow\n"
+msgstr ""
+
+msgid "** report bug details to http://www.selenic.com/mercurial/bts\n"
+msgstr ""
+
+msgid "** or mercurial@selenic.com\n"
+msgstr ""
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr "** Mercurial Κατανεμημένο SCM (έκδοση %s)\n"
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr "** ΕνεÏγές επεκτάσεις: %s\n"
+
+#, python-format
+msgid "no definition for alias '%s'\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "alias '%s' resolves to unknown command '%s'\n"
+msgstr "η αλλαγή αναφέÏεται σε άγνωστο manifest %s"
+
+#, python-format
+msgid "alias '%s' resolves to ambiguous command '%s'\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "alias '%s' shadows command\n"
+msgstr ""
+"λίστα εντολών:\n"
+"\n"
+
+#, python-format
+msgid "malformed --config option: %s"
+msgstr ""
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr ""
+
+msgid "Option --config may not be abbreviated!"
+msgstr ""
+
+msgid "Option --cwd may not be abbreviated!"
+msgstr ""
+
+msgid ""
+"Option -R has to be separated from other options (e.g. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr ""
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr ""
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr ""
+
+msgid "invalid arguments"
+msgstr ""
+
+#, python-format
+msgid "unrecognized profiling format '%s' - Ignored\n"
+msgstr ""
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr ""
+
+#, python-format
+msgid "picked tool '%s' for %s (binary %s symlink %s)\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+
+msgid "&Local"
+msgstr ""
+
+msgid "&Other"
+msgstr ""
+
+msgid "l"
+msgstr ""
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "my %s other %s ancestor %s\n"
+msgstr ""
+
+msgid " premerge successful\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+
+msgid "&No"
+msgstr ""
+
+msgid "&Yes"
+msgstr ""
+
+msgid "n"
+msgstr ""
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr ""
+
+#, python-format
+msgid "Inconsistent state, %s:%s is good and bad"
+msgstr ""
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr ""
+
+msgid "Date Formats"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"\n"
+" Some commands allow the user to specify a date, e.g.:\n"
+" * backout, commit, import, tag: Specify the commit date.\n"
+" * log, revert, update: Select revision(s) by date.\n"
+"\n"
+" Many date formats are valid. Here are some examples:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n"
+" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n"
+" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n"
+" \"Dec 6\" (midnight)\n"
+" \"13:18\" (today assumed)\n"
+" \"3:39\" (3:39AM assumed)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Lastly, there is Mercurial's internal format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" This is the internal representation format for dates. unixtime is\n"
+" the number of seconds since the epoch (1970-01-01 00:00 UTC).\n"
+" offset is the offset of the local timezone, in seconds west of UTC\n"
+" (negative if the timezone is east of UTC).\n"
+"\n"
+" The log command also accepts date ranges:\n"
+"\n"
+" \"<{datetime}\" - at or before a given date/time\n"
+" \">{datetime}\" - on or after a given date/time\n"
+" \"{datetime} to {datetime}\" - a date range, inclusive\n"
+" \"-{days}\" - within a given number of days of today\n"
+" "
+msgstr ""
+"\n"
+" Nogle kommandoer tillader brugeren at specificere en dato:\n"
+" backout, commit, import, tag: specificer commit-datøn.\n"
+" log, revert, update: vælg revisioner eftre dato.\n"
+"\n"
+" Der er mange gyldige datoformater. Her er nogle eksempler:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (antager lokal tidszone)\n"
+" \"Dec 6 13:18 -0600\" (antager år, tidszone er angivet)\n"
+" \"Dec 6 13:18 UTC\" (UTC og GMT er aliaser for +0000)\n"
+" \"Dec 6\" (midnat)\n"
+" \"13:18\" (antager dags dato)\n"
+" \"3:39\"\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (6. dec. 2006)\n"
+"\n"
+" Endelig er der Mercurials interne format:\n"
+"\n"
+" \"1165432709 0\" (Ons 6. dec. 13:18:29 2006 UTC)\n"
+"\n"
+" Dette er den interne representation af datoer. unixtime er\n"
+" antallet af sekunder siden begyndelsen af epoken (1970-01-01 00:00\n"
+" UTC). offset er den lokale tidszone, angivet i antal sekunder vest\n"
+" for UTC (negativ hvis tidszonen er øst for UTC).\n"
+"\n"
+" Kommandoen log accepterer også datointervaller:\n"
+"\n"
+" \"<{date}\" - på eller før den angivne dato\n"
+" \">{date}\" - på eller efter den angivne dato\n"
+" \"{date} to {date}\" - et datointerval, inklusiv endepunkterne\n"
+" \"-{days}\" - indenfor et angivet antal date, fra dags dato\n"
+" "
+
+msgid "File Name Patterns"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial accepts several notations for identifying one or more\n"
+" files at a time.\n"
+"\n"
+" By default, Mercurial treats filenames as shell-style extended\n"
+" glob patterns.\n"
+"\n"
+" Alternate pattern notations must be specified explicitly.\n"
+"\n"
+" To use a plain path name without any pattern matching, start it\n"
+" with \"path:\". These path names must completely match starting at\n"
+" the current repository root.\n"
+"\n"
+" To use an extended glob, start a name with \"glob:\". Globs are\n"
+" rooted at the current directory; a glob such as \"*.c\" will only\n"
+" match files in the current directory ending with \".c\".\n"
+"\n"
+" The supported glob syntax extensions are \"**\" to match any string\n"
+" across path separators and \"{a,b}\" to mean \"a or b\".\n"
+"\n"
+" To use a Perl/Python regular expression, start a name with \"re:\".\n"
+" Regexp pattern matching is anchored at the root of the repository.\n"
+"\n"
+" Plain examples:\n"
+"\n"
+" path:foo/bar a name bar in a directory named foo in the root of\n"
+" the repository\n"
+" path:path:name a file or directory named \"path:name\"\n"
+"\n"
+" Glob examples:\n"
+"\n"
+" glob:*.c any name ending in \".c\" in the current directory\n"
+" *.c any name ending in \".c\" in the current directory\n"
+" **.c any name ending in \".c\" in any subdirectory of the\n"
+" current directory including itself.\n"
+" foo/*.c any name ending in \".c\" in the directory foo\n"
+" foo/**.c any name ending in \".c\" in any subdirectory of foo\n"
+" including itself.\n"
+"\n"
+" Regexp examples:\n"
+"\n"
+" re:.*\\.c$ any name ending in \".c\", anywhere in the repository\n"
+"\n"
+" "
+msgstr ""
+
+msgid "Environment Variables"
+msgstr ""
+
+msgid ""
+"\n"
+"HG::\n"
+" Path to the 'hg' executable, automatically passed when running\n"
+" hooks, extensions or external tools. If unset or empty, this is\n"
+" the hg executable's name if it's frozen, or an executable named\n"
+" 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+" Windows) is searched.\n"
+"\n"
+"HGEDITOR::\n"
+" This is the name of the editor to run when committing. See EDITOR.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" This overrides the default locale setting detected by Mercurial.\n"
+" This setting is used to convert data including usernames,\n"
+" changeset descriptions, tag names, and branches. This setting can\n"
+" be overridden with the --encoding command-line option.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" This sets Mercurial's behavior for handling unknown characters\n"
+" while transcoding user input. The default is \"strict\", which\n"
+" causes Mercurial to abort if it can't map a character. Other\n"
+" settings include \"replace\", which replaces unknown characters, and\n"
+" \"ignore\", which drops them. This setting can be overridden with\n"
+" the --encodingmode command-line option.\n"
+"\n"
+"HGMERGE::\n"
+" An executable to use for resolving merge conflicts. The program\n"
+" will be executed with three arguments: local file, remote file,\n"
+" ancestor file.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" A list of files or directories to search for hgrc files. Item\n"
+" separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
+" platform default search path is used. If empty, only the .hg/hgrc\n"
+" from the current repository is read.\n"
+"\n"
+" For each element in HGRCPATH:\n"
+" * if it's a directory, all files ending with .rc are added\n"
+" * otherwise, the file itself will be added\n"
+"\n"
+"HGUSER::\n"
+" This is the string used as the author of a commit. If not set,\n"
+" available values will be considered in this order:\n"
+"\n"
+" * HGUSER (deprecated)\n"
+" * hgrc files from the HGRCPATH\n"
+" * EMAIL\n"
+" * interactive prompt\n"
+" * LOGNAME (with '@hostname' appended)\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"LOGNAME::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"VISUAL::\n"
+" This is the name of the editor to use when committing. See EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Sometimes Mercurial needs to open a text file in an editor for a\n"
+" user to modify, for example when writing commit messages. The\n"
+" editor it uses is determined by looking at the environment\n"
+" variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+" non-empty one is chosen. If all of them are empty, the editor\n"
+" defaults to 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" This is used by Python to find imported modules and may need to be\n"
+" set appropriately if this Mercurial is not installed system-wide.\n"
+" "
+msgstr ""
+
+msgid "Specifying Single Revisions"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial supports several ways to specify individual revisions.\n"
+"\n"
+" A plain integer is treated as a revision number. Negative integers\n"
+" are treated as topological offsets from the tip, with -1 denoting\n"
+" the tip. As such, negative numbers are only useful if you've\n"
+" memorized your local tree numbers and want to save typing a single\n"
+" digit. This editor suggests copy and paste.\n"
+"\n"
+" A 40-digit hexadecimal string is treated as a unique revision\n"
+" identifier.\n"
+"\n"
+" A hexadecimal string less than 40 characters long is treated as a\n"
+" unique revision identifier, and referred to as a short-form\n"
+" identifier. A short-form identifier is only valid if it is the\n"
+" prefix of exactly one full-length identifier.\n"
+"\n"
+" Any other string is treated as a tag name, which is a symbolic\n"
+" name associated with a revision identifier. Tag names may not\n"
+" contain the \":\" character.\n"
+"\n"
+" The reserved name \"tip\" is a special tag that always identifies\n"
+" the most recent revision.\n"
+"\n"
+" The reserved name \"null\" indicates the null revision. This is the\n"
+" revision of an empty repository, and the parent of revision 0.\n"
+"\n"
+" The reserved name \".\" indicates the working directory parent. If\n"
+" no working directory is checked out, it is equivalent to null. If\n"
+" an uncommitted merge is in progress, \".\" is the revision of the\n"
+" first parent.\n"
+" "
+msgstr ""
+
+msgid "Specifying Multiple Revisions"
+msgstr ""
+
+msgid ""
+"\n"
+" When Mercurial accepts more than one revision, they may be\n"
+" specified individually, or provided as a topologically continuous\n"
+" range, separated by the \":\" character.\n"
+"\n"
+" The syntax of range notation is [BEGIN]:[END], where BEGIN and END\n"
+" are revision identifiers. Both BEGIN and END are optional. If\n"
+" BEGIN is not specified, it defaults to revision number 0. If END\n"
+" is not specified, it defaults to the tip. The range \":\" thus means\n"
+" \"all revisions\".\n"
+"\n"
+" If BEGIN is greater than END, revisions are treated in reverse\n"
+" order.\n"
+"\n"
+" A range acts as a closed interval. This means that a range of 3:5\n"
+" gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+" "
+msgstr ""
+
+msgid "Diff Formats"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial's default format for showing changes between two\n"
+" versions of a file is compatible with the unified format of GNU\n"
+" diff, which can be used by GNU patch and many other standard\n"
+" tools.\n"
+"\n"
+" While this standard format is often enough, it does not encode the\n"
+" following information:\n"
+"\n"
+" - executable status and other permission bits\n"
+" - copy or rename information\n"
+" - changes in binary files\n"
+" - creation or deletion of empty files\n"
+"\n"
+" Mercurial also supports the extended diff format from the git VCS\n"
+" which addresses these limitations. The git diff format is not\n"
+" produced by default because a few widespread tools still do not\n"
+" understand this format.\n"
+"\n"
+" This means that when generating diffs from a Mercurial repository\n"
+" (e.g. with \"hg export\"), you should be careful about things like\n"
+" file copies and renames or other things mentioned above, because\n"
+" when applying a standard diff to a different repository, this\n"
+" extra information is lost. Mercurial's internal operations (like\n"
+" push and pull) are not affected by this, because they use an\n"
+" internal binary format for communicating changes.\n"
+"\n"
+" To make Mercurial produce the git extended diff format, use the\n"
+" --git option available for many commands, or set 'git = True' in\n"
+" the [diff] section of your hgrc. You do not need to set this\n"
+" option when importing diffs in this format or using them in the mq\n"
+" extension.\n"
+" "
+msgstr ""
+
+msgid "Template Usage"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial allows you to customize output of commands through\n"
+" templates. You can either pass in a template from the command\n"
+" line, via the --template option, or select an existing\n"
+" template-style (--style).\n"
+"\n"
+" You can customize output for any \"log-like\" command: log,\n"
+" outgoing, incoming, tip, parents, heads and glog.\n"
+"\n"
+" Three styles are packaged with Mercurial: default (the style used\n"
+" when no explicit preference is passed), compact and changelog.\n"
+" Usage:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" A template is a piece of text, with markup to invoke variable\n"
+" expansion:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings in curly braces are called keywords. The availability of\n"
+" keywords depends on the exact context of the templater. These\n"
+" keywords are usually available for templating a log-like command:\n"
+"\n"
+" - author: String. The unmodified author of the changeset.\n"
+" - branches: String. The name of the branch on which the changeset\n"
+" was committed. Will be empty if the branch name was default.\n"
+" - date: Date information. The date when the changeset was committed.\n"
+" - desc: String. The text of the changeset description.\n"
+" - diffstat: String. Statistics of changes with the following\n"
+" format: \"modified files: +added/-removed lines\"\n"
+" - files: List of strings. All files modified, added, or removed by\n"
+" this changeset.\n"
+" - file_adds: List of strings. Files added by this changeset.\n"
+" - file_mods: List of strings. Files modified by this changeset.\n"
+" - file_dels: List of strings. Files removed by this changeset.\n"
+" - node: String. The changeset identification hash, as a\n"
+" 40-character hexadecimal string.\n"
+" - parents: List of strings. The parents of the changeset.\n"
+" - rev: Integer. The repository-local changeset revision number.\n"
+" - tags: List of strings. Any tags associated with the changeset.\n"
+"\n"
+" The \"date\" keyword does not produce human-readable output. If you\n"
+" want to use a date in your output, you can use a filter to process\n"
+" it. Filters are functions which return a string based on the input\n"
+" variable. You can also use a chain of filters to get the desired\n"
+" output:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" List of filters:\n"
+"\n"
+" - addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
+" every line except the last.\n"
+" - age: Date. Returns a human-readable date/time difference between\n"
+" the given date/time and the current date/time.\n"
+" - basename: Any text. Treats the text as a path, and returns the\n"
+" last component of the path after splitting by the path\n"
+" separator (ignoring trailing separators). For example,\n"
+" \"foo/bar/baz\" becomes \"baz\" and \"foo/bar//\" becomes \"bar"
+"\".\n"
+" - stripdir: Treat the text as path and strip a directory level, if\n"
+" possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\".\n"
+" - date: Date. Returns a date in a Unix date format, including\n"
+" the timezone: \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - domain: Any text. Finds the first string that looks like an\n"
+" email address, and extracts just the domain component.\n"
+" Example: 'User <user@example.com>' becomes 'example.com'.\n"
+" - email: Any text. Extracts the first string that looks like an\n"
+" email address. Example: 'User <user@example.com>' becomes\n"
+" 'user@example.com'.\n"
+" - escape: Any text. Replaces the special XML/XHTML characters \"&\",\n"
+" \"<\" and \">\" with XML entities.\n"
+" - fill68: Any text. Wraps the text to fit in 68 columns.\n"
+" - fill76: Any text. Wraps the text to fit in 76 columns.\n"
+" - firstline: Any text. Returns the first line of text.\n"
+" - nonempty: Any text. Returns '(none)' if the string is empty.\n"
+" - hgdate: Date. Returns the date as a pair of numbers:\n"
+" \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
+" - isodate: Date. Returns the date in ISO 8601 format.\n"
+" - localdate: Date. Converts a date to local date.\n"
+" - obfuscate: Any text. Returns the input text rendered as a\n"
+" sequence of XML entities.\n"
+" - person: Any text. Returns the text before an email address.\n"
+" - rfc822date: Date. Returns a date using the same format used\n"
+" in email headers.\n"
+" - short: Changeset hash. Returns the short form of a changeset\n"
+" hash, i.e. a 12-byte hexadecimal string.\n"
+" - shortdate: Date. Returns a date like \"2006-09-18\".\n"
+" - strip: Any text. Strips all leading and trailing whitespace.\n"
+" - tabindent: Any text. Returns the text, with every line except\n"
+" the first starting with a tab character.\n"
+" - urlescape: Any text. Escapes all \"special\" characters. For\n"
+" example, \"foo bar\" becomes \"foo%20bar\".\n"
+" - user: Any text. Returns the user portion of an email address.\n"
+" "
+msgstr ""
+
+msgid "URL Paths"
+msgstr ""
+
+msgid ""
+"\n"
+" Valid URLs are of the form:\n"
+"\n"
+" local/filesystem/path (or file://local/filesystem/path)\n"
+" http://[user[:pass]@]host[:port]/[path]\n"
+" https://[user[:pass]@]host[:port]/[path]\n"
+" ssh://[user[:pass]@]host[:port]/[path]\n"
+"\n"
+" Paths in the local filesystem can either point to Mercurial\n"
+" repositories or to bundle files (as created by 'hg bundle' or\n"
+" 'hg incoming --bundle').\n"
+"\n"
+" An optional identifier after # indicates a particular branch, tag,\n"
+" or changeset to use from the remote repository.\n"
+"\n"
+" Some features, such as pushing to http:// and https:// URLs are\n"
+" only possible if the feature is explicitly enabled on the remote\n"
+" Mercurial server.\n"
+"\n"
+" Some notes about using SSH with Mercurial:\n"
+" - SSH requires an accessible shell account on the destination\n"
+" machine and a copy of hg in the remote path or specified with as\n"
+" remotecmd.\n"
+" - path is relative to the remote user's home directory by default.\n"
+" Use an extra slash at the start of a path to specify an absolute "
+"path:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial doesn't use its own compression via SSH; the right\n"
+" thing to do is to configure it in your ~/.ssh/config, e.g.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternatively specify \"ssh -C\" as your ssh command in your hgrc\n"
+" or with the --ssh command line option.\n"
+"\n"
+" These URLs can all be stored in your hgrc with path aliases under\n"
+" the [paths] section like so:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" You can then use the alias for any command that uses a URL (for\n"
+" example 'hg pull alias1' would pull from the 'alias1' path).\n"
+"\n"
+" Two path aliases are special because they are used as defaults\n"
+" when you do not provide the URL to a command:\n"
+"\n"
+" default:\n"
+" When you create a repository with hg clone, the clone command\n"
+" saves the location of the source repository as the new\n"
+" repository's 'default' path. This is then used when you omit\n"
+" path from push- and pull-like commands (including incoming and\n"
+" outgoing).\n"
+"\n"
+" default-push:\n"
+" The push command will look for a path named 'default-push', and\n"
+" prefer it over 'default' if both are defined.\n"
+" "
+msgstr ""
+
+msgid "can only share local repositories"
+msgstr ""
+
+#, fuzzy
+msgid "destination already exists"
+msgstr ""
+
+msgid "updating working directory\n"
+msgstr ""
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr ""
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "destination '%s' is not empty"
+msgstr ""
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr ""
+
+msgid "clone from remote to remote not supported"
+msgstr ""
+
+msgid "updated"
+msgstr ""
+
+msgid "merged"
+msgstr ""
+
+msgid "removed"
+msgstr ""
+
+msgid "unresolved"
+msgstr ""
+
+#, python-format
+msgid "%d files %s"
+msgstr ""
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr ""
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to "
+"abandon\n"
+msgstr ""
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr ""
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr ""
+
+msgid "SSL support is unavailable"
+msgstr ""
+
+#, fuzzy
+msgid "IPv6 is not available on this system"
+msgstr ""
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr ""
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook failed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr ""
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook %s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr ""
+
+msgid "connection ended unexpectedly"
+msgstr ""
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "using %s\n"
+msgstr ""
+
+#, python-format
+msgid "capabilities: %s\n"
+msgstr ""
+
+msgid "operation not supported over http"
+msgstr ""
+
+#, python-format
+msgid "sending %s command\n"
+msgstr ""
+
+#, python-format
+msgid "sending %s bytes\n"
+msgstr ""
+
+msgid "authorization failed"
+msgstr ""
+
+#, python-format
+msgid "http error while sending %s command\n"
+msgstr ""
+
+msgid "http error, possibly caused by proxy setting"
+msgstr ""
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr ""
+
+#, python-format
+msgid "requested URL: '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr ""
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr ""
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr ""
+
+msgid "look up remote revision"
+msgstr ""
+
+msgid "unexpected response:"
+msgstr ""
+
+msgid "look up remote changes"
+msgstr ""
+
+msgid "push failed (unexpected response):"
+msgstr ""
+
+#, python-format
+msgid "push failed: %s"
+msgstr ""
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr "δεν έχει εγκατασταθεί υποστήÏιξη SSL και HTTPS για την Python"
+
+msgid "cannot create new http repository"
+msgstr "δε μποÏεί να δημιουÏγηθεί ένα νέο αποθετήÏιο μέσω http"
+
+#, python-format
+msgid "%s: ignoring invalid syntax '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s not found"
+msgstr "το αποθετήÏιο %s δε βÏέθηκε"
+
+#, python-format
+msgid "repository %s already exists"
+msgstr "το αποθετήÏιο %s υπάÏχει ήδη"
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr ""
+
+#, python-format
+msgid ".hg/sharedpath points to nonexistent directory %s"
+msgstr ""
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr "το %r δε μποÏεί να χÏησιμοποιηθεί ως όνομα ετικέτας"
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr ""
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr "%s, γÏαμμή %s: %s\n"
+
+msgid "cannot parse entry"
+msgstr ""
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' refers to unknown node"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "working directory has unknown parent '%s'!"
+msgstr "χώÏος εÏγασίας του %s"
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr ""
+
+#, python-format
+msgid "filtering %s through %s\n"
+msgstr ""
+
+msgid "journal already exists - run hg recover"
+msgstr ""
+
+msgid "rolling back interrupted transaction\n"
+msgstr ""
+
+msgid "no interrupted transaction available\n"
+msgstr ""
+
+msgid "rolling back last transaction\n"
+msgstr ""
+
+#, python-format
+msgid "Named branch could not be reset, current branch still is: %s\n"
+msgstr ""
+
+msgid "no rollback information available\n"
+msgstr ""
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s"
+msgstr ""
+
+#, python-format
+msgid "working directory of %s"
+msgstr "χώÏος εÏγασίας του %s"
+
+#, python-format
+msgid " %s: searching for copy revision for %s\n"
+msgstr ""
+
+#, python-format
+msgid " %s: copy %s:%s\n"
+msgstr ""
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr ""
+
+#, fuzzy
+msgid "file not found!"
+msgstr "δε βÏέθηκε!\n"
+
+msgid "no match under directory!"
+msgstr ""
+
+msgid "file not tracked!"
+msgstr ""
+
+msgid "nothing changed\n"
+msgstr ""
+
+msgid "unresolved merge conflicts (see hg resolve)"
+msgstr ""
+
+#, python-format
+msgid "committing subrepository %s\n"
+msgstr ""
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"%s: files over 10MB may cause memory and performance problems\n"
+"(use 'hg revert %s' to unadd the file)\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr ""
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added!\n"
+msgstr ""
+
+#, python-format
+msgid "%s still exists!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr ""
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr ""
+
+msgid "searching for changes\n"
+msgstr ""
+
+#, python-format
+msgid "examining %s:%s\n"
+msgstr ""
+
+msgid "branch already found\n"
+msgstr ""
+
+#, python-format
+msgid "found incomplete branch %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "found new changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "request %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "received %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowing %d:%d %s\n"
+msgstr ""
+
+#, python-format
+msgid "found new branch changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowed branch search to %s:%s\n"
+msgstr ""
+
+msgid "already have changeset "
+msgstr ""
+
+msgid "warning: repository is unrelated\n"
+msgstr ""
+
+msgid "repository is unrelated"
+msgstr ""
+
+msgid "found new changesets starting at "
+msgstr ""
+
+#, python-format
+msgid "%d total queries\n"
+msgstr ""
+
+msgid "common changesets up to "
+msgstr ""
+
+msgid "requesting all changes\n"
+msgstr ""
+
+msgid ""
+"Partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr ""
+
+#, python-format
+msgid "abort: push creates new remote branch '%s'!\n"
+msgstr ""
+
+msgid "abort: push creates new remote heads!\n"
+msgstr ""
+
+msgid "(did you forget to merge? use push -f to force)\n"
+msgstr ""
+
+msgid "note: unsynced remote changes!\n"
+msgstr ""
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr ""
+
+msgid "list of changesets:\n"
+msgstr ""
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr ""
+
+#, python-format
+msgid "add changeset %s\n"
+msgstr "Ï€Ïοσθήκη αλλαγής %s\n"
+
+msgid "adding changesets\n"
+msgstr "Ï€Ïοσθήκη αλλαγών\n"
+
+msgid "received changelog group is empty"
+msgstr ""
+
+msgid "adding manifests\n"
+msgstr ""
+
+msgid "adding file changes\n"
+msgstr ""
+
+#, python-format
+msgid "adding %s revisions\n"
+msgstr ""
+
+msgid "received file revlog group is empty"
+msgstr ""
+
+#, python-format
+msgid " (%+d heads)"
+msgstr ""
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr ""
+
+msgid "updating the branch cache\n"
+msgstr ""
+
+msgid "Unexpected response from remote server:"
+msgstr ""
+
+msgid "operation forbidden by server"
+msgstr ""
+
+msgid "locking the remote repository failed"
+msgstr ""
+
+msgid "the server sent an unknown error code"
+msgstr ""
+
+msgid "streaming all changes\n"
+msgstr ""
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr ""
+
+#, python-format
+msgid "adding %s (%s)\n"
+msgstr ""
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr ""
+
+msgid "no [smtp]host in hgrc - cannot send mail"
+msgstr ""
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr ""
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr ""
+
+msgid "(using tls)\n"
+msgstr ""
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr ""
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr ""
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr ""
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr ""
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr ""
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr ""
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr ""
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr ""
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr ""
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+
+#, fuzzy
+msgid "&None"
+msgstr "ολοκληÏώθηκε\n"
+
+msgid "E&xec"
+msgstr ""
+
+msgid "Sym&link"
+msgstr ""
+
+msgid "resolving manifests\n"
+msgstr ""
+
+#, python-format
+msgid " overwrite %s partial %s\n"
+msgstr ""
+
+#, python-format
+msgid " ancestor %s local %s remote %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+msgid "&Changed"
+msgstr ""
+
+msgid "&Delete"
+msgstr ""
+
+msgid "c"
+msgstr ""
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+
+msgid "&Deleted"
+msgstr ""
+
+#, python-format
+msgid "preserving %s for resolve of %s\n"
+msgstr ""
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s\n"
+msgstr "λήψη του %s\n"
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr "λήψη του %s στο %s\n"
+
+#, python-format
+msgid "warning: detected divergent renames of %s to:\n"
+msgstr ""
+
+#, python-format
+msgid "branch %s not found"
+msgstr ""
+
+msgid "can't merge with ancestor"
+msgstr ""
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr ""
+
+#, fuzzy
+msgid "outstanding uncommitted changes (use 'hg status' to list changes)"
+msgstr "υπάÏχουν τοπικές αλλαγές ακόμη"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C' to discard changes)"
+msgstr ""
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C')"
+msgstr ""
+
+msgid "crosses named branches (use 'hg update -C' to discard changes)"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr ""
+
+#, python-format
+msgid "found patch at byte %d\n"
+msgstr ""
+
+msgid "patch generated by hg export\n"
+msgstr ""
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr ""
+
+#, python-format
+msgid "patching file %s\n"
+msgstr ""
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr ""
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d line).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d lines).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr ""
+
+msgid "could not extract binary patch"
+msgstr ""
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr ""
+
+#, python-format
+msgid "unable to strip away %d dirs from %s"
+msgstr ""
+
+msgid "undefined source and destination files"
+msgstr ""
+
+#, python-format
+msgid "malformed patch %s %s"
+msgstr ""
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr ""
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr ""
+
+#, python-format
+msgid "Unsupported line endings type: %s"
+msgstr ""
+
+#, python-format
+msgid "no valid hunks found; trying with %r instead\n"
+msgstr ""
+
+#, python-format
+msgid "exited with status %d"
+msgstr ""
+
+#, python-format
+msgid "killed by signal %d"
+msgstr ""
+
+#, python-format
+msgid "stopped by signal %d"
+msgstr ""
+
+msgid "invalid exit code"
+msgstr ""
+
+#, python-format
+msgid "saving bundle to %s\n"
+msgstr ""
+
+msgid "adding branch\n"
+msgstr ""
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr ""
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "index %s is corrupted"
+msgstr ""
+
+msgid "no node"
+msgstr ""
+
+msgid "ambiguous identifier"
+msgstr ""
+
+msgid "no match found"
+msgstr ""
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr ""
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr ""
+
+msgid "unknown base"
+msgstr ""
+
+msgid "consistency error adding group"
+msgstr ""
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr ""
+
+msgid "can only specify two labels."
+msgstr ""
+
+msgid "warning: conflicts during merge.\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr ""
+
+msgid "could not create remote repo"
+msgstr ""
+
+msgid "remote: "
+msgstr "απομακÏυσμένο:"
+
+msgid "no suitable response from remote hg"
+msgstr ""
+
+#, python-format
+msgid "push refused: %s"
+msgstr ""
+
+msgid "unsynced changes"
+msgstr ""
+
+msgid "cannot lock static-http repository"
+msgstr ""
+
+msgid "cannot create new static-http repository"
+msgstr ""
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr ""
+
+msgid "scanning\n"
+msgstr ""
+
+#, python-format
+msgid "%d files, %d bytes to transfer\n"
+msgstr ""
+
+#, python-format
+msgid "sending %s (%d bytes)\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?"
+msgstr ""
+
+#, fuzzy
+msgid "&Remote"
+msgstr "απομακÏυσμένο:"
+
+msgid "r"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed subrepository %s which remote removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid ""
+" remote changed subrepository %s which local removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "removing subrepo %s\n"
+msgstr "αφαίÏεση του %s\n"
+
+#, fuzzy, python-format
+msgid "pulling subrepo %s\n"
+msgstr "καθαÏισμός %s\n"
+
+#, fuzzy, python-format
+msgid "pushing subrepo %s\n"
+msgstr ""
+
+msgid "unmatched quotes"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "error expanding '%s%%%s'"
+msgstr ""
+
+#, python-format
+msgid "unknown filter '%s'"
+msgstr ""
+
+#, python-format
+msgid "style not found: %s"
+msgstr ""
+
+#, python-format
+msgid "template file %s: %s"
+msgstr ""
+
+msgid "cannot use transaction when it is already committed/aborted"
+msgstr ""
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr ""
+
+msgid "transaction abort!\n"
+msgstr ""
+
+msgid "rollback completed\n"
+msgstr ""
+
+msgid "rollback failed - please run hg recover\n"
+msgstr ""
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring untrusted configuration option %s.%s = %s\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "%s.%s not a boolean ('%s')"
+msgstr "η αλλαγή %s δεν είναι γονική αλλαγή της %s"
+
+msgid "enter a commit username:"
+msgstr ""
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr ""
+
+msgid "Please specify a username."
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr ""
+
+msgid "unrecognized response\n"
+msgstr ""
+
+msgid "response expected"
+msgstr ""
+
+msgid "password: "
+msgstr "κωδικός: "
+
+msgid "edit failed"
+msgstr "η επεξεÏγασία απέτυχε"
+
+msgid "http authorization required"
+msgstr ""
+
+msgid "http authorization required\n"
+msgstr ""
+
+#, python-format
+msgid "realm: %s\n"
+msgstr ""
+
+#, python-format
+msgid "user: %s\n"
+msgstr ""
+
+msgid "user:"
+msgstr ""
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr ""
+
+#, python-format
+msgid "proxying through http://%s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr ""
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr ""
+
+#, python-format
+msgid "path %r is inside repo %r"
+msgstr ""
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr ""
+
+msgid "Hardlinks not supported"
+msgstr ""
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid date: %r "
+msgstr ""
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr ""
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr ""
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr ""
+
+#, python-format
+msgid "%.0f GB"
+msgstr "%.0f GB"
+
+#, python-format
+msgid "%.1f GB"
+msgstr "%.1f GB"
+
+#, python-format
+msgid "%.2f GB"
+msgstr "%.2f GB"
+
+#, python-format
+msgid "%.0f MB"
+msgstr "%.0f MB"
+
+#, python-format
+msgid "%.1f MB"
+msgstr "%.1f MB"
+
+#, python-format
+msgid "%.2f MB"
+msgstr "%.2f MB"
+
+#, python-format
+msgid "%.0f KB"
+msgstr "%.0f KB"
+
+#, python-format
+msgid "%.1f KB"
+msgstr "%.1f KB"
+
+#, python-format
+msgid "%.2f KB"
+msgstr "%.2f KB"
+
+#, python-format
+msgid "%.0f bytes"
+msgstr "%.0f bytes"
+
+msgid "cannot verify bundle or remote repos"
+msgstr ""
+
+msgid "interrupted"
+msgstr ""
+
+#, python-format
+msgid "empty or missing %s"
+msgstr "κενό ή μη υπαÏκτό %s"
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr "το μέγεθος των δεδομένων διαφέÏει κατά %d bytes"
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr "Ï€Ïοειδοποίηση: το '%s' χÏησιμοποιεί revlog έκδοσης 1"
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr "Ï€Ïοειδοποίηση: το '%s' χÏησιμοποιεί revlog έκδοσης 0"
+
+#, fuzzy, python-format
+msgid "rev %d points to nonexistent changeset %d"
+msgstr "η έκδοση %d αναφέÏεται στο %s της αλλαγής %d"
+
+#, fuzzy, python-format
+msgid "rev %d points to unexpected changeset %d"
+msgstr "η έκδοση %d αναφέÏεται στο %s της αλλαγής %d"
+
+#, python-format
+msgid " (expected %s)"
+msgstr " (αναμενόταν %s)"
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "checking parents of %s"
+msgstr ""
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr "διπλή έκδοση %d (%d)"
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr "το αποθετήÏιο χÏησιμοποιεί τη μοÏφή revlog %d\n"
+
+msgid "checking changesets\n"
+msgstr "έλεγχος αλλαγών\n"
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr "εξαγωγή αλλαγής %s"
+
+msgid "checking manifests\n"
+msgstr "έλεγχος manifests\n"
+
+#, fuzzy, python-format
+msgid "%s not in changesets"
+msgstr "το %s δεν υπάÏχει στα manifests"
+
+msgid "file without name in manifest"
+msgstr "αÏχείο χωÏίς όνομα στο manifest"
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr "ανάγνωση αλλαγής manifest %s"
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr "διασταÏÏωση αÏχείων στις αλλαγές και τα manifests\n"
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr "η αλλαγή αναφέÏεται σε άγνωστο manifest %s"
+
+msgid "in changeset but not in manifest"
+msgstr "υπάÏχει στην αλλαγή αλλά όχι στο manifest"
+
+msgid "in manifest but not in changeset"
+msgstr "υπάÏχει στο manifest αλλά όχι στην αλλαγή"
+
+msgid "checking files\n"
+msgstr "έλεγχος αÏχείων\n"
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr "δε μποÏεί να αποκωδικοποιηθεί το όνομα αÏχείου '%s'"
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr "μη έγκυÏο revlog! (%s)"
+
+msgid "missing revlog!"
+msgstr "δεν υπάÏχει αυτό το revlog!"
+
+#, python-format
+msgid "%s not in manifests"
+msgstr "το %s δεν υπάÏχει στα manifests"
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr "μέγεθος εξαγόμενων δεδομένων %s, αναμενόταν %s"
+
+#, python-format
+msgid "unpacking %s"
+msgstr "εξαγωγή του %s"
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr "κενό ή μη έγκυÏο revlog Ï€Ïοέλευσης %s:%s"
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s"
+msgstr ""
+"Ï€Ïοειδοποίηση: %s@%s: η έκδοση Ï€Ïοέλευσης της αντιγÏαφής αÏχείου είναι το "
+"nullid %s:%s"
+
+#, python-format
+msgid "checking rename of %s"
+msgstr "έλεγχος μετονομασίας του %s"
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr ""
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr "Ï€Ïοειδοποίηση: οÏφανό revlog '%s'"
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr "%d αÏχεία, %d αλλαγές, %d εκδόσεις αÏχείων\n"
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr "%d ειδοποιήσεις λάθους!\n"
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr "βÏέθηκαν %d λάθη!\n"
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr "(η Ï€Ïώτη Ï€Ïοβληματική αλλαγή φαίνεται να είναι η %d)\n"
+
+msgid "user name not available - set USERNAME environment variable"
+msgstr ""
+
+#~ msgid "return tuple of (match function, list enabled)."
+#~ msgstr "επιστÏέφει ένα tuple (match function, list enabled)."
+
+#~ msgid ""
+#~ "allow user-defined command aliases\n"
+#~ "\n"
+#~ "To use, create entries in your hgrc of the form\n"
+#~ "\n"
+#~ "[alias]\n"
+#~ "mycmd = cmd --args\n"
+#~ msgstr ""
+#~ "οÏισμός Ï€ÏοσαÏμοσμένων εντολών\n"
+#~ "\n"
+#~ "Για να οÏίσετε δικές σας εντολές, Ï€Ïοσθέστε στο αÏχείο hgrc ένα τμήμα\n"
+#~ "σαν το παÏακάτω\n"
+#~ "\n"
+#~ "[alias]\n"
+#~ "mycmd = cmd --args\n"
+
+#~ msgid ""
+#~ "defer command lookup until needed, so that extensions loaded\n"
+#~ " after alias can be aliased"
+#~ msgstr ""
+#~ "καθυστέÏηση ελέγχου εντολών μέχÏι να έχουν φοÏτωθεί όλες οι\n"
+#~ " επεκτάσεις και να οÏισθοÏν όλα τα aliases"
+
+#~ msgid "*** [alias] %s: command %s is unknown"
+#~ msgstr "*** [alias] %s: η εντολή %s είναι άγνωστη"
+
+#~ msgid "*** [alias] %s: command %s is ambiguous"
+#~ msgstr "*** [alias] %s: η εντολή %s είναι ασαφής"
+
+#~ msgid "*** [alias] %s: circular dependency on %s"
+#~ msgstr "*** [alias] %s: κυκλική εξάÏτηση από την εντολή %s"
+
+#~ msgid "*** [alias] %s: no definition\n"
+#~ msgstr "*** [alias] %s: δεν υπάÏχει οÏισμός\n"
+
+#~ msgid ""
+#~ "Strip bookmarks if revisions are stripped using\n"
+#~ " the mercurial.strip method. This usually happens during\n"
+#~ " qpush and qpop"
+#~ msgstr ""
+#~ "ΑφαίÏεση των σελιδοδεικτών όταν αφαιÏοÏνται κάποιες\n"
+#~ " αλλαγές από το αποθετήÏιο με τη μέθοδο mercurial.strip.\n"
+#~ " Αυτό γίνεται συνήθως με τις εντολές qpush και qpop"
+
+#~ msgid ""
+#~ "Add a revision to the repository and\n"
+#~ " move the bookmark"
+#~ msgstr ""
+#~ "ΠÏοσθήκη μιας αλλαγής στο αποθετήÏιο και\n"
+#~ " μετακίνηση του σελιδοδείκτη"
+
+#~ msgid "Merge bookmarks with normal tags"
+#~ msgstr "Συγχώνευση σελιδοδεικτών με τα κανονικά tags"
+
+#~ msgid ""
+#~ "Set the current bookmark\n"
+#~ "\n"
+#~ " If the user updates to a bookmark we update the .hg/bookmarks."
+#~ "current\n"
+#~ " file.\n"
+#~ " "
+#~ msgstr ""
+#~ "ΟÏισμός ενεÏÎ³Î¿Ï ÏƒÎµÎ»Î¹Î´Î¿Î´ÎµÎ¯ÎºÏ„Î·\n"
+#~ "\n"
+#~ " Αυτόματη ενημέÏωση του .hg/bookmarks.current κάθε φοÏά που ο χÏήστης\n"
+#~ " εξάγει τα αÏχεία με βάση ένα σελιδοδείκτη.\n"
+#~ " "
+
+#~ msgid "support for bugzilla version 2.16."
+#~ msgstr "υποστήÏιξη για το buzgilla 2.16."
+
+#~ msgid "run a query."
+#~ msgstr "εκτέλεση μιας αίτησης."
+
+#~ msgid "look up numeric bugzilla user id."
+#~ msgstr "αναζήτηση χÏήστη με βάση τον αÏιθμό id του."
+
+#~ msgid "map name of committer to bugzilla user name."
+#~ msgstr ""
+#~ "αντιστοίχηση ονόματος συγγÏαφέα αλλαγών με όνομα χÏήστη στο bugzilla."
+
+#~ msgid "support for bugzilla 2.18 series."
+#~ msgstr "υποστήÏιξη για τη σειÏά bugzilla 2.18."
+
+#~ msgid "support for bugzilla 3.0 series."
+#~ msgstr "υποστήÏιξη για τη σειÏά bugzilla 3.0."
+
+#~ msgid "unable to open %s: %s"
+#~ msgstr ""
+
+#~ msgid "%s, please check your locale settings"
+#~ msgstr ""
diff --git a/sys/src/cmd/hg/i18n/fr.po b/sys/src/cmd/hg/i18n/fr.po
new file mode 100644
index 000000000..55759cdf1
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/fr.po
@@ -0,0 +1,9171 @@
+# French translations for Mercurial
+# Traductions françaises de Mercurial
+# Copyright (C) 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# Quelques règles :
+# - dans l'aide d'une commande, la première ligne descriptive
+# commence par un verbe au présent sans majuscule
+# - dans l'aide d'une commande, la description des options
+# utilise un verbe à l'infinitif
+#
+# Note : la terminologie ci-dessous est loin d'être complète, figée ou
+# parfaite. À compléter et à améliorer, particulièrement les
+# termes comportant un point d'interrogation...
+#
+# Dictionnaire de termes courants :
+# - to apply a patch appliquer un patch
+# - a branch une branche
+# - to check out extraire (terminologie utilisée par svn)
+# - children des rejetons ? des descendants ?
+# - to clone clôner
+# - a conflict un conflit
+# - an extension une extension (au sens de module Mercurial)
+# - to fold patches agréger des patchs (replier des patch ?? bof)
+# - an integrity check une vérification d'intégrité (ou de cohérence ?)
+# - a mail un courriel, un courrier électronique
+# - a merge une fusion
+# - to merge fusionner
+# - a node un nœud ?
+# - a patch queue/stack une pile de patchs (mq)
+# - à l'utilisation c'est vraiment une _pile_
+# (on y empile et dépile des patchs)
+# - l'unique cas où _file_ conviendrait est dans le
+# contexte de la commande qfinish
+# => terme unique de pile pour plus de cohérence
+# - the patch series la série (complète) de patchs (suite ?)
+# - rejects des rejets ? (à propos de l'application d'un
+# patch)
+# - a repository un dépôt
+# - to revert annuler des modifications (ou défaire ?)
+# - a revision une révision
+# - the topmost patch le dernier patch appliqué
+# - a tree une arborescence
+# - an unrelated repository un dépôt non apparenté
+# - unversioned
+# unmanaged
+# untracked non suivi, non géré, pas sous contrôle du dépôt,
+# hors révision ?
+# - the working directory le répertoire de travail
+#
+# Termes très courants repris de l'anglais - à utiliser sans guillemets
+# pour ne pas alourdir inutilement la traduction :
+# - a diff un diff ? (ou également un patch ? synonymes...)
+# - a hook un hook
+# - a patch un patch
+# - a tag un tag
+# - to tag taguer
+#
+# Termes anglais avec une signification très spécifique, difficile à
+# paraphraser sans alourdir ou perdre le sens - à utiliser avec guillemets :
+# - a bundle un \"bundle\"
+# - to bundle créer un \"bundle\" ?
+# - a changeset un \"changeset\"
+# - a changegroup un \"changegroup\"
+# - the tip la révision \"tip\"
+#
+# Termes dont le classement / la traduction sont à déterminer :
+# - a commit un commit, un \"commit\"
+# - to commit \"committer\" ? (beuark, même dit tous les jours)
+# - a guard une \"garde\" ? (une protection ?)
+# - to guard a patch \"garder\" un patch ?
+# - to pull rapatrier des \"changesets\" ? effectuer une
+# opération de \"pull\" ? \"puller\" ?? (argh !)
+# - to push propager ? (utilisé par svn pour commit)
+# publier ? pousser ?? envoyer ??
+# - the series file (mq) ?
+#
+# Notes :
+# - (cédric) je verrais bien l'ajout d'une rubrique générale dans l'aide
+# (par exemple 'hg help glossary') librement remplissable par chaque équipe
+# de traduction, qui introduirait succintement à l'utilisateur les termes
+# qui vont être rencontrés dans mercurial - et en particulier permettrait
+# de faire le lien avec des termes franglisants parfois utilisés
+# (par ex. fusionner = "merger", etc.) ... ?
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial\n"
+"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
+"POT-Creation-Date: 2009-07-18 22:46+0200\n"
+"PO-Revision-Date: 2009-05-14 13:06+0200\n"
+"Last-Translator: Cedric Duval <cedricduval@free.fr>\n"
+"Language-Team: French\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (défaut: %s)"
+
+msgid "OPTIONS"
+msgstr ""
+
+msgid "COMMANDS"
+msgstr ""
+
+msgid " options:\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" aliases: %s\n"
+"\n"
+msgstr ""
+
+msgid ""
+"hooks for controlling repository access\n"
+"\n"
+"This hook makes it possible to allow or deny write access to portions\n"
+"of a repository when receiving incoming changesets.\n"
+"\n"
+"The authorization is matched based on the local user name on the\n"
+"system where the hook runs, and not the committer of the original\n"
+"changeset (since the latter is merely informative).\n"
+"\n"
+"The acl hook is best used along with a restricted shell like hgsh,\n"
+"preventing authenticating users from doing anything other than\n"
+"pushing or pulling. The hook is not safe to use if users have\n"
+"interactive shell access, as they can then disable the hook.\n"
+"Nor is it safe if remote users share an account, because then there\n"
+"is no way to distinguish them.\n"
+"\n"
+"To use this hook, configure the acl extension in your hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.acl =\n"
+"\n"
+" [hooks]\n"
+" pretxnchangegroup.acl = python:hgext.acl.hook\n"
+"\n"
+" [acl]\n"
+" # Check whether the source of incoming changes is in this list\n"
+" # (\"serve\" == ssh or http, \"push\", \"pull\", \"bundle\")\n"
+" sources = serve\n"
+"\n"
+"The allow and deny sections take a subtree pattern as key (with a\n"
+"glob syntax by default), and a comma separated list of users as\n"
+"the corresponding value. The deny list is checked before the allow\n"
+"list is.\n"
+"\n"
+" [acl.allow]\n"
+" # If acl.allow is not present, all users are allowed by default.\n"
+" # An empty acl.allow section means no users allowed.\n"
+" docs/** = doc_writer\n"
+" .hgtags = release_engineer\n"
+"\n"
+" [acl.deny]\n"
+" # If acl.deny is not present, no users are refused by default.\n"
+" # An empty acl.deny section means all users allowed.\n"
+" glob pattern = user4, user5\n"
+" ** = user6\n"
+msgstr ""
+
+#, python-format
+msgid "acl: %s not enabled\n"
+msgstr ""
+
+#, python-format
+msgid "acl: %s enabled, %d entries for user %s\n"
+msgstr ""
+
+#, python-format
+msgid "config error - hook type \"%s\" cannot stop incoming changesets"
+msgstr ""
+
+#, python-format
+msgid "acl: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+#, python-format
+msgid "acl: user %s denied on %s\n"
+msgstr ""
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr ""
+
+#, python-format
+msgid "acl: user %s not allowed on %s\n"
+msgstr ""
+
+#, python-format
+msgid "acl: allowing changeset %s\n"
+msgstr ""
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+"Bookmarks are local movable markers to changesets. Every bookmark\n"
+"points to a changeset identified by its hash. If you commit a\n"
+"changeset that is based on a changeset that has a bookmark on it,\n"
+"the bookmark shifts to the new changeset.\n"
+"\n"
+"It is possible to use bookmark names in every revision lookup\n"
+"(e.g. hg merge, hg update).\n"
+"\n"
+"By default, when several bookmarks point to the same changeset, they\n"
+"will all move forward together. It is possible to obtain a more\n"
+"git-like experience by adding the following configuration option to\n"
+"your .hgrc:\n"
+"\n"
+" [bookmarks]\n"
+" track.current = True\n"
+"\n"
+"This will cause Mercurial to track the bookmark that you are currently\n"
+"using, and only update it. This is similar to git's approach to\n"
+"branching.\n"
+msgstr ""
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+" Bookmarks are pointers to certain commits that move when\n"
+" committing. Bookmarks are local. They can be renamed, copied and\n"
+" deleted. It is possible to use bookmark names in 'hg merge' and\n"
+" 'hg update' to merge and update respectively to a given bookmark.\n"
+"\n"
+" You can use 'hg bookmark NAME' to set a bookmark on the working\n"
+" directory's parent revision with the given name. If you specify\n"
+" a revision using -r REV (where REV may be an existing bookmark),\n"
+" the bookmark is assigned to that revision.\n"
+" "
+msgstr ""
+
+msgid "a bookmark of this name does not exist"
+msgstr ""
+
+msgid "a bookmark of the same name already exists"
+msgstr ""
+
+msgid "new bookmark name required"
+msgstr ""
+
+msgid "bookmark name required"
+msgstr ""
+
+msgid "bookmark name cannot contain newlines"
+msgstr ""
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr ""
+
+msgid "force"
+msgstr ""
+
+msgid "revision"
+msgstr ""
+
+msgid "delete a given bookmark"
+msgstr ""
+
+msgid "rename a given bookmark"
+msgstr ""
+
+msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
+msgstr ""
+
+msgid ""
+"hooks for integrating with the Bugzilla bug tracker\n"
+"\n"
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
+"bug status.\n"
+"\n"
+"The hook updates the Bugzilla database directly. Only Bugzilla\n"
+"installations using MySQL are supported.\n"
+"\n"
+"The hook relies on a Bugzilla script to send bug change notification\n"
+"emails. That script changes between Bugzilla versions; the\n"
+"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
+"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
+"be run by Mercurial as the user pushing the change; you will need to\n"
+"ensure the Bugzilla install file permissions are set appropriately.\n"
+"\n"
+"Configuring the extension:\n"
+"\n"
+" [bugzilla]\n"
+"\n"
+" host Hostname of the MySQL server holding the Bugzilla\n"
+" database.\n"
+" db Name of the Bugzilla database in MySQL. Default 'bugs'.\n"
+" user Username to use to access MySQL server. Default 'bugs'.\n"
+" password Password to use to access MySQL server.\n"
+" timeout Database connection timeout (seconds). Default 5.\n"
+" version Bugzilla version. Specify '3.0' for Bugzilla versions\n"
+" 3.0 and later, '2.18' for Bugzilla versions from 2.18\n"
+" and '2.16' for versions prior to 2.18.\n"
+" bzuser Fallback Bugzilla user name to record comments with, if\n"
+" changeset committer cannot be found as a Bugzilla user.\n"
+" bzdir Bugzilla install directory. Used by default notify.\n"
+" Default '/var/www/html/bugzilla'.\n"
+" notify The command to run to get Bugzilla to send bug change\n"
+" notification emails. Substitutes from a map with 3\n"
+" keys, 'bzdir', 'id' (bug id) and 'user' (committer\n"
+" bugzilla email). Default depends on version; from 2.18\n"
+" it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
+" %(id)s %(user)s\".\n"
+" regexp Regular expression to match bug IDs in changeset commit\n"
+" message. Must contain one \"()\" group. The default\n"
+" expression matches 'Bug 1234', 'Bug no. 1234', 'Bug\n"
+" number 1234', 'Bugs 1234,5678', 'Bug 1234 and 5678' and\n"
+" variations thereof. Matching is case insensitive.\n"
+" style The style file to use when formatting comments.\n"
+" template Template to use when formatting comments. Overrides\n"
+" style if specified. In addition to the usual Mercurial\n"
+" keywords, the extension specifies:\n"
+" {bug} The Bugzilla bug ID.\n"
+" {root} The full pathname of the Mercurial\n"
+" repository.\n"
+" {webroot} Stripped pathname of the Mercurial\n"
+" repository.\n"
+" {hgweb} Base URL for browsing Mercurial\n"
+" repositories.\n"
+" Default 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip The number of slashes to strip from the front of {root}\n"
+" to produce {webroot}. Default 0.\n"
+" usermap Path of file containing Mercurial committer ID to\n"
+" Bugzilla user ID mappings. If specified, the file\n"
+" should contain one mapping per line,\n"
+" \"committer\"=\"Bugzilla user\". See also the [usermap]\n"
+" section.\n"
+"\n"
+" [usermap]\n"
+" Any entries in this section specify mappings of Mercurial\n"
+" committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl Base URL for browsing Mercurial repositories. Reference\n"
+" from templates as {hgweb}.\n"
+"\n"
+"Activating the extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # run bugzilla hook on every change pulled or pushed in here\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Example configuration:\n"
+"\n"
+"This example configuration is for a collection of Mercurial\n"
+"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
+"installation in /opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Commits add a comment to the Bugzilla bug record of the form:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr ""
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr ""
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr ""
+
+msgid "unknown database schema"
+msgstr ""
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr ""
+
+msgid "telling bugzilla to send mail:\n"
+msgstr ""
+
+#, python-format
+msgid " bug %s\n"
+msgstr ""
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr ""
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr ""
+
+msgid "done\n"
+msgstr "effectué\n"
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr ""
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr ""
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr ""
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr ""
+
+#, python-format
+msgid "database error: %s"
+msgstr ""
+
+msgid "command to display child changesets"
+msgstr ""
+
+msgid ""
+"show the children of the given or working directory revision\n"
+"\n"
+" Print the children of the working directory's revisions. If a\n"
+" revision is given via -r/--rev, the children of that revision will\n"
+" be printed. If a file argument is given, revision in which the\n"
+" file was last changed (after the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+
+msgid "show children of the specified revision"
+msgstr ""
+
+msgid "hg children [-r REV] [FILE]"
+msgstr ""
+
+msgid "command to display statistics about repository history"
+msgstr ""
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr ""
+
+#, python-format
+msgid "generating stats: %d%%"
+msgstr ""
+
+msgid ""
+"histogram of changes to the repository\n"
+"\n"
+" This command will display a histogram representing the number\n"
+" of changed lines or revisions, grouped according to the given\n"
+" template. The default template will group changes by author.\n"
+" The --dateformat option may be used to group the results by\n"
+" date instead.\n"
+"\n"
+" Statistics are based on the number of changed lines, or\n"
+" alternatively the number of matching revisions if the\n"
+" --changesets option is specified.\n"
+"\n"
+" Examples:\n"
+"\n"
+" # display count of changed lines for every committer\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # display daily activity graph\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # display activity of developers by month\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # display count of lines changed in every year\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" It is possible to map alternate email addresses to a main address\n"
+" by providing a file using the following format:\n"
+"\n"
+" <alias email> <actual email>\n"
+"\n"
+" Such a file may be specified with the --aliases option, otherwise a\n"
+" .hgchurn file will be looked for in the working directory root.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "assuming %i character terminal\n"
+msgstr ""
+
+msgid "count rate for the specified revision or range"
+msgstr ""
+
+msgid "count rate for revisions matching date spec"
+msgstr ""
+
+msgid "template to group changesets"
+msgstr ""
+
+msgid "strftime-compatible format for grouping by date"
+msgstr ""
+
+msgid "count rate by number of changesets"
+msgstr ""
+
+msgid "sort by key (default: sort by count)"
+msgstr ""
+
+msgid "file with email aliases"
+msgstr ""
+
+msgid "show progress"
+msgstr ""
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+msgstr ""
+
+msgid ""
+"colorize output from some commands\n"
+"\n"
+"This extension modifies the status command to add color to its output\n"
+"to reflect file status, the qseries command to add color to reflect\n"
+"patch status (applied, unapplied, missing), and to diff-related\n"
+"commands to highlight additions, removals, diff headers, and trailing\n"
+"whitespace.\n"
+"\n"
+"Other effects in addition to color, like bold and underlined text, are\n"
+"also available. Effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes). This module also provides the\n"
+"render_text function, which can be used to add effects to any text.\n"
+"\n"
+"Default effects may be overridden from the .hgrc file:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' turns off all effects\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+msgstr ""
+
+msgid "when to colorize (always, auto, or never)"
+msgstr ""
+
+msgid "don't colorize output"
+msgstr ""
+
+#, python-format
+msgid "ignoring unknown color/effect %r (configured in color.%s)\n"
+msgstr ""
+
+msgid "import revisions from foreign VCS repositories into Mercurial"
+msgstr ""
+
+msgid ""
+"convert a foreign SCM repository to a Mercurial one.\n"
+"\n"
+" Accepted source formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Accepted destination formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (history on branches is not preserved)\n"
+"\n"
+" If no revision is given, all revisions will be converted.\n"
+" Otherwise, convert will only import up to the named revision\n"
+" (given in a format understood by the source).\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source with '-hg' appended. If the destination\n"
+" repository doesn't exist, it will be created.\n"
+"\n"
+" By default, all sources except Mercurial will use\n"
+" --branchsort. Mercurial uses --sourcesort to preserve original\n"
+" revision numbers order. Sort modes have the following effects:\n"
+" --branchsort: convert from parent to child revision when\n"
+" possible, which means branches are usually converted one after\n"
+" the other. It generates more compact repositories.\n"
+" --datesort: sort revisions by date. Converted repositories have\n"
+" good-looking changelogs but are often an order of magnitude\n"
+" larger than the same ones generated by --branchsort.\n"
+" --sourcesort: try to preserve source revisions order, only\n"
+" supported by Mercurial sources.\n"
+"\n"
+" If <REVMAP> isn't given, it will be put in a default location\n"
+" (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file\n"
+" that maps each source commit ID to the destination ID for that\n"
+" revision, like so:\n"
+" <source ID> <destination ID>\n"
+"\n"
+" If the file doesn't exist, it's automatically created. It's\n"
+" updated on each commit copied, so convert-repo can be interrupted\n"
+" and can be run repeatedly to copy new commits.\n"
+"\n"
+" The [username mapping] file is a simple text file that maps each\n"
+" source commit author to a destination commit author. It is handy\n"
+" for source SCMs that use unix logins to identify authors (eg:\n"
+" CVS). One line per author mapping and the line format is:\n"
+" srcauthor=whatever string you want\n"
+"\n"
+" The filemap is a file that allows filtering and remapping of files\n"
+" and directories. Comment lines start with '#'. Each line can\n"
+" contain one of the following directives:\n"
+"\n"
+" include path/to/file\n"
+"\n"
+" exclude path/to/file\n"
+"\n"
+" rename from/file to/file\n"
+"\n"
+" The 'include' directive causes a file, or all files under a\n"
+" directory, to be included in the destination repository, and the\n"
+" exclusion of all other files and directories not explicitly included.\n"
+" The 'exclude' directive causes files or directories to be omitted.\n"
+" The 'rename' directive renames a file or directory. To rename from\n"
+" a subdirectory into the root of the repository, use '.' as the\n"
+" path to rename to.\n"
+"\n"
+" The splicemap is a file that allows insertion of synthetic\n"
+" history, letting you specify the parents of a revision. This is\n"
+" useful if you want to e.g. give a Subversion merge two parents, or\n"
+" graft two disconnected series of history together. Each entry\n"
+" contains a key, followed by a space, followed by one or two\n"
+" comma-separated values. The key is the revision ID in the source\n"
+" revision control system whose parents should be modified (same\n"
+" format as a key in .hg/shamap). The values are the revision IDs\n"
+" (in either the source or destination revision control system) that\n"
+" should be used as the new parents for that node.\n"
+"\n"
+" The branchmap is a file that allows you to rename a branch when it is\n"
+" being brought in from whatever external repository. When used in\n"
+" conjunction with a splicemap, it allows for a powerful combination\n"
+" to help fix even the most badly mismanaged repositories and turn them\n"
+" into nicely structured Mercurial repositories. The branchmap contains\n"
+" lines of the form \"original_branch_name new_branch_name\".\n"
+" \"original_branch_name\" is the name of the branch in the source\n"
+" repository, and \"new_branch_name\" is the name of the branch is the\n"
+" destination repository. This can be used to (for instance) move code\n"
+" in one repository from \"default\" to a named branch.\n"
+"\n"
+" Mercurial Source\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (boolean)\n"
+" ignore integrity errors when reading. Use it to fix Mercurial\n"
+" repositories with missing revlogs, by converting from and to\n"
+" Mercurial.\n"
+" --config convert.hg.saverev=False (boolean)\n"
+" store original revision ID in changeset (forces target IDs to\n"
+" change)\n"
+" --config convert.hg.startrev=0 (hg revision identifier)\n"
+" convert start revision and its descendants\n"
+"\n"
+" CVS Source\n"
+" ----------\n"
+"\n"
+" CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+" to indicate the starting point of what will be converted. Direct\n"
+" access to the repository files is not needed, unless of course the\n"
+" repository is :local:. The conversion uses the top level directory\n"
+" in the sandbox to find the CVS repository, and then uses CVS rlog\n"
+" commands to find files to convert. This means that unless a\n"
+" filemap is given, all files under the starting directory will be\n"
+" converted, and that any directory reorganization in the CVS\n"
+" sandbox is ignored.\n"
+"\n"
+" Because CVS does not have changesets, it is necessary to collect\n"
+" individual commits to CVS and merge them into changesets. CVS\n"
+" source uses its internal changeset merging code by default but can\n"
+" be configured to call the external 'cvsps' program by setting:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" This option is deprecated and will be removed in Mercurial 1.4.\n"
+"\n"
+" The options shown are the defaults.\n"
+"\n"
+" Internal cvsps is selected by setting\n"
+" --config convert.cvsps=builtin\n"
+" and has a few more configurable options:\n"
+" --config convert.cvsps.cache=True (boolean)\n"
+" Set to False to disable remote log caching, for testing and\n"
+" debugging purposes.\n"
+" --config convert.cvsps.fuzz=60 (integer)\n"
+" Specify the maximum time (in seconds) that is allowed\n"
+" between commits with identical user and log message in a\n"
+" single changeset. When very large files were checked in as\n"
+" part of a changeset then the default may not be long\n"
+" enough.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will insert a dummy revision merging the branch on\n"
+" which this log message occurs to the branch indicated in\n"
+" the regex.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will add the most recent revision on the branch\n"
+" indicated in the regex as the second parent of the\n"
+" changeset.\n"
+"\n"
+" The hgext/convert/cvsps wrapper script allows the builtin\n"
+" changeset merging code to be run without doing a conversion. Its\n"
+" parameters and output are similar to that of cvsps 2.1.\n"
+"\n"
+" Subversion Source\n"
+" -----------------\n"
+"\n"
+" Subversion source detects classical trunk/branches/tags layouts.\n"
+" By default, the supplied \"svn://repo/path/\" source URL is\n"
+" converted as a single branch. If \"svn://repo/path/trunk\" exists it\n"
+" replaces the default branch. If \"svn://repo/path/branches\" exists,\n"
+" its subdirectories are listed as possible branches. If\n"
+" \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
+" converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
+" can be overridden with following options. Set them to paths\n"
+" relative to the source URL, or leave them blank to disable auto\n"
+" detection.\n"
+"\n"
+" --config convert.svn.branches=branches (directory name)\n"
+" specify the directory containing branches\n"
+" --config convert.svn.tags=tags (directory name)\n"
+" specify the directory containing tags\n"
+" --config convert.svn.trunk=trunk (directory name)\n"
+" specify the name of the trunk branch\n"
+"\n"
+" Source history can be retrieved starting at a specific revision,\n"
+" instead of being integrally converted. Only single branch\n"
+" conversions are supported.\n"
+"\n"
+" --config convert.svn.startrev=0 (svn revision number)\n"
+" specify start Subversion revision.\n"
+"\n"
+" Perforce Source\n"
+" ---------------\n"
+"\n"
+" The Perforce (P4) importer can be given a p4 depot path or a\n"
+" client specification as source. It will convert all files in the\n"
+" source to a flat Mercurial repository, ignoring labels, branches\n"
+" and integrations. Note that when a depot path is given you then\n"
+" usually should specify a target directory, because otherwise the\n"
+" target may be named ...-hg.\n"
+"\n"
+" It is possible to limit the amount of source history to be\n"
+" converted by specifying an initial Perforce revision.\n"
+"\n"
+" --config convert.p4.startrev=0 (perforce changelist number)\n"
+" specify initial Perforce revision.\n"
+"\n"
+"\n"
+" Mercurial Destination\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (boolean)\n"
+" dispatch source branches in separate clones.\n"
+" --config convert.hg.tagsbranch=default (branch name)\n"
+" tag revisions branch name\n"
+" --config convert.hg.usebranchnames=True (boolean)\n"
+" preserve branch names\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"create changeset information from CVS\n"
+"\n"
+" This command is intended as a debugging tool for the CVS to\n"
+" Mercurial converter, and can be used as a direct replacement for\n"
+" cvsps.\n"
+"\n"
+" Hg debugcvsps reads the CVS rlog for current directory (or any\n"
+" named directory) in the CVS repository, and converts the log to a\n"
+" series of changesets based on matching commit log entries and\n"
+" dates."
+msgstr ""
+
+msgid "username mapping filename"
+msgstr ""
+
+msgid "destination repository type"
+msgstr ""
+
+msgid "remap file names using contents of file"
+msgstr ""
+
+msgid "import up to target revision REV"
+msgstr ""
+
+msgid "source repository type"
+msgstr ""
+
+msgid "splice synthesized history into place"
+msgstr ""
+
+msgid "change branch names while converting"
+msgstr ""
+
+msgid "try to sort changesets by branches"
+msgstr ""
+
+msgid "try to sort changesets by date"
+msgstr ""
+
+msgid "preserve source changesets order"
+msgstr ""
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr ""
+
+msgid "only return changes on specified branches"
+msgstr ""
+
+msgid "prefix to remove from file names"
+msgstr ""
+
+msgid "only return changes after or between specified tags"
+msgstr ""
+
+msgid "update cvs log cache"
+msgstr ""
+
+msgid "create new cvs log cache"
+msgstr ""
+
+msgid "set commit time fuzz in seconds"
+msgstr ""
+
+msgid "specify cvsroot"
+msgstr ""
+
+msgid "show parent changesets"
+msgstr ""
+
+msgid "show current changeset in ancestor branches"
+msgstr ""
+
+msgid "ignored for compatibility"
+msgstr ""
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr ""
+
+msgid ""
+"warning: lightweight checkouts may cause conversion failures, try with a "
+"regular branch instead.\n"
+msgstr ""
+
+msgid "bzr source type could not be determined\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr ""
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr ""
+
+#, python-format
+msgid "%s.%s symlink has no target"
+msgstr ""
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr ""
+
+#, python-format
+msgid "running: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s error:\n"
+msgstr ""
+
+#, python-format
+msgid "syntax error in %s(%d): key/value pair expected"
+msgstr ""
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr ""
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr ""
+
+#, python-format
+msgid "convert: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr ""
+
+#, python-format
+msgid "unknown sort mode: %s"
+msgstr ""
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr ""
+
+msgid "not all revisions were sorted"
+msgstr ""
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "overriding mapping for author %s, was %s, will be %s\n"
+msgstr ""
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr ""
+
+msgid "scanning source...\n"
+msgstr ""
+
+msgid "sorting...\n"
+msgstr ""
+
+msgid "converting...\n"
+msgstr ""
+
+#, python-format
+msgid "source: %s\n"
+msgstr ""
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr ""
+
+msgid "more than one sort mode specified"
+msgstr ""
+
+msgid "--sourcesort is not supported by this data source"
+msgstr ""
+
+msgid ""
+"warning: support for external cvsps is deprecated and will be removed in "
+"Mercurial 1.4\n"
+msgstr ""
+
+#, python-format
+msgid "revision %s is not a patchset number or date"
+msgstr ""
+
+msgid "using builtin cvsps\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr ""
+
+msgid "CVS pserver authentication failed"
+msgstr ""
+
+#, python-format
+msgid ""
+"unexpected response from CVS server (expected \"Valid-requests\", but got %r)"
+msgstr ""
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr ""
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr ""
+
+msgid "collecting CVS rlog\n"
+msgstr ""
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr ""
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr ""
+
+#, python-format
+msgid "running %s\n"
+msgstr ""
+
+#, python-format
+msgid "prefix=%r directory=%r root=%r\n"
+msgstr ""
+
+msgid "RCS file must be followed by working file"
+msgstr ""
+
+msgid "must have at least some revisions"
+msgstr ""
+
+msgid "expected revision number"
+msgstr ""
+
+msgid "revision must be followed by date line"
+msgstr ""
+
+#, python-format
+msgid "found synthetic revision in %s: %r\n"
+msgstr ""
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "%d log entries\n"
+msgstr ""
+
+msgid "creating changesets\n"
+msgstr ""
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: CVS commit message references non-existent branch %r:\n"
+"%s\n"
+msgstr ""
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr ""
+
+msgid "Python ElementTree module is not available"
+msgstr ""
+
+#, python-format
+msgid "cleaning up %s\n"
+msgstr ""
+
+msgid "internal calling inconsistency"
+msgstr ""
+
+msgid "errors in filemap"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr ""
+
+msgid "source repository doesn't support --filemap"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a GNU Arch repo"
+msgstr ""
+
+msgid "cannot find a GNU Arch tool"
+msgstr ""
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr ""
+
+#, python-format
+msgid "applying revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "computing changeset between %s and %s...\n"
+msgstr ""
+
+#, python-format
+msgid "obtaining revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "analyzing revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr ""
+
+#, python-format
+msgid "%s is not a local Mercurial repo"
+msgstr ""
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr ""
+
+msgid "run hg sink pre-conversion action\n"
+msgstr ""
+
+msgid "run hg sink post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr ""
+
+msgid "filtering out empty revision\n"
+msgstr ""
+
+msgid "updating tags\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr ""
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr ""
+
+msgid "run hg source pre-conversion action\n"
+msgstr ""
+
+msgid "run hg source post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a monotone repo"
+msgstr ""
+
+#, python-format
+msgid "copying file in renamed directory from '%s' to '%s'"
+msgstr ""
+
+msgid "reading p4 views\n"
+msgstr ""
+
+msgid "collecting p4 changelists\n"
+msgstr ""
+
+msgid "Subversion python bindings could not be loaded"
+msgstr ""
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr ""
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr ""
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr ""
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr ""
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr ""
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr ""
+
+msgid "svn: start revision is not supported with more than one branch"
+msgstr ""
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr ""
+
+#, python-format
+msgid "no tags found at revision %d\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring foreign branch %r\n"
+msgstr ""
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr ""
+
+#, python-format
+msgid "branch renamed from %s to %s at %d\n"
+msgstr ""
+
+#, python-format
+msgid "reparent to %s\n"
+msgstr ""
+
+#, python-format
+msgid "copied to %s from %s@%s\n"
+msgstr ""
+
+#, python-format
+msgid "gone from %s\n"
+msgstr ""
+
+#, python-format
+msgid "entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown path in revision %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mark %s came from %s:%d\n"
+msgstr ""
+
+#, python-format
+msgid "parsing revision %d (%d changes)\n"
+msgstr ""
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr ""
+
+msgid "no copyfrom path, don't know what to do.\n"
+msgstr ""
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d has no entries\n"
+msgstr ""
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr ""
+
+#, python-format
+msgid "%r is not under %r, ignoring\n"
+msgstr ""
+
+#, python-format
+msgid "initializing svn repo %r\n"
+msgstr ""
+
+#, python-format
+msgid "initializing svn wc %r\n"
+msgstr ""
+
+msgid "unexpected svn output:\n"
+msgstr ""
+
+msgid "unable to cope with svn output"
+msgstr ""
+
+msgid "XXX TAGS NOT IMPLEMENTED YET\n"
+msgstr ""
+
+msgid ""
+"command to allow external programs to compare revisions\n"
+"\n"
+"The `extdiff' Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working directory. The external diff\n"
+"programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare.\n"
+"\n"
+"The `extdiff' extension also allows to configure new diff commands, so\n"
+"you do not need to type \"hg extdiff -p kdiff3\" always.\n"
+"\n"
+" [extdiff]\n"
+" # add new command that runs GNU diff(1) in 'context diff' mode\n"
+" cdiff = gdiff -Nprc5\n"
+" ## or the old way:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # add new command called vdiff, runs kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # add new command called meld, runs meld (no need to name twice)\n"
+" meld =\n"
+"\n"
+" # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+" # (see http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Non English user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" "
+"in\n"
+" # your .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"You can use -I/-X and list of file or directory names like normal \"hg\n"
+"diff\" command. The `extdiff' extension makes snapshots of only needed\n"
+"files, so running the external diff program will actually be pretty\n"
+"fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from working directory\n"
+msgstr ""
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr ""
+
+#, python-format
+msgid "running %r in %s\n"
+msgstr ""
+
+#, python-format
+msgid "file changed while diffing. Overwriting: %s (src: %s)\n"
+msgstr ""
+
+msgid "cleaning up temp directory\n"
+msgstr ""
+
+msgid ""
+"use external program to diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files, using\n"
+" an external program. The default program used is diff, with\n"
+" default options \"-Npru\".\n"
+"\n"
+" To select a different program, use the -p/--program option. The\n"
+" program will be passed the names of two directories to compare. To\n"
+" pass additional options to the program, use -o/--option. These\n"
+" will be passed before the names of the directories to compare.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent."
+msgstr ""
+
+msgid "comparison program to run"
+msgstr ""
+
+msgid "pass option to comparison program"
+msgstr ""
+
+msgid "change made by revision"
+msgstr ""
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr ""
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "pull, update and merge in one command"
+msgstr ""
+
+msgid ""
+"pull changes from a remote repository, merge new changes if needed.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository.\n"
+"\n"
+" If the pulled changes add a new branch head, the head is\n"
+" automatically merged, and the result of the merge is committed.\n"
+" Otherwise, the working directory is updated to include the new\n"
+" changes.\n"
+"\n"
+" When a merge occurs, the newly pulled changes are assumed to be\n"
+" \"authoritative\". The head of the new changes is used as the first\n"
+" parent, with local changes as the second. To switch the merge\n"
+" order, use --switch-parent.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid ""
+"working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+
+msgid "outstanding uncommitted merge"
+msgstr ""
+
+msgid "outstanding uncommitted changes"
+msgstr ""
+
+msgid "working directory is missing some files"
+msgstr ""
+
+msgid ""
+"multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr ""
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "Automated merge with %s"
+msgstr ""
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr ""
+
+msgid "a specific revision you would like to pull"
+msgstr ""
+
+msgid "edit commit message"
+msgstr ""
+
+msgid "edit commit message (DEPRECATED)"
+msgstr ""
+
+msgid "switch parents when merging"
+msgstr ""
+
+msgid "hg fetch [SOURCE]"
+msgstr ""
+
+msgid "commands to sign and verify changesets"
+msgstr ""
+
+msgid "error while verifying signature"
+msgstr ""
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr ""
+
+msgid "list signed changesets"
+msgstr ""
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr ""
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr ""
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr ""
+
+msgid ""
+"add a signature for the current or given revision\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr ""
+
+msgid "Error while signing"
+msgstr ""
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+
+#, python-format
+msgid "Added signature for changeset %s"
+msgstr ""
+
+msgid "unknown signature version"
+msgstr ""
+
+msgid "make the signature local"
+msgstr ""
+
+msgid "sign even if the sigfile is modified"
+msgstr ""
+
+msgid "do not commit the sigfile after signing"
+msgstr ""
+
+msgid "the key id to sign with"
+msgstr ""
+
+msgid "commit message"
+msgstr ""
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr ""
+
+msgid "hg sigcheck REVISION"
+msgstr ""
+
+msgid "hg sigs"
+msgstr ""
+
+msgid ""
+"command to view revision graphs from a shell\n"
+"\n"
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ASCII representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+
+#, python-format
+msgid "--graph option is incompatible with --%s"
+msgstr ""
+
+msgid ""
+"show revision history alongside an ASCII revision graph\n"
+"\n"
+" Print a revision history alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr "comparaison avec %s\n"
+
+msgid "no changes found\n"
+msgstr "aucun changement trouvé\n"
+
+msgid "show the revision DAG"
+msgstr ""
+
+msgid "limit number of changes displayed"
+msgstr ""
+
+msgid "show patch"
+msgstr ""
+
+msgid "show the specified revision or range"
+msgstr ""
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr ""
+
+msgid ""
+"hooks for integrating with the CIA.vc notification service\n"
+"\n"
+"This is meant to be run as a changegroup or incoming hook.\n"
+"To configure it, set the following options in your hgrc:\n"
+"\n"
+"[cia]\n"
+"# your registered CIA user name\n"
+"user = foo\n"
+"# the name of the project in CIA\n"
+"project = foo\n"
+"# the module (subproject) (optional)\n"
+"#module = foo\n"
+"# Append a diffstat to the log message (optional)\n"
+"#diffstat = False\n"
+"# Template to use for log messages (optional)\n"
+"#template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"# Style to use (optional)\n"
+"#style = foo\n"
+"# The URL of the CIA notification service (optional)\n"
+"# You can use mailto: URLs to send by email, eg\n"
+"# mailto:cia@cia.vc\n"
+"# Make sure to set email.from if you do this.\n"
+"#url = http://cia.vc/\n"
+"# print message instead of sending it (optional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# one of these:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# If you want hyperlinks (optional)\n"
+"baseurl = http://server/path/to/repo\n"
+msgstr ""
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr ""
+
+msgid "email.from must be defined when sending by email"
+msgstr ""
+
+msgid "cia: no user specified"
+msgstr ""
+
+msgid "cia: no project specified"
+msgstr ""
+
+msgid ""
+"browse the repository in a graphical way\n"
+"\n"
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not\n"
+"distributed with Mercurial.)\n"
+"\n"
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to Mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and the extension is shipped in the hgext\n"
+"repository, and needs to be enabled.\n"
+"\n"
+"The hg view command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can specify\n"
+"the path to hgk in your .hgrc file:\n"
+"\n"
+" [hgk]\n"
+" path=/location/of/hgk\n"
+"\n"
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions."
+msgstr ""
+
+msgid "diff trees from two commits"
+msgstr ""
+
+msgid "output common ancestor information"
+msgstr ""
+
+msgid "cat a specific revision"
+msgstr ""
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr ""
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr ""
+
+msgid "parse given revisions"
+msgstr ""
+
+msgid "print revisions"
+msgstr ""
+
+msgid "print extension options"
+msgstr ""
+
+msgid "start interactive history viewer"
+msgstr ""
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr ""
+
+msgid "generate patch"
+msgstr ""
+
+msgid "recursive"
+msgstr ""
+
+msgid "pretty"
+msgstr ""
+
+msgid "stdin"
+msgstr ""
+
+msgid "detect copies"
+msgstr ""
+
+msgid "search"
+msgstr ""
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr ""
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr ""
+
+msgid "hg debug-config"
+msgstr ""
+
+msgid "hg debug-merge-base REV REV"
+msgstr ""
+
+msgid "ignored"
+msgstr ""
+
+msgid "hg debug-rev-parse REV"
+msgstr ""
+
+msgid "header"
+msgstr ""
+
+msgid "topo-order"
+msgstr ""
+
+msgid "parents"
+msgstr ""
+
+msgid "max-count"
+msgstr ""
+
+msgid "hg debug-rev-list [OPTION]... REV..."
+msgstr "hg debug-rev-list [OPTION]... REV..."
+
+msgid ""
+"syntax highlighting for hgweb (requires Pygments)\n"
+"\n"
+"It depends on the Pygments syntax highlighting library:\n"
+"http://pygments.org/\n"
+"\n"
+"There is a single configuration option:\n"
+"\n"
+"[web]\n"
+"pygments_style = <style>\n"
+"\n"
+"The default is 'colorful'.\n"
+msgstr ""
+
+msgid "accelerate status report using Linux's inotify service"
+msgstr ""
+
+msgid "start an inotify server for this repository"
+msgstr ""
+
+msgid ""
+"debugging information for inotify extension\n"
+"\n"
+" Prints the list of directories being watched by the inotify server.\n"
+" "
+msgstr ""
+
+msgid "directories being watched:\n"
+msgstr ""
+
+msgid "run server in background"
+msgstr ""
+
+msgid "used internally by daemon mode"
+msgstr ""
+
+msgid "minutes to sit idle before exiting"
+msgstr ""
+
+msgid "name of file to write process ID to"
+msgstr ""
+
+msgid "hg inserve [OPTION]..."
+msgstr "hg inserve [OPTION]..."
+
+msgid "(found dead inotify server socket; removing it)\n"
+msgstr ""
+
+msgid "(starting inotify server)\n"
+msgstr ""
+
+#, python-format
+msgid "could not start inotify server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "could not talk to new inotify server: %s\n"
+msgstr ""
+
+msgid "(inotify server not running)\n"
+msgstr ""
+
+#, python-format
+msgid "failed to contact inotify server: %s\n"
+msgstr ""
+
+msgid "received empty answer from inotify server"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received '%s' response when expecting '%s')\n"
+msgstr ""
+
+msgid "this system does not seem to support inotify"
+msgstr ""
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr ""
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr ""
+
+msgid "*** counting directories: "
+msgstr ""
+
+#, python-format
+msgid "found %d\n"
+msgstr ""
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr ""
+
+#, python-format
+msgid "*** echo %d > %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr ""
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr ""
+
+#, python-format
+msgid "watching %r\n"
+msgstr ""
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r dir(%d) -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s dirstate reload\n"
+msgstr ""
+
+#, python-format
+msgid "%s end dirstate reload\n"
+msgstr ""
+
+msgid "rescanning due to .hgignore change\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr ""
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr ""
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr ""
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr ""
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr ""
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr ""
+
+#, python-format
+msgid "could not start server: %s"
+msgstr ""
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr ""
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr ""
+
+#, python-format
+msgid "unrecognized query type: %s\n"
+msgstr ""
+
+msgid "finished setup\n"
+msgstr ""
+
+msgid ""
+"expand expressions into changelog and summaries\n"
+"\n"
+"This extension allows the use of a special syntax in summaries,\n"
+"which will be automatically expanded into links or any other\n"
+"arbitrary expression, much like InterWiki does.\n"
+"\n"
+"A few example patterns (link to bug tracking, etc.) that may\n"
+"be used in your hgrc:\n"
+"\n"
+" [interhg]\n"
+" issues = s!issue(\\d+)!<a href=\"http://bts/issue\\1\">issue\\1</a>!\n"
+" bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2\">\\1</a>!"
+"i\n"
+" boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr ""
+
+msgid ""
+"expand keywords in tracked files\n"
+"\n"
+"This extension expands RCS/CVS-like or self-customized $Keywords$ in\n"
+"tracked text files selected by your configuration.\n"
+"\n"
+"Keywords are only expanded in local repositories and not stored in the\n"
+"change history. The mechanism can be regarded as a convenience for the\n"
+"current user or for archive distribution.\n"
+"\n"
+"Configuration is done in the [keyword] and [keywordmaps] sections of\n"
+"hgrc files.\n"
+"\n"
+"Example:\n"
+"\n"
+" [keyword]\n"
+" # expand keywords in every python file except those matching \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Note: the more specific you are in your filename patterns\n"
+" the less you lose speed in huge repositories.\n"
+"\n"
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run \"hg kwdemo\".\n"
+"\n"
+"An additional date template filter {date|utcdate} is provided.\n"
+"\n"
+"The default template mappings (view with \"hg kwdemo -d\") can be\n"
+"replaced with customized keywords and templates. Again, run \"hg\n"
+"kwdemo\" to control the results of your config changes.\n"
+"\n"
+"Before changing/disabling active keywords, run \"hg kwshrink\" to avoid\n"
+"the risk of inadvertently storing expanded keywords in the change\n"
+"history.\n"
+"\n"
+"To force expansion after enabling it, or a configuration change, run\n"
+"\"hg kwexpand\".\n"
+"\n"
+"Also, when committing with the record extension or using mq's qrecord,\n"
+"be aware that keywords cannot be updated. Again, run \"hg kwexpand\" on\n"
+"the files in question to update keyword expansions after all changes\n"
+"have been checked in.\n"
+"\n"
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map\n"
+"\"Log = {desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s expanding keywords\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s shrinking keywords\n"
+msgstr ""
+
+msgid "[keyword] patterns cannot match"
+msgstr ""
+
+msgid "no [keyword] patterns configured"
+msgstr ""
+
+msgid ""
+"print [keywordmaps] configuration and an expansion example\n"
+"\n"
+" Show current, custom, or default keyword template maps and their\n"
+" expansions.\n"
+"\n"
+" Extend current configuration by specifying maps as arguments and\n"
+" optionally by reading from an additional hgrc file.\n"
+"\n"
+" Override current keyword template maps with \"default\" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "creating temporary repository at %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"\tconfig using %s keyword template maps\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"%s keywords written to %s:\n"
+msgstr ""
+
+msgid "unhooked all commit hooks\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"\t%s keywords expanded%s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"removing temporary repository %s\n"
+msgstr ""
+
+msgid ""
+"expand keywords in the working directory\n"
+"\n"
+" Run after (re)enabling keyword expansion.\n"
+"\n"
+" kwexpand refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid ""
+"show files configured for keyword expansion\n"
+"\n"
+" List which files in the working directory are matched by the\n"
+" [keyword] configuration patterns.\n"
+"\n"
+" Useful to prevent inadvertent keyword expansion and to speed up\n"
+" execution by including only files that are actual candidates\n"
+" for expansion.\n"
+"\n"
+" See \"hg help keyword\" on how to construct patterns both for\n"
+" inclusion and exclusion of files.\n"
+"\n"
+" Use -u/--untracked to list untracked files as well.\n"
+"\n"
+" With -a/--all and -v/--verbose the codes used to show the status\n"
+" of files are:\n"
+" K = keyword expansion candidate\n"
+" k = keyword expansion candidate (untracked)\n"
+" I = ignored\n"
+" i = ignored (untracked)\n"
+" "
+msgstr ""
+
+msgid ""
+"revert expanded keywords in the working directory\n"
+"\n"
+" Run before changing/disabling active keywords or if you experience\n"
+" problems with \"hg import\" or \"hg merge\".\n"
+"\n"
+" kwshrink refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid "show default keyword template maps"
+msgstr ""
+
+msgid "read maps from rcfile"
+msgstr ""
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr ""
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "show keyword status flags of all files"
+msgstr ""
+
+msgid "show files excluded from expansion"
+msgstr ""
+
+msgid "additionally show untracked files"
+msgstr ""
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr ""
+
+msgid ""
+"manage a stack of patches\n"
+"\n"
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches).\n"
+"\n"
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets.\n"
+"\n"
+"Common tasks (use \"hg help command\" for more details):\n"
+"\n"
+"prepare repository to work with patches qinit\n"
+"create new patch qnew\n"
+"import existing patch qimport\n"
+"\n"
+"print patch series qseries\n"
+"print applied patches qapplied\n"
+"print name of top applied patch qtop\n"
+"\n"
+"add known patch to applied stack qpush\n"
+"remove patch from applied stack qpop\n"
+"refresh contents of top applied patch qrefresh\n"
+msgstr ""
+"gestion et utilisation d'une pile de patchs\n"
+"\n"
+"Cette extension permet de travailler avec une pile de patchs au\n"
+"dessus d'un dépôt Mercurial. Deux piles de patchs sont gérées :\n"
+"l'ensemble des patchs référencés, et le sous-ensemble des patchs\n"
+"qui ont été appliqués.\n"
+"\n"
+"Les patchs référencés sont stockés en tant que fichiers au format\n"
+"patch au sein du répertoire .hg/patches, tandis que les patchs\n"
+"appliqués sont présents à la fois sous forme de fichier et de\n"
+"\"changesets\".\n"
+"\n"
+"Tâches usuelles (utiliser \"hg help commande\" pour plus de détails):\n"
+"\n"
+"préparer un dépôt pour utilisation avec des patchs qinit\n"
+"créer un nouveau patch qnew\n"
+"importer un patch existant qimport\n"
+"\n"
+"afficher la série de patchs complète qseries\n"
+"afficher les patchs appliqués qapplied\n"
+"afficher le nom du dernier patch appliqué qtop\n"
+"\n"
+"empiler/appliquer un patch référencé sur la pile qpush\n"
+"dépiler/ôter un patch de la pile qpop\n"
+"rafraîchir le contenu du dernier patch appliqué qrefresh\n"
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr "%s apparaît plus d'une fois dans %s"
+
+msgid "guard cannot be an empty string"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr ""
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr ""
+
+#, python-format
+msgid "active guards: %s\n"
+msgstr ""
+
+#, python-format
+msgid "guard %r too short"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr ""
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr ""
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr "l'application du patch %s a échoué"
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr "l'application simple du patch a échoué, fusion de %s\n"
+
+#, python-format
+msgid "update returned %d"
+msgstr ""
+
+msgid "repo commit failed"
+msgstr ""
+
+#, python-format
+msgid "unable to read %s"
+msgstr "impossible de lire %s"
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr "le patch %s n'existe pas\n"
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr "le patch %s n'est pas appliqué\n"
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr ""
+"l'application du patch a échoué, impossible de continuer (essayez avec -v)\n"
+
+#, python-format
+msgid "applying %s\n"
+msgstr "application de %s\n"
+
+#, python-format
+msgid "unable to read %s\n"
+msgstr "impossible de lire %s\n"
+
+#, python-format
+msgid "imported patch %s\n"
+msgstr "le patch %s a été importé\n"
+
+#, python-format
+msgid ""
+"\n"
+"imported patch %s"
+msgstr ""
+"\n"
+"le patch %s a été importé"
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr "le patch %s est vide\n"
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr ""
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr "la révision %d n'est pas gérée"
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr "impossible de supprimer la révision %d au-dessus de patchs appliqués"
+
+#, python-format
+msgid "patch %s finalized without changeset message\n"
+msgstr ""
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr "qdelete requiert au moins une révision ou le nom d'un patch"
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr "impossible de supprimer le patch appliqué %s"
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr "le patch %s n'est pas listé (fichier \"series\")"
+
+msgid "no patches applied"
+msgstr "pas de patchs appliqués"
+
+msgid "working directory revision is not qtip"
+msgstr "le répertoire de travail n'est pas à la révision qtip"
+
+msgid "local changes found, refresh first"
+msgstr "modifications locales trouvées, veuillez d'abord rafraîchir le patch"
+
+msgid "local changes found"
+msgstr "modifications locales trouvées"
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr "\"%s\" ne peut être utilisé comme nom de patch"
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr "le patch \"%s\" existe déjà"
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr "erreur lors de la suppression de %s\n"
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr "\"%s\" est un nom de patch ambigu :\n"
+
+#, python-format
+msgid "patch %s not in series"
+msgstr "le patch %s ne figure pas dans la série"
+
+#, fuzzy
+msgid "(working directory not at a head)\n"
+msgstr "(le répertoire de travail est à une révision différente de tip)\n"
+
+msgid "no patches in series\n"
+msgstr "pas de patchs dans la série\n"
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr "impossible d'empiler un patch déjà appliqué : %s"
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr "qpush: %s est déjà le dernier patch appliqué\n"
+
+#, python-format
+msgid "guarded by %r"
+msgstr ""
+
+msgid "no matching guards"
+msgstr ""
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr "impossible d'empiler '%s' - %s\n"
+
+msgid "all patches are currently applied\n"
+msgstr "tous les patchs sont actuellement appliqués\n"
+
+msgid "patch series already fully applied\n"
+msgstr "la série de patchs est déjà complètement appliquée\n"
+
+msgid "cleaning up working directory..."
+msgstr "nettoyage du répertoire de travail..."
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr ""
+"des erreurs se sont produites durant l'application, veuillez corriger puis "
+"rafraîchir %s\n"
+
+#, python-format
+msgid "now at: %s\n"
+msgstr "actuellement à : %s\n"
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr "le patch %s n'est pas appliqué"
+
+msgid "no patches applied\n"
+msgstr "aucun patch appliqué\n"
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr "qpop: %s est déjà le dernier patch appliqué\n"
+
+msgid "qpop: forcing dirstate update\n"
+msgstr ""
+"qpop: mise à jour de l'état du répertoire de travail (dirstate) forcée\n"
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr "tentative de dépilement d'un nœud inconnu : %s"
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr ""
+"le dépilement enlèverait une révision non gérée par cette pile de patchs"
+
+msgid "deletions found between repo revs"
+msgstr "suppressions trouvées entre des révisions du dépôt"
+
+msgid "patch queue now empty\n"
+msgstr "la pile de patchs est maintenant vide\n"
+
+msgid "cannot refresh a revision with children"
+msgstr "impossible de rafraîchir une révision possédant des révisions filles"
+
+# restaurer/récupérer ? pas satisfait...
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to "
+"recover)\n"
+msgstr ""
+"rafraîchissement interrompu alors qu'un patch était en cours de dépilement "
+"(utiliser revert --all, ou qpush pour restaurer l'état)\n"
+
+msgid "patch queue directory already exists"
+msgstr "la pile de patchs existe déjà"
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr "le patch %s n'est pas dans la liste (fichier \"series\")"
+
+msgid "No saved patch data found\n"
+msgstr ""
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr "rétablissement de l'état : %s\n"
+
+msgid "save entry has children, leaving it alone\n"
+msgstr ""
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr ""
+
+msgid "queue directory updating\n"
+msgstr "mise à jour du répertoire de patchs\n"
+
+msgid "Unable to load queue repository\n"
+msgstr "Impossible de charger le dépôt de patchs\n"
+
+msgid "save: no patches applied, exiting\n"
+msgstr ""
+
+msgid "status is already saved\n"
+msgstr "l'état a déjà été sauvegardé\n"
+
+msgid "hg patches saved state"
+msgstr ""
+
+msgid "repo commit failed\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr "le patch %s est déjà dans la liste (fichier \"series\")"
+
+msgid "option \"-r\" not valid when importing files"
+msgstr "l'option \"-r\" n'est pas utilisable lors de l'importation de fichiers"
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr ""
+"l'option \"-n\" n'est pas utilisable lors de l'importation de plusieurs "
+"patchs"
+
+# origine/base/racine ?
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr "la révision %d est à l'origine de plus d'une branche"
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr "la révision %d est déjà gérée"
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr "la révision %d n'est pas parente de la pile"
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr "la révision %d possède des révisions filles non gérées"
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr "impossible d'importer la révision fusionnée %d"
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr "%d n'est pas la révision parente de %d"
+
+msgid "-e is incompatible with import from -"
+msgstr "-e n'est pas compatible avec l'importation depuis -"
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr "le patch %s n'existe pas"
+
+msgid "need --name to import a patch from -"
+msgstr "il est nécessaire d'utiliser --name pour importer un patch depuis -"
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr "ajout de %s à la liste de patchs (fichier \"series\")\n"
+
+msgid ""
+"remove patches from queue\n"
+"\n"
+" The patches must not be applied, and at least one patch is required. "
+"With\n"
+" -k/--keep, the patch files are preserved in the patch directory.\n"
+"\n"
+" To stop managing a patch and move it into permanent history,\n"
+" use the qfinish command."
+msgstr ""
+"supprime des patchs de la pile\n"
+"\n"
+" Les patchs ne doivent pas avoir été appliqués, et il est\n"
+" nécessaire de fournir au moins un patch.\n"
+"\n"
+" Avec -k/--keep, les fichiers sont préservés au sein du répertoire\n"
+" de patchs.\n"
+"\n"
+" Pour arrêter de gérer un patch et le déplacer de manière\n"
+" permanente vers l'historique du dépôt, utilisez la commande\n"
+" qfinish."
+
+msgid "print the patches already applied"
+msgstr "affiche les patchs déjà appliqués"
+
+msgid "print the patches not yet applied"
+msgstr "affiche les patchs non encore appliqués"
+
+msgid ""
+"import a patch\n"
+"\n"
+" The patch is inserted into the series after the last applied\n"
+" patch. If no patches have been applied, qimport prepends the patch\n"
+" to the series.\n"
+"\n"
+" The patch will have the same name as its source file unless you\n"
+" give it a new one with -n/--name.\n"
+"\n"
+" You can register an existing patch inside the patch directory with\n"
+" the -e/--existing flag.\n"
+"\n"
+" With -f/--force, an existing patch of the same name will be\n"
+" overwritten.\n"
+"\n"
+" An existing changeset may be placed under mq control with -r/--rev\n"
+" (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+" With -g/--git, patches imported with --rev will use the git diff\n"
+" format. See the diffs help topic for information on why this is\n"
+" important for preserving rename/copy information and permission\n"
+" changes.\n"
+"\n"
+" To import a patch from standard input, pass - as the patch file.\n"
+" When importing from standard input, a patch name must be specified\n"
+" using the --name flag.\n"
+" "
+msgstr ""
+"importe un patch\n"
+"\n"
+" Le patch est inséré dans la série à la suite du dernier patch\n"
+" appliqué. Si aucun patch n'a encore été appliqué, le patch sera\n"
+" ajouté en tête de série.\n"
+"\n"
+" Le patch portera le même nom que le fichier dont il provient,\n"
+" à moins qu'un autre nom ne soit spécifié à l'aide de -n/--name.\n"
+"\n"
+" Vous pouvez enregistrer un patch déjà présent dans le répertoire\n"
+" de patchs à l'aide de l'option -e/--existing.\n"
+"\n"
+" Avec -f/--force, un patch déjà présent du même nom sera écrasé.\n"
+"\n"
+" Un \"changeset\" existant peut-être placé sous le contrôle de mq\n"
+" à l'aide de -r/--rev (par exemple qimport --rev tip -n patch\n"
+" placera la révision tip sous le contrôle de mq).\n"
+" Avec -g/--git, les patchs importés à l'aide de --rev seront\n"
+" enregistrés au format \"git diff\". La section \"diffs\" de\n"
+" l'aide explique l'importance de cette option pour la\n"
+" préservation des informations de copie/renommage et des\n"
+" modifications de permissions.\n"
+"\n"
+" Pour importer un patch depuis l'entrée standard, utilisez -\n"
+" comme nom de fichier. Il sera alors nécessaire de nommer le\n"
+" patch à l'aide de l'option --name.\n"
+" "
+
+msgid ""
+"init a new queue repository\n"
+"\n"
+" The queue repository is unversioned by default. If\n"
+" -c/--create-repo is specified, qinit will create a separate nested\n"
+" repository for patches (qinit -c may also be run later to convert\n"
+" an unversioned patch repository into a versioned one). You can use\n"
+" qcommit to commit changes to this queue repository."
+msgstr ""
+
+msgid ""
+"clone main and patch repository at same time\n"
+"\n"
+" If source is local, destination will have no patches applied. If\n"
+" source is remote, this command can not check if patches are\n"
+" applied in source, so cannot guarantee that patches are not\n"
+" applied in destination. If you clone remote repository, be sure\n"
+" before that it has no patches applied.\n"
+"\n"
+" Source patch repository is looked for in <src>/.hg/patches by\n"
+" default. Use -p <url> to change.\n"
+"\n"
+" The patch directory must be a nested Mercurial repository, as\n"
+" would be created by qinit -c.\n"
+" "
+msgstr ""
+"clône simultanément le dépôt principal et le dépôt des patchs\n"
+"\n"
+" Si la source est locale, aucun patch ne sera appliqué sur la\n"
+" cible. En revanche, si la source est distante, cette commande\n"
+" n'est pas en mesure de vérifier si des patchs y ont été\n"
+" empilés, et par conséquent ne peut garantir qu'aucun patch\n"
+" ne sera appliqué au dessus de la cible. Autrement dit, si vous\n"
+" clônez un dépôt distant, assurez-vous auparavant qu'il n'ait\n"
+" aucun patch d'appliqué.\n"
+"\n"
+" Le dépôt de patchs est recherché dans <src>/.hg/patches par\n"
+" défaut, à moins que -p <url> ne soit utilisé pour spécifier\n"
+" un chemin différent.\n"
+"\n"
+" Le répertoire de patchs doit être contenu dans le dépôt\n"
+" principal, tel que créé par qinit -c.\n"
+" "
+
+msgid "versioned patch repository not found (see qinit -c)"
+msgstr "aucun dépôt de patch trouvé (voir qinit -c)"
+
+msgid "cloning main repository\n"
+msgstr "clônage du dépôt principal\n"
+
+msgid "cloning patch repository\n"
+msgstr "clônage du dépôt des patchs\n"
+
+msgid "stripping applied patches from destination repository\n"
+msgstr "enlèvement des patchs appliqués du dépôt cible\n"
+
+msgid "updating destination repository\n"
+msgstr "mise à jour du dépôt cible\n"
+
+msgid "commit changes in the queue repository"
+msgstr ""
+
+msgid "print the entire series file"
+msgstr "afficher la liste complète de patchs (fichier \"series\")"
+
+msgid "print the name of the current patch"
+msgstr "affiche le nom du dernier patch appliqué"
+
+msgid "print the name of the next patch"
+msgstr "affiche le nom du prochain patch"
+
+msgid "all patches applied\n"
+msgstr "tous les patchs ont été appliqués\n"
+
+msgid "print the name of the previous patch"
+msgstr "affiche le nom du patch précédent"
+
+msgid "only one patch applied\n"
+msgstr "un seul patch d'appliqué\n"
+
+msgid ""
+"create a new patch\n"
+"\n"
+" qnew creates a new patch on top of the currently-applied patch (if\n"
+" any). It will refuse to run if there are any outstanding changes\n"
+" unless -f/--force is specified, in which case the patch will be\n"
+" initialized with them. You may also use -I/--include,\n"
+" -X/--exclude, and/or a list of files after the patch name to add\n"
+" only changes to matching files to the new patch, leaving the rest\n"
+" as uncommitted modifications.\n"
+"\n"
+" -u/--user and -d/--date can be used to set the (given) user and\n"
+" date, respectively. -U/--currentuser and -D/--currentdate set user\n"
+" to current user and date to current date.\n"
+"\n"
+" -e/--edit, -m/--message or -l/--logfile set the patch header as\n"
+" well as the commit message. If none is specified, the header is\n"
+" empty and the commit message is '[mq]: PATCH'.\n"
+"\n"
+" Use the -g/--git option to keep the patch in the git extended diff\n"
+" format. Read the diffs help topic for more information on why this\n"
+" is important for preserving permission changes and copy/rename\n"
+" information.\n"
+" "
+msgstr ""
+"crée un nouveau patch\n"
+"\n"
+" qnew crée un nouveau patch au-dessus du dernier patch\n"
+" actuellement appliqué, le cas échéant. Si le répertoire\n"
+" de travail comporte des modifications non enregistrées,\n"
+" la création du patch sera refusée, à moins d'utiliser\n"
+" -f/--force auquel cas le contenu du nouveau patch sera\n"
+" initialisé avec ces modifications. Il est également\n"
+" possible d'utiliser -I/--include, -X/--exclude ou une liste\n"
+" de noms de fichiers après le nom du patch, afin de n'inclure\n"
+" que les changements des fichiers concernés, et laisser le\n"
+" reste dans le répertoire de travail en tant que modifications\n"
+" non enregistrées.\n"
+"\n"
+" Le nom d'utilisateur et la date peuvent être spécifiés à\n"
+" l'aide de -u/--user et -d/--date respectivement.\n"
+" -U/--currentuser et -D/--currentdate positionnent le nom\n"
+" d'utilisateur et la date à leur valeur actuelle.\n"
+"\n"
+" L'en-tête du patch et le message de \"commit\" peuvent être\n"
+" spécifiés à l'aide de -e/--edit, -m/--message ou -l/--logfile.\n"
+" Si aucune de ces options n'est utilisée, l'en-tête restera\n"
+" vierge et le message de \"commit\" sera '[mq]: PATCH'.\n"
+"\n"
+" Utilisez -g/--git pour garder le patch au format étendu de\n"
+" \"git\". La section \"diffs\" de l'aide explique l'importance\n"
+" de cette option pour la préservation des informations de\n"
+" copie/renommage et des modifications de permissions.\n"
+" "
+
+msgid ""
+"update the current patch\n"
+"\n"
+" If any file patterns are provided, the refreshed patch will\n"
+" contain only the modifications that match those patterns; the\n"
+" remaining modifications will remain in the working directory.\n"
+"\n"
+" If -s/--short is specified, files currently included in the patch\n"
+" will be refreshed just like matched files and remain in the patch.\n"
+"\n"
+" hg add/remove/copy/rename work as usual, though you might want to\n"
+" use git-style patches (-g/--git or [diff] git=1) to track copies\n"
+" and renames. See the diffs help topic for more information on the\n"
+" git diff format.\n"
+" "
+msgstr ""
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr "l'option \"-e\" est incompatible avec \"-m\" ou \"-l\""
+
+msgid ""
+"diff of the current patch and subsequent modifications\n"
+"\n"
+" Shows a diff which includes the current patch as well as any\n"
+" changes which have been made in the working directory since the\n"
+" last refresh (thus showing what the current patch would become\n"
+" after a qrefresh).\n"
+"\n"
+" Use 'hg diff' if you only want to see the changes made since the\n"
+" last qrefresh, or 'hg export qtip' if you want to see changes made\n"
+" by the current patch without including changes made since the\n"
+" qrefresh.\n"
+" "
+msgstr ""
+
+msgid ""
+"fold the named patches into the current patch\n"
+"\n"
+" Patches must not yet be applied. Each patch will be successively\n"
+" applied to the current patch in the order given. If all the\n"
+" patches apply successfully, the current patch will be refreshed\n"
+" with the new cumulative patch, and the folded patches will be\n"
+" deleted. With -k/--keep, the folded patch files will not be\n"
+" removed afterwards.\n"
+"\n"
+" The header for each folded patch will be concatenated with the\n"
+" current patch header, separated by a line of '* * *'."
+msgstr ""
+
+msgid "qfold requires at least one patch name"
+msgstr "qfold a besoin au minimum du nom d'un patch"
+
+msgid "No patches applied"
+msgstr "Aucun patch d'appliqué"
+
+#, python-format
+msgid "Skipping already folded patch %s"
+msgstr ""
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "Error folding patch %s"
+msgstr ""
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr "empile ou dépile les patchs jusqu'à arriver au patch indiqué"
+
+msgid ""
+"set or print guards for a patch\n"
+"\n"
+" Guards control whether a patch can be pushed. A patch with no\n"
+" guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+" pushed only if the qselect command has activated it. A patch with\n"
+" a negative guard (\"-foo\") is never pushed if the qselect command\n"
+" has activated it.\n"
+"\n"
+" With no arguments, print the currently active guards.\n"
+" With arguments, set guards for the named patch.\n"
+" NOTE: Specifying negative guards now requires '--'.\n"
+"\n"
+" To set guards on another patch:\n"
+" hg qguard -- other.patch +2.6.17 -stable\n"
+" "
+msgstr ""
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr "impossible d'utiliser -l/--list avec d'autres options ou paramètres"
+
+msgid "no patch to work with"
+msgstr "aucun patch avec lequel travailler"
+
+#, python-format
+msgid "no patch named %s"
+msgstr "aucun patch du nom de %s"
+
+msgid "print the header of the topmost or specified patch"
+msgstr "affiche l'en-tête du dernier patch appliqué"
+
+msgid ""
+"push the next patch onto the stack\n"
+"\n"
+" When -f/--force is applied, all local changes in patched files\n"
+" will be lost.\n"
+" "
+msgstr ""
+"applique le patch suivant sur la pile\n"
+"\n"
+" Si -f/--force est utilisé, tout changement local dans les\n"
+" fichiers concernés par le patch seront perdus.\n"
+" "
+
+msgid "no saved queues found, please use -n\n"
+msgstr "aucune ssauvegarde de pile de patchs trouvée, veuillez utiliser -n\n"
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr "fusion avec la pile située à %s\n"
+
+msgid ""
+"pop the current patch off the stack\n"
+"\n"
+" By default, pops off the top of the patch stack. If given a patch\n"
+" name, keeps popping off patches until the named patch is at the\n"
+" top of the stack.\n"
+" "
+msgstr ""
+"dépile le dernier patch appliqué\n"
+"\n"
+" Par défaut, le dernier patch appliqué est ôté de la pile. Si\n"
+" un nom de patch est fourni, les patchs seront dépilés en\n"
+" séquence jusqu'à arriver au patch demandé.\n"
+" "
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr "utilisation de la pile de patchs %s\n"
+
+msgid ""
+"rename a patch\n"
+"\n"
+" With one argument, renames the current patch to PATCH1.\n"
+" With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+"renomme un patch\n"
+"\n"
+" Avec un seul argument, le patch actuel est renommé PATCH1.\n"
+" Avec deux arguments, PATCH1 devient PATCH2."
+
+#, python-format
+msgid "%s already exists"
+msgstr "%s existe déjà"
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr "Il existe déjà un patch du nom de %s (dans le fichier \"series\")"
+
+msgid "restore the queue state saved by a revision"
+msgstr "rétablissement d'un état sauvegardé de la pile"
+
+msgid "save current queue state"
+msgstr "sauvegarde de l'étatt de la pile de patchs"
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr "%s: la cible existe et n'est pas un répertoire"
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr "%s: la cible existe, utilisez -f pour forcer l'action"
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr "copie de %s vers %s\n"
+
+msgid ""
+"strip a revision and all its descendants from the repository\n"
+"\n"
+" If one of the working directory's parent revisions is stripped, the\n"
+" working directory will be updated to the parent of the stripped\n"
+" revision.\n"
+" "
+msgstr ""
+
+msgid ""
+"set or print guarded patches to push\n"
+"\n"
+" Use the qguard command to set or print guards on patch, then use\n"
+" qselect to tell mq which guards to use. A patch will be pushed if\n"
+" it has no guards or any positive guards match the currently\n"
+" selected guard, but will not be pushed if any negative guards\n"
+" match the current guard. For example:\n"
+"\n"
+" qguard foo.patch -stable (negative guard)\n"
+" qguard bar.patch +stable (positive guard)\n"
+" qselect stable\n"
+"\n"
+" This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+" it has a negative match) but push bar.patch (because it has a\n"
+" positive match).\n"
+"\n"
+" With no arguments, prints the currently active guards.\n"
+" With one argument, sets the active guard.\n"
+"\n"
+" Use -n/--none to deactivate guards (no other arguments needed).\n"
+" When no guards are active, patches with positive guards are\n"
+" skipped and patches with negative guards are pushed.\n"
+"\n"
+" qselect can change the guards on applied patches. It does not pop\n"
+" guarded patches by default. Use --pop to pop back to the last\n"
+" applied patch that is not guarded. Use --reapply (which implies\n"
+" --pop) to push back to the current patch afterwards, but skip\n"
+" guarded patches.\n"
+"\n"
+" Use -s/--series to print a list of all guards in the series file\n"
+" (no other arguments needed). Use -v for more information."
+msgstr ""
+
+msgid "guards deactivated\n"
+msgstr ""
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr ""
+
+msgid "guards in series file:\n"
+msgstr ""
+
+msgid "no guards in series file\n"
+msgstr ""
+
+msgid "active guards:\n"
+msgstr ""
+
+msgid "no active guards\n"
+msgstr ""
+
+msgid "popping guarded patches\n"
+msgstr ""
+
+msgid "reapplying unguarded patches\n"
+msgstr ""
+
+msgid ""
+"move applied patches into repository history\n"
+"\n"
+" Finishes the specified revisions (corresponding to applied\n"
+" patches) by moving them out of mq control into regular repository\n"
+" history.\n"
+"\n"
+" Accepts a revision range or the -a/--applied option. If --applied\n"
+" is specified, all applied mq revisions are removed from mq\n"
+" control. Otherwise, the given revisions must be at the base of the\n"
+" stack of applied patches.\n"
+"\n"
+" This can be especially useful if your changes have been applied to\n"
+" an upstream repository, or if you are about to push your changes\n"
+" to upstream.\n"
+" "
+msgstr ""
+"déplacement des patchs vers l'historique du dépôt\n"
+"\n"
+" Achève le développement des révisions spécifiées (qui doivent\n"
+" correspondre à des patch appliqués) en les retirant du contrôle\n"
+" de mq, pour les transformer en \"changeset\" ordinaires dans\n"
+" l'historique du dépôt.\n"
+"\n"
+" Il est possible d'utiliser l'option -a/--applied, ou de fournir\n"
+" une plage de révisions. Avec --applied, tous les patchs\n"
+" appliqués seront retirés du contrôle de mq. Autrement, les\n"
+" révisions fournies doivent être situées à la base de la pile de\n"
+" patchs appliqués.\n"
+"\n"
+" Ceci est utile en particulier si vos changements ont été adoptés\n"
+" dans un dépôt amont, ou si vous vous apprêtez à les y envoyer.\n"
+" "
+
+msgid "no revisions specified"
+msgstr "aucune révision spécifiée"
+
+msgid "cannot commit over an applied mq patch"
+msgstr ""
+
+msgid "source has mq patches applied"
+msgstr ""
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr "le fichier d'état de mq fait référence à un nœud inconnu : %s\n"
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr ""
+
+msgid "cannot import over an applied patch"
+msgstr "impossible d'importer au-dessus d'un patch appliqué"
+
+msgid "print first line of patch header"
+msgstr "affiche la première ligne de l'en-tête d'un patch"
+
+msgid "hg qapplied [-s] [PATCH]"
+msgstr "hg qapplied [-s] [PATCH]"
+
+msgid "use pull protocol to copy metadata"
+msgstr ""
+
+msgid "do not update the new working directories"
+msgstr "ne pas mettre à jour le répertoire de travail"
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr "transférer sans compression (rapide sur un réseau local)"
+
+msgid "location of source patch repository"
+msgstr "emplacement du dépôt de patchs"
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr "hg qclone [OPTION]... SOURCE [DEST]"
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr "hg qcommit [OPTION]... [FICHIER]..."
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr "hg qdiff [OPTION]... [FICHIER]..."
+
+msgid "keep patch file"
+msgstr "garder le fichier du patch"
+
+msgid "stop managing a revision (DEPRECATED)"
+msgstr "arrêter de gérer une révision"
+
+msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
+msgstr "hg qdelete [-k] [-r REV]... [PATCH]..."
+
+msgid "edit patch header"
+msgstr "éditer l'en-tête du patch"
+
+msgid "keep folded patch files"
+msgstr ""
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr "hg qfold [-e] [-k] [-m TEXTE] [-l FICHIER] PATCH..."
+
+msgid "overwrite any local changes"
+msgstr "écraser tout modification locale"
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr "hg qgoto [OPTION]... PATCH"
+
+msgid "list all patches and guards"
+msgstr ""
+
+msgid "drop all guards"
+msgstr ""
+
+msgid "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+msgstr ""
+
+msgid "hg qheader [PATCH]"
+msgstr "hg qheader [PATCH]"
+
+msgid "import file in patch directory"
+msgstr "importer un fichier résidant dans le répertoire de patchs"
+
+msgid "name of patch file"
+msgstr "nom du fichier de patch"
+
+msgid "overwrite existing files"
+msgstr "écraser les fichiers existant"
+
+msgid "place existing revisions under mq control"
+msgstr "placer des révisions existantes sous le contrôle de mq"
+
+msgid "use git extended diff format"
+msgstr "utiliser le format de patch étendu de git"
+
+msgid "qpush after importing"
+msgstr "qpush après l'importation"
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr "hg qimport [-e] [-n NOM] [-f] [-g] [-P] [-r REV]... FICHIER..."
+
+msgid "create queue repository"
+msgstr "crée un dépôt de patchs"
+
+msgid "hg qinit [-c]"
+msgstr "hg qinit [-c]"
+
+msgid "import uncommitted changes into patch"
+msgstr "importer les modifications locales dans le patch"
+
+msgid "add \"From: <current user>\" to patch"
+msgstr "ajout de \"From: <utilisateur actuel>\" au patch"
+
+msgid "add \"From: <given user>\" to patch"
+msgstr "ajout de \"From: <utilisateur spécifié>\" au patch"
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr "ajout de \"Date: <date actuelle>\" au patch"
+
+msgid "add \"Date: <given date>\" to patch"
+msgstr "ajout de \"Date: <date spécifiée>\" au patch"
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+msgstr "hg qnew [-e] [-m TEXTE] [-l FICHIER] [-f] PATCH [FICHIER]..."
+
+msgid "hg qnext [-s]"
+msgstr "hg qnext [-s]"
+
+msgid "hg qprev [-s]"
+msgstr "hg qprev [-s]"
+
+msgid "pop all patches"
+msgstr "dépiler tous les patchs"
+
+msgid "queue name to pop"
+msgstr "nom de la pile à dépiler"
+
+msgid "forget any local changes"
+msgstr "oublier toute modification locale"
+
+msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+msgstr "hg qpop [-a] [-n NOM] [-f] [PATCH | INDEX]"
+
+msgid "apply if the patch has rejects"
+msgstr ""
+
+msgid "list patch name in commit text"
+msgstr ""
+
+msgid "apply all patches"
+msgstr "appliquer tous les patchs"
+
+msgid "merge from another queue"
+msgstr "fusionner avec une autre pile de patchs"
+
+msgid "merge queue name"
+msgstr "nom de la pile à fusionner"
+
+msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+msgstr "hg qpush [-f] [-l] [-a] [-m] [-n NOM] [PATCH | INDEX]"
+
+msgid "refresh only files already in the patch and specified files"
+msgstr ""
+"ne rafraîchir que les fichiers déjà présent dans le patch et ceux "
+"explicitement spécifiés"
+
+msgid "add/update \"From: <current user>\" in patch"
+msgstr "ajouter/mettre à jour \"From: <utilisateur actuel>\" dans le patch"
+
+msgid "add/update \"From: <given user>\" in patch"
+msgstr "ajouter/mettre à jour \"From: <utilisateur spécifié>\" dans le patch"
+
+msgid "update \"Date: <current date>\" in patch (if present)"
+msgstr "mettre à jour \"Date: <date actuelle>\" dans le patch (si présente)"
+
+msgid "update \"Date: <given date>\" in patch (if present)"
+msgstr "mettre à jour \"Date: <date spécifiée>\" dans le patch (si présente)"
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr "hg qrefresh [-I] [-X] [-e] [-m TEXTE] [-l FICHIER] [-s] [FICHIER]..."
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr "hg qrename PATCH1 [PATCH2]"
+
+msgid "delete save entry"
+msgstr ""
+
+msgid "update queue working directory"
+msgstr ""
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr ""
+
+msgid "copy patch directory"
+msgstr ""
+
+msgid "copy directory name"
+msgstr ""
+
+msgid "clear queue status file"
+msgstr ""
+
+msgid "force copy"
+msgstr ""
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr "hg qsave [-m TEXT] [-l FILE] [-c] [-n NOM] [-e] [-f]"
+
+msgid "disable all guards"
+msgstr ""
+
+msgid "list all guards in series file"
+msgstr ""
+
+msgid "pop to before first guarded applied patch"
+msgstr ""
+
+msgid "pop, then reapply patches"
+msgstr "dépiler, puis appliquer à nouveau les patchs"
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr ""
+
+msgid "print patches not in series"
+msgstr "afficher les patchs absents de la série"
+
+msgid "hg qseries [-ms]"
+msgstr "hg qseries [-ms]"
+
+msgid "force removal with local changes"
+msgstr "forcer la suppression malgré les modifications locales"
+
+msgid "bundle unrelated changesets"
+msgstr ""
+
+msgid "no backups"
+msgstr ""
+
+msgid "hg strip [-f] [-b] [-n] REV"
+msgstr "hg strip [-f] [-b] [-n] REV"
+
+msgid "hg qtop [-s]"
+msgstr "hg qtop [-s]"
+
+msgid "hg qunapplied [-s] [PATCH]"
+msgstr "hg qunapplied [-s] [PATCH]"
+
+msgid "finish all applied changesets"
+msgstr ""
+
+msgid "hg qfinish [-a] [REV]..."
+msgstr "hg qfinish [-a] [REV]..."
+
+msgid ""
+"hooks for sending email notifications at commit/push time\n"
+"\n"
+"Subscriptions can be managed through hgrc. Default mode is to print\n"
+"messages to stdout, for testing and configuring.\n"
+"\n"
+"To use, configure notify extension and enable in hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # one email for each incoming changeset\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # batch emails when many changesets incoming at one time\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # config items go in here\n"
+"\n"
+" config items:\n"
+"\n"
+" REQUIRED:\n"
+" config = /path/to/file # file containing subscriptions\n"
+"\n"
+" OPTIONAL:\n"
+" test = True # print messages to stdout for testing\n"
+" strip = 3 # number of slashes to strip for url paths\n"
+" domain = example.com # domain to use if committer missing domain\n"
+" style = ... # style file to use when formatting email\n"
+" template = ... # template to use when formatting email\n"
+" incoming = ... # template to use when run as incoming hook\n"
+" changegroup = ... # template when run as changegroup hook\n"
+" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n"
+" maxsubject = 67 # truncate subject line longer than this\n"
+" diffstat = True # add a diffstat before the diff content\n"
+" sources = serve # notify if source of incoming changes in this "
+"list\n"
+" # (serve == ssh or http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # email address to send as if none given\n"
+" [web]\n"
+" baseurl = http://hgserver/... # root of hg web site for browsing commits\n"
+"\n"
+" notify config file has same format as regular hgrc. it has two\n"
+" sections so you can express subscriptions in whatever way is handier\n"
+" for you.\n"
+"\n"
+" [usersubs]\n"
+" # key is subscriber email, value is \",\"-separated list of glob "
+"patterns\n"
+" user@host = pattern\n"
+"\n"
+" [reposubs]\n"
+" # key is glob pattern, value is \",\"-separated list of subscriber "
+"emails\n"
+" pattern = user@host\n"
+"\n"
+" glob patterns are matched against path to repository root.\n"
+"\n"
+" if you like, you can put notify config file in repository that users\n"
+" can push changes to, they can manage their own subscriptions."
+msgstr ""
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr ""
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "notify: no subscribers to repository %s\n"
+msgstr ""
+
+#, python-format
+msgid "notify: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+msgid ""
+"browse command output with an external pager\n"
+"\n"
+"To set the pager that should be used, set the application variable:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"If no pager is set, the pager extensions uses the environment variable\n"
+"$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.\n"
+"\n"
+"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
+"setting:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"You can also enable the pager only for certain commands using\n"
+"pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"If pager.attend is present, pager.ignore will be ignored.\n"
+"\n"
+"To ignore global commands like \"hg version\" or \"hg help\", you have to\n"
+"specify them in the global .hgrc\n"
+msgstr ""
+
+# première ligne trop longue -> traduction abrégée (à retraduire quand hg
+# sera capable de replier automatiquement la première ligne d'aide)
+msgid ""
+"interpret suffixes to refer to ancestor revisions\n"
+"\n"
+"This extension allows you to use git-style suffixes to refer to the\n"
+"ancestors of a specific revision.\n"
+"\n"
+"For example, if you can refer to a revision as \"foo\", then:\n"
+"\n"
+"- foo^N = Nth parent of foo\n"
+" foo^0 = foo\n"
+" foo^1 = first parent of foo\n"
+" foo^2 = second parent of foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nth first grandparent of foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = first parent of foo\n"
+" foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
+msgstr ""
+"suffixes faisant référence à des révisions antérieures\n"
+"\n"
+"Cette extension permet d'utiliser des suffixes à la mode git pour\n"
+"faire référence aux ancêtres d'une révision donnée.\n"
+"\n"
+"Par exemple, si \"foo\" désigne une révision, alors :\n"
+"\n"
+"- foo^N = Nième parent de foo\n"
+" foo^0 = foo\n"
+" foo^1 = premier parent de foo\n"
+" foo^2 = second parent de foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nième premier grand-parent de foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = premier parent de foo\n"
+" foo~2 = foo^1^1 = foo^^ = premier parent du premier parent de foo\n"
+
+# première ligne trop longue -> traduction abrégée (à retraduire quand hg
+# sera capable de replier automatiquement la première ligne d'aide)
+msgid ""
+"command to send changesets as (a series of) patch emails\n"
+"\n"
+"The series is started off with a \"[PATCH 0 of N]\" introduction, which\n"
+"describes the series as a whole.\n"
+"\n"
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using the\n"
+"first line of the changeset description as the subject text. The\n"
+"message contains two or three body parts:\n"
+"\n"
+" The changeset description.\n"
+"\n"
+" [Optional] The result of running diffstat on the patch.\n"
+"\n"
+" The patch itself, as generated by \"hg export\".\n"
+"\n"
+"Each message refers to the first in the series using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in threaded\n"
+"mail and news readers, and in mail archives.\n"
+"\n"
+"With the -d/--diffstat option, you will be prompted for each changeset\n"
+"with a diffstat summary and the changeset summary, so you can be sure\n"
+"you are sending the right changes.\n"
+"\n"
+"To configure other defaults, add a section like this to your hgrc\n"
+"file:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Then you can use the \"hg email\" command to mail a series of changesets\n"
+"as a patchbomb.\n"
+"\n"
+"To avoid sending patches prematurely, it is a good idea to first run\n"
+"the \"email\" command with the \"-n\" option (test only). You will be\n"
+"prompted for an email recipient address, a subject and an introductory\n"
+"message describing the patches of your patchbomb. Then when all is\n"
+"done, patchbomb messages are displayed. If the PAGER environment\n"
+"variable is set, your pager will be fired up once for each patchbomb\n"
+"message, so you can verify everything is alright.\n"
+"\n"
+"The -m/--mbox option is also very useful. Instead of previewing each\n"
+"patchbomb message in a pager or sending the messages directly, it will\n"
+"create a UNIX mailbox file with the patch emails. This mailbox file\n"
+"can be previewed with any mail user agent which supports UNIX mbox\n"
+"files, e.g. with mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"When you are previewing the patchbomb messages, you can use `formail'\n"
+"(a utility that is commonly installed as part of the procmail\n"
+"package), to send each message out:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"That should be all. Now your patchbomb is on its way out.\n"
+"\n"
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatible mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs\n"
+"directly from the commandline. See the [email] and [smtp] sections in\n"
+"hgrc(5) for details."
+msgstr ""
+"envoi d'une série de \"changesets\" par courrier électronique\n"
+"\n"
+"La série débute par un message d'introduction \"[PATCH 0 of N]\" la\n"
+"décrivant dans son ensemble.\n"
+"\n"
+"Ensuite, pour chaque patch est créé un courriel dont le sujet est\n"
+"la première ligne du commentaire du \"changeset\", préfixée par\n"
+"\"[PATCH M of N] \". Le corps du message comporte deux ou trois\n"
+"parties :\n"
+"\n"
+" La description du \"changeset\".\n"
+"\n"
+" Optionnellement, un résumé des modifications généré par le\n"
+" programme diffstat.\n"
+"\n"
+" Le patch proprement dit, tel que généré par \"hg export\".\n"
+"\n"
+"Chaque message fait référence au premier de la série (à l'aide\n"
+"des en-têtes de message In-Reply-To et References) de manière à\n"
+"apparaître comme un fil de discussion dans les lecteurs de courrier\n"
+"électronique et de nouvelles, ainsi que dans les archives de\n"
+"messagerie.\n"
+"\n"
+"Avec l'option -d/--diffstat, il vous sera demandé pour chaque\n"
+"\"changeset\" d'en confirmer l'envoi après avoir vu un résumé des\n"
+"modifications (par diffstat) et le commentaire associé ; ceci afin\n"
+"d'être certain de bien envoyer les bonnes modifications.\n"
+"\n"
+"Pour configurer les valeurs par défaut d'autres options d'envoi,\n"
+"ajoutez à votre fichier hgrc une section telle ci-dessous :\n"
+"\n"
+" [email]\n"
+" from = Mon Nom <mon@adresse_de_courriel>\n"
+" to = destinataire1, destinataire2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Après cela il vous sera possible d'utiliser la commande \"hg email\"\n"
+"pour envoyer par courrier électronique une série de \"changesets\".\n"
+"\n"
+"Pour éviter d'envoyer des patchs prématurément, utiliser tout d'abord\n"
+"l'option \"-n\" (simple test) s'avère être une bonne idée. Il vous\n"
+"sera demandé l'adresse du destinataire ainsi qu'un sujet et un\n"
+"message d'introduction pour la série de patchs. Lorsque tout est\n"
+"prêt, les messages seront affichés. Si la variable d'environnement\n"
+"PAGER a été définie, le programme qu'elle indique sera utilisé pour\n"
+"l'affichage chaque message, permettant de vérifier que tout est\n"
+"correct.\n"
+"\n"
+"L'option -m/--mbox est également très utile : au lieu que les\n"
+"messages soient affichés ou envoyés directement, ils seront écrits\n"
+"dans un fichier (au format de boîte aux lettres UNIX). Cette boîte\n"
+"aux lettres peut alors être consultée pour vérification par n'importe\n"
+"quel lecteur de courrier électronique comprenant le format UNIX mbox,\n"
+"comme par exemple mutt :\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"Lors de votre vérification, vous pouvez envoyer chaque message en\n"
+"utilisant formail (un outil généralement installé en même temps que\n"
+"procmail) :\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"Et voilà, vos patchs sont en route vers leur destination.\n"
+"\n"
+"Vous pouvez aussi configurer l'option \"method\" de la section\n"
+"[email] pour utiliser un programme compatible avec sendmail, ou\n"
+"alors remplir la section [smtp] de telle sorte que l'extension\n"
+"patchbomb puisse automatiquement envoyer les messages depuis la\n"
+"ligne de commande. Consulter les sections [email] et [smtp] dans la\n"
+"page de manuel hgrc(5) pour plus de détails."
+
+msgid "Please enter a valid value.\n"
+msgstr "Veuillez fournir une valeur valide.\n"
+
+msgid "does the diffstat above look okay? "
+msgstr "le résumé des modifications ci-dessus semble-t-il correct ?"
+
+msgid "diffstat rejected"
+msgstr "résumé des modifications rejeté"
+
+msgid ""
+"send changesets by email\n"
+"\n"
+" By default, diffs are sent in the format generated by hg export,\n"
+" one per message. The series starts with a \"[PATCH 0 of N]\"\n"
+" introduction, which describes the series as a whole.\n"
+"\n"
+" Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+" the first line of the changeset description as the subject text.\n"
+" The message contains two or three parts. First, the changeset\n"
+" description. Next, (optionally) if the diffstat program is\n"
+" installed and -d/--diffstat is used, the result of running\n"
+" diffstat on the patch. Finally, the patch itself, as generated by\n"
+" \"hg export\".\n"
+"\n"
+" By default the patch is included as text in the email body for\n"
+" easy reviewing. Using the -a/--attach option will instead create\n"
+" an attachment for the patch. With -i/--inline an inline attachment\n"
+" will be created.\n"
+"\n"
+" With -o/--outgoing, emails will be generated for patches not found\n"
+" in the destination repository (or only those which are ancestors\n"
+" of the specified revisions if any are provided)\n"
+"\n"
+" With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+" single email containing a binary Mercurial bundle as an attachment\n"
+" will be sent.\n"
+"\n"
+" Examples:\n"
+"\n"
+" hg email -r 3000 # send patch 3000 only\n"
+" hg email -r 3000 -r 3001 # send patches 3000 and 3001\n"
+" hg email -r 3000:3005 # send patches 3000 through 3005\n"
+" hg email 3000 # send patch 3000 (deprecated)\n"
+"\n"
+" hg email -o # send all patches not in default\n"
+" hg email -o DEST # send all patches not in DEST\n"
+" hg email -o -r 3000 # send all ancestors of 3000 not in default\n"
+" hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST\n"
+"\n"
+" hg email -b # send bundle of all patches not in default\n"
+" hg email -b DEST # send bundle of all patches not in DEST\n"
+" hg email -b -r 3000 # bundle of all ancestors of 3000 not in "
+"default\n"
+" hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST\n"
+"\n"
+" Before using this command, you will need to enable email in your\n"
+" hgrc. See the [email] section in hgrc(5) for details.\n"
+" "
+msgstr ""
+"envoi de \"changesets\" par courrier électronique\n"
+"\n"
+" Par défaut, les modifications sont envoyées au format généré par\n"
+" \"hg export\", une par message. La série débute par un message\n"
+" la décrivant dans son ensemble, intitulé \"[PATCH 0 of N]\".\n"
+"\n"
+" Chaque courriel a pour sujet un résumé des modifications\n"
+" apportées par le patch (pris en première ligne de la description\n"
+" du \"changeset\"), préfixé par \"[PATCH M of N] \".\n"
+" Le message est constitué de deux ou trois parties. D'abord,\n"
+" le texte décrivant le \"changeset\". Puis, (optionnellement)\n"
+" un résumé des modifications généré par le programme diffstat si\n"
+" celui-ci est installé et que l'option -d/--diffstat a été\n"
+" spécifiée. Et enfin le patch, tel que généré par \"hg export\".\n"
+"\n"
+" Par défaut le patch est inclus textuellement dans le corps du\n"
+" message afin de faciliter les relectures et commentaires.\n"
+" Cela peut être changé avec l'option -a/--attach qui crée une\n"
+" pièce jointe séparée pour le patch, ou avec -i/--inline qui\n"
+" insère celle-ci dans le corps.\n"
+"\n"
+" Avec -o/--outgoing, des courriels seront générés pour chaque\n"
+" révision non trouvée dans le dépôt cible (ou seulement pour les\n"
+" ancêtres des révisions spécifiées, le cas échéant).\n"
+"\n"
+" Avec -b/--bundle, les \"changesets\" sont sélectionnés de la\n"
+" même manière que pour --outgoing, mais il seront envoyés via\n"
+" un unique courriel dans un \"bundle\" Mercurial binaire joint.\n"
+"\n"
+" Exemples :\n"
+"\n"
+" hg email -r 3000 # envoyer uniquement le patch 3000\n"
+" hg email -r 3000 -r 3001 # envoyer les patchs 3000 et 3001\n"
+" hg email -r 3000:3005 # envoyer les patchs 3000 à 3005\n"
+" hg email 3000 # envoyer le patch 3000 (déprécié)\n"
+"\n"
+" hg email -o # envoyer les patchs absents de la\n"
+" destination par défaut\n"
+" hg email -o DEST # envoyer les patchs absents de DEST\n"
+" hg email -o -r 3000 # envoyer les ancêtres de 3000 absents\n"
+" de la destination par défaut\n"
+" hg email -o -r 3000 DEST # envoyer les ancêtres de 3000 absents\n"
+" de DEST\n"
+"\n"
+" Afin de pouvoir utiliser cette commande, il est nécessaire\n"
+" d'activer préalablement l'envoi de courriel dans le fichier\n"
+" de configuration (hgrc). Consulter hgrc(5) à la section\n"
+" [email] pour plus de détails.\n"
+" "
+
+msgid "specify at least one changeset with -r or -o"
+msgstr "veuillez spécifier au minimum un \"changeset\", à l'aide de -r ou -o"
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr ""
+"ne pas spécifier --outgoing, qui est systématiquement activé lorsque --"
+"bundle est utilisé"
+
+msgid "too many destinations"
+msgstr "trop de destinations"
+
+msgid "use only one form to specify the revision"
+msgstr "veuillez ne spécifier les révisions que d'une seule manière"
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series.\n"
+"\n"
+msgstr ""
+"\n"
+"Veuillez écrire le message d'introduction de la série de patchs.\n"
+"\n"
+
+#, python-format
+msgid ""
+"This patch series consists of %d patches.\n"
+"\n"
+msgstr ""
+"Cette série comporte %d patchs.\n"
+"\n"
+
+# diffstat sur l'ensemble des patchs
+msgid "Final summary:\n"
+msgstr "Résumé complet des modifications :\n"
+
+# mode --test
+msgid "Displaying "
+msgstr "Affichage de "
+
+# mode --mbox
+msgid "Writing "
+msgstr "Écriture de "
+
+# mode d'envoi par défaut
+msgid "Sending "
+msgstr "Envoi de "
+
+msgid "send patches as attachments"
+msgstr "envoyer les patchs en tant que pièces jointes"
+
+msgid "send patches as inline attachments"
+msgstr "envoyer les patchs comme pièces insérées dans le corps du message"
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr "adresses électroniques des destinataires en copie carbone invisible"
+
+msgid "email addresses of copy recipients"
+msgstr "adresses électroniques des destinataires en copie carbone"
+
+msgid "add diffstat output to messages"
+msgstr "ajouter un résumé des modifications avec diffstat dans les messages"
+
+msgid "use the given date as the sending date"
+msgstr "utiliser la date fournie comme date d'envoi"
+
+msgid "use the given file as the series description"
+msgstr "lire le message d'introduction à la série dans le fichier fourni"
+
+msgid "email address of sender"
+msgstr "adresse électronique de l'expéditeur"
+
+msgid "print messages that would be sent"
+msgstr "afficher les messages tels qu'ils seraient envoyés"
+
+msgid "write messages to mbox file instead of sending them"
+msgstr ""
+"écrire les messages dans un fichier au format \"mbox\" au lieu de les envoyer"
+
+msgid "subject of first message (intro or single patch)"
+msgstr "sujet du premier message (intro ou patch unique)"
+
+msgid "message identifier to reply to"
+msgstr "identifiant du message auquel répondre"
+
+msgid "email addresses of recipients"
+msgstr "adresses électroniques des destinataires"
+
+msgid "omit hg patch header"
+msgstr "omettre l'en-tête de patch spécifique à Mercurial"
+
+msgid "send changes not found in the target repository"
+msgstr "envoyer les modifications non présentes dans le dépôt cible"
+
+msgid "send changes not in target as a binary bundle"
+msgstr ""
+"envoyer les modifications non présentes dans le dépôt cible sous forme de "
+"\"bundle\" binaire"
+
+msgid "name of the bundle attachment file"
+msgstr "nom à donner au fichier \"bundle\" envoyé"
+
+msgid "a revision to send"
+msgstr "une révision à envoyer"
+
+msgid "run even when remote repository is unrelated (with -b/--bundle)"
+msgstr "procéder même si le dépôt cible n'est pas apparenté (avec -b/--bundle)"
+
+msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
+msgstr ""
+"un \"changeset\" à utiliser comme point de départ, au lieu d'une destination "
+"(avec -b/--bundle)"
+
+msgid "send an introduction email for a single patch"
+msgstr "envoyer un courriel d'introduction pour un patch seul"
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr "hg email [OPTION]... [DEST]..."
+
+msgid "command to delete untracked files from the working directory"
+msgstr ""
+
+msgid ""
+"removes files not tracked by Mercurial\n"
+"\n"
+" Delete files not known to Mercurial. This is useful to test local\n"
+" and uncommitted changes in an otherwise-clean source tree.\n"
+"\n"
+" This means that purge will delete:\n"
+" - Unknown files: files marked with \"?\" by \"hg status\"\n"
+" - Empty directories: in fact Mercurial ignores directories unless\n"
+" they contain files under source control management\n"
+" But it will leave untouched:\n"
+" - Modified and unmodified tracked files\n"
+" - Ignored files (unless --all is specified)\n"
+" - New files added to the repository (with \"hg add\")\n"
+"\n"
+" If directories are given on the command line, only files in these\n"
+" directories are considered.\n"
+"\n"
+" Be careful with purge, as you could irreversibly delete some files\n"
+" you forgot to add to the repository. If you only want to print the\n"
+" list of files that this program would delete, use the --print\n"
+" option.\n"
+" "
+msgstr ""
+"retire les fichiers non suivis par Mercurial\n"
+"\n"
+" Supprime les fichiers non connus de Mercurial, ce qui peut être\n"
+" utile pour tester des changements locaux non enregistrés à\n"
+" l'intérieur d'une arborescence de sources propre.\n"
+"\n"
+" Ainsi, purge effacera :\n"
+" - les fichiers inconnus : fichiers que \"hg status\" indique\n"
+" par un point d'interrogation\n"
+" - les répertoires vides : en fait Mercurial ignore complètement\n"
+" les répertoires, à moins qu'ils ne contiennent des fichiers\n"
+" sous son contrôle\n"
+" Seront par contre laissés intacts :\n"
+" - Les fichiers placés sous contrôle, qu'ils aient été modifiés\n"
+" ou non\n"
+" - Les fichiers ignorés (sauf si --all est utilisé)\n"
+" - Les fichiers nouvellement ajoutés au dépôt (avec \"hg add\")\n"
+"\n"
+" Si des répertoires sont spécifiés sur la ligne de commande,\n"
+" seuls les fichiers qu'ils contiennent seront considérés.\n"
+"\n"
+" Soyez prudent en utilisant purge, si vous avez oublié d'ajouter\n"
+" des fichiers au dépôt, ils seront perdus irrémédiablement.\n"
+" Si vous souhaitez seulement afficher la liste des fichiers qui\n"
+" seraient effacés par purge, utilisez l'option --print.\n"
+" "
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr "%s ne peut être supprimé"
+
+#, python-format
+msgid "warning: %s\n"
+msgstr "attention: %s\n"
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr "Suppression du fichier %s\n"
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr "Suppression du répertoire %s\n"
+
+msgid "abort if an error occurs"
+msgstr "abandonner en cas d'erreur"
+
+msgid "purge ignored files too"
+msgstr "supprimer également les fichiers ignorés"
+
+msgid "print filenames instead of deleting them"
+msgstr "afficher les nom des fichiers au lieu de les supprimer"
+
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr ""
+"terminer les noms de fichiers par un caractère nul, pour utilisation avec "
+"xargs (implique -p/--print)"
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr "hg purge [OPTION]... [RÉPERTOIRE]..."
+
+msgid ""
+"command to move sets of revisions to a different ancestor\n"
+"\n"
+"This extension lets you rebase changesets in an existing Mercurial\n"
+"repository.\n"
+"\n"
+"For more information:\n"
+"http://mercurial.selenic.com/wiki/RebaseProject\n"
+msgstr ""
+
+msgid "first revision, do not change ancestor\n"
+msgstr ""
+
+msgid ""
+"move changeset (and descendants) to a different branch\n"
+"\n"
+" Rebase uses repeated merging to graft changesets from one part of\n"
+" history onto another. This can be useful for linearizing local\n"
+" changes relative to a master development tree.\n"
+"\n"
+" If a rebase is interrupted to manually resolve a merge, it can be\n"
+" continued with --continue/-c or aborted with --abort/-a.\n"
+" "
+msgstr ""
+
+msgid "cannot use both abort and continue"
+msgstr ""
+
+msgid "cannot use collapse with continue or abort"
+msgstr ""
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr ""
+
+msgid "cannot specify both a revision and a base"
+msgstr ""
+
+msgid "nothing to rebase\n"
+msgstr ""
+
+msgid "cannot use both keepbranches and extrafn"
+msgstr ""
+
+msgid "rebase merging completed\n"
+msgstr ""
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr ""
+
+msgid "rebase completed\n"
+msgstr ""
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr ""
+
+msgid " set parents\n"
+msgstr ""
+
+#, python-format
+msgid "rebasing %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid " future parents are %d and %d\n"
+msgstr ""
+
+#, python-format
+msgid " update to %d:%s\n"
+msgstr ""
+
+msgid " already in target\n"
+msgstr ""
+
+#, python-format
+msgid " merge against %d:%s\n"
+msgstr ""
+
+msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgstr ""
+
+msgid "resuming interrupted rebase\n"
+msgstr ""
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr ""
+
+#, python-format
+msgid "next revision set to %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr ""
+
+#, python-format
+msgid "revision %d is an mq patch (%s), finalize it.\n"
+msgstr ""
+
+#, python-format
+msgid "import mq patch %d (%s)\n"
+msgstr ""
+
+msgid "rebase status stored\n"
+msgstr ""
+
+msgid "rebase status resumed\n"
+msgstr ""
+
+msgid "no rebase in progress"
+msgstr ""
+
+msgid "warning: new changesets detected on target branch, not stripping\n"
+msgstr ""
+
+msgid "rebase aborted\n"
+msgstr ""
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr ""
+
+msgid "cannot rebase an ancestor"
+msgstr ""
+
+msgid "cannot rebase a descendant"
+msgstr ""
+
+msgid "already working on current\n"
+msgstr ""
+
+msgid "already working on the current branch\n"
+msgstr ""
+
+#, python-format
+msgid "rebase onto %d starting from %d\n"
+msgstr ""
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr ""
+
+msgid "--update and --rebase are not compatible, ignoring the update flag\n"
+msgstr ""
+
+msgid "rebase working directory to branch head"
+msgstr ""
+
+msgid "rebase from a given revision"
+msgstr ""
+
+msgid "rebase from the base of a given revision"
+msgstr ""
+
+msgid "rebase onto a given revision"
+msgstr ""
+
+msgid "collapse the rebased revisions"
+msgstr ""
+
+msgid "keep original revisions"
+msgstr ""
+
+msgid "keep original branches"
+msgstr ""
+
+msgid "continue an interrupted rebase"
+msgstr ""
+
+msgid "abort an interrupted rebase"
+msgstr ""
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+msgstr ""
+
+msgid "commands to interactively select changes for commit/qrefresh"
+msgstr ""
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr ""
+
+msgid "this is a binary file\n"
+msgstr ""
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr ""
+
+msgid "[Ynsfdaq?]"
+msgstr ""
+
+msgid "&Yes, record this change"
+msgstr ""
+
+msgid "&No, skip this change"
+msgstr ""
+
+msgid "&Skip remaining changes to this file"
+msgstr ""
+
+msgid "Record remaining changes to this &file"
+msgstr ""
+
+msgid "&Done, skip remaining changes and files"
+msgstr ""
+
+msgid "Record &all changes to all remaining files"
+msgstr ""
+
+msgid "&Quit, recording no changes"
+msgstr ""
+
+msgid "&?"
+msgstr ""
+
+msgid "y"
+msgstr ""
+
+msgid "?"
+msgstr ""
+
+msgid "y - record this change"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "f"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "a"
+msgstr ""
+
+msgid "q"
+msgstr ""
+
+msgid "user quit"
+msgstr ""
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr ""
+
+msgid " and "
+msgstr ""
+
+#, python-format
+msgid "record this change to %r?"
+msgstr ""
+
+#, python-format
+msgid "record change %d/%d to %r?"
+msgstr ""
+
+msgid ""
+"interactively select changes to commit\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be candidates for recording.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" You will be prompted for whether to record changes to each\n"
+" modified file, and for files with multiple changes, for each\n"
+" change to use. For each query, the following responses are\n"
+" possible:\n"
+"\n"
+" y - record this change\n"
+" n - skip this change\n"
+"\n"
+" s - skip remaining changes to this file\n"
+" f - record remaining changes to this file\n"
+"\n"
+" d - done, skip remaining changes and files\n"
+" a - record all changes to all remaining files\n"
+" q - quit, recording no changes\n"
+"\n"
+" ? - display help"
+msgstr ""
+
+msgid "'mq' extension not loaded"
+msgstr ""
+
+msgid "running non-interactively, use commit instead"
+msgstr ""
+
+msgid "no changes to record\n"
+msgstr ""
+
+#, python-format
+msgid "backup %r as %r\n"
+msgstr ""
+
+msgid "applying patch\n"
+msgstr ""
+
+msgid "patch failed to apply"
+msgstr ""
+
+#, python-format
+msgid "restoring %r to %r\n"
+msgstr ""
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr ""
+
+msgid "share a common history between several working directories"
+msgstr ""
+
+msgid ""
+"create a new shared repository (experimental)\n"
+"\n"
+" Initialize a new repository and working directory that shares its\n"
+" history with another repository.\n"
+"\n"
+" NOTE: actions that change history such as rollback or moving the\n"
+" source may confuse sharers.\n"
+" "
+msgstr ""
+
+msgid "do not create a working copy"
+msgstr ""
+
+msgid "[-U] SOURCE [DEST]"
+msgstr ""
+
+msgid ""
+"command to transplant changesets from another branch\n"
+"\n"
+"This extension allows you to transplant patches from another branch.\n"
+"\n"
+"Transplanted patches are recorded in .hg/transplant/transplants, as a\n"
+"map from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr ""
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr ""
+
+#, python-format
+msgid "filtering %s\n"
+msgstr ""
+
+msgid "filter failed"
+msgstr ""
+
+msgid "can only omit patchfile if merging"
+msgstr ""
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr ""
+
+msgid "Fix up the merge and run hg transplant --continue"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr ""
+
+msgid "transplant log file is corrupt"
+msgstr ""
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr ""
+
+msgid "commit failed"
+msgstr ""
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr ""
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+" Selected changesets will be applied on top of the current working\n"
+" directory with the log of the original changeset. If --log is\n"
+" specified, log messages will have a comment appended of the form:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" You can rewrite the changelog message with the --filter option.\n"
+" Its argument will be invoked with the current changelog message as\n"
+" $1 and the patch as $2.\n"
+"\n"
+" If --source/-s is specified, selects changesets from the named\n"
+" repository. If --branch/-b is specified, selects changesets from\n"
+" the branch holding the named revision, up to that revision. If\n"
+" --all/-a is specified, all changesets on the branch will be\n"
+" transplanted, otherwise you will be prompted to select the\n"
+" changesets you want.\n"
+"\n"
+" hg transplant --branch REVISION --all will rebase the selected\n"
+" branch (up to the named revision) onto your current working\n"
+" directory.\n"
+"\n"
+" You can optionally mark selected transplanted changesets as merge\n"
+" changesets. You will not be prompted to transplant any ancestors\n"
+" of a merged transplant, and you can merge descendants of them\n"
+" normally instead of transplanting them.\n"
+"\n"
+" If no merges or revisions are provided, hg transplant will start\n"
+" an interactive changeset browser.\n"
+"\n"
+" If a changeset application fails, you can fix the merge by hand\n"
+" and then resume where you left off by calling hg transplant\n"
+" --continue/-c.\n"
+" "
+msgstr ""
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr ""
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr ""
+
+msgid "--all requires a branch revision"
+msgstr ""
+
+msgid "--all is incompatible with a revision list"
+msgstr ""
+
+msgid "no revision checked out"
+msgstr ""
+
+msgid "outstanding uncommitted merges"
+msgstr ""
+
+msgid "outstanding local changes"
+msgstr ""
+
+msgid "pull patches from REPOSITORY"
+msgstr ""
+
+msgid "pull patches from branch BRANCH"
+msgstr ""
+
+msgid "pull all changesets up to BRANCH"
+msgstr ""
+
+msgid "skip over REV"
+msgstr ""
+
+msgid "merge at REV"
+msgstr ""
+
+msgid "append transplant info to log message"
+msgstr ""
+
+msgid "continue last transplant session after repair"
+msgstr ""
+
+msgid "filter changesets through FILTER"
+msgstr ""
+
+msgid ""
+"hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr ""
+
+msgid ""
+"allow the use of MBCS paths with problematic encodings\n"
+"\n"
+"Some MBCS encodings are not good for some path operations (i.e.\n"
+"splitting path, case conversion, etc.) with its encoded bytes. We call\n"
+"such a encoding (i.e. shift_jis and big5) as \"problematic encoding\".\n"
+"This extension can be used to fix the issue with those encodings by\n"
+"wrapping some functions to convert to Unicode string before path\n"
+"operation.\n"
+"\n"
+"This extension is useful for:\n"
+" * Japanese Windows users using shift_jis encoding.\n"
+" * Chinese Windows users using big5 encoding.\n"
+" * All users who use a repository with one of problematic encodings on\n"
+" case-insensitive file system.\n"
+"\n"
+"This extension is not needed for:\n"
+" * Any user who use only ASCII chars in path.\n"
+" * Any user who do not use any of problematic encodings.\n"
+"\n"
+"Note that there are some limitations on using this extension:\n"
+" * You should use single encoding in one repository.\n"
+" * You should set same encoding for the repository by locale or\n"
+" HGENCODING.\n"
+"\n"
+"Path encoding conversion are done between Unicode and\n"
+"encoding.encoding which is decided by Mercurial from current locale\n"
+"setting or HGENCODING.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] filename conversion fail with %s encoding\n"
+msgstr ""
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] activated with encoding: %s\n"
+msgstr ""
+
+msgid ""
+"perform automatic newline conversion\n"
+"\n"
+"To perform automatic newline conversion, use:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = cleverencode:\n"
+"# or ** = macencode:\n"
+"\n"
+"[decode]\n"
+"** = cleverdecode:\n"
+"# or ** = macdecode:\n"
+"\n"
+"If not doing conversion, to make sure you do not commit CRLF/CR by "
+"accident:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxncommit.cr = python:hgext.win32text.forbidcr\n"
+"\n"
+"To do the same check on a server to prevent CRLF/CR from being\n"
+"pushed or pulled:\n"
+"\n"
+"[hooks]\n"
+"pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxnchangegroup.cr = python:hgext.win32text.forbidcr\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr ""
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"and also consider adding:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+
+msgid ""
+"discover and advertise repositories on the local network\n"
+"\n"
+"Zeroconf enabled repositories will be announced in a network without\n"
+"the need to configure a server or a service. They can be discovered\n"
+"without knowing their actual IP address.\n"
+"\n"
+"To allow other people to discover your repository using run \"hg serve\"\n"
+"in your repository.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"You can discover zeroconf enabled repositories by running \"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+msgstr ""
+"découverte et annonce de dépôts sur le réseau local\n"
+"\n"
+"Les dépôts utilisant zeroconf seront visibles sur le réseau sans\n"
+"qu'il n'y ait besoin de configurer un serveur ou service\n"
+"particuliers, et ils peuvent être accédés simplement, sans\n"
+"connaissance de leur adresse IP.\n"
+"\n"
+"Pour permettre à d'autres personnes de découvrir votre dépôt,\n"
+"lancez-y la commande \"hg serve\" :\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"Vous pouvez découvrir les dépôts utilisant zeroconf en utilisant\n"
+"la commande \"hg paths\", par exemple :\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+
+msgid "archive prefix contains illegal components"
+msgstr "le préfixe donné pour l'archive contient des composants non autorisés"
+
+msgid "cannot give prefix when archiving to files"
+msgstr ""
+"impossible de donner un préfixe pour une création d'archive vers un "
+"répertoire (de type \"files\")"
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr "type d'archive inconnu : '%s'"
+
+msgid "invalid changegroup"
+msgstr ""
+
+msgid "unknown parent"
+msgstr ""
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr ""
+
+#, python-format
+msgid "%s: not a Mercurial bundle file"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle version"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle compression type"
+msgstr ""
+
+msgid "cannot create new bundle repository"
+msgstr ""
+
+#, python-format
+msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgstr ""
+
+msgid "empty username"
+msgstr "le nom d'utilisateur est vide"
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr "le nom d'utilisateur %s contient un saut de ligne"
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr "les options --message et --logfile s'excluent mutuellement"
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr ""
+
+msgid "limit must be a positive integer"
+msgstr "la limite spécifiée doit être un entier positif"
+
+msgid "limit must be positive"
+msgstr "la limite doit être positive"
+
+msgid "too many revisions specified"
+msgstr "trop de révisions spécifiées"
+
+#, python-format
+msgid "invalid format spec '%%%s' in output filename"
+msgstr ""
+"'%%%s'spécification de format invalide dans le nom du fichier de sortie"
+
+#, python-format
+msgid "adding %s\n"
+msgstr "ajout de %s\n"
+
+#, python-format
+msgid "removing %s\n"
+msgstr "suppression de %s\n"
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr ""
+"suppression de %s plannifiée, en tant que renommage de %s (similaire à %d%"
+"%)\n"
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr "%s: le fichier n'est pas suivi, pas de copie\n"
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr "%s: le fichier a été marqué pour suppression, pas de copie\n"
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr "%s: %s entre en collision avec %s, pas d'écrasement\n"
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr "%s: le fichier existe, pas d'écrasement\n"
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr "%s: supprimé dans la copie de travail\n"
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr "%s: impossible de copier - %s\n"
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr "déplacement de %s vers %s\n"
+
+#, python-format
+msgid "copying %s to %s\n"
+msgstr "copie de %s vers %s\n"
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+
+msgid "no source or destination specified"
+msgstr ""
+
+msgid "no destination specified"
+msgstr ""
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr ""
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr ""
+
+msgid "no files to copy"
+msgstr ""
+
+msgid "(consider using --after)\n"
+msgstr ""
+
+#, python-format
+msgid "changeset: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "branch: %s\n"
+msgstr ""
+
+#, python-format
+msgid "tag: %s\n"
+msgstr ""
+
+#, python-format
+msgid "parent: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "manifest: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "user: %s\n"
+msgstr ""
+
+#, python-format
+msgid "date: %s\n"
+msgstr ""
+
+msgid "files+:"
+msgstr ""
+
+msgid "files-:"
+msgstr ""
+
+msgid "files:"
+msgstr ""
+
+#, python-format
+msgid "files: %s\n"
+msgstr ""
+
+#, python-format
+msgid "copies: %s\n"
+msgstr ""
+
+#, python-format
+msgid "extra: %s=%s\n"
+msgstr ""
+
+msgid "description:\n"
+msgstr ""
+
+#, python-format
+msgid "summary: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr ""
+
+#, python-format
+msgid "%s: %s"
+msgstr ""
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr ""
+
+msgid "revision matching date not found"
+msgstr ""
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "%s:%s copy source revision cannot be found!\n"
+msgstr ""
+
+msgid "can only follow copies/renames for explicit filenames"
+msgstr ""
+
+msgid "HG: Enter commit message. Lines beginning with 'HG:' are removed."
+msgstr ""
+
+msgid "HG: Leave message empty to abort commit."
+msgstr ""
+
+#, python-format
+msgid "HG: user: %s"
+msgstr ""
+
+msgid "HG: branch merge"
+msgstr ""
+
+#, python-format
+msgid "HG: branch '%s'"
+msgstr ""
+
+#, python-format
+msgid "HG: subrepo %s"
+msgstr ""
+
+#, python-format
+msgid "HG: added %s"
+msgstr ""
+
+#, python-format
+msgid "HG: changed %s"
+msgstr ""
+
+#, python-format
+msgid "HG: removed %s"
+msgstr ""
+
+msgid "HG: no files changed"
+msgstr ""
+
+msgid "empty commit message"
+msgstr ""
+
+msgid ""
+"add the specified files on the next commit\n"
+"\n"
+" Schedule files to be version controlled and added to the\n"
+" repository.\n"
+"\n"
+" The files will be added to the repository at the next commit. To\n"
+" undo an add before that, see hg forget.\n"
+"\n"
+" If no names are given, add all files to the repository.\n"
+" "
+msgstr ""
+
+msgid ""
+"add all new files, delete all missing files\n"
+"\n"
+" Add all new files and remove all missing files from the\n"
+" repository.\n"
+"\n"
+" New files are ignored if they match any of the patterns in\n"
+" .hgignore. As with add, these changes take effect at the next\n"
+" commit.\n"
+"\n"
+" Use the -s/--similarity option to detect renamed files. With a\n"
+" parameter > 0, this compares every removed file with every added\n"
+" file and records those similar enough as renames. This option\n"
+" takes a percentage between 0 (disabled) and 100 (files must be\n"
+" identical) as its parameter. Detecting renamed files this way can\n"
+" be expensive.\n"
+" "
+msgstr ""
+
+msgid "similarity must be a number"
+msgstr ""
+
+msgid "similarity must be between 0 and 100"
+msgstr ""
+
+msgid ""
+"show changeset information by line for each file\n"
+"\n"
+" List changes in files, showing the revision id responsible for\n"
+" each line\n"
+"\n"
+" This command is useful for discovering when a change was made and\n"
+" by whom.\n"
+"\n"
+" Without the -a/--text option, annotate will avoid processing files\n"
+" it detects as binary. With -a, annotate will annotate the file\n"
+" anyway, although the results will probably be neither useful\n"
+" nor desirable.\n"
+" "
+msgstr ""
+
+msgid "at least one filename or pattern is required"
+msgstr ""
+
+msgid "at least one of -n/-c is required for -l"
+msgstr ""
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr ""
+
+msgid ""
+"create an unversioned archive of a repository revision\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use -r/--rev to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use -t/--type. Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see 'hg help export' for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use -p/--prefix to specify a format string for the\n"
+" prefix. The default is the basename of the archive, with suffixes\n"
+" removed.\n"
+" "
+msgstr ""
+"crée une archive du dépôt à une révision donnée, sans conserver "
+"l'historique\n"
+"\n"
+" Par défaut l'archive est créée à partir de la révision parente\n"
+" du répertoire de travail. Une autre révision peut être spécifiée\n"
+" à l'aide de -r/--rev.\n"
+"\n"
+" -t/--type permet de spécifier le type d'archive à créer, parmi :\n"
+"\n"
+" \"files\" (par défaut) : un répertoire rempli de fichiers\n"
+" \"tar\" : une archive tar non compressée\n"
+" \"tbz2\" : une archive tar compressée avec bzip2\n"
+" \"tgz\" : une archive tar compressée avec gzip\n"
+" \"uzip\" : une archive zip non compressée\n"
+" \"zip\" : une archive zip compressée avec l'algorithme deflate\n"
+"\n"
+" Le nom exact de l'archive ou du répertoire de destination est\n"
+" donné à l'aide d'une chaîne de format. Consulter 'hg help export'\n"
+" pour plus de détails.\n"
+"\n"
+" Un chemin relatif est ajouté devant chaque membre de l'archive,\n"
+" par défaut le nom du fichier d'archive (sans répertoires ni\n"
+" suffixes). Un préfixe différent peut être spécifié avec\n"
+" -p/--prefix.\n"
+" "
+
+msgid "no working directory: please specify a revision"
+msgstr "pas de répertoire de travail, veuillez spécifier une révision"
+
+msgid "repository root cannot be destination"
+msgstr "le répertoire racine ne peut servir de destination"
+
+msgid "cannot archive plain files to stdout"
+msgstr ""
+"impossible d'envoyer une archive de simples fichiers vers la sortie standard"
+
+msgid ""
+"reverse effect of earlier changeset\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you backout a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head.\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by hand.\n"
+" The result of this merge is not committed, as with a normal merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "please specify just one revision"
+msgstr ""
+
+msgid "please specify a revision to backout"
+msgstr ""
+
+msgid "cannot backout change on a different branch"
+msgstr ""
+
+msgid "cannot backout a change with no parents"
+msgstr ""
+
+msgid "cannot backout a merge changeset without --parent"
+msgstr ""
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr ""
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr ""
+
+#, python-format
+msgid "Backed out changeset %s"
+msgstr ""
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr ""
+
+msgid "the backout changeset is a new head - do not forget to merge\n"
+msgstr ""
+
+msgid "(use \"backout --merge\" if you want to auto-merge)\n"
+msgstr ""
+
+msgid ""
+"subdivision search of changesets\n"
+"\n"
+" This command helps to find changesets which introduce problems. To\n"
+" use, mark the earliest changeset you know exhibits the problem as\n"
+" bad, then mark the latest changeset which is free from the problem\n"
+" as good. Bisect will update your working directory to a revision\n"
+" for testing (unless the -U/--noupdate option is specified). Once\n"
+" you have performed tests, mark the working directory as good or\n"
+" bad, and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command, it will be used for automatic bisection.\n"
+" Its exit status will be used to mark revisions as good or bad:\n"
+" status 0 means good, 125 means to skip the revision, 127\n"
+" (command not found) will abort the bisection, and any other\n"
+" non-zero exit status means the revision is bad.\n"
+" "
+msgstr ""
+"recherche de \"changesets\" par dichotomie\n"
+"\n"
+" Cette commande aide à trouver les \"changesets\" étant à\n"
+" l'origine de problèmes. Pour l'utiliser, marquez comme étant\n"
+" mauvaise la première révision pour laquelle vous avez relevé les\n"
+" symptômes, puis comme bonne la dernière révision connue pour\n"
+" être exempte du problème. Bisect va alors mettre à jour votre\n"
+" répertoire de travail à une révision à tester (à moins que\n"
+" -U/--noupdate n'ait été spécifié). Une fois vos tests réalisés,\n"
+" indiquez si le problème était présent ou non. Bisect\n"
+" recommencera alors pour une autre révision candidate jusqu'à\n"
+" être en mesure d'annoncer la révision fautive.\n"
+"\n"
+" Vous pouvez aussi passer une révision en argument lors du\n"
+" marquage afin d'éviter l'étape manuelle de mise à jour du\n"
+" répertoire de travail à cette révision.\n"
+"\n"
+" Vous pouvez fournir une commande pour automatiser la recherche\n"
+" par dichotomie. Son code de retour sera utilisé pour marquer les\n"
+" révisions : 0 indique une révision sans problème, 125 qu'il ne\n"
+" faut pas prendre cette révision en compte, 127 (commande\n"
+" introuvable) cause l'abandon du processus de recherche, et tout\n"
+" autre code de retour non nul désigne une révision affectée par\n"
+" le problème.\n"
+" "
+
+msgid "The first good revision is:\n"
+msgstr "La première révision exempte du problème est :\n"
+
+msgid "The first bad revision is:\n"
+msgstr "La première révision présentant le problème est :\n"
+
+msgid "Due to skipped revisions, the first good revision could be any of:\n"
+msgstr ""
+"Certaines révisions n'ayant pas été considérées, la première révision\n"
+"exempte du problème pourrait être parmi :\n"
+
+msgid "Due to skipped revisions, the first bad revision could be any of:\n"
+msgstr ""
+"Certaines révisions n'ayant pas été considérées, la première révision\n"
+"présentant le problème pourrait être parmi :\n"
+
+msgid "cannot bisect (no known good revisions)"
+msgstr "dichotomie impossible (pas de bonne révision connue)"
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr "dichotomie impossible (pas de mauvaise révision connue)"
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr "('hg bisect <cmd>' ne devrait plus être utilisé)\n"
+
+msgid "incompatible arguments"
+msgstr "arguments incompatibles"
+
+#, python-format
+msgid "cannot find executable: %s"
+msgstr "exécutable %s introuvable"
+
+#, python-format
+msgid "failed to execute %s"
+msgstr "impossible d'exécuter %s"
+
+#, python-format
+msgid "%s killed"
+msgstr "%s a été tué"
+
+#, python-format
+msgid "Changeset %d:%s: %s\n"
+msgstr "\"Changeset\" %d:%s: %s\n"
+
+#, python-format
+msgid "Testing changeset %s:%s (%s changesets remaining, ~%s tests)\n"
+msgstr "Test du \"changeset\" %s:%s (%s \"changesets\" restant, ~%s tests)\n"
+
+msgid ""
+"set or show the current branch name\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch will not exist\n"
+" in the repository until the next commit). Standard practice\n"
+" recommends that primary development take place on the 'default'\n"
+" branch.\n"
+"\n"
+" Unless -f/--force is specified, branch will not let you set a\n"
+" branch name that already exists, even if it's inactive.\n"
+"\n"
+" Use -C/--clean to reset the working directory branch to that of\n"
+" the parent of the working directory, negating a previous branch\n"
+" change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch. Use\n"
+" 'hg commit --close-branch' to mark this branch as closed.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr ""
+
+msgid "a branch of the same name already exists (use --force to override)"
+msgstr ""
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr ""
+
+msgid ""
+"list repository named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If -c/--closed is specified, also list branches which have\n"
+" been marked closed (see hg commit --close-branch).\n"
+"\n"
+" If -a/--active is specified, only show active branches. A branch\n"
+" is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+
+msgid ""
+"create a changegroup file\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" -a/--all (or --base null).\n"
+"\n"
+" You can change compression method with the -t/--type option.\n"
+" The available compression methods are: none, bzip2, and\n"
+" gzip (by default, bundles are compressed using bzip2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means\n"
+" and applied to another repository with the unbundle or pull\n"
+" command. This is useful when direct push and pull are not\n"
+" available or when exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+msgstr ""
+
+msgid "--base is incompatible with specifying a destination"
+msgstr ""
+
+msgid "unknown bundle type specified with --type"
+msgstr ""
+
+msgid ""
+"output the current or given revision of files\n"
+"\n"
+" Print the specified files as they were at the given revision. If\n"
+" no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repository root\n"
+" %p root-relative path name of file being printed\n"
+" "
+msgstr ""
+
+msgid ""
+"make a copy of an existing repository\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" If you use the -r/--rev option to clone up to a specific revision,\n"
+" no subsequent revisions (including subsequent tags) will be\n"
+" present in the cloned repository. This option implies --pull, even\n"
+" on local repositories.\n"
+"\n"
+" By default, clone will check out the head of the 'default' branch.\n"
+" If the -U/--noupdate option is used, the new clone will contain\n"
+" only a repository (.hg) and no working copy (the working copy\n"
+" parent is the null revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Please see 'hg help urls' for important details about ssh:// URLs.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"commit the specified files or all outstanding changes\n"
+"\n"
+" Commit changes to the given files into the repository. Unlike a\n"
+" centralized RCS, this operation is a local operation. See hg push\n"
+" for a way to actively distribute your changes.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" filenames or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is\n"
+" started to prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "nothing changed\n"
+msgstr ""
+
+msgid "created new head\n"
+msgstr ""
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr ""
+
+msgid ""
+"mark files as copied for the next commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr ""
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr ""
+
+msgid "either two or three arguments required"
+msgstr ""
+
+msgid "returns the completion list associated with the given command"
+msgstr ""
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr ""
+
+msgid "validate the correctness of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr ""
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr ""
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr ""
+
+msgid ""
+"show combined config settings from all hgrc files\n"
+"\n"
+" With no arguments, print names and values of all config items.\n"
+"\n"
+" With one argument of the form section.name, print just the value\n"
+" of that config item.\n"
+"\n"
+" With multiple arguments, print names and values of all config\n"
+" items with matching section names.\n"
+"\n"
+" With --debug, the source (filename and line number) is printed\n"
+" for each config item.\n"
+" "
+msgstr ""
+
+msgid "only one config item permitted"
+msgstr ""
+
+msgid ""
+"manually set the parents of the current working directory\n"
+"\n"
+" This is useful for writing repository conversion tools, but should\n"
+" be used with care.\n"
+" "
+msgstr ""
+
+msgid "show the contents of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr ""
+
+msgid "dump the contents of a data file revision"
+msgstr ""
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr ""
+
+msgid "parse and display a date"
+msgstr ""
+
+msgid "dump the contents of an index file"
+msgstr ""
+
+msgid "dump an index DAG as a graphviz dot file"
+msgstr ""
+
+msgid "test Mercurial installation"
+msgstr ""
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr ""
+
+msgid " (check that your locale is properly set)\n"
+msgstr ""
+
+msgid "Checking extensions...\n"
+msgstr ""
+
+msgid " One or more extensions could not be found"
+msgstr ""
+
+msgid " (check that you compiled the extensions)\n"
+msgstr ""
+
+msgid "Checking templates...\n"
+msgstr ""
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr ""
+
+msgid "Checking patch...\n"
+msgstr ""
+
+msgid " patch call failed:\n"
+msgstr ""
+
+msgid " unexpected patch output!\n"
+msgstr ""
+
+msgid " patch test failed!\n"
+msgstr ""
+
+msgid ""
+" (Current patch tool may be incompatible with patch, or misconfigured. "
+"Please check your .hgrc file)\n"
+msgstr ""
+
+msgid ""
+" Internal patcher failure, please report this error to http://mercurial."
+"selenic.com/bts/\n"
+msgstr ""
+
+msgid "Checking commit editor...\n"
+msgstr ""
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr ""
+
+msgid " (specify a commit editor in your .hgrc file)\n"
+msgstr ""
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr ""
+
+msgid "Checking username...\n"
+msgstr ""
+
+msgid " (specify a username in your .hgrc file)\n"
+msgstr ""
+
+msgid "No problems detected\n"
+msgstr ""
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr ""
+
+msgid "dump rename information"
+msgstr ""
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr ""
+
+msgid "show how files match on given patterns"
+msgstr ""
+
+msgid ""
+"diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a/--text option, diff will avoid generating diffs of\n"
+" files it detects as binary. With -a, diff will generate a diff\n"
+" anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. For more information, read 'hg help diffs'.\n"
+" "
+msgstr ""
+
+msgid ""
+"dump the header and diffs for one or more changesets\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a/--text option, export will avoid generating diffs\n"
+" of files it detects as binary. With -a, export will generate a\n"
+" diff anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. See 'hg help diffs' for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the\n"
+" second parent. It can be useful to review a merge.\n"
+" "
+msgstr ""
+
+msgid "export requires at least one changeset"
+msgstr ""
+
+msgid "exporting patches:\n"
+msgstr ""
+
+msgid "exporting patch:\n"
+msgstr ""
+
+msgid ""
+"forget the specified files on the next commit\n"
+"\n"
+" Mark the specified files so they will no longer be tracked\n"
+" after the next commit.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history, and it does not delete them from the\n"
+" working directory.\n"
+"\n"
+" To undo a forget before the next commit, see hg add.\n"
+" "
+msgstr ""
+
+msgid "no files specified"
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file is already untracked\n"
+msgstr ""
+
+msgid ""
+"search for a pattern in specified files and revisions\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which a\n"
+" match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr ""
+
+msgid ""
+"show current repository heads or show branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" If one or more REV is given, the \"branch heads\" will be shown for\n"
+" the named branch associated with that revision. The name of the\n"
+" branch is called the revision's branch tag.\n"
+"\n"
+" Branch heads are revisions on a given named branch that do not have\n"
+" any descendants on the same branch. A branch head could be a true head\n"
+" or it could be the last changeset on a branch before a new branch\n"
+" was created. If none of the branch heads are true heads, the branch\n"
+" is considered inactive. If -c/--closed is specified, also show branch\n"
+" heads marked closed (see hg commit --close-branch).\n"
+"\n"
+" If STARTREV is specified only those heads (or branch heads) that\n"
+" are descendants of STARTREV will be displayed.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "no open branch heads on branch %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes on branch %s containing %s are reachable from %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes on branch %s are reachable from %s\n"
+msgstr ""
+
+msgid ""
+"show help for a given topic or a help overview\n"
+"\n"
+" With no arguments, print a list of commands with short help messages.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that\n"
+" topic."
+msgstr ""
+
+msgid "global options:"
+msgstr "options globales :"
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr "utiliser \"hg help\" pour la liste complète des commandes"
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr ""
+"utiliser \"hg help\" pour la liste complète des commandes ou \"hg -v\" pour "
+"plus de détails"
+
+# la chaîne passée est préfixée par un espace
+#, python-format
+msgid "use \"hg -v help%s\" to show aliases and global options"
+msgstr ""
+"utiliser \"hg -v help%s\" pour afficher les alias et les options globales"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "utiliser \"hg -v help %s\" pour afficher les options globales"
+
+msgid ""
+"list of commands:\n"
+"\n"
+msgstr ""
+"liste des commandes :\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"alias : %s\n"
+
+msgid "(no help text available)"
+msgstr "(pas d'aide disponible)"
+
+msgid "options:\n"
+msgstr "options :\n"
+
+msgid "no commands defined\n"
+msgstr "pas de commandes définies\n"
+
+msgid "enabled extensions:"
+msgstr "extensions activées :"
+
+msgid "no help text available"
+msgstr "pas d'aide disponible"
+
+#, python-format
+msgid "%s extension - %s\n"
+msgstr "extension %s - %s\n"
+
+msgid "Mercurial Distributed SCM\n"
+msgstr "Mercurial, système de gestion de sources distribué\n"
+
+msgid ""
+"basic commands:\n"
+"\n"
+msgstr ""
+"commandes de base :\n"
+"\n"
+
+msgid ""
+"\n"
+"additional help topics:\n"
+"\n"
+msgstr ""
+"\n"
+"sujets d'aide supplémentaires :\n"
+"\n"
+
+msgid ""
+"identify the working copy or specified revision\n"
+"\n"
+" With no revision, print a summary of the current state of the\n"
+" repository.\n"
+"\n"
+" Specifying a path to a repository root or Mercurial bundle will\n"
+" cause lookup to operate on that repository/bundle.\n"
+"\n"
+" This summary identifies the repository state using one or two\n"
+" parent hash identifiers, followed by a \"+\" if there are\n"
+" uncommitted changes in the working directory, a list of tags for\n"
+" this revision and a branch name for non-default branches.\n"
+" "
+msgstr ""
+
+msgid ""
+"import an ordered set of patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f/--force flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (to use the body part, it must have type\n"
+" text/plain or text/x-patch). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and\n"
+" description from patch override values from message headers and\n"
+" body. Values given on command line with -m/--message and -u/--user\n"
+" override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory to\n"
+" the parent of each patch before applying it, and will abort if the\n"
+" resulting changeset has a different ID than the one recorded in\n"
+" the patch. This may happen due to character set problems or other\n"
+" deficiencies in the text patch format.\n"
+"\n"
+" With -s/--similarity, hg will attempt to discover renames and\n"
+" copies in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use \"-\" as the patch name. If\n"
+" a URL is specified, the patch will be downloaded from it.\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "applying patch from stdin\n"
+msgstr ""
+
+msgid "no diffs found"
+msgstr ""
+
+#, python-format
+msgid ""
+"message:\n"
+"%s\n"
+msgstr ""
+
+msgid "not a Mercurial patch"
+msgstr ""
+
+msgid "patch is damaged or loses information"
+msgstr ""
+
+msgid ""
+"show new changesets found in source\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would have been pulled\n"
+" if a pull at the time you issued this command.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the\n"
+" changesets twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+msgstr ""
+
+msgid ""
+"create a new repository in the given directory\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it will be created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+msgid ""
+"locate files matching specific patterns\n"
+"\n"
+" Print files under Mercurial control in the working directory whose\n"
+" names match the given patterns.\n"
+"\n"
+" By default, this command searches all directories in the working\n"
+" directory. To search just the current directory and its\n"
+" subdirectories, use \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints the names\n"
+" of all files under Mercurial control in the working directory.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the -0 option to both this command and \"xargs\". This\n"
+" will avoid the problem of \"xargs\" treating single filenames that\n"
+" contain whitespace as multiple filenames.\n"
+" "
+msgstr ""
+
+msgid ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a filename to follow history across\n"
+" renames and copies. --follow without a filename will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command prints revision number and changeset id,\n"
+" tags, non-trivial parents, user, date and time, and a summary for\n"
+" each commit. When the -v/--verbose switch is used, the list of\n"
+" changed files and full commit message are shown.\n"
+"\n"
+" NOTE: log -p/--patch may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, only files different from BOTH parents\n"
+" will appear in files:.\n"
+" "
+msgstr ""
+
+msgid ""
+"output the current or given revision of the project manifest\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the first parent of the working directory\n"
+" is used, or the null revision if no revision is checked out.\n"
+"\n"
+" With -v, print file permissions, symlink and executable bits.\n"
+" With --debug, print file revision hashes.\n"
+" "
+msgstr ""
+
+msgid ""
+"merge working directory with another revision\n"
+"\n"
+" The current working directory is updated with all changes made in\n"
+" the requested revision since the last common predecessor revision.\n"
+"\n"
+" Files that changed between either parent are marked as changed for\n"
+" the next commit and a commit must be performed before any further\n"
+" updates to the repository are allowed. The next commit will have\n"
+" two parents.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other\n"
+" head, the other head is merged with by default. Otherwise, an\n"
+" explicit revision with which to merge with must be provided.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr ""
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr ""
+
+msgid "there is nothing to merge"
+msgstr ""
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr ""
+
+msgid ""
+"working dir not at a head rev - use \"hg update\" or merge with an explicit "
+"rev"
+msgstr ""
+
+msgid ""
+"show changesets not found in destination\n"
+"\n"
+" Show changesets not found in the specified destination repository\n"
+" or the default push location. These are the changesets that would\n"
+" be pushed if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+msgstr ""
+
+msgid ""
+"show the parents of the working directory or revision\n"
+"\n"
+" Print the working directory's parent revisions. If a revision is\n"
+" given via -r/--rev, the parent of that revision will be printed.\n"
+" If a file argument is given, the revision in which the file was\n"
+" last changed (before the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+
+msgid "can only specify an explicit filename"
+msgstr ""
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr ""
+
+msgid ""
+"show aliases for remote repositories\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given,\n"
+" show definition of all available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+msgid "not found!\n"
+msgstr ""
+
+msgid "not updating, since new heads added\n"
+msgstr ""
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr ""
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr ""
+
+msgid ""
+"pull changes from the specified source\n"
+"\n"
+" Pull changes from a remote repository to a local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to a local repository (the current one unless\n"
+" -R is specified). By default, this does not update the copy of the\n"
+" project in the working directory.\n"
+"\n"
+" Use hg incoming if you want to see what would have been added by a\n"
+" pull at the time you issued this command. If you then decide to\n"
+" added those changes to the repository, you should use pull -r X\n"
+" where X is the last changeset listed by hg incoming.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+msgid ""
+"push changes to the specified destination\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It moves changes from\n"
+" the current repository to a different one. If the destination is\n"
+" local this is identical to a pull in that directory from the\n"
+" current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" user forgot to pull and merge before pushing.\n"
+"\n"
+" If -r/--rev is used, the named revision and all its ancestors will\n"
+" be pushed to the remote repository.\n"
+"\n"
+" Please see 'hg help urls' for important details about ssh://\n"
+" URLs. If DESTINATION is omitted, a default path will be used.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr ""
+
+msgid ""
+"roll back an interrupted transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an\n"
+" interrupted operation. It should only be necessary when Mercurial\n"
+" suggests it.\n"
+" "
+msgstr ""
+
+msgid ""
+"remove the specified files on the next commit\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history. -A/--after can be used to remove only\n"
+" files that have already been deleted, -f/--force can be used to\n"
+" force deletion, and -Af can be used to remove files from the next\n"
+" revision without deleting them from the working directory.\n"
+"\n"
+" The following table details the behavior of remove for different\n"
+" file states (columns) and option combinations (rows). The file\n"
+" states are Added [A], Clean [C], Modified [M] and Missing [!]\n"
+" (as reported by hg status). The actions are Warn, Remove (from\n"
+" branch) and Delete (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file is untracked\n"
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file %s (use -f to force removal)\n"
+msgstr ""
+
+msgid "still exists"
+msgstr ""
+
+msgid "is modified"
+msgstr ""
+
+msgid "has been marked for add"
+msgstr ""
+
+msgid ""
+"rename files; equivalent of copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If dest\n"
+" is a directory, copies are put in that directory. If dest is a\n"
+" file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid ""
+"retry file merges from a merge or update\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a/--all switch.\n"
+"\n"
+" If a conflict is resolved manually, please note that the changes\n"
+" will be overwritten if the merge is retried with resolve. The\n"
+" -m/--mark switch should be used to mark the file as resolved.\n"
+"\n"
+" This command also allows listing resolved files and manually\n"
+" indicating whether or not files are resolved. All files must be\n"
+" marked as resolved before a commit is permitted.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+msgstr ""
+
+msgid "too many options specified"
+msgstr ""
+
+msgid "can't specify --all and patterns"
+msgstr ""
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr ""
+
+msgid ""
+"restore individual files or directories to an earlier state\n"
+"\n"
+" (Use update -r to check out earlier revisions, revert does not\n"
+" change the working directory parents.)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r/--rev option, revert the given files or directories\n"
+" to their contents as of a specific revision. This can be helpful\n"
+" to \"roll back\" some or all of an earlier change. See 'hg help\n"
+" dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable mode\n"
+" of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+msgstr ""
+
+msgid "you can't specify a revision and a date"
+msgstr ""
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr ""
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr ""
+
+#, python-format
+msgid "reverting %s\n"
+msgstr ""
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr ""
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr ""
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr ""
+
+msgid ""
+"roll back the last transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time. This command does not alter\n"
+" the working directory.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+msgstr ""
+
+msgid ""
+"print the root (top) of the current working directory\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+msgstr ""
+
+msgid ""
+"export the repository via HTTP\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+" files.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr ""
+
+msgid ""
+"show changed files in the working directory\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" the source of a copy/move operation, are not listed unless\n"
+" -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.\n"
+" Unless options described with \"show only ...\" are given, the\n"
+" options -mardu are used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/--ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the differences between them are\n"
+" shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = missing (deleted by non-hg command, but still tracked)\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = origin of the previous file listed as A (added)\n"
+" "
+msgstr ""
+
+msgid ""
+"add one or more tags for the current or given revision\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is\n"
+" used, or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "tag names must be unique"
+msgstr ""
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr ""
+
+msgid "--rev and --remove are incompatible"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' is not a global tag"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' is not a local tag"
+msgstr ""
+
+#, python-format
+msgid "Removed tag %s"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr ""
+
+#, python-format
+msgid "Added tag %s for changeset %s"
+msgstr ""
+
+msgid ""
+"list repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose\n"
+" switch is used, a third column \"local\" is printed for local tags.\n"
+" "
+msgstr ""
+
+msgid ""
+"show the tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the changeset\n"
+" most recently added to the repository (and therefore the most\n"
+" recently changed head).\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+msgstr ""
+
+msgid ""
+"apply one or more changegroup files\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+msgstr ""
+
+msgid ""
+"update working directory\n"
+"\n"
+" Update the repository's working directory to the specified\n"
+" revision, or the tip of the current branch if none is specified.\n"
+" Use null as the revision to remove the working copy (like 'hg\n"
+" clone -U').\n"
+"\n"
+" When the working directory contains no uncommitted changes, it\n"
+" will be replaced by the state of the requested revision from the\n"
+" repository. When the requested revision is on a different branch,\n"
+" the working directory will additionally be switched to that\n"
+" branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C/--clean to\n"
+" discard them, forcibly replacing the state of the working\n"
+" directory with the requested revision. Alternately, use -c/--check\n"
+" to abort.\n"
+"\n"
+" When there are uncommitted changes and option -C/--clean is not\n"
+" used, and the parent revision and requested revision are on the\n"
+" same branch, and one of them is an ancestor of the other, then the\n"
+" new working directory will contain the requested revision merged\n"
+" with the uncommitted changes. Otherwise, the update will fail with\n"
+" a suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use\n"
+" revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "uncommitted local changes"
+msgstr ""
+
+msgid ""
+"verify the integrity of the repository\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+msgstr ""
+
+msgid "output version and copyright information"
+msgstr ""
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr ""
+
+msgid ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+
+msgid "repository root directory or symbolic path name"
+msgstr ""
+
+msgid "change working directory"
+msgstr ""
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr ""
+
+msgid "suppress output"
+msgstr ""
+
+msgid "enable additional output"
+msgstr ""
+
+msgid "set/override config option"
+msgstr ""
+
+msgid "enable debugging output"
+msgstr ""
+
+msgid "start debugger"
+msgstr ""
+
+msgid "set the charset encoding"
+msgstr ""
+
+msgid "set the charset encoding mode"
+msgstr ""
+
+msgid "print traceback on exception"
+msgstr ""
+
+msgid "time how long the command takes"
+msgstr ""
+
+msgid "print command execution profile"
+msgstr ""
+
+msgid "output version information and exit"
+msgstr ""
+
+msgid "display help and exit"
+msgstr ""
+
+msgid "do not perform actions, just print output"
+msgstr ""
+
+msgid "specify ssh command to use"
+msgstr ""
+
+msgid "specify hg command to run on the remote side"
+msgstr ""
+
+msgid "include names matching the given patterns"
+msgstr ""
+
+msgid "exclude names matching the given patterns"
+msgstr ""
+
+msgid "use <text> as commit message"
+msgstr ""
+
+msgid "read commit message from <file>"
+msgstr ""
+
+msgid "record datecode as commit date"
+msgstr ""
+
+msgid "record the specified user as committer"
+msgstr ""
+
+msgid "display using template map file"
+msgstr ""
+
+msgid "display with template"
+msgstr ""
+
+msgid "do not show merges"
+msgstr ""
+
+msgid "treat all files as text"
+msgstr ""
+
+msgid "don't include dates in diff headers"
+msgstr ""
+
+msgid "show which function each change is in"
+msgstr ""
+
+msgid "ignore white space when comparing lines"
+msgstr ""
+
+msgid "ignore changes in the amount of white space"
+msgstr ""
+
+msgid "ignore changes whose lines are all blank"
+msgstr ""
+
+msgid "number of lines of context to show"
+msgstr ""
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr ""
+
+msgid "[OPTION]... [FILE]..."
+msgstr ""
+
+msgid "annotate the specified revision"
+msgstr ""
+
+msgid "follow file copies and renames"
+msgstr ""
+
+msgid "list the author (long with -v)"
+msgstr ""
+
+msgid "list the date (short with -q)"
+msgstr ""
+
+msgid "list the revision number (default)"
+msgstr ""
+
+msgid "list the changeset"
+msgstr ""
+
+msgid "show line number at the first appearance"
+msgstr ""
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr ""
+
+msgid "do not pass files through decoders"
+msgstr ""
+
+msgid "directory prefix for files in archive"
+msgstr "chemin préfixé aux fichiers de l'archive"
+
+msgid "revision to distribute"
+msgstr "révision à distribuer"
+
+msgid "type of distribution to create"
+msgstr "type de distribution à créer"
+
+msgid "[OPTION]... DEST"
+msgstr "[OPTION]... DEST"
+
+msgid "merge with old dirstate parent after backout"
+msgstr ""
+
+msgid "parent to choose when backing out merge"
+msgstr ""
+
+msgid "revision to backout"
+msgstr ""
+
+msgid "[OPTION]... [-r] REV"
+msgstr ""
+
+msgid "reset bisect state"
+msgstr "réinitialiser l'état de la recherche par dichotomie"
+
+msgid "mark changeset good"
+msgstr "marquer la révision comme \"bonne\""
+
+msgid "mark changeset bad"
+msgstr "marquer la révision comme \"mauvaise\""
+
+msgid "skip testing changeset"
+msgstr "ne pas considérer la révision"
+
+msgid "use command to check changeset state"
+msgstr "utiliser une commande pour tester l'état des révisions"
+
+msgid "do not update to target"
+msgstr "ne pas mettre à jour à la révision cible"
+
+msgid "[-gbsr] [-c CMD] [REV]"
+msgstr "[-gbsr] [-c CMD] [REV]"
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr ""
+
+msgid "reset branch name to parent branch name"
+msgstr ""
+
+msgid "[-fC] [NAME]"
+msgstr ""
+
+msgid "show only branches that have unmerged heads"
+msgstr ""
+
+msgid "show normal and closed heads"
+msgstr ""
+
+msgid "[-a]"
+msgstr ""
+
+msgid "run even when remote repository is unrelated"
+msgstr ""
+
+msgid "a changeset up to which you would like to bundle"
+msgstr ""
+
+msgid "a base changeset to specify instead of a destination"
+msgstr ""
+
+msgid "bundle all changesets in the repository"
+msgstr ""
+
+msgid "bundle compression type to use"
+msgstr ""
+
+msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr ""
+
+msgid "print output to file with formatted name"
+msgstr ""
+
+msgid "print the given revision"
+msgstr ""
+
+msgid "apply any matching decode filter"
+msgstr ""
+
+msgid "[OPTION]... FILE..."
+msgstr ""
+
+msgid "the clone will only contain a repository (no working copy)"
+msgstr ""
+
+msgid "a changeset you would like to have after cloning"
+msgstr ""
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr ""
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr ""
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr ""
+
+msgid "record a copy that has already occurred"
+msgstr ""
+
+msgid "forcibly copy over an existing managed file"
+msgstr ""
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr ""
+
+msgid "[INDEX] REV1 REV2"
+msgstr ""
+
+msgid "[COMMAND]"
+msgstr ""
+
+msgid "show the command options"
+msgstr ""
+
+msgid "[-o] CMD"
+msgstr ""
+
+msgid "try extended date formats"
+msgstr ""
+
+msgid "[-e] DATE [RANGE]"
+msgstr ""
+
+msgid "FILE REV"
+msgstr ""
+
+msgid "[PATH]"
+msgstr ""
+
+msgid "FILE"
+msgstr ""
+
+msgid "revision to rebuild to"
+msgstr ""
+
+msgid "[-r REV] [REV]"
+msgstr ""
+
+msgid "revision to debug"
+msgstr ""
+
+msgid "[-r REV] FILE"
+msgstr ""
+
+msgid "REV1 [REV2]"
+msgstr ""
+
+msgid "do not display the saved mtime"
+msgstr ""
+
+msgid "[OPTION]..."
+msgstr ""
+
+msgid "revision to check"
+msgstr ""
+
+msgid "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+msgstr ""
+
+msgid "diff against the second parent"
+msgstr ""
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr ""
+
+msgid "end fields with NUL"
+msgstr ""
+
+msgid "print all revisions that match"
+msgstr ""
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr ""
+
+msgid "ignore case when matching"
+msgstr ""
+
+msgid "print only filenames and revisions that match"
+msgstr ""
+
+msgid "print matching line numbers"
+msgstr ""
+
+msgid "search in given revision range"
+msgstr ""
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr ""
+
+msgid "show only heads which are descendants of REV"
+msgstr ""
+
+msgid "show only the active heads from open branches"
+msgstr ""
+
+msgid "[-r STARTREV] [REV]..."
+msgstr ""
+
+msgid "[TOPIC]"
+msgstr ""
+
+msgid "identify the specified revision"
+msgstr ""
+
+msgid "show local revision number"
+msgstr ""
+
+msgid "show global revision id"
+msgstr ""
+
+msgid "show branch"
+msgstr ""
+
+msgid "show tags"
+msgstr ""
+
+msgid "[-nibt] [-r REV] [SOURCE]"
+msgstr ""
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr ""
+
+msgid "base path"
+msgstr ""
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr ""
+
+msgid "don't commit, just update the working directory"
+msgstr ""
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr ""
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr ""
+
+msgid "[OPTION]... PATCH..."
+msgstr ""
+
+msgid "show newest record first"
+msgstr ""
+
+msgid "file to store the bundles into"
+msgstr ""
+
+msgid "a specific revision up to which you would like to pull"
+msgstr ""
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr ""
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr ""
+
+msgid "search the repository as it stood at REV"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr ""
+
+msgid "print complete paths from the filesystem root"
+msgstr ""
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr ""
+
+msgid "only follow the first parent of merge changesets"
+msgstr ""
+
+msgid "show revisions matching date spec"
+msgstr ""
+
+msgid "show copied files"
+msgstr ""
+
+msgid "do case-insensitive search for a keyword"
+msgstr ""
+
+msgid "include revisions where files were removed"
+msgstr ""
+
+msgid "show only merges"
+msgstr ""
+
+msgid "revisions committed by user"
+msgstr ""
+
+msgid "show only changesets within the given named branch"
+msgstr ""
+
+msgid "do not display revision or any of its ancestors"
+msgstr ""
+
+msgid "[OPTION]... [FILE]"
+msgstr ""
+
+msgid "revision to display"
+msgstr ""
+
+msgid "[-r REV]"
+msgstr ""
+
+msgid "force a merge with outstanding changes"
+msgstr ""
+
+msgid "revision to merge"
+msgstr ""
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr ""
+
+msgid "[-f] [[-r] REV]"
+msgstr ""
+
+msgid "a specific revision up to which you would like to push"
+msgstr ""
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr ""
+
+msgid "show parents from the specified revision"
+msgstr ""
+
+msgid "[-r REV] [FILE]"
+msgstr ""
+
+msgid "[NAME]"
+msgstr ""
+
+msgid "update to new tip if changesets were pulled"
+msgstr ""
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr ""
+
+msgid "force push"
+msgstr ""
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr ""
+
+msgid "record delete for missing files"
+msgstr ""
+
+msgid "remove (and delete) file even if added or modified"
+msgstr ""
+
+msgid "record a rename that has already occurred"
+msgstr ""
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr ""
+
+msgid "remerge all unresolved files"
+msgstr ""
+
+msgid "list state of files needing merge"
+msgstr ""
+
+msgid "mark files as resolved"
+msgstr ""
+
+msgid "unmark files as resolved"
+msgstr ""
+
+msgid "revert all changes when no arguments given"
+msgstr ""
+
+msgid "tipmost revision matching date"
+msgstr ""
+
+msgid "revision to revert to"
+msgstr ""
+
+msgid "do not save backup copies of files"
+msgstr ""
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr ""
+
+msgid "name of access log file to write to"
+msgstr ""
+
+msgid "name of error log file to write to"
+msgstr ""
+
+msgid "port to listen on (default: 8000)"
+msgstr ""
+
+msgid "address to listen on (default: all interfaces)"
+msgstr ""
+
+msgid "prefix path to serve from (default: server root)"
+msgstr ""
+
+msgid "name to show in web pages (default: working directory)"
+msgstr ""
+
+msgid "name of the webdir config file (serve more than one repository)"
+msgstr ""
+
+msgid "for remote clients"
+msgstr ""
+
+msgid "web templates to use"
+msgstr ""
+
+msgid "template style to use"
+msgstr ""
+
+msgid "use IPv6 in addition to IPv4"
+msgstr ""
+
+msgid "SSL certificate file"
+msgstr ""
+
+msgid "show untrusted configuration options"
+msgstr ""
+
+msgid "[-u] [NAME]..."
+msgstr ""
+
+msgid "show status of all files"
+msgstr ""
+
+msgid "show only modified files"
+msgstr ""
+
+msgid "show only added files"
+msgstr ""
+
+msgid "show only removed files"
+msgstr ""
+
+msgid "show only deleted (but tracked) files"
+msgstr ""
+
+msgid "show only files without changes"
+msgstr ""
+
+msgid "show only unknown (not tracked) files"
+msgstr ""
+
+msgid "show only ignored files"
+msgstr ""
+
+msgid "hide status prefix"
+msgstr ""
+
+msgid "show source of copied files"
+msgstr ""
+
+msgid "show difference from revision"
+msgstr ""
+
+msgid "replace existing tag"
+msgstr ""
+
+msgid "make the tag local"
+msgstr ""
+
+msgid "revision to tag"
+msgstr ""
+
+msgid "remove a tag"
+msgstr ""
+
+msgid "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr ""
+
+msgid "[-p]"
+msgstr ""
+
+msgid "update to new tip if changesets were unbundled"
+msgstr ""
+
+msgid "[-u] FILE..."
+msgstr ""
+
+msgid "overwrite locally modified files (no backup)"
+msgstr ""
+
+msgid "check for uncommitted changes"
+msgstr ""
+
+msgid "[-C] [-d DATE] [[-r] REV]"
+msgstr ""
+
+#, python-format
+msgid "config error at %s:%d: '%s'"
+msgstr "erreur de configuration à %s:%d : '%s'"
+
+msgid "not found in manifest"
+msgstr ""
+
+msgid "branch name not in UTF-8!"
+msgstr "le nom de la branche n'est pas en UTF-8 !"
+
+#, python-format
+msgid " searching for copies back to rev %d\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" unmatched files in local:\n"
+" %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" unmatched files in other:\n"
+" %s\n"
+msgstr ""
+
+msgid " all copies found (* = to merge, ! = divergent):\n"
+msgstr ""
+
+msgid " checking for directory renames\n"
+msgstr ""
+
+#, python-format
+msgid " dir %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid " file %s -> %s\n"
+msgstr ""
+
+msgid "working directory state appears damaged!"
+msgstr ""
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr ""
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr ""
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr ""
+
+#, python-format
+msgid "not in dirstate: %s\n"
+msgstr ""
+
+msgid "unknown"
+msgstr ""
+
+msgid "character device"
+msgstr ""
+
+msgid "block device"
+msgstr ""
+
+msgid "fifo"
+msgstr ""
+
+msgid "socket"
+msgstr ""
+
+msgid "directory"
+msgstr ""
+
+#, python-format
+msgid "unsupported file type (type is %s)"
+msgstr ""
+
+#, python-format
+msgid "abort: %s\n"
+msgstr "abandon : %s\n"
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+" %s\n"
+msgstr ""
+"hg: la commande '%s' est ambiguë :\n"
+" %s\n"
+
+#, python-format
+msgid "hg: %s\n"
+msgstr "hg: %s\n"
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr "attendu trop longtemps le verrou détenu par %s"
+
+#, python-format
+msgid "lock held by %s"
+msgstr ""
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr "abandon : %s : %s\n"
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr "abandon : impossible de verrouiller %s : %s\n"
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr "hg %s: %s\n"
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr "abandon : %s !\n"
+
+#, python-format
+msgid "abort: %s"
+msgstr "abandon : %s"
+
+msgid " empty string\n"
+msgstr " chaîne vide\n"
+
+msgid "killed!\n"
+msgstr "tué !\n"
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr "hg: commande inconnue : '%s'\n"
+
+#, python-format
+msgid "abort: could not import module %s!\n"
+msgstr "abandon : impossible d'importer le module %s !\n"
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr "(avez-vous oublié de compiler les extensions ?)\n"
+
+msgid "(is your Python install correct?)\n"
+msgstr "(votre installation de Python est-elle correcte ?)\n"
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr "abandon : erreur : %s\n"
+
+# traduction utilisée par la glibc...
+msgid "broken pipe\n"
+msgstr "relais brisé (pipe)\n"
+
+msgid "interrupted!\n"
+msgstr "interrompu !\n"
+
+# traduction utilisée par la glibc...
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+"\n"
+"relais brisé (pipe)\n"
+
+msgid "abort: out of memory\n"
+msgstr "abandon : plus de mémoire libre\n"
+
+msgid "** unknown exception encountered, details follow\n"
+msgstr "** exception inconnue rencontrée, détails ci-dessous\n"
+
+msgid "** report bug details to http://mercurial.selenic.com/bts/\n"
+msgstr ""
+"** veuillez signaler le problème en détails sur http://www.selenic.com/"
+"mercurial/bts\n"
+
+msgid "** or mercurial@selenic.com\n"
+msgstr "** ou mercurial@selenic.com\n"
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr "** Mercurial version %s, système de gestion de sources distribué\n"
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr "** Extensions chargées : %s\n"
+
+#, python-format
+msgid "no definition for alias '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' resolves to unknown command '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' resolves to ambiguous command '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' shadows command\n"
+msgstr ""
+
+#, python-format
+msgid "malformed --config option: %s"
+msgstr "option incorrecte pour --config : %s"
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr "l'extension '%s' redéfinit ces commandes : %s\n"
+
+msgid "Option --config may not be abbreviated!"
+msgstr "L'option --config ne peut être abrégée !"
+
+msgid "Option --cwd may not be abbreviated!"
+msgstr "L'option --cwd ne peut être abrégée !"
+
+msgid ""
+"Option -R has to be separated from other options (e.g. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr ""
+"L'option -R doit être séparée des autres options (autrement dit -qR est "
+"invalide) et --repository ne peut être abrégé qu'en --repo !"
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr ""
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr "le dépôt '%s' n'est pas local"
+
+msgid "invalid arguments"
+msgstr "arguments invalides"
+
+#, python-format
+msgid "unrecognized profiling format '%s' - Ignored\n"
+msgstr ""
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr ""
+
+#, python-format
+msgid "picked tool '%s' for %s (binary %s symlink %s)\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+
+msgid "&Local"
+msgstr ""
+
+msgid "&Other"
+msgstr ""
+
+msgid "l"
+msgstr ""
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "my %s other %s ancestor %s\n"
+msgstr ""
+
+msgid " premerge successful\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+
+msgid "&No"
+msgstr ""
+
+msgid "&Yes"
+msgstr ""
+
+msgid "n"
+msgstr ""
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr ""
+
+#, python-format
+msgid "Inconsistent state, %s:%s is good and bad"
+msgstr "État incohérent, %s:%s est à la fois \"bon\" et \"mauvais\""
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr "type inconnu pour dichotomie : %s"
+
+msgid ""
+"\n"
+" Mercurial has the ability to add new features through the use of\n"
+" extensions. Extensions may add new commands, add options to\n"
+" existing commands, change the default behavior of commands, or\n"
+" implement hooks.\n"
+"\n"
+" Extensions are not loaded by default for a variety of reasons:\n"
+" they can increase startup overhead; they may be meant for\n"
+" advanced usage only; they may provide potentially dangerous\n"
+" abilities (such as letting you destroy or modify history); they\n"
+" might not be ready for prime time; or they may alter some\n"
+" usual behaviors of stock Mercurial. It is thus up to the user to\n"
+" activate extensions as needed.\n"
+"\n"
+" To enable the \"foo\" extension, either shipped with Mercurial\n"
+" or in the Python search path, create an entry for it in your\n"
+" hgrc, like this:\n"
+"\n"
+" [extensions]\n"
+" foo =\n"
+"\n"
+" You may also specify the full path to an extension:\n"
+"\n"
+" [extensions]\n"
+" myfeature = ~/.hgext/myfeature.py\n"
+"\n"
+" To explicitly disable an extension enabled in an hgrc of broader\n"
+" scope, prepend its path with !:\n"
+"\n"
+" [extensions]\n"
+" # disabling extension bar residing in /path/to/extension/bar.py\n"
+" hgext.bar = !/path/to/extension/bar.py\n"
+" # ditto, but no path was supplied for extension baz\n"
+" hgext.baz = !\n"
+" "
+msgstr ""
+"\n"
+" Mercurial a la capacité de s'enrichir de nouvelles\n"
+" fonctionnalités par le biais d'extensions. Les extensions\n"
+" permettent d'ajouter des nouvelles commandes, de changer le\n"
+" comportement de commandes existantes ou leur ajouter des\n"
+" options, ou encore d'implémenter de nouveaux \"hooks\".\n"
+"\n"
+" Les extensions ne sont pas chargées automatiquement par défaut\n"
+" pour diverses raisons : elles peuvent accroître la latence\n"
+" de lancement de Mercurial ; elle peuvent n'être destinées qu'à\n"
+" une utilisation avancée ; elle peuvent fournir des\n"
+" fonctionnalités potentiellement dangereuses, comme de vous\n"
+" permettre de modifier ou détruire l'historique du dépôt ; elles\n"
+" peuvent ne pas être encore prêtes à être utilisées par le plus\n"
+" grand nombre ; ou encore elles peuvent modifier certains des\n"
+" comportements habituels de Mercurial.\n"
+" Il appartient donc à l'utilisateur de les activer en fonction\n"
+" de ses besoins.\n"
+"\n"
+" Pour activer l'extension \"truc\" fournie avec Mercurial ou\n"
+" présente dans le chemin de recherche de Python, déclarez-la\n"
+" dans votre fichier de configuration hgrc comme suit :\n"
+"\n"
+" [extensions]\n"
+" truc =\n"
+"\n"
+" Vous pouvez aussi indiquer l'endroit où elle se trouve :\n"
+"\n"
+" [extensions]\n"
+" monbidule = ~/.hgext/monbidule.py\n"
+"\n"
+" Pour forcer la désactivation d'une extension activée par un\n"
+" autre hgrc, précédez son chemin d'un point d'exclamation :\n"
+"\n"
+" [extensions]\n"
+" # désactivation de machin qui se trouve dans /vers/machin.py\n"
+" hgext.bar = !/vers/machin.py\n"
+" # idem, mais aucun chemin n'avait été donné pour chose \n"
+" hgext.chose = !\n"
+" "
+
+msgid "disabled extensions:"
+msgstr "extensions désactivées :"
+
+msgid "Date Formats"
+msgstr ""
+
+msgid ""
+"\n"
+" Some commands allow the user to specify a date, e.g.:\n"
+" * backout, commit, import, tag: Specify the commit date.\n"
+" * log, revert, update: Select revision(s) by date.\n"
+"\n"
+" Many date formats are valid. Here are some examples:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n"
+" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n"
+" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n"
+" \"Dec 6\" (midnight)\n"
+" \"13:18\" (today assumed)\n"
+" \"3:39\" (3:39AM assumed)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Lastly, there is Mercurial's internal format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" This is the internal representation format for dates. unixtime is\n"
+" the number of seconds since the epoch (1970-01-01 00:00 UTC).\n"
+" offset is the offset of the local timezone, in seconds west of UTC\n"
+" (negative if the timezone is east of UTC).\n"
+"\n"
+" The log command also accepts date ranges:\n"
+"\n"
+" \"<{datetime}\" - at or before a given date/time\n"
+" \">{datetime}\" - on or after a given date/time\n"
+" \"{datetime} to {datetime}\" - a date range, inclusive\n"
+" \"-{days}\" - within a given number of days of today\n"
+" "
+msgstr ""
+
+msgid "File Name Patterns"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial accepts several notations for identifying one or more\n"
+" files at a time.\n"
+"\n"
+" By default, Mercurial treats filenames as shell-style extended\n"
+" glob patterns.\n"
+"\n"
+" Alternate pattern notations must be specified explicitly.\n"
+"\n"
+" To use a plain path name without any pattern matching, start it\n"
+" with \"path:\". These path names must completely match starting at\n"
+" the current repository root.\n"
+"\n"
+" To use an extended glob, start a name with \"glob:\". Globs are\n"
+" rooted at the current directory; a glob such as \"*.c\" will only\n"
+" match files in the current directory ending with \".c\".\n"
+"\n"
+" The supported glob syntax extensions are \"**\" to match any string\n"
+" across path separators and \"{a,b}\" to mean \"a or b\".\n"
+"\n"
+" To use a Perl/Python regular expression, start a name with \"re:\".\n"
+" Regexp pattern matching is anchored at the root of the repository.\n"
+"\n"
+" Plain examples:\n"
+"\n"
+" path:foo/bar a name bar in a directory named foo in the root of\n"
+" the repository\n"
+" path:path:name a file or directory named \"path:name\"\n"
+"\n"
+" Glob examples:\n"
+"\n"
+" glob:*.c any name ending in \".c\" in the current directory\n"
+" *.c any name ending in \".c\" in the current directory\n"
+" **.c any name ending in \".c\" in any subdirectory of the\n"
+" current directory including itself.\n"
+" foo/*.c any name ending in \".c\" in the directory foo\n"
+" foo/**.c any name ending in \".c\" in any subdirectory of foo\n"
+" including itself.\n"
+"\n"
+" Regexp examples:\n"
+"\n"
+" re:.*\\.c$ any name ending in \".c\", anywhere in the repository\n"
+"\n"
+" "
+msgstr ""
+
+msgid "Environment Variables"
+msgstr ""
+
+msgid ""
+"\n"
+"HG::\n"
+" Path to the 'hg' executable, automatically passed when running\n"
+" hooks, extensions or external tools. If unset or empty, this is\n"
+" the hg executable's name if it's frozen, or an executable named\n"
+" 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+" Windows) is searched.\n"
+"\n"
+"HGEDITOR::\n"
+" This is the name of the editor to run when committing. See EDITOR.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" This overrides the default locale setting detected by Mercurial.\n"
+" This setting is used to convert data including usernames,\n"
+" changeset descriptions, tag names, and branches. This setting can\n"
+" be overridden with the --encoding command-line option.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" This sets Mercurial's behavior for handling unknown characters\n"
+" while transcoding user input. The default is \"strict\", which\n"
+" causes Mercurial to abort if it can't map a character. Other\n"
+" settings include \"replace\", which replaces unknown characters, and\n"
+" \"ignore\", which drops them. This setting can be overridden with\n"
+" the --encodingmode command-line option.\n"
+"\n"
+"HGMERGE::\n"
+" An executable to use for resolving merge conflicts. The program\n"
+" will be executed with three arguments: local file, remote file,\n"
+" ancestor file.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" A list of files or directories to search for hgrc files. Item\n"
+" separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
+" platform default search path is used. If empty, only the .hg/hgrc\n"
+" from the current repository is read.\n"
+"\n"
+" For each element in HGRCPATH:\n"
+" * if it's a directory, all files ending with .rc are added\n"
+" * otherwise, the file itself will be added\n"
+"\n"
+"HGUSER::\n"
+" This is the string used as the author of a commit. If not set,\n"
+" available values will be considered in this order:\n"
+"\n"
+" * HGUSER (deprecated)\n"
+" * hgrc files from the HGRCPATH\n"
+" * EMAIL\n"
+" * interactive prompt\n"
+" * LOGNAME (with '@hostname' appended)\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"LOGNAME::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"VISUAL::\n"
+" This is the name of the editor to use when committing. See EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Sometimes Mercurial needs to open a text file in an editor for a\n"
+" user to modify, for example when writing commit messages. The\n"
+" editor it uses is determined by looking at the environment\n"
+" variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+" non-empty one is chosen. If all of them are empty, the editor\n"
+" defaults to 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" This is used by Python to find imported modules and may need to be\n"
+" set appropriately if this Mercurial is not installed system-wide.\n"
+" "
+msgstr ""
+
+msgid "Specifying Single Revisions"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial supports several ways to specify individual revisions.\n"
+"\n"
+" A plain integer is treated as a revision number. Negative integers\n"
+" are treated as topological offsets from the tip, with -1 denoting\n"
+" the tip. As such, negative numbers are only useful if you've\n"
+" memorized your local tree numbers and want to save typing a single\n"
+" digit. This editor suggests copy and paste.\n"
+"\n"
+" A 40-digit hexadecimal string is treated as a unique revision\n"
+" identifier.\n"
+"\n"
+" A hexadecimal string less than 40 characters long is treated as a\n"
+" unique revision identifier, and referred to as a short-form\n"
+" identifier. A short-form identifier is only valid if it is the\n"
+" prefix of exactly one full-length identifier.\n"
+"\n"
+" Any other string is treated as a tag name, which is a symbolic\n"
+" name associated with a revision identifier. Tag names may not\n"
+" contain the \":\" character.\n"
+"\n"
+" The reserved name \"tip\" is a special tag that always identifies\n"
+" the most recent revision.\n"
+"\n"
+" The reserved name \"null\" indicates the null revision. This is the\n"
+" revision of an empty repository, and the parent of revision 0.\n"
+"\n"
+" The reserved name \".\" indicates the working directory parent. If\n"
+" no working directory is checked out, it is equivalent to null. If\n"
+" an uncommitted merge is in progress, \".\" is the revision of the\n"
+" first parent.\n"
+" "
+msgstr ""
+
+msgid "Specifying Multiple Revisions"
+msgstr ""
+
+msgid ""
+"\n"
+" When Mercurial accepts more than one revision, they may be\n"
+" specified individually, or provided as a topologically continuous\n"
+" range, separated by the \":\" character.\n"
+"\n"
+" The syntax of range notation is [BEGIN]:[END], where BEGIN and END\n"
+" are revision identifiers. Both BEGIN and END are optional. If\n"
+" BEGIN is not specified, it defaults to revision number 0. If END\n"
+" is not specified, it defaults to the tip. The range \":\" thus means\n"
+" \"all revisions\".\n"
+"\n"
+" If BEGIN is greater than END, revisions are treated in reverse\n"
+" order.\n"
+"\n"
+" A range acts as a closed interval. This means that a range of 3:5\n"
+" gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+" "
+msgstr ""
+
+msgid "Diff Formats"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial's default format for showing changes between two\n"
+" versions of a file is compatible with the unified format of GNU\n"
+" diff, which can be used by GNU patch and many other standard\n"
+" tools.\n"
+"\n"
+" While this standard format is often enough, it does not encode the\n"
+" following information:\n"
+"\n"
+" - executable status and other permission bits\n"
+" - copy or rename information\n"
+" - changes in binary files\n"
+" - creation or deletion of empty files\n"
+"\n"
+" Mercurial also supports the extended diff format from the git VCS\n"
+" which addresses these limitations. The git diff format is not\n"
+" produced by default because a few widespread tools still do not\n"
+" understand this format.\n"
+"\n"
+" This means that when generating diffs from a Mercurial repository\n"
+" (e.g. with \"hg export\"), you should be careful about things like\n"
+" file copies and renames or other things mentioned above, because\n"
+" when applying a standard diff to a different repository, this\n"
+" extra information is lost. Mercurial's internal operations (like\n"
+" push and pull) are not affected by this, because they use an\n"
+" internal binary format for communicating changes.\n"
+"\n"
+" To make Mercurial produce the git extended diff format, use the\n"
+" --git option available for many commands, or set 'git = True' in\n"
+" the [diff] section of your hgrc. You do not need to set this\n"
+" option when importing diffs in this format or using them in the mq\n"
+" extension.\n"
+" "
+msgstr ""
+
+msgid "Template Usage"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial allows you to customize output of commands through\n"
+" templates. You can either pass in a template from the command\n"
+" line, via the --template option, or select an existing\n"
+" template-style (--style).\n"
+"\n"
+" You can customize output for any \"log-like\" command: log,\n"
+" outgoing, incoming, tip, parents, heads and glog.\n"
+"\n"
+" Three styles are packaged with Mercurial: default (the style used\n"
+" when no explicit preference is passed), compact and changelog.\n"
+" Usage:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" A template is a piece of text, with markup to invoke variable\n"
+" expansion:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings in curly braces are called keywords. The availability of\n"
+" keywords depends on the exact context of the templater. These\n"
+" keywords are usually available for templating a log-like command:\n"
+"\n"
+" - author: String. The unmodified author of the changeset.\n"
+" - branches: String. The name of the branch on which the changeset\n"
+" was committed. Will be empty if the branch name was default.\n"
+" - date: Date information. The date when the changeset was committed.\n"
+" - desc: String. The text of the changeset description.\n"
+" - diffstat: String. Statistics of changes with the following\n"
+" format: \"modified files: +added/-removed lines\"\n"
+" - files: List of strings. All files modified, added, or removed by\n"
+" this changeset.\n"
+" - file_adds: List of strings. Files added by this changeset.\n"
+" - file_mods: List of strings. Files modified by this changeset.\n"
+" - file_dels: List of strings. Files removed by this changeset.\n"
+" - node: String. The changeset identification hash, as a\n"
+" 40-character hexadecimal string.\n"
+" - parents: List of strings. The parents of the changeset.\n"
+" - rev: Integer. The repository-local changeset revision number.\n"
+" - tags: List of strings. Any tags associated with the changeset.\n"
+"\n"
+" The \"date\" keyword does not produce human-readable output. If you\n"
+" want to use a date in your output, you can use a filter to process\n"
+" it. Filters are functions which return a string based on the input\n"
+" variable. You can also use a chain of filters to get the desired\n"
+" output:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" List of filters:\n"
+"\n"
+" - addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
+" every line except the last.\n"
+" - age: Date. Returns a human-readable date/time difference between\n"
+" the given date/time and the current date/time.\n"
+" - basename: Any text. Treats the text as a path, and returns the\n"
+" last component of the path after splitting by the path\n"
+" separator (ignoring trailing separators). For example,\n"
+" \"foo/bar/baz\" becomes \"baz\" and \"foo/bar//\" becomes \"bar"
+"\".\n"
+" - stripdir: Treat the text as path and strip a directory level, if\n"
+" possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\".\n"
+" - date: Date. Returns a date in a Unix date format, including\n"
+" the timezone: \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - domain: Any text. Finds the first string that looks like an\n"
+" email address, and extracts just the domain component.\n"
+" Example: 'User <user@example.com>' becomes 'example.com'.\n"
+" - email: Any text. Extracts the first string that looks like an\n"
+" email address. Example: 'User <user@example.com>' becomes\n"
+" 'user@example.com'.\n"
+" - escape: Any text. Replaces the special XML/XHTML characters \"&\",\n"
+" \"<\" and \">\" with XML entities.\n"
+" - fill68: Any text. Wraps the text to fit in 68 columns.\n"
+" - fill76: Any text. Wraps the text to fit in 76 columns.\n"
+" - firstline: Any text. Returns the first line of text.\n"
+" - nonempty: Any text. Returns '(none)' if the string is empty.\n"
+" - hgdate: Date. Returns the date as a pair of numbers:\n"
+" \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
+" - isodate: Date. Returns the date in ISO 8601 format.\n"
+" - localdate: Date. Converts a date to local date.\n"
+" - obfuscate: Any text. Returns the input text rendered as a\n"
+" sequence of XML entities.\n"
+" - person: Any text. Returns the text before an email address.\n"
+" - rfc822date: Date. Returns a date using the same format used\n"
+" in email headers.\n"
+" - short: Changeset hash. Returns the short form of a changeset\n"
+" hash, i.e. a 12-byte hexadecimal string.\n"
+" - shortdate: Date. Returns a date like \"2006-09-18\".\n"
+" - strip: Any text. Strips all leading and trailing whitespace.\n"
+" - tabindent: Any text. Returns the text, with every line except\n"
+" the first starting with a tab character.\n"
+" - urlescape: Any text. Escapes all \"special\" characters. For\n"
+" example, \"foo bar\" becomes \"foo%20bar\".\n"
+" - user: Any text. Returns the user portion of an email address.\n"
+" "
+msgstr ""
+
+msgid "URL Paths"
+msgstr ""
+
+msgid ""
+"\n"
+" Valid URLs are of the form:\n"
+"\n"
+" local/filesystem/path[#revision]\n"
+" file://local/filesystem/path[#revision]\n"
+" http://[user[:pass]@]host[:port]/[path][#revision]\n"
+" https://[user[:pass]@]host[:port]/[path][#revision]\n"
+" ssh://[user[:pass]@]host[:port]/[path][#revision]\n"
+"\n"
+" Paths in the local filesystem can either point to Mercurial\n"
+" repositories or to bundle files (as created by 'hg bundle' or\n"
+" 'hg incoming --bundle').\n"
+"\n"
+" An optional identifier after # indicates a particular branch, tag,\n"
+" or changeset to use from the remote repository. See also 'hg help\n"
+" revisions'.\n"
+"\n"
+" Some features, such as pushing to http:// and https:// URLs are\n"
+" only possible if the feature is explicitly enabled on the remote\n"
+" Mercurial server.\n"
+"\n"
+" Some notes about using SSH with Mercurial:\n"
+" - SSH requires an accessible shell account on the destination\n"
+" machine and a copy of hg in the remote path or specified with as\n"
+" remotecmd.\n"
+" - path is relative to the remote user's home directory by default.\n"
+" Use an extra slash at the start of a path to specify an absolute "
+"path:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial doesn't use its own compression via SSH; the right\n"
+" thing to do is to configure it in your ~/.ssh/config, e.g.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternatively specify \"ssh -C\" as your ssh command in your hgrc\n"
+" or with the --ssh command line option.\n"
+"\n"
+" These URLs can all be stored in your hgrc with path aliases under\n"
+" the [paths] section like so:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" You can then use the alias for any command that uses a URL (for\n"
+" example 'hg pull alias1' would pull from the 'alias1' path).\n"
+"\n"
+" Two path aliases are special because they are used as defaults\n"
+" when you do not provide the URL to a command:\n"
+"\n"
+" default:\n"
+" When you create a repository with hg clone, the clone command\n"
+" saves the location of the source repository as the new\n"
+" repository's 'default' path. This is then used when you omit\n"
+" path from push- and pull-like commands (including incoming and\n"
+" outgoing).\n"
+"\n"
+" default-push:\n"
+" The push command will look for a path named 'default-push', and\n"
+" prefer it over 'default' if both are defined.\n"
+" "
+msgstr ""
+
+msgid "Using additional features"
+msgstr ""
+
+msgid "can only share local repositories"
+msgstr ""
+
+msgid "destination already exists"
+msgstr ""
+
+msgid "updating working directory\n"
+msgstr ""
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr ""
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr ""
+
+#, python-format
+msgid "destination '%s' is not empty"
+msgstr ""
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr ""
+
+msgid "clone from remote to remote not supported"
+msgstr ""
+
+msgid "updated"
+msgstr ""
+
+msgid "merged"
+msgstr ""
+
+msgid "removed"
+msgstr ""
+
+msgid "unresolved"
+msgstr ""
+
+#, python-format
+msgid "%d files %s"
+msgstr ""
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr ""
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to "
+"abandon\n"
+msgstr ""
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr ""
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr ""
+
+msgid "SSL support is unavailable"
+msgstr ""
+
+msgid "IPv6 is not available on this system"
+msgstr ""
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr ""
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook failed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr ""
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook %s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr ""
+
+msgid "connection ended unexpectedly"
+msgstr ""
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "using %s\n"
+msgstr ""
+
+#, python-format
+msgid "capabilities: %s\n"
+msgstr ""
+
+msgid "operation not supported over http"
+msgstr ""
+
+#, python-format
+msgid "sending %s command\n"
+msgstr ""
+
+#, python-format
+msgid "sending %s bytes\n"
+msgstr ""
+
+msgid "authorization failed"
+msgstr ""
+
+#, python-format
+msgid "http error while sending %s command\n"
+msgstr ""
+
+msgid "http error, possibly caused by proxy setting"
+msgstr ""
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr ""
+
+#, python-format
+msgid "requested URL: '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr ""
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr ""
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr ""
+
+msgid "look up remote revision"
+msgstr ""
+
+msgid "unexpected response:"
+msgstr ""
+
+msgid "look up remote changes"
+msgstr ""
+
+msgid "push failed (unexpected response):"
+msgstr ""
+
+#, python-format
+msgid "push failed: %s"
+msgstr ""
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr ""
+
+msgid "cannot create new http repository"
+msgstr ""
+
+#, python-format
+msgid "%s: ignoring invalid syntax '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s not found"
+msgstr ""
+
+#, python-format
+msgid "repository %s already exists"
+msgstr ""
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr ""
+
+#, python-format
+msgid ".hg/sharedpath points to nonexistent directory %s"
+msgstr ""
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr ""
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr ""
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr ""
+
+msgid "cannot parse entry"
+msgstr ""
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr ""
+
+#, python-format
+msgid "working directory has unknown parent '%s'!"
+msgstr ""
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr ""
+
+#, python-format
+msgid "filtering %s through %s\n"
+msgstr ""
+
+msgid "journal already exists - run hg recover"
+msgstr ""
+
+msgid "rolling back interrupted transaction\n"
+msgstr ""
+
+msgid "no interrupted transaction available\n"
+msgstr ""
+
+msgid "rolling back last transaction\n"
+msgstr ""
+
+#, python-format
+msgid "Named branch could not be reset, current branch still is: %s\n"
+msgstr ""
+
+msgid "no rollback information available\n"
+msgstr ""
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s"
+msgstr ""
+
+#, python-format
+msgid "working directory of %s"
+msgstr ""
+
+#, python-format
+msgid " %s: searching for copy revision for %s\n"
+msgstr ""
+
+#, python-format
+msgid " %s: copy %s:%s\n"
+msgstr ""
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr ""
+
+msgid "file not found!"
+msgstr ""
+
+msgid "no match under directory!"
+msgstr ""
+
+msgid "file not tracked!"
+msgstr ""
+
+msgid "unresolved merge conflicts (see hg resolve)"
+msgstr ""
+
+#, python-format
+msgid "committing subrepository %s\n"
+msgstr ""
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"%s: files over 10MB may cause memory and performance problems\n"
+"(use 'hg revert %s' to unadd the file)\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr ""
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added!\n"
+msgstr ""
+
+#, python-format
+msgid "%s still exists!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr ""
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr ""
+
+msgid "searching for changes\n"
+msgstr ""
+
+#, python-format
+msgid "examining %s:%s\n"
+msgstr ""
+
+msgid "branch already found\n"
+msgstr ""
+
+#, python-format
+msgid "found incomplete branch %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "found new changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "request %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "received %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowing %d:%d %s\n"
+msgstr ""
+
+#, python-format
+msgid "found new branch changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowed branch search to %s:%s\n"
+msgstr ""
+
+msgid "already have changeset "
+msgstr ""
+
+msgid "warning: repository is unrelated\n"
+msgstr ""
+
+msgid "repository is unrelated"
+msgstr ""
+
+msgid "found new changesets starting at "
+msgstr ""
+
+#, python-format
+msgid "%d total queries\n"
+msgstr ""
+
+msgid "common changesets up to "
+msgstr ""
+
+msgid "requesting all changes\n"
+msgstr ""
+
+msgid ""
+"Partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr ""
+
+#, python-format
+msgid "abort: push creates new remote branch '%s'!\n"
+msgstr ""
+
+msgid "abort: push creates new remote heads!\n"
+msgstr ""
+
+msgid "(did you forget to merge? use push -f to force)\n"
+msgstr ""
+
+msgid "note: unsynced remote changes!\n"
+msgstr ""
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr ""
+
+msgid "list of changesets:\n"
+msgstr ""
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr ""
+
+#, python-format
+msgid "add changeset %s\n"
+msgstr ""
+
+msgid "adding changesets\n"
+msgstr ""
+
+msgid "received changelog group is empty"
+msgstr ""
+
+msgid "adding manifests\n"
+msgstr ""
+
+msgid "adding file changes\n"
+msgstr ""
+
+#, python-format
+msgid "adding %s revisions\n"
+msgstr ""
+
+msgid "received file revlog group is empty"
+msgstr ""
+
+#, python-format
+msgid " (%+d heads)"
+msgstr ""
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr ""
+
+msgid "updating the branch cache\n"
+msgstr ""
+
+msgid "Unexpected response from remote server:"
+msgstr ""
+
+msgid "operation forbidden by server"
+msgstr ""
+
+msgid "locking the remote repository failed"
+msgstr ""
+
+msgid "the server sent an unknown error code"
+msgstr ""
+
+msgid "streaming all changes\n"
+msgstr ""
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr ""
+
+#, python-format
+msgid "adding %s (%s)\n"
+msgstr ""
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr ""
+
+msgid "no [smtp]host in hgrc - cannot send mail"
+msgstr ""
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr ""
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr ""
+
+msgid "(using tls)\n"
+msgstr ""
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr ""
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr ""
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr ""
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr ""
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr ""
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr ""
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr ""
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr ""
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr ""
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+
+msgid "&None"
+msgstr ""
+
+msgid "E&xec"
+msgstr ""
+
+msgid "Sym&link"
+msgstr ""
+
+msgid "resolving manifests\n"
+msgstr ""
+
+#, python-format
+msgid " overwrite %s partial %s\n"
+msgstr ""
+
+#, python-format
+msgid " ancestor %s local %s remote %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+msgid "&Changed"
+msgstr ""
+
+msgid "&Delete"
+msgstr ""
+
+msgid "c"
+msgstr ""
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+
+msgid "&Deleted"
+msgstr ""
+
+#, python-format
+msgid "preserving %s for resolve of %s\n"
+msgstr ""
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "warning: detected divergent renames of %s to:\n"
+msgstr ""
+
+#, python-format
+msgid "branch %s not found"
+msgstr ""
+
+msgid "can't merge with ancestor"
+msgstr ""
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr ""
+
+msgid "outstanding uncommitted changes (use 'hg status' to list changes)"
+msgstr ""
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C' to discard changes)"
+msgstr ""
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C')"
+msgstr ""
+
+msgid "crosses named branches (use 'hg update -C' to discard changes)"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr ""
+
+#, python-format
+msgid "found patch at byte %d\n"
+msgstr ""
+
+msgid "patch generated by hg export\n"
+msgstr ""
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr ""
+
+#, python-format
+msgid "patching file %s\n"
+msgstr ""
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr ""
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d line).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d lines).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr ""
+
+msgid "could not extract binary patch"
+msgstr ""
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr ""
+
+#, python-format
+msgid "unable to strip away %d dirs from %s"
+msgstr ""
+
+msgid "undefined source and destination files"
+msgstr ""
+
+#, python-format
+msgid "malformed patch %s %s"
+msgstr ""
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr ""
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr ""
+
+#, python-format
+msgid "Unsupported line endings type: %s"
+msgstr ""
+
+#, python-format
+msgid "no valid hunks found; trying with %r instead\n"
+msgstr ""
+
+#, python-format
+msgid "exited with status %d"
+msgstr ""
+
+#, python-format
+msgid "killed by signal %d"
+msgstr ""
+
+#, python-format
+msgid "stopped by signal %d"
+msgstr ""
+
+msgid "invalid exit code"
+msgstr ""
+
+#, python-format
+msgid "saving bundle to %s\n"
+msgstr ""
+
+msgid "adding branch\n"
+msgstr ""
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr ""
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr ""
+
+#, python-format
+msgid "index %s is corrupted"
+msgstr ""
+
+msgid "no node"
+msgstr ""
+
+msgid "ambiguous identifier"
+msgstr ""
+
+msgid "no match found"
+msgstr ""
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr ""
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr ""
+
+msgid "unknown base"
+msgstr ""
+
+msgid "consistency error adding group"
+msgstr ""
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr ""
+
+msgid "can only specify two labels."
+msgstr ""
+
+msgid "warning: conflicts during merge.\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr ""
+
+msgid "could not create remote repo"
+msgstr ""
+
+msgid "remote: "
+msgstr ""
+
+msgid "no suitable response from remote hg"
+msgstr ""
+
+#, python-format
+msgid "push refused: %s"
+msgstr ""
+
+msgid "unsynced changes"
+msgstr ""
+
+msgid "cannot lock static-http repository"
+msgstr ""
+
+msgid "cannot create new static-http repository"
+msgstr ""
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr ""
+
+msgid "scanning\n"
+msgstr ""
+
+#, python-format
+msgid "%d files, %d bytes to transfer\n"
+msgstr ""
+
+#, python-format
+msgid "sending %s (%d bytes)\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?"
+msgstr ""
+
+msgid "&Remote"
+msgstr ""
+
+msgid "r"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed subrepository %s which remote removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid ""
+" remote changed subrepository %s which local removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid "removing subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid "pulling subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid "pushing subrepo %s\n"
+msgstr ""
+
+msgid "unmatched quotes"
+msgstr ""
+
+#, python-format
+msgid "error expanding '%s%%%s'"
+msgstr ""
+
+#, python-format
+msgid "unknown filter '%s'"
+msgstr ""
+
+#, python-format
+msgid "style not found: %s"
+msgstr ""
+
+#, python-format
+msgid "template file %s: %s"
+msgstr ""
+
+msgid "cannot use transaction when it is already committed/aborted"
+msgstr ""
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr ""
+
+msgid "transaction abort!\n"
+msgstr ""
+
+msgid "rollback completed\n"
+msgstr ""
+
+msgid "rollback failed - please run hg recover\n"
+msgstr ""
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring untrusted configuration option %s.%s = %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s.%s not a boolean ('%s')"
+msgstr ""
+
+msgid "enter a commit username:"
+msgstr ""
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr ""
+
+msgid "Please specify a username."
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr ""
+
+msgid "unrecognized response\n"
+msgstr ""
+
+msgid "response expected"
+msgstr ""
+
+msgid "password: "
+msgstr ""
+
+msgid "edit failed"
+msgstr ""
+
+msgid "http authorization required"
+msgstr ""
+
+msgid "http authorization required\n"
+msgstr ""
+
+#, python-format
+msgid "realm: %s\n"
+msgstr ""
+
+#, python-format
+msgid "user: %s\n"
+msgstr ""
+
+msgid "user:"
+msgstr ""
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr ""
+
+#, python-format
+msgid "proxying through http://%s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr ""
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr ""
+
+#, python-format
+msgid "path %r is inside repo %r"
+msgstr ""
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr ""
+
+msgid "Hardlinks not supported"
+msgstr ""
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid date: %r "
+msgstr ""
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr ""
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr ""
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr ""
+
+#, python-format
+msgid "%.0f GB"
+msgstr ""
+
+#, python-format
+msgid "%.1f GB"
+msgstr ""
+
+#, python-format
+msgid "%.2f GB"
+msgstr ""
+
+#, python-format
+msgid "%.0f MB"
+msgstr ""
+
+#, python-format
+msgid "%.1f MB"
+msgstr ""
+
+#, python-format
+msgid "%.2f MB"
+msgstr ""
+
+#, python-format
+msgid "%.0f KB"
+msgstr ""
+
+#, python-format
+msgid "%.1f KB"
+msgstr ""
+
+#, python-format
+msgid "%.2f KB"
+msgstr ""
+
+#, python-format
+msgid "%.0f bytes"
+msgstr ""
+
+msgid "cannot verify bundle or remote repos"
+msgstr ""
+
+msgid "interrupted"
+msgstr ""
+
+#, python-format
+msgid "empty or missing %s"
+msgstr ""
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr ""
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to nonexistent changeset %d"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to unexpected changeset %d"
+msgstr ""
+
+#, python-format
+msgid " (expected %s)"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "checking parents of %s"
+msgstr ""
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr ""
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr ""
+
+msgid "checking changesets\n"
+msgstr ""
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr ""
+
+msgid "checking manifests\n"
+msgstr ""
+
+#, python-format
+msgid "%s not in changesets"
+msgstr ""
+
+msgid "file without name in manifest"
+msgstr ""
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr ""
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr ""
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr ""
+
+msgid "in changeset but not in manifest"
+msgstr ""
+
+msgid "in manifest but not in changeset"
+msgstr ""
+
+msgid "checking files\n"
+msgstr ""
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr ""
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr ""
+
+msgid "missing revlog!"
+msgstr ""
+
+#, python-format
+msgid "%s not in manifests"
+msgstr ""
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr ""
+
+#, python-format
+msgid "unpacking %s"
+msgstr ""
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "checking rename of %s"
+msgstr ""
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr ""
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr ""
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr ""
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr ""
+
+msgid "user name not available - set USERNAME environment variable"
+msgstr ""
diff --git a/sys/src/cmd/hg/i18n/hggettext b/sys/src/cmd/hg/i18n/hggettext
new file mode 100755
index 000000000..7e6e12a67
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/hggettext
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+#
+# hggettext - carefully extract docstrings for Mercurial
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+# The normalize function is taken from pygettext which is distributed
+# with Python under the Python License, which is GPL compatible.
+
+"""Extract docstrings from Mercurial commands.
+
+Compared to pygettext, this script knows about the cmdtable and table
+dictionaries used by Mercurial, and will only extract docstrings from
+functions mentioned therein.
+
+Use xgettext like normal to extract strings marked as translatable and
+join the message cataloges to get the final catalog.
+"""
+
+import os, sys, inspect
+
+
+def escape(s):
+ # The order is important, the backslash must be escaped first
+ # since the other replacements introduce new backslashes
+ # themselves.
+ s = s.replace('\\', '\\\\')
+ s = s.replace('\n', '\\n')
+ s = s.replace('\r', '\\r')
+ s = s.replace('\t', '\\t')
+ s = s.replace('"', '\\"')
+ return s
+
+
+def normalize(s):
+ # This converts the various Python string types into a format that
+ # is appropriate for .po files, namely much closer to C style.
+ lines = s.split('\n')
+ if len(lines) == 1:
+ s = '"' + escape(s) + '"'
+ else:
+ if not lines[-1]:
+ del lines[-1]
+ lines[-1] = lines[-1] + '\n'
+ lines = map(escape, lines)
+ lineterm = '\\n"\n"'
+ s = '""\n"' + lineterm.join(lines) + '"'
+ return s
+
+
+def poentry(path, lineno, s):
+ return ('#: %s:%d\n' % (path, lineno) +
+ 'msgid %s\n' % normalize(s) +
+ 'msgstr ""\n')
+
+
+def offset(src, doc, name, default):
+ """Compute offset or issue a warning on stdout."""
+ # Backslashes in doc appear doubled in src.
+ end = src.find(doc.replace('\\', '\\\\'))
+ if end == -1:
+ # This can happen if the docstring contains unnecessary escape
+ # sequences such as \" in a triple-quoted string. The problem
+ # is that \" is turned into " and so doc wont appear in src.
+ sys.stderr.write("warning: unknown offset in %s, assuming %d lines\n"
+ % (name, default))
+ return default
+ else:
+ return src.count('\n', 0, end)
+
+
+def importpath(path):
+ """Import a path like foo/bar/baz.py and return the baz module."""
+ if path.endswith('.py'):
+ path = path[:-3]
+ if path.endswith('/__init__'):
+ path = path[:-9]
+ path = path.replace('/', '.')
+ mod = __import__(path)
+ for comp in path.split('.')[1:]:
+ mod = getattr(mod, comp)
+ return mod
+
+
+def docstrings(path):
+ """Extract docstrings from path.
+
+ This respects the Mercurial cmdtable/table convention and will
+ only extract docstrings from functions mentioned in these tables.
+ """
+ mod = importpath(path)
+ if mod.__doc__:
+ src = open(path).read()
+ lineno = 1 + offset(src, mod.__doc__, path, 7)
+ print poentry(path, lineno, mod.__doc__)
+
+ cmdtable = getattr(mod, 'cmdtable', {})
+ if not cmdtable:
+ # Maybe we are processing mercurial.commands?
+ cmdtable = getattr(mod, 'table', {})
+
+ for entry in cmdtable.itervalues():
+ func = entry[0]
+ if func.__doc__:
+ src = inspect.getsource(func)
+ name = "%s.%s" % (path, func.__name__)
+ lineno = func.func_code.co_firstlineno
+ lineno += offset(src, func.__doc__, name, 1)
+ print poentry(path, lineno, func.__doc__)
+
+
+if __name__ == "__main__":
+ # It is very important that we import the Mercurial modules from
+ # the source tree where hggettext is executed. Otherwise we might
+ # accidentally import and extract strings from a Mercurial
+ # installation mentioned in PYTHONPATH.
+ sys.path.insert(0, os.getcwd())
+ from mercurial import demandimport; demandimport.enable()
+ for path in sys.argv[1:]:
+ docstrings(path)
diff --git a/sys/src/cmd/hg/i18n/it.po b/sys/src/cmd/hg/i18n/it.po
new file mode 100644
index 000000000..193c2547f
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/it.po
@@ -0,0 +1,9510 @@
+# Italian translations for Mercurial
+# Traduzione italiana per Mercurial
+# Copyright (C) 2009 Matt Mackall and others
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-03-27 18:18+0100\n"
+"PO-Revision-Date: 2009-03-03 20:05+0100\n"
+"Last-Translator: Stefano Tortarolo <stefano.tortarolo@gmail.com>\n"
+"Language-Team: Italian <Italian>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (default: %s)"
+
+msgid "OPTIONS"
+msgstr "OPZIONI"
+
+msgid "COMMANDS"
+msgstr "COMANDI"
+
+msgid " options:\n"
+msgstr " opzioni:\n"
+
+#, python-format
+msgid ""
+" aliases: %s\n"
+"\n"
+msgstr ""
+" alias: %s\n"
+"\n"
+
+msgid "return tuple of (match function, list enabled)."
+msgstr "restituisce una tupla di (funzione match, elenco abilitato)."
+
+#, python-format
+msgid "acl: %s not enabled\n"
+msgstr "acl: %s non abilitato\n"
+
+#, python-format
+msgid "acl: %s enabled, %d entries for user %s\n"
+msgstr "acl: %s abilitato, %d entry per l'utente %s\n"
+
+#, python-format
+msgid "config error - hook type \"%s\" cannot stop incoming changesets"
+msgstr ""
+"errore di configurazione - l'hook di tipo \"%s\" non pu fermare i changeset "
+"in entrata"
+
+#, python-format
+msgid "acl: changes have source \"%s\" - skipping\n"
+msgstr "acl: le modifiche hanno sorgente \"%s\" - saltato\n"
+
+#, python-format
+msgid "acl: user %s denied on %s\n"
+msgstr "acl: utente %s bloccato su %s\n"
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr "acl: accesso negato per il changeset %s"
+
+#, python-format
+msgid "acl: user %s not allowed on %s\n"
+msgstr "acl: l'utente %s non pu avere accesso a %s\n"
+
+#, python-format
+msgid "acl: allowing changeset %s\n"
+msgstr "acl: consentendo il changeset %s\n"
+
+msgid ""
+"allow user-defined command aliases\n"
+"\n"
+"To use, create entries in your hgrc of the form\n"
+"\n"
+"[alias]\n"
+"mycmd = cmd --args\n"
+msgstr ""
+"consente alias definiti dall'utente\n"
+"\n"
+"Per usarlo, crea entry nel tuo hgrc della forma\n"
+"\n"
+"[alias]\n"
+"mycmd = cmd --args\n"
+
+msgid ""
+"defer command lookup until needed, so that extensions loaded\n"
+" after alias can be aliased"
+msgstr ""
+"ritarda la ricerca del comando fin quando necessario, in modo che si "
+"attivino gli alias\n"
+" per le estensioni caricate dopo alias"
+
+#, python-format
+msgid "*** [alias] %s: command %s is unknown"
+msgstr "*** [alias] %s: il comando %s sconosciuto"
+
+#, python-format
+msgid "*** [alias] %s: command %s is ambiguous"
+msgstr "*** [alias] %s: il comando %s ambiguo"
+
+#, python-format
+msgid "*** [alias] %s: circular dependency on %s"
+msgstr "*** [alias] %s: dipendenza circolare su %s"
+
+#, python-format
+msgid "*** [alias] %s: no definition\n"
+msgstr "*** [alias] %s: nessuna definizione\n"
+
+msgid ""
+"mercurial bookmarks\n"
+"\n"
+"Mercurial bookmarks are local moveable pointers to changesets. Every\n"
+"bookmark points to a changeset identified by its hash. If you commit a\n"
+"changeset that is based on a changeset that has a bookmark on it, the\n"
+"bookmark is forwarded to the new changeset.\n"
+"\n"
+"It is possible to use bookmark names in every revision lookup (e.g. hg\n"
+"merge, hg update).\n"
+"\n"
+"The bookmark extension offers the possiblity to have a more git-like "
+"experience\n"
+"by adding the following configuration option to your .hgrc:\n"
+"\n"
+"[bookmarks]\n"
+"track.current = True\n"
+"\n"
+"This will cause bookmarks to track the bookmark that you are currently on, "
+"and\n"
+"just updates it. This is similar to git's approach of branching.\n"
+msgstr ""
+"mercurial bookmarks\n"
+"\n"
+"I segnalibri di Mercurial sono puntatori locali e mobili a changeset. Ogni\n"
+"segnalibro punta ad un changeset identificato dal proprio hash. Se fai il "
+"commit di un\n"
+"changeset basato su un changeset che ha un segnalibro, \n"
+"il segnalibro spostato sul nuovo changeset\n"
+"\n"
+"E' possibile usare nomi di segnalibri in ogni ricerca di revisioni (es. hg\n"
+"merge, hg update).\n"
+"\n"
+"L'estensione bookmark offre la possibilit di avere un'esperienza pi simile a "
+"git\n"
+"aggiungendo la seguente opzione di configurazione al tuo .hgrc:\n"
+"\n"
+"[bookmarks]\n"
+"track.current = True\n"
+"\n"
+"Questo porter i segnalibri a tener traccia del segnalibro su cui sei "
+"attualmente,e\n"
+"ad aggiornarlo. Questo simile all'approccio di branching di git.\n"
+
+msgid ""
+"Parse .hg/bookmarks file and return a dictionary\n"
+"\n"
+" Bookmarks are stored as {HASH}\\s{NAME}\\n (localtags format) values\n"
+" in the .hg/bookmarks file. They are read by the parse() method and\n"
+" returned as a dictionary with name => hash values.\n"
+"\n"
+" The parsed dictionary is cached until a write() operation is done.\n"
+" "
+msgstr ""
+"Parsifica il file .hg/bookmarks e restituisce un dizionario\n"
+"\n"
+" I segnalibri sono memorizzati nel file .hg/bookmarks come \n"
+" valori {HASH}\\s{NAME} (formato di localtags).\n"
+" Sono letti dal metodo parse() e restituiti come dizionario con \n"
+" nome => valore di hash.\n"
+"\n"
+" Il dizionario parsificato viene memorizzato in cache finchè\n"
+" un'operazione di write() non viene eseguita.\n"
+" "
+
+msgid ""
+"Write bookmarks\n"
+"\n"
+" Write the given bookmark => hash dictionary to the .hg/bookmarks file\n"
+" in a format equal to those of localtags.\n"
+"\n"
+" We also store a backup of the previous state in undo.bookmarks that\n"
+" can be copied back on rollback.\n"
+" "
+msgstr ""
+"Scrive segnalibri\n"
+"\n"
+" Scrive il dato dizionario segnalibro => hash nel file\n"
+" .hg/bookmarks nello stesso formato di localtags.\n"
+"\n"
+" Viene anche effettuato un backup dello stato\n"
+" precedente in undo.bookmarks che può essere\n"
+" ripristinato con rollback.\n"
+" "
+
+msgid ""
+"Get the current bookmark\n"
+"\n"
+" If we use gittishsh branches we have a current bookmark that\n"
+" we are on. This function returns the name of the bookmark. It\n"
+" is stored in .hg/bookmarks.current\n"
+" "
+msgstr ""
+"Ottiene il segnalibro corrente\n"
+"\n"
+" Se si usano branch in stile git si ha un segnalibro\n"
+" corrente attivo. Questa funzione restituisce il\n"
+" nome del segnalibro. Questi è memorizzato in\n"
+" .hg/bookmarks.current\n"
+" "
+
+msgid ""
+"Set the name of the bookmark that we are currently on\n"
+"\n"
+" Set the name of the bookmark that we are on (hg update <bookmark>).\n"
+" The name is recoreded in .hg/bookmarks.current\n"
+" "
+msgstr ""
+"Imposta il nome del segnalibro sul quale ci si trova attualmente\n"
+"\n"
+" Imposta il nome del segnalibro sul quale ci si trova\n"
+" (hg update <bookmark>). Il nome viene memorizzato in\n"
+" .hg/bookmarks.current\n"
+" "
+
+msgid ""
+"mercurial bookmarks\n"
+"\n"
+" Bookmarks are pointers to certain commits that move when\n"
+" commiting. Bookmarks are local. They can be renamed, copied and\n"
+" deleted. It is possible to use bookmark names in 'hg merge' and 'hg\n"
+" update' to update to a given bookmark.\n"
+"\n"
+" You can use 'hg bookmark NAME' to set a bookmark on the current\n"
+" tip with the given name. If you specify a revision using -r REV\n"
+" (where REV may be an existing bookmark), the bookmark is set to\n"
+" that revision.\n"
+" "
+msgstr ""
+
+msgid "a bookmark of this name does not exist"
+msgstr "non esiste un segnalibro con questo nome"
+
+msgid "a bookmark of the same name already exists"
+msgstr "esiste già un segnalibro con lo stesso nome"
+
+msgid "new bookmark name required"
+msgstr "richiesto nuovo nome per il segnalibro"
+
+msgid "bookmark name required"
+msgstr "richiesto nome per il segnalibro"
+
+msgid "bookmark name cannot contain newlines"
+msgstr "il nome di un segnalibro non può contenere a capo"
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr "un segnalibro non può avere lo stesso nome di una branch esistente"
+
+msgid ""
+"Strip bookmarks if revisions are stripped using\n"
+" the mercurial.strip method. This usually happens during\n"
+" qpush and qpop"
+msgstr ""
+"Elimina i segnalibri se revisioni sono rimosse usando il metodo\n"
+" mercurial.strip. Questo di norma succede durante qpush e qpop"
+
+msgid ""
+"Add a revision to the repository and\n"
+" move the bookmark"
+msgstr ""
+"Aggiunge una revisione al repository e\n"
+" sposta il segnalibro"
+
+msgid "Merge bookmarks with normal tags"
+msgstr "Fa il merge dei segnalibri con tag normali"
+
+msgid ""
+"Set the current bookmark\n"
+"\n"
+" If the user updates to a bookmark we update the .hg/bookmarks.current\n"
+" file.\n"
+" "
+msgstr ""
+"Imposta il segnalibro corrente\n"
+"\n"
+" Se l'utente fa l'update ad un segnalibro viene aggiornato il file\n"
+" .hg/bookmarks.current\n"
+" "
+
+msgid "force"
+msgstr "forza"
+
+msgid "revision"
+msgstr "revisione"
+
+msgid "delete a given bookmark"
+msgstr "elimina un dato segnalibro"
+
+msgid "rename a given bookmark"
+msgstr "rinomina un dato segnalibro"
+
+msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
+msgstr "hg bookmarks [-f] [-d] [-m NOME] [-r REV] [NOME]"
+
+msgid ""
+"Bugzilla integration\n"
+"\n"
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The hook does not change bug\n"
+"status.\n"
+"\n"
+"The hook updates the Bugzilla database directly. Only Bugzilla "
+"installations\n"
+"using MySQL are supported.\n"
+"\n"
+"The hook relies on a Bugzilla script to send bug change notification "
+"emails.\n"
+"That script changes between Bugzilla versions; the 'processmail' script "
+"used\n"
+"prior to 2.18 is replaced in 2.18 and subsequent versions by\n"
+"'config/sendbugmail.pl'. Note that these will be run by Mercurial as the "
+"user\n"
+"pushing the change; you will need to ensure the Bugzilla install file\n"
+"permissions are set appropriately.\n"
+"\n"
+"Configuring the extension:\n"
+"\n"
+" [bugzilla]\n"
+" host Hostname of the MySQL server holding the Bugzilla database.\n"
+" db Name of the Bugzilla database in MySQL. Default 'bugs'.\n"
+" user Username to use to access MySQL server. Default 'bugs'.\n"
+" password Password to use to access MySQL server.\n"
+" timeout Database connection timeout (seconds). Default 5.\n"
+" version Bugzilla version. Specify '3.0' for Bugzilla versions 3.0 "
+"and\n"
+" later, '2.18' for Bugzilla versions from 2.18 and '2.16' for\n"
+" versions prior to 2.18.\n"
+" bzuser Fallback Bugzilla user name to record comments with, if\n"
+" changeset committer cannot be found as a Bugzilla user.\n"
+" bzdir Bugzilla install directory. Used by default notify.\n"
+" Default '/var/www/html/bugzilla'.\n"
+" notify The command to run to get Bugzilla to send bug change\n"
+" notification emails. Substitutes from a map with 3 keys,\n"
+" 'bzdir', 'id' (bug id) and 'user' (committer bugzilla "
+"email).\n"
+" Default depends on version; from 2.18 it is\n"
+" \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl %(id)s %"
+"(user)s\".\n"
+" regexp Regular expression to match bug IDs in changeset commit "
+"message.\n"
+" Must contain one \"()\" group. The default expression "
+"matches\n"
+" 'Bug 1234', 'Bug no. 1234', 'Bug number 1234',\n"
+" 'Bugs 1234,5678', 'Bug 1234 and 5678' and variations "
+"thereof.\n"
+" Matching is case insensitive.\n"
+" style The style file to use when formatting comments.\n"
+" template Template to use when formatting comments. Overrides\n"
+" style if specified. In addition to the usual Mercurial\n"
+" keywords, the extension specifies:\n"
+" {bug} The Bugzilla bug ID.\n"
+" {root} The full pathname of the Mercurial "
+"repository.\n"
+" {webroot} Stripped pathname of the Mercurial "
+"repository.\n"
+" {hgweb} Base URL for browsing Mercurial "
+"repositories.\n"
+" Default 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip The number of slashes to strip from the front of {root}\n"
+" to produce {webroot}. Default 0.\n"
+" usermap Path of file containing Mercurial committer ID to Bugzilla "
+"user\n"
+" ID mappings. If specified, the file should contain one "
+"mapping\n"
+" per line, \"committer\"=\"Bugzilla user\". See also the\n"
+" [usermap] section.\n"
+"\n"
+" [usermap]\n"
+" Any entries in this section specify mappings of Mercurial committer ID\n"
+" to Bugzilla user ID. See also [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl Base URL for browsing Mercurial repositories. Reference from\n"
+" templates as {hgweb}.\n"
+"\n"
+"Activating the extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # run bugzilla hook on every change pulled or pushed in here\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Example configuration:\n"
+"\n"
+"This example configuration is for a collection of Mercurial repositories\n"
+"in /var/local/hg/repos/ used with a local Bugzilla 3.2 installation in\n"
+"/opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Commits add a comment to the Bugzilla bug record of the form:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+msgstr ""
+
+msgid "support for bugzilla version 2.16."
+msgstr "supporto per la versione di bugzilla 2.16."
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr "sto connettendomi a %s:%s come %s, password %s\n"
+
+msgid "run a query."
+msgstr "esegue una query."
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr "query: %s %s\n"
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr "query fallita: %s %s\n"
+
+msgid "get identity of longdesc field"
+msgstr ""
+
+msgid "unknown database schema"
+msgstr "schema del database sconosciuto"
+
+msgid "filter not-existing bug ids from list."
+msgstr "filtra id di bug non esistenti dalla lista"
+
+msgid "filter bug ids from list that already refer to this changeset."
+msgstr ""
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr "il bug %d gi a conoscenza del changeset %s\n"
+
+msgid "tell bugzilla to send mail."
+msgstr "dice a bugzilla di inviare la mail."
+
+msgid "telling bugzilla to send mail:\n"
+msgstr "sto dicendo a bugzilla di inviare la mail:\n"
+
+#, python-format
+msgid " bug %s\n"
+msgstr " bug %s\n"
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr "sto eseguendo il comando di notifica %s\n"
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr "comando di notifica di bugzilla %s"
+
+msgid "done\n"
+msgstr "fatto\n"
+
+msgid "look up numeric bugzilla user id."
+msgstr "cerca l'identificatore utente numerico di bugzilla"
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr "ricercando l'utente %s\n"
+
+msgid "map name of committer to bugzilla user name."
+msgstr "mappa il nome del committente al nome utente bugzilla"
+
+msgid ""
+"see if committer is a registered bugzilla user. Return\n"
+" bugzilla username and userid if so. If not, return default\n"
+" bugzilla username and userid."
+msgstr ""
+"controlla se il committente è un utente registrato bugzilla. In tal\n"
+" caso restituisce userid e username bugzilla. Altrimenti\n"
+" restituisce userid e username bugzilla di default."
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr "impossibile trovare nome utente bugzilla per %s"
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr "impossibile trovare nome utente bugzilla per %s o %s"
+
+msgid ""
+"add comment to bug. try adding comment as committer of\n"
+" changeset, otherwise as default bugzilla user."
+msgstr ""
+
+msgid "support for bugzilla 2.18 series."
+msgstr "supporto per la serie di bugzilla 2.18."
+
+msgid "support for bugzilla 3.0 series."
+msgstr "sopporto per la serie di bugzilla 3.0."
+
+msgid ""
+"return object that knows how to talk to bugzilla version in\n"
+" use."
+msgstr ""
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr "versione di bugzilla %s non supportata"
+
+msgid ""
+"find valid bug ids that are referred to in changeset\n"
+" comments and that do not already have references to this\n"
+" changeset."
+msgstr ""
+
+msgid "update bugzilla bug with reference to changeset."
+msgstr "aggiorna il bug bugzilla con riferimento al changeset."
+
+msgid ""
+"strip leading prefix of repo root and turn into\n"
+" url-safe path."
+msgstr ""
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+"changeset {node|short} nel repository {root} si riferisce al bug {bug}.\n"
+"dettagli:\n"
+"\t{desc|tabindent}"
+
+msgid ""
+"add comment to bugzilla for each changeset that refers to a\n"
+" bugzilla bug id. only add a comment once per bug, so same change\n"
+" seen multiple times does not fill bug with duplicate data."
+msgstr ""
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr "il supporto per python per mysql non è disponibile: %s"
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr ""
+
+#, python-format
+msgid "database error: %s"
+msgstr "errore del database: %s"
+
+msgid ""
+"show the children of the given or working dir revision\n"
+"\n"
+" Print the children of the working directory's revisions.\n"
+" If a revision is given via --rev, the children of that revision\n"
+" will be printed. If a file argument is given, revision in\n"
+" which the file was last changed (after the working directory\n"
+" revision or the argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+
+msgid "show children of the specified rev"
+msgstr "mostra i figli della revisione specificata"
+
+msgid "hg children [-r REV] [FILE]"
+msgstr "hg·children·[-r·REV]·[FILE]"
+
+msgid "command to show certain statistics about revision history"
+msgstr "comando per mostrare alcune statistiche sulla storia delle revisioni"
+
+msgid "Calculate stats"
+msgstr "Calcola statistiche"
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr "La revisione %d è un merge, ignoro...\n"
+
+#, python-format
+msgid "\rgenerating stats: %d%%"
+msgstr "\rsto generando le statistiche: %d%%"
+
+msgid ""
+"graph count of revisions grouped by template\n"
+"\n"
+" Will graph count of changed lines or revisions grouped by template or\n"
+" alternatively by date, if dateformat is used. In this case it will "
+"override\n"
+" template.\n"
+"\n"
+" By default statistics are counted for number of changed lines.\n"
+"\n"
+" Examples:\n"
+"\n"
+" # display count of changed lines for every committer\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # display daily activity graph\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # display activity of developers by month\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # display count of lines changed in every year\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" The map file format used to specify aliases is fairly simple:\n"
+"\n"
+" <alias email> <actual email>"
+msgstr ""
+
+#, python-format
+msgid "assuming %i character terminal\n"
+msgstr "assumo carattere di terminazione %i\n"
+
+msgid "count rate for the specified revision or range"
+msgstr ""
+
+msgid "count rate for revs matching date spec"
+msgstr ""
+
+msgid "template to group changesets"
+msgstr ""
+
+msgid "strftime-compatible format for grouping by date"
+msgstr ""
+
+msgid "count rate by number of changesets"
+msgstr ""
+
+msgid "sort by key (default: sort by count)"
+msgstr "ordina per chiave (default: ordina per conteggio)"
+
+msgid "file with email aliases"
+msgstr "file con alias email"
+
+msgid "show progress"
+msgstr "mostra progresso"
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+msgstr "hg churn [-d DATA] [-r REV] [--aliases FILE] [--progress] [FILE]"
+
+msgid ""
+"add color output to status, qseries, and diff-related commands\n"
+"\n"
+"This extension modifies the status command to add color to its output to\n"
+"reflect file status, the qseries command to add color to reflect patch "
+"status\n"
+"(applied, unapplied, missing), and to diff-related commands to highlight\n"
+"additions, removals, diff headers, and trailing whitespace.\n"
+"\n"
+"Other effects in addition to color, like bold and underlined text, are also\n"
+"available. Effects are rendered with the ECMA-48 SGR control function (aka\n"
+"ANSI escape codes). This module also provides the render_text function,\n"
+"which can be used to add effects to any text.\n"
+"\n"
+"To enable this extension, add this to your .hgrc file:\n"
+"[extensions]\n"
+"color =\n"
+"\n"
+"Default effects my be overriden from the .hgrc file:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' turns off all effects\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+msgstr ""
+
+msgid "Wrap text in commands to turn on each effect."
+msgstr ""
+
+msgid "run the status command with colored output"
+msgstr "esegue il comando status con output colorato"
+
+msgid "run the qseries command with colored output"
+msgstr "esegue il comando qseries con output colorato"
+
+msgid "wrap ui.write for colored diff output"
+msgstr ""
+
+msgid "wrap cmdutil.changeset_printer.showpatch with colored output"
+msgstr ""
+
+msgid "run the diff command with colored output"
+msgstr "esegue il comando diff con output colorato"
+
+msgid "Initialize the extension."
+msgstr "Inizializza l'estensione."
+
+msgid "patch in command to command table and load effect map"
+msgstr ""
+
+msgid "when to colorize (always, auto, or never)"
+msgstr "quando colorare (sempre, auto o mai)"
+
+msgid "don't colorize output"
+msgstr "non colorare l'output"
+
+msgid "converting foreign VCS repositories to Mercurial"
+msgstr "converte repository di altri VCS in Mercurial"
+
+msgid ""
+"convert a foreign SCM repository to a Mercurial one.\n"
+"\n"
+" Accepted source formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Accepted destination formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (history on branches is not preserved)\n"
+"\n"
+" If no revision is given, all revisions will be converted. Otherwise,\n"
+" convert will only import up to the named revision (given in a format\n"
+" understood by the source).\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source with '-hg' appended. If the destination\n"
+" repository doesn't exist, it will be created.\n"
+"\n"
+" If <REVMAP> isn't given, it will be put in a default location\n"
+" (<dest>/.hg/shamap by default). The <REVMAP> is a simple text\n"
+" file that maps each source commit ID to the destination ID for\n"
+" that revision, like so:\n"
+" <source ID> <destination ID>\n"
+"\n"
+" If the file doesn't exist, it's automatically created. It's updated\n"
+" on each commit copied, so convert-repo can be interrupted and can\n"
+" be run repeatedly to copy new commits.\n"
+"\n"
+" The [username mapping] file is a simple text file that maps each source\n"
+" commit author to a destination commit author. It is handy for source "
+"SCMs\n"
+" that use unix logins to identify authors (eg: CVS). One line per author\n"
+" mapping and the line format is:\n"
+" srcauthor=whatever string you want\n"
+"\n"
+" The filemap is a file that allows filtering and remapping of files\n"
+" and directories. Comment lines start with '#'. Each line can\n"
+" contain one of the following directives:\n"
+"\n"
+" include path/to/file\n"
+"\n"
+" exclude path/to/file\n"
+"\n"
+" rename from/file to/file\n"
+"\n"
+" The 'include' directive causes a file, or all files under a\n"
+" directory, to be included in the destination repository, and the\n"
+" exclusion of all other files and dirs not explicitely included.\n"
+" The 'exclude' directive causes files or directories to be omitted.\n"
+" The 'rename' directive renames a file or directory. To rename from a\n"
+" subdirectory into the root of the repository, use '.' as the path to\n"
+" rename to.\n"
+"\n"
+" The splicemap is a file that allows insertion of synthetic\n"
+" history, letting you specify the parents of a revision. This is\n"
+" useful if you want to e.g. give a Subversion merge two parents, or\n"
+" graft two disconnected series of history together. Each entry\n"
+" contains a key, followed by a space, followed by one or two\n"
+" values, separated by spaces. The key is the revision ID in the\n"
+" source revision control system whose parents should be modified\n"
+" (same format as a key in .hg/shamap). The values are the revision\n"
+" IDs (in either the source or destination revision control system)\n"
+" that should be used as the new parents for that node.\n"
+"\n"
+" Mercurial Source\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (boolean)\n"
+" ignore integrity errors when reading. Use it to fix Mercurial\n"
+" repositories with missing revlogs, by converting from and to\n"
+" Mercurial.\n"
+" --config convert.hg.saverev=False (boolean)\n"
+" store original revision ID in changeset (forces target IDs to "
+"change)\n"
+" --config convert.hg.startrev=0 (hg revision identifier)\n"
+" convert start revision and its descendants\n"
+"\n"
+" CVS Source\n"
+" ----------\n"
+"\n"
+" CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+" to indicate the starting point of what will be converted. Direct\n"
+" access to the repository files is not needed, unless of course\n"
+" the repository is :local:. The conversion uses the top level\n"
+" directory in the sandbox to find the CVS repository, and then uses\n"
+" CVS rlog commands to find files to convert. This means that unless\n"
+" a filemap is given, all files under the starting directory will be\n"
+" converted, and that any directory reorganisation in the CVS\n"
+" sandbox is ignored.\n"
+"\n"
+" Because CVS does not have changesets, it is necessary to collect\n"
+" individual commits to CVS and merge them into changesets. CVS\n"
+" source uses its internal changeset merging code by default but can\n"
+" be configured to call the external 'cvsps' program by setting:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" This is a legacy option and may be removed in future.\n"
+"\n"
+" The options shown are the defaults.\n"
+"\n"
+" Internal cvsps is selected by setting\n"
+" --config convert.cvsps=builtin\n"
+" and has a few more configurable options:\n"
+" --config convert.cvsps.fuzz=60 (integer)\n"
+" Specify the maximum time (in seconds) that is allowed between\n"
+" commits with identical user and log message in a single\n"
+" changeset. When very large files were checked in as part\n"
+" of a changeset then the default may not be long enough.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages are\n"
+" matched. If a match occurs, then the conversion process will\n"
+" insert a dummy revision merging the branch on which this log\n"
+" message occurs to the branch indicated in the regex.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages are\n"
+" matched. If a match occurs, then the conversion process will\n"
+" add the most recent revision on the branch indicated in the\n"
+" regex as the second parent of the changeset.\n"
+"\n"
+" The hgext/convert/cvsps wrapper script allows the builtin changeset\n"
+" merging code to be run without doing a conversion. Its parameters and\n"
+" output are similar to that of cvsps 2.1.\n"
+"\n"
+" Subversion Source\n"
+" -----------------\n"
+"\n"
+" Subversion source detects classical trunk/branches/tags layouts.\n"
+" By default, the supplied \"svn://repo/path/\" source URL is\n"
+" converted as a single branch. If \"svn://repo/path/trunk\" exists\n"
+" it replaces the default branch. If \"svn://repo/path/branches\"\n"
+" exists, its subdirectories are listed as possible branches. If\n"
+" \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
+" converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
+" can be overriden with following options. Set them to paths\n"
+" relative to the source URL, or leave them blank to disable\n"
+" autodetection.\n"
+"\n"
+" --config convert.svn.branches=branches (directory name)\n"
+" specify the directory containing branches\n"
+" --config convert.svn.tags=tags (directory name)\n"
+" specify the directory containing tags\n"
+" --config convert.svn.trunk=trunk (directory name)\n"
+" specify the name of the trunk branch\n"
+"\n"
+" Source history can be retrieved starting at a specific revision,\n"
+" instead of being integrally converted. Only single branch\n"
+" conversions are supported.\n"
+"\n"
+" --config convert.svn.startrev=0 (svn revision number)\n"
+" specify start Subversion revision.\n"
+"\n"
+" Perforce Source\n"
+" ---------------\n"
+"\n"
+" The Perforce (P4) importer can be given a p4 depot path or a client\n"
+" specification as source. It will convert all files in the source to\n"
+" a flat Mercurial repository, ignoring labels, branches and "
+"integrations.\n"
+" Note that when a depot path is given you then usually should specify a\n"
+" target directory, because otherwise the target may be named ...-hg.\n"
+"\n"
+" It is possible to limit the amount of source history to be converted\n"
+" by specifying an initial Perforce revision.\n"
+"\n"
+" --config convert.p4.startrev=0 (perforce changelist number)\n"
+" specify initial Perforce revision.\n"
+"\n"
+"\n"
+" Mercurial Destination\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (boolean)\n"
+" dispatch source branches in separate clones.\n"
+" --config convert.hg.tagsbranch=default (branch name)\n"
+" tag revisions branch name\n"
+" --config convert.hg.usebranchnames=True (boolean)\n"
+" preserve branch names\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"create changeset information from CVS\n"
+"\n"
+" This command is intended as a debugging tool for the CVS to Mercurial\n"
+" converter, and can be used as a direct replacement for cvsps.\n"
+"\n"
+" Hg debugcvsps reads the CVS rlog for current directory (or any named\n"
+" directory) in the CVS repository, and converts the log to a series of\n"
+" changesets based on matching commit log entries and dates."
+msgstr ""
+
+msgid "username mapping filename"
+msgstr "nome del file con il mapping degli username"
+
+msgid "destination repository type"
+msgstr "tipo di repository di destinazione"
+
+msgid "remap file names using contents of file"
+msgstr "rimappa i nomi dei file usando il contenuto dei file"
+
+msgid "import up to target revision REV"
+msgstr "importa fino alla revisione target REV"
+
+msgid "source repository type"
+msgstr "tipo del repository sorgente"
+
+msgid "splice synthesized history into place"
+msgstr ""
+
+msgid "try to sort changesets by date"
+msgstr "prova ad ordinare i changeset per data"
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr "hg convert [OPZIONI]... SORGENTE [DEST [REVMAP]]"
+
+msgid "only return changes on specified branches"
+msgstr "restituisce solo le modifiche relative alle branch specificate"
+
+msgid "prefix to remove from file names"
+msgstr "prefisso da rimuovere dai nomi dei file"
+
+msgid "only return changes after or between specified tags"
+msgstr "restituisce solo le modifiche dopo o tra le tag specificate"
+
+msgid "update cvs log cache"
+msgstr "aggiorna la cache dei log di cvs"
+
+msgid "create new cvs log cache"
+msgstr "crea una nuova cache dei log cvs"
+
+msgid "set commit time fuzz in seconds"
+msgstr "imposta il lasso temporale del commit in secondi"
+
+msgid "specify cvsroot"
+msgstr "specifica la cvsroot"
+
+msgid "show parent changesets"
+msgstr "mostra i changeset genitori"
+
+msgid "show current changeset in ancestor branches"
+msgstr "mostra il changeset corrente nei rami degli antenati"
+
+msgid "ignored for compatibility"
+msgstr "ignorato per compatibilità"
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr "hg debugcvsps [OPZIONI]... [PERCORSO]..."
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr "%s non è una revisione valida nella branch corrente"
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr "%s non è più disponibile in %s"
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr "impossibile trovare il tool \"%s\""
+
+#, python-format
+msgid "running: %s\n"
+msgstr "sto eseguendo: %s\n"
+
+#, python-format
+msgid "%s error:\n"
+msgstr "%s errore:\n"
+
+#, python-format
+msgid "%s %s"
+msgstr "%s %s"
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr "impossibile aprire il file di associazione %r: %s"
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr "%s: repository mancante o non supportato"
+
+#, python-format
+msgid "convert: %s\n"
+msgstr "convert: %s\n"
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr "%s: tipo di repository sconosciuto"
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr "ciclo rilevato tra %s e %s"
+
+msgid "not all revisions were sorted"
+msgstr "non tutte le revisioni erano ordinate"
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr "Scrivo il file di associazione degli autori %s\n"
+
+#, python-format
+msgid "Overriding mapping for author %s, was %s, will be %s\n"
+msgstr "Rimpiazzo l'associazione per l'autore %s, era %s, sarà %s\n"
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr "sto associando l'autore %s a %s\n"
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr "Ignoro riga non valida nel file di associazione degli autori %s: %s\n"
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr "inserito %s come genitore di %s\n"
+
+msgid "scanning source...\n"
+msgstr "sto effettuando la scansione della sorgente...\n"
+
+msgid "sorting...\n"
+msgstr "sto ordinando...\n"
+
+msgid "converting...\n"
+msgstr "sto effettuando la conversione...\n"
+
+#, python-format
+msgid "source: %s\n"
+msgstr "sorgente: %s\n"
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr "assumo destinazione %s\n"
+
+#, python-format
+msgid "revision %s is not a patchset number or date"
+msgstr "la revisione %s non è un numero di patchset o una data"
+
+msgid "using builtin cvsps\n"
+msgstr "sto usando cvsps integrato\n"
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr "sto connettendomi a %s\n"
+
+msgid "CVS pserver authentication failed"
+msgstr "autenticazione al pserver CVS fallita"
+
+msgid "server sucks"
+msgstr "il server fa schifo"
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr "%d byte mancanti dal file remoto"
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr "server cvs: %s\n"
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr "risposta CVS sconosciuta: %s"
+
+msgid "collecting CVS rlog\n"
+msgstr "sto collezionando gli rlog CVS\n"
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr "sto leggendo la cache dei log cvs %s\n"
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr "la cache ha %d voci di log\n"
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr "errore durante la lettura della cache: %r\n"
+
+#, python-format
+msgid "running %s\n"
+msgstr "sto eseguendo %s\n"
+
+#, python-format
+msgid "prefix=%r directory=%r root=%r\n"
+msgstr "prefisso=%r directory=%r radice=%r\n"
+
+msgid "RCS file must be followed by working file"
+msgstr "Il file RCS deve essere seguito da un file funzionante"
+
+msgid "must have at least some revisions"
+msgstr "è necessario avere almeno alcune revisioni"
+
+msgid "expected revision number"
+msgstr "numero di revisione atteso"
+
+msgid "revision must be followed by date line"
+msgstr "la revisione deve essere seguita da una riga con la data"
+
+#, python-format
+msgid "found synthetic rev in %s: %r\n"
+msgstr "trovata revisione sintetica in %s: %r\n"
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr "sto scrivendo la cache dei log cvs %s\n"
+
+#, python-format
+msgid "%d log entries\n"
+msgstr "%d voci di log\n"
+
+msgid "creating changesets\n"
+msgstr "sto creando i changeset\n"
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr "changeset sintetici non possono avere genitori multipli"
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr "%d voci di changeset\n"
+
+msgid "Python ElementTree module is not available"
+msgstr "il modulo Python ElementTree non è disponibile"
+
+#, python-format
+msgid "cleaning up %s\n"
+msgstr "sto ripulendo %s\n"
+
+msgid "internal calling inconsistency"
+msgstr "inconsistenza nella chiamata interna"
+
+msgid "errors in filemap"
+msgstr "errori nel filemap"
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr "%s:%d: %r esiste già nell'elenco %s\n"
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr "%s:%d: direttiva sconosciuta %r\n"
+
+msgid "source repository doesn't support --filemap"
+msgstr "il repository sorgente non supporta --filemap"
+
+#, python-format
+msgid "%s does not look like a GNU Arch repo"
+msgstr "%s non sembra essere un repository GNU Arch"
+
+msgid "cannot find a GNU Arch tool"
+msgstr "impossibile trovare un tool GNU Arch"
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr "sto analizzando la versione dell'albero %s...\n"
+
+#, python-format
+msgid ""
+"tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr ""
+"analisi dell'albero interrotta in quanto punta ad un archivio non\n"
+" registrato %s...\n"
+
+#, python-format
+msgid "applying revision %s...\n"
+msgstr "sto applicando la revisione %s...\n"
+
+#, python-format
+msgid "computing changeset between %s and %s...\n"
+msgstr "sto calcolando il changeset tra %s e %s...\n"
+
+#, python-format
+msgid "obtaining revision %s...\n"
+msgstr "sto ottenendo la revisione %s...\n"
+
+#, python-format
+msgid "analysing revision %s...\n"
+msgstr "sto analizzando la revisione %s...\n"
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr ""
+
+#, python-format
+msgid "%s is not a local Mercurial repo"
+msgstr "%s non è un repository locale Mercurial"
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr "sto inizializzando il repository destinatario %s\n"
+
+msgid "run hg sink pre-conversion action\n"
+msgstr ""
+
+msgid "run hg sink post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr "sto effettuando il pull da %s a %s\n"
+
+msgid "updating tags\n"
+msgstr "sto aggiornando le tag\n"
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr "%s non è una revisione iniziale valida"
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr "sto ignorando: %s\n"
+
+msgid "run hg source pre-conversion action\n"
+msgstr ""
+
+msgid "run hg source post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a monotone repo"
+msgstr "%s non sembra essere un repository monotone"
+
+#, python-format
+msgid "copying file in renamed dir from '%s' to '%s'"
+msgstr ""
+
+msgid "reading p4 views\n"
+msgstr "sto leggendo le viste p4\n"
+
+msgid "collecting p4 changelists\n"
+msgstr "sto raccogliendo le changelist p4\n"
+
+msgid "Subversion python bindings could not be loaded"
+msgstr "Non è stato possibile caricare i binding python per Subversion"
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr ""
+"Trovati binding python per Subversion %d.%d, richiesti 1.4 o successivi"
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr ""
+"I binding python per Subversion sono troppo vecchi, richiesti 1.4 o "
+"successivi"
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr "svn: la revisione %s non è un intero"
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr "svn: la revisione iniziale %s non è un intero"
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr "nessuna revisione trovata nel modulo %s"
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr "mi aspettavo di trovare %s in %r, ma non esiste"
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr "trovato %s in %r\n"
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr "ignoro branch vuota %s\n"
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr "trovata branch %s in %d\n"
+
+msgid "svn: start revision is not supported with with more than one branch"
+msgstr "svn: non è supportata una revisione iniziale con più di una branch"
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr "svn: nessuna revisione trovata dopo la revisione iniziale %d"
+
+#, python-format
+msgid "no tags found at revision %d\n"
+msgstr "nessuna tag trovata alla revisione %d\n"
+
+#, python-format
+msgid "ignoring foreign branch %r\n"
+msgstr "ignoro la branch straniera %r\n"
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr "%s non trovato fino alla revisione %d"
+
+#, python-format
+msgid "branch renamed from %s to %s at %d\n"
+msgstr "branch rinominata da %s a %s in %d\n"
+
+#, python-format
+msgid "reparent to %s\n"
+msgstr "riassociato il genitore come %s\n"
+
+#, python-format
+msgid "copied to %s from %s@%s\n"
+msgstr "copiato in %s da %s@%s\n"
+
+#, python-format
+msgid "gone from %s\n"
+msgstr "andato da %s\n"
+
+#, python-format
+msgid "found parent directory %s\n"
+msgstr "trovata directory genitore %s\n"
+
+#, python-format
+msgid "base, entry %s %s\n"
+msgstr "base, voce %s %s\n"
+
+msgid "munge-o-matic\n"
+msgstr "munge-o-matic\n"
+
+#, python-format
+msgid "info: %s %s %s %s\n"
+msgstr "info: %s %s %s %s\n"
+
+#, python-format
+msgid "unknown path in revision %d: %s\n"
+msgstr "percorso sconosciuto nella revisione %d: %s\n"
+
+#, python-format
+msgid "mark %s came from %s:%d\n"
+msgstr "%s marcato come proveniente da %s:%d\n"
+
+#, python-format
+msgid "parsing revision %d (%d changes)\n"
+msgstr "sto effettuando il parsing della revisione %d (%d modifiche)\n"
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr "trovato genitore della branch %s in %d: %s\n"
+
+msgid "no copyfrom path, don't know what to do.\n"
+msgstr ""
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "skipping blacklisted revision %d\n"
+msgstr "sto saltando la revisione nella blacklist %d\n"
+
+#, python-format
+msgid "revision %d has no entries\n"
+msgstr "la revisione %d non ha voci\n"
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr "svn: la branch non ha nessuna revisione %s"
+
+#, python-format
+msgid "%r is not under %r, ignoring\n"
+msgstr "%r non è sotto %r, ignoro\n"
+
+#, python-format
+msgid "initializing svn repo %r\n"
+msgstr "inizializzo il repository svn %r\n"
+
+#, python-format
+msgid "initializing svn wc %r\n"
+msgstr "inizializzo svn wc %r\n"
+
+msgid "unexpected svn output:\n"
+msgstr "output svn inatteso:\n"
+
+msgid "unable to cope with svn output"
+msgstr ""
+
+msgid "XXX TAGS NOT IMPLEMENTED YET\n"
+msgstr "XXX TAG NON ANCORA IMPLEMENTATE\n"
+
+msgid ""
+"\n"
+"The `extdiff' Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working dir. The external diff\n"
+"programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare.\n"
+"\n"
+"To enable this extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.extdiff =\n"
+"\n"
+"The `extdiff' extension also allows to configure new diff commands, so\n"
+"you do not need to type \"hg extdiff -p kdiff3\" always.\n"
+"\n"
+" [extdiff]\n"
+" # add new command that runs GNU diff(1) in 'context diff' mode\n"
+" cdiff = gdiff -Nprc5\n"
+" ## or the old way:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # add new command called vdiff, runs kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # add new command called meld, runs meld (no need to name twice)\n"
+" meld =\n"
+"\n"
+" # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+" #(see http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Non english user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" "
+"in\n"
+" # your .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"You can use -I/-X and list of file or directory names like normal\n"
+"\"hg diff\" command. The `extdiff' extension makes snapshots of only\n"
+"needed files, so running the external diff program will actually be\n"
+"pretty fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+
+msgid "snapshot files as of some revision"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr ""
+
+msgid ""
+"snapshot files from working directory.\n"
+" if not using snapshot, -I/-X does not work and recursive diff\n"
+" in tools like kdiff3 and meld displays too many files."
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from working dir\n"
+msgstr ""
+
+msgid ""
+"Do the actuall diff:\n"
+"\n"
+" - copy to a temp structure if diffing 2 internal revisions\n"
+" - copy to a temp structure if diffing working revision with\n"
+" another one and more than 1 file is changed\n"
+" - just invoke the diff for a single file in the working dir\n"
+" "
+msgstr ""
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr "impossibile specificare sia --rev sia --change"
+
+#, python-format
+msgid "running %r in %s\n"
+msgstr "sto eseguendo %r in %s\n"
+
+#, python-format
+msgid "file changed while diffing. Overwriting: %s (src: %s)\n"
+msgstr "file modificato durante il diff. Sovrascrivo: %s (sorgente: %s)\n"
+
+msgid "cleaning up temp directory\n"
+msgstr "sto ripulendo la directory temporanea\n"
+
+msgid ""
+"use external program to diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files, using\n"
+" an external program. The default program used is diff, with\n"
+" default options \"-Npru\".\n"
+"\n"
+" To select a different program, use the -p option. The program\n"
+" will be passed the names of two directories to compare. To pass\n"
+" additional options to the program, use the -o option. These will\n"
+" be passed before the names of the directories to compare.\n"
+"\n"
+" When two revision arguments are given, then changes are\n"
+" shown between those revisions. If only one revision is\n"
+" specified then that revision is compared to the working\n"
+" directory, and, when no revisions are specified, the\n"
+" working directory files are compared to its parent."
+msgstr ""
+
+msgid "comparison program to run"
+msgstr "programma per i confronti da eseguire"
+
+msgid "pass option to comparison program"
+msgstr "passa l'opzione al programma per i confronti"
+
+msgid "change made by revision"
+msgstr "modifica effettuata dalla revisione"
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr "hg extdiff [OPT]... [FILE]..."
+
+msgid "use closure to save diff command to use"
+msgstr ""
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr "hg %s [OPZIONI]... [FILE]..."
+
+msgid "pulling, updating and merging in one command"
+msgstr "pull, update e merge in un comando"
+
+msgid ""
+"pull changes from a remote repository, merge new changes if needed.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository.\n"
+"\n"
+" If the pulled changes add a new branch head, the head is automatically\n"
+" merged, and the result of the merge is committed. Otherwise, the\n"
+" working directory is updated to include the new changes.\n"
+"\n"
+" When a merge occurs, the newly pulled changes are assumed to be\n"
+" \"authoritative\". The head of the new changes is used as the first\n"
+" parent, with local changes as the second. To switch the merge\n"
+" order, use --switch-parent.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"effettua il pull delle modifiche da un repository remoto, effettua il merge "
+"delle nuove modifiche se necessario.\n"
+"\n"
+" Questo trova tutte le modifiche dal repository al percorso o URL "
+"specificato\n"
+" e le aggiunge al repository locale.\n"
+"\n"
+" Se le modifiche ottenute aggiungono una nuova head, il merge di questa "
+"viene effettuato\n"
+" automaticamente e si effettua il commit del merge. Altrimenti, la\n"
+" directory di lavoro viene aggiornata per includere le nuove modifiche.\n"
+"\n"
+" Quando si verifica un merge, si assume che le modifiche appena ottenute "
+"siano\n"
+" \"autoritarie\". La head delle nuove modifiche è usata come primo\n"
+" genitore, con le modifiche locali come secondo. Per invertire l'ordine\n"
+" di merge, usare --switch-parent.\n"
+"\n"
+" Vedere 'hg help dates' per un elenco dei formati validi per -d/--date.\n"
+" "
+
+msgid ""
+"working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+"directory di lavoro non al tip della branch (usa \"hg update\" per\n"
+" fare il check out della tip della branch)"
+
+msgid "outstanding uncommitted merge"
+msgstr "c'è un merge in sospeso di cui non si è effettuato il commit"
+
+msgid "outstanding uncommitted changes"
+msgstr "ci sono modifiche in sospeso di cui non si è effettuato il commit"
+
+msgid "working directory is missing some files"
+msgstr "alla directory di lavoro mancano alcuni file"
+
+msgid ""
+"multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr ""
+"head multiple in questa branch (usa \"hg heads .\" e \"hg merge\"\n"
+" per fare il merge"
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr "sto facendo pull da %s\n"
+
+msgid "fetch -r doesn't work for remote repositories yet"
+msgstr ""
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr "sto aggiornando a %d:%s\n"
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr "sto facendo il merge con %d:%s\n"
+
+#, python-format
+msgid "Automated merge with %s"
+msgstr "Merge automatico con %s"
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr ""
+"il nuovo changeset %d:%s fa il merge delle modifiche remote con quelle "
+"locali\n"
+
+msgid "a specific revision you would like to pull"
+msgstr "una specifica revisione di cui si desidera fare il pull"
+
+msgid "edit commit message"
+msgstr "modifica il messaggio di commit"
+
+msgid "edit commit message (DEPRECATED)"
+msgstr "modifica il messaggio di commit (DEPRECATO)"
+
+msgid "switch parents when merging"
+msgstr "inverte i genitori durante il merge"
+
+msgid "hg fetch [SOURCE]"
+msgstr "hg fetch [SORGENTE]"
+
+msgid " returns of the good and bad signatures"
+msgstr " restituisce le firme valide e non valide"
+
+msgid "error while verifying signature"
+msgstr "errore durante la verifica della firma"
+
+msgid "create a new gpg instance"
+msgstr "crea una nuova istanza gpg"
+
+msgid ""
+"\n"
+" walk over every sigs, yields a couple\n"
+" ((node, version, sig), (filename, linenumber))\n"
+" "
+msgstr ""
+"\n"
+" percorre ogni firma, restituendo una coppia\n"
+" ((nodo, versione, firma), (nome del file, numero di riga))\n"
+" "
+
+msgid "get the keys who signed a data"
+msgstr "ottiene le chiavi di chi ha firmato i dati"
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr "%s Firma non valida da \"%s\"\n"
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr "%s Nota: La firma è scaduta (firmato da: \"%s\")\n"
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr "%s Nota: Questa chiave è scaduta (firmato da: \"%s\")\n"
+
+msgid "list signed changesets"
+msgstr "elenca i changeset firmati"
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr "il nodo %s:%d non esiste\n"
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr ""
+"verifica tutte le firme che potrebbero esistere per una particolare revisione"
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr "Nessuna firma valida per %s\n"
+
+msgid "associate a string to a key (username, comment)"
+msgstr "associa una stringa ad una chiave (username, commento)"
+
+msgid ""
+"add a signature for the current or given revision\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"aggiunge una firma per la revisione corrente o data\n"
+"\n"
+" Se nessuna revisione è stata specificata, viene usato il genitore\n"
+" della directory di lavoro, oppure tip se non si è eseguito il\n"
+" checkout di nessuna revisione.\n"
+"\n"
+" Vedere 'hg help dates' per un elenco dei formati validi per\n"
+" -d/--date.\n"
+" "
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr ""
+"merge di cui non si è effettuato il commit - si prega di fornire una "
+"revisione specifica"
+
+msgid "Error while signing"
+msgstr "Errore durante la firma"
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+"la copia di lavoro di .hgsigs è cambiata (si prega di fare il commit "
+"manualmente di .hgsigs o usare --force)"
+
+#, python-format
+msgid "Added signature for changeset %s"
+msgstr "Aggiunta firma per il changeset %s"
+
+msgid "map a manifest into some text"
+msgstr "associa un manifesto ad un qualche testo"
+
+msgid "unknown signature version"
+msgstr "versione della firma sconosciuta"
+
+msgid "make the signature local"
+msgstr "rende la firma locale"
+
+msgid "sign even if the sigfile is modified"
+msgstr "firma anche se il sigfile è stato modificato"
+
+msgid "do not commit the sigfile after signing"
+msgstr "non effettuare il commit del sigfile dopo la firma"
+
+msgid "the key id to sign with"
+msgstr "l'id della chiave con cui firmare"
+
+msgid "commit message"
+msgstr "messaggio di commit"
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr "hg sign [OPZIONI]... [REVISIONE]..."
+
+msgid "hg sigcheck REVISION"
+msgstr "hg sigcheck REVISIONE"
+
+msgid "hg sigs"
+msgstr "hg sigs"
+
+msgid ""
+"show revision graphs in terminal windows\n"
+"\n"
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ascii representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+
+msgid ""
+"cset DAG generator yielding (rev, node, [parents]) tuples\n"
+"\n"
+" This generator function walks through the revision history from "
+"revision\n"
+" start to revision stop (which must be less than or equal to start).\n"
+" "
+msgstr ""
+
+msgid ""
+"file cset DAG generator yielding (rev, node, [parents]) tuples\n"
+"\n"
+" This generator function walks through the revision history of a single\n"
+" file from revision start to revision stop (which must be less than or\n"
+" equal to start).\n"
+" "
+msgstr ""
+
+msgid ""
+"grapher for asciigraph on a list of nodes and their parents\n"
+"\n"
+" nodes must generate tuples (node, parents, char, lines) where\n"
+" - parents must generate the parents of node, in sorted order,\n"
+" and max length 2,\n"
+" - char is the char to print as the node symbol, and\n"
+" - lines are the lines to display next to the node.\n"
+" "
+msgstr ""
+
+msgid ""
+"prints an ASCII graph of the DAG returned by the grapher\n"
+"\n"
+" grapher is a generator that emits tuples with the following elements:\n"
+"\n"
+" - Character to use as node's symbol.\n"
+" - List of lines to display as the node's text.\n"
+" - Column of the current node in the set of ongoing edges.\n"
+" - Edges; a list of (col, next_col) indicating the edges between\n"
+" the current node and its parents.\n"
+" - Number of columns (ongoing edges) in the current revision.\n"
+" - The difference between the number of columns (ongoing edges)\n"
+" in the next revision and the number of columns (ongoing edges)\n"
+" in the current revision. That is: -1 means one column removed;\n"
+" 0 means no columns added or removed; 1 means one column added.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "--graph option is incompatible with --%s"
+msgstr "l'opzione --graph è incompatibile con --%s"
+
+msgid ""
+"show revision history alongside an ASCII revision graph\n"
+"\n"
+" Print a revision history alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+
+msgid ""
+"show the outgoing changesets alongside an ASCII revision graph\n"
+"\n"
+" Print the outgoing changesets alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr "sto confrontando con %s\n"
+
+msgid "no changes found\n"
+msgstr "nessuna modifica trovata\n"
+
+msgid ""
+"show the incoming changesets alongside an ASCII revision graph\n"
+"\n"
+" Print the incoming changesets alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+
+msgid "wrap the command"
+msgstr ""
+
+msgid "show the revision DAG"
+msgstr ""
+
+msgid "limit number of changes displayed"
+msgstr ""
+
+msgid "show patch"
+msgstr "mostra patch"
+
+msgid "show the specified revision or range"
+msgstr ""
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr "hg glog [OPZIONI]... [FILE]"
+
+msgid ""
+"CIA notification\n"
+"\n"
+"This is meant to be run as a changegroup or incoming hook.\n"
+"To configure it, set the following options in your hgrc:\n"
+"\n"
+"[cia]\n"
+"# your registered CIA user name\n"
+"user = foo\n"
+"# the name of the project in CIA\n"
+"project = foo\n"
+"# the module (subproject) (optional)\n"
+"#module = foo\n"
+"# Append a diffstat to the log message (optional)\n"
+"#diffstat = False\n"
+"# Template to use for log messages (optional)\n"
+"#template = {desc}\n"
+"{baseurl}/rev/{node}-- {diffstat}\n"
+"# Style to use (optional)\n"
+"#style = foo\n"
+"# The URL of the CIA notification service (optional)\n"
+"# You can use mailto: URLs to send by email, eg\n"
+"# mailto:cia@cia.vc\n"
+"# Make sure to set email.from if you do this.\n"
+"#url = http://cia.vc/\n"
+"# print message instead of sending it (optional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# one of these:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# If you want hyperlinks (optional)\n"
+"baseurl = http://server/path/to/repo\n"
+msgstr ""
+
+msgid " A CIA message "
+msgstr ""
+
+msgid " CIA notification class "
+msgstr ""
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr ""
+
+msgid " send CIA notification "
+msgstr "invia notifica CIA"
+
+msgid "email.from must be defined when sending by email"
+msgstr "email.from deve essere definito quando si mandano mail"
+
+msgid "cia: no user specified"
+msgstr ""
+
+msgid "cia: no project specified"
+msgstr ""
+
+msgid ""
+"browsing the repository in a graphical way\n"
+"\n"
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is\n"
+"not distributed with Mercurial.)\n"
+"\n"
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and hgk.py can be found in the hgext directory.\n"
+"\n"
+"To load the hgext.py extension, add it to your .hgrc file (you have\n"
+"to use your global $HOME/.hgrc file, not one in a repository). You\n"
+"can specify an absolute path:\n"
+"\n"
+" [extensions]\n"
+" hgk=/usr/local/lib/hgk.py\n"
+"\n"
+"Mercurial can also scan the default python library path for a file\n"
+"named 'hgk.py' if you set hgk empty:\n"
+"\n"
+" [extensions]\n"
+" hgk=\n"
+"\n"
+"The hg view command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can\n"
+"specify the path to hgk in your .hgrc file:\n"
+"\n"
+" [hgk]\n"
+" path=/location/of/hgk\n"
+"\n"
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions."
+msgstr ""
+
+msgid "diff trees from two commits"
+msgstr "mostra le differenze tra alberi di due commit"
+
+msgid "output common ancestor information"
+msgstr "stampa in output informazioni sull'antenato comune"
+
+msgid "cat a specific revision"
+msgstr "stampa a video una specifica revisione"
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr "cat-file: tipo o revisione non forniti\n"
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr ""
+
+msgid "parse given revisions"
+msgstr "parsifica le revisioni date"
+
+msgid "print revisions"
+msgstr "stampa revisioni"
+
+msgid "print extension options"
+msgstr "stampa le opzioni dell'estensione"
+
+msgid "start interactive history viewer"
+msgstr "avvia visualizzatore interattivo della storia"
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr "hg view [-l LIMITE] [INTERVALLOREV]"
+
+msgid "generate patch"
+msgstr "genera patch"
+
+msgid "recursive"
+msgstr "ricorsivo"
+
+msgid "pretty"
+msgstr ""
+
+msgid "stdin"
+msgstr "stdin"
+
+msgid "detect copies"
+msgstr "rileva copie"
+
+msgid "search"
+msgstr "ricerca"
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr "hg git-diff-tree [OPZIONI]... NODO1 NODO2 [FILE]..."
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr "hg debug-cat-file [OPZIONI]... TIPO FILE"
+
+msgid "hg debug-config"
+msgstr "hg debug-config"
+
+msgid "hg debug-merge-base node node"
+msgstr "hg debug-merge-base nodo nodo"
+
+msgid "ignored"
+msgstr "ignorato"
+
+msgid "hg debug-rev-parse REV"
+msgstr "hg debug-rev-parse REV"
+
+msgid "header"
+msgstr "intestazione"
+
+msgid "topo-order"
+msgstr "ordine topologico"
+
+msgid "parents"
+msgstr "genitori"
+
+msgid "max-count"
+msgstr "conto massimo"
+
+msgid "hg debug-rev-list [options] revs"
+msgstr "hg debug-rev-list [opzioni] revs"
+
+msgid ""
+"syntax highlighting in hgweb, based on Pygments\n"
+"\n"
+"It depends on the pygments syntax highlighting library:\n"
+"http://pygments.org/\n"
+"\n"
+"To enable the extension add this to hgrc:\n"
+"\n"
+"[extensions]\n"
+"hgext.highlight =\n"
+"\n"
+"There is a single configuration option:\n"
+"\n"
+"[web]\n"
+"pygments_style = <style>\n"
+"\n"
+"The default is 'colorful'.\n"
+"\n"
+"-- Adam Hupp <adam@hupp.org>\n"
+msgstr ""
+
+msgid "inotify-based status acceleration for Linux systems\n"
+msgstr "accelerazione di status per sistemi Linux basata su inotify\n"
+
+msgid "start an inotify server for this repository"
+msgstr "avvia un server inotify per questo repository"
+
+msgid "(found dead inotify server socket; removing it)\n"
+msgstr "(trovato socket morto del server inotify; lo rimuovo)\n"
+
+msgid "(starting inotify server)\n"
+msgstr "(sto avviando il server inotify)\n"
+
+#, python-format
+msgid "could not start inotify server: %s\n"
+msgstr "impossibile avviare il server inotify: %s\n"
+
+#, python-format
+msgid "could not talk to new inotify server: %s\n"
+msgstr "impossibile comunicare con il nuovo server inotify: %s\n"
+
+msgid "(inotify server not running)\n"
+msgstr "(server inotify non in esecuzione\n"
+
+#, python-format
+msgid "failed to contact inotify server: %s\n"
+msgstr "non sono riuscito a contattare il server inotify: %s\n"
+
+msgid "run server in background"
+msgstr "avvia il server in background"
+
+msgid "used internally by daemon mode"
+msgstr "usato internamente dalla modalità demone"
+
+msgid "minutes to sit idle before exiting"
+msgstr "minuti per cui stare in attesa prima di uscire"
+
+msgid "name of file to write process ID to"
+msgstr "nome del file in cui scrivere l'ID del processo"
+
+msgid "hg inserve [OPT]..."
+msgstr "hg inserve [OPT]..."
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr ""
+
+msgid "this system does not seem to support inotify"
+msgstr "questo sistema sembra non supportare inotify"
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr ""
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr ""
+
+msgid "*** counting directories: "
+msgstr "*** sto contando le directory: "
+
+#, python-format
+msgid "found %d\n"
+msgstr "trovato %d\n"
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr ""
+
+#, python-format
+msgid "*** echo %d > %s\n"
+msgstr "*** echo %d > %s\n"
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr ""
+"impossibile controllare %s finchè il limite di controlli di inotify non "
+"verrà aumentato"
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr "servizio inotify non disponibile: %s"
+
+#, python-format
+msgid "watching %r\n"
+msgstr "sto controllando %r\n"
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr "sto controllando le directory sotto %r\n"
+
+#, python-format
+msgid "status: %r dir(%d) -> %s\n"
+msgstr "status: %r dir(%d) -> %s\n"
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr "status: %r %s -> %s\n"
+
+#, python-format
+msgid "%s dirstate reload\n"
+msgstr ""
+
+#, python-format
+msgid "%s end dirstate reload\n"
+msgstr ""
+
+msgid "rescanning due to .hgignore change\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr "evento %s: creato %s\n"
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr "evento %s: cancellato %s\n"
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr "evento %s: modificato %s\n"
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr "il filesystem contenente %s era smontato\n"
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr "%s leggibile: %d byte\n"
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr ""
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr ""
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr ""
+
+#, python-format
+msgid "%s processing %d deferred events as %d\n"
+msgstr ""
+
+#, python-format
+msgid "could not start server: %s"
+msgstr ""
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr ""
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr ""
+
+msgid "finished setup\n"
+msgstr ""
+
+msgid "polling: no timeout\n"
+msgstr ""
+
+#, python-format
+msgid "polling: %sms timeout\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr ""
+
+msgid ""
+"keyword expansion in local repositories\n"
+"\n"
+"This extension expands RCS/CVS-like or self-customized $Keywords$\n"
+"in tracked text files selected by your configuration.\n"
+"\n"
+"Keywords are only expanded in local repositories and not stored in\n"
+"the change history. The mechanism can be regarded as a convenience\n"
+"for the current user or for archive distribution.\n"
+"\n"
+"Configuration is done in the [keyword] and [keywordmaps] sections\n"
+"of hgrc files.\n"
+"\n"
+"Example:\n"
+"\n"
+" [keyword]\n"
+" # expand keywords in every python file except those matching \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Note: the more specific you are in your filename patterns\n"
+" the less you lose speed in huge repos.\n"
+"\n"
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run \"hg kwdemo\".\n"
+"\n"
+"An additional date template filter {date|utcdate} is provided.\n"
+"\n"
+"The default template mappings (view with \"hg kwdemo -d\") can be replaced\n"
+"with customized keywords and templates.\n"
+"Again, run \"hg kwdemo\" to control the results of your config changes.\n"
+"\n"
+"Before changing/disabling active keywords, run \"hg kwshrink\" to avoid\n"
+"the risk of inadvertedly storing expanded keywords in the change history.\n"
+"\n"
+"To force expansion after enabling it, or a configuration change, run\n"
+"\"hg kwexpand\".\n"
+"\n"
+"Also, when committing with the record extension or using mq's qrecord, be "
+"aware\n"
+"that keywords cannot be updated. Again, run \"hg kwexpand\" on the files in\n"
+"question to update keyword expansions after all changes have been checked "
+"in.\n"
+"\n"
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map\n"
+"\"Log = {desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+
+msgid "Returns hgdate in cvs-like UTC format."
+msgstr ""
+
+msgid ""
+"\n"
+" Sets up keyword templates, corresponding keyword regex, and\n"
+" provides keyword substitution functions.\n"
+" "
+msgstr ""
+
+msgid "Replaces keywords in data with expanded template."
+msgstr ""
+
+msgid "Returns data with keywords expanded."
+msgstr ""
+
+msgid ""
+"Returns true if path matches [keyword] pattern\n"
+" and is not a symbolic link.\n"
+" Caveat: localrepository._link fails on Windows."
+msgstr ""
+
+msgid "Overwrites selected files expanding/shrinking keywords."
+msgstr ""
+
+#, python-format
+msgid "overwriting %s %s keywords\n"
+msgstr ""
+
+msgid "Unconditionally removes all keyword substitutions from text."
+msgstr ""
+
+msgid "Returns text with all keyword substitutions removed."
+msgstr ""
+
+msgid "Returns lines with keyword substitutions removed."
+msgstr ""
+
+msgid ""
+"If in restricted mode returns data read from wdir with\n"
+" keyword substitutions removed."
+msgstr ""
+
+msgid ""
+"\n"
+" Subclass of filelog to hook into its read, add, cmp methods.\n"
+" Keywords are \"stored\" unexpanded, and processed on reading.\n"
+" "
+msgstr ""
+
+msgid "Expands keywords when reading filelog."
+msgstr ""
+
+msgid "Removes keyword substitutions when adding to filelog."
+msgstr ""
+
+msgid "Removes keyword substitutions for comparison."
+msgstr ""
+
+msgid ""
+"Bails out if [keyword] configuration is not active.\n"
+" Returns status of working directory."
+msgstr ""
+"Esce se la configurazione [keyword] non è attiva.\n"
+" Restituisce lo stato della directory di lavoro."
+
+msgid "[keyword] patterns cannot match"
+msgstr ""
+
+msgid "no [keyword] patterns configured"
+msgstr ""
+
+msgid "Selects files and passes them to kwtemplater.overwrite."
+msgstr ""
+
+msgid ""
+"print [keywordmaps] configuration and an expansion example\n"
+"\n"
+" Show current, custom, or default keyword template maps\n"
+" and their expansion.\n"
+"\n"
+" Extend current configuration by specifying maps as arguments\n"
+" and optionally by reading from an additional hgrc file.\n"
+"\n"
+" Override current keyword template maps with \"default\" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"\t%s\n"
+msgstr ""
+
+#, python-format
+msgid "creating temporary repo at %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"%s keywords written to %s:\n"
+msgstr ""
+
+msgid "unhooked all commit hooks\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"removing temporary repo %s\n"
+msgstr ""
+
+msgid ""
+"expand keywords in working directory\n"
+"\n"
+" Run after (re)enabling keyword expansion.\n"
+"\n"
+" kwexpand refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid ""
+"print files currently configured for keyword expansion\n"
+"\n"
+" Crosscheck which files in working directory are potential targets for\n"
+" keyword expansion.\n"
+" That is, files matched by [keyword] config patterns but not symlinks.\n"
+" "
+msgstr ""
+
+msgid ""
+"revert expanded keywords in working directory\n"
+"\n"
+" Run before changing/disabling active keywords\n"
+" or if you experience problems with \"hg import\" or \"hg merge\".\n"
+"\n"
+" kwshrink refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid ""
+"Collects [keyword] config in kwtools.\n"
+" Monkeypatches dispatch._parse if needed."
+msgstr ""
+
+msgid "Monkeypatch dispatch._parse to obtain running hg command."
+msgstr ""
+
+msgid ""
+"Sets up repo as kwrepo for keyword substitution.\n"
+" Overrides file method to return kwfilelog instead of filelog\n"
+" if file matches user configuration.\n"
+" Wraps commit to overwrite configured files with updated\n"
+" keyword substitutions.\n"
+" Monkeypatches patch and webcommands."
+msgstr ""
+
+msgid ""
+"Monkeypatch/wrap patch.patchfile.__init__ to avoid\n"
+" rejects or conflicts due to expanded keywords in working dir."
+msgstr ""
+
+msgid ""
+"Monkeypatch patch.diff to avoid expansion except when\n"
+" comparing against working dir."
+msgstr ""
+
+msgid "Wraps webcommands.x turning off keyword expansion."
+msgstr ""
+
+msgid "show default keyword template maps"
+msgstr ""
+
+msgid "read maps from rcfile"
+msgstr ""
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr ""
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr "hg kwexpand [OPZIONI]... [FILE]..."
+
+msgid "show keyword status flags of all files"
+msgstr ""
+
+msgid "show files excluded from expansion"
+msgstr ""
+
+msgid "additionally show untracked files"
+msgstr ""
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr "hg kwfiles [OPZIONI]... [FILE]..."
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr "hg kwshrink [OPZIONI]... [FILE]..."
+
+msgid ""
+"patch management and development\n"
+"\n"
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches).\n"
+"\n"
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets.\n"
+"\n"
+"Common tasks (use \"hg help command\" for more details):\n"
+"\n"
+"prepare repository to work with patches qinit\n"
+"create new patch qnew\n"
+"import existing patch qimport\n"
+"\n"
+"print patch series qseries\n"
+"print applied patches qapplied\n"
+"print name of top applied patch qtop\n"
+"\n"
+"add known patch to applied stack qpush\n"
+"remove patch from applied stack qpop\n"
+"refresh contents of top applied patch qrefresh\n"
+msgstr ""
+
+msgid ""
+"Update all references to a field in the patch header.\n"
+" If none found, add it email style."
+msgstr ""
+"Aggiorna tutti i riferimenti ad un campo nell'intestazione della patch.\n"
+" If none found, add it email style."
+
+msgid ""
+"Remove existing message, keeping the rest of the comments fields.\n"
+" If comments contains 'subject: ', message will prepend\n"
+" the field and a blank line."
+msgstr ""
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr "%s compare più di una volta in %s"
+
+msgid "guard cannot be an empty string"
+msgstr "una guardia non può essere una stringa vuota"
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr "la guardia %r inizia con un carattere non valido: %r"
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr "carattere non valido nella guardia %r: %r"
+
+#, python-format
+msgid "active guards: %s\n"
+msgstr "guardie attive: %s\n"
+
+#, python-format
+msgid "guard %r too short"
+msgstr "la guardia %r è troppo corta"
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr "la guardia %r inizia con un carattere non valido"
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr "sto saltando %s - controllato da %r\n"
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr "sto saltando %s - nessuna guardia corrispondente\n"
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr ""
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr "applicazione della patch %s fallita"
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "update returned %d"
+msgstr "l'aggiornamento ha restituito %d"
+
+msgid "repo commit failed"
+msgstr "commit del repository fallito"
+
+#, python-format
+msgid "unable to read %s"
+msgstr "impossibile leggere %s"
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr "la patch %s non esiste\n"
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr "la patch %s non è applicata\n"
+
+msgid ""
+"Apply patchfile to the working directory.\n"
+" patchfile: file name of patch"
+msgstr ""
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr "patch fallita, impossibile continuare (provare con -v)\n"
+
+#, python-format
+msgid "applying %s\n"
+msgstr "sto applicando %s\n"
+
+#, python-format
+msgid "Unable to read %s\n"
+msgstr "Impossibile leggere %s\n"
+
+#, python-format
+msgid "imported patch %s\n"
+msgstr "patch %s importata\n"
+
+#, python-format
+msgid ""
+"\n"
+"imported patch %s"
+msgstr ""
+"\n"
+"patch %s importata"
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr "la patch %s è vuota\n"
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr ""
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr ""
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr ""
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr ""
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr ""
+
+msgid "no patches applied"
+msgstr ""
+
+msgid "working directory revision is not qtip"
+msgstr ""
+
+msgid "local changes found, refresh first"
+msgstr ""
+
+msgid "local changes found"
+msgstr ""
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr ""
+
+msgid ""
+"options:\n"
+" msg: a string or a no-argument function returning a string\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr "la patch \"%s\" esiste gi"
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr ""
+
+msgid "returns (index, rev, patch)"
+msgstr ""
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr "il nome della patch \"%s\" ambiguo:\n"
+
+#, python-format
+msgid "patch %s not in series"
+msgstr "la patch %s non nella serie"
+
+msgid "(working directory not at tip)\n"
+msgstr "(directory di lavoro non tip)\n"
+
+msgid "no patches in series\n"
+msgstr "nessuna patch nella serie\n"
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr "impossibile fare push su una patch precedente: %s"
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr "qpush: %s gi in cima\n"
+
+#, python-format
+msgid "guarded by %r"
+msgstr "controllato da %r"
+
+msgid "no matching guards"
+msgstr "nessuna guardia corrispondente"
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr "impossibile fare push di '%s' - %s\n"
+
+msgid "all patches are currently applied\n"
+msgstr "tutte le patch sono correntemente applicate\n"
+
+msgid "patch series already fully applied\n"
+msgstr "la serie di patch gi stata applicata completamente\n"
+
+msgid "cleaning up working directory..."
+msgstr "sto pulendo la directory di lavoro..."
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr ""
+"errori durante l'applicazione, si prega di correggere e aggiornare %s\n"
+
+#, python-format
+msgid "now at: %s\n"
+msgstr "ora a: %s\n"
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr "la patch %s non applicata"
+
+msgid "no patches applied\n"
+msgstr "nessuna patch applicata\n"
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr ""
+
+msgid "qpop: forcing dirstate update\n"
+msgstr ""
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr ""
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr ""
+
+msgid "deletions found between repo revs"
+msgstr ""
+
+msgid "patch queue now empty\n"
+msgstr ""
+
+msgid "cannot refresh a revision with children"
+msgstr ""
+
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to "
+"recover)\n"
+msgstr ""
+
+msgid "patch queue directory already exists"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr ""
+
+msgid "No saved patch data found\n"
+msgstr ""
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr "sto ripristinando lo stato: %s\n"
+
+msgid "save entry has children, leaving it alone\n"
+msgstr ""
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr ""
+
+msgid "queue directory updating\n"
+msgstr ""
+
+msgid "Unable to load queue repository\n"
+msgstr "Impossibile caricare il repository della coda\n"
+
+msgid "save: no patches applied, exiting\n"
+msgstr ""
+
+msgid "status is already saved\n"
+msgstr "lo status è già stato salvato\n"
+
+msgid "hg patches saved state"
+msgstr ""
+
+msgid "repo commit failed\n"
+msgstr "commit del repository fallito\n"
+
+msgid ""
+"If all_patches is False, return the index of the next pushable patch\n"
+" in the series, or the series length. If all_patches is True, return "
+"the\n"
+" index of the first patch past the last applied one.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr "la patch %s gi nel file series"
+
+msgid "option \"-r\" not valid when importing files"
+msgstr "l'opzione \"-r\" non è valida quando si importano file"
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr "l'opzione \"-n\" non è valida quando si importano patch multiple"
+
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr ""
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr ""
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr ""
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr "la revisione %d non il genitore di %d"
+
+msgid "-e is incompatible with import from -"
+msgstr "-e incompatibile con l'import da -"
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr "la patch %s non esiste"
+
+msgid "need --name to import a patch from -"
+msgstr "necessario --name per importare una patch da -"
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr "sto aggiungendo %s al file series\n"
+
+msgid ""
+"remove patches from queue\n"
+"\n"
+" The patches must not be applied, unless they are arguments to\n"
+" the --rev parameter. At least one patch or revision is required.\n"
+"\n"
+" With --rev, mq will stop managing the named revisions (converting\n"
+" them to regular mercurial changesets). The qfinish command should be\n"
+" used as an alternative for qdel -r, as the latter option is deprecated.\n"
+"\n"
+" With --keep, the patch files are preserved in the patch directory."
+msgstr ""
+
+msgid "print the patches already applied"
+msgstr "stampa le patch gi applicate"
+
+msgid "print the patches not yet applied"
+msgstr "stampa le patch non ancora applicate"
+
+msgid ""
+"import a patch\n"
+"\n"
+" The patch is inserted into the series after the last applied patch.\n"
+" If no patches have been applied, qimport prepends the patch\n"
+" to the series.\n"
+"\n"
+" The patch will have the same name as its source file unless you\n"
+" give it a new one with --name.\n"
+"\n"
+" You can register an existing patch inside the patch directory\n"
+" with the --existing flag.\n"
+"\n"
+" With --force, an existing patch of the same name will be overwritten.\n"
+"\n"
+" An existing changeset may be placed under mq control with --rev\n"
+" (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+" With --git, patches imported with --rev will use the git diff\n"
+" format. See the diffs help topic for information on why this is\n"
+" important for preserving rename/copy information and permission "
+"changes.\n"
+" "
+msgstr ""
+
+msgid ""
+"init a new queue repository\n"
+"\n"
+" The queue repository is unversioned by default. If -c is\n"
+" specified, qinit will create a separate nested repository\n"
+" for patches (qinit -c may also be run later to convert\n"
+" an unversioned patch repository into a versioned one).\n"
+" You can use qcommit to commit changes to this queue repository."
+msgstr ""
+"inizializza un nuovo repository della coda\n"
+"\n"
+" Il repository della coda di default non è sotto controllo di\n"
+" versione. Se viene specificato -c, qinit creerà un separato\n"
+" repository annidato per le patch (qinit -c potrebbe anche essere\n"
+" eseguito in seguito per convertire un repository non gestito in\n"
+" uno gestito).\n"
+" Si può usare qcommit per effettuare il commit delle modifiche in\n"
+" questo repository della coda."
+
+msgid ""
+"clone main and patch repository at same time\n"
+"\n"
+" If source is local, destination will have no patches applied. If\n"
+" source is remote, this command can not check if patches are\n"
+" applied in source, so cannot guarantee that patches are not\n"
+" applied in destination. If you clone remote repository, be sure\n"
+" before that it has no patches applied.\n"
+"\n"
+" Source patch repository is looked for in <src>/.hg/patches by\n"
+" default. Use -p <url> to change.\n"
+"\n"
+" The patch directory must be a nested mercurial repository, as\n"
+" would be created by qinit -c.\n"
+" "
+msgstr ""
+
+msgid "versioned patch repository not found (see qinit -c)"
+msgstr ""
+"repository delle patch sotto controllo di versione non trovato (vedere qinit "
+"-c)"
+
+msgid "cloning main repo\n"
+msgstr "sto clonando il repository principale\n"
+
+msgid "cloning patch repo\n"
+msgstr "sto clonando il repository delle patch\n"
+
+msgid "stripping applied patches from destination repo\n"
+msgstr "sto rimuovendo le patch applicate dal repository di destinazione\n"
+
+msgid "updating destination repo\n"
+msgstr "sto aggiornando il repository di destinazione\n"
+
+msgid "commit changes in the queue repository"
+msgstr "effettua il commit delle modifiche nel repository della coda"
+
+msgid "print the entire series file"
+msgstr "stampa l'intero file series"
+
+msgid "print the name of the current patch"
+msgstr "stampa il nome della patch corrente"
+
+msgid "print the name of the next patch"
+msgstr "stampa il nome della patch seguente"
+
+msgid "all patches applied\n"
+msgstr "tutte le patch sono state applicate\n"
+
+msgid "print the name of the previous patch"
+msgstr "stampa il nome della patch precedente"
+
+msgid "only one patch applied\n"
+msgstr " stata applicata solo una patch\n"
+
+msgid ""
+"create a new patch\n"
+"\n"
+" qnew creates a new patch on top of the currently-applied patch (if "
+"any).\n"
+" It will refuse to run if there are any outstanding changes unless -f is\n"
+" specified, in which case the patch will be initialized with them. You\n"
+" may also use -I, -X, and/or a list of files after the patch name to add\n"
+" only changes to matching files to the new patch, leaving the rest as\n"
+" uncommitted modifications.\n"
+"\n"
+" -u and -d can be used to set the (given) user and date, respectively.\n"
+" -U and -D set user to current user and date to current date.\n"
+"\n"
+" -e, -m or -l set the patch header as well as the commit message. If "
+"none\n"
+" is specified, the header is empty and the commit message is '[mq]: "
+"PATCH'.\n"
+"\n"
+" Use the --git option to keep the patch in the git extended diff\n"
+" format. Read the diffs help topic for more information on why this\n"
+" is important for preserving permission changes and copy/rename\n"
+" information.\n"
+" "
+msgstr ""
+"crea una nuova patch\n"
+"\n"
+" qnew crea una nuova patch sopra alla patch correntemente applicata\n"
+" (seesiste).\n"
+" Si rifiuter di farlo se ci sono modifiche pendenti a meno che -f\n"
+" non sia stato specificato, nel qual caso la patch sar\n"
+" inizializzata con tali modifiche. Si potrebbe anche usare -I, -X,\n"
+" e/o una lista di file dopo il nome della patch per aggiungere alla\n"
+" patch solamente le modifiche a tali file, lasciando il resto come\n"
+" cambiamenti non salvati.\n"
+"\n"
+" -u e -d possono essere usati per impostare rispettivamente un dato\n"
+" utente e data.\n"
+" -U e -D impostano l'utente all'utente corrente e la data alla data\n"
+" corrente.\n"
+"\n"
+" -e, -m o -l impostano l'intestazione della patch cos come il\n"
+" messaggio di commit. Se nulla stato specificato, l'intestazione\n"
+" sar vuota e il messaggio di commit '[mq]: PATCH'.\n"
+"\n"
+" Usa l'opzione --git per mantenere la patch nel formato diff esteso\n"
+" git. Leggere le informazioni di aiuto sui diff per maggiori\n"
+" informazioni sul motivo per cui quest'opzione importante per\n"
+" preservare modifiche di permessi e informazioni su copie/rinomine.\n"
+" "
+
+msgid ""
+"update the current patch\n"
+"\n"
+" If any file patterns are provided, the refreshed patch will contain "
+"only\n"
+" the modifications that match those patterns; the remaining "
+"modifications\n"
+" will remain in the working directory.\n"
+"\n"
+" If --short is specified, files currently included in the patch will\n"
+" be refreshed just like matched files and remain in the patch.\n"
+"\n"
+" hg add/remove/copy/rename work as usual, though you might want to use\n"
+" git-style patches (--git or [diff] git=1) to track copies and renames.\n"
+" See the diffs help topic for more information on the git diff format.\n"
+" "
+msgstr ""
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr "l'opzione \"-e\" è incompatibile con \"-m\" o \"-l\""
+
+msgid ""
+"diff of the current patch and subsequent modifications\n"
+"\n"
+" Shows a diff which includes the current patch as well as any changes "
+"which\n"
+" have been made in the working directory since the last refresh (thus\n"
+" showing what the current patch would become after a qrefresh).\n"
+"\n"
+" Use 'hg diff' if you only want to see the changes made since the last\n"
+" qrefresh, or 'hg export qtip' if you want to see changes made by the\n"
+" current patch without including changes made since the qrefresh.\n"
+" "
+msgstr ""
+
+msgid ""
+"fold the named patches into the current patch\n"
+"\n"
+" Patches must not yet be applied. Each patch will be successively\n"
+" applied to the current patch in the order given. If all the\n"
+" patches apply successfully, the current patch will be refreshed\n"
+" with the new cumulative patch, and the folded patches will\n"
+" be deleted. With -k/--keep, the folded patch files will not\n"
+" be removed afterwards.\n"
+"\n"
+" The header for each folded patch will be concatenated with\n"
+" the current patch header, separated by a line of '* * *'."
+msgstr ""
+
+msgid "qfold requires at least one patch name"
+msgstr ""
+
+msgid "No patches applied"
+msgstr "Nessuna patch applicata"
+
+#, python-format
+msgid "Skipping already folded patch %s"
+msgstr "Salto patch già ripiegata %s"
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr "qfold non può ripiegare la patch già applicata %s"
+
+#, python-format
+msgid "Error folding patch %s"
+msgstr "Errore nel ripiegare la patch %s"
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr ""
+
+msgid ""
+"set or print guards for a patch\n"
+"\n"
+" Guards control whether a patch can be pushed. A patch with no\n"
+" guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+" pushed only if the qselect command has activated it. A patch with\n"
+" a negative guard (\"-foo\") is never pushed if the qselect command\n"
+" has activated it.\n"
+"\n"
+" With no arguments, print the currently active guards.\n"
+" With arguments, set guards for the named patch.\n"
+" NOTE: Specifying negative guards now requires '--'.\n"
+"\n"
+" To set guards on another patch:\n"
+" hg qguard -- other.patch +2.6.17 -stable\n"
+" "
+msgstr ""
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr ""
+
+msgid "no patch to work with"
+msgstr ""
+
+#, python-format
+msgid "no patch named %s"
+msgstr ""
+
+msgid "print the header of the topmost or specified patch"
+msgstr ""
+
+msgid ""
+"push the next patch onto the stack\n"
+"\n"
+" When --force is applied, all local changes in patched files will be "
+"lost.\n"
+" "
+msgstr ""
+
+msgid "no saved queues found, please use -n\n"
+msgstr ""
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr ""
+
+msgid ""
+"pop the current patch off the stack\n"
+"\n"
+" By default, pops off the top of the patch stack. If given a patch name,\n"
+" keeps popping off patches until the named patch is at the top of the "
+"stack.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr ""
+
+msgid ""
+"rename a patch\n"
+"\n"
+" With one argument, renames the current patch to PATCH1.\n"
+" With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+"rinomina una patch\n"
+"\n"
+" Con un argomento rinomina la patch corrente in PATCH1.\n"
+" Con due argomenti rinomina PATCH1 in PATCH2."
+
+#, python-format
+msgid "%s already exists"
+msgstr "%s esiste già"
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr "Una patch chiamata %s esiste già nel file series"
+
+msgid "restore the queue state saved by a rev"
+msgstr "ripristina lo stato della coda salvato da una revisione"
+
+msgid "save current queue state"
+msgstr "salva lo stato corrente della coda"
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr "la destinazione %s esiste e non è una directory"
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr "la destinazione %s esiste, usare -f per forzare l'operazione"
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr "copia %s a %s\n"
+
+msgid ""
+"strip a revision and all its descendants from the repository\n"
+"\n"
+" If one of the working dir's parent revisions is stripped, the working\n"
+" directory will be updated to the parent of the stripped revision.\n"
+" "
+msgstr ""
+"elimina una revisione e tutti i suoi discendenti dal repository\n"
+"\n"
+" Se una delle revisioni genitore della directory di lavoro\n"
+" viene rimossa, la directory di lavorò sarà aggiornata al\n"
+" genitore della revisione rimossa.\n"
+" "
+
+msgid ""
+"set or print guarded patches to push\n"
+"\n"
+" Use the qguard command to set or print guards on patch, then use\n"
+" qselect to tell mq which guards to use. A patch will be pushed if it\n"
+" has no guards or any positive guards match the currently selected "
+"guard,\n"
+" but will not be pushed if any negative guards match the current guard.\n"
+" For example:\n"
+"\n"
+" qguard foo.patch -stable (negative guard)\n"
+" qguard bar.patch +stable (positive guard)\n"
+" qselect stable\n"
+"\n"
+" This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+" it has a negative match) but push bar.patch (because it\n"
+" has a positive match).\n"
+"\n"
+" With no arguments, prints the currently active guards.\n"
+" With one argument, sets the active guard.\n"
+"\n"
+" Use -n/--none to deactivate guards (no other arguments needed).\n"
+" When no guards are active, patches with positive guards are skipped\n"
+" and patches with negative guards are pushed.\n"
+"\n"
+" qselect can change the guards on applied patches. It does not pop\n"
+" guarded patches by default. Use --pop to pop back to the last applied\n"
+" patch that is not guarded. Use --reapply (which implies --pop) to push\n"
+" back to the current patch afterwards, but skip guarded patches.\n"
+"\n"
+" Use -s/--series to print a list of all guards in the series file (no\n"
+" other arguments needed). Use -v for more information."
+msgstr ""
+
+msgid "guards deactivated\n"
+msgstr "guardie disattivate\n"
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr ""
+"il numero di patch non applicate, senza guardia è cambiato da %d a %d\n"
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr "il numero di patch applicate aventi guardia è cambiato da %d a %d\n"
+
+msgid "guards in series file:\n"
+msgstr "guardie nel file series:\n"
+
+msgid "no guards in series file\n"
+msgstr "nessuna guardia nel file series\n"
+
+msgid "active guards:\n"
+msgstr "guardie attive:\n"
+
+msgid "no active guards\n"
+msgstr "nessuna guardia attiva\n"
+
+msgid "popping guarded patches\n"
+msgstr "sto disapplicando patch che hanno una guardia\n"
+
+msgid "reapplying unguarded patches\n"
+msgstr "sto riapplicando patch che non hanno guardia\n"
+
+msgid ""
+"move applied patches into repository history\n"
+"\n"
+" Finishes the specified revisions (corresponding to applied patches) by\n"
+" moving them out of mq control into regular repository history.\n"
+"\n"
+" Accepts a revision range or the --applied option. If --applied is\n"
+" specified, all applied mq revisions are removed from mq control.\n"
+" Otherwise, the given revisions must be at the base of the stack of\n"
+" applied patches.\n"
+"\n"
+" This can be especially useful if your changes have been applied to an\n"
+" upstream repository, or if you are about to push your changes to "
+"upstream.\n"
+" "
+msgstr ""
+
+msgid "no revisions specified"
+msgstr "nessuna revisione specificata"
+
+msgid "cannot commit over an applied mq patch"
+msgstr "impossibile effettuare commit su una patch mq applicata"
+
+msgid "source has mq patches applied"
+msgstr "la sorgente ha patch mq applicate"
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr "il file dello stato di mq fa riferimento al nodo sconosciuto %s\n"
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr "La tag %s annulla una patch mq con lo stesso nome\n"
+
+msgid "cannot import over an applied patch"
+msgstr "impossibile importare sopra ad una patch applicata"
+
+msgid "print first line of patch header"
+msgstr "stampa la prima riga dell'intestazione della patch"
+
+msgid "hg qapplied [-s] [PATCH]"
+msgstr "hg qapplied [-s] [PATCH]"
+
+msgid "use pull protocol to copy metadata"
+msgstr "usa il protocollo pull per copiare i metadati"
+
+msgid "do not update the new working directories"
+msgstr "non aggiornare le nuove directory di lavoro"
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr "usa trasferimento non compresso (veloce su LAN)"
+
+msgid "location of source patch repo"
+msgstr "posizione del repository delle patch sorgente"
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr "hg qclone [OPZIONI]... SORGENTE [DEST]"
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr "hg qcommit [OPZIONI]... [FILE]..."
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr "hg qdiff [OPZIONI]... [FILE]..."
+
+msgid "keep patch file"
+msgstr "mantieni il file della patch"
+
+msgid "stop managing a revision"
+msgstr "smetti di gestire una revisione"
+
+msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
+msgstr "hg qdelete [-k] [-r REV]... [PATCH]..."
+
+msgid "edit patch header"
+msgstr "modifica l'intestazione della patch"
+
+msgid "keep folded patch files"
+msgstr ""
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr "hg qfold [-e] [-k] [-m TESTO] [-l FILE] PATCH..."
+
+msgid "overwrite any local changes"
+msgstr "sovrascrivi ogni modifica locale"
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr "hg qgoto [OPZIONI]... PATCH"
+
+msgid "list all patches and guards"
+msgstr "elenca tutte le patch e le guardie"
+
+msgid "drop all guards"
+msgstr "scarta tutte le guardie"
+
+msgid "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+msgstr "hg qguard [-l] [-n] -- [PATCH] [+GUARDIA]... [-GUARDIA]..."
+
+msgid "hg qheader [PATCH]"
+msgstr "hg qheader [PATCH]"
+
+msgid "import file in patch dir"
+msgstr "importa il file nella directory delle patch"
+
+msgid "patch file name"
+msgstr "nome del file della patch"
+
+msgid "overwrite existing files"
+msgstr "sovrascrive i file esistenti"
+
+msgid "place existing revisions under mq control"
+msgstr "metti le revisioni esistenti sotto il controllo di mq"
+
+msgid "use git extended diff format"
+msgstr "usa il formato diff git esteso"
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-r REV]... FILE..."
+msgstr "hg qimport [-e] [-n NOME] [-f] [-g] [-r REV]... FILE..."
+
+msgid "create queue repository"
+msgstr "crea il repository della coda"
+
+msgid "hg qinit [-c]"
+msgstr "hg qinit [-c]"
+
+msgid "import uncommitted changes into patch"
+msgstr "importa nella patch le modifiche di cui non si è effettuato il commit"
+
+msgid "add \"From: <current user>\" to patch"
+msgstr "aggiunge \"Da: <utente corrente>\" alla patch"
+
+msgid "add \"From: <given user>\" to patch"
+msgstr "aggiunge \"Da: <utente fornito>\" alla patch"
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr "aggiunge \"Data: <data corrente>\" alla patch"
+
+msgid "add \"Date: <given date>\" to patch"
+msgstr "aggiunge \"Data: <data fornita>\" alla patch"
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+msgstr "hg qnew [-e] [-m TESTO] [-l FILE] [-f] PATCH [FILE]..."
+
+msgid "hg qnext [-s]"
+msgstr "hg qnext [-s]"
+
+msgid "hg qprev [-s]"
+msgstr "hg qprev [-s]"
+
+msgid "pop all patches"
+msgstr "disapplica tutte le patch"
+
+msgid "queue name to pop"
+msgstr "nome della coda da disapplicare"
+
+msgid "forget any local changes"
+msgstr "dimentica ogni modifica locale"
+
+msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+msgstr "hg qpop [-a] [-n NOME] [-f] [PATCH | INDEX]"
+
+msgid "apply if the patch has rejects"
+msgstr ""
+
+msgid "list patch name in commit text"
+msgstr "elenca il nome della patch nel testo di commit"
+
+msgid "apply all patches"
+msgstr "applica tutte le patch"
+
+msgid "merge from another queue"
+msgstr "effettua il merge da un'altra coda"
+
+msgid "merge queue name"
+msgstr "nome della coda del merge"
+
+msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+msgstr "hg qpush [-f] [-l] [-a] [-m] [-n NOME] [PATCH | INDICE]"
+
+msgid "refresh only files already in the patch and specified files"
+msgstr "aggiorna solo file già nella patch e quelli specificati"
+
+msgid "add/update \"From: <current user>\" in patch"
+msgstr "aggiunge/aggiorna \"Da: <utente corrente>\" nella patch"
+
+msgid "add/update \"From: <given user>\" in patch"
+msgstr "aggiunge/aggiorna \"Da: <utente fornito>\" nella patch"
+
+msgid "update \"Date: <current date>\" in patch (if present)"
+msgstr "aggiorna \"Data: <data corrente>\" nella patch (se presente)"
+
+msgid "update \"Date: <given date>\" in patch (if present)"
+msgstr "aggiorna \"Data: <data fornita>\" nella patch (se presente)"
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr "hg qrefresh [-I] [-X] [-e] [-m TESTO] [-l FILE] [-s] [FILE]..."
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr "hg qrename PATCH1 [PATCH2]"
+
+msgid "delete save entry"
+msgstr "elimina la voce salvata"
+
+msgid "update queue working dir"
+msgstr "aggiorna la directory di lavoro della coda"
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr "hg qrestore [-d] [-u] REV"
+
+msgid "copy patch directory"
+msgstr "copia la directory delle patch"
+
+msgid "copy directory name"
+msgstr "copia il nome della directory"
+
+msgid "clear queue status file"
+msgstr "pulisce il file di stato della coda"
+
+msgid "force copy"
+msgstr "forza la copia"
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr "hg qsave [-m TESTO] [-l FILE] [-c] [-n NOME] [-e] [-f]"
+
+msgid "disable all guards"
+msgstr "disabilita tutte le guardie"
+
+msgid "list all guards in series file"
+msgstr "elenca tutte le guardie nel file series"
+
+msgid "pop to before first guarded applied patch"
+msgstr "disapplica fino alla prima patch con guardia applicata"
+
+msgid "pop, then reapply patches"
+msgstr "disapplica e poi riapplica le patch"
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr "hg qselect [OPZIONE]... [GUARDIA]..."
+
+msgid "print patches not in series"
+msgstr "stampa le patch non in series"
+
+msgid "hg qseries [-ms]"
+msgstr "hg qseries [-ms]"
+
+msgid "force removal with local changes"
+msgstr "forza la rimozione con modifiche locali"
+
+msgid "bundle unrelated changesets"
+msgstr ""
+
+msgid "no backups"
+msgstr "nessun backup"
+
+msgid "hg strip [-f] [-b] [-n] REV"
+msgstr "hg strip [-f] [-b] [-n] REV"
+
+msgid "hg qtop [-s]"
+msgstr "hg qtop [-s]"
+
+msgid "hg qunapplied [-s] [PATCH]"
+msgstr "hg qunapplied [-s] [PATCH]"
+
+msgid "finish all applied changesets"
+msgstr "finalizza tutti i changeset applicati"
+
+msgid "hg qfinish [-a] [REV...]"
+msgstr "hg qfinish [-a] [REV...]"
+
+msgid ""
+"hook extension to email notifications on commits/pushes\n"
+"\n"
+"Subscriptions can be managed through hgrc. Default mode is to print\n"
+"messages to stdout, for testing and configuring.\n"
+"\n"
+"To use, configure notify extension and enable in hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # one email for each incoming changeset\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # batch emails when many changesets incoming at one time\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # config items go in here\n"
+"\n"
+" config items:\n"
+"\n"
+" REQUIRED:\n"
+" config = /path/to/file # file containing subscriptions\n"
+"\n"
+" OPTIONAL:\n"
+" test = True # print messages to stdout for testing\n"
+" strip = 3 # number of slashes to strip for url paths\n"
+" domain = example.com # domain to use if committer missing domain\n"
+" style = ... # style file to use when formatting email\n"
+" template = ... # template to use when formatting email\n"
+" incoming = ... # template to use when run as incoming hook\n"
+" changegroup = ... # template when run as changegroup hook\n"
+" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n"
+" maxsubject = 67 # truncate subject line longer than this\n"
+" diffstat = True # add a diffstat before the diff content\n"
+" sources = serve # notify if source of incoming changes in this "
+"list\n"
+" # (serve == ssh or http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # email address to send as if none given\n"
+" [web]\n"
+" baseurl = http://hgserver/... # root of hg web site for browsing commits\n"
+"\n"
+" notify config file has same format as regular hgrc. it has two\n"
+" sections so you can express subscriptions in whatever way is handier\n"
+" for you.\n"
+"\n"
+" [usersubs]\n"
+" # key is subscriber email, value is \",\"-separated list of glob "
+"patterns\n"
+" user@host = pattern\n"
+"\n"
+" [reposubs]\n"
+" # key is glob pattern, value is \",\"-separated list of subscriber "
+"emails\n"
+" pattern = user@host\n"
+"\n"
+" glob patterns are matched against path to repo root.\n"
+"\n"
+" if you like, you can put notify config file in repo that users can\n"
+" push changes to, they can manage their own subscriptions."
+msgstr ""
+
+msgid "email notification class."
+msgstr "classe per la notifica via email."
+
+msgid "strip leading slashes from local path, turn into web-safe path."
+msgstr ""
+
+msgid "try to clean up email addresses."
+msgstr "prova a pulire gli indirizzi email."
+
+msgid "return list of email addresses of subscribers to this repo."
+msgstr "restituisce gli indirizzi email dei sottoscritti a questo repository"
+
+msgid "format one changeset."
+msgstr "formatta un changeset."
+
+msgid "true if incoming changes from this source should be skipped."
+msgstr ""
+"vero se le modifiche in entrata da questa sorgente dovrebbero essere saltate."
+
+msgid "send message."
+msgstr "invia messaggio."
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr "%s: %d nuovi changeset"
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr "notify: sto inviando a %d sottoscritti %d modifiche\n"
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):\n"
+"\n"
+msgstr ""
+"\n"
+"diff (troncati da %d linee a %d):\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):\n"
+"\n"
+msgstr ""
+"\n"
+"diff (%d linee):\n"
+"\n"
+
+msgid ""
+"send email notifications to interested subscribers.\n"
+"\n"
+" if used as changegroup hook, send one email for all changesets in\n"
+" changegroup. else send one email per changeset."
+msgstr ""
+
+#, python-format
+msgid "notify: no subscribers to repo %s\n"
+msgstr ""
+
+#, python-format
+msgid "notify: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+msgid ""
+"browse command output with external pager\n"
+"\n"
+"To set the pager that should be used, set the application variable:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"If no pager is set, the pager extensions uses the environment\n"
+"variable $PAGER. If neither pager.pager, nor $PAGER is set, no pager\n"
+"is used.\n"
+"\n"
+"If you notice \"BROKEN PIPE\" error messages, you can disable them\n"
+"by setting:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"You can also enable the pager only for certain commands using pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"If pager.attend is present, pager.ignore will be ignored.\n"
+"\n"
+"To ignore global commands like \"hg version\" or \"hg help\", you have to "
+"specify\n"
+"them in the global .hgrc\n"
+msgstr ""
+
+msgid ""
+"use suffixes to refer to ancestor revisions\n"
+"\n"
+"This extension allows you to use git-style suffixes to refer to\n"
+"the ancestors of a specific revision.\n"
+"\n"
+"For example, if you can refer to a revision as \"foo\", then:\n"
+"\n"
+"- foo^N = Nth parent of foo:\n"
+" foo^0 = foo\n"
+" foo^1 = first parent of foo\n"
+" foo^2 = second parent of foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nth first grandparent of foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = first parent of foo\n"
+" foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
+msgstr ""
+
+msgid ""
+"sending Mercurial changesets as a series of patch emails\n"
+"\n"
+"The series is started off with a \"[PATCH 0 of N]\" introduction,\n"
+"which describes the series as a whole.\n"
+"\n"
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+"the first line of the changeset description as the subject text.\n"
+"The message contains two or three body parts:\n"
+"\n"
+" The remainder of the changeset description.\n"
+"\n"
+" [Optional] The result of running diffstat on the patch.\n"
+"\n"
+" The patch itself, as generated by \"hg export\".\n"
+"\n"
+"Each message refers to all of its predecessors using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in\n"
+"threaded mail and news readers, and in mail archives.\n"
+"\n"
+"For each changeset, you will be prompted with a diffstat summary and\n"
+"the changeset summary, so you can be sure you are sending the right "
+"changes.\n"
+"\n"
+"To enable this extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.patchbomb =\n"
+"\n"
+"To configure other defaults, add a section like this to your hgrc file:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Then you can use the \"hg email\" command to mail a series of changesets\n"
+"as a patchbomb.\n"
+"\n"
+"To avoid sending patches prematurely, it is a good idea to first run\n"
+"the \"email\" command with the \"-n\" option (test only). You will be\n"
+"prompted for an email recipient address, a subject an an introductory\n"
+"message describing the patches of your patchbomb. Then when all is\n"
+"done, patchbomb messages are displayed. If PAGER environment variable\n"
+"is set, your pager will be fired up once for each patchbomb message, so\n"
+"you can verify everything is alright.\n"
+"\n"
+"The \"-m\" (mbox) option is also very useful. Instead of previewing\n"
+"each patchbomb message in a pager or sending the messages directly,\n"
+"it will create a UNIX mailbox file with the patch emails. This\n"
+"mailbox file can be previewed with any mail user agent which supports\n"
+"UNIX mbox files, e.g. with mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"When you are previewing the patchbomb messages, you can use `formail'\n"
+"(a utility that is commonly installed as part of the procmail package),\n"
+"to send each message out:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"That should be all. Now your patchbomb is on its way out.\n"
+"\n"
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatable mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs directly\n"
+"from the commandline. See the [email] and [smtp] sections in hgrc(5)\n"
+"for details."
+msgstr ""
+
+msgid "Please enter a valid value.\n"
+msgstr "Si prega di inserire un valore valido.\n"
+
+msgid "does the diffstat above look okay? "
+msgstr "il diffstat di sopra sembra corretto? "
+
+msgid "diffstat rejected"
+msgstr "diffstat rifiutato"
+
+msgid ""
+"send changesets by email\n"
+"\n"
+" By default, diffs are sent in the format generated by hg export,\n"
+" one per message. The series starts with a \"[PATCH 0 of N]\"\n"
+" introduction, which describes the series as a whole.\n"
+"\n"
+" Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+" the first line of the changeset description as the subject text.\n"
+" The message contains two or three body parts. First, the rest of\n"
+" the changeset description. Next, (optionally) if the diffstat\n"
+" program is installed, the result of running diffstat on the patch.\n"
+" Finally, the patch itself, as generated by \"hg export\".\n"
+"\n"
+" With --outgoing, emails will be generated for patches not\n"
+" found in the destination repository (or only those which are\n"
+" ancestors of the specified revisions if any are provided)\n"
+"\n"
+" With --bundle, changesets are selected as for --outgoing,\n"
+" but a single email containing a binary Mercurial bundle as an\n"
+" attachment will be sent.\n"
+"\n"
+" Examples:\n"
+"\n"
+" hg email -r 3000 # send patch 3000 only\n"
+" hg email -r 3000 -r 3001 # send patches 3000 and 3001\n"
+" hg email -r 3000:3005 # send patches 3000 through 3005\n"
+" hg email 3000 # send patch 3000 (deprecated)\n"
+"\n"
+" hg email -o # send all patches not in default\n"
+" hg email -o DEST # send all patches not in DEST\n"
+" hg email -o -r 3000 # send all ancestors of 3000 not in default\n"
+" hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST\n"
+"\n"
+" hg email -b # send bundle of all patches not in default\n"
+" hg email -b DEST # send bundle of all patches not in DEST\n"
+" hg email -b -r 3000 # bundle of all ancestors of 3000 not in "
+"default\n"
+" hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST\n"
+"\n"
+" Before using this command, you will need to enable email in your hgrc.\n"
+" See the [email] section in hgrc(5) for details.\n"
+" "
+msgstr ""
+
+msgid "Return the revisions present locally but not in dest"
+msgstr ""
+
+msgid "specify at least one changeset with -r or -o"
+msgstr ""
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr ""
+
+msgid "too many destinations"
+msgstr "troppe destinazioni"
+
+msgid "use only one form to specify the revision"
+msgstr "usa solo un formato per specificare la revisione"
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series.\n"
+"\n"
+msgstr ""
+"\n"
+"Scrivi il messaggio introduttivo per la serie di patch.\n"
+"\n"
+
+#, python-format
+msgid ""
+"This patch series consists of %d patches.\n"
+"\n"
+msgstr ""
+"Questa serie di patch consiste di %d patch.\n"
+"\n"
+
+msgid "Final summary:\n"
+msgstr "Sommario finale:\n"
+
+msgid "Displaying "
+msgstr "Sto mostrando "
+
+msgid "Writing "
+msgstr "Sto scrivendo "
+
+msgid "Sending "
+msgstr "Sto inviando "
+
+msgid "send patches as attachments"
+msgstr "invia patch come allegati"
+
+msgid "send patches as inline attachments"
+msgstr "invia patch come allegati in linea"
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr "indirizzi mail dei destinatari in copia nascosta"
+
+msgid "email addresses of copy recipients"
+msgstr "indirizzi mail dei destinatari in copia"
+
+msgid "add diffstat output to messages"
+msgstr "aggiungi l'output del diffstat ai messaggi"
+
+msgid "use the given date as the sending date"
+msgstr "usa la data fornita come data di invio"
+
+msgid "use the given file as the series description"
+msgstr "usa il file fornito come descrizione della serie"
+
+msgid "email address of sender"
+msgstr "indirizzo email del mittente"
+
+msgid "print messages that would be sent"
+msgstr "stampa i messaggi che verrebbero inviati"
+
+msgid "write messages to mbox file instead of sending them"
+msgstr "scrive i messaggi nel file mbox invece di inviarli"
+
+msgid "subject of first message (intro or single patch)"
+msgstr "soggetto del primo messaggio (introduzione o patch singola)"
+
+msgid "email addresses of recipients"
+msgstr "indirizzi mail dei destinatari"
+
+msgid "omit hg patch header"
+msgstr "ometti l'intestazione della patch hg"
+
+msgid "send changes not found in the target repository"
+msgstr "invia le modifiche non trovate nel repository di destinazione"
+
+msgid "send changes not in target as a binary bundle"
+msgstr "invia le modifiche non in target come bundle binario"
+
+msgid "file name of the bundle attachment"
+msgstr "nome del file dell'allegato bundle"
+
+msgid "a revision to send"
+msgstr "una revisione da inviare"
+
+msgid "run even when remote repository is unrelated (with -b)"
+msgstr "esegui anche quando il repository remoto non è collegato (con -b)"
+
+msgid "a base changeset to specify instead of a destination (with -b)"
+msgstr "un changeset base da specificare invece di una destinazione (con -b)"
+
+msgid "send an introduction email for a single patch"
+msgstr "invia una mail introduttiva per una patch singola"
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr "hg email [OPZIONI]... [DEST]..."
+
+msgid ""
+"removes files not tracked by Mercurial\n"
+"\n"
+" Delete files not known to Mercurial. This is useful to test local and\n"
+" uncommitted changes in an otherwise-clean source tree.\n"
+"\n"
+" This means that purge will delete:\n"
+" - Unknown files: files marked with \"?\" by \"hg status\"\n"
+" - Empty directories: in fact Mercurial ignores directories unless they\n"
+" contain files under source control managment\n"
+" But it will leave untouched:\n"
+" - Modified and unmodified tracked files\n"
+" - Ignored files (unless --all is specified)\n"
+" - New files added to the repository (with \"hg add\")\n"
+"\n"
+" If directories are given on the command line, only files in these\n"
+" directories are considered.\n"
+"\n"
+" Be careful with purge, as you could irreversibly delete some files you\n"
+" forgot to add to the repository. If you only want to print the list of\n"
+" files that this program would delete, use the --print option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr "%s non può essere rimosso"
+
+#, python-format
+msgid "warning: %s\n"
+msgstr "attenzione: %s\n"
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr "Sto rimuovendo il file %s\n"
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr "Sto rimuovendo la directory %s\n"
+
+msgid "abort if an error occurs"
+msgstr "abortisce se si verifica un errore"
+
+msgid "purge ignored files too"
+msgstr "rimuove anche i file ignorati"
+
+msgid "print the file names instead of deleting them"
+msgstr "stampa i nomi dei file invece di cancellarli"
+
+msgid "end filenames with NUL, for use with xargs (implies -p)"
+msgstr "termina il nome dei file con NUL, per usarli con xargs (implica -p)"
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr "hg purge [OPZIONI]... [DIR]..."
+
+msgid ""
+"move sets of revisions to a different ancestor\n"
+"\n"
+"This extension lets you rebase changesets in an existing Mercurial "
+"repository.\n"
+"\n"
+"For more information:\n"
+"http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject\n"
+msgstr ""
+"sposta insiemi di revisioni su un antenato differente\n"
+"\n"
+"Questa estensione consente di effettuare il rebase di changeset in un\n"
+"repository Mercurial esistente.\n"
+"\n"
+"Per maggiori informazioni:\n"
+"http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject\n"
+
+msgid "return the correct ancestor"
+msgstr "restituisce l'antenato corretto"
+
+msgid "first revision, do not change ancestor\n"
+msgstr "prima revisione, non cambia l'antenato\n"
+
+msgid ""
+"move changeset (and descendants) to a different branch\n"
+"\n"
+" Rebase uses repeated merging to graft changesets from one part of "
+"history\n"
+" onto another. This can be useful for linearizing local changes relative "
+"to\n"
+" a master development tree.\n"
+"\n"
+" If a rebase is interrupted to manually resolve a merge, it can be "
+"continued\n"
+" with --continue or aborted with --abort.\n"
+" "
+msgstr ""
+"sposta changeset (e discendenti) su una branch differente\n"
+"\n"
+" Rebase usa merge ripetuti per trapiantare changeset da una parte\n"
+" della storia in un'altra. Questo può essere utile per linearizzare\n"
+" modifiche locali relative ad un albero di sviluppo principale.\n"
+"\n"
+" Se un rebase viene interrotto per risolvere manualmente un merge,\n"
+" può essere ripreso con --continue o abortito con --abort.\n"
+" "
+
+msgid "cannot use both keepbranches and extrafn"
+msgstr "non è possibile usare sia keepbranches sia extrafn"
+
+msgid "cannot use both abort and continue"
+msgstr "non è possibile usare sia abort sia continue"
+
+msgid "cannot use collapse with continue or abort"
+msgstr "non è possibile usare collapse con continue o abort"
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr "abort e continue non consentono di specificare revisioni"
+
+msgid "cannot specify both a revision and a base"
+msgstr "non è possibile specificare sia una revisione sia una base"
+
+msgid "nothing to rebase\n"
+msgstr "niente di cui effettuare il rebase\n"
+
+msgid "rebase merging completed\n"
+msgstr "merge del rebase completato\n"
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr ""
+"attenzione: nuovi changeset rilevati sulla branch sorgente, non li rimuovo\n"
+
+msgid "rebase completed\n"
+msgstr "rebase completato\n"
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr "%d revisioni sono state saltate\n"
+
+msgid ""
+"Skip commit if collapsing has been required and rev is not the last\n"
+" revision, commit otherwise\n"
+" "
+msgstr ""
+"Salta il commit se è stato richiesto di collassare e rev non è l'ultima\n"
+" revisione, effettua il commit altrimenti\n"
+" "
+
+msgid " set parents\n"
+msgstr " imposta i genitori\n"
+
+msgid "Rebase a single revision"
+msgstr "Rebase di una singola revisione"
+
+#, python-format
+msgid "rebasing %d:%s\n"
+msgstr "sto effettuando il rebase di %d:%s\n"
+
+#, python-format
+msgid " future parents are %d and %d\n"
+msgstr " i genitori futuri sono %d e %d\n"
+
+#, python-format
+msgid " update to %d:%s\n"
+msgstr " aggiorno a %d:%s\n"
+
+msgid " already in target\n"
+msgstr " già su target\n"
+
+#, python-format
+msgid " merge against %d:%s\n"
+msgstr " merge con %d:%s\n"
+
+msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgstr ""
+"correggi i conflitti non risolti con hg resolve e poi esegui hg rebase --"
+"continue"
+
+msgid "resuming interrupted rebase\n"
+msgstr "sto riprendendo un rebase interrotto\n"
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr "nessuna modifica, revisione %d saltata\n"
+
+#, python-format
+msgid "next revision set to %s\n"
+msgstr "prossima revisione impostata su %s\n"
+
+msgid "Return the new parent relationship of the revision that will be rebased"
+msgstr ""
+"Restituisce la nuova relazione di parentela della revisione di cui si farà "
+"il rebase"
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr ""
+"non è possibile usare la revisione %d come base, il risultato avrebbe 3 "
+"genitori"
+
+msgid "Update rebased mq patches - finalize and then import them"
+msgstr ""
+"Aggiorna le patch mq di cui si è effettuato il rebase - le finalizza e poi "
+"le importa"
+
+#, python-format
+msgid "revision %d is an mq patch (%s), finalize it.\n"
+msgstr "la revisione %d è una patch mq (%s), la finalizzo.\n"
+
+#, python-format
+msgid "import mq patch %d (%s)\n"
+msgstr "import della patch mq %d (%s)\n"
+
+msgid "Store the current status to allow recovery"
+msgstr "Salva lo status corrente per consentire il recupero"
+
+msgid "rebase status stored\n"
+msgstr "status del rebase salvato\n"
+
+msgid "Remove the status files"
+msgstr "Rimuove i file dello stato"
+
+msgid "Restore a previously stored status"
+msgstr "Ripristina uno stato precedentemente salvato"
+
+msgid "rebase status resumed\n"
+msgstr "status di rebase recuperato\n"
+
+msgid "no rebase in progress"
+msgstr "nessun rebase in corso"
+
+msgid "Restore the repository to its original state"
+msgstr "Ripristina il repository al suo stato originale"
+
+msgid "warning: new changesets detected on target branch, not stripping\n"
+msgstr ""
+"attenzione: nuovi changeset rilevati sulla branch target, non li rimuovo\n"
+
+msgid "rebase aborted\n"
+msgstr "rebase abortito\n"
+
+msgid "Define which revisions are going to be rebased and where"
+msgstr "Definisce di quali revisioni si farà il rebase e dove"
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr "non è possibile effettuare il rebase su una patch mq applicata"
+
+msgid "cannot rebase an ancestor"
+msgstr "non è possibile effettuare il rebase di un antenato"
+
+msgid "cannot rebase a descendant"
+msgstr "non è possibile effettuare il rebase di un discendente"
+
+msgid "already working on current\n"
+msgstr "sto già lavorando su current\n"
+
+msgid "already working on the current branch\n"
+msgstr "sto già lavorando sulla branch corrente\n"
+
+#, python-format
+msgid "rebase onto %d starting from %d\n"
+msgstr "rebase su %d partendo da %d\n"
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr "impossibile effettuare il collapse, c'è più di un genitore esterno"
+
+msgid "Call rebase after pull if the latter has been invoked with --rebase"
+msgstr "Invoca rebase dopo pull se l'ultimo è stato invocato con --rebase"
+
+msgid "--update and --rebase are not compatible, ignoring the update flag\n"
+msgstr "--update e --rebase non sono compatibili, ignoro il flag update\n"
+
+msgid "Replace pull with a decorator to provide --rebase option"
+msgstr "Rimpiazza pull con un decoratore per fornire l'opzione --rebase"
+
+msgid "rebase working directory to branch head"
+msgstr "effettua il rebase della directory di lavoro sulla head della branch"
+
+msgid "keep original revisions"
+msgstr "mantiene le revisioni originali"
+
+msgid "keep original branches"
+msgstr "mantiene le branch originali"
+
+msgid "rebase from a given revision"
+msgstr "rebase da una data revisione"
+
+msgid "rebase from the base of a given revision"
+msgstr "rebase dalla base di una data revisione"
+
+msgid "rebase onto a given revision"
+msgstr "rebase su una data revisione"
+
+msgid "collapse the rebased revisions"
+msgstr "collassa le revisioni di cui si effettua il rebase"
+
+msgid "continue an interrupted rebase"
+msgstr "continua un rebase interrotto"
+
+msgid "abort an interrupted rebase"
+msgstr "abortisce un rebase interrotto"
+
+msgid ""
+"hg rebase [-s rev | -b rev] [-d rev] [--collapse] | [-c] | [-a] | [--keep]"
+msgstr ""
+"hg rebase [-s rev | -b rev] [-d rev] [--collapse] | [-c] | [-a] | [--keep]"
+
+msgid "interactive change selection during commit or qrefresh"
+msgstr "cambia interattivamente la selezione durante un commit o qrefresh"
+
+msgid ""
+"like patch.iterhunks, but yield different events\n"
+"\n"
+" - ('file', [header_lines + fromfile + tofile])\n"
+" - ('context', [context_lines])\n"
+" - ('hunk', [hunk_lines])\n"
+" - ('range', (-start,len, +start,len, diffp))\n"
+" "
+msgstr ""
+
+msgid "scan lr while predicate holds"
+msgstr "scansiona lr fino a quando il predicato vale"
+
+msgid ""
+"patch header\n"
+"\n"
+" XXX shoudn't we move this to mercurial/patch.py ?\n"
+" "
+msgstr ""
+"intestazione della patch\n"
+"\n"
+" XXX non dovremmo spostare questo in mercurial/patch.py ?\n"
+" "
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr "questo modifica un file binario (tutto o niente)\n"
+
+msgid "this is a binary file\n"
+msgstr "questo è un file binario\n"
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr ""
+
+msgid "hunk -> (n+,n-)"
+msgstr "hunk -> (n+,n-)"
+
+msgid ""
+"patch hunk\n"
+"\n"
+" XXX shouldn't we merge this with patch.hunk ?\n"
+" "
+msgstr ""
+
+msgid "patch -> [] of hunks "
+msgstr ""
+
+msgid "patch parsing state machine"
+msgstr ""
+
+msgid "Interactively filter patch chunks into applied-only chunks"
+msgstr ""
+
+msgid ""
+"fetch next portion from chunks until a 'header' is seen\n"
+" NB: header == new-file mark\n"
+" "
+msgstr ""
+
+msgid ""
+"prompt query, and process base inputs\n"
+"\n"
+" - y/n for the rest of file\n"
+" - y/n for the rest\n"
+" - ? (help)\n"
+" - q (quit)\n"
+"\n"
+" else, input is returned to the caller.\n"
+" "
+msgstr ""
+
+msgid "[Ynsfdaq?]"
+msgstr "[Ynsfdaq?]"
+
+msgid "y"
+msgstr "y"
+
+msgid "?"
+msgstr "?"
+
+msgid "y - record this change"
+msgstr "y - registra questa modifica"
+
+msgid "s"
+msgstr "s"
+
+msgid "f"
+msgstr "f"
+
+msgid "d"
+msgstr "d"
+
+msgid "a"
+msgstr "a"
+
+msgid "q"
+msgstr "q"
+
+msgid "user quit"
+msgstr ""
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr ""
+
+msgid " and "
+msgstr " e "
+
+#, python-format
+msgid "record this change to %r?"
+msgstr "registrare questa modifica a %r?"
+
+msgid ""
+"interactively select changes to commit\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be candidates for recording.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" You will be prompted for whether to record changes to each\n"
+" modified file, and for files with multiple changes, for each\n"
+" change to use. For each query, the following responses are\n"
+" possible:\n"
+"\n"
+" y - record this change\n"
+" n - skip this change\n"
+"\n"
+" s - skip remaining changes to this file\n"
+" f - record remaining changes to this file\n"
+"\n"
+" d - done, skip remaining changes and files\n"
+" a - record all changes to all remaining files\n"
+" q - quit, recording no changes\n"
+"\n"
+" ? - display help"
+msgstr ""
+"seleziona interattivamente le modifiche di cui eseguire il commit\n"
+"\n"
+" Se viene omesso un elenco di file, tutte le modifiche\n"
+" riportate da \"hg status\" saranno candidati per la\n"
+" registrazione.\n"
+"\n"
+" Vedere 'hg help dates' per un elenco di formati\n"
+" validi per -d/--date.\n"
+"\n"
+" Si verrà interrogati su quali modifiche registrare\n"
+" per ogni file modificato e, per file con modifiche\n"
+" multiple, per ogni modifica da usare. Per ogni domanda\n"
+" sono possibili le seguenti risposte:\n"
+"\n"
+" y - registra questa modifica\n"
+" n - salta questa modifica\n"
+"\n"
+" s - salta le modifiche rimanenti di questo file\n"
+" f - registra le modifiche rimanenti di questo file\n"
+"\n"
+" d - fatto, salta le modifiche e i file rimanenti\n"
+" a - registra tutte le modifiche a tutti i file rimanenti\n"
+" q - esci, non registrare alcuna modifica\n"
+"\n"
+" ? - mostra il messaggio di aiuto"
+
+msgid ""
+"interactively record a new patch\n"
+"\n"
+" see 'hg help qnew' & 'hg help record' for more information and usage\n"
+" "
+msgstr ""
+
+msgid "'mq' extension not loaded"
+msgstr "estensione 'mq' non caricata"
+
+msgid "running non-interactively, use commit instead"
+msgstr ""
+
+msgid ""
+"This is generic record driver.\n"
+"\n"
+" It's job is to interactively filter local changes, and accordingly\n"
+" prepare working dir into a state, where the job can be delegated to\n"
+" non-interactive commit command such as 'commit' or 'qrefresh'.\n"
+"\n"
+" After the actual job is done by non-interactive command, working "
+"dir\n"
+" state is restored to original.\n"
+"\n"
+" In the end we'll record intresting changes, and everything else will "
+"be\n"
+" left in place, so the user can continue his work.\n"
+" "
+msgstr ""
+
+msgid "no changes to record\n"
+msgstr "nessuna modifica da registrare\n"
+
+#, python-format
+msgid "backup %r as %r\n"
+msgstr "backup %r come %r\n"
+
+msgid "applying patch\n"
+msgstr "sto applicando una patch\n"
+
+msgid "patch failed to apply"
+msgstr ""
+
+#, python-format
+msgid "restoring %r to %r\n"
+msgstr ""
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr "hg record [OPZIONI]... [FILE]..."
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr "hg qrecord [OPZIONI]... PATCH [FILE]..."
+
+msgid ""
+"patch transplanting tool\n"
+"\n"
+"This extension allows you to transplant patches from another branch.\n"
+"\n"
+"Transplanted patches are recorded in .hg/transplant/transplants, as a map\n"
+"from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+
+msgid ""
+"returns True if a node is already an ancestor of parent\n"
+" or has already been transplanted"
+msgstr ""
+
+msgid "apply the revisions in revmap one by one in revision order"
+msgstr ""
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr ""
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr ""
+
+msgid "arbitrarily rewrite changeset before applying it"
+msgstr ""
+
+#, python-format
+msgid "filtering %s\n"
+msgstr "sto filtrando %s\n"
+
+msgid "filter failed"
+msgstr "filtraggio fallito"
+
+msgid "apply the patch in patchfile to the repository as a transplant"
+msgstr ""
+
+msgid "can only omit patchfile if merging"
+msgstr ""
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr "%s: changeset vuoto"
+
+msgid "Fix up the merge and run hg transplant --continue"
+msgstr ""
+
+msgid "recover last transaction and apply remaining changesets"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr "%s trapiantato come %s\n"
+
+msgid "commit working directory using journal metadata"
+msgstr ""
+
+msgid "transplant log file is corrupt"
+msgstr ""
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr ""
+
+msgid "commit failed"
+msgstr "commit fallito"
+
+msgid "journal changelog metadata for later recover"
+msgstr ""
+
+msgid "remove changelog journal"
+msgstr ""
+
+msgid "interactively transplant changesets"
+msgstr ""
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr "applicare il changeset? [ynmpcq?]:"
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+" Selected changesets will be applied on top of the current working\n"
+" directory with the log of the original changeset. If --log is\n"
+" specified, log messages will have a comment appended of the form:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" You can rewrite the changelog message with the --filter option.\n"
+" Its argument will be invoked with the current changelog message\n"
+" as $1 and the patch as $2.\n"
+"\n"
+" If --source is specified, selects changesets from the named\n"
+" repository. If --branch is specified, selects changesets from the\n"
+" branch holding the named revision, up to that revision. If --all\n"
+" is specified, all changesets on the branch will be transplanted,\n"
+" otherwise you will be prompted to select the changesets you want.\n"
+"\n"
+" hg transplant --branch REVISION --all will rebase the selected branch\n"
+" (up to the named revision) onto your current working directory.\n"
+"\n"
+" You can optionally mark selected transplanted changesets as\n"
+" merge changesets. You will not be prompted to transplant any\n"
+" ancestors of a merged transplant, and you can merge descendants\n"
+" of them normally instead of transplanting them.\n"
+"\n"
+" If no merges or revisions are provided, hg transplant will start\n"
+" an interactive changeset browser.\n"
+"\n"
+" If a changeset application fails, you can fix the merge by hand and\n"
+" then resume where you left off by calling hg transplant --continue.\n"
+" "
+msgstr ""
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr ""
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr ""
+
+msgid "--all requires a branch revision"
+msgstr ""
+
+msgid "--all is incompatible with a revision list"
+msgstr ""
+
+msgid "no revision checked out"
+msgstr ""
+
+msgid "outstanding uncommitted merges"
+msgstr ""
+
+msgid "outstanding local changes"
+msgstr ""
+
+msgid "pull patches from REPOSITORY"
+msgstr ""
+
+msgid "pull patches from branch BRANCH"
+msgstr ""
+
+msgid "pull all changesets up to BRANCH"
+msgstr ""
+
+msgid "skip over REV"
+msgstr ""
+
+msgid "merge at REV"
+msgstr ""
+
+msgid "append transplant info to log message"
+msgstr ""
+
+msgid "continue last transplant session after repair"
+msgstr ""
+
+msgid "filter changesets through FILTER"
+msgstr ""
+
+msgid ""
+"hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr ""
+
+msgid ""
+"allow to use MBCS path with problematic encoding.\n"
+"\n"
+"Some MBCS encodings are not good for some path operations\n"
+"(i.e. splitting path, case conversion, etc.) with its encoded bytes.\n"
+"We call such a encoding (i.e. shift_jis and big5) as \"problematic\n"
+"encoding\". This extension can be used to fix the issue with those\n"
+"encodings by wrapping some functions to convert to unicode string\n"
+"before path operation.\n"
+"\n"
+"This extension is usefull for:\n"
+" * Japanese Windows users using shift_jis encoding.\n"
+" * Chinese Windows users using big5 encoding.\n"
+" * All users who use a repository with one of problematic encodings\n"
+" on case-insensitive file system.\n"
+"\n"
+"This extension is not needed for:\n"
+" * Any user who use only ascii chars in path.\n"
+" * Any user who do not use any of problematic encodings.\n"
+"\n"
+"Note that there are some limitations on using this extension:\n"
+" * You should use single encoding in one repository.\n"
+" * You should set same encoding for the repository by locale or HGENCODING.\n"
+"\n"
+"To use this extension, enable the extension in .hg/hgrc or ~/.hgrc:\n"
+"\n"
+" [extensions]\n"
+" hgext.win32mbcs =\n"
+"\n"
+"Path encoding conversion are done between unicode and util._encoding\n"
+"which is decided by mercurial from current locale setting or HGENCODING.\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] filename conversion fail with %s encoding\n"
+msgstr ""
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] activated with encoding: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr ""
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"and also consider adding:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+
+msgid ""
+"zeroconf support for mercurial repositories\n"
+"\n"
+"Zeroconf enabled repositories will be announced in a network without the "
+"need\n"
+"to configure a server or a service. They can be discovered without knowing\n"
+"their actual IP address.\n"
+"\n"
+"To use the zeroconf extension add the following entry to your hgrc file:\n"
+"\n"
+"[extensions]\n"
+"hgext.zeroconf =\n"
+"\n"
+"To allow other people to discover your repository using run \"hg serve\" in "
+"your\n"
+"repository.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"You can discover zeroconf enabled repositories by running \"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+msgstr ""
+
+msgid "archive prefix contains illegal components"
+msgstr ""
+
+msgid "cannot give prefix when archiving to files"
+msgstr ""
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr ""
+
+msgid "invalid changegroup"
+msgstr ""
+
+msgid "unknown parent"
+msgstr ""
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr ""
+
+#, python-format
+msgid "%s: not a Mercurial bundle file"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle version"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle compression type"
+msgstr ""
+
+msgid "cannot create new bundle repository"
+msgstr ""
+
+#, python-format
+msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr ""
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr ""
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr ""
+
+msgid "limit must be a positive integer"
+msgstr ""
+
+msgid "limit must be positive"
+msgstr ""
+
+msgid "too many revisions specified"
+msgstr ""
+
+#, python-format
+msgid "invalid format spec '%%%s' in output file name"
+msgstr ""
+
+#, python-format
+msgid "adding %s\n"
+msgstr ""
+
+#, python-format
+msgid "removing %s\n"
+msgstr "sto rimuovendo %s\n"
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr ""
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr ""
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr "%s: impossibile copiare - %s\n"
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr "sto spostando %s in %s\n"
+
+#, python-format
+msgid "copying %s to %s\n"
+msgstr "sto copiando %s in %s\n"
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+
+msgid "no source or destination specified"
+msgstr "nessuna sorgente o destinazione specificata"
+
+msgid "no destination specified"
+msgstr "nessuna destinazione specificata"
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr ""
+"con sorgenti multiple la destinazione deve essere una directory esistente"
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr "la destinazione %s non è una directory"
+
+msgid "no files to copy"
+msgstr "nessun file da copiare"
+
+msgid "(consider using --after)\n"
+msgstr "(considera di usare --after)\n"
+
+#, python-format
+msgid "changeset: %d:%s\n"
+msgstr "changeset: %d:%s\n"
+
+#, python-format
+msgid "branch: %s\n"
+msgstr "branch: %s\n"
+
+#, python-format
+msgid "tag: %s\n"
+msgstr "tag: %s\n"
+
+#, python-format
+msgid "parent: %d:%s\n"
+msgstr "genitore: %d:%s\n"
+
+#, python-format
+msgid "manifest: %d:%s\n"
+msgstr "manifesto: %d:%s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "utente: %s\n"
+
+#, python-format
+msgid "date: %s\n"
+msgstr "data: %s\n"
+
+msgid "files+:"
+msgstr "file+:"
+
+msgid "files-:"
+msgstr "file-:"
+
+msgid "files:"
+msgstr "file:"
+
+#, python-format
+msgid "files: %s\n"
+msgstr "file: %s\n"
+
+#, python-format
+msgid "copies: %s\n"
+msgstr "copie: %s\n"
+
+#, python-format
+msgid "extra: %s=%s\n"
+msgstr "extra: %s=%s\n"
+
+msgid "description:\n"
+msgstr "descrizione:\n"
+
+#, python-format
+msgid "summary: %s\n"
+msgstr "sommario: %s\n"
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr "%s: nessuna chiave chiamata '%s'"
+
+#, python-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr "Trovata revisione %s da %s\n"
+
+msgid "revision matching date not found"
+msgstr "revisione corrispondente alla data non trovata"
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr "impossibile seguire il file non esistente: \"%s\""
+
+#, python-format
+msgid "%s:%s copy source revision cannot be found!\n"
+msgstr ""
+
+msgid "can only follow copies/renames for explicit file names"
+msgstr ""
+
+#, python-format
+msgid "file %s not found!"
+msgstr "file %s non trovato!"
+
+#, python-format
+msgid "no match under directory %s!"
+msgstr "nessuna corrispondenza sotto la directory %s!"
+
+#, python-format
+msgid "can't commit %s: unsupported file type!"
+msgstr "impossibile fare il commit di %s: tipo di file non supportato!"
+
+#, python-format
+msgid "file %s not tracked!"
+msgstr "il file %s non è tracciato!"
+
+msgid ""
+"add the specified files on the next commit\n"
+"\n"
+" Schedule files to be version controlled and added to the repository.\n"
+"\n"
+" The files will be added to the repository at the next commit. To\n"
+" undo an add before that, see hg revert.\n"
+"\n"
+" If no names are given, add all files to the repository.\n"
+" "
+msgstr ""
+
+msgid ""
+"add all new files, delete all missing files\n"
+"\n"
+" Add all new files and remove all missing files from the repository.\n"
+"\n"
+" New files are ignored if they match any of the patterns in .hgignore. "
+"As\n"
+" with add, these changes take effect at the next commit.\n"
+"\n"
+" Use the -s option to detect renamed files. With a parameter > 0,\n"
+" this compares every removed file with every added file and records\n"
+" those similar enough as renames. This option takes a percentage\n"
+" between 0 (disabled) and 100 (files must be identical) as its\n"
+" parameter. Detecting renamed files this way can be expensive.\n"
+" "
+msgstr ""
+
+msgid "similarity must be a number"
+msgstr ""
+
+msgid "similarity must be between 0 and 100"
+msgstr ""
+
+msgid ""
+"show changeset information per file line\n"
+"\n"
+" List changes in files, showing the revision id responsible for each "
+"line\n"
+"\n"
+" This command is useful to discover who did a change or when a change "
+"took\n"
+" place.\n"
+"\n"
+" Without the -a option, annotate will avoid processing files it\n"
+" detects as binary. With -a, annotate will generate an annotation\n"
+" anyway, probably with undesirable results.\n"
+" "
+msgstr ""
+
+msgid "at least one file name or pattern required"
+msgstr ""
+
+msgid "at least one of -n/-c is required for -l"
+msgstr ""
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr ""
+
+msgid ""
+"create unversioned archive of a repository revision\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use \"-r\" to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use \"-t\". Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see \"hg help export\" for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use \"-p\" to specify a format string for the prefix.\n"
+" The default is the basename of the archive, with suffixes removed.\n"
+" "
+msgstr ""
+
+msgid "no working directory: please specify a revision"
+msgstr ""
+
+msgid "repository root cannot be destination"
+msgstr ""
+
+msgid "cannot archive plain files to stdout"
+msgstr ""
+
+msgid ""
+"reverse effect of earlier changeset\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you back out a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head (current one by default).\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by\n"
+" hand. The result of this merge is not committed, as with a normal\n"
+" merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"inverte l'effetto di un changeset precedente\n"
+"\n"
+" Effettua il commit delle modifiche di cui si è fatto backout\n"
+" come nuovo changeset. Il nuovo changeset è un figlio del\n"
+" changeset di cui si è fatto backout.\n"
+"\n"
+" Se si fa il backout di un changeset diverso da tip, viene creata\n"
+" una nuova head. Questa sarà la nuova tip e si dovrebbe fare il\n"
+" merge di questo changeset di backout con un'altra head\n"
+" (attualmente una di default).\n"
+"\n"
+" L'opzione --merge ricorda il genitore della directory di lavoro\n"
+" prima di avviare il backout, poi fa il merge della nuova head con\n"
+" quel changeset. Questo evita di fare il merge a mano. Non viene\n"
+" effettuato il commit del risultato di questo merge, come per un\n"
+" merge normale.\n"
+"\n"
+" Vedere 'hg help dates' per un elenco dei formati validi per -d/--date.\n"
+" "
+
+msgid "please specify just one revision"
+msgstr ""
+
+msgid "please specify a revision to backout"
+msgstr ""
+
+msgid "cannot back out change on a different branch"
+msgstr ""
+
+msgid "cannot back out a change with no parents"
+msgstr ""
+
+msgid "cannot back out a merge changeset without --parent"
+msgstr ""
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr ""
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr ""
+
+#, python-format
+msgid "Backed out changeset %s"
+msgstr ""
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr "sto effettuando il merge con il changeset %s\n"
+
+msgid "the backout changeset is a new head - do not forget to merge\n"
+msgstr ""
+
+msgid "(use \"backout --merge\" if you want to auto-merge)\n"
+msgstr ""
+
+msgid ""
+"subdivision search of changesets\n"
+"\n"
+" This command helps to find changesets which introduce problems.\n"
+" To use, mark the earliest changeset you know exhibits the problem\n"
+" as bad, then mark the latest changeset which is free from the\n"
+" problem as good. Bisect will update your working directory to a\n"
+" revision for testing (unless the --noupdate option is specified).\n"
+" Once you have performed tests, mark the working directory as bad\n"
+" or good and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command it will be used for automatic bisection. Its "
+"exit\n"
+" status will be used as flag to mark revision as bad or good. In case "
+"exit\n"
+" status is 0 the revision is marked as good, 125 - skipped, 127 (command "
+"not\n"
+" found) - bisection will be aborted; any other status bigger than 0 will\n"
+" mark revision as bad.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "The first %s revision is:\n"
+msgstr "La prima revisione %s è:\n"
+
+#, python-format
+msgid "Due to skipped revisions, the first %s revision could be any of:\n"
+msgstr ""
+
+msgid "cannot bisect (no known good revisions)"
+msgstr "impossibile fare bisect (nessuna revisione buona nota)"
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr "impossibile fare bisect (nessuna revisione cattiva nota)"
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr "(l'uso di 'hg bisect <cmd>' è deprecato)\n"
+
+msgid "incompatible arguments"
+msgstr "argomenti incompatibili"
+
+#, python-format
+msgid "failed to execute %s"
+msgstr "esecuzione di %s fallita"
+
+#, python-format
+msgid "%s killed"
+msgstr "%s ucciso"
+
+#, python-format
+msgid "Changeset %s: %s\n"
+msgstr "Changeset %s: %s\n"
+
+#, python-format
+msgid "Testing changeset %s:%s (%s changesets remaining, ~%s tests)\n"
+msgstr ""
+
+msgid ""
+"set or show the current branch name\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch does not exist in\n"
+" the repository until the next commit).\n"
+"\n"
+" Unless --force is specified, branch will not let you set a\n"
+" branch name that shadows an existing branch.\n"
+"\n"
+" Use --clean to reset the working directory branch to that of the\n"
+" parent of the working directory, negating a previous branch change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr "resetto la directory di lavoro alla branch %s\n"
+
+msgid "a branch of the same name already exists (use --force to override)"
+msgstr ""
+"una branch con lo stesso nome esiste già (usare --force per sovrascrivere)"
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr "marcata directory di lavoro come branch %s\n"
+
+msgid ""
+"list repository named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If active is specified, only show active branches.\n"
+"\n"
+" A branch is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+
+msgid ""
+"create a changegroup file\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" --all (or --base null). To change the compression method applied,\n"
+" use the -t option (by default, bundles are compressed using bz2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means and\n"
+" applied to another repository with the unbundle or pull command.\n"
+" This is useful when direct push and pull are not available or when\n"
+" exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+msgstr ""
+
+msgid "--base is incompatible with specifiying a destination"
+msgstr ""
+
+msgid "unknown bundle type specified with --type"
+msgstr ""
+
+msgid ""
+"output the current or given revision of files\n"
+"\n"
+" Print the specified files as they were at the given revision.\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repo root\n"
+" %p root-relative path name of file being printed\n"
+" "
+msgstr ""
+
+msgid ""
+"make a copy of an existing repository\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" If you use the -r option to clone up to a specific revision, no\n"
+" subsequent revisions will be present in the cloned repository.\n"
+" This option implies --pull, even on local repositories.\n"
+"\n"
+" If the -U option is used, the new clone will contain only a repository\n"
+" (.hg) and no working copy (the working copy parent is the null "
+"revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Look at the help text for urls for important details about ssh:// URLs.\n"
+" "
+msgstr ""
+"crea una copia di un repository esistente\n"
+"\n"
+" Crea una copia di un repository esistente in una nuova directory.\n"
+"\n"
+" Se non viene specificato nessun nome di directory\n"
+" destinazione, di default viene usata la directory base\n"
+" della sorgente.\n"
+"\n"
+" La posizione della sorgente viene aggiunta al file .hg/hgrc\n"
+" del nuovo repository, come default da usare per pull futuri.\n"
+"\n"
+" Per efficienza, si usano hardlink per clonare ogni volta che\n"
+" la sorgente e la destinazione sono sullo stesso filesystem\n"
+" (notare che questo vale per i dati del repository, non per\n"
+" per i file di cui si è fatto il check out). Alcuni\n"
+" filesystem, tipo AFS, non implementano correttamente gli\n"
+" hardlink, ma non riportano errori. In questi casi, usare\n"
+" l'opzione --pull per evitare gli hardlink.\n"
+"\n"
+" In alcuni casi, è possibile clonare i repository e i file di\n"
+" cui si è fatto il check out usando hardlink completi con\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" Questo è il modo più veloce per clonare, ma non è sempre\n"
+" sicuro. L'operazione non è atomica (spetta all'utente\n"
+" assicurarsi che REPO non venga modificato durante la\n"
+" operazione) e bisogna assicurarsi che l'editor usato spezzi\n"
+" gli hardlink (Emacs e i principali tool del Kernel Linux lo\n"
+" fanno). Inoltre, questo non è compatibile con alcune\n"
+" estensioni che mettono i loro metadati sotto la directory\n"
+" .hg, tipo mq.\n"
+"\n"
+" Se viene usata l'opzione -r per clonare fino ad una\n"
+" revisione specifica, nessuna revisione seguente sarà presente\n"
+" nel repository clonato. Questa opzione implica --pull, anche\n"
+" per repository locali.\n"
+"\n"
+" Se viene usata l'opzione -U, il nuovo clone conterrà solo un\n"
+" repository (.hg) e nessuna copia di lavoro (il genitore\n"
+" della copia di lavoro è la revisione nulla).\n"
+"\n"
+" Vedere 'hg help urls' per dettagli sui formati di sorgenti\n"
+" validi.\n"
+"\n"
+" E' possibile specificare un URL ssh:// come destinazione, ma\n"
+" nessun .hg/hgrc e directory di lavoro verranno creati sul\n"
+" lato remoto. Riferirsi al testo di aiuto per gli url per\n"
+" dettagli importanti riguardo gli URL ssh://.\n"
+" "
+
+msgid ""
+"commit the specified files or all outstanding changes\n"
+"\n"
+" Commit changes to the given files into the repository.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" file names or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is started to\n"
+" prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"effettua il commit dei file specificati o di tutte le modifiche pendenti\n"
+"\n"
+" Effettua il commit delle modifiche sui file dati nel repository.\n"
+"\n"
+" Se si omette un elenco di file, si farà il commit di tutte le\n"
+" modifiche riportate da \"hg status\".\n"
+"\n"
+" Se si sta effettuando il commit del risultato di un merge, non\n"
+" fornire nessun nome di file o filtri -I/-X.\n"
+"\n"
+" Se non è specificato nessun messaggio di commit, l'editor\n"
+" configurato viene lanciato per inserire un messaggio.\n"
+"\n"
+" Vedere 'hg help dates' per un elenco dei formati validi per\n"
+" -d/--date.\n"
+" "
+
+msgid "created new head\n"
+msgstr "creata una nuova head\n"
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr "effettuato il commit del changeset %d:%s\n"
+
+msgid ""
+"mark files as copied for the next commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" stand in the working directory. If invoked with --after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr ""
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr "Non esiste alcun repository Mercurial qui (.hg non trovata)"
+
+msgid "either two or three arguments required"
+msgstr "due o tre argomenti sono richiesti"
+
+msgid "returns the completion list associated with the given command"
+msgstr "restituisce l'elenco di completamento associato al dato comando"
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr ""
+
+msgid "validate the correctness of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr "%s è nello state %s, ma non nel manifest1\n"
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr "%s è nello state %s, ma anche nel manifest1\n"
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr "%s è nello state %s, ma non in uno dei manifesti\n"
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr ""
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr ""
+
+msgid ""
+"show combined config settings from all hgrc files\n"
+"\n"
+" With no args, print names and values of all config items.\n"
+"\n"
+" With one arg of the form section.name, print just the value of\n"
+" that config item.\n"
+"\n"
+" With multiple args, print names and values of all config items\n"
+" with matching section names."
+msgstr ""
+
+msgid "only one config item permitted"
+msgstr ""
+
+msgid ""
+"manually set the parents of the current working directory\n"
+"\n"
+" This is useful for writing repository conversion tools, but should\n"
+" be used with care.\n"
+" "
+msgstr ""
+
+msgid "show the contents of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr ""
+
+msgid "dump the contents of a data file revision"
+msgstr ""
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr ""
+
+msgid "parse and display a date"
+msgstr ""
+
+msgid "dump the contents of an index file"
+msgstr ""
+
+msgid "dump an index DAG as a .dot file"
+msgstr ""
+
+msgid "test Mercurial installation"
+msgstr ""
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr ""
+
+msgid " (check that your locale is properly set)\n"
+msgstr ""
+
+msgid "Checking extensions...\n"
+msgstr ""
+
+msgid " One or more extensions could not be found"
+msgstr ""
+
+msgid " (check that you compiled the extensions)\n"
+msgstr ""
+
+msgid "Checking templates...\n"
+msgstr ""
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr ""
+
+msgid "Checking patch...\n"
+msgstr ""
+
+msgid " patch call failed:\n"
+msgstr ""
+
+msgid " unexpected patch output!\n"
+msgstr ""
+
+msgid " patch test failed!\n"
+msgstr ""
+
+msgid ""
+" (Current patch tool may be incompatible with patch, or misconfigured. "
+"Please check your .hgrc file)\n"
+msgstr ""
+
+msgid ""
+" Internal patcher failure, please report this error to http://www.selenic."
+"com/mercurial/bts\n"
+msgstr ""
+
+msgid "Checking commit editor...\n"
+msgstr "Sto controllando l'editor per il commit...\n"
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr "Nessun editor per il commit trovato e non trovo vi in PATH\n"
+
+msgid " (specify a commit editor in your .hgrc file)\n"
+msgstr " (specificare un editore per il commit nel proprio file .hgrc)\n"
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr "Editor '%s' non trovato in PATH\n"
+
+msgid "Checking username...\n"
+msgstr "Sto controllando lo username...\n"
+
+msgid " (specify a username in your .hgrc file)\n"
+msgstr " (specificare un nome utente nel proprio file .hgrc)\n"
+
+msgid "No problems detected\n"
+msgstr "Nessun problema riscontrato\n"
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr "%s problemi riscontrati, si prega di controllare l'installazione!\n"
+
+msgid "dump rename information"
+msgstr ""
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr ""
+
+msgid "show how files match on given patterns"
+msgstr "mostra come i file corrispondono ai dati pattern"
+
+msgid ""
+"diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a option, diff will avoid generating diffs of files\n"
+" it detects as binary. With -a, diff will generate a diff anyway,\n"
+" probably with undesirable results.\n"
+"\n"
+" Use the --git option to generate diffs in the git extended diff\n"
+" format. For more information, read hg help diffs.\n"
+" "
+msgstr ""
+
+msgid ""
+"dump the header and diffs for one or more changesets\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge changesets,\n"
+" as it will compare the merge changeset against its first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a option, export will avoid generating diffs of files\n"
+" it detects as binary. With -a, export will generate a diff anyway,\n"
+" probably with undesirable results.\n"
+"\n"
+" Use the --git option to generate diffs in the git extended diff\n"
+" format. Read the diffs help topic for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the second\n"
+" parent. It can be useful to review a merge.\n"
+" "
+msgstr ""
+
+msgid "export requires at least one changeset"
+msgstr ""
+
+msgid "exporting patches:\n"
+msgstr ""
+
+msgid "exporting patch:\n"
+msgstr ""
+
+msgid ""
+"search for a pattern in specified files and revisions\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which\n"
+" a match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr ""
+
+msgid ""
+"show current repository heads or show branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" If branch or revisions names are given this will show the heads of\n"
+" the specified branches or the branches those revisions are tagged\n"
+" with.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" Branch heads are changesets that have a given branch tag, but have\n"
+" no child changesets with that tag. They are usually where\n"
+" development on the given branch takes place.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "no changes on branch %s containing %s are reachable from %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes on branch %s are reachable from %s\n"
+msgstr ""
+
+msgid ""
+"show help for a given topic or a help overview\n"
+"\n"
+" With no arguments, print a list of commands and short help.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that topic."
+msgstr ""
+"mostra l'aiuto per un dato argomento o una panoramica d'aiuto\n"
+"\n"
+" Senza argomenti stampa un elenco dei comandi ed un breve aiuto.\n"
+"\n"
+" Dato un argomento, estensione o nome di comando, stampa l'aiuto\n"
+" per tale argomento."
+
+msgid "global options:"
+msgstr "opzioni globali:"
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr "usare \"hg help\" per l'elenco completo dei comandi"
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr ""
+"usare \"hg help\" per la lista completa dei comandi oppure \"hg -v\" per i "
+"dettagli"
+
+#, python-format
+msgid "use \"hg -v help%s\" to show aliases and global options"
+msgstr "usare \"hg -v help%s\" per mostrare gli alias e le opzioni globali"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "usare \"hg -v help %s\" per mostrare le opzioni globali"
+
+msgid ""
+"list of commands:\n"
+"\n"
+msgstr ""
+"elenco dei comandi:\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"alias: %s\n"
+
+msgid "(no help text available)"
+msgstr "(nessun testo di aiuto disponibile)"
+
+msgid "options:\n"
+msgstr "opzioni:\n"
+
+msgid "no commands defined\n"
+msgstr "nessun comando definito\n"
+
+msgid ""
+"\n"
+"enabled extensions:\n"
+"\n"
+msgstr ""
+"\n"
+"estensioni abilitate:\n"
+"\n"
+
+#, python-format
+msgid " %s %s\n"
+msgstr " %s %s\n"
+
+msgid "no help text available"
+msgstr "nessun testo di aiuto disponibile"
+
+#, python-format
+msgid "%s extension - %s\n"
+msgstr "estensione %s - %s\n"
+
+msgid "Mercurial Distributed SCM\n"
+msgstr "Mercurial SCM Distribuito\n"
+
+msgid ""
+"basic commands:\n"
+"\n"
+msgstr ""
+"comandi base:\n"
+"\n"
+
+msgid ""
+"\n"
+"additional help topics:\n"
+"\n"
+msgstr ""
+"\n"
+"argomenti di aiuto aggiuntivi:\n"
+"\n"
+
+msgid ""
+"identify the working copy or specified revision\n"
+"\n"
+" With no revision, print a summary of the current state of the repo.\n"
+"\n"
+" With a path, do a lookup in another repository.\n"
+"\n"
+" This summary identifies the repository state using one or two parent\n"
+" hash identifiers, followed by a \"+\" if there are uncommitted changes\n"
+" in the working directory, a list of tags for this revision and a branch\n"
+" name for non-default branches.\n"
+" "
+msgstr ""
+"identifica la copia di lavoro o una revisione specifica\n"
+"\n"
+" Con nessuna revisione, stampa un sommario dello stato corrente del\n"
+" repository.\n"
+"\n"
+" Con un percorso, effettua una ricerca in un altro repository.\n"
+"\n"
+" Questo sommario identifica lo stato del repository usando uno o\n"
+" due hash dei genitori, seguito da un \"+\" se ci sono modifiche di\n"
+" cui non si è eseguito il commit nella directory di lavoro, un\n"
+" elenco di tag per questa revisione e un nome di branch per branch\n"
+" non-default.\n"
+" "
+
+msgid ""
+"import an ordered set of patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (body part must be type text/plain or\n"
+" text/x-patch to be used). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and description\n"
+" from patch override values from message headers and body. Values\n"
+" given on command line with -m and -u override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory\n"
+" to the parent of each patch before applying it, and will abort\n"
+" if the resulting changeset has a different ID than the one\n"
+" recorded in the patch. This may happen due to character set\n"
+" problems or other deficiencies in the text patch format.\n"
+"\n"
+" With --similarity, hg will attempt to discover renames and copies\n"
+" in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use patch name \"-\".\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"importa un insieme ordinato di patch\n"
+"\n"
+" Importa un elenco di patch e ne effettua il commit\n"
+" individualmente.\n"
+"\n"
+" Se ci sono modifiche pendenti nella directory di lavoro,\n"
+" l'importazione abortirà a meno che non si usi il flag -f.\n"
+"\n"
+" E' possibile importare una patch direttamente da un messaggio\n"
+" mail. Anche le patch come allegato funzionano (il corpo deve\n"
+" essere di tipo text/plain o deve essere usato text/x-patch). Le\n"
+" intestazioni Da e Soggetto della mail sono usate come committente\n"
+" e messaggio di commit di default. Tutte le parti del corpo\n"
+" text/plain antecedenti il primo diff sono aggiunte al messaggio di\n"
+" commit.\n"
+"\n"
+" Se la patch importata è stata generata da hg export, l'utente e la\n"
+" descrizione dalla patch rimpiazzano i valori dal corpo e\n"
+" dall'intestazione del messaggio. I valori forniti dalla riga di\n"
+" comando con -m e -u rimpiazzano questi.\n"
+"\n"
+" Se viene specificato --exact, l'importazione imposterà la\n"
+" directory di lavoro al genitore di ogni patch prima di applicarla,\n"
+" e abortirà se il changeset risultante avrà un ID differente\n"
+" rispetto a quello registrato nella patch Questo potrebbe capitare\n"
+" a causa di problemi del set di caratteri o altre carenze nel\n"
+" formato della patch testuale.\n"
+"\n"
+" Con --similarity, hg tenterà di scoprire le rinomine e le copie\n"
+" nella patch allo stesso modo di 'addremove'.\n"
+"\n"
+" Per leggere una patch dallo standard input, usare come nome della\n"
+" patch \"-\". Vedere 'hg help dates' per un elenco dei formati validi\n"
+" per -d/--date.\n"
+" "
+
+msgid "applying patch from stdin\n"
+msgstr "sto applicando patch dallo stdin\n"
+
+msgid "no diffs found"
+msgstr "nessun diff trovato"
+
+#, python-format
+msgid ""
+"message:\n"
+"%s\n"
+msgstr ""
+"messaggio:\n"
+"%s\n"
+
+msgid "not a mercurial patch"
+msgstr "non è una patch di mercurial"
+
+msgid "patch is damaged or loses information"
+msgstr "la patch è danneggiata o perde informazioni"
+
+msgid ""
+"show new changesets found in source\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would be pulled if a pull\n"
+" was requested.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the changesets\n"
+" twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+msgstr ""
+"mostra i nuovi changeset trovati nella sorgente\n"
+"\n"
+" Mostra i nuovi changeset trovati nel percorso/URL specificato o\n"
+" nella posizione di pull di default. Questi sono i changeset di cui\n"
+" si effettuerebbe il pull se questo venisse richiesto.\n"
+"\n"
+" Per repository remoti, usare --bundle evita di scaricare due volte\n"
+" i changeset se incoming è seguito da un pull.\n"
+"\n"
+" Vedere pull per dettagli sui formati di sorgenti validi.\n"
+" "
+
+msgid ""
+"create a new repository in the given directory\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it is created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"crea un nuovo repository nella directory data\n"
+"\n"
+" Inizializza un nuovo repository nella directory data. Se tale\n"
+" directory non esiste la crea.\n"
+"\n"
+" Se nessuna directory è specificata si usa la directory corrente.\n"
+"\n"
+" E' possibile specificare un URL ssh:// come destinazione.\n"
+" Vedere 'hg help urls' per maggiorni informazioni.\n"
+" "
+
+msgid ""
+"locate files matching specific patterns\n"
+"\n"
+" Print all files under Mercurial control whose names match the\n"
+" given patterns.\n"
+"\n"
+" This command searches the entire repository by default. To search\n"
+" just the current directory and its subdirectories, use\n"
+" \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints all file\n"
+" names.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the \"-0\" option to both this command and \"xargs\".\n"
+" This will avoid the problem of \"xargs\" treating single filenames\n"
+" that contain white space as multiple filenames.\n"
+" "
+msgstr ""
+"trova file corrispondenti a pattern specificati\n"
+"\n"
+" Stampa tutti i file sotto il controllo di Mercurial il cui nome\n"
+" corrisponde ai dati pattern.\n"
+"\n"
+" Questo comando cerca nell'intero repository di default. Per\n"
+" ricercare solo nella directory corrente e le sue sottodirectory,\n"
+" usare \"--include .\".\n"
+"\n"
+" Se non sono forniti pattern, questo comando stampa il nome di\n"
+" tutti i file.\n"
+"\n"
+" Se si desidera fornire l'output di questo comando al comando\n"
+" \"xargs\", usare l'opzione \"-0\" sia per questo comando sia per\n"
+" \"xargs\". Questo eviterà il problema per cui \"xargs\" tratta\n"
+" filename singoli che contengono spazi bianchi come filename\n"
+" multipli.\n"
+" "
+
+#, fuzzy
+msgid ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a file name to follow history across\n"
+" renames and copies. --follow without a file name will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command outputs: changeset id and hash, tags,\n"
+" non-trivial parents, user, date and time, and a summary for each\n"
+" commit. When the -v/--verbose switch is used, the list of changed\n"
+" files and full commit message is shown.\n"
+"\n"
+" NOTE: log -p may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, the files: list will only reflect files\n"
+" that are different from BOTH parents.\n"
+"\n"
+" "
+msgstr ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a file name to follow history across\n"
+" renames and copies. --follow without a file name will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" Vedere 'hg help dates' per un elenco dei formati validi per -d/--date.\n"
+"\n"
+" By default this command outputs: changeset id and hash, tags,\n"
+" non-trivial parents, user, date and time, and a summary for each\n"
+" commit. When the -v/--verbose switch is used, the list of changed\n"
+" files and full commit message is shown.\n"
+"\n"
+" NOTE: log -p may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only. Also, the files: list will only reflect files\n"
+" that are different from BOTH parents.\n"
+"\n"
+" "
+
+msgid ""
+"looks up all renames for a file (up to endrev) the first\n"
+" time the file is given. It indexes on the changerev and only\n"
+" parses the manifest if linkrev != changerev.\n"
+" Returns rename info for fn at changerev rev."
+msgstr ""
+"cerca tutte le rinomine di un file (fino a endrev) la prima volta che\n"
+" il file viene fornito. Indicizza su changerev e parsifica solo\n"
+" il manifesto se linkrev != changerev.\n"
+" Restituisce le informazioni sulle rinomine per fn alla\n"
+" revisione changerev."
+
+msgid ""
+"output the current or given revision of the project manifest\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" The manifest is the list of files being version controlled. If no "
+"revision\n"
+" is given then the first parent of the working directory is used.\n"
+"\n"
+" With -v flag, print file permissions, symlink and executable bits. With\n"
+" --debug flag, print file revision hashes.\n"
+" "
+msgstr ""
+
+msgid ""
+"merge working directory with another revision\n"
+"\n"
+" Merge the contents of the current working directory and the\n"
+" requested revision. Files that changed between either parent are\n"
+" marked as changed for the next commit and a commit must be\n"
+" performed before any further updates are allowed.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other head,\n"
+" the other head is merged with by default. Otherwise, an explicit\n"
+" revision to merge with must be provided.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr "la branch '%s' ha %d head - fare il merge con una revisione esplicita"
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr "la branch '%s' ha una head - fare il merge con una revisione esplicita"
+
+msgid "there is nothing to merge"
+msgstr "non c'è nulla di cui fare il merge"
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr "%s - invece usare \"hg update\""
+
+msgid ""
+"working dir not at a head rev - use \"hg update\" or merge with an explicit "
+"rev"
+msgstr ""
+"la directory di lavoro non è una revisione head - usare \"hg update\"\n"
+"o fare il merge con una revisione esplicita"
+
+msgid ""
+"show changesets not found in destination\n"
+"\n"
+" Show changesets not found in the specified destination repository or\n"
+" the default push location. These are the changesets that would be "
+"pushed\n"
+" if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+msgstr ""
+"mostra changeset non trovati nella destinazione\n"
+"\n"
+" Mostra i changeset non trovati nel repository di destinazione\n"
+" specificato o nella posizione di default di push. Questi sono i\n"
+" changeset che di cui si effetterebbe il push se questo venisse\n"
+" richiesto.\n"
+"\n"
+" Vedere pull per dettagli sui formati validi di destinazioni.\n"
+" "
+
+msgid ""
+"show the parents of the working dir or revision\n"
+"\n"
+" Print the working directory's parent revisions. If a\n"
+" revision is given via --rev, the parent of that revision\n"
+" will be printed. If a file argument is given, revision in\n"
+" which the file was last changed (before the working directory\n"
+" revision or the argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"mostra i genitori della directory di lavoro o di una revisione\n"
+"\n"
+" Stampa le revisioni genitori della directory di lavoro. Se una\n"
+" revisione è data tramite --rev, verrà stampato il genitore di\n"
+" quella revisione. Se viene fornito un file come argomento,\n"
+" verrà stampata l'ultima revisione in cui il file è stato\n"
+" modificato (prima della revisione della directory di lavoro\n"
+" o dell'argomento di --rev se fornito).\n"
+" "
+
+msgid "can only specify an explicit file name"
+msgstr ""
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr "'%s' non trovato nel manifesto!"
+
+msgid ""
+"show aliases for remote repositories\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given, show\n"
+" definition of available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+msgid "not found!\n"
+msgstr "non trovato!\n"
+
+msgid "not updating, since new heads added\n"
+msgstr ""
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr "(esegui 'hg heads' per vedere le head, 'hg merge' per fare un merge)\n"
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr "(esegui 'hg update' per ottenere una copia funzionante)\n"
+
+msgid ""
+"pull changes from the specified source\n"
+"\n"
+" Pull changes from a remote repository to a local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository. By default, this\n"
+" does not update the copy of the project in the working directory.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"effettua il pull delle modifiche dalla sorgente specificata\n"
+"\n"
+" Effettua il pull di modifiche da un repository remoto in uno locale.\n"
+"\n"
+" Questo trova tutte le modifiche dal repository al percorso o URL "
+"specificato\n"
+" e le aggiunge al repository locale. Di default non aggiorna la copia "
+"del\n"
+" progetto nella directory di lavoro.\n"
+"\n"
+" Se SOURCE viene omesso, verrà usato il percorso 'default'.\n"
+" Vedere 'hg help urls' per maggiori informazioni.\n"
+" "
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+"L'altro repository non supporta la ricerca di revisioni, quindi una "
+"revisione non può essere specificata."
+
+msgid ""
+"push changes to the specified destination\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It helps to move\n"
+" changes from the current repository to a different one. If the\n"
+" destination is local this is identical to a pull in that directory\n"
+" from the current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" the client has forgotten to pull and merge before pushing.\n"
+"\n"
+" If -r is used, the named changeset and all its ancestors will be pushed\n"
+" to the remote repository.\n"
+"\n"
+" Look at the help text for urls for important details about ssh:// URLs.\n"
+" If DESTINATION is omitted, a default path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"effettua il push di modifiche verso la destinazione specificata\n"
+"\n"
+" Effettua il push di modifiche dal repository locale verso la\n"
+" destinazione data.\n"
+"\n"
+" Questa è l'operazione simmetrica di pull. Aiuta a spostare modifiche\n"
+" dal repository corrente in un altro. Se la destinazione è locale questo\n"
+" è identico ad un pull in quella directory verso questa.\n"
+"\n"
+" Di default, il push verrà rifiutato se viene rivelato che aumenterà il\n"
+" numerdo di head remote. Questo generalmente indica che il client ha\n"
+" dimenticato di fare pull e merge prima del push.\n"
+"\n"
+" Se si usa -r, si farà il push del changeset dato e tutti i suoi "
+"antenati\n"
+" verso il repository remoto.\n"
+"\n"
+" Vedere il testo di aiuto per gli url per importanti dettagli sugli\n"
+" URL ssh://.\n"
+" Se viene omessa DESTINATION, verrà usato il percorso di default.\n"
+" Vedere 'hg help urls' per maggiori informazioni.\n"
+" "
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr "sto effettuando il push verso %s\n"
+
+msgid ""
+"raw commit interface (DEPRECATED)\n"
+"\n"
+" (DEPRECATED)\n"
+" Lowlevel commit, for use in helper scripts.\n"
+"\n"
+" This command is not intended to be used by normal users, as it is\n"
+" primarily useful for importing from other SCMs.\n"
+"\n"
+" This command is now deprecated and will be removed in a future\n"
+" release, please use debugsetparents and commit instead.\n"
+" "
+msgstr ""
+
+msgid "(the rawcommit command is deprecated)\n"
+msgstr "(il comando rawcommit è deprecato)\n"
+
+msgid ""
+"roll back an interrupted transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an interrupted\n"
+" operation. It should only be necessary when Mercurial suggests it.\n"
+" "
+msgstr ""
+"effettua il rollback di una transazione interrotta\n"
+"\n"
+" Effettua il ripristino da un commit o pull interrotto.\n"
+"\n"
+" Questo comando prova a correggere lo stato del repository dopo\n"
+" un'operazione interrotta. Dovrebbe essere necessario solamente\n"
+" quando Mercurial lo suggerisce.\n"
+" "
+
+msgid ""
+"remove the specified files on the next commit\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the entire\n"
+" project history. -A can be used to remove only files that have already\n"
+" been deleted, -f can be used to force deletion, and -Af can be used\n"
+" to remove files from the next revision without deleting them.\n"
+"\n"
+" The following table details the behavior of remove for different file\n"
+" states (columns) and option combinations (rows). The file states are\n"
+" Added, Clean, Modified and Missing (as reported by hg status). The\n"
+" actions are Warn, Remove (from branch) and Delete (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid "no files specified"
+msgstr "nessun file specificato"
+
+#, python-format
+msgid "not removing %s: file %s (use -f to force removal)\n"
+msgstr "non rimuovo %s: file %s (usare -f per forzare la rimozione)\n"
+
+msgid "still exists"
+msgstr "esiste ancora"
+
+msgid "is modified"
+msgstr "è modificato"
+
+msgid "has been marked for add"
+msgstr "è stato marcato per l'aggiunta"
+
+msgid ""
+"rename files; equivalent of copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If\n"
+" dest is a directory, copies are put in that directory. If dest is\n"
+" a file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with --after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid ""
+"retry file merges from a merge or update\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a switch.\n"
+"\n"
+" This command will also allow listing resolved files and manually\n"
+" marking and unmarking files as resolved.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+msgstr ""
+
+msgid "too many options specified"
+msgstr "troppe opzioni specificate"
+
+msgid "can't specify --all and patterns"
+msgstr "non è possibile specificare pattern e --all"
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr ""
+"nessun file o directory specificata; usare --all per rieffettuare il merge "
+"di tutti i file"
+
+msgid ""
+"restore individual files or dirs to an earlier state\n"
+"\n"
+" (use update -r to check out earlier revisions, revert does not\n"
+" change the working dir parents)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r option, revert the given files or directories to their\n"
+" contents as of a specific revision. This can be helpful to \"roll\n"
+" back\" some or all of an earlier change.\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable\n"
+" mode of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+msgstr ""
+"ripristina file singoli o directory ad uno stato precedente\n"
+"\n"
+" (usare update -r per effettuare il checkout di revisioni\n"
+" precedenti, revert non cambia i genitori della directory di\n"
+" lavoro)\n"
+"\n"
+" Se nessuna revisione viene specificata, i file o directory\n"
+" specificati vengono riportati al contenuto che avevano nel\n"
+" genitore della directory di lavoro. Questo ripristina il contenuto\n"
+" dei file interessati ad uno stato non modificato e annulla\n"
+" aggiunte, rimozioni, copie e rinomine. Se la directory di lavoro\n"
+" ha due genitori, è necessario specificare esplicitamente la\n"
+" revisione a cui tornare.\n"
+"\n"
+" Usando l'opzione -r, riporta i dati file o directory al loro\n"
+" contenuto ad una specifica revisione. Questo può essere utile per\n"
+" effettuare il \"roll back\" di alcune o tutte le modifiche\n"
+" precedenti. Vedere 'hg help dates' per un elenco dei formati\n"
+" validi per -d/--date.\n"
+"\n"
+" Revert modifica la directory di lavoro. Non effettua il commit di\n"
+" alcuna modifica, nè cambia i genitori della directory di lavoro Se\n"
+" si effettua il revert ad una revisione differente di quella del\n"
+" genitore della directory di lavoro, i file interessati in seguito\n"
+" appariranno quindi modificati.\n"
+"\n"
+" Se un file è stato cancellato viene ripristinato. Se è stato\n"
+" modificato il flag di esecuzione di file, questo viene resettato.\n"
+"\n"
+" Se vengono forniti nomi, tutti i file corrispondenti ai nomi\n"
+" vengono ripristinati. Se non vengono forniti argomenti nessun file\n"
+" viene ripristinato.\n"
+"\n"
+" I file modificati vengono salvati con un suffisso .orig prima di\n"
+" essere ripristinati. Per disabilitare questi backup, usare\n"
+" --no-backup.\n"
+" "
+
+msgid "you can't specify a revision and a date"
+msgstr "non è possibile specificare sia una revisione sia una data"
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr ""
+"nessun file o directory specificati; usare --all per ripristinare l'intero "
+"repository"
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr "sto dimenticandomi di %s\n"
+
+#, python-format
+msgid "reverting %s\n"
+msgstr "sto ripristinando %s\n"
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr "sto annullando la rimozione di %s\n"
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr "sto salvando la versione corrente di %s come %s\n"
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr "file non gestito: %s\n"
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr "nessuna modifica richiesta per %s\n"
+
+msgid ""
+"roll back the last transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+msgstr ""
+"effettua il rollback dell'ultima transazione\n"
+"\n"
+" Questo comando dovrebbe essere usato con cautela. Esiste un solo\n"
+" livello di rollback e non c'è modo di annullare un rollback.\n"
+" Ripristinerà anche il dirstate al tempo dell'ultima transazione,\n"
+" perdendo qualunque modifica ad esso da quel momento in poi.\n"
+"\n"
+" Le transazioni sono usate per incapsulare gli effetti di tutti i\n"
+" comandi che creano nuovi changeset o propagano changeset esistenti\n"
+" in un altro repository. Ad esempio, i seguenti comandi sono\n"
+" transazionali ed è possibile effettuare il rollback dei loro\n"
+" effetti:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (con questo repository come destinazione)\n"
+" unbundle\n"
+"\n"
+" L'uso di questo comando non è inteso per repository pubblici. Una\n"
+" volta che le modifiche sono visibili per il pull da parte di altri\n"
+" utenti, effettuare il rollback locale di una transazione non ha\n"
+" effetti (qualcun'altro potrebbe aver già effettuato il pull delle\n"
+" modifiche). Inoltre, è possibile che si verifichi un race con i\n"
+" lettori del repository; ad esempio un pull in progresso dal\n"
+" repository potrebbe fallire se viene effettuato un rollback.\n"
+" "
+
+msgid ""
+"print the root (top) of the current working dir\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+msgstr ""
+"stampa la radice (top) della directory di lavoro corrente\n"
+"\n"
+" Stampa la directory radice del repository corrente.\n"
+" "
+
+msgid ""
+"export the repository via HTTP\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the \"-A\" and \"-E\" options to log to files.\n"
+" "
+msgstr ""
+"esporta il repository via HTTP\n"
+"\n"
+" Avvia un server HTTP locale per il pull e la navigazione.\n"
+"\n"
+" Di default i log del server vengono inviati allo stdout e gli\n"
+" errori allo stderr. Usare le opzioni \"-A\" e \"-E\" per effettuare il\n"
+" log su file.\n"
+" "
+
+#, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr "in ascolto su http://%s%s/%s (limitato a %s:%d)\n"
+
+msgid ""
+"show changed files in the working directory\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" source of a copy/move operation, are not listed unless -c (clean),\n"
+" -i (ignored), -C (copies) or -A is given. Unless options described\n"
+" with \"show only ...\" are given, the options -mardu are used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/-ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the difference between them is shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = deleted, but still tracked\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = the previous added file was copied from here\n"
+" "
+msgstr ""
+
+msgid ""
+"add one or more tags for the current or given revision\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"aggiunge una o più tag per la revisione corrente o data\n"
+"\n"
+" Nomina una revisione particolare usando <nome>.\n"
+"\n"
+" Le tag sono usate per dare un nome a revisioni particolari del\n"
+" repository e sono molto utili per confrontare revisioni\n"
+" differenti, per tornare indietro a versioni precedenti\n"
+" significative o per marcare punti di branch come release, ecc.\n"
+"\n"
+" Se nessuna revisione viene fornita, viene usato il genitore della\n"
+" directory di lavoro, o tip se non si è effettuato il check out di\n"
+" nessuna revisione.\n"
+"\n"
+" Per facilitare il controllo di versione, la distribuzione e il\n"
+" merge di tag, sono memorizzate come file chiamato \".hgtags\" che è\n"
+" gestito analogamente ad altri file del progetto e può essere\n"
+" modificato manualmente se necessario. Il file '.hg/localtags' è\n"
+" usato per le tag locali (non condivise tra repository).\n"
+"\n"
+" Vedere 'hg help dates' per un elenco di formati validi per\n"
+" -d/--date.\n"
+" "
+
+msgid "tag names must be unique"
+msgstr "i nomi delle tag devono essere univoci"
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr "il nome '%s' è riservato"
+
+msgid "--rev and --remove are incompatible"
+msgstr "--rev e --remove sono incompatibili"
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr "la tag '%s' non esiste"
+
+#, python-format
+msgid "tag '%s' is not a %s tag"
+msgstr "la tag '%s' non è una tag %s"
+
+#, python-format
+msgid "Removed tag %s"
+msgstr "Rimossa tag %s"
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr "la tag '%s' esiste già (usare -f per forzare)"
+
+#, python-format
+msgid "Added tag %s for changeset %s"
+msgstr "Aggiunta tag %s per il changeset %s"
+
+msgid ""
+"list repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose switch\n"
+" is used, a third column \"local\" is printed for local tags.\n"
+" "
+msgstr ""
+"elenca le tag del repository\n"
+"\n"
+" Questo elenca sia le tag regolari sia le tag locali. Quando viene usata "
+"l'opzione -v/--verbose\n"
+" una terza colonna \"local\" viene stampata per le tag locali.\n"
+" "
+
+msgid ""
+"show the tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the most\n"
+" recently added changeset in the repository, the most recently\n"
+" changed head.\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+msgstr ""
+"mostra la revisione tip\n"
+"\n"
+" La revisione tip (di solito chiamata solo tip) è il più recente\n"
+" changeset aggiunto al repository, l'head modificata più\n"
+" recentemente.\n"
+"\n"
+" Se si ha fatto solo un commit, quel commit sarà il tip. Se si ha\n"
+" appena fatto il pull di modifiche da un altro repository, il tip\n"
+" di quel repository diventa il tip corrente. La tag \"tip\" tag è\n"
+" speciale e non può essere rinominata o assegnata ad un changeset\n"
+" differente.\n"
+" "
+
+msgid ""
+"apply one or more changegroup files\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+msgstr ""
+"applica uno o più file changegroup\n"
+"\n"
+" Applica uno o più file changegroup compressi generati dal\n"
+" comando bundle.\n"
+" "
+
+msgid ""
+"update working directory\n"
+"\n"
+" Update the repository's working directory to the specified revision,\n"
+" or the tip of the current branch if none is specified. Use null as\n"
+" the revision to remove the working copy (like 'hg clone -U').\n"
+"\n"
+" When the working dir contains no uncommitted changes, it will be\n"
+" replaced by the state of the requested revision from the repo. When\n"
+" the requested revision is on a different branch, the working dir\n"
+" will additionally be switched to that branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C to discard them,\n"
+" forcibly replacing the state of the working dir with the requested\n"
+" revision.\n"
+"\n"
+" When there are uncommitted changes and option -C is not used, and\n"
+" the parent revision and requested revision are on the same branch,\n"
+" and one of them is an ancestor of the other, then the new working\n"
+" directory will contain the requested revision merged with the\n"
+" uncommitted changes. Otherwise, the update will fail with a\n"
+" suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for --date.\n"
+" "
+msgstr ""
+"aggiorna la directory di lavoro\n"
+"\n"
+" Aggiorna la directory di lavoro del repository ad una revisione\n"
+" specifica, o al tip della branch corrente se nessuna è stata\n"
+" specificata. Usare null come revisione per rimuovere la copia di\n"
+" lavoro (come 'hg clone -U').\n"
+"\n"
+" Quando la directory di lavoro non contiene modifiche di cui non si\n"
+" è eseguito il commit, sarà rimpiazzata dallo stato della revisione\n"
+" richiesta dal repository. Quando la revisione richiesta è su una\n"
+" branch differente, la directory di lavoro verrà inoltre spostata\n"
+" su quella branch.\n"
+"\n"
+" Quandi ci sono modifiche di cui non si è eseguito il commit, usare\n"
+" l'opzione -C per scartarle, forzando la sostituzione dello stato\n"
+" della directory di lavoro con la revisione richiesta.\n"
+"\n"
+" Quando ci sono modifiche di cui non si è eseguito il commit,\n"
+" l'opzione -C non è usata, la revisione del genitore e di quella\n"
+" richiesta sono sulla stessa branch e una di queste è un antenato\n"
+" dell'altro, allora la nuova directory di lavoro conterrà la\n"
+" revisione richiesta unita con le modifiche non salvate. Altrimenti\n"
+" l'aggiornamento fallirà con un suggerimento di usare invece\n"
+" 'merge' o 'update -C'.\n"
+"\n"
+" Se si desidera aggiornare solo un file ad una revisione più\n"
+" vecchia, usare revert.\n"
+"\n"
+" Vedere 'hg help dates' per un elenco di formati validi per --date.\n"
+" "
+
+msgid ""
+"verify the integrity of the repository\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+msgstr ""
+"verifica l'integrità del repository\n"
+"\n"
+" Verifica l'integrità del repository corrente.\n"
+"\n"
+" Questo comando eseguirà un controllo estensivo dell'integrità del\n"
+" repository validando gli hash e i checksum di ogni voce nel\n"
+" changelog, manifesto, e file tracciati, così come l'integrità dei\n"
+" loro link incrociati e indici.\n"
+" "
+
+msgid "output version and copyright information"
+msgstr "stampa la versione e le informazioni di copyright"
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr "Mercurial SCM Distribuito (versione %s)\n"
+
+msgid ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> e altri\n"
+"Questo è software libero; vedere i sorgenti per le condizioni di copia.\n"
+"Non c'è alcuna garanzia; neppure di COMMERCIABILITÀ o IDONEITÀ AD UNO\n"
+"SCOPO PARTICOLARE.\n"
+
+msgid "repository root directory or symbolic path name"
+msgstr "directory radice del repository o nome del percorso simbolico"
+
+msgid "change working directory"
+msgstr "cambia la directory di lavoro"
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr "non chiedere conferma, assume 'yes' per ogni risposta richiesta"
+
+msgid "suppress output"
+msgstr "sopprime l'output"
+
+msgid "enable additional output"
+msgstr "abilita output aggiuntivo"
+
+msgid "set/override config option"
+msgstr "imposta/sovrascrive l'opzione di configurazione"
+
+msgid "enable debugging output"
+msgstr "abilita output di debug"
+
+msgid "start debugger"
+msgstr "avvia il debugger"
+
+msgid "set the charset encoding"
+msgstr "imposta la codifica dei caratteri"
+
+msgid "set the charset encoding mode"
+msgstr "imposta la modalità di codifica dei caratteri"
+
+msgid "print improved command execution profile"
+msgstr "stampa il profilo di esecuzione dei comandi migliorato"
+
+msgid "print traceback on exception"
+msgstr "stampa un traceback in seguito ad eccezioni"
+
+msgid "time how long the command takes"
+msgstr "misura quanto tempo impiega il comando"
+
+msgid "print command execution profile"
+msgstr "stampa il profilo di esecuzione dei comandi"
+
+msgid "output version information and exit"
+msgstr "stampa informazioni sulla versione ed esce"
+
+msgid "display help and exit"
+msgstr "mostra l'aiuto ed esce"
+
+msgid "do not perform actions, just print output"
+msgstr "non esegue azioni, stampa solamente l'output"
+
+msgid "specify ssh command to use"
+msgstr "specifica il comando ssh da usare"
+
+msgid "specify hg command to run on the remote side"
+msgstr "specifica il comando hg da eseguire in remoto"
+
+msgid "include names matching the given patterns"
+msgstr "include nomi che corrispondono ai pattern dati"
+
+msgid "exclude names matching the given patterns"
+msgstr "esclude nomi che corrispondono ai pattern dati"
+
+msgid "use <text> as commit message"
+msgstr "usa <text> come messaggio di commit"
+
+msgid "read commit message from <file>"
+msgstr "legge il messaggio di commit da <file>"
+
+msgid "record datecode as commit date"
+msgstr "registra il datecode come data del commit"
+
+msgid "record user as committer"
+msgstr "registra l'utente come committente"
+
+msgid "display using template map file"
+msgstr "mostra usando un file mappa template"
+
+msgid "display with template"
+msgstr "mostra con un template"
+
+msgid "do not show merges"
+msgstr "non mostrare i merge"
+
+msgid "treat all files as text"
+msgstr "tratta tutti i file come testo"
+
+msgid "don't include dates in diff headers"
+msgstr "non includere le date nelle intestazioni dei diff"
+
+msgid "show which function each change is in"
+msgstr "mostra in quale funzione si trova ogni modifica"
+
+msgid "ignore white space when comparing lines"
+msgstr "ignora spazi bianchi quando si confrontano righe"
+
+msgid "ignore changes in the amount of white space"
+msgstr "ignora le modifiche nel conteggio degli spazi bianchi"
+
+msgid "ignore changes whose lines are all blank"
+msgstr "ignora le modifiche le cui righe sono tutte vuote"
+
+msgid "number of lines of context to show"
+msgstr "numero di righe di contesto da mostrare"
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr "stima i file rinominati per similarità (0<=s<=100)"
+
+msgid "[OPTION]... [FILE]..."
+msgstr "[OPZIONI]... [FILE]..."
+
+msgid "annotate the specified revision"
+msgstr "annota la revisione specificata"
+
+msgid "follow file copies and renames"
+msgstr "segue le copie e le rinomine dei file"
+
+msgid "list the author (long with -v)"
+msgstr "elenca l'autore (verboso con -v)"
+
+msgid "list the date (short with -q)"
+msgstr "elenca la data (breve con -q)"
+
+msgid "list the revision number (default)"
+msgstr "elenca il numero di revisione (default)"
+
+msgid "list the changeset"
+msgstr "elenca il changeset"
+
+msgid "show line number at the first appearance"
+msgstr "mostra il numero di riga alla prima apparizione"
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+
+msgid "do not pass files through decoders"
+msgstr "non passare file attraverso decodificatori"
+
+msgid "directory prefix for files in archive"
+msgstr "prefisso di directory per i file nell'archivio"
+
+msgid "revision to distribute"
+msgstr "revisione da distribuire"
+
+msgid "type of distribution to create"
+msgstr "tipo di distribuzione da creare"
+
+msgid "[OPTION]... DEST"
+msgstr "[OPZIONI]... DEST"
+
+msgid "merge with old dirstate parent after backout"
+msgstr "effettua il merge con il vecchio dirstate del genitore dopo il backout"
+
+msgid "parent to choose when backing out merge"
+msgstr "il genitore da scegliere quando effettuare il backout del merge"
+
+msgid "revision to backout"
+msgstr "revisione di cui effettuare il backout"
+
+msgid "[OPTION]... [-r] REV"
+msgstr "[OPZIONI]... [-r] REV"
+
+msgid "reset bisect state"
+msgstr "resetta lo stato di bisect"
+
+msgid "mark changeset good"
+msgstr "marca il changeset come buono"
+
+msgid "mark changeset bad"
+msgstr "marca il changeset come cattivo"
+
+msgid "skip testing changeset"
+msgstr "salta il changeset di test"
+
+msgid "use command to check changeset state"
+msgstr "usa il comando per controllare lo stato del changeset"
+
+msgid "do not update to target"
+msgstr "non aggiornare a target"
+
+msgid "[-gbsr] [-c CMD] [REV]"
+msgstr "[-gbsr] [-c CMD] [REV]"
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr "imposta il nome della branch anche se nasconde una branch esistente"
+
+msgid "reset branch name to parent branch name"
+msgstr "resetta il nome della branch al nome della branch genitore"
+
+msgid "[-fC] [NAME]"
+msgstr "[-fC] [NOME]"
+
+msgid "show only branches that have unmerged heads"
+msgstr ""
+"mostra solo le branch che hanno head di cui non si è effettuato il merge"
+
+msgid "[-a]"
+msgstr "[-a]"
+
+msgid "run even when remote repository is unrelated"
+msgstr "esegui anche quando il repository remoto non è collegato"
+
+msgid "a changeset up to which you would like to bundle"
+msgstr "un changeset fino al quale si desidera effettuare il bundle"
+
+msgid "a base changeset to specify instead of a destination"
+msgstr "un changeset base da specificare invece di una destinazione"
+
+msgid "bundle all changesets in the repository"
+msgstr "effettua il bundle di tutti i changeset nel repository"
+
+msgid "bundle compression type to use"
+msgstr "tipo di compressione da usare per il bundle"
+
+msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+
+msgid "print output to file with formatted name"
+msgstr "stampa l'output su file con un nome formattato"
+
+msgid "print the given revision"
+msgstr "stampa la data revisione"
+
+msgid "apply any matching decode filter"
+msgstr "applica qualunque filtro di decodifica corrispondente"
+
+msgid "[OPTION]... FILE..."
+msgstr "[OPZIONI]... FILE..."
+
+msgid "the clone will only contain a repository (no working copy)"
+msgstr "il clone conterrà solo un repository (nessuna copia di lavoro)"
+
+msgid "a changeset you would like to have after cloning"
+msgstr "un changeset che si desidera avere dopo il clone"
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr "[OPZIONI]... SORGENTE [DEST]"
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr ""
+"marca file nuovi/mancanti come aggiunti/rimossi prima di effettuare il commit"
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr "marca una branch come chiusa, nascondendola dall'elenco delle branch"
+
+msgid "record a copy that has already occurred"
+msgstr "registra una copia che si è già verificata"
+
+msgid "forcibly copy over an existing managed file"
+msgstr "forza una copia su un file gestito esistente"
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr "[OPZIONI]... [SORGENTE]... DEST"
+
+msgid "[INDEX] REV1 REV2"
+msgstr "[INDICE] REV1 REV2"
+
+msgid "[COMMAND]"
+msgstr "[COMANDO]"
+
+msgid "show the command options"
+msgstr "mostra le opzioni dei comandi"
+
+msgid "[-o] CMD"
+msgstr "[-o] CMD"
+
+msgid "try extended date formats"
+msgstr "prova formati di date estesi"
+
+msgid "[-e] DATE [RANGE]"
+msgstr "[-e] DATA [RANGE]"
+
+msgid "FILE REV"
+msgstr "FILE REV"
+
+msgid "[PATH]"
+msgstr "[PERCORSO]"
+
+msgid "FILE"
+msgstr "FILE"
+
+msgid "parent"
+msgstr "genitore"
+
+msgid "file list"
+msgstr "elenco dei file"
+
+msgid "revision to rebuild to"
+msgstr "revisione alla quale ricostruire"
+
+msgid "[-r REV] [REV]"
+msgstr "[-r REV] [REV]"
+
+msgid "revision to debug"
+msgstr "revisione di cui fare il debug"
+
+msgid "[-r REV] FILE"
+msgstr "[-r REV] FILE"
+
+msgid "REV1 [REV2]"
+msgstr "REV1 [REV2]"
+
+msgid "do not display the saved mtime"
+msgstr "non mostrare l'mtime salvato"
+
+msgid "[OPTION]..."
+msgstr "[OPZIONI]..."
+
+msgid "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+msgstr "[OPZIONI]... [-r REV1 [-r REV2]] [FILE]..."
+
+msgid "diff against the second parent"
+msgstr "effettua il diff con il secondo genitore"
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr "[OPZIONI]... [-o OUTFILESPEC] REV..."
+
+msgid "end fields with NUL"
+msgstr "termina i campi con NUL"
+
+msgid "print all revisions that match"
+msgstr "stampa tutte le revisioni che corrispondono"
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr ""
+"segue la storia del changeset, o la storia del file attraverso copie e "
+"rinomine"
+
+msgid "ignore case when matching"
+msgstr "ignora il case quando si cercano corrispondenze"
+
+msgid "print only filenames and revs that match"
+msgstr "stampa solo i nomi dei file e le revisioni che corrispondono"
+
+msgid "print matching line numbers"
+msgstr "stampa i numeri di riga corrispondenti"
+
+msgid "search in given revision range"
+msgstr "cerca nell'intervallo di revisioni fornito"
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr "[OPZIONI]... PATTERN [FILE]..."
+
+msgid "show only heads which are descendants of rev"
+msgstr "mostra solo le head che sono discendenti della revisione"
+
+msgid "show only the active heads from open branches"
+msgstr "mostra solo le head attive dalle branch aperte"
+
+msgid "[-r REV] [REV]..."
+msgstr "[-r REV] [REV]..."
+
+msgid "[TOPIC]"
+msgstr "[ARGOMENTO]"
+
+msgid "identify the specified rev"
+msgstr "identifica la revisione specificata"
+
+msgid "show local revision number"
+msgstr "mostra il numero locale della revisione"
+
+msgid "show global revision id"
+msgstr "mostra id globale della revisione"
+
+msgid "show branch"
+msgstr "mostra le branch"
+
+msgid "show tags"
+msgstr "mostra le tag"
+
+msgid "[-nibt] [-r REV] [SOURCE]"
+msgstr "[-nibt] [-r REV] [SORGENTE]"
+
+msgid ""
+"directory strip option for patch. This has the same\n"
+"meaning as the corresponding patch option"
+msgstr ""
+"opzione di rimozione della directory per patch. Questa ha lo stesso\n"
+"significato dell'opzione corrispondente di patch"
+
+msgid "base path"
+msgstr "percorso base"
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr ""
+"salta il controllo di modifiche pendenti di cui non si è effettuato il commit"
+
+msgid "don't commit, just update the working directory"
+msgstr "non effettuare il commit, aggiorna solo la directory di lavoro"
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr "applica la patch al nodo da cui è stata generata"
+
+msgid "Use any branch information in patch (implied by --exact)"
+msgstr ""
+"Usa qualunque informazione sulla branch nella patch (implicato da --exact)"
+
+msgid "[OPTION]... PATCH..."
+msgstr "[OPZIONI]... PATCH..."
+
+msgid "show newest record first"
+msgstr "mostra prima il record più nuovo"
+
+msgid "file to store the bundles into"
+msgstr "file in cui salvare i bundle"
+
+msgid "a specific revision up to which you would like to pull"
+msgstr "una specifica revisione fino alla quale si desidera fare il pull"
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr "[-p] [-n] [-M] [-f] [-r REV]... [--bundle NOME_FILE] [SORGENTE]"
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-e CMD] [--remotecmd CMD] [DEST]"
+
+msgid "search the repository as it stood at rev"
+msgstr "cerca nel repository per come era alla revisione rev"
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr "termina il nome dei file con NUL, da usare con xargs"
+
+msgid "print complete paths from the filesystem root"
+msgstr "stampa i percorsi completi dalla radice del filesystem"
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr "[OPZIONI]... [PATTERN]..."
+
+msgid "only follow the first parent of merge changesets"
+msgstr "segui solo il primo genitore di un changeset di merge"
+
+msgid "show revs matching date spec"
+msgstr "mostra le revisioni che corrispondono ad una data fornita"
+
+msgid "show copied files"
+msgstr "mostra i file copiati"
+
+msgid "do case-insensitive search for a keyword"
+msgstr "effettua una ricerca case-insensitive di una parola chiave"
+
+msgid "include revs where files were removed"
+msgstr "include le revisioni in cui sono stati rimossi dei file"
+
+msgid "show only merges"
+msgstr "mostra solo i merge"
+
+msgid "revs committed by user"
+msgstr "commit delle revisioni effettuato dall'utente"
+
+msgid "show only changesets within the given named branch"
+msgstr "mostra solo i changeset all'interno della data named branch"
+
+msgid "do not display revision or any of its ancestors"
+msgstr "non mostrare la revisione o qualche suo antenato"
+
+msgid "[OPTION]... [FILE]"
+msgstr "[OPZIONI]... [FILE]"
+
+msgid "revision to display"
+msgstr "revisione da mostrare"
+
+msgid "[-r REV]"
+msgstr "[-r REV]"
+
+msgid "force a merge with outstanding changes"
+msgstr "forza un merge con modifiche pendenti"
+
+msgid "revision to merge"
+msgstr "revisione di cui fare il merge"
+
+msgid "[-f] [[-r] REV]"
+msgstr "[-f] [[-r] REV]"
+
+msgid "a specific revision up to which you would like to push"
+msgstr "una specifica revisione fino alla quale si desidera effettuare il push"
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+
+msgid "show parents from the specified rev"
+msgstr "mostra i genitori della revisione specificata"
+
+msgid "hg parents [-r REV] [FILE]"
+msgstr "hg parents [-r REV] [FILE]"
+
+msgid "[NAME]"
+msgstr "[NOME]"
+
+msgid "update to new tip if changesets were pulled"
+msgstr "aggiorna alla nuova tip se si è effettuato il pull di changeset"
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SORGENTE]"
+
+msgid "force push"
+msgstr "forza il push"
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+
+msgid "record delete for missing files"
+msgstr "registra cancellazione per i file mancanti"
+
+msgid "remove (and delete) file even if added or modified"
+msgstr "rimuove (e cancella) i file anche se sono stati aggiunti o modificati"
+
+msgid "record a rename that has already occurred"
+msgstr "registra una rinomina che si è già verificata"
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr "[OPZIONI]... SORGENTE... DEST"
+
+msgid "remerge all unresolved files"
+msgstr "rieffettua il merge di tutti i file non risolti"
+
+msgid "list state of files needing merge"
+msgstr "elenca lo stato dei file che necessitano merge"
+
+msgid "mark files as resolved"
+msgstr "marca i file come risolti"
+
+msgid "unmark files as resolved"
+msgstr "smarca i file come risolti"
+
+msgid "revert all changes when no arguments given"
+msgstr "annulla tutte le modifiche quando nessun argomento è stato fornito"
+
+msgid "tipmost revision matching date"
+msgstr "la revisione più vicina a tip corrispondente alla data"
+
+msgid "revision to revert to"
+msgstr "revisione a cui annullare"
+
+msgid "do not save backup copies of files"
+msgstr "non salva copie di backup dei file"
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr "[OPZIONI]... [-r REV] [NOME]..."
+
+msgid "name of access log file to write to"
+msgstr "nome del file di log degli accessi su cui scrivere"
+
+msgid "name of error log file to write to"
+msgstr "nome del file di log degli errori su cui scrivere"
+
+msgid "port to listen on (default: 8000)"
+msgstr "porta su cui stare in ascolto (default: 8000)"
+
+msgid "address to listen on (default: all interfaces)"
+msgstr "indirizzo su cui stare in ascolto (default: tutte le interfacce)"
+
+msgid "prefix path to serve from (default: server root)"
+msgstr "prefisso del percorso da cui servire (default: radice del server)"
+
+msgid "name to show in web pages (default: working dir)"
+msgstr "nome da mostrare nelle pagine web (default: la directory di lavoro)"
+
+msgid "name of the webdir config file (serve more than one repo)"
+msgstr "nome del file di configurazione webdir (serve più di un repository)"
+
+msgid "for remote clients"
+msgstr "per i client remoti"
+
+msgid "web templates to use"
+msgstr "template web da usare"
+
+msgid "template style to use"
+msgstr "stile dei template da usare"
+
+msgid "use IPv6 in addition to IPv4"
+msgstr "usa IPv6 in aggiunta ad IPv4"
+
+msgid "SSL certificate file"
+msgstr "file del certificato SSL"
+
+msgid "show untrusted configuration options"
+msgstr "mostra le opzioni di configurazioni non affidabili"
+
+msgid "[-u] [NAME]..."
+msgstr "[-u] [NOME]..."
+
+msgid "show status of all files"
+msgstr "mostra lo stato di tutti i file"
+
+msgid "show only modified files"
+msgstr "mostra solo i file modificati"
+
+msgid "show only added files"
+msgstr "mostra solo i file aggiunti"
+
+msgid "show only removed files"
+msgstr "mostra solo i file rimossi"
+
+msgid "show only deleted (but tracked) files"
+msgstr "mostra solo i file rimossi (ma tracciati)"
+
+msgid "show only files without changes"
+msgstr "mostra solo i file senza modifiche"
+
+msgid "show only unknown (not tracked) files"
+msgstr "mostra solo i file sconosciuti (non tracciati)"
+
+msgid "show only ignored files"
+msgstr "mostra solo i file ignorati"
+
+msgid "hide status prefix"
+msgstr "nascondi lo stato del prefisso"
+
+msgid "show source of copied files"
+msgstr "mostra la sorgente dei file copiati"
+
+msgid "show difference from revision"
+msgstr "mostra le differenze dalla revisione"
+
+msgid "replace existing tag"
+msgstr "rimpiazza tag esistente"
+
+msgid "make the tag local"
+msgstr "rendi la tag locale"
+
+msgid "revision to tag"
+msgstr "revisione da taggare"
+
+msgid "remove a tag"
+msgstr "rimuove una tag"
+
+msgid "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr "[-l] [-m TESTO] [-d DATA] [-u UTENTE] [-r REV] NOME..."
+
+msgid "[-p]"
+msgstr "[-p]"
+
+msgid "update to new tip if changesets were unbundled"
+msgstr "aggiorna alla nuova tip se changeset sono stati estratti da un bundle"
+
+msgid "[-u] FILE..."
+msgstr "[-u] FILE..."
+
+msgid "overwrite locally modified files (no backup)"
+msgstr "sovrascrivi file modificati localmente (nessun backup)"
+
+msgid "[-C] [-d DATE] [[-r] REV]"
+msgstr "[-C] [-d DATA] [[-r] REV]"
+
+msgid "not found in manifest"
+msgstr "non trovato nel manifesto"
+
+msgid "branch name not in UTF-8!"
+msgstr "il nome della branch non è in UTF-8!"
+
+#, python-format
+msgid " searching for copies back to rev %d\n"
+msgstr " sto cercando copie fino alla revisione %d\n"
+
+#, python-format
+msgid ""
+" unmatched files in local:\n"
+" %s\n"
+msgstr ""
+" file non corrispondenti in locale:\n"
+" %s\n"
+
+#, python-format
+msgid ""
+" unmatched files in other:\n"
+" %s\n"
+msgstr ""
+" file non corrispondenti in altro:\n"
+" %s\n"
+
+msgid " all copies found (* = to merge, ! = divergent):\n"
+msgstr " trovate tutte le copie (* = per merge, ! = divergenti):\n"
+
+#, python-format
+msgid " %s -> %s %s\n"
+msgstr " %s -> %s %s\n"
+
+msgid " checking for directory renames\n"
+msgstr " sto controllando directory rinominate\n"
+
+#, python-format
+msgid " dir %s -> %s\n"
+msgstr " dir %s -> %s\n"
+
+#, python-format
+msgid " file %s -> %s\n"
+msgstr " file %s -> %s\n"
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr "'\\n' e '\\r' non sono consentiti nei nomi dei file: %r"
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr "la directory %r è già nel dirstate"
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr "il file %r nel dirstate collide con %r"
+
+#, python-format
+msgid "not in dirstate: %s\n"
+msgstr "non nel dirstate: %s\n"
+
+msgid "character device"
+msgstr "device a caratteri"
+
+msgid "block device"
+msgstr "device a blocchi"
+
+msgid "fifo"
+msgstr "fifo"
+
+msgid "socket"
+msgstr "socket"
+
+msgid "directory"
+msgstr "directory"
+
+#, python-format
+msgid "%s: unsupported file type (type is %s)\n"
+msgstr "%s: tipo di file non supportato (il tipo è %s)\n"
+
+#, python-format
+msgid "abort: %s\n"
+msgstr "abortito: %s\n"
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+" %s\n"
+msgstr ""
+"hg: il comando '%s' è ambiguo:\n"
+" %s\n"
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr "tempo esaurito per l'attesa del lock tenuto da %s"
+
+#, python-format
+msgid "lock held by %s"
+msgstr "lock tenuto da %s"
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr "abortito: %s: %s\n"
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr "abortito: impossibile acquisire il lock su %s: %s\n"
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr "hg %s: %s\n"
+
+#, python-format
+msgid "hg: %s\n"
+msgstr "hg: %s\n"
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr "abortito: %s!\n"
+
+#, python-format
+msgid "abort: %s"
+msgstr "abortito: %s"
+
+msgid " empty string\n"
+msgstr "stringa vuota\n"
+
+msgid "killed!\n"
+msgstr "ucciso!\n"
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr "hg: comando '%s' sconosciuto\n"
+
+#, python-format
+msgid "abort: could not import module %s!\n"
+msgstr "abortito: non è stato possibile importare %s!\n"
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr "(ti sei dimenticato di compilare le estensioni?)\n"
+
+msgid "(is your Python install correct?)\n"
+msgstr "(l'installazione di Python è corretta?)\n"
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr "abortito: errore: %s\n"
+
+msgid "broken pipe\n"
+msgstr "pipe rotta\n"
+
+msgid "interrupted!\n"
+msgstr "interrotto!\n"
+
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+"\n"
+"pipe rotta\n"
+
+msgid "abort: out of memory\n"
+msgstr "abortito: memoria esaurita\n"
+
+msgid "** unknown exception encountered, details follow\n"
+msgstr "** incontrata eccezione sconosciuta, seguono dettagli\n"
+
+msgid "** report bug details to http://www.selenic.com/mercurial/bts\n"
+msgstr "** riportare dettagli del bug a http://www.selenic.com/mercurial/bts\n"
+
+msgid "** or mercurial@selenic.com\n"
+msgstr "** o mercurial@selenic.com\n"
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr "** Mercurial SCM Distribuito (versione %s)\n"
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr "** Estensioni caricate: %s\n"
+
+#, python-format
+msgid "malformed --config option: %s"
+msgstr "opzione --config malformata: %s"
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr "l'estensione '%s' rimpiazza i comandi: %s\n"
+
+msgid "Option --config may not be abbreviated!"
+msgstr "Non si può abbreviare l'opzione --config!"
+
+msgid "Option --cwd may not be abbreviated!"
+msgstr "Non si può abbreviare l'opzione --cwd!"
+
+msgid ""
+"Option -R has to be separated from other options (i.e. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr ""
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr ""
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr "il repository '%s' non è locale"
+
+msgid "invalid arguments"
+msgstr "argomenti non validi"
+
+msgid "exception raised - generating profile anyway\n"
+msgstr "eccezione sollevata - genero comunque il profilo\n"
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr "*** fallita l'importazione dell'estensione %s da %s: %s\n"
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr "*** fallita l'importazione dell'estensione %s: %s\n"
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr "non è stato possibile trovare il tool per il merge %s\n"
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr "il tool %s non può gestire link simbolici\n"
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr "il tool %s non può gestire file binari\n"
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr "il tool %s richiede una GUI\n"
+
+#, python-format
+msgid "picked tool '%s' for %s (binary %s symlink %s)\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+
+msgid "[lo]"
+msgstr "[lo]"
+
+msgid "l"
+msgstr "l"
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr "sto effettuando il merge di %s e %s in %s\n"
+
+#, python-format
+msgid "merging %s\n"
+msgstr "sto effettuando il merge di %s\n"
+
+#, python-format
+msgid "my %s other %s ancestor %s\n"
+msgstr "mio %s altro %s antenato %s\n"
+
+msgid " premerge successful\n"
+msgstr " premerge eseguito con successo\n"
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+
+msgid "[yn]"
+msgstr "[yn]"
+
+msgid "n"
+msgstr "n"
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr "merge di %s fallito!\n"
+
+#, python-format
+msgid "Inconsistent state, %s:%s is good and bad"
+msgstr "Stato inconsistente, %s:%s è buona e cattiva"
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr ""
+
+msgid "Date Formats"
+msgstr "Formati della data"
+
+msgid ""
+"\n"
+" Some commands allow the user to specify a date, e.g.:\n"
+" * backout, commit, import, tag: Specify the commit date.\n"
+" * log, revert, update: Select revision(s) by date.\n"
+"\n"
+" Many date formats are valid. Here are some examples:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n"
+" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n"
+" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n"
+" \"Dec 6\" (midnight)\n"
+" \"13:18\" (today assumed)\n"
+" \"3:39\" (3:39AM assumed)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Lastly, there is Mercurial's internal format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" This is the internal representation format for dates. unixtime is\n"
+" the number of seconds since the epoch (1970-01-01 00:00 UTC). offset\n"
+" is the offset of the local timezone, in seconds west of UTC (negative\n"
+" if the timezone is east of UTC).\n"
+"\n"
+" The log command also accepts date ranges:\n"
+"\n"
+" \"<{datetime}\" - at or before a given date/time\n"
+" \">{datetime}\" - on or after a given date/time\n"
+" \"{datetime} to {datetime}\" - a date range, inclusive\n"
+" \"-{days}\" - within a given number of days of today\n"
+" "
+msgstr ""
+
+msgid "File Name Patterns"
+msgstr "Pattern dei Nomi dei File"
+
+msgid ""
+"\n"
+" Mercurial accepts several notations for identifying one or more\n"
+" files at a time.\n"
+"\n"
+" By default, Mercurial treats filenames as shell-style extended\n"
+" glob patterns.\n"
+"\n"
+" Alternate pattern notations must be specified explicitly.\n"
+"\n"
+" To use a plain path name without any pattern matching, start it\n"
+" with \"path:\". These path names must completely match starting at\n"
+" the current repository root.\n"
+"\n"
+" To use an extended glob, start a name with \"glob:\". Globs are\n"
+" rooted at the current directory; a glob such as \"*.c\" will only\n"
+" match files in the current directory ending with \".c\".\n"
+"\n"
+" The supported glob syntax extensions are \"**\" to match any string\n"
+" across path separators and \"{a,b}\" to mean \"a or b\".\n"
+"\n"
+" To use a Perl/Python regular expression, start a name with \"re:\".\n"
+" Regexp pattern matching is anchored at the root of the repository.\n"
+"\n"
+" Plain examples:\n"
+"\n"
+" path:foo/bar a name bar in a directory named foo in the root of\n"
+" the repository\n"
+" path:path:name a file or directory named \"path:name\"\n"
+"\n"
+" Glob examples:\n"
+"\n"
+" glob:*.c any name ending in \".c\" in the current directory\n"
+" *.c any name ending in \".c\" in the current directory\n"
+" **.c any name ending in \".c\" in any subdirectory of the\n"
+" current directory including itself.\n"
+" foo/*.c any name ending in \".c\" in the directory foo\n"
+" foo/**.c any name ending in \".c\" in any subdirectory of foo\n"
+" including itself.\n"
+"\n"
+" Regexp examples:\n"
+"\n"
+" re:.*\\.c$ any name ending in \".c\", anywhere in the repository\n"
+"\n"
+" "
+msgstr ""
+
+msgid "Environment Variables"
+msgstr "Variabili d'ambiente"
+
+msgid ""
+"\n"
+"HG::\n"
+" Path to the 'hg' executable, automatically passed when running hooks,\n"
+" extensions or external tools. If unset or empty, this is the hg\n"
+" executable's name if it's frozen, or an executable named 'hg'\n"
+" (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+" Windows) is searched.\n"
+"\n"
+"HGEDITOR::\n"
+" This is the name of the editor to run when committing. See EDITOR.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" This overrides the default locale setting detected by Mercurial.\n"
+" This setting is used to convert data including usernames,\n"
+" changeset descriptions, tag names, and branches. This setting can\n"
+" be overridden with the --encoding command-line option.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" This sets Mercurial's behavior for handling unknown characters\n"
+" while transcoding user input. The default is \"strict\", which\n"
+" causes Mercurial to abort if it can't map a character. Other\n"
+" settings include \"replace\", which replaces unknown characters, and\n"
+" \"ignore\", which drops them. This setting can be overridden with\n"
+" the --encodingmode command-line option.\n"
+"\n"
+"HGMERGE::\n"
+" An executable to use for resolving merge conflicts. The program\n"
+" will be executed with three arguments: local file, remote file,\n"
+" ancestor file.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" A list of files or directories to search for hgrc files. Item\n"
+" separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
+" platform default search path is used. If empty, only the .hg/hgrc\n"
+" from the current repository is read.\n"
+"\n"
+" For each element in HGRCPATH:\n"
+" * if it's a directory, all directories ending with .rc are added\n"
+" * otherwise, the directory itself will be added\n"
+"\n"
+"HGUSER::\n"
+" This is the string used as the author of a commit. If not set,\n"
+" available values will be considered in this order:\n"
+"\n"
+" * HGUSER (deprecated)\n"
+" * hgrc files from the HGRCPATH\n"
+" * EMAIL\n"
+" * interactive prompt\n"
+" * LOGNAME (with '@hostname' appended)\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"LOGNAME::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"VISUAL::\n"
+" This is the name of the editor to use when committing. See EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Sometimes Mercurial needs to open a text file in an editor\n"
+" for a user to modify, for example when writing commit messages.\n"
+" The editor it uses is determined by looking at the environment\n"
+" variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+" non-empty one is chosen. If all of them are empty, the editor\n"
+" defaults to 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" This is used by Python to find imported modules and may need to be set\n"
+" appropriately if this Mercurial is not installed system-wide.\n"
+" "
+msgstr ""
+
+msgid "Specifying Single Revisions"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial supports several ways to specify individual\n"
+" revisions.\n"
+"\n"
+" A plain integer is treated as a revision number. Negative\n"
+" integers are treated as topological offsets from the tip, with\n"
+" -1 denoting the tip. As such, negative numbers are only useful\n"
+" if you've memorized your local tree numbers and want to save\n"
+" typing a single digit. This editor suggests copy and paste.\n"
+"\n"
+" A 40-digit hexadecimal string is treated as a unique revision\n"
+" identifier.\n"
+"\n"
+" A hexadecimal string less than 40 characters long is treated as a\n"
+" unique revision identifier, and referred to as a short-form\n"
+" identifier. A short-form identifier is only valid if it is the\n"
+" prefix of exactly one full-length identifier.\n"
+"\n"
+" Any other string is treated as a tag name, which is a symbolic\n"
+" name associated with a revision identifier. Tag names may not\n"
+" contain the \":\" character.\n"
+"\n"
+" The reserved name \"tip\" is a special tag that always identifies\n"
+" the most recent revision.\n"
+"\n"
+" The reserved name \"null\" indicates the null revision. This is the\n"
+" revision of an empty repository, and the parent of revision 0.\n"
+"\n"
+" The reserved name \".\" indicates the working directory parent. If\n"
+" no working directory is checked out, it is equivalent to null.\n"
+" If an uncommitted merge is in progress, \".\" is the revision of\n"
+" the first parent.\n"
+" "
+msgstr ""
+
+msgid "Specifying Multiple Revisions"
+msgstr "Specificare Revisioni Multiple"
+
+msgid ""
+"\n"
+" When Mercurial accepts more than one revision, they may be\n"
+" specified individually, or provided as a topologically continuous\n"
+" range, separated by the \":\" character.\n"
+"\n"
+" The syntax of range notation is [BEGIN]:[END], where BEGIN and END\n"
+" are revision identifiers. Both BEGIN and END are optional. If\n"
+" BEGIN is not specified, it defaults to revision number 0. If END\n"
+" is not specified, it defaults to the tip. The range \":\" thus\n"
+" means \"all revisions\".\n"
+"\n"
+" If BEGIN is greater than END, revisions are treated in reverse\n"
+" order.\n"
+"\n"
+" A range acts as a closed interval. This means that a range of 3:5\n"
+" gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+" "
+msgstr ""
+
+msgid "Diff Formats"
+msgstr "Formati di diff"
+
+msgid ""
+"\n"
+" Mercurial's default format for showing changes between two versions\n"
+" of a file is compatible with the unified format of GNU diff, which\n"
+" can be used by GNU patch and many other standard tools.\n"
+"\n"
+" While this standard format is often enough, it does not encode the\n"
+" following information:\n"
+"\n"
+" - executable status and other permission bits\n"
+" - copy or rename information\n"
+" - changes in binary files\n"
+" - creation or deletion of empty files\n"
+"\n"
+" Mercurial also supports the extended diff format from the git VCS\n"
+" which addresses these limitations. The git diff format is not\n"
+" produced by default because a few widespread tools still do not\n"
+" understand this format.\n"
+"\n"
+" This means that when generating diffs from a Mercurial repository\n"
+" (e.g. with \"hg export\"), you should be careful about things like\n"
+" file copies and renames or other things mentioned above, because\n"
+" when applying a standard diff to a different repository, this extra\n"
+" information is lost. Mercurial's internal operations (like push and\n"
+" pull) are not affected by this, because they use an internal binary\n"
+" format for communicating changes.\n"
+"\n"
+" To make Mercurial produce the git extended diff format, use the\n"
+" --git option available for many commands, or set 'git = True' in the\n"
+" [diff] section of your hgrc. You do not need to set this option when\n"
+" importing diffs in this format or using them in the mq extension.\n"
+" "
+msgstr ""
+
+msgid "Template Usage"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial allows you to customize output of commands through\n"
+" templates. You can either pass in a template from the command line,\n"
+" via the --template option, or select an existing template-style (--"
+"style).\n"
+"\n"
+" You can customize output for any \"log-like\" command: log, outgoing,\n"
+" incoming, tip, parents, heads and glog.\n"
+"\n"
+" Three styles are packaged with Mercurial: default (the style used\n"
+" when no explicit preference is passed), compact and changelog. Usage:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" A template is a piece of text, with markup to invoke variable "
+"expansion:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings in curly braces are called keywords. The availability of\n"
+" keywords depends on the exact context of the templater. These keywords\n"
+" are usually available for templating a log-like command:\n"
+"\n"
+" - author: String. The unmodified author of the changeset.\n"
+" - branches: String. The name of the branch on which the changeset\n"
+" was committed. Will be empty if the branch name was default.\n"
+" - date: Date information. The date when the changeset was committed.\n"
+" - desc: String. The text of the changeset description.\n"
+" - diffstat: String. Statistics of changes with the following format:\n"
+" \"modified files: +added/-removed lines\"\n"
+" - files: List of strings. All files modified, added, or removed by\n"
+" this changeset.\n"
+" - file_adds: List of strings. Files added by this changeset.\n"
+" - file_mods: List of strings. Files modified by this changeset.\n"
+" - file_dels: List of strings. Files removed by this changeset.\n"
+" - node: String. The changeset identification hash, as a 40-character\n"
+" hexadecimal string.\n"
+" - parents: List of strings. The parents of the changeset.\n"
+" - rev: Integer. The repository-local changeset revision number.\n"
+" - tags: List of strings. Any tags associated with the changeset.\n"
+"\n"
+" The \"date\" keyword does not produce human-readable output. If you\n"
+" want to use a date in your output, you can use a filter to process it.\n"
+" Filters are functions which return a string based on the input "
+"variable.\n"
+" You can also use a chain of filters to get the desired output:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" List of filters:\n"
+"\n"
+" - addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
+" every line except the last.\n"
+" - age: Date. Returns a human-readable date/time difference between\n"
+" the given date/time and the current date/time.\n"
+" - basename: Any text. Treats the text as a path, and returns the\n"
+" last component of the path after splitting by the path\n"
+" separator (ignoring trailing seprators). For example,\n"
+" \"foo/bar/baz\" becomes \"baz\" and \"foo/bar//\" becomes \"bar"
+"\".\n"
+" - date: Date. Returns a date in a Unix date format, including\n"
+" the timezone: \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - domain: Any text. Finds the first string that looks like an email\n"
+" address, and extracts just the domain component.\n"
+" Example: 'User <user@example.com>' becomes 'example.com'.\n"
+" - email: Any text. Extracts the first string that looks like an email\n"
+" address. Example: 'User <user@example.com>' becomes\n"
+" 'user@example.com'.\n"
+" - escape: Any text. Replaces the special XML/XHTML characters \"&\",\n"
+" \"<\" and \">\" with XML entities.\n"
+" - fill68: Any text. Wraps the text to fit in 68 columns.\n"
+" - fill76: Any text. Wraps the text to fit in 76 columns.\n"
+" - firstline: Any text. Returns the first line of text.\n"
+" - hgdate: Date. Returns the date as a pair of numbers:\n"
+" \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
+" - isodate: Date. Returns the date in ISO 8601 format.\n"
+" - obfuscate: Any text. Returns the input text rendered as a sequence\n"
+" of XML entities.\n"
+" - person: Any text. Returns the text before an email address.\n"
+" - rfc822date: Date. Returns a date using the same format used\n"
+" in email headers.\n"
+" - short: Changeset hash. Returns the short form of a changeset hash,\n"
+" i.e. a 12-byte hexadecimal string.\n"
+" - shortdate: Date. Returns a date like \"2006-09-18\".\n"
+" - strip: Any text. Strips all leading and trailing whitespace.\n"
+" - tabindent: Any text. Returns the text, with every line except the\n"
+" first starting with a tab character.\n"
+" - urlescape: Any text. Escapes all \"special\" characters. For example,\n"
+" \"foo bar\" becomes \"foo%20bar\".\n"
+" - user: Any text. Returns the user portion of an email address.\n"
+" "
+msgstr ""
+
+msgid "Url Paths"
+msgstr "Percorsi url"
+
+msgid ""
+"\n"
+" Valid URLs are of the form:\n"
+"\n"
+" local/filesystem/path (or file://local/filesystem/path)\n"
+" http://[user[:pass]@]host[:port]/[path]\n"
+" https://[user[:pass]@]host[:port]/[path]\n"
+" ssh://[user[:pass]@]host[:port]/[path]\n"
+"\n"
+" Paths in the local filesystem can either point to Mercurial\n"
+" repositories or to bundle files (as created by 'hg bundle' or\n"
+" 'hg incoming --bundle').\n"
+"\n"
+" An optional identifier after # indicates a particular branch, tag,\n"
+" or changeset to use from the remote repository.\n"
+"\n"
+" Some features, such as pushing to http:// and https:// URLs are\n"
+" only possible if the feature is explicitly enabled on the\n"
+" remote Mercurial server.\n"
+"\n"
+" Some notes about using SSH with Mercurial:\n"
+" - SSH requires an accessible shell account on the destination machine\n"
+" and a copy of hg in the remote path or specified with as remotecmd.\n"
+" - path is relative to the remote user's home directory by default.\n"
+" Use an extra slash at the start of a path to specify an absolute "
+"path:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial doesn't use its own compression via SSH; the right thing\n"
+" to do is to configure it in your ~/.ssh/config, e.g.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternatively specify \"ssh -C\" as your ssh command in your hgrc or\n"
+" with the --ssh command line option.\n"
+"\n"
+" These urls can all be stored in your hgrc with path aliases under the\n"
+" [paths] section like so:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" You can then use the alias for any command that uses a url (for example\n"
+" 'hg pull alias1' would pull from the 'alias1' path).\n"
+"\n"
+" Two path aliases are special because they are used as defaults\n"
+" when you do not provide the url to a command:\n"
+"\n"
+" default:\n"
+" When you create a repository with hg clone, the clone command saves\n"
+" the location of the source repository as the new repository's\n"
+" 'default' path. This is then used when you omit path from push-\n"
+" and pull-like commands (including in and out).\n"
+"\n"
+" default-push:\n"
+" The push command will look for a path named 'default-push', and\n"
+" prefer it over 'default' if both are defined.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr "directory di destinazione: %s\n"
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr "la destinazione '%s' esiste già"
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr ""
+
+msgid "clone from remote to remote not supported"
+msgstr "clone da remoto a remoto non supportato"
+
+msgid "updating working directory\n"
+msgstr "sto aggiornando la directory di lavoro\n"
+
+msgid "updated"
+msgstr "aggiornati"
+
+msgid "merged"
+msgstr "merge"
+
+msgid "removed"
+msgstr "rimossi"
+
+msgid "unresolved"
+msgstr "non risolti"
+
+#, python-format
+msgid "%d files %s"
+msgstr "%d file %s"
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr "usa 'hg resolve' per riprovare i merge sui file non risolti\n"
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to "
+"abandon\n"
+msgstr ""
+"usa 'hg resolve' per riprovare i merge sui file non risolti o\n"
+"'hg up --clean' per abbandonare\n"
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr "(merge su branch, non dimenticare di effettuare il commit)\n"
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr "errore di lettura di %s/.hg/hgrc: %s\n"
+
+msgid "SSL support is unavailable"
+msgstr "Supporto SSL non disponibile"
+
+msgid "IPv6 not available on this system"
+msgstr "IPv6 non disponibile su questo sistema"
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr "impossibile avviare il server a '%s:%d': %s"
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr "sto invocando l'hook %s: %s\n"
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr "l'hook %s non è valido (\"%s\" non in un modulo)"
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook failed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr ""
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook %s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr ""
+
+msgid "connection ended unexpectedly"
+msgstr "connessione terminata inaspettatamente"
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr "componente URL non supportato: \"%s\""
+
+#, python-format
+msgid "using %s\n"
+msgstr "sto usando %s\n"
+
+#, python-format
+msgid "capabilities: %s\n"
+msgstr "funzionalità: %s\n"
+
+msgid "operation not supported over http"
+msgstr "operazione non supportata su http"
+
+#, python-format
+msgid "sending %s command\n"
+msgstr "sto inviando il comando %s\n"
+
+#, python-format
+msgid "sending %s bytes\n"
+msgstr "sto inviando %s byte\n"
+
+msgid "authorization failed"
+msgstr "autorizzazione fallita"
+
+#, python-format
+msgid "http error while sending %s command\n"
+msgstr "errore http durante l'invio del comando %s\n"
+
+msgid "http error, possibly caused by proxy setting"
+msgstr "errore http, probabilmente causato dalle impostazioni del proxy"
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr "il vero URL è %s\n"
+
+#, python-format
+msgid "Requested URL: '%s'\n"
+msgstr "URL richiesto: '%s'\n"
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr "'%s' non sembra essere un repository hg"
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr "'%s' ha inviato un header Content-Type rotto (%s)"
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr ""
+
+msgid "look up remote revision"
+msgstr ""
+
+msgid "unexpected response:"
+msgstr "risposta inattesa: "
+
+msgid "look up remote changes"
+msgstr ""
+
+msgid "push failed (unexpected response):"
+msgstr "push fallito (risposta inattesa):"
+
+#, python-format
+msgid "push failed: %s"
+msgstr "push fallito: %s"
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr "Supporto per Python per SSL e HTTPS non installato"
+
+msgid "cannot create new http repository"
+msgstr "impossibile creare un nuovo repository http"
+
+#, python-format
+msgid "%s: ignoring invalid syntax '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr "sto saltando file ignore non leggibile '%s': %s\n"
+
+#, python-format
+msgid "repository %s not found"
+msgstr "repository %s non trovato"
+
+#, python-format
+msgid "repository %s already exists"
+msgstr ""
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr "requisito '%s' non supportato"
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr ""
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr ""
+"la copia di lavoro di .hgtags è cambiata (si prega di effettuare il commit "
+"manuale di .hgtags)"
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr "%s, linea %s: %s\n"
+
+msgid "cannot parse entry"
+msgstr "impossibile parsificare la entry"
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr "il nodo '%s' non è ben formato"
+
+#, python-format
+msgid "tag '%s' refers to unknown node"
+msgstr "la tag '%s' si riferisce ad un nodo sconosciuto"
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr "revisione sconosciuta '%s'"
+
+#, python-format
+msgid "filtering %s through %s\n"
+msgstr "sto filtrando %s attraverso %s\n"
+
+msgid "journal already exists - run hg recover"
+msgstr "il journal esiste già - eseguire hg recover"
+
+msgid "rolling back interrupted transaction\n"
+msgstr "sto effettuando il rollback della transazione interrotta\n"
+
+msgid "no interrupted transaction available\n"
+msgstr "nessuna transazione interrotta disponibile\n"
+
+msgid "rolling back last transaction\n"
+msgstr "sto effettuando il rollback dell'ultima transazione\n"
+
+#, python-format
+msgid "Named branch could not be reset, current branch still is: %s\n"
+msgstr ""
+
+msgid "no rollback information available\n"
+msgstr "nessuna informazione disponibile per il rollback\n"
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr "sto aspettando il lock su %s mantenuto da %r\n"
+
+#, python-format
+msgid "repository %s"
+msgstr "repository·%s"
+
+#, python-format
+msgid "working directory of %s"
+msgstr "directory di lavoro di %s"
+
+#, python-format
+msgid " %s: searching for copy revision for %s\n"
+msgstr ""
+
+#, python-format
+msgid " %s: copy %s:%s\n"
+msgstr ""
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr ""
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr "%s non è tracciato!\n"
+
+msgid "unresolved merge conflicts (see hg resolve)"
+msgstr ""
+
+msgid "nothing changed\n"
+msgstr "nulla è cambiato\n"
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr ""
+
+msgid "HG: Enter commit message. Lines beginning with 'HG:' are removed."
+msgstr ""
+
+msgid "empty commit message"
+msgstr "messaggio di commit vuoto"
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr "%s non esiste!\n"
+
+#, python-format
+msgid ""
+"%s: files over 10MB may cause memory and performance problems\n"
+"(use 'hg revert %s' to unadd the file)\n"
+msgstr ""
+"%s: file oltre i 10MB potrebbero causare problemi di memoria\n"
+"e performance (usare 'hg revert %s' per annullare l'aggiunta\n"
+"del file)\n"
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr ""
+"%s non aggiunto: attualmente solo file e link simbolici sono supportati\n"
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr "%s è già tracciato!\n"
+
+#, python-format
+msgid "%s not added!\n"
+msgstr "%s non aggiunto!\n"
+
+#, python-format
+msgid "%s still exists!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr ""
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr ""
+
+msgid "searching for changes\n"
+msgstr "sto cercando modifiche\n"
+
+#, python-format
+msgid "examining %s:%s\n"
+msgstr ""
+
+msgid "branch already found\n"
+msgstr "branch già trovata\n"
+
+#, python-format
+msgid "found incomplete branch %s:%s\n"
+msgstr "trovata branch incompleta %s:%s\n"
+
+#, python-format
+msgid "found new changeset %s\n"
+msgstr "trovato nuovo changeset %s\n"
+
+#, python-format
+msgid "request %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "received %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowing %d:%d %s\n"
+msgstr ""
+
+#, python-format
+msgid "found new branch changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowed branch search to %s:%s\n"
+msgstr ""
+
+msgid "already have changeset "
+msgstr ""
+
+msgid "warning: repository is unrelated\n"
+msgstr ""
+
+msgid "repository is unrelated"
+msgstr "il repository non è imparentato"
+
+msgid "found new changesets starting at "
+msgstr "trovati nuovi changeset a partire da "
+
+#, python-format
+msgid "%d total queries\n"
+msgstr "%d query totali\n"
+
+msgid "common changesets up to "
+msgstr "changeset comuni fino a "
+
+msgid "requesting all changes\n"
+msgstr "sto richiedendo tutte le modifiche\n"
+
+msgid ""
+"Partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr ""
+
+msgid "abort: push creates new remote heads!\n"
+msgstr "abortito: push crea nuove head remote!\n"
+
+msgid "(did you forget to merge? use push -f to force)\n"
+msgstr ""
+"(ti sei dimenticato di effettuare il merge? usare push -f per forzare)\n"
+
+msgid "note: unsynced remote changes!\n"
+msgstr "nota: modifiche remote non sincronizzate!\n"
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr "%d changeset trovati\n"
+
+msgid "list of changesets:\n"
+msgstr "elenco dei changeset:\n"
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr "revlog vuoto o mancante per %s"
+
+#, python-format
+msgid "add changeset %s\n"
+msgstr "aggiungo changeset %s\n"
+
+msgid "adding changesets\n"
+msgstr "sto aggiungendo i changeset\n"
+
+msgid "received changelog group is empty"
+msgstr "il gruppo di changelog ricevuto è vuoto"
+
+msgid "adding manifests\n"
+msgstr "sto aggiungendo i manifesti\n"
+
+msgid "adding file changes\n"
+msgstr "sto aggiungendo le modifiche ai file\n"
+
+#, python-format
+msgid "adding %s revisions\n"
+msgstr "sto aggiungendo %s revisioni\n"
+
+msgid "received file revlog group is empty"
+msgstr "il gruppo di file revlog ricevuto è vuoto"
+
+#, python-format
+msgid " (%+d heads)"
+msgstr " (%+d head)"
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr "aggiunti %d changeset con %d modifiche a %d file%s\n"
+
+msgid "updating the branch cache\n"
+msgstr "sto aggiornando la cache delle branch\n"
+
+msgid "Unexpected response from remote server:"
+msgstr "Risposta inaspettata dal server remoto:"
+
+msgid "operation forbidden by server"
+msgstr "operazione vietata dal server"
+
+msgid "locking the remote repository failed"
+msgstr "lock del repository remoto fallito"
+
+msgid "the server sent an unknown error code"
+msgstr "il server ha inviato un codice d'errore sconosciuto"
+
+msgid "streaming all changes\n"
+msgstr "sto effettuando lo streaming di tutte le modifiche\n"
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr "%d file da trasferire, %s di dati\n"
+
+#, python-format
+msgid "adding %s (%s)\n"
+msgstr "sto aggiungendo %s (%s)\n"
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr "trasferiti %s in %.1f secondi (%s/sec)\n"
+
+msgid "no [smtp]host in hgrc - cannot send mail"
+msgstr ""
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr ""
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr ""
+
+msgid "(using tls)\n"
+msgstr "(sto usando tls)\n"
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr ""
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr "sto inviando la mail: %s\n"
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr ""
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr ""
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr ""
+
+msgid "'\\n' and '\\r' disallowed in filenames"
+msgstr ""
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr ""
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr ""
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr ""
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr ""
+
+msgid "resolving manifests\n"
+msgstr "sto risolvendo i manifesti\n"
+
+#, python-format
+msgid " overwrite %s partial %s\n"
+msgstr "sovrascrivi %s parziale %s\n"
+
+#, python-format
+msgid " ancestor %s local %s remote %s\n"
+msgstr "antenato %s locale %s remoto %s\n"
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+msgid "[cd]"
+msgstr ""
+
+msgid "c"
+msgstr ""
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+
+#, python-format
+msgid "preserving %s for resolve of %s\n"
+msgstr ""
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s\n"
+msgstr "sto ottenendo %s\n"
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr "sto ottenendo %s in %s\n"
+
+#, python-format
+msgid "warning: detected divergent renames of %s to:\n"
+msgstr ""
+
+#, python-format
+msgid "branch %s not found"
+msgstr "branch %s non trovata"
+
+msgid "can't merge with ancestor"
+msgstr "impossibile fare merge con un antenato"
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr ""
+"niente di cui effettuare il merge (usare 'hg update' ocontrollare 'hg heads')"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C' to discard changes)"
+msgstr ""
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C')"
+msgstr ""
+
+msgid "crosses named branches (use 'hg update -C' to discard changes)"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr "impossibile creare %s: la destinazione esiste già"
+
+#, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr "impossibile creare %s: impossibile creare la directory di destinazione"
+
+#, python-format
+msgid "found patch at byte %d\n"
+msgstr ""
+
+msgid "patch generated by hg export\n"
+msgstr "patch generata da hg export\n"
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr ""
+
+#, python-format
+msgid "patching file %s\n"
+msgstr "sto applicando una patch al file %s\n"
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr ""
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d %s).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr ""
+
+msgid "could not extract binary patch"
+msgstr ""
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr ""
+
+#, python-format
+msgid "unable to strip away %d dirs from %s"
+msgstr ""
+
+msgid "undefined source and destination files"
+msgstr ""
+
+#, python-format
+msgid "malformed patch %s %s"
+msgstr ""
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr ""
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr "comando patch fallito: %s"
+
+#, python-format
+msgid "no valid hunks found; trying with %r instead\n"
+msgstr ""
+
+#, python-format
+msgid "exited with status %d"
+msgstr "uscito con status %d"
+
+#, python-format
+msgid "killed by signal %d"
+msgstr "ucciso dal segnale %d"
+
+#, python-format
+msgid "stopped by signal %d"
+msgstr "terminato dal segnale %d"
+
+msgid "invalid exit code"
+msgstr "codice d'uscita non valido"
+
+#, python-format
+msgid "saving bundle to %s\n"
+msgstr "sto salvando il bundle in %s\n"
+
+msgid "adding branch\n"
+msgstr ""
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr "%s impossibile; il repository remoto non supporta la funzionalità %r"
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr ""
+
+msgid "no node"
+msgstr "nessun nodo"
+
+msgid "ambiguous identifier"
+msgstr "identificatore ambiguo"
+
+msgid "no match found"
+msgstr ""
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr ""
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr ""
+
+msgid "unknown base"
+msgstr "base sconosciuta"
+
+msgid "consistency error adding group"
+msgstr ""
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr ""
+
+msgid "can only specify two labels."
+msgstr "possibile specificare solo due etichette."
+
+msgid "warning: conflicts during merge.\n"
+msgstr "attenzione: conflitti durante il merge.\n"
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr "non è stato possibile parsificare la posizione %s"
+
+msgid "could not create remote repo"
+msgstr "non è stato possibile creare il repository remoto"
+
+msgid "remote: "
+msgstr "remoto: "
+
+msgid "no suitable response from remote hg"
+msgstr "nessuna risposta accettabile dall'hg remoto"
+
+#, python-format
+msgid "push refused: %s"
+msgstr "push rifiutato: %s"
+
+msgid "unsynced changes"
+msgstr "modifiche non sincronizzate"
+
+msgid "cannot lock static-http repository"
+msgstr "impossibile bloccare il repository http statico"
+
+msgid "cannot create new static-http repository"
+msgstr "impossibile creare un nuovo repository http statico"
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr "voce non valida in fncache, linea %s"
+
+msgid "scanning\n"
+msgstr "sto effettuando la scansione\n"
+
+#, python-format
+msgid "%d files, %d bytes to transfer\n"
+msgstr ""
+
+#, python-format
+msgid "sending %s (%d bytes)\n"
+msgstr "sto inviando %s (%d byte)\n"
+
+msgid "unmatched quotes"
+msgstr ""
+
+#, python-format
+msgid "style not found: %s"
+msgstr "stile non trovato: %s"
+
+#, python-format
+msgid "%s:%s: parse error"
+msgstr ""
+
+#, python-format
+msgid "template file %s: %s"
+msgstr ""
+
+#, python-format
+msgid "Error expanding '%s%%%s'"
+msgstr ""
+
+msgid "transaction abort!\n"
+msgstr "transazione abortita!\n"
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr ""
+
+msgid "rollback completed\n"
+msgstr "rollback completato\n"
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"Failed to parse %s\n"
+"%s"
+msgstr ""
+"Fallita la parsificazione di %s\n"
+"%s"
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr "Ignorato: %s\n"
+
+#, python-format
+msgid "unable to open %s: %s"
+msgstr "impossibile aprire %s: %s"
+
+#, python-format
+msgid ""
+"failed to parse %s\n"
+"%s"
+msgstr ""
+"fallita la parsificazione di %s\n"
+"%s"
+
+#, python-format
+msgid ""
+"Error in configuration section [%s] parameter '%s':\n"
+"%s"
+msgstr ""
+"Errore nella sezione di configurazione [%s] parametro '%s':\n"
+"%s"
+
+#, python-format
+msgid "Ignoring untrusted configuration option %s.%s = %s\n"
+msgstr "Ignoro l'opzione di configurazione non affidabile %s.%s = %s\n"
+
+#, python-format
+msgid ""
+"Error in configuration section [%s]:\n"
+"%s"
+msgstr ""
+"Errore nella sezione di configurazione [%s]:\n"
+"%s"
+
+msgid "enter a commit username:"
+msgstr "inserire uno username per il commit:"
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr "Nessuno username trovato, uso '%s' invece\n"
+
+msgid "Please specify a username."
+msgstr "Si prega di specificare uno username."
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr "lo username %s contiene un carattere di fine riga\n"
+
+msgid "unrecognized response\n"
+msgstr "risposta non riconosciuta\n"
+
+msgid "response expected"
+msgstr "risposta attesa"
+
+msgid "password: "
+msgstr "password: "
+
+msgid "edit failed"
+msgstr "modifica fallita"
+
+msgid "http authorization required"
+msgstr "autorizzazione http richiesta"
+
+msgid "http authorization required\n"
+msgstr "autorizzazione http richiesta\n"
+
+#, python-format
+msgid "realm: %s\n"
+msgstr "reame: %s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "utente: %s\n"
+
+msgid "user:"
+msgstr "utente:"
+
+#, python-format
+msgid "proxying through http://%s:%s\n"
+msgstr "usando proxy attraverso http://%s:%s\n"
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr "autenticazione http: utente %s, password %s\n"
+
+#, python-format
+msgid "%s, please check your locale settings"
+msgstr "%s, si prega di controllare le impostazioni di localizzazione"
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr "comando '%s' fallito: %s"
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr "il percorso contiene un componente non consentito: %s"
+
+#, python-format
+msgid "path %r is inside repo %r"
+msgstr "il percorso %r all'interno del repository %r"
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr "il percorso %r attraversa il link simbolico %r"
+
+msgid "Hardlinks not supported"
+msgstr "Hardlink non supportati"
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr "impossibile creare un link simbolico a %r: %s"
+
+#, python-format
+msgid "invalid date: %r "
+msgstr "data non valida: %r "
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr "la data supera i 32 bit: %d"
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr "fuso orario impossibile: %d"
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr ""
+
+#, python-format
+msgid "%.0f GB"
+msgstr "%.0f GB"
+
+#, python-format
+msgid "%.1f GB"
+msgstr "%.1f GB"
+
+#, python-format
+msgid "%.2f GB"
+msgstr "%.2f GB"
+
+#, python-format
+msgid "%.0f MB"
+msgstr "%.0f MB"
+
+#, python-format
+msgid "%.1f MB"
+msgstr "%.1f MB"
+
+#, python-format
+msgid "%.2f MB"
+msgstr "%.2f MB"
+
+#, python-format
+msgid "%.0f KB"
+msgstr "%.0f KB"
+
+#, python-format
+msgid "%.1f KB"
+msgstr "%.1f KB"
+
+#, python-format
+msgid "%.2f KB"
+msgstr "%.2f KB"
+
+#, python-format
+msgid "%.0f bytes"
+msgstr "%.0f byte"
+
+msgid "cannot verify bundle or remote repos"
+msgstr "impossibile verificare bundle o repository remoti"
+
+msgid "interrupted"
+msgstr "interrotto"
+
+#, python-format
+msgid "empty or missing %s"
+msgstr "%s vuoto o mancante"
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr ""
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr "l'indice contiene %d extra byte"
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr "attenzione: `%s' usa il formato di revlog 1"
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr "attenzione: `%s' usa il formato di revlog 0"
+
+#, python-format
+msgid "rev %d point to %s changeset %d"
+msgstr "rev %d punta a %s changeset %d"
+
+#, python-format
+msgid " (expected %s)"
+msgstr "(atteso %s)"
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr "genitore 1 %s di %s sconosciuto"
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr "genitore 2 %s di %s sconosciuto"
+
+#, python-format
+msgid "checking parents of %s"
+msgstr "sto controllando i genitori di %s"
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr "revisione duplicata %d (%d)"
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr "il repository usa il formato di revlog %d\n"
+
+msgid "checking changesets\n"
+msgstr "sto controllando i changeset\n"
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr "sto spacchettando il changeset %s"
+
+msgid "checking manifests\n"
+msgstr "sto controllando i manifesti\n"
+
+msgid "file without name in manifest"
+msgstr "file senza nome nel manifesto"
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr "sto leggendo il delta del manifesto %s"
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr ""
+"sto facendo un controllo incrociato sui file nei changeset e nei manifesti\n"
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr "il changeset si riferisce ad un manifesto sconosciuto %s"
+
+msgid "in changeset but not in manifest"
+msgstr "nel changeset ma non nel manifesto"
+
+msgid "in manifest but not in changeset"
+msgstr "nel manifesto ma non nel changeset"
+
+msgid "checking files\n"
+msgstr "sto controllando i file\n"
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr "impossibile decodificare il nome del file '%s'"
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr "revlog danneggiato! (%s)"
+
+msgid "missing revlog!"
+msgstr "revlog mancante!"
+
+#, python-format
+msgid "%s not in manifests"
+msgstr "%s non è nei manifesti"
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr "la dimensione spacchettata è %s, attesa %s"
+
+#, python-format
+msgid "unpacking %s"
+msgstr "sto spacchettando %s"
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s"
+msgstr ""
+
+#, python-format
+msgid "checking rename of %s"
+msgstr "sto controllando la rinomina di %s"
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr "%s non trovato nei manifesti"
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr "attenzione: revlog '%s' orfano"
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr "%d file, %d changeset, %d revisioni totali\n"
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr "%d warning incontrati!\n"
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr "%d errori di integrit incontrati!\n"
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr "(il primo changeset danneggiato sembra essere %d)\n"
+
+msgid "user name not available - set USERNAME environment variable"
+msgstr ""
+"nome utente non disponibile - impostare la variabile d'ambiente USERNAME"
+
+#~ msgid "%s %s to %s\n"
+#~ msgstr "%s %s in %s\n"
diff --git a/sys/src/cmd/hg/i18n/ja.po b/sys/src/cmd/hg/i18n/ja.po
new file mode 100644
index 000000000..a0928774b
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/ja.po
@@ -0,0 +1,10605 @@
+# Japanese translation for Mercurial
+# Mercurial 日本語翻訳
+#
+# Copyright (C) 2009 the Mercurial team
+#
+# ========================================
+# ã€ç¿»è¨³ç”¨èªžé›†ã€‘
+#
+# 言ã„回ã—:
+#
+# no XXXX avairable XXXX ãŒã‚りã¾ã›ã‚“
+# XXXX found XXXX ãŒå­˜åœ¨ã—ã¾ã™
+# XXXX exists XXXX ãŒå­˜åœ¨ã—ã¾ã™
+# do not XXXX XXXX ã§ãã¾ã›ã‚“ ※ 「XXXX ã—ã¦ã¯ã„ã‘ãªã„ã€ã®æ„
+# XXXX failed XXXX ãŒ(or ã«)失敗
+# error XXXX-ing XXXX ãŒ(or ã«)失敗
+# error while XXXX XXXX ãŒ(or ã«)失敗
+# XXXX-ing YYYY YYYY ã‚’ XXXX 中 ※ メッセージ冒頭ã‹ã‚‰å§‹ã¾ã‚‹å ´åˆ
+# YYYY ã‚’ XXXX ※ 「以後ã®å‡¦ç†ã¯ YYYY ã‚’ XXXX ã¨ã™ã‚‹ã€
+# ã¨ã„ã†ãƒ‹ãƒ¥ã‚¢ãƒ³ã‚¹ï¾å ´åˆ
+# --XXXX option --XXXX ※ 「オプションã€ã§ã‚ã‚‹ã“ã¨ãŒè‡ªæ˜Žãªã®ã§
+# option --XXXX --XXXX ※ 「オプションã€ã§ã‚ã‚‹ã“ã¨ãŒè‡ªæ˜Žãªã®ã§
+# invalid XXXX XXXX ãŒä¸æ­£ã§ã™ or 䏿­£ãª XXXX
+# malformed XXXX XXXX ãŒä¸æ­£ã§ã™ or 䏿­£ãª XXXX
+#
+# å˜èªž:
+#
+# Distributed SCM 分散構æˆç®¡ç†ãƒ„ール
+#
+# abort 中断
+# add (æ§‹æˆç®¡ç†ã¸ã®)追加登録
+# apply é©ç”¨
+# archive アーカイブ
+# argument(, with no) 引数(指定ãŒç„¡ã„å ´åˆ)
+# author 作æˆè€…
+# backout æ‰“ã¡æ¶ˆã—
+# basename ベースå
+# binary ãƒã‚¤ãƒŠãƒª
+# branch ブランãƒ
+# bundle( file) ãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイル
+# change ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ/差分
+# changegroup( file) ãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイル
+# changeset ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ
+# changeset hash ãƒãƒƒã‚·ãƒ¥å€¤
+# changeset header ヘッダ情報
+# checkout/update (作業領域ã®)æ›´æ–°
+# command(, this) (本)コマンド
+# commit コミット
+# commit comment コミットログ
+# default(, by) 指定ãŒç„¡ã„å ´åˆ/通常ã¯
+# delete/remove (æ§‹æˆç®¡ç†ã‹ã‚‰ã®)登録除外
+# diff 差分
+# directory ディレクトリ
+# dirstate dirstate
+# entry エントリ
+# extend(ed) æ‹¡å¼µ
+# extension (Mercurialã®)エクステンション
+# hash identifier(s) ãƒãƒƒã‚·ãƒ¥å€¤
+# head ヘッド
+# head changeset(s) ヘッド
+# header ヘッダ
+# history(, revision) 変更履歴
+# import å–り込ã¿(patch ç³»)/読ã¿è¾¼ã¿(module/extension)
+# interrupt 中断
+# list of .... 列挙ã•れãŸ..../.... ã®ä¸€è¦§
+# local (repo) 手元(ã®ãƒªãƒã‚¸ãƒˆãƒª)
+# manifest マニフェスト or 管ç†å¯¾è±¡(一覧)
+# merge マージ
+# node リビジョン
+# note 備考
+# patch パッãƒ
+# platform 稼åƒç’°å¢ƒ
+# pop(patch) (パッãƒã®)é©ç”¨è§£é™¤
+# pull (追加リビジョンã®)å–り込ã¿
+# push (追加リビジョンã®)åæ˜ 
+# push(patch) (パッãƒã®)é©ç”¨
+# remote(repo) 連æºå…ˆ(リãƒã‚¸ãƒˆãƒª)
+# rename 改å
+# repo(sitory) リãƒã‚¸ãƒˆãƒª/(.hg を指ã™å ´åˆã¯)管ç†é ˜åŸŸ
+# resolve/unresolve (è¡çª)解消/(è¡çª)未解消
+# revert/undo å–り消ã—
+# revision リビジョン
+# schedule (add/remove ã®)予約
+# search 探索
+# server サーãƒ
+# summary è¦ç´„(情報)
+# tag ã‚¿ã‚°
+# tracked xxxx æ§‹æˆç®¡ç†å¯¾è±¡ã® xxxx
+# xxxxx type xxxx 種別
+# user ユーザ
+# unknown xxxx 未知㮠xxxx
+# working copy(of xxx) 作業領域(中㮠xxx)
+# working directory 作業領域
+# ========================================
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial\n"
+"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
+"POT-Creation-Date: 2009-07-01 11:25+0900\n"
+"PO-Revision-Date: 2009-07-01 18:00+0900\n"
+"Last-Translator: Japanese translation team <mercurial-ja@googlegroups.com>\n"
+"Language-Team: Japanese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (既定値: %s)"
+
+msgid "OPTIONS"
+msgstr ""
+
+msgid "COMMANDS"
+msgstr ""
+
+msgid " options:\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" aliases: %s\n"
+"\n"
+msgstr ""
+" 別å: %s\n"
+"\n"
+
+msgid ""
+"hooks for controlling repository access\n"
+"\n"
+"This hook makes it possible to allow or deny write access to portions\n"
+"of a repository when receiving incoming changesets.\n"
+"\n"
+"The authorization is matched based on the local user name on the\n"
+"system where the hook runs, and not the committer of the original\n"
+"changeset (since the latter is merely informative).\n"
+"\n"
+"The acl hook is best used along with a restricted shell like hgsh,\n"
+"preventing authenticating users from doing anything other than\n"
+"pushing or pulling. The hook is not safe to use if users have\n"
+"interactive shell access, as they can then disable the hook.\n"
+"Nor is it safe if remote users share an account, because then there\n"
+"is no way to distinguish them.\n"
+"\n"
+"To use this hook, configure the acl extension in your hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.acl =\n"
+"\n"
+" [hooks]\n"
+" pretxnchangegroup.acl = python:hgext.acl.hook\n"
+"\n"
+" [acl]\n"
+" # Check whether the source of incoming changes is in this list\n"
+" # (\"serve\" == ssh or http, \"push\", \"pull\", \"bundle\")\n"
+" sources = serve\n"
+"\n"
+"The allow and deny sections take a subtree pattern as key (with a\n"
+"glob syntax by default), and a comma separated list of users as\n"
+"the corresponding value. The deny list is checked before the allow\n"
+"list is.\n"
+"\n"
+" [acl.allow]\n"
+" # If acl.allow is not present, all users are allowed by default.\n"
+" # An empty acl.allow section means no users allowed.\n"
+" docs/** = doc_writer\n"
+" .hgtags = release_engineer\n"
+"\n"
+" [acl.deny]\n"
+" # If acl.deny is not present, no users are refused by default.\n"
+" # An empty acl.deny section means all users allowed.\n"
+" glob pattern = user4, user5\n"
+" ** = user6\n"
+msgstr ""
+
+#, python-format
+msgid "acl: %s not enabled\n"
+msgstr ""
+
+#, python-format
+msgid "acl: %s enabled, %d entries for user %s\n"
+msgstr ""
+
+#, python-format
+msgid "config error - hook type \"%s\" cannot stop incoming changesets"
+msgstr ""
+
+#, python-format
+msgid "acl: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+#, python-format
+msgid "acl: user %s denied on %s\n"
+msgstr "acl: ユーザ %s 㯠%s ã«æ‹’å¦ã•れã¾ã—ãŸ\n"
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr "acl: ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ %s ã®ã‚¢ã‚¯ã‚»ã‚¹ã¯æ‹’å¦ã•れã¾ã—ãŸ"
+
+#, python-format
+msgid "acl: user %s not allowed on %s\n"
+msgstr "acl: ユーザ %s 㯠%s ã§è¨±å¯ã•れã¦ã„ã¾ã›ã‚“\n"
+
+#, python-format
+msgid "acl: allowing changeset %s\n"
+msgstr "acl: è¨±å¯æ¸ˆã¿ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ %s\n"
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+"Bookmarks are local movable markers to changesets. Every bookmark\n"
+"points to a changeset identified by its hash. If you commit a\n"
+"changeset that is based on a changeset that has a bookmark on it,\n"
+"the bookmark shifts to the new changeset.\n"
+"\n"
+"It is possible to use bookmark names in every revision lookup\n"
+"(e.g. hg merge, hg update).\n"
+"\n"
+"By default, when several bookmarks point to the same changeset, they\n"
+"will all move forward together. It is possible to obtain a more\n"
+"git-like experience by adding the following configuration option to\n"
+"your .hgrc:\n"
+"\n"
+" [bookmarks]\n"
+" track.current = True\n"
+"\n"
+"This will cause Mercurial to track the bookmark that you are currently\n"
+"using, and only update it. This is similar to git's approach to\n"
+"branching.\n"
+msgstr ""
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+" Bookmarks are pointers to certain commits that move when\n"
+" committing. Bookmarks are local. They can be renamed, copied and\n"
+" deleted. It is possible to use bookmark names in 'hg merge' and\n"
+" 'hg update' to merge and update respectively to a given bookmark.\n"
+"\n"
+" You can use 'hg bookmark NAME' to set a bookmark on the working\n"
+" directory's parent revision with the given name. If you specify\n"
+" a revision using -r REV (where REV may be an existing bookmark),\n"
+" the bookmark is assigned to that revision.\n"
+" "
+msgstr ""
+
+msgid "a bookmark of this name does not exist"
+msgstr "ã“ã®åå‰ã®ãƒ–ックマークã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+
+msgid "a bookmark of the same name already exists"
+msgstr "åŒã˜åå‰ã®ãƒ–ックマークãŒã™ã§ã«å­˜åœ¨ã—ã¾ã™"
+
+msgid "new bookmark name required"
+msgstr "æ–°ã—ã„ブックマークåã‚’è¦æ±‚ã—ã¾ã—ãŸ"
+
+msgid "bookmark name required"
+msgstr "ブックマークåã‚’è¦æ±‚ã—ã¾ã—ãŸ"
+
+msgid "bookmark name cannot contain newlines"
+msgstr "ブックマークåã«æ”¹è¡Œã‚’å«ã‚ã¾ã›ã‚“"
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr ""
+
+msgid "force"
+msgstr ""
+
+msgid "revision"
+msgstr "リビジョン"
+
+msgid "delete a given bookmark"
+msgstr ""
+
+msgid "rename a given bookmark"
+msgstr ""
+
+msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
+msgstr ""
+
+msgid ""
+"hooks for integrating with the Bugzilla bug tracker\n"
+"\n"
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
+"bug status.\n"
+"\n"
+"The hook updates the Bugzilla database directly. Only Bugzilla\n"
+"installations using MySQL are supported.\n"
+"\n"
+"The hook relies on a Bugzilla script to send bug change notification\n"
+"emails. That script changes between Bugzilla versions; the\n"
+"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
+"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
+"be run by Mercurial as the user pushing the change; you will need to\n"
+"ensure the Bugzilla install file permissions are set appropriately.\n"
+"\n"
+"Configuring the extension:\n"
+"\n"
+" [bugzilla]\n"
+"\n"
+" host Hostname of the MySQL server holding the Bugzilla\n"
+" database.\n"
+" db Name of the Bugzilla database in MySQL. Default 'bugs'.\n"
+" user Username to use to access MySQL server. Default 'bugs'.\n"
+" password Password to use to access MySQL server.\n"
+" timeout Database connection timeout (seconds). Default 5.\n"
+" version Bugzilla version. Specify '3.0' for Bugzilla versions\n"
+" 3.0 and later, '2.18' for Bugzilla versions from 2.18\n"
+" and '2.16' for versions prior to 2.18.\n"
+" bzuser Fallback Bugzilla user name to record comments with, if\n"
+" changeset committer cannot be found as a Bugzilla user.\n"
+" bzdir Bugzilla install directory. Used by default notify.\n"
+" Default '/var/www/html/bugzilla'.\n"
+" notify The command to run to get Bugzilla to send bug change\n"
+" notification emails. Substitutes from a map with 3\n"
+" keys, 'bzdir', 'id' (bug id) and 'user' (committer\n"
+" bugzilla email). Default depends on version; from 2.18\n"
+" it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
+" %(id)s %(user)s\".\n"
+" regexp Regular expression to match bug IDs in changeset commit\n"
+" message. Must contain one \"()\" group. The default\n"
+" expression matches 'Bug 1234', 'Bug no. 1234', 'Bug\n"
+" number 1234', 'Bugs 1234,5678', 'Bug 1234 and 5678' and\n"
+" variations thereof. Matching is case insensitive.\n"
+" style The style file to use when formatting comments.\n"
+" template Template to use when formatting comments. Overrides\n"
+" style if specified. In addition to the usual Mercurial\n"
+" keywords, the extension specifies:\n"
+" {bug} The Bugzilla bug ID.\n"
+" {root} The full pathname of the Mercurial\n"
+" repository.\n"
+" {webroot} Stripped pathname of the Mercurial\n"
+" repository.\n"
+" {hgweb} Base URL for browsing Mercurial\n"
+" repositories.\n"
+" Default 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip The number of slashes to strip from the front of {root}\n"
+" to produce {webroot}. Default 0.\n"
+" usermap Path of file containing Mercurial committer ID to\n"
+" Bugzilla user ID mappings. If specified, the file\n"
+" should contain one mapping per line,\n"
+" \"committer\"=\"Bugzilla user\". See also the [usermap]\n"
+" section.\n"
+"\n"
+" [usermap]\n"
+" Any entries in this section specify mappings of Mercurial\n"
+" committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl Base URL for browsing Mercurial repositories. Reference\n"
+" from templates as {hgweb}.\n"
+"\n"
+"Activating the extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # run bugzilla hook on every change pulled or pushed in here\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Example configuration:\n"
+"\n"
+"This example configuration is for a collection of Mercurial\n"
+"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
+"installation in /opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Commits add a comment to the Bugzilla bug record of the form:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr "%s:%s ã« %s ã¨ã—ã¦æŽ¥ç¶šã—ã¦ã„ã¾ã™ (パスワード:%s)\n"
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr "å•ã„åˆã‚ã›: %s %s\n"
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr "å•ã„åˆã‚ã›ã«å¤±æ•—: %s %s\n"
+
+msgid "unknown database schema"
+msgstr "未知ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚¹ã‚­ãƒ¼ãƒž"
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr ""
+
+msgid "telling bugzilla to send mail:\n"
+msgstr ""
+
+#, python-format
+msgid " bug %s\n"
+msgstr " ãƒã‚° %s\n"
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr "通知コマンド %s 実行中\n"
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr ""
+
+msgid "done\n"
+msgstr "完了\n"
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr "ユーザ %s を検索ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr "%s ã® buzilla ユーザ ID を見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr "%s ã‹ %s ã® buzilla ユーザ ID を見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr "bugzilla ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“"
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr "python mysql ã®ã‚µãƒãƒ¼ãƒˆãŒåˆ©ç”¨ã§ãã¾ã›ã‚“: %s"
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr ""
+
+#, python-format
+msgid "database error: %s"
+msgstr "データベースエラー: %s"
+
+msgid "command to display child changesets"
+msgstr "å­ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆè¡¨ç¤ºã®ã‚³ãƒžãƒ³ãƒ‰"
+
+msgid ""
+"show the children of the given or working directory revision\n"
+"\n"
+" Print the children of the working directory's revisions. If a\n"
+" revision is given via -r/--rev, the children of that revision will\n"
+" be printed. If a file argument is given, revision in which the\n"
+" file was last changed (after the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"指定リビジョンã®å­ãƒªãƒ“ジョンã®è¡¨ç¤º\n"
+"\n"
+" 作業領域ã®å­ãƒªãƒ“ジョンを表示ã—ã¾ã™ã€‚-r/--rev ã«ã‚ˆã‚‹ãƒªãƒ“ジョン指定ãŒ\n"
+" ã‚ã‚‹å ´åˆã¯ã€æŒ‡å®šãƒªãƒ“ジョンã®å­ãƒªãƒ“ジョンを表示ã—ã¾ã™ã€‚引数ã¨ã—ã¦\n"
+" ãƒ•ã‚¡ã‚¤ãƒ«ãŒæŒ‡å®šã•れãŸå ´åˆã€ãƒ•ァイルãŒ(作業領域ã®ãƒªãƒ“ジョンãªã„ã—\n"
+" --rev ã§æŒ‡å®šã•れãŸãƒªãƒ“ジョンã®å¾Œã§)最後ã«å¤‰æ›´ã•れãŸãƒªãƒ“ジョンを表示\n"
+" ã—ã¾ã™ã€‚\n"
+" "
+
+msgid "show children of the specified revision"
+msgstr "指定リビジョンã®å­ãƒªãƒ“ジョンã®è¡¨ç¤º"
+
+msgid "hg children [-r REV] [FILE]"
+msgstr "hg children [-r REV] [FILE]"
+
+msgid "command to display statistics about repository history"
+msgstr "変更履歴ã®çµ±è¨ˆæƒ…報表示ã®ã‚³ãƒžãƒ³ãƒ‰"
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr "マージ実施リビジョン %d を無視...\n"
+
+#, python-format
+msgid "generating stats: %d%%"
+msgstr "統計作業中: %d%%"
+
+msgid ""
+"histogram of changes to the repository\n"
+"\n"
+" This command will display a histogram representing the number\n"
+" of changed lines or revisions, grouped according to the given\n"
+" template. The default template will group changes by author.\n"
+" The --dateformat option may be used to group the results by\n"
+" date instead.\n"
+"\n"
+" Statistics are based on the number of changed lines, or\n"
+" alternatively the number of matching revisions if the\n"
+" --changesets option is specified.\n"
+"\n"
+" Examples:\n"
+"\n"
+" # display count of changed lines for every committer\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # display daily activity graph\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # display activity of developers by month\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # display count of lines changed in every year\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" It is possible to map alternate email addresses to a main address\n"
+" by providing a file using the following format:\n"
+"\n"
+" <alias email> <actual email>\n"
+"\n"
+" Such a file may be specified with the --aliases option, otherwise a\n"
+" .hgchurn file will be looked for in the working directory root.\n"
+" "
+msgstr ""
+"リãƒã‚¸ãƒˆãƒªã«ãŠã‘る変更ã®çµ±è¨ˆåˆ†å¸ƒè¡¨ç¤º\n"
+"\n"
+" 本コマンドã¯ã€å¤‰æ›´è¡Œæ•°ãªã„ã—リビジョン数ã®åº¦æ•°åˆ†å¸ƒã‚’ã€ãƒ†ãƒ³ãƒ—レート\n"
+" 指定ãªã„ã—æ—¥æ™‚ã«ã‚ˆã£ã¦ã‚°ãƒ«ãƒ¼ãƒ—化ã—ãŸã‚‚ã®ã‚’グラフ表示ã—ã¾ã™ã€‚特ã«\n"
+" 指定ã®ç„¡ã„å ´åˆã€ãƒªãƒ“ジョン作æˆè€…毎ã«å¤‰æ›´è¡Œæ•°ã‚’グループ化ã—ã¾ã™ã€‚\n"
+" --dateformat ãŒæŒ‡å®šã•れãŸå ´åˆã€åº¦æ•°åˆ†å¸ƒã¯æ—¥æ™‚ã§ã‚°ãƒ«ãƒ¼ãƒ—化ã•れã¾ã™ã€‚\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šã®ç„¡ã„å ´åˆã€åº¦æ•°åˆ†å¸ƒã®çµ±è¨ˆå¯¾è±¡ã¯å¤‰æ›´è¡Œæ•°ã¨ãªã‚Šã¾ã™ãŒã€\n"
+" --changesets ãŒæŒ‡å®šã•れãŸå ´åˆã¯ã€å¯¾è±¡ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æ•°ãŒçµ±è¨ˆå¯¾è±¡ã¨\n"
+" ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" 例:\n"
+"\n"
+" # ユーザ毎ã®å¤‰æ›´è¡Œæ•°ã®è¡¨ç¤º\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # æ—¥æ¯Žã®æ´»ç™ºåº¦(コミット実施数)を表示\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # æœˆæ¯Žã®æ´»ç™ºåº¦ã‚’表示\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # 年毎ã®å¤‰æ›´è¡Œæ•°ã‚’表示\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" 以下ã®å½¢å¼ã®ãƒ•ァイルを指定ã™ã‚‹ã“ã¨ã§ã€ãƒªãƒ“ジョンã«è¨˜éŒ²ã•れãŸé›»å­\n"
+" メールアドレスを別ã®ã‚‚ã®ã«å¤‰æ›ã™ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™:\n"
+"\n"
+" <別å> <実å>\n"
+"\n"
+" 上記形å¼ã®ãƒ•ァイルã¯ã€--aliases ãŒæŒ‡å®šã•れãŸå ´åˆã¯æŒ‡å®šã•れãŸ\n"
+" ファイルãŒèª­ã¿è¾¼ã¾ã‚Œã¾ã™ãŒã€ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆ\n"
+" 直下㫠.hgchurn ã¨ã„ã†ãƒ•ァイルãŒã‚れã°ã€ã“れãŒä½¿ç”¨ã•れã¾ã™ã€‚\n"
+" "
+
+#, python-format
+msgid "assuming %i character terminal\n"
+msgstr "ç”»é¢ã®æ¨ªå¹…ã‚’ %i 文字ã¨ä»®å®š\n"
+
+msgid "count rate for the specified revision or range"
+msgstr "処ç†å¯¾è±¡ã¨ã™ã‚‹ç‰¹å®šãƒªãƒ“ジョンï¼ç¯„å›²ã®æŒ‡å®š"
+
+msgid "count rate for revisions matching date spec"
+msgstr "指定日時ã¨ä¸€è‡´ã—ãŸãƒªãƒ“ジョンを処ç†å¯¾è±¡ã¨ã™ã‚‹"
+
+msgid "template to group changesets"
+msgstr "表示をグループ化ã™ã‚‹ãŸã‚ã®ãƒ†ãƒ³ãƒ—レート"
+
+msgid "strftime-compatible format for grouping by date"
+msgstr "日時グループ化ã®ãŸã‚ã® strftime 互æ›å½¢å¼ãƒ•ォーマット"
+
+msgid "count rate by number of changesets"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆæ•°ã§çµ±è¨ˆ"
+
+msgid "sort by key (default: sort by count)"
+msgstr "キーã«ã‚ˆã‚‹æ•´åˆ—(無指定時: 統計é‡ã§æ•´åˆ—)"
+
+msgid "file with email aliases"
+msgstr "ユーザå変æ›ç”¨ãƒ•ァイル"
+
+msgid "show progress"
+msgstr "進æ—状æ³ã®è¡¨ç¤º"
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+msgstr "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+
+msgid ""
+"colorize output from some commands\n"
+"\n"
+"This extension modifies the status command to add color to its output\n"
+"to reflect file status, the qseries command to add color to reflect\n"
+"patch status (applied, unapplied, missing), and to diff-related\n"
+"commands to highlight additions, removals, diff headers, and trailing\n"
+"whitespace.\n"
+"\n"
+"Other effects in addition to color, like bold and underlined text, are\n"
+"also available. Effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes). This module also provides the\n"
+"render_text function, which can be used to add effects to any text.\n"
+"\n"
+"Default effects may be overridden from the .hgrc file:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' turns off all effects\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+msgstr ""
+
+msgid "when to colorize (always, auto, or never)"
+msgstr ""
+
+msgid "don't colorize output"
+msgstr "出力を色ã¥ã‘市内"
+
+#, python-format
+msgid "ignoring unknown color/effect %r (configured in color.%s)\n"
+msgstr ""
+
+msgid "import revisions from foreign VCS repositories into Mercurial"
+msgstr "ä»–ã®æ§‹æˆç®¡ç†ãƒ„ールã‹ã‚‰ Mercurial ã¸ã®å±¥æ­´å–り込ã¿"
+
+msgid ""
+"convert a foreign SCM repository to a Mercurial one.\n"
+"\n"
+" Accepted source formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Accepted destination formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (history on branches is not preserved)\n"
+"\n"
+" If no revision is given, all revisions will be converted.\n"
+" Otherwise, convert will only import up to the named revision\n"
+" (given in a format understood by the source).\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source with '-hg' appended. If the destination\n"
+" repository doesn't exist, it will be created.\n"
+"\n"
+" By default, all sources except Mercurial will use\n"
+" --branchsort. Mercurial uses --sourcesort to preserve original\n"
+" revision numbers order. Sort modes have the following effects:\n"
+" --branchsort: convert from parent to child revision when\n"
+" possible, which means branches are usually converted one after\n"
+" the other. It generates more compact repositories.\n"
+" --datesort: sort revisions by date. Converted repositories have\n"
+" good-looking changelogs but are often an order of magnitude\n"
+" larger than the same ones generated by --branchsort.\n"
+" --sourcesort: try to preserve source revisions order, only\n"
+" supported by Mercurial sources.\n"
+"\n"
+" If <REVMAP> isn't given, it will be put in a default location\n"
+" (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file\n"
+" that maps each source commit ID to the destination ID for that\n"
+" revision, like so:\n"
+" <source ID> <destination ID>\n"
+"\n"
+" If the file doesn't exist, it's automatically created. It's\n"
+" updated on each commit copied, so convert-repo can be interrupted\n"
+" and can be run repeatedly to copy new commits.\n"
+"\n"
+" The [username mapping] file is a simple text file that maps each\n"
+" source commit author to a destination commit author. It is handy\n"
+" for source SCMs that use unix logins to identify authors (eg:\n"
+" CVS). One line per author mapping and the line format is:\n"
+" srcauthor=whatever string you want\n"
+"\n"
+" The filemap is a file that allows filtering and remapping of files\n"
+" and directories. Comment lines start with '#'. Each line can\n"
+" contain one of the following directives:\n"
+"\n"
+" include path/to/file\n"
+"\n"
+" exclude path/to/file\n"
+"\n"
+" rename from/file to/file\n"
+"\n"
+" The 'include' directive causes a file, or all files under a\n"
+" directory, to be included in the destination repository, and the\n"
+" exclusion of all other files and directories not explicitly included.\n"
+" The 'exclude' directive causes files or directories to be omitted.\n"
+" The 'rename' directive renames a file or directory. To rename from\n"
+" a subdirectory into the root of the repository, use '.' as the\n"
+" path to rename to.\n"
+"\n"
+" The splicemap is a file that allows insertion of synthetic\n"
+" history, letting you specify the parents of a revision. This is\n"
+" useful if you want to e.g. give a Subversion merge two parents, or\n"
+" graft two disconnected series of history together. Each entry\n"
+" contains a key, followed by a space, followed by one or two\n"
+" comma-separated values. The key is the revision ID in the source\n"
+" revision control system whose parents should be modified (same\n"
+" format as a key in .hg/shamap). The values are the revision IDs\n"
+" (in either the source or destination revision control system) that\n"
+" should be used as the new parents for that node.\n"
+"\n"
+" The branchmap is a file that allows you to rename a branch when it is\n"
+" being brought in from whatever external repository. When used in\n"
+" conjunction with a splicemap, it allows for a powerful combination\n"
+" to help fix even the most badly mismanaged repositories and turn them\n"
+" into nicely structured Mercurial repositories. The branchmap contains\n"
+" lines of the form \"original_branch_name new_branch_name\".\n"
+" \"original_branch_name\" is the name of the branch in the source\n"
+" repository, and \"new_branch_name\" is the name of the branch is the\n"
+" destination repository. This can be used to (for instance) move code\n"
+" in one repository from \"default\" to a named branch.\n"
+"\n"
+" Mercurial Source\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (boolean)\n"
+" ignore integrity errors when reading. Use it to fix Mercurial\n"
+" repositories with missing revlogs, by converting from and to\n"
+" Mercurial.\n"
+" --config convert.hg.saverev=False (boolean)\n"
+" store original revision ID in changeset (forces target IDs to\n"
+" change)\n"
+" --config convert.hg.startrev=0 (hg revision identifier)\n"
+" convert start revision and its descendants\n"
+"\n"
+" CVS Source\n"
+" ----------\n"
+"\n"
+" CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+" to indicate the starting point of what will be converted. Direct\n"
+" access to the repository files is not needed, unless of course the\n"
+" repository is :local:. The conversion uses the top level directory\n"
+" in the sandbox to find the CVS repository, and then uses CVS rlog\n"
+" commands to find files to convert. This means that unless a\n"
+" filemap is given, all files under the starting directory will be\n"
+" converted, and that any directory reorganization in the CVS\n"
+" sandbox is ignored.\n"
+"\n"
+" Because CVS does not have changesets, it is necessary to collect\n"
+" individual commits to CVS and merge them into changesets. CVS\n"
+" source uses its internal changeset merging code by default but can\n"
+" be configured to call the external 'cvsps' program by setting:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" This option is deprecated and will be removed in Mercurial 1.4.\n"
+"\n"
+" The options shown are the defaults.\n"
+"\n"
+" Internal cvsps is selected by setting\n"
+" --config convert.cvsps=builtin\n"
+" and has a few more configurable options:\n"
+" --config convert.cvsps.cache=True (boolean)\n"
+" Set to False to disable remote log caching, for testing and\n"
+" debugging purposes.\n"
+" --config convert.cvsps.fuzz=60 (integer)\n"
+" Specify the maximum time (in seconds) that is allowed\n"
+" between commits with identical user and log message in a\n"
+" single changeset. When very large files were checked in as\n"
+" part of a changeset then the default may not be long\n"
+" enough.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will insert a dummy revision merging the branch on\n"
+" which this log message occurs to the branch indicated in\n"
+" the regex.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will add the most recent revision on the branch\n"
+" indicated in the regex as the second parent of the\n"
+" changeset.\n"
+"\n"
+" The hgext/convert/cvsps wrapper script allows the builtin\n"
+" changeset merging code to be run without doing a conversion. Its\n"
+" parameters and output are similar to that of cvsps 2.1.\n"
+"\n"
+" Subversion Source\n"
+" -----------------\n"
+"\n"
+" Subversion source detects classical trunk/branches/tags layouts.\n"
+" By default, the supplied \"svn://repo/path/\" source URL is\n"
+" converted as a single branch. If \"svn://repo/path/trunk\" exists it\n"
+" replaces the default branch. If \"svn://repo/path/branches\" exists,\n"
+" its subdirectories are listed as possible branches. If\n"
+" \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
+" converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
+" can be overridden with following options. Set them to paths\n"
+" relative to the source URL, or leave them blank to disable auto\n"
+" detection.\n"
+"\n"
+" --config convert.svn.branches=branches (directory name)\n"
+" specify the directory containing branches\n"
+" --config convert.svn.tags=tags (directory name)\n"
+" specify the directory containing tags\n"
+" --config convert.svn.trunk=trunk (directory name)\n"
+" specify the name of the trunk branch\n"
+"\n"
+" Source history can be retrieved starting at a specific revision,\n"
+" instead of being integrally converted. Only single branch\n"
+" conversions are supported.\n"
+"\n"
+" --config convert.svn.startrev=0 (svn revision number)\n"
+" specify start Subversion revision.\n"
+"\n"
+" Perforce Source\n"
+" ---------------\n"
+"\n"
+" The Perforce (P4) importer can be given a p4 depot path or a\n"
+" client specification as source. It will convert all files in the\n"
+" source to a flat Mercurial repository, ignoring labels, branches\n"
+" and integrations. Note that when a depot path is given you then\n"
+" usually should specify a target directory, because otherwise the\n"
+" target may be named ...-hg.\n"
+"\n"
+" It is possible to limit the amount of source history to be\n"
+" converted by specifying an initial Perforce revision.\n"
+"\n"
+" --config convert.p4.startrev=0 (perforce changelist number)\n"
+" specify initial Perforce revision.\n"
+"\n"
+"\n"
+" Mercurial Destination\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (boolean)\n"
+" dispatch source branches in separate clones.\n"
+" --config convert.hg.tagsbranch=default (branch name)\n"
+" tag revisions branch name\n"
+" --config convert.hg.usebranchnames=True (boolean)\n"
+" preserve branch names\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"create changeset information from CVS\n"
+"\n"
+" This command is intended as a debugging tool for the CVS to\n"
+" Mercurial converter, and can be used as a direct replacement for\n"
+" cvsps.\n"
+"\n"
+" Hg debugcvsps reads the CVS rlog for current directory (or any\n"
+" named directory) in the CVS repository, and converts the log to a\n"
+" series of changesets based on matching commit log entries and\n"
+" dates."
+msgstr ""
+"CVS ã‹ã‚‰ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆæƒ…報作æˆ\n"
+"\n"
+" 本コマンドã®ä½ç½®ä»˜ã‘ã¯ã€CVS ã‹ã‚‰ Mercurial ã¸ã®å¤‰æ›ã«ãŠã‘るデãƒãƒƒã‚°\n"
+" ツールã§ã‚りã€cvsps ã®ä»£æ›¿ãƒ„ールã¨ã—ã¦ä½¿ç”¨å¯èƒ½ã§ã™ã€‚\n"
+"\n"
+" 本コマンドã¯ã€ç¾ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª(ãªã„ã—æŒ‡å®šãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª)中㮠CVS rlog ã‚’\n"
+" 読ã¿è¾¼ã¿ã€ã‚³ãƒŸãƒƒãƒˆãƒ­ã‚°ã®å†…å®¹ã¨æ—¥ä»˜ã‚’å…ƒã«æŽ¨æ¸¬ã•れるãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã¸ã¨\n"
+" 変æ›ã—ã¾ã™ã€‚"
+
+msgid "username mapping filename"
+msgstr "ユーザå対応付ã‘ãƒ•ã‚¡ã‚¤ãƒ«ã®æŒ‡å®š"
+
+msgid "destination repository type"
+msgstr "変æ›å…ˆã®ãƒªãƒã‚¸ãƒˆãƒªç¨®åˆ¥"
+
+msgid "remap file names using contents of file"
+msgstr "å¤‰æ›æ™‚ã®ãƒ•ァイルå変æ›ç”¨ãƒ•ァイル"
+
+msgid "import up to target revision REV"
+msgstr "指定リビジョンã¾ã§ã®å–り込ã¿"
+
+msgid "source repository type"
+msgstr "変æ›å…ƒãƒªãƒã‚¸ãƒˆãƒªç¨®åˆ¥"
+
+msgid "splice synthesized history into place"
+msgstr "履歴ã®åˆæˆ"
+
+msgid "change branch names while converting"
+msgstr "å¤‰æ›æ™‚ã®ãƒ–ランãƒå変æ›ç”¨ãƒ•ァイル"
+
+msgid "try to sort changesets by branches"
+msgstr "ブランãƒã«ã‚ˆã‚‹ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ä¸¦ã³æ›¿ãˆã‚’試ã™"
+
+msgid "try to sort changesets by date"
+msgstr "日付ã«ã‚ˆã‚‹ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ä¸¦ã³æ›¿ãˆã‚’試ã™"
+
+msgid "preserve source changesets order"
+msgstr "元リãƒã‚¸ãƒˆãƒªã§ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆä¸¦ã³é †ã‚’å°Šé‡"
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+
+msgid "only return changes on specified branches"
+msgstr "指定ブランãƒã®ã¿ã®å¤‰æ›"
+
+msgid "prefix to remove from file names"
+msgstr "ファイルåã‹ã‚‰é™¤å¤–ã™ã‚‹æŽ¥é ­è¾ž"
+
+msgid "only return changes after or between specified tags"
+msgstr "指定リビジョンã®ã¿ã®å¤‰æ›"
+
+msgid "update cvs log cache"
+msgstr "cvs ãƒ­ã‚°ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®æ›´æ–°"
+
+msgid "create new cvs log cache"
+msgstr "cvs ãƒ­ã‚°ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®æ–°è¦ä½œæˆ"
+
+msgid "set commit time fuzz in seconds"
+msgstr "ç§’ã®ä½ãŒä¸æ˜Žãªæ—¥æ™‚ã«è¨­å®šã™ã‚‹ç§’値"
+
+msgid "specify cvsroot"
+msgstr "cvsroot ã®æŒ‡å®š"
+
+msgid "show parent changesets"
+msgstr "親ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®è¡¨ç¤º"
+
+msgid "show current changeset in ancestor branches"
+msgstr "祖先ã®ãƒ–ランãƒã«ãŠã‘ã‚‹ç¾è¡Œãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®è¡¨ç¤º"
+
+msgid "ignored for compatibility"
+msgstr "※ å¾Œæ–¹äº’æ›æ€§ã®ãŸã‚ã®ã‚ªãƒ—ション"
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr "hg debugcvsps [OPTION]... [PATH]..."
+
+msgid ""
+"warning: lightweight checkouts may cause conversion failures, try with a "
+"regular branch instead.\n"
+msgstr "警告: 簡易ãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆã¯å¤±æ•—è¦å› ã¨ãªã‚‹ãŸã‚通常ブランãƒã‚’使ã„ã¾ã™\n"
+
+msgid "bzr source type could not be determined\n"
+msgstr "変æ›å…ƒã®ç¨®åˆ¥ãŒ bzr ã§ã‚ã‚‹ã¨ç‰¹å®šã§ãã¾ã›ã‚“\n"
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr "%s ã¯ç¾åœ¨ã®ãƒ–ランãƒã®æ­£ã—ã„リビジョンã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr "%s 㯠%s ã«ãŠã„ã¦å­˜åœ¨ã—ã¾ã›ã‚“"
+
+#, python-format
+msgid "%s.%s symlink has no target"
+msgstr "%s.%s ã¯ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯å…ˆãŒã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr "è¦æ±‚ã•れãŸãƒ„ール '%s' を見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "running: %s\n"
+msgstr "実行ã—ã¦ã„ã¾ã™: %s\n"
+
+#, python-format
+msgid "%s error:\n"
+msgstr "%s エラー:\n"
+
+#, python-format
+msgid "syntax error in %s(%d): key/value pair expected"
+msgstr "%s(%d) ã§ã®æ–‡æ³•エラー: key/value ã®çµ„ãŒå¿…è¦ã§ã™"
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr "変æ›ãƒ•ァイル %r ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“: %s"
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr "%s: リãƒã‚¸ãƒˆãƒªãŒè¦‹ã¤ã‹ã‚‰ãªã„ã‹ã€ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ãªã„å½¢å¼ã§ã™"
+
+#, python-format
+msgid "convert: %s\n"
+msgstr "変æ›: %s\n"
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr "%s: 未知ã®ãƒªãƒã‚¸ãƒˆãƒªå½¢å¼"
+
+#, python-format
+msgid "unknown sort mode: %s"
+msgstr "æœªçŸ¥ã®æ•´åˆ—æ–¹å¼ %s"
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr "%s 㨠%s ã®é–“ã§å·¡å›žã‚’検出ã—ã¾ã—ãŸ"
+
+msgid "not all revisions were sorted"
+msgstr "æ ¼ç´ã•れã¦ã„ãªã„リビジョンãŒã‚りã¾ã™"
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr "作æˆè€…å変æ›ãƒ•ァイル %s ã¸ã®æ›¸ãè¾¼ã¿ä¸­\n"
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr "作æˆè€…å変æ›ãƒ•ァイル %s ã®ä¸æ­£ãªè¡Œã‚’無視: %s\n"
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr "作æˆè€… %s ã‚’ %s ã«å¤‰æ›\n"
+
+#, python-format
+msgid "overriding mapping for author %s, was %s, will be %s\n"
+msgstr "作æˆè€… %s ã® %s ã¸ã®å¤‰æ›ã‚’ã€%s ã¸ã®å¤‰æ›ã§ä¸Šæ›¸ãã—ã¾ã™\n"
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr "%s ã‚’ %s ã®è¦ªã¨ã—ã¦åˆæˆ\n"
+
+msgid "scanning source...\n"
+msgstr "変æ›å…ƒãƒªãƒã‚¸ãƒˆãƒªã®èµ°æŸ»ä¸­...\n"
+
+msgid "sorting...\n"
+msgstr "ä¸¦ã¹æ›¿ãˆä¸­...\n"
+
+msgid "converting...\n"
+msgstr "変æ›ä¸­...\n"
+
+#, python-format
+msgid "source: %s\n"
+msgstr "変æ›å…ƒ: %s\n"
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr "変æ›å…ˆã¨ã—㦠%s を想定\n"
+
+msgid "more than one sort mode specified"
+msgstr "æ•´åˆ—ã‚ªãƒ—ã‚·ãƒ§ãƒ³ã®æŒ‡å®šãŒéŽå‰°ã§ã™"
+
+msgid "--sourcesort is not supported by this data source"
+msgstr "指定ã®å¤‰æ›å…ƒã§ã¯ --sourcesort を指定ã§ãã¾ã›ã‚“"
+
+msgid ""
+"warning: support for external cvsps is deprecated and will be removed in "
+"Mercurial 1.4\n"
+msgstr "警告: 外部 cvsps 㯠Mercurial 1.4 ã§ã‚µãƒãƒ¼ãƒˆæ‰“ã¡åˆ‡ã‚Šäºˆå®šã§ã™\n"
+
+#, python-format
+msgid "revision %s is not a patchset number or date"
+msgstr "%s ã¯ãƒªãƒ“ジョンåã§ã‚‚日付ã§ã‚‚ã‚りã¾ã›ã‚“"
+
+msgid "using builtin cvsps\n"
+msgstr "組ã¿è¾¼ã¿ cvsps を使用ã—ã¾ã™\n"
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr "%s ã¸æŽ¥ç¶šä¸­\n"
+
+msgid "CVS pserver authentication failed"
+msgstr "CVS pserver ã®èªè¨¼ã«å¤±æ•—"
+
+msgid "server sucks"
+msgstr "サーãƒå¿œç­”ãŒä¸æ­£ã§ã™"
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr "リモートファイル㨠%d ãƒã‚¤ãƒˆé•ã„ã¾ã™"
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr "cvs サーãƒ: %s\n"
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr "未知㮠CVS レスãƒãƒ³ã‚¹: %s"
+
+msgid "collecting CVS rlog\n"
+msgstr "CVS rlog åŽé›†ä¸­\n"
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr "CVS ログキャッシュ %s 読ã¿è¾¼ã¿ä¸­\n"
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr "キャッシュã«ã¯ %d ä»¶ã®ãƒ­ã‚°ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã™\n"
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr "キャッシュ読ã¿è¾¼ã¿ã®å¤±æ•—: %r\n"
+
+#, python-format
+msgid "running %s\n"
+msgstr "%s ã®å®Ÿè¡Œä¸­\n"
+
+#, python-format
+msgid "prefix=%r directory=%r root=%r\n"
+msgstr "接頭辞=%r ディレクトリ=%r ルート=%r\n"
+
+msgid "RCS file must be followed by working file"
+msgstr "RCS ファイルã¯ãƒ¯ãƒ¼ã‚­ãƒ³ã‚°ãƒ•ァイル情報を伴ã†ç­ˆã§ã™"
+
+msgid "must have at least some revisions"
+msgstr "リビジョン指定ãŒè¶³ã‚Šã¾ã›ã‚“"
+
+msgid "expected revision number"
+msgstr "リビジョン番å·ãŒã‚りã¾ã›ã‚“"
+
+msgid "revision must be followed by date line"
+msgstr "ãƒªãƒ“ã‚¸ãƒ§ãƒ³æƒ…å ±ã¯æ—¥ä»˜æƒ…報を伴ã†ç­ˆã§ã™"
+
+#, python-format
+msgid "found synthetic revision in %s: %r\n"
+msgstr "%s ã§åˆæˆãƒªãƒ“ジョン %r を検出\n"
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr "cvs ログキャッシュ %s ã®æ›¸ãè¾¼ã¿ä¸­\n"
+
+#, python-format
+msgid "%d log entries\n"
+msgstr "%d ä»¶ã®ãƒ­ã‚°ã‚¨ãƒ³ãƒˆãƒª\n"
+
+msgid "creating changesets\n"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆä½œæˆä¸­\n"
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr "åˆæˆãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã¯è¤‡æ•°ã®è¦ªã‚’ã‚‚ã¦ã¾ã›ã‚“"
+
+#, python-format
+msgid ""
+"warning: CVS commit message references non-existent branch %r:\n"
+"%s\n"
+msgstr ""
+"警告: CVS ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒæœªçŸ¥ã®ãƒ–ランム%r ã‚’å‚ç…§ã—ã¦ã„ã¾ã™:\n"
+"%s\n"
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr "%d ä»¶ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚¨ãƒ³ãƒˆãƒª\n"
+
+msgid "Python ElementTree module is not available"
+msgstr "Python ã® ElementTree モジュールãŒåˆ©ç”¨ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "cleaning up %s\n"
+msgstr "%s ã‚’æ•´ç†ä¸­\n"
+
+msgid "internal calling inconsistency"
+msgstr "å†…éƒ¨ä¸æ•´åˆ"
+
+msgid "errors in filemap"
+msgstr "ファイルマップã§ã®è§£æžã‚¨ãƒ©ãƒ¼"
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr "%s:%d: %r ã¯æ—¢ã« %s 中ã«ã‚りã¾ã™\n"
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr "%s:%d: %r ã¯æœªçŸ¥ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒ†ã‚£ãƒ–ã§ã™\n"
+
+msgid "source repository doesn't support --filemap"
+msgstr "変æ›å…ƒãƒªãƒã‚¸ãƒˆãƒªã¯ --filemap をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“"
+
+#, python-format
+msgid "%s does not look like a GNU Arch repo"
+msgstr "%s 㯠GNU Arch å½¢å¼ã§ã¯ãªã„ã¨æ€ã‚れã¾ã™"
+
+msgid "cannot find a GNU Arch tool"
+msgstr "GNU Arch ツールを見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr "ツリーãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s ã®è§£æžä¸­...\n"
+
+#, python-format
+msgid ""
+"tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr "未登録アーカイブ %s ã®å‚ç…§ã«ã‚ˆã‚Šãƒ„リー解æžã‚’中断...\n"
+
+#, python-format
+msgid "applying revision %s...\n"
+msgstr "リビジョン %s ã®é©ç”¨ä¸­...\n"
+
+#, python-format
+msgid "computing changeset between %s and %s...\n"
+msgstr "%s 㨠%s ã¨ã®é–“ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’算出中...\n"
+
+#, python-format
+msgid "obtaining revision %s...\n"
+msgstr "リビジョン %s ã®å–得中...\n"
+
+#, python-format
+msgid "analyzing revision %s...\n"
+msgstr "リビジョン %s ã®è§£æžä¸­...\n"
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr "リビジョン %s ã® cat-log ã®è§£æžã«å¤±æ•—"
+
+#, python-format
+msgid "%s is not a local Mercurial repo"
+msgstr "%s ã¯ãƒ­ãƒ¼ã‚«ãƒ«ã® Mercurial リãƒã‚¸ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr "変æ›å…ˆãƒªãƒã‚¸ãƒˆãƒª %s ã®åˆæœŸåŒ–中\n"
+
+msgid "run hg sink pre-conversion action\n"
+msgstr "変æ›å…ˆã§ã®å‰å‡¦ç†ã‚’実施\n"
+
+msgid "run hg sink post-conversion action\n"
+msgstr "変æ›å…ˆã§ã®å¾Œå‡¦ç†ã‚’実施\n"
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr "%s ã‹ã‚‰ %s ã«å–り込ã¿ä¸­\n"
+
+msgid "filtering out empty revision\n"
+msgstr "空リビジョンã®é™¤å¤–中\n"
+
+msgid "updating tags\n"
+msgstr "ã‚¿ã‚°ã®æ›´æ–°ä¸­\n"
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr "%s ã¯æ­£ã—ã„開始リビジョンã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr "例外を無視ã—ã¾ã™: %s\n"
+
+msgid "run hg source pre-conversion action\n"
+msgstr "変æ›å…ƒã§ã®å‰å‡¦ç†ã‚’実施\n"
+
+msgid "run hg source post-conversion action\n"
+msgstr "変æ›å…ƒã§ã®å¾Œå‡¦ç†ã‚’実施\n"
+
+#, python-format
+msgid "%s does not look like a monotone repo"
+msgstr "%s 㯠monotone ã®ãƒªãƒã‚¸ãƒˆãƒªã¨ã¯æ€ã‚れã¾ã›ã‚“"
+
+#, python-format
+msgid "copying file in renamed directory from '%s' to '%s'"
+msgstr "改å先ディレクトリ㮠'%s' ã‹ã‚‰ '%s' ã¸ãƒ•ァイルを複製中"
+
+msgid "reading p4 views\n"
+msgstr "p4 ビューã®èª­ã¿è¾¼ã¿ä¸­\n"
+
+msgid "collecting p4 changelists\n"
+msgstr "p4 ãƒã‚§ãƒ³ã‚¸ãƒªã‚¹ãƒˆã®åŽé›†ä¸­\n"
+
+msgid "Subversion python bindings could not be loaded"
+msgstr "Subversion python ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ãŒèª­ã¿è¾¼ã‚ã¾ã›ã‚“"
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr "Subversion python ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ã¯ 1.4 以上ãŒå¿…è¦ã§ã™(%d.%d を検出)"
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr "Subversion python ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ã¯ 1.4 以上ãŒå¿…è¦ã§ã™"
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr "svn: リビジョン %s ãŒæ•°å­—ã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr "svn: 開始リビジョン %s ãŒæ•°å­—ã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr "モジュール %s ã§ãƒªãƒ“ジョンãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr "%s ㌠%r ã«ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr "%s ㌠%r ã«ã‚りã¾ã—ãŸ\n"
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr "空ブランム%s を無視ã—ã¾ã™\n"
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr "ブランム%s ã‚’ %d ã§è¦‹ã¤ã‘ã¾ã—ãŸ\n"
+
+msgid "svn: start revision is not supported with more than one branch"
+msgstr "svn: 複数ブランãƒã«å¯¾ã™ã‚‹é–‹å§‹ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã¯æœªã‚µãƒãƒ¼ãƒˆã§ã™"
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr "svn: 開始リビジョン %d 以é™ã«ãƒªãƒ“ジョンã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "no tags found at revision %d\n"
+msgstr "リビジョン %d ã«ã‚¿ã‚°ã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "ignoring foreign branch %r\n"
+msgstr "外部ブランム%r を無視ã—ã¾ã™\n"
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr "リビジョン %s 㯠%d ã¾ã§ã®ã‚Šãƒ“ジョンã«è¦‹å½“ãŸã‚Šã¾ã›ã‚“"
+
+#, python-format
+msgid "branch renamed from %s to %s at %d\n"
+msgstr "ブランム%s ã‹ã‚‰ %s ã¸ã® %d ã«ãŠã‘る改å\n"
+
+#, python-format
+msgid "reparent to %s\n"
+msgstr "%s ã¸ã®ãƒªãƒšã‚¢ãƒ¬ãƒ³ãƒˆ\n"
+
+#, python-format
+msgid "copied to %s from %s@%s\n"
+msgstr "%s ã« %s@%s ã‹ã‚‰è¤‡è£½\n"
+
+#, python-format
+msgid "gone from %s\n"
+msgstr "%s を去りã¾ã™\n"
+
+#, python-format
+msgid "entry %s\n"
+msgstr "エントリ=%s\n"
+
+#, python-format
+msgid "unknown path in revision %d: %s\n"
+msgstr "リビジョン %d ã«æœªçŸ¥ã®ãƒ‘ス: %s\n"
+
+#, python-format
+msgid "mark %s came from %s:%d\n"
+msgstr "%s ã‚’ %s:%d ç”±æ¥ã¨ã¿ãªã™\n"
+
+#, python-format
+msgid "parsing revision %d (%d changes)\n"
+msgstr "リビジョン %d ã®è§£æžä¸­(%d ä»¶ã®å¤‰æ›´)\n"
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr "ブランム%s ã®è¦ªã‚’ %d:%s ã§æ¤œå‡º\n"
+
+msgid "no copyfrom path, don't know what to do.\n"
+msgstr "複製元パスãŒä¸æ˜ŽãªãŸã‚ã€å¯¾å‡¦ä¸èƒ½\n"
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr "\"%s\" ã®å¤‰æ›´å±¥æ­´(%d ã‹ã‚‰ %d)ã®å…ˆèª­ã¿ä¸­\n"
+
+#, python-format
+msgid "revision %d has no entries\n"
+msgstr "リビジョン %d ã¯ã‚¨ãƒ³ãƒˆãƒªã‚’æŒã£ã¦ã„ã¾ã›ã‚“\n"
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr "svn: ブランãƒã«ã¯ãƒªãƒ“ジョン %s ãŒã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "%r is not under %r, ignoring\n"
+msgstr "%r 㯠%r é…下ã«ãªã„ãŸã‚無視ã—ã¾ã™\n"
+
+#, python-format
+msgid "initializing svn repo %r\n"
+msgstr "svn リãƒã‚¸ãƒˆãƒª %r ã®åˆæœŸåŒ–中\n"
+
+#, python-format
+msgid "initializing svn wc %r\n"
+msgstr "svn ワーキングコピー %r ã‚’åˆæœŸåŒ–ã—ã¦ã„ã¾ã™\n"
+
+msgid "unexpected svn output:\n"
+msgstr "予期ã›ã¬ svn ã®å‡ºåŠ›:\n"
+
+msgid "unable to cope with svn output"
+msgstr "予期ã›ã¬ svn 出力ã®ãŸã‚継続ã§ãã¾ã›ã‚“"
+
+msgid "XXX TAGS NOT IMPLEMENTED YET\n"
+msgstr "XXX タグ付ã‘ã¯ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“\n"
+
+msgid ""
+"command to allow external programs to compare revisions\n"
+"\n"
+"The `extdiff' Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working directory. The external diff\n"
+"programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare.\n"
+"\n"
+"The `extdiff' extension also allows to configure new diff commands, so\n"
+"you do not need to type \"hg extdiff -p kdiff3\" always.\n"
+"\n"
+" [extdiff]\n"
+" # add new command that runs GNU diff(1) in 'context diff' mode\n"
+" cdiff = gdiff -Nprc5\n"
+" ## or the old way:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # add new command called vdiff, runs kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # add new command called meld, runs meld (no need to name twice)\n"
+" meld =\n"
+"\n"
+" # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+" # (see http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Non English user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" "
+"in\n"
+" # your .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"You can use -I/-X and list of file or directory names like normal \"hg\n"
+"diff\" command. The `extdiff' extension makes snapshots of only needed\n"
+"files, so running the external diff program will actually be pretty\n"
+"fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from working directory\n"
+msgstr ""
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr "--rev 㨠--change ã¯åŒæ™‚ã«ã¯æŒ‡å®šå‡ºæ¥ã¾ã›ã‚“"
+
+#, python-format
+msgid "running %r in %s\n"
+msgstr ""
+
+#, python-format
+msgid "file changed while diffing. Overwriting: %s (src: %s)\n"
+msgstr ""
+
+msgid "cleaning up temp directory\n"
+msgstr "ä¸€æ™‚ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®æ•´ç†ã‚’ã—ã¦ã„ã¾ã™\n"
+
+msgid ""
+"use external program to diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files, using\n"
+" an external program. The default program used is diff, with\n"
+" default options \"-Npru\".\n"
+"\n"
+" To select a different program, use the -p/--program option. The\n"
+" program will be passed the names of two directories to compare. To\n"
+" pass additional options to the program, use -o/--option. These\n"
+" will be passed before the names of the directories to compare.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent."
+msgstr ""
+
+msgid "comparison program to run"
+msgstr ""
+
+msgid "pass option to comparison program"
+msgstr ""
+
+msgid "change made by revision"
+msgstr "当該リビジョンã«ãŠã‘る変更内容ã®è¡¨ç¤º"
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr ""
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "pull, update and merge in one command"
+msgstr ""
+
+msgid ""
+"pull changes from a remote repository, merge new changes if needed.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository.\n"
+"\n"
+" If the pulled changes add a new branch head, the head is\n"
+" automatically merged, and the result of the merge is committed.\n"
+" Otherwise, the working directory is updated to include the new\n"
+" changes.\n"
+"\n"
+" When a merge occurs, the newly pulled changes are assumed to be\n"
+" \"authoritative\". The head of the new changes is used as the first\n"
+" parent, with local changes as the second. To switch the merge\n"
+" order, use --switch-parent.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid ""
+"working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+
+msgid "outstanding uncommitted merge"
+msgstr "ãƒžãƒ¼ã‚¸ãŒæœªã‚³ãƒŸãƒƒãƒˆã§ã™"
+
+msgid "outstanding uncommitted changes"
+msgstr "未コミットã®å¤‰æ›´ãŒã‚りã¾ã™"
+
+msgid "working directory is missing some files"
+msgstr "作業領域ã«å­˜åœ¨ã—ãªã„ファイルãŒã‚りã¾ã™"
+
+msgid ""
+"multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr "%s ã‹ã‚‰å–り込ã¿ä¸­\n"
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr "連æºå…ˆã§ãƒªãƒ“ジョンãŒç‰¹å®šå‡ºæ¥ãªã„ãŸã‚ã€ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã¯æŒ‡å®šã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr "%d ã«æ›´æ–°ã—ã¦ã„ã¾ã™:%s\n"
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr "%d ã¨ãƒžãƒ¼ã‚¸ã—ã¦ã„ã¾ã™:%s\n"
+
+#, python-format
+msgid "Automated merge with %s"
+msgstr ""
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr ""
+
+msgid "a specific revision you would like to pull"
+msgstr ""
+
+msgid "edit commit message"
+msgstr "コミットメッセージã®ç·¨é›†"
+
+msgid "edit commit message (DEPRECATED)"
+msgstr ""
+
+msgid "switch parents when merging"
+msgstr ""
+
+msgid "hg fetch [SOURCE]"
+msgstr ""
+
+msgid "commands to sign and verify changesets"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ç½²åãŠã‚ˆã³æ¤œè¨¼ã®ã‚³ãƒžãƒ³ãƒ‰"
+
+msgid "error while verifying signature"
+msgstr ""
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr ""
+
+msgid "list signed changesets"
+msgstr "ç½²åæ¸ˆã¿ãƒªãƒ“ジョンã®ä¸€è¦§è¡¨ç¤º"
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr "%s:%d ノードã¯å­˜åœ¨ã—ã¾ã›ã‚“\n"
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr ""
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr "%s ã®æ­£ã—ã„ç½²åã§ã¯ã‚りã¾ã›ã‚“\n"
+
+msgid ""
+"add a signature for the current or given revision\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr "ãƒžãƒ¼ã‚¸ãŒæœªã‚³ãƒŸãƒƒãƒˆã§ã™ - 対象リビジョンを指定ã—ã¦ãã ã•ã„"
+
+msgid "Error while signing"
+msgstr "ç½²å処ç†ã®å¤±æ•—"
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+
+#, python-format
+msgid "Added signature for changeset %s"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ %s ã®ç½²åを追加ã—ã¾ã—ãŸ"
+
+msgid "unknown signature version"
+msgstr "未知ã®ç½²åãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+msgid "make the signature local"
+msgstr ""
+
+msgid "sign even if the sigfile is modified"
+msgstr ""
+
+msgid "do not commit the sigfile after signing"
+msgstr ""
+
+msgid "the key id to sign with"
+msgstr ""
+
+msgid "commit message"
+msgstr "コミットメッセージ"
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr "hg sign [OPTION]... [REVISION]..."
+
+msgid "hg sigcheck REVISION"
+msgstr "hg sigcheck REVISION"
+
+msgid "hg sigs"
+msgstr "hg sigs"
+
+msgid ""
+"command to view revision graphs from a shell\n"
+"\n"
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ASCII representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+"端末ã§ã®ãƒªãƒ“ジョングラフ表示ã®ã‚³ãƒžãƒ³ãƒ‰\n"
+"\n"
+"本エクステンションã¯ã€incoming, outgoing ãŠã‚ˆã³ log コマンド㫠--graph\n"
+"オプションを付与ã—ã¾ã™ã€‚ã“ã®ã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒæŒ‡å®šã•れãŸå ´åˆã€ASCII 文字ã«ã‚ˆã‚‹\n"
+"リビジョングラフãŒè¡¨ç¤ºã•れã¾ã™ã€‚\n"
+
+#, python-format
+msgid "--graph option is incompatible with --%s"
+msgstr "--graph 㨠--%s ã¯éžäº’æ›ã§ã™"
+
+msgid ""
+"show revision history alongside an ASCII revision graph\n"
+"\n"
+" Print a revision history alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+"ASCII 文字ã«ã‚ˆã‚‹ãƒªãƒ“ジョングラフ表示をæŒã¤å±¥æ­´è¡¨ç¤º\n"
+"\n"
+" ASCII 文字ã«ã‚ˆã‚‹ãƒªãƒ“ジョングラフ表示を伴ã£ãŸå¤‰æ›´å±¥æ­´ã‚’表示ã—ã¾ã™ã€‚\n"
+"\n"
+" @ 文字ã§è¡¨ç¤ºã•れるリビジョンã¯ã€ä½œæ¥­é ˜åŸŸã®è¦ªãƒªãƒ“ジョンã§ã™ã€‚\n"
+" "
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr "%s ã¨æ¯”較中\n"
+
+msgid "no changes found\n"
+msgstr "差分ã¯ã‚りã¾ã›ã‚“\n"
+
+msgid "show the revision DAG"
+msgstr "リビジョングラフã®è¡¨ç¤º"
+
+msgid "limit number of changes displayed"
+msgstr "最大表示リビジョン数"
+
+msgid "show patch"
+msgstr "パッãƒå½¢å¼ã§ã®è¡¨ç¤º"
+
+msgid "show the specified revision or range"
+msgstr "指定ã•れãŸå˜ä¸€ã€ãªã„ã—リビジョン区間ã®è¡¨ç¤º"
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr "hg glog [OPTION]... [FILE]"
+
+msgid ""
+"hooks for integrating with the CIA.vc notification service\n"
+"\n"
+"This is meant to be run as a changegroup or incoming hook.\n"
+"To configure it, set the following options in your hgrc:\n"
+"\n"
+"[cia]\n"
+"# your registered CIA user name\n"
+"user = foo\n"
+"# the name of the project in CIA\n"
+"project = foo\n"
+"# the module (subproject) (optional)\n"
+"#module = foo\n"
+"# Append a diffstat to the log message (optional)\n"
+"#diffstat = False\n"
+"# Template to use for log messages (optional)\n"
+"#template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"# Style to use (optional)\n"
+"#style = foo\n"
+"# The URL of the CIA notification service (optional)\n"
+"# You can use mailto: URLs to send by email, eg\n"
+"# mailto:cia@cia.vc\n"
+"# Make sure to set email.from if you do this.\n"
+"#url = http://cia.vc/\n"
+"# print message instead of sending it (optional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# one of these:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# If you want hyperlinks (optional)\n"
+"baseurl = http://server/path/to/repo\n"
+msgstr ""
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr "hgcia: %s ã«æ›´æ–°ã‚’é€ä¿¡ã—ã¦ã„ã¾ã™\n"
+
+msgid "email.from must be defined when sending by email"
+msgstr ""
+
+msgid "cia: no user specified"
+msgstr "cia: ãƒ¦ãƒ¼ã‚¶ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "cia: no project specified"
+msgstr "cia: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
+
+msgid ""
+"browse the repository in a graphical way\n"
+"\n"
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not\n"
+"distributed with Mercurial.)\n"
+"\n"
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to Mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and the extension is shipped in the hgext\n"
+"repository, and needs to be enabled.\n"
+"\n"
+"The hg view command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can specify\n"
+"the path to hgk in your .hgrc file:\n"
+"\n"
+" [hgk]\n"
+" path=/location/of/hgk\n"
+"\n"
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions."
+msgstr ""
+
+msgid "diff trees from two commits"
+msgstr ""
+
+msgid "output common ancestor information"
+msgstr "共通ã®å…ˆç¥–ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æƒ…報表示"
+
+msgid "cat a specific revision"
+msgstr "指定リビジョン時点ã®å†…容表示"
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr ""
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr ""
+
+msgid "parse given revisions"
+msgstr "指定リビジョンã®è§£æž"
+
+msgid "print revisions"
+msgstr "リビジョンã®è¡¨ç¤º"
+
+msgid "print extension options"
+msgstr "エクステンション設定ã®è¡¨ç¤º"
+
+msgid "start interactive history viewer"
+msgstr ""
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr "hg view [-l LIMIT] [REVRANGE]"
+
+msgid "generate patch"
+msgstr "パッãƒã®ç”Ÿæˆ"
+
+msgid "recursive"
+msgstr "å†èµ·"
+
+msgid "pretty"
+msgstr ""
+
+msgid "stdin"
+msgstr "標準入力"
+
+msgid "detect copies"
+msgstr "ã‚³ãƒ”ãƒ¼ã®æ¤œå‡º"
+
+msgid "search"
+msgstr ""
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr "hg debug-cat-file [OPTION]... TYPE FILE"
+
+msgid "hg debug-config"
+msgstr "hg debug-config"
+
+msgid "hg debug-merge-base REV REV"
+msgstr "hg debug-merge-base REV REV"
+
+msgid "ignored"
+msgstr "無視ã—ã¾ã—ãŸ"
+
+msgid "hg debug-rev-parse REV"
+msgstr "hg debug-rev-parse REV"
+
+msgid "header"
+msgstr "ヘッダ"
+
+msgid "topo-order"
+msgstr ""
+
+msgid "parents"
+msgstr "親"
+
+msgid "max-count"
+msgstr ""
+
+msgid "hg debug-rev-list [OPTION]... REV..."
+msgstr "hg debug-rev-list [OPTION]... REV..."
+
+msgid ""
+"syntax highlighting for hgweb (requires Pygments)\n"
+"\n"
+"It depends on the Pygments syntax highlighting library:\n"
+"http://pygments.org/\n"
+"\n"
+"There is a single configuration option:\n"
+"\n"
+"[web]\n"
+"pygments_style = <style>\n"
+"\n"
+"The default is 'colorful'.\n"
+msgstr ""
+
+msgid "accelerate status report using Linux's inotify service"
+msgstr "Linux ã® inoitfy サービスã«ã‚ˆã‚‹çŠ¶æ…‹å ±å‘Šã®é«˜é€ŸåŒ–"
+
+msgid "start an inotify server for this repository"
+msgstr "リãƒã‚¸ãƒˆãƒªã«å¯¾ã™ã‚‹ inotify サーãƒã®èµ·å‹•"
+
+msgid ""
+"debugging information for inotify extension\n"
+"\n"
+" Prints the list of directories being watched by the inotify server.\n"
+" "
+msgstr ""
+"inotify エクステンションå‘ã‘デãƒãƒƒã‚°æƒ…å ±\n"
+"\n"
+" inotify サーãƒã®ç›£è¦–対象ディレクトリを一覧表示ã—ã¾ã™ã€‚\n"
+" "
+
+msgid "directories being watched:\n"
+msgstr "監視対象ディレクトリ:\n"
+
+msgid "run server in background"
+msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ã§ã®ã‚µãƒ¼ãƒå®Ÿè¡Œ"
+
+msgid "used internally by daemon mode"
+msgstr "(ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰å®Ÿè¡Œæ™‚ã§ã®å†…部用途å‘ã‘)"
+
+msgid "minutes to sit idle before exiting"
+msgstr "終了å‰ã®ã‚¢ã‚¤ãƒ‰ãƒªãƒ³ã‚°å¾…機時間(å˜ä½:分)"
+
+msgid "name of file to write process ID to"
+msgstr "プロセスIDã®æ›¸ã出ã—先ファイル"
+
+msgid "hg inserve [OPTION]..."
+msgstr "hg inserve [OPTION]..."
+
+msgid "(found dead inotify server socket; removing it)\n"
+msgstr "(終了ã—㟠inotify サーãƒã®ã‚½ã‚±ãƒƒãƒˆã‚’検出ã—ãŸã®ã§å‰Šé™¤ã—ã¾ã™)\n"
+
+msgid "(starting inotify server)\n"
+msgstr "(inotify サーãƒã®èµ·å‹•中)\n"
+
+#, python-format
+msgid "could not start inotify server: %s\n"
+msgstr "inotify サーãƒã®èµ·å‹•ã«å¤±æ•—: %s\n"
+
+#, python-format
+msgid "could not talk to new inotify server: %s\n"
+msgstr "inotify サーãƒã¨ã®é€£æºã«å¤±æ•—: %s\n"
+
+msgid "(inotify server not running)\n"
+msgstr "(inotify サーãƒã¯èµ·å‹•ã•れã¦ã„ã¾ã›ã‚“)\n"
+
+#, python-format
+msgid "failed to contact inotify server: %s\n"
+msgstr "inotify サーãƒã¨ã®é€£æºã«å¤±æ•—: %s\n"
+
+msgid "received empty answer from inotify server"
+msgstr "inotify サーãƒã‹ã‚‰ã®ç©ºå¿œç­” "
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr "(inotify: äº’æ›æ€§ã®ç„¡ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ã®ã‚µãƒ¼ãƒå¿œç­”ã‚’å—ç†)\n"
+
+#, python-format
+msgid "(inotify: received '%s' response when expecting '%s')\n"
+msgstr "(inotify: 想定外㮠'%s' 応答をå—ç†ã€‚想定応答㯠'%s')\n"
+
+msgid "this system does not seem to support inotify"
+msgstr "ã“ã®ã‚·ã‚¹ãƒ†ãƒ ã§ã¯ inotify ã¯åˆ©ç”¨ã§ããªã„よã†ã«è¦‹ãˆã¾ã™"
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr "*** inotify ã®ãƒ¦ãƒ¼ã‚¶æ¯Žç›£è¦–å¯¾è±¡ä¸Šé™æ•°ã¯ %s\n"
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr "*** ã“ã®ä¸Šé™ã¯ä½œæ¥­é ˜åŸŸã®å…¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ç›£è¦–ã«ã¯å°‘ãªã™ãŽã¾ã™\n"
+
+msgid "*** counting directories: "
+msgstr "*** ディレクトリã®è¨ˆä¸Šä¸­: "
+
+#, python-format
+msgid "found %d\n"
+msgstr "%d 個ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’検出\n"
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr "*** 上é™ã‚’ %d ã‹ã‚‰ %d ã«ä¸Šã’ã¦ãã ã•ã„(root 権é™ãŒå¿…è¦):\n"
+
+#, python-format
+msgid "*** echo %d > %s\n"
+msgstr "*** echo %d > %s\n"
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr "inotify ã®ç›£è¦–対象上é™ãŒä¸ŠãŒã‚‹ã¾ã§ã¯ %s を監視ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr "inotify サービスãŒä½¿ç”¨ã§ãã¾ã›ã‚“: %s"
+
+#, python-format
+msgid "watching %r\n"
+msgstr "%r を監視\n"
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr "%r é…下ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’監視\n"
+
+#, python-format
+msgid "status: %r dir(%d) -> %s\n"
+msgstr "status: %r dir(%d) -> %s\n"
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr "status: %r %s -> %s\n"
+
+#, python-format
+msgid "%s dirstate reload\n"
+msgstr "%s: dirstate å†èª­ã¿è¾¼ã¿ä¸­\n"
+
+#, python-format
+msgid "%s end dirstate reload\n"
+msgstr "%s: dirstate å†èª­ã¿è¾¼ã¿å®Œäº†\n"
+
+msgid "rescanning due to .hgignore change\n"
+msgstr ".hgignore 変更ã«ä»˜ãå†èµ°æŸ»ä¸­\n"
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr "%s: %s を作æˆ\n"
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr "%s: %s を削除\n"
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr "%s: %s を変更\n"
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr "%s ã‚’å«ã‚€ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ãŒæœªãƒžã‚¦ãƒ³ãƒˆã§ã™\n"
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr "%s: 読ã¿è¾¼ã¿å¯èƒ½: %d ãƒã‚¤ãƒˆ\n"
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr "%s: 閾値未満 - ロック解放\n"
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr "%s: %d 個ã®ã‚¤ãƒ™ãƒ³ãƒˆèª­ã¿è¾¼ã¿ä¸­\n"
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr "%s: 読ã¿è¾¼ã¿å¯èƒ½ãª %d ãƒã‚¤ãƒˆã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—をフック\n"
+
+#, python-format
+msgid "could not start server: %s"
+msgstr "サーãƒèµ·å‹•ãŒå¤±æ•—: %s"
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr "%r ã¸ã®å•ã„åˆã‚ã›ã«è¿”答中\n"
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr "äº’æ›æ€§ã®ç„¡ã„クライアントãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ã‹ã‚‰ã®å•ã„åˆã‚ã›ã‚’å—ä¿¡\n"
+
+#, python-format
+msgid "unrecognized query type: %s\n"
+msgstr "未知ã®å•ã„åˆã‚ã›ç¨®åˆ¥: %s\n"
+
+msgid "finished setup\n"
+msgstr "セットアップを終了ã—ã¾ã—ãŸ\n"
+
+msgid ""
+"expand expressions into changelog and summaries\n"
+"\n"
+"This extension allows the use of a special syntax in summaries,\n"
+"which will be automatically expanded into links or any other\n"
+"arbitrary expression, much like InterWiki does.\n"
+"\n"
+"A few example patterns (link to bug tracking, etc.) that may\n"
+"be used in your hgrc:\n"
+"\n"
+" [interhg]\n"
+" issues = s!issue(\\d+)!<a href=\"http://bts/issue\\1\">issue\\1</a>!\n"
+" bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2\">\\1</a>!"
+"i\n"
+" boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!\n"
+msgstr ""
+"コミットログ中ã®è¨˜è¿°ã®å±•é–‹\n"
+"\n"
+"本エクステンションã¯ã€ãƒªãƒ³ã‚¯ãªã‚Šä»»æ„ã®å¼ã®å½¢å¼ã¸ã¨è‡ªå‹•çš„ã«å¤‰æ›ã•れる\n"
+"InterWiki ã®ã‚ˆã†ãªç‰¹åˆ¥ãªæ›¸å¼ã‚’用ã„ãŸã‚³ãƒŸãƒƒãƒˆãƒ­ã‚°ã®è¨˜è¿°ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚\n"
+"\n"
+"ãƒã‚°ç®¡ç†ã‚·ã‚¹ãƒ†ãƒ ã§ä½¿ç”¨ã•れるよã†ãªãƒ‘ターンを設定ファイルã§è¨˜è¿°ã™ã‚‹ä¾‹ã‚’\n"
+"以下ã«ç¤ºã—ã¾ã™ã€‚\n"
+"\n"
+" [interhg]\n"
+" issues = s!issue(\\d+)!<a href=\"http://bts/issue\\1\">issue\\1</a>!\n"
+" bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2\">\\1</a>!"
+"i\n"
+" boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!\n"
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr "interhg: %s ã®ãƒ‘ターンãŒä¸æ­£ã§ã™: %s\n"
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr "interhg: %s ã®æ­£è¦è¡¨ç¾ãŒä¸æ­£ã§ã™: %s\n"
+
+msgid ""
+"expand keywords in tracked files\n"
+"\n"
+"This extension expands RCS/CVS-like or self-customized $Keywords$ in\n"
+"tracked text files selected by your configuration.\n"
+"\n"
+"Keywords are only expanded in local repositories and not stored in the\n"
+"change history. The mechanism can be regarded as a convenience for the\n"
+"current user or for archive distribution.\n"
+"\n"
+"Configuration is done in the [keyword] and [keywordmaps] sections of\n"
+"hgrc files.\n"
+"\n"
+"Example:\n"
+"\n"
+" [keyword]\n"
+" # expand keywords in every python file except those matching \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Note: the more specific you are in your filename patterns\n"
+" the less you lose speed in huge repositories.\n"
+"\n"
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run \"hg kwdemo\".\n"
+"\n"
+"An additional date template filter {date|utcdate} is provided.\n"
+"\n"
+"The default template mappings (view with \"hg kwdemo -d\") can be\n"
+"replaced with customized keywords and templates. Again, run \"hg\n"
+"kwdemo\" to control the results of your config changes.\n"
+"\n"
+"Before changing/disabling active keywords, run \"hg kwshrink\" to avoid\n"
+"the risk of inadvertently storing expanded keywords in the change\n"
+"history.\n"
+"\n"
+"To force expansion after enabling it, or a configuration change, run\n"
+"\"hg kwexpand\".\n"
+"\n"
+"Also, when committing with the record extension or using mq's qrecord,\n"
+"be aware that keywords cannot be updated. Again, run \"hg kwexpand\" on\n"
+"the files in question to update keyword expansions after all changes\n"
+"have been checked in.\n"
+"\n"
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map\n"
+"\"Log = {desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+"æ§‹æˆç®¡ç†å¯¾è±¡ãƒ•ァイル中ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å±•é–‹\n"
+"\n"
+"本エクステンションã¯ã€æ§‹æˆç®¡ç†å¯¾è±¡ãƒ•ァイル中㮠RCS/CVS çš„(カスタマイズ\n"
+"å¯èƒ½)㪠$Keywords$ ã‚’ã€è¨­å®šãƒ•ァイルã§ã®è¨˜è¿°ã«å¾“ã„展開ã—ã¾ã™ã€‚\n"
+"\n"
+"キーワード展開ã¯ä½œæ¥­é ˜åŸŸã§ã®ã¿è¡Œã‚れã€å±¥æ­´ã«ã¯æ®‹ã‚Šã¾ã›ã‚“。ã“ã®ä»•組ã¿ã¯\n"
+"ç¾è¡Œãƒ¦ãƒ¼ã‚¶ã‚„アーカイブé…布者ã«é…æ…®ã—ã¦ã„ã¾ã™ã€‚\n"
+"\n"
+"設定ã¯ã€è¨­å®šãƒ•ァイル中㮠[keyword] ãŠã‚ˆã³ [keywordmaps] セクションã«\n"
+"記述ã—ã¾ã™ã€‚\n"
+"\n"
+"記述例:\n"
+"\n"
+" [keyword]\n"
+" # \"x*\" ã«åˆè‡´ã€Œã—ãªã„〠python ファイルã§ã®ã¿ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å±•é–‹\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"備考: ファイルåãƒ‘ã‚¿ãƒ¼ãƒ³ãŒæ›´ã«ç‰¹æ®Šã«ãªã‚‹å ´åˆã€\n"
+" リãƒã‚¸ãƒˆãƒªã‚µã‚¤ã‚ºæ¬¡ç¬¬ã§ã¯æ€§èƒ½åŠ£åŒ–ãŒç”Ÿã˜å¾—ã¾ã™ã€‚\n"
+"\n"
+"[keywordmaps] ã§ã®ãƒ†ãƒ³ãƒ—レート設定ã®å±•開を実演ã™ã‚‹ã«ã¯ã€'hg kwdemo' ã‚’\n"
+"実行ã—ã¾ã™ã€‚\n"
+"\n"
+"日付テンプレート用フィルタã¨ã—㦠{date|utcdate} も使用å¯èƒ½ã§ã™ã€‚\n"
+"\n"
+"無指定時ã®ãƒ†ãƒ³ãƒ—レート設定('hg kwdemo -d' ã§é–²è¦§å¯èƒ½)ã¯ã€ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰åŠã³\n"
+"テンプレートã®ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºã§ç½®ãæ›ãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚繰り返ã—ã¾ã™ãŒ\n"
+"設定変更ã®ç¢ºèªã¯ 'hg kwdemo' ã§è¡Œã†ã“ã¨ãŒã§ãã¾ã™ã€‚\n"
+"\n"
+"展開済ã¿ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãŒæ„図ã›ãšå±¥æ­´ã«è¨˜éŒ²ã•れã¦ã—ã¾ã†ã“ã¨ã‚’防ããŸã‚ã«ã€\n"
+"キーワードã®è¨­å®šå¤‰æ›´/無効化ã®å‰ã«ã¯ 'hg kwshrink' を実行ã—ã¦ãã ã•ã„。\n"
+"\n"
+"キーワードã®è¨­å®šå¤‰æ›´/有効化後ã«ã€å¼·åˆ¶çš„ã«å±•é–‹ã™ã‚‹å ´åˆã¯ 'hg kwexpand'\n"
+"を実行ã—ã¦ãã ã•ã„。\n"
+"\n"
+"record エクステンション併用時㫠qrecord コマンドを使用ã—ã¦ã‚³ãƒŸãƒƒãƒˆã™ã‚‹\n"
+"å ´åˆã€ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã¯æ›´æ–°ã•れãªã„ç‚¹ã«æ³¨æ„ã—ã¦ãã ã•ã„。全ã¦ã®å¤‰æ›´å†…容を\n"
+"確èªã—ãŸä¸Šã§ã€å½“該ファイルã«å¯¾ã—㦠'hg kwexpand' を実行ã™ã‚‹ã“ã¨ã§\n"
+"キーワード展開を行ã£ã¦ãã ã•ã„。\n"
+"\n"
+"è¤‡æ•°è¡Œã«æ¸¡ã‚‹å±•é–‹ã‚„ã€CVS ã® $Log$ ã®ã‚ˆã†ãªå¢—加ã™ã‚‹å†…容ã®å±•é–‹ã¯ã‚µãƒãƒ¼ãƒˆ\n"
+"ã—ã¦ã„ã¾ã›ã‚“。キーワードテンプレート設定 \"Log = {desc}\" ã¯ã€\n"
+"ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®æœ€åˆã®ä¸€è¡Œã‚’埋ã‚è¾¼ã¿ã¾ã™ã€‚\n"
+
+#, python-format
+msgid "overwriting %s expanding keywords\n"
+msgstr "キーワード置æ›ã§ %s を上書ã\n"
+
+#, python-format
+msgid "overwriting %s shrinking keywords\n"
+msgstr "キーワード置æ›ã§ %s を上書ã\n"
+
+msgid "[keyword] patterns cannot match"
+msgstr "[keyword] パターンãŒåˆè‡´ã—ã¾ã›ã‚“"
+
+msgid "no [keyword] patterns configured"
+msgstr "[keyword] ã§ã®ãƒ‘ターン設定ãŒã‚りã¾ã›ã‚“"
+
+msgid ""
+"print [keywordmaps] configuration and an expansion example\n"
+"\n"
+" Show current, custom, or default keyword template maps and their\n"
+" expansions.\n"
+"\n"
+" Extend current configuration by specifying maps as arguments and\n"
+" optionally by reading from an additional hgrc file.\n"
+"\n"
+" Override current keyword template maps with \"default\" option.\n"
+" "
+msgstr ""
+"[keywordmaps] ã§ã®è¨­å®šå†…容ãŠã‚ˆã³å±•開例ã®è¡¨ç¤º\n"
+"\n"
+" ç¾æ™‚点ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãƒ†ãƒ³ãƒ—レートã®è¨­å®šå†…容ãŠã‚ˆã³å±•開例を表示ã—ã¾ã™ã€‚\n"
+"\n"
+" 引数ã§ã®ãƒžãƒƒãƒ—指定やã€è¨­å®šãƒ•ァイルã‹ã‚‰ã®ä»˜åŠ çš„ãªèª­ã¿è¾¼ã¿ã«ã‚ˆã‚Šã€\n"
+" ç¾æ™‚点ã§ã®è¨­å®šã‚’æ‹¡å¼µã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n"
+"\n"
+" --default 指定ã«ã‚ˆã‚Šã€ç¾æ™‚点ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãƒ†ãƒ³ãƒ—レート設定を\n"
+" デフォルトã®ã‚‚ã®ã§ä¸€æ™‚çš„ã«ç½®ãæ›ãˆã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚\n"
+" "
+
+#, python-format
+msgid "creating temporary repository at %s\n"
+msgstr "一時リãƒã‚¸ãƒˆãƒª %s ã®ä½œæˆä¸­\n"
+
+#, python-format
+msgid ""
+"\n"
+"\tconfig using %s keyword template maps\n"
+msgstr ""
+"\n"
+"\t%s をキーワードã®ãƒ†ãƒ³ãƒ—レートマップã¨ã—ã¦ä½¿ç”¨\n"
+
+#, python-format
+msgid ""
+"\n"
+"%s keywords written to %s:\n"
+msgstr ""
+"\n"
+"%sキーワードを %s ã«æ›¸ãè¾¼ã¿ã¾ã—ãŸ:\n"
+
+msgid "unhooked all commit hooks\n"
+msgstr "å…¨ã¦ã® commit フックを無効化\n"
+
+#, python-format
+msgid ""
+"\n"
+"\t%s keywords expanded%s\n"
+msgstr ""
+"\n"
+"%s キーワードを展開: %s\n"
+
+#, python-format
+msgid ""
+"\n"
+"removing temporary repository %s\n"
+msgstr ""
+"\n"
+"一時リãƒã‚¸ãƒˆãƒª %s ã®å‰Šé™¤ä¸­\n"
+
+msgid ""
+"expand keywords in the working directory\n"
+"\n"
+" Run after (re)enabling keyword expansion.\n"
+"\n"
+" kwexpand refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+"作業領域ã«ãŠã‘るキーワードã®å±•é–‹\n"
+"\n"
+" キーワード埋ã‚è¾¼ã¿ãŒ(å†)有効化ã•れã¦ã‹ã‚‰å®Ÿè¡Œã—ã¦ãã ã•ã„。\n"
+"\n"
+" 指定ã•れãŸãƒ•ã‚¡ã‚¤ãƒ«ã«æœªã‚³ãƒŸãƒƒãƒˆå¤‰æ›´ãŒã‚ã‚‹å ´åˆã€å®Ÿè¡Œã¯ä¸­æ–­ã•れã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"show files configured for keyword expansion\n"
+"\n"
+" List which files in the working directory are matched by the\n"
+" [keyword] configuration patterns.\n"
+"\n"
+" Useful to prevent inadvertent keyword expansion and to speed up\n"
+" execution by including only files that are actual candidates\n"
+" for expansion.\n"
+"\n"
+" See \"hg help keyword\" on how to construct patterns both for\n"
+" inclusion and exclusion of files.\n"
+"\n"
+" Use -u/--untracked to list untracked files as well.\n"
+"\n"
+" With -a/--all and -v/--verbose the codes used to show the status\n"
+" of files are:\n"
+" K = keyword expansion candidate\n"
+" k = keyword expansion candidate (untracked)\n"
+" I = ignored\n"
+" i = ignored (untracked)\n"
+" "
+msgstr ""
+"キーワード展開設定ã®ã‚るファイルã®è¡¨ç¤º\n"
+"\n"
+" 作業領域中ã®ãƒ•ァイルã§ã€[keyword] 設定ã§ã®ãƒ‘ターンã«åˆè‡´ã™ã‚‹\n"
+" ファイルã®ä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n"
+"\n"
+" 予期ã›ã¬ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å±•é–‹ã®é˜²æ­¢ã¨ã€å®Ÿè¡Œæ€§èƒ½å‘上ã®ãŸã‚ã«ã€å®Ÿéš›ã®\n"
+" 埋ã‚è¾¼ã¿å¯¾è±¡ã¨ãªã‚‹ãƒ•ァイルã®ã¿ã‚’設定ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚\n"
+"\n"
+" パターンåˆè‡´ã«é–¢ã™ã‚‹è©³ç´°ã¯ã€'hg help keyword' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" -u/--untracked 指定ã®ã‚ã‚‹å ´åˆã€æ§‹æˆç®¡ç†å¯¾è±¡å¤–ã®ãƒ•ァイルも列挙\n"
+" ã•れã¾ã™ã€‚\n"
+"\n"
+" -a/--all ãŠã‚ˆã³ -v/--verbose 指定ã®ã‚ã‚‹å ´åˆã€å„ファイルã®çжæ³ã¯\n"
+" 以下ã®è¨˜å·ã§è¡¨ç¾ã•れã¾ã™ã€‚\n"
+"\n"
+" K = キーワード展開候補\n"
+" k = キーワード展開候補(æ§‹æˆç®¡ç†å¯¾è±¡å¤–)\n"
+" I = 無視\n"
+" i = 無視(æ§‹æˆç®¡ç†å¯¾è±¡å¤–)\n"
+" "
+
+msgid ""
+"revert expanded keywords in the working directory\n"
+"\n"
+" Run before changing/disabling active keywords or if you experience\n"
+" problems with \"hg import\" or \"hg merge\".\n"
+"\n"
+" kwshrink refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+"作業領域中ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å±•é–‹ã®å–り消ã—\n"
+"\n"
+" キーワード設定ã®å¤‰æ›´å‰ã‚„ã€'hg import' ãªã„ã— 'hg merge' ã§å•題ãŒ\n"
+" 発生ã—ãŸçµŒé¨“ãŒã‚ã‚‹å ´åˆã«å®Ÿè¡Œã—ã¦ãã ã•ã„。\n"
+"\n"
+" 指定ã•れãŸãƒ•ã‚¡ã‚¤ãƒ«ã«æœªã‚³ãƒŸãƒƒãƒˆå¤‰æ›´ãŒã‚ã‚‹å ´åˆã€å®Ÿè¡Œã¯ä¸­æ–­ã•れã¾ã™ã€‚\n"
+" "
+
+msgid "show default keyword template maps"
+msgstr "デフォルトã®ãƒ†ãƒ³ãƒ—レートマップã§è¡¨ç¤º"
+
+msgid "read maps from rcfile"
+msgstr "設定ファイルã‹ã‚‰ã®ãƒžãƒƒãƒ—設定ã®èª­ã¿è¾¼ã¿"
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr "hg kwexpand [OPTION]... [FILE]..."
+
+msgid "show keyword status flags of all files"
+msgstr "全ファイルã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å±•開設定を表示"
+
+msgid "show files excluded from expansion"
+msgstr "キーワード展開対象外ã®ãƒ•ァイルを表示"
+
+msgid "additionally show untracked files"
+msgstr "未登録ファイルã®è¡¨ç¤º"
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr "hg kwfiles [OPTION]... [FILE]..."
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr "hg kwshrink [OPTION]... [FILE]..."
+
+msgid ""
+"manage a stack of patches\n"
+"\n"
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches).\n"
+"\n"
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets.\n"
+"\n"
+"Common tasks (use \"hg help command\" for more details):\n"
+"\n"
+"prepare repository to work with patches qinit\n"
+"create new patch qnew\n"
+"import existing patch qimport\n"
+"\n"
+"print patch series qseries\n"
+"print applied patches qapplied\n"
+"print name of top applied patch qtop\n"
+"\n"
+"add known patch to applied stack qpush\n"
+"remove patch from applied stack qpop\n"
+"refresh contents of top applied patch qrefresh\n"
+msgstr ""
+"パッãƒä½µç”¨ã®ç®¡ç†\n"
+"\n"
+"本エクステンションã¯ã€Mercurial リãƒã‚¸ãƒˆãƒªã®ä½œæ¥­é ˜åŸŸã«ãŠã„ã¦ã€ãƒ‘ッãƒã‚’\n"
+"併用ã—ãŸä½œæ¥­ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚本エクステンションã§ã¯ã€ã€Œæ—¢çŸ¥ã®ãƒ‘ッãƒã€ã¨\n"
+"「é©ç”¨ä¸­ã®ãƒ‘ッãƒã€(「既知ã®ãƒ‘ッãƒã€ã®éƒ¨åˆ†é›†åˆ)ã®2ã¤ã®é›†åˆã‚’ã€ã‚¹ã‚¿ãƒƒã‚¯\n"
+"を用ã„ã¦ç®¡ç†ã—ã¾ã™ã€‚\n"
+"\n"
+"「既知ã®ãƒ‘ッãƒã€ã¯ã€.hg/patches ディレクトリé…下ã«ç½®ã‹ã‚ŒãŸãƒ‘ッãƒãƒ•ァイル\n"
+"ã«ç›¸å½“ã—ã¾ã™ã€‚「é©ç”¨ä¸­ã®ãƒ‘ッãƒã€ã¯ã€ã€Œæ—¢çŸ¥ã®ãƒ‘ッãƒã€ã®ã†ã¡ã€å¯¾å¿œã™ã‚‹\n"
+"リビジョンãŒãƒªãƒã‚¸ãƒˆãƒªã®å±¥æ­´ã«(一時的ã«)記録ã•れã¦ã„ã‚‹ã‚‚ã®ã‚’指ã—ã¾ã™ã€‚\n"
+"\n"
+"良ã使用ã•れる機能(詳細㯠\"hg help コマンドå\" ã‚’å‚ç…§):\n"
+"\n"
+" パッãƒç®¡ç†é ˜åŸŸã®åˆæœŸåŒ– qinit\n"
+" æ–°è¦ãƒ‘ッãƒã®ä½œæˆ qnew\n"
+" 外部ã‹ã‚‰ã®ãƒ‘ッãƒãƒ•ァイルã®å–り込㿠qimport\n"
+"\n"
+" 既知ã®ãƒ‘ッãƒä¸€è¦§ã®è¡¨ç¤º qseries\n"
+" é©ç”¨ä¸­ã®ãƒ‘ッãƒä¸€è¦§ã®è¡¨ç¤º qapplied\n"
+" é©ç”¨ä¸­ã®æœ€ä¸Šä½ãƒ‘ッãƒåã®è¡¨ç¤º qtop\n"
+"\n"
+" 既知ã®ãƒ‘ッãƒã®é©ç”¨ qpush\n"
+" パッãƒé©ç”¨ã®è§£é™¤ qpop\n"
+" é©ç”¨ä¸­ã®æœ€ä¸Šä½ãƒ‘ッãƒã®å†…容更新 qrefresh\n"
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr "%s 㯠%s 中ã«è¤‡æ•°å›žç™»å ´ã—ã¦ã„ã¾ã™"
+
+msgid "guard cannot be an empty string"
+msgstr "ガードã«ç©ºæ–‡å­—列を指定ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr "ガード %r ã®å†’頭文字ã¯ä¸é©åˆ‡ãªæ–‡å­—ã§ã™: %r"
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr "ガード %r 中ã«ä¸é©åˆ‡ãªæ–‡å­—ãŒã‚りã¾ã™: %r"
+
+#, python-format
+msgid "active guards: %s\n"
+msgstr "有効ãªã‚¬ãƒ¼ãƒ‰: %s\n"
+
+#, python-format
+msgid "guard %r too short"
+msgstr "ガードå %r ã¯çŸ­éŽãŽã¾ã™"
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr "ガード %r ã®å†’頭文字ã¯ä¸é©åˆ‡ãªæ–‡å­—ã§ã™"
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr "%s ã‚’é©ç”¨ - åˆè‡´ã™ã‚‹ã‚¬ãƒ¼ãƒ‰ã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr "%s ã‚’é©ç”¨ - åˆè‡´ã™ã‚‹ãƒã‚¬ãƒ†ã‚£ãƒ–ガードã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr "%s ã‚’é©ç”¨ - ガード %r ãŒé©ç”¨ã•れã¾ã—ãŸ\n"
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr "%s を抑止 - ガード %r ãŒé©ç”¨ã•れã¾ã—ãŸ\n"
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr "%s を抑止 - åˆè‡´ã™ã‚‹ã‚¬ãƒ¼ãƒ‰ã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr "å–ã‚Šæ¶ˆã—æƒ…å ±ã®ç ´æ£„ã«å¤±æ•—: %s\n"
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr "パッム%s ã®é©ç”¨ã«å¤±æ•—"
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr "パッム%s ãŒé©ç”¨ã§ããªã„ã®ã§ãƒžãƒ¼ã‚¸å®Ÿæ–½ä¸­\n"
+
+#, python-format
+msgid "update returned %d"
+msgstr "ä½œæ¥­é ˜åŸŸã®æ›´æ–°ãŒã‚¨ãƒ©ãƒ¼ %d ã§çµ‚了ã—ã¾ã—ãŸ"
+
+msgid "repo commit failed"
+msgstr "リãƒã‚¸ãƒˆãƒªã®ã‚³ãƒŸãƒƒãƒˆæ“作ã«å¤±æ•—"
+
+#, python-format
+msgid "unable to read %s"
+msgstr "ファイル %s ãŒèª­ã¿è¾¼ã‚ã¾ã›ã‚“"
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr "パッム%s ã¯å­˜åœ¨ã—ã¾ã›ã‚“\n"
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr "パッム%s ã¯æœªé©ç”¨ã§ã™\n"
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr "パッãƒé©ç”¨ã®å¤±æ•—ã®ãŸã‚処ç†ãŒç¶™ç¶šã§ãã¾ã›ã‚“(-v 付ã実行ã§è©³ç´°è¡¨ç¤º)\n"
+
+#, python-format
+msgid "applying %s\n"
+msgstr "%s ã‚’é©ç”¨ä¸­\n"
+
+#, python-format
+msgid "unable to read %s\n"
+msgstr "ファイル %s ãŒèª­ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#, python-format
+msgid "imported patch %s\n"
+msgstr "パッム%s ã®å–り込ã¿\n"
+
+#, python-format
+msgid ""
+"\n"
+"imported patch %s"
+msgstr ""
+"\n"
+"パッム%s ã®å–り込ã¿"
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr "パッム%s ã¯ç©ºã§ã™\n"
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr "パッãƒé©ç”¨ãŒå¤±æ•—ã—ã€å´ä¸‹å·®åˆ†ã¯ä½œæ¥­é ˜åŸŸã«æ®‹ã•れã¦ã„ã¾ã™\n"
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr "パッãƒãŒæ›–昧ãªãŸã‚ã€é©ç”¨ã‚’中止\n"
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr "リビジョン %d 㯠MQ 管ç†ä¸‹ã«ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr "é©ç”¨ä¸­ã®æœ€ä¸‹ä½ãƒ‘ッãƒã‹ã‚‰é€£ç¶šã—ã¦ã„ãªã„リビジョン %d ã¯å‰Šé™¤ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "patch %s finalized without changeset message\n"
+msgstr "パッム%s をメッセージ無ã—ã§é€šå¸¸ãƒªãƒ“ジョン化ã—ã¾ã—ãŸ\n"
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr "qdelete ã«ã¯æœ€ä½Ž1ã¤ã®ãƒªãƒ“ジョン(åˆã¯ãƒ‘ッãƒå)指定ãŒå¿…è¦ã§ã™"
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr "é©ç”¨ä¸­ã®ãƒ‘ッム%s ã¯å‰Šé™¤ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr "パッム%s ã¯æœªçŸ¥ã®ãƒ‘ッãƒã§ã™"
+
+msgid "no patches applied"
+msgstr "é©ç”¨ä¸­ã®ãƒ‘ッãƒã¯ã‚りã¾ã›ã‚“"
+
+msgid "working directory revision is not qtip"
+msgstr "作業領域ã®è¦ªãƒªãƒ“ジョン㯠qtip ã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "local changes found, refresh first"
+msgstr "作業領域ã®å†…容ã¯å¤‰æ›´ã•れã¦ã„ã¾ã™ã®ã§ qrefresh を実施ã—ã¦ãã ã•ã„"
+
+msgid "local changes found"
+msgstr "作業領域ã®å†…容ã¯å¤‰æ›´ã•れã¦ã„ã¾ã™"
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr "\"%s\" ã¯ãƒ‘ッãƒåã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr "パッム\"%s\" ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr "%s ã® unlink ã«å¤±æ•—\n"
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr "パッãƒå \"%s\" ã¯æ›–昧ã§ã™:\n"
+
+#, python-format
+msgid "patch %s not in series"
+msgstr "パッム%s ã¯æœªçŸ¥ã®ãƒ‘ッãƒã§ã™"
+
+msgid "(working directory not at a head)\n"
+msgstr "(作業領域ã®è¦ªãƒªãƒ“ジョンã¯ãƒ˜ãƒƒãƒ‰ã§ã¯ã‚りã¾ã›ã‚“)\n"
+
+msgid "no patches in series\n"
+msgstr "既知ã®ãƒ‘ッãƒã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr "é©ç”¨ä¸­ã®ãƒ‘ッム%s ã®å†é©ç”¨ã¯ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr "qpush: パッム%s ã¯æ—¢ã«é©ç”¨ä¸­ã®æœ€ä¸Šä½ãƒ‘ッãƒã§ã™\n"
+
+#, python-format
+msgid "guarded by %r"
+msgstr "ガード %r ãŒé©ç”¨ã•れã¾ã—ãŸ"
+
+msgid "no matching guards"
+msgstr "åˆè‡´ã™ã‚‹ã‚¬ãƒ¼ãƒ‰ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr "パッム'%s' ã¯é©ç”¨ã§ãã¾ã›ã‚“ã§ã—㟠- %s\n"
+
+msgid "all patches are currently applied\n"
+msgstr "å…¨ã¦ã®ãƒ‘ッãƒãŒé©ç”¨ä¸­ã§ã™\n"
+
+msgid "patch series already fully applied\n"
+msgstr "å…¨ã¦ã®ãƒ‘ッãƒãŒé©ç”¨ä¸­ã§ã™\n"
+
+msgid "cleaning up working directory..."
+msgstr "ä½œæ¥­é ˜åŸŸã®æ•´ç†ä¸­..."
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr "é©ç”¨ãŒå¤±æ•—ã—ãŸãŸã‚ã€å¯¾å‡¦å¾Œã« %s ã¸ã® qrefresh を実施ã—ã¦ãã ã•ã„\n"
+
+#, python-format
+msgid "now at: %s\n"
+msgstr "é©ç”¨ä¸­ã®æœ€ä¸Šä½ãƒ‘ッãƒã¯ %s ã§ã™\n"
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr "パッム%s ã¯æœªé©ç”¨ã§ã™"
+
+msgid "no patches applied\n"
+msgstr "é©ç”¨ä¸­ã®ãƒ‘ッãƒã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr "qpop: パッム%s ã¯æ—¢ã«é©ç”¨ä¸­ã®æœ€ä¸Šä½ãƒ‘ッãƒã§ã™\n"
+
+msgid "qpop: forcing dirstate update\n"
+msgstr "qpop: ä½œæ¥­é ˜åŸŸçŠ¶æ…‹ã®æ›´æ–°ã‚’強行ã—ã¾ã™\n"
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr "未知ã®ãƒªãƒ“ジョン %s ãŒè§£é™¤å¯¾è±¡ã«æŒ‡å®šã•れã¾ã—ãŸ"
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr "管ç†å¯¾è±¡å¤–ã®ãƒªãƒ“ジョンãŒè§£é™¤å¯¾è±¡ã«æŒ‡å®šã•れã¾ã—ãŸ"
+
+msgid "deletions found between repo revs"
+msgstr "リビジョン間ã§å‰Šé™¤ãŒæ¤œå‡ºã•れã¾ã—ãŸ"
+
+msgid "patch queue now empty\n"
+msgstr "å…¨ã¦ã®ãƒ‘ッãƒã®é©ç”¨ãŒè§£é™¤ã•れã¾ã—ãŸ\n"
+
+msgid "cannot refresh a revision with children"
+msgstr "ヘッド以外㯠qrefresh ã®å¯¾è±¡ã«æŒ‡å®šã§ãã¾ã›ã‚“"
+
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to "
+"recover)\n"
+msgstr "パッãƒè§£é™¤ä¸­ã«ä¸­æ–­ã•れã¾ã—ãŸ!(revert --all ãŠã‚ˆã³ qpush ã§å¾©æ—§)\n"
+
+msgid "patch queue directory already exists"
+msgstr "パッãƒç®¡ç†é ˜åŸŸã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr "パッム%s ã¯æœªçŸ¥ã®ãƒ‘ッãƒã§ã™"
+
+msgid "No saved patch data found\n"
+msgstr "ä¿å­˜ã•れãŸãƒ‘ッãƒçŠ¶æ…‹ãƒ‡ãƒ¼ã‚¿ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n"
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr "パッãƒçŠ¶æ…‹ %s ã®å¾©æ—§ä¸­\n"
+
+msgid "save entry has children, leaving it alone\n"
+msgstr "パッãƒçŠ¶æ…‹ä¿å­˜ãƒªãƒ“ジョンã¯ãƒ˜ãƒƒãƒ‰ã§ãªã„ã®ã§å‰Šé™¤ã§ãã¾ã›ã‚“\n"
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr "パッãƒçŠ¶æ…‹ä¿å­˜ãƒªãƒ“ジョン %s ã®å‰Šé™¤ä¸­\n"
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr "パッãƒçŠ¶æ…‹ä¿å­˜ãƒªãƒ“ジョンã®è¦ª: %s %s\n"
+
+msgid "queue directory updating\n"
+msgstr "パッãƒç®¡ç†é ˜åŸŸã®æ›´æ–°ä¸­\n"
+
+msgid "Unable to load queue repository\n"
+msgstr "パッãƒç®¡ç†é ˜åŸŸã‚’読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+msgid "save: no patches applied, exiting\n"
+msgstr "save: é©ç”¨ä¸­ã®ãƒ‘ッãƒãŒç„¡ã„ãŸã‚終了ã—ã¾ã™\n"
+
+msgid "status is already saved\n"
+msgstr "パッãƒçŠ¶æ…‹ã¯ä¿å­˜æ¸ˆã¿ã§ã™\n"
+
+msgid "hg patches saved state"
+msgstr "パッãƒçŠ¶æ…‹ä¿å­˜ç”¨ãƒªãƒ“ジョン"
+
+msgid "repo commit failed\n"
+msgstr "リãƒã‚¸ãƒˆãƒªã®ã‚³ãƒŸãƒƒãƒˆæ“作ã«å¤±æ•—\n"
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr "åŒåã®ãƒ‘ッム%s ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
+
+msgid "option \"-r\" not valid when importing files"
+msgstr "ファイルå–り込ã¿ã®éš›ã® \"-r\" 指定ã¯ä¸é©åˆ‡ã§ã™"
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr "複数パッãƒå–り込ã¿ã®éš›ã® \"-n\" 指定ã¯ä¸é©åˆ‡ã§ã™"
+
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr "リビジョン %d ã¯1ã¤ä»¥ä¸Šã®ãƒ–ランãƒã®åˆ†å²ç‚¹ã§ã™"
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr "リビジョン %d ã¯æ—¢ã« MQ 管ç†ä¸‹ã«ã‚りã¾ã™"
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr "リビジョン %d ã¯ãƒ‘ッãƒé©ç”¨ã®èµ·ç‚¹ã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr "リビジョン %d ã«ã¯ MQ 管ç†ä¸‹ã«ç„¡ã„å­ãƒªãƒ“ジョンãŒã‚りã¾ã™"
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr "マージ実施リビジョン %d ã¯å–り込ã‚ã¾ã›ã‚“"
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr "リビジョン %d ã¯ã€%d ã®è¦ªãƒªãƒ“ジョンã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "-e is incompatible with import from -"
+msgstr "標準入力(-)ã‹ã‚‰ã®å–り込ã¿ã®éš›ã® -e 指定ã¯ä¸é©åˆ‡ã§ã™"
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr "パッム%s ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+
+msgid "need --name to import a patch from -"
+msgstr "標準入力(-)ã‹ã‚‰ã®å–り込ã¿ã®éš›ã«ã¯ --name 指定ãŒå¿…è¦ã§ã™"
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr "パッム%s を追加中\n"
+
+msgid ""
+"remove patches from queue\n"
+"\n"
+" The patches must not be applied, and at least one patch is required. "
+"With\n"
+" -k/--keep, the patch files are preserved in the patch directory.\n"
+"\n"
+" To stop managing a patch and move it into permanent history,\n"
+" use the qfinish command."
+msgstr ""
+"管ç†å¯¾è±¡ã‹ã‚‰ã®ãƒ‘ッãƒé™¤å¤–\n"
+"\n"
+" 対象パッãƒã¯æœªé©ç”¨ã§ãªã‘れã°ãªã‚‰ãšã€æœ€ä½Ž1ã¤ã®ãƒ‘ッãƒåã®æŒ‡å®šãŒ\n"
+" å¿…è¦ã§ã™ã€‚-k/--keep を指定ã—ãŸå ´åˆã€ãƒ‘ッãƒãƒ•ァイルãã®ã‚‚ã®ã¯\n"
+" 管ç†é ˜åŸŸã«æ®‹ã•れãŸã¾ã¾ã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" 管ç†å¯¾è±¡å¤–ã¨ãªã£ãŸãƒ‘ッãƒã‚’通常リビジョン化ã™ã‚‹å ´åˆã¯ qfinish ã‚’\n"
+" 使用ã—ã¦ãã ã•ã„。"
+
+msgid "print the patches already applied"
+msgstr "é©ç”¨ä¸­ã®ãƒ‘ッãƒä¸€è¦§ã®è¡¨ç¤º"
+
+msgid "print the patches not yet applied"
+msgstr "未é©ç”¨ã®ãƒ‘ッãƒä¸€è¦§ã®è¡¨ç¤º"
+
+msgid ""
+"import a patch\n"
+"\n"
+" The patch is inserted into the series after the last applied\n"
+" patch. If no patches have been applied, qimport prepends the patch\n"
+" to the series.\n"
+"\n"
+" The patch will have the same name as its source file unless you\n"
+" give it a new one with -n/--name.\n"
+"\n"
+" You can register an existing patch inside the patch directory with\n"
+" the -e/--existing flag.\n"
+"\n"
+" With -f/--force, an existing patch of the same name will be\n"
+" overwritten.\n"
+"\n"
+" An existing changeset may be placed under mq control with -r/--rev\n"
+" (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+" With -g/--git, patches imported with --rev will use the git diff\n"
+" format. See the diffs help topic for information on why this is\n"
+" important for preserving rename/copy information and permission\n"
+" changes.\n"
+"\n"
+" To import a patch from standard input, pass - as the patch file.\n"
+" When importing from standard input, a patch name must be specified\n"
+" using the --name flag.\n"
+" "
+msgstr ""
+"パッãƒã®å–り込ã¿\n"
+"\n"
+" å–り込ã¾ã‚ŒãŸãƒ‘ッãƒã®é©ç”¨é †åºã¯ã€ç¾åœ¨é©ç”¨ä¸­ã®æœ€ä¸Šä½ãƒ‘ッãƒã®æ¬¡ã«\n"
+" ãªã‚Šã¾ã™ã€‚é©ç”¨ä¸­ã®ãƒ‘ッãƒãŒç„¡ã„å ´åˆã€å–り込ã¾ã‚ŒãŸãƒ‘ッãƒã®é©ç”¨é †åºã¯\n"
+" 一番最åˆã«ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" -n/--name ã«ã‚ˆã‚‹åå‰ã®æŒ‡å®šãŒç„¡ã„å ´åˆã€å–り込ã¿å¯¾è±¡ã®ãƒ•ァイルåãŒ\n"
+" ãã®ã¾ã¾ãƒ‘ッãƒåã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" -e/--existing を指定ã™ã‚‹ã“ã¨ã§ã€ãƒ‘ッãƒç®¡ç†é ˜åŸŸä¸­ã®æ—¢å­˜ãƒ•ァイルを\n"
+" å–り込ã¿å¯¾è±¡ã¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n"
+"\n"
+" -f/--force ãŒæŒ‡å®šã•れãŸå ´åˆã€åŒåã®æ—¢å­˜ãƒ‘ッãƒã‚’上書ãã—ã¾ã™ã€‚\n"
+"\n"
+" -r/--rev を指定ã™ã‚‹ã“ã¨ã§ã€æ—¢å­˜ã®é€šå¸¸ãƒªãƒ“ジョンを MQ 管ç†ä¸‹ã«ç½®ã\n"
+" ã“ã¨ãŒã§ãã¾ã™(例: 'qimport --rev tip -n patch' ã¯ã€tip ã‚’ MQ 管ç†\n"
+" 下ã«ç½®ãã¾ã™)。-g/--git 指定ã¯ã€--rev 指定ã«ã‚ˆã‚‹å–り込ã¿ã®éš›ã« git\n"
+" 差分形å¼ã‚’使用ã—ã¾ã™ã€‚改åï¼è¤‡è£½æƒ…å ±ã‚„ã€æ¨©é™è¨­å®šã®æƒ…å ±ä¿æŒã«ã¨ã£ã¦ã®\n"
+" git 差分形å¼ã®æœ‰ç”¨æ€§ã«é–¢ã—ã¦ã¯ã€'help diffs' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" 標準入力ã‹ã‚‰ãƒ‘ッãƒã‚’å–り込む場åˆã€ãƒ•ァイルåã« '-' を指定ã—ã¾ã™ã€‚\n"
+" 標準入力ã‹ã‚‰ã®å–り込ã¿ã®éš›ã«ã¯ã€--name ã§ã®ãƒ‘ッãƒå指定ãŒå¿…é ˆã§ã™ã€‚\n"
+" "
+
+msgid ""
+"init a new queue repository\n"
+"\n"
+" The queue repository is unversioned by default. If\n"
+" -c/--create-repo is specified, qinit will create a separate nested\n"
+" repository for patches (qinit -c may also be run later to convert\n"
+" an unversioned patch repository into a versioned one). You can use\n"
+" qcommit to commit changes to this queue repository."
+msgstr ""
+"パッãƒç®¡ç†é ˜åŸŸã®åˆæœŸåŒ–\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€ãƒ‘ッãƒç®¡ç†é ˜åŸŸã¯æ§‹æˆç®¡ç†ã•れã¾ã›ã‚“。\n"
+" -c/--create-repo ãŒæŒ‡å®šã•れãŸå ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒ‘ッãƒç®¡ç†é ˜åŸŸè‡ªä½“ã‚’\n"
+" Mercurial ã®ãƒªãƒã‚¸ãƒˆãƒªã¨ã—ã¦ä½œæˆã—ã¾ã™(既存ã®ãƒ‘ッãƒç®¡ç†é ˜åŸŸã‚’後ã‹ã‚‰\n"
+" Mercurial リãƒã‚¸ãƒˆãƒªåŒ–ã™ã‚‹ã®ã«ã‚‚使用ã§ãã¾ã™)。管ç†é ˜åŸŸã®å¤‰æ›´å†…容ã¯\n"
+" qcommit ã«ã‚ˆã£ã¦ã‚³ãƒŸãƒƒãƒˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+msgid ""
+"clone main and patch repository at same time\n"
+"\n"
+" If source is local, destination will have no patches applied. If\n"
+" source is remote, this command can not check if patches are\n"
+" applied in source, so cannot guarantee that patches are not\n"
+" applied in destination. If you clone remote repository, be sure\n"
+" before that it has no patches applied.\n"
+"\n"
+" Source patch repository is looked for in <src>/.hg/patches by\n"
+" default. Use -p <url> to change.\n"
+"\n"
+" The patch directory must be a nested Mercurial repository, as\n"
+" would be created by qinit -c.\n"
+" "
+msgstr ""
+"リãƒã‚¸ãƒˆãƒªã¨ãƒ‘ッãƒç®¡ç†é ˜åŸŸã®åŒæ™‚複製\n"
+"\n"
+" 複製元ãŒåŒä¸€ãƒ›ã‚¹ãƒˆä¸Šã«ã‚ã‚‹å ´åˆã€è¤‡è£½å…ˆãƒªãƒã‚¸ãƒˆãƒªã§ã¯ã€å…¨ã¦ã®ãƒ‘ッãƒãŒ\n"
+" 未é©ç”¨ãªçŠ¶æ…‹ã¨ãªã‚Šã¾ã™ã€‚複製元ãŒé éš”ホストã«ã‚ã‚‹å ´åˆã€è¤‡è£½å…ƒã§ã®\n"
+" パッãƒé©ç”¨çжæ³ãŒä¸æ˜Žãªã®ã§ã€è¤‡è£½å…ˆã§ã®ãƒ‘ッãƒé©ç”¨çжæ³ã¯æœªä¿è¨¼ã§ã™ã€‚\n"
+" é éš”ホスト上ã®ãƒªãƒã‚¸ãƒˆãƒªã‚’複製ã™ã‚‹å ´åˆã€ãƒ‘ッãƒãŒæœªé©ç”¨ã§ã‚ã‚‹ã“ã¨ã‚’\n"
+" 確èªã—ã¦ãã ã•ã„。\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€ãƒ‘ッãƒç®¡ç†é ˜åŸŸã¯ <src>/.hg/patches ã‹ã‚‰è¤‡è£½ã•れ\n"
+" ã¾ã™ã€‚変更ã™ã‚‹å ´åˆã¯ -p <url> を使用ã—ã¾ã™ã€‚\n"
+"\n"
+" パッãƒç®¡ç†é ˜åŸŸã¯ã€'qinit -c' ã«ã‚ˆã£ã¦ç”Ÿæˆã•れãŸã€å…¥ã‚Œå­ã«ãªã£ãŸ\n"
+" Mercurial リãƒã‚¸ãƒˆãƒªã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。\n"
+" "
+
+msgid "versioned patch repository not found (see qinit -c)"
+msgstr "æ§‹æˆç®¡ç†ã•れãŸãƒ‘ッãƒé ˜åŸŸãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“(qinit -c å‚ç…§)"
+
+msgid "cloning main repository\n"
+msgstr "主リãƒã‚¸ãƒˆãƒªã‚’複製中\n"
+
+msgid "cloning patch repository\n"
+msgstr "パッãƒç®¡ç†ãƒªãƒã‚¸ãƒˆãƒªã‚’複製中\n"
+
+msgid "stripping applied patches from destination repository\n"
+msgstr "複製先リãƒã‚¸ãƒˆãƒªã«ãŠã„ã¦ãƒ‘ッãƒé©ç”¨ã‚’解除中\n"
+
+msgid "updating destination repository\n"
+msgstr "複製先ã®ä½œæ¥­é ˜åŸŸã‚’更新中\n"
+
+msgid "commit changes in the queue repository"
+msgstr "パッãƒç®¡ç†é ˜åŸŸã®å¤‰æ›´ã‚’コミット"
+
+msgid "print the entire series file"
+msgstr "既知ã®ãƒ‘ッãƒä¸€è¦§ã®è¡¨ç¤º"
+
+msgid "print the name of the current patch"
+msgstr "ç¾è¡Œãƒ‘ッãƒã®åå‰è¡¨ç¤º"
+
+msgid "print the name of the next patch"
+msgstr "ç¾è¡Œãƒ‘ッãƒã®ã€Œæ¬¡ã€ã®æ—¢çŸ¥ã®ãƒ‘ッãƒã®åå‰è¡¨ç¤º"
+
+msgid "all patches applied\n"
+msgstr "å…¨ã¦ã®ãƒ‘ッãƒãŒé©ç”¨ä¸­ã§ã™\n"
+
+msgid "print the name of the previous patch"
+msgstr "ç¾è¡Œãƒ‘ッãƒã®ã€Œå‰ã€ã®æ—¢çŸ¥ã®ãƒ‘ッãƒã®åå‰è¡¨ç¤º"
+
+msgid "only one patch applied\n"
+msgstr "å˜ä¸€ã®ãƒ‘ッãƒã ã‘ãŒé©ç”¨ä¸­ã§ã™\n"
+
+msgid ""
+"create a new patch\n"
+"\n"
+" qnew creates a new patch on top of the currently-applied patch (if\n"
+" any). It will refuse to run if there are any outstanding changes\n"
+" unless -f/--force is specified, in which case the patch will be\n"
+" initialized with them. You may also use -I/--include,\n"
+" -X/--exclude, and/or a list of files after the patch name to add\n"
+" only changes to matching files to the new patch, leaving the rest\n"
+" as uncommitted modifications.\n"
+"\n"
+" -u/--user and -d/--date can be used to set the (given) user and\n"
+" date, respectively. -U/--currentuser and -D/--currentdate set user\n"
+" to current user and date to current date.\n"
+"\n"
+" -e/--edit, -m/--message or -l/--logfile set the patch header as\n"
+" well as the commit message. If none is specified, the header is\n"
+" empty and the commit message is '[mq]: PATCH'.\n"
+"\n"
+" Use the -g/--git option to keep the patch in the git extended diff\n"
+" format. Read the diffs help topic for more information on why this\n"
+" is important for preserving permission changes and copy/rename\n"
+" information.\n"
+" "
+msgstr ""
+"æ–°è¦ãƒ‘ッãƒã®ä½œæˆ\n"
+"\n"
+" 本コマンドã¯ã€(パッãƒé©ç”¨ä¸­ã®å ´åˆã¯)é©ç”¨ä¸­ãƒ‘ッãƒã®æœ€ä¸Šä½ã®ä½ç½®ã«\n"
+" æ–°è¦ãƒ‘ッãƒã‚’作æˆã—ã¾ã™ã€‚作業領域ã«å¤‰æ›´ãŒã‚ã‚‹å ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯å®Ÿè¡Œã‚’\n"
+" 中断ã—ã¾ã™ãŒã€-f/--force ãŒæŒ‡å®šã•れãŸå ´åˆã€ä½œæ¥­é ˜åŸŸä¸­ã®å¤‰æ›´ã‚’å–り\n"
+" è¾¼ã‚“ã§æ–°è¦ãƒ‘ッãƒãŒä½œæˆã•れã¾ã™ã€‚-I/--includeã€-X/--exclude ãŠã‚ˆã³\n"
+" ãƒ•ã‚¡ã‚¤ãƒ«åæŒ‡å®šã®çµ„ã¿åˆã‚ã›ã«ã‚ˆã£ã¦ã€å¤‰æ›´ã‚’æ–°è¦ãƒ‘ッãƒã«å–り込む\n"
+" ファイルãŒé™å®šã•れã€ãれ以外ã®ãƒ•ァイルã«å¯¾ã™ã‚‹å¤‰æ›´ã¯æœªã‚³ãƒŸãƒƒãƒˆãª\n"
+" 変更ã®ã¾ã¾ã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" -u/--user ãŠã‚ˆã³ -d/--date ã¯ã€ãれãžã‚ŒæŒ‡å®šã®ãƒ¦ãƒ¼ã‚¶åï¼æ—¥æ™‚ã®è¨˜éŒ²ã«\n"
+" 使用ã§ãã¾ã™ã€‚ -U/--currentuser ãŠã‚ˆã³ -D/--currendate ã¯ã€ãれãžã‚Œ\n"
+" ç¾ãƒ¦ãƒ¼ã‚¶åï¼ç¾åœ¨æ—¥æ™‚を記録ã—ã¾ã™ã€‚\n"
+"\n"
+" -e/--edit, -m/--message ãªã„ã— -l/--logfile ã¯ã€ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¨\n"
+" åŒæ§˜ã«ã€ãƒ‘ッãƒã®ãƒ˜ãƒƒãƒ€ã«è¨˜éŒ²ã™ã‚‹æƒ…報を指定ã—ã¾ã™ã€‚指定ãŒç„¡ã„å ´åˆã¯ã€\n"
+" ヘッダã¯ç©ºã®ã¾ã¾ã€ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒ '[mq]: パッãƒå' ã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" git 拡張差分形å¼ã‚’使用ã™ã‚‹å ´åˆã¯ã€-g/--git を指定ã—ã¾ã™ã€‚改åï¼è¤‡è£½\n"
+" æƒ…å ±ã‚„ã€æ¨©é™è¨­å®šã®æƒ…å ±ä¿æŒã«ã¨ã£ã¦ã® git 差分形å¼ã®æœ‰ç”¨æ€§ã«é–¢ã—ã¦ã¯ã€\n"
+" 'help diffs' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid ""
+"update the current patch\n"
+"\n"
+" If any file patterns are provided, the refreshed patch will\n"
+" contain only the modifications that match those patterns; the\n"
+" remaining modifications will remain in the working directory.\n"
+"\n"
+" If -s/--short is specified, files currently included in the patch\n"
+" will be refreshed just like matched files and remain in the patch.\n"
+"\n"
+" hg add/remove/copy/rename work as usual, though you might want to\n"
+" use git-style patches (-g/--git or [diff] git=1) to track copies\n"
+" and renames. See the diffs help topic for more information on the\n"
+" git diff format.\n"
+" "
+msgstr ""
+"ç¾è¡Œãƒ‘ッãƒã®æ›´æ–°\n"
+"\n"
+" 何らã‹ã®ãƒ‘ã‚¿ãƒ¼ãƒ³ãŒæŒ‡å®šã•れãŸå ´åˆã€æ›´æ–°å¾Œã®ãƒ‘ッãƒã¯å½“該パターンã«\n"
+" åˆè‡´ã™ã‚‹ãƒ•ァイルã®å¤‰æ›´å†…容ã ã‘ã‚’å«ã¿ã€ä»–ã®ãƒ•ァイルã®å¤‰æ›´å†…容ã¯ä½œæ¥­\n"
+" é ˜åŸŸã«æ®‹ã£ãŸã¾ã¾ã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" -s/--short ãŒæŒ‡å®šã•れãŸå ´åˆã€ç¾è¡Œãƒ‘ッãƒãŒå¤‰æ›´ã‚’ä¿æŒã™ã‚‹ãƒ•ァイルã®ã¿ãŒ\n"
+" パッãƒå†…容更新ã®å¯¾è±¡ã¨ãªã£ã¦ã€ãƒ‘ッãƒã«ã¨ã©ã¾ã‚Šç¶šã‘ã¾ã™ã€‚\n"
+"\n"
+" è¤‡è£½ï¼æ”¹åã«é–¢ã™ã‚‹å±¥æ­´ä¿å­˜ã®ãŸã‚ã« git 差分形å¼ã‚’使用(-g/--git 指定や\n"
+" 設定ファイルã§ã® [diff] git=1 記述)ã™ã‚‹ã®ã§ã‚れã°ã€\n"
+" add/remove/copy/rename ã¨ã„ã£ãŸ hg ã®ã‚³ãƒžãƒ³ãƒ‰ã«ã‚ˆã‚‹å±¥æ­´è¨˜éŒ²ã‚‚ã€\n"
+" 通常ã¨å¤‰ã‚りãªã機能ã—ã¾ã™ã€‚git 差分形å¼ã®è©³ç´°ã«é–¢ã—ã¦ã¯ã€\n"
+" 'help diffs' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr "\"-e\" ã¯ã€\"-m\" ãªã„ã— \"-l\" ã¨ä½µç”¨ã§ãã¾ã›ã‚“"
+
+msgid ""
+"diff of the current patch and subsequent modifications\n"
+"\n"
+" Shows a diff which includes the current patch as well as any\n"
+" changes which have been made in the working directory since the\n"
+" last refresh (thus showing what the current patch would become\n"
+" after a qrefresh).\n"
+"\n"
+" Use 'hg diff' if you only want to see the changes made since the\n"
+" last qrefresh, or 'hg export qtip' if you want to see changes made\n"
+" by the current patch without including changes made since the\n"
+" qrefresh.\n"
+" "
+msgstr ""
+"ç¾è¡Œãƒ‘ッãƒã¨ä½œæ¥­é ˜åŸŸå¤‰æ›´ã®çµåˆçµæžœã®è¡¨ç¤º\n"
+"\n"
+" ç¾è¡Œãƒ‘ッãƒã®å¤‰æ›´å†…容ã¨ã€å‰å›žã® qrefresh 実施以後ã®ä½œæ¥­é ˜åŸŸã«ãŠã‘ã‚‹\n"
+" 変更内容をåˆã‚ã›ãŸå·®åˆ†(ï¼ ç¾æ™‚点ã§ã® qrefresh 実施ã«ã‚ˆã‚‹ãƒ‘ッãƒå†…容ã®\n"
+" æ›´æ–°çµæžœ)を表示ã—ã¾ã™ã€‚\n"
+"\n"
+" å‰å›žã® qrefresh 実施以後ã®ä½œæ¥­é ˜åŸŸã«ãŠã‘る変更内容を見ãŸã„å ´åˆã¯\n"
+" 'hg diff' ã‚’ã€ä½œæ¥­é ˜åŸŸã®å¤‰æ›´å†…容をå«ã¾ãªã„ç¾è¡Œãƒ‘ッãƒã®å†…容ã®ã¿ã‚’\n"
+" 見ãŸã„å ´åˆã¯ 'hg export qtip' を使用ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid ""
+"fold the named patches into the current patch\n"
+"\n"
+" Patches must not yet be applied. Each patch will be successively\n"
+" applied to the current patch in the order given. If all the\n"
+" patches apply successfully, the current patch will be refreshed\n"
+" with the new cumulative patch, and the folded patches will be\n"
+" deleted. With -k/--keep, the folded patch files will not be\n"
+" removed afterwards.\n"
+"\n"
+" The header for each folded patch will be concatenated with the\n"
+" current patch header, separated by a line of '* * *'."
+msgstr ""
+"指定パッãƒã®ç¾è¡Œãƒ‘ッãƒã¸ã®çµ±åˆ\n"
+"\n"
+" 対象パッãƒã¯æœªé©ç”¨ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。ãれãžã‚Œã®ãƒ‘ッãƒã¯æŒ‡å®šã•れãŸ\n"
+" é †åºã§é€£ç¶šçš„ã«ç¾è¡Œãƒ‘ッãƒã«é©ç”¨ã•れã¾ã™ã€‚å…¨ã¦ã®é©ç”¨ãŒæˆåŠŸã—ãŸå ´åˆã¯ã€\n"
+" ç¾è¡Œãƒ‘ッãƒãŒå…¨ã¦ã®ãƒ‘ッãƒã®ç´¯ç©ã¨ã—ã¦æ›´æ–°ã•れã€çµ±åˆã•れãŸãƒ‘ッãƒã¯å‰Šé™¤\n"
+" ã•れã¾ã™ã€‚-k/--keep ãŒæŒ‡å®šã•れãŸå ´åˆã¯ã€çµ±åˆå®Ÿæ–½å¾Œã‚‚çµ±åˆã•れtパッãƒã®\n"
+" ãƒ•ã‚¡ã‚¤ãƒ«ã¯æ®‹ã•れã¾ã™ã€‚\n"
+"\n"
+" çµ±åˆå¯¾è±¡ãƒ‘ッãƒã®ãƒ˜ãƒƒãƒ€æƒ…å ±ã¯ã€'* * *' 行を区切り記å·ã¨ã—ã¦ã€ç¾è¡Œã®\n"
+" パッãƒã«è¿½åŠ ã•れã¾ã™ã€‚"
+
+msgid "qfold requires at least one patch name"
+msgstr "çµ±åˆå®Ÿæ–½ã«ã¯æœ€ä½Ž1ã¤ã®ãƒ‘ッãƒå指定ãŒå¿…è¦ã§ã™"
+
+msgid "No patches applied"
+msgstr "é©ç”¨ä¸­ã®ãƒ‘ッãƒã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "Skipping already folded patch %s"
+msgstr "æ—¢ã«çµ±åˆæ¸ˆã¿ã®ãƒ‘ッム%s ã¯ç„¡è¦–ã—ã¾ã™"
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr "パッム%s ã¯é©ç”¨ä¸­ãªã®ã§çµ±åˆã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "Error folding patch %s"
+msgstr "パッム%s ã®çµ±åˆã«å¤±æ•—"
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr "指定パッãƒã‚’é©ç”¨ãƒ‘ッãƒã®æœ€ä¸Šä½ã«ã™ã‚‹ qpush/qpop ã®å®Ÿæ–½"
+
+msgid ""
+"set or print guards for a patch\n"
+"\n"
+" Guards control whether a patch can be pushed. A patch with no\n"
+" guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+" pushed only if the qselect command has activated it. A patch with\n"
+" a negative guard (\"-foo\") is never pushed if the qselect command\n"
+" has activated it.\n"
+"\n"
+" With no arguments, print the currently active guards.\n"
+" With arguments, set guards for the named patch.\n"
+" NOTE: Specifying negative guards now requires '--'.\n"
+"\n"
+" To set guards on another patch:\n"
+" hg qguard -- other.patch +2.6.17 -stable\n"
+" "
+msgstr ""
+"パッãƒã®ã‚¬ãƒ¼ãƒ‰è¨­å®šãªã„ã—表示\n"
+"\n"
+" 「ガードã€ã¯ãƒ‘ッãƒé©ç”¨ã®å¯å¦ã‚’制御ã—ã¾ã™ã€‚ガードãŒè¨­å®šã•れã¦ã„ãªã„\n"
+" パッãƒã¯å¸¸ã«é©ç”¨ã•れã¾ã™ã€‚「正ã€ã®ã‚¬ãƒ¼ãƒ‰(例: \"+foo\")ãŒè¨­å®šã•れãŸ\n"
+" パッãƒã¯ã€qselect ã«ã‚ˆã£ã¦å½“該ガードãŒè¨­å®šã•れã¦ã„ã‚‹å ´åˆã«ã®ã¿é©ç”¨\n"
+" ã•れã¾ã™ã€‚「負ã€ã®ã‚¬ãƒ¼ãƒ‰(例: \"-foo\")ãŒè¨­å®šã•れã¦ã„るパッãƒã¯ã€\n"
+" qselect ã«ã‚ˆã£ã¦å½“該ガードãŒè¨­å®šã•れã¦ã„ã‚‹å ´åˆã«ã¯é©ç”¨ã•れã¾ã›ã‚“。\n"
+"\n"
+" 本コマンドãŒå¼•æ•°ç„¡ã—ã§å®Ÿè¡Œã•れãŸå ´åˆã€ç¾è¡Œã®ã‚¬ãƒ¼ãƒ‰è¨­å®šã‚’表示ã—ã¾ã™ã€‚\n"
+" 引数有りã§å®Ÿè¡Œã•れãŸå ´åˆã€æŒ‡å®šã®ãƒ‘ッãƒã«å¯¾ã™ã‚‹ã‚¬ãƒ¼ãƒ‰è¨­å®šã‚’行ã„ã¾ã™ã€‚\n"
+" 備考: è² ã®ã‚¬ãƒ¼ãƒ‰ã®è¨­å®šã«ã¯ '--' ãŒå¿…è¦ã§ã™ã€‚\n"
+"\n"
+" ç¾è¡Œãƒ‘ッãƒä»¥å¤–ã«ã‚¬ãƒ¼ãƒ‰ã‚’設定ã™ã‚‹ã«ã¯:\n"
+" hg qguard -- 対象パッãƒå +2.6.17 -stable\n"
+" "
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr "-l/--list ã¯ã€ä»–ã®ã‚ªãƒ—ションや引数ã¨åŒæ™‚ã«æŒ‡å®šã§ãã¾ã›ã‚“"
+
+msgid "no patch to work with"
+msgstr "対象ã¨ã™ã¹ãパッãƒãŒã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "no patch named %s"
+msgstr "パッム%s ã¯æœªçŸ¥ã®ãƒ‘ッãƒã§ã™"
+
+msgid "print the header of the topmost or specified patch"
+msgstr "ç¾è¡Œãƒ‘ッãƒãªã„ã—æŒ‡å®šãƒ‘ッãƒã®ãƒ˜ãƒƒãƒ€è¡¨ç¤º"
+
+msgid ""
+"push the next patch onto the stack\n"
+"\n"
+" When -f/--force is applied, all local changes in patched files\n"
+" will be lost.\n"
+" "
+msgstr ""
+"次ã®ãƒ‘ッãƒã®é©ç”¨\n"
+"\n"
+" -f/--force ãŒæŒ‡å®šã•れãŸå ´åˆã€ãƒ‘ッãƒé©ç”¨å¯¾è±¡ãƒ•ァイルã®ã€ä½œæ¥­é ˜åŸŸã«\n"
+" ãŠã‘る変更内容ã¯ç ´æ£„ã•れã¾ã™ã€‚\n"
+" "
+
+msgid "no saved queues found, please use -n\n"
+msgstr "ä¿å­˜ã•れãŸãƒ‘ッãƒç®¡ç†é ˜åŸŸãŒã‚りã¾ã›ã‚“。-n を使用ã—ã¦ãã ã•ã„\n"
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr "パッãƒç®¡ç†é ˜åŸŸ %s ã¨ãƒžãƒ¼ã‚¸ä¸­\n"
+
+msgid ""
+"pop the current patch off the stack\n"
+"\n"
+" By default, pops off the top of the patch stack. If given a patch\n"
+" name, keeps popping off patches until the named patch is at the\n"
+" top of the stack.\n"
+" "
+msgstr ""
+"ç¾è¡Œãƒ‘ッãƒã®é©ç”¨è§£é™¤\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€é©ç”¨ä¸­ã®æœ€ä¸Šä½ãƒ‘ッãƒã‚’解除ã—ã¾ã™ã€‚パッãƒåãŒæŒ‡å®š\n"
+" ã•れãŸå ´åˆã€å½“該パッãƒãŒé©ç”¨ä¸­ã®æœ€ä¸Šä½ãƒ‘ッãƒã«ãªã‚‹ã¾ã§ã€ä»–ã®ãƒ‘ッãƒã®\n"
+" é©ç”¨è§£é™¤ã‚’行ã„ã¾ã™ã€‚\n"
+" "
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr "パッãƒç®¡ç†é ˜åŸŸ %s を使用中\n"
+
+msgid ""
+"rename a patch\n"
+"\n"
+" With one argument, renames the current patch to PATCH1.\n"
+" With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+"パッãƒã®æ”¹å\n"
+"\n"
+" 引数ãŒ1ã¤ã®å ´åˆã€ç¾è¡Œãƒ‘ッãƒã‚’指定ã•れãŸåå‰ã«æ”¹åã—ã¾ã™ã€‚\n"
+" 引数ãŒ2ã¤ã®å ´åˆã€1ã¤ç›®ã®ãƒ‘ッãƒã®åå‰ã‚’2ã¤ç›®ã«æ”¹åã—ã¾ã™ã€‚"
+
+#, python-format
+msgid "%s already exists"
+msgstr "ファイル %s ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr "åŒåã®ãƒ‘ッム%s ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
+
+msgid "restore the queue state saved by a revision"
+msgstr "指定リビジョンã«ã‚ˆã£ã¦ä¿å­˜ã•れãŸãƒ‘ッãƒç®¡ç†çŠ¶æ…‹ã®å¾©æ—§"
+
+msgid "save current queue state"
+msgstr "パッãƒç®¡ç†çŠ¶æ…‹ã®ä¿å­˜"
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr "ä¿å­˜å…ˆ %s ã¯æ—¢å­˜ã®ãƒ•ァイルã§ã™"
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr "ä¿å­˜å…ˆ %s ãŒå­˜åœ¨ã—ã¾ã™ã€‚実施ã™ã‚‹å ´åˆã¯ -f を指定ã—ã¦ãã ã•ã„"
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr "%s ã‹ã‚‰ %s ã«è¤‡è£½ã—ã¾ã™\n"
+
+msgid ""
+"strip a revision and all its descendants from the repository\n"
+"\n"
+" If one of the working directory's parent revisions is stripped, the\n"
+" working directory will be updated to the parent of the stripped\n"
+" revision.\n"
+" "
+msgstr ""
+"リãƒã‚¸ãƒˆãƒªã‹ã‚‰ã®ã€ç‰¹å®šãƒªãƒ“ジョンãŠã‚ˆã³ãã®å­å­«ã®é™¤å¤–\n"
+"\n"
+" 作業領域ã®è¦ªãƒªãƒ“ジョンãŒé™¤å¤–対象ã«ãªã£ãŸå ´åˆã€ä½œæ¥­é ˜åŸŸã¯é™¤å¤–対象ã®\n"
+" 親リビジョンã®å†…å®¹ã§æ›´æ–°ã•れã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"set or print guarded patches to push\n"
+"\n"
+" Use the qguard command to set or print guards on patch, then use\n"
+" qselect to tell mq which guards to use. A patch will be pushed if\n"
+" it has no guards or any positive guards match the currently\n"
+" selected guard, but will not be pushed if any negative guards\n"
+" match the current guard. For example:\n"
+"\n"
+" qguard foo.patch -stable (negative guard)\n"
+" qguard bar.patch +stable (positive guard)\n"
+" qselect stable\n"
+"\n"
+" This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+" it has a negative match) but push bar.patch (because it has a\n"
+" positive match).\n"
+"\n"
+" With no arguments, prints the currently active guards.\n"
+" With one argument, sets the active guard.\n"
+"\n"
+" Use -n/--none to deactivate guards (no other arguments needed).\n"
+" When no guards are active, patches with positive guards are\n"
+" skipped and patches with negative guards are pushed.\n"
+"\n"
+" qselect can change the guards on applied patches. It does not pop\n"
+" guarded patches by default. Use --pop to pop back to the last\n"
+" applied patch that is not guarded. Use --reapply (which implies\n"
+" --pop) to push back to the current patch afterwards, but skip\n"
+" guarded patches.\n"
+"\n"
+" Use -s/--series to print a list of all guards in the series file\n"
+" (no other arguments needed). Use -v for more information."
+msgstr ""
+"作業領域ã«ãŠã‘ã‚‹ã‚¬ãƒ¼ãƒ‰é¸æŠžã®è¨­å®šãªã„ã—表示\n"
+"\n"
+" ãƒ‘ãƒƒãƒæ¯Žã®ã‚¬ãƒ¼ãƒ‰è¨­å®šãªã„ã—表示ã«ã¯ qguard を使用ã—ã¾ã™ãŒã€ä½œæ¥­é ˜åŸŸã«\n"
+" ãŠã‘ã‚‹ã‚¬ãƒ¼ãƒ‰é¸æŠžãªã„ã—表示ã«ã¯ qselect を使用ã—ã¾ã™ã€‚ガードãŒè¨­å®š\n"
+" ã•れã¦ã„ãªã„ã‹ã€ã„ãšã‚Œã‹ã®ã€Œæ­£ã€ã®ã‚¬ãƒ¼ãƒ‰ãŒã‚¬ãƒ¼ãƒ‰é¸æŠžã«åˆè‡´ã™ã‚‹å ´åˆã€\n"
+" パッãƒã¯é©ç”¨ã•れã¾ã™ãŒã€ã„ãšã‚Œã‹ã®ã€Œè² ã€ã®ã‚¬ãƒ¼ãƒ‰ãŒã‚¬ãƒ¼ãƒ‰é¸æŠžã«åˆè‡´\n"
+" ã™ã‚‹å ´åˆã€ãƒ‘ッãƒã¯é©ç”¨ã•れã¾ã›ã‚“。例ãˆã°:\n"
+"\n"
+" qguard foo.patch -stable (「負ã€ã®ã‚¬ãƒ¼ãƒ‰)\n"
+" qguard bar.patch +stable (「正ã€ã®ã‚¬ãƒ¼ãƒ‰)\n"
+" qselect stable\n"
+"\n"
+" 上記㮠qselect 実行ã«ã‚ˆã‚Šã€\"stable\" ガードãŒé¸æŠžã•れã¾ã™ã€‚MQ ã¯\n"
+" foo.patch ã®é©ç”¨ã‚’(「負ã€ã®ã‚¬ãƒ¼ãƒ‰ã«åˆè‡´ã™ã‚‹ãŸã‚)見é€ã‚Šã¾ã™ãŒã€\n"
+" bar.patch ã®é©ç”¨ã¯(「正ã€ã®ã‚¬ãƒ¼ãƒ‰ã«åˆè‡´ã™ã‚‹ãŸã‚)実施ã—ã¾ã™ã€‚\n"
+"\n"
+" 本コマンドãŒå¼•æ•°ç„¡ã—ã§å®Ÿè¡Œã•れãŸå ´åˆã€ç¾åœ¨ã®ã‚¬ãƒ¼ãƒ‰é¸æŠžçжæ³ã‚’表示\n"
+" ã—ã¾ã™ã€‚å¼•æ•°ãŒæŒ‡å®šã•れãŸå ´åˆã€ã‚¬ãƒ¼ãƒ‰é¸æŠžã‚’設定ã—ã¾ã™ã€‚\n"
+"\n"
+" -n/--none を指定ã™ã‚‹ã“ã¨ã§ã€ã‚¬ãƒ¼ãƒ‰é¸æŠžã‚’無効化ã—ã¾ã™(ä»–ã®å¼•æ•°ã¯å¿…è¦\n"
+" ã‚りã¾ã›ã‚“)。ã„ãšã‚Œã®ã‚¬ãƒ¼ãƒ‰ã‚‚é¸æŠžã•れã¦ã„ãªã„å ´åˆã€ã€Œæ­£ã€ã®ã‚¬ãƒ¼ãƒ‰ãŒ\n"
+" 設定ã•れãŸãƒ‘ッãƒã®é©ç”¨ã¯è¦‹é€ã‚‰ã‚Œã¾ã™ãŒã€ã€Œè² ã€ã®ã‚¬ãƒ¼ãƒ‰ãŒè¨­å®šã•れãŸ\n"
+" パッãƒã¯é©ç”¨ã•れã¾ã™ã€‚\n"
+"\n"
+" 本コマンドã®å®Ÿè¡Œã«ã‚ˆã‚Šã€é©ç”¨ä¸­ã®ãƒ‘ッãƒã®é©ç”¨å¯å¦ã‚‚変化ã—å¾—ã¾ã™ã€‚特ã«\n"
+" 指定ãŒç„¡ã„å ´åˆã€ã‚¬ãƒ¼ãƒ‰ãŒæœ‰åйãªãƒ‘ッãƒã®é©ç”¨è§£é™¤ã¯è¡Œã‚れã¾ã›ã‚“。 \n"
+" --pop ãŒæŒ‡å®šã•れãŸå ´åˆã€é©ç”¨å¯å¦ãŒå¤‰ã‚る最åˆã®ãƒ‘ッãƒã¾ã§ã®ãƒ‘ッãƒãŒ\n"
+" é©ç”¨è§£é™¤ã•れã¾ã™ã€‚--reapply ãŒæŒ‡å®šã•れãŸå ´åˆã€--pop 相当ã®å‡¦ç†å¾Œã«ã€\n"
+" ã‚¬ãƒ¼ãƒ‰ãŒæœ‰åйãªãƒ‘ッãƒã®é©ç”¨ã‚’見é€ã‚Šã¤ã¤ã€ç¾è¡Œãƒ‘ッãƒã«è‡³ã‚‹ã¾ã§ãƒ‘ッãƒã‚’\n"
+" å†é©ç”¨ã—ã¾ã™ã€‚\n"
+"\n"
+" -s/--series ãŒæŒ‡å®šã•れãŸå ´åˆã€ãƒ‘ッãƒã«è¨­å®šã•れãŸã‚¬ãƒ¼ãƒ‰ã‚’一覧化ã—ã¦\n"
+" 表示ã—ã¾ã™(ä»–ã®å¼•æ•°ã¯ä¸è¦)。詳細表示ã«ã¯ -v を指定ã—ã¦ãã ã•ã„。"
+
+msgid "guards deactivated\n"
+msgstr "ガード設定を無効化ã—ã¾ã™\n"
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr "ガード設定ã®å¤‰æ›´ã«ã‚ˆã‚Šã€é©ç”¨é™¤å¤–ãƒ‘ãƒƒãƒæ•°ãŒ %d ã‹ã‚‰ %d ã«ãªã‚Šã¾ã—ãŸ\n"
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr "ガード設定ã®å¤‰æ›´ã«ã‚ˆã‚Šã€é©ç”¨å¯¾è±¡ãƒ‘ãƒƒãƒæ•°ãŒ %d ã‹ã‚‰ %d ã«ãªã‚Šã¾ã—ãŸ\n"
+
+msgid "guards in series file:\n"
+msgstr "パッãƒã«è¨­å®šã•れã¦ã„るガードã®ä¸€è¦§:\n"
+
+msgid "no guards in series file\n"
+msgstr "ガードãŒè¨­å®šã•れãŸãƒ‘ッãƒã¯ã‚りã¾ã›ã‚“\n"
+
+msgid "active guards:\n"
+msgstr "有効ãªã‚¬ãƒ¼ãƒ‰:\n"
+
+msgid "no active guards\n"
+msgstr "有効ãªã‚¬ãƒ¼ãƒ‰ã¯ã‚りã¾ã›ã‚“\n"
+
+msgid "popping guarded patches\n"
+msgstr "ã‚¬ãƒ¼ãƒ‰ãŒæœ‰åйãªãƒ‘ッãƒã‚’解除中\n"
+
+msgid "reapplying unguarded patches\n"
+msgstr "ガードãŒç„¡åйãªãƒ‘ッãƒã‚’å†é©ç”¨ä¸­\n"
+
+msgid ""
+"move applied patches into repository history\n"
+"\n"
+" Finishes the specified revisions (corresponding to applied\n"
+" patches) by moving them out of mq control into regular repository\n"
+" history.\n"
+"\n"
+" Accepts a revision range or the -a/--applied option. If --applied\n"
+" is specified, all applied mq revisions are removed from mq\n"
+" control. Otherwise, the given revisions must be at the base of the\n"
+" stack of applied patches.\n"
+"\n"
+" This can be especially useful if your changes have been applied to\n"
+" an upstream repository, or if you are about to push your changes\n"
+" to upstream.\n"
+" "
+msgstr ""
+"é©ç”¨ä¸­ãƒ‘ッãƒã®é€šå¸¸ãƒªãƒ“ジョン化\n"
+"\n"
+" 指定ã•れãŸãƒªãƒ“ジョン(é©ç”¨ä¸­ãƒ‘ッãƒã«ç›¸å½“)ã‚’ã€MQ 管ç†ä¸‹ã‹ã‚‰é™¤å¤–ã—ã€\n"
+" 通常ã®ãƒªãƒ“ジョンã¨ã—ã¦ãƒªãƒã‚¸ãƒˆãƒªã«è¨˜éŒ²ã—ã¾ã™ã€‚\n"
+"\n"
+" リビジョン範囲指定やã€-a/--applied ãŒæŒ‡å®šå¯èƒ½ã§ã™ã€‚--applied ãŒæŒ‡å®š\n"
+" ã•れãŸå ´åˆã€å…¨ã¦ã®é©ç”¨ä¸­ãƒ‘ッãƒãŒ MQ 管ç†ä¸‹ã‹ã‚‰é™¤å¤–ã•れã¾ã™ã€‚ãれ\n"
+" 以外ã®å ´åˆã€æŒ‡å®šã•れãŸãƒªãƒ“ジョンã¯ã€é©ç”¨ä¸­ã‚¹ã‚¿ãƒƒã‚¯ã®æœ€ä¸‹ä½ã‹ã‚‰ã®\n"
+" 一連ã®ãƒªãƒ“ジョンã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。\n"
+"\n"
+" ã“ã®æ©Ÿèƒ½ã¯ã€ä¸Šæµã®ãƒªãƒã‚¸ãƒˆãƒªã§ãƒ‘ッãƒãŒå—ç†ã•れãŸå ´åˆã‚„ã€ãƒ‘ッãƒå†…容を\n"
+" 上æµãƒªãƒã‚¸ãƒˆãƒªã«å映ã—よã†ã¨ã—ã¦ã„ã‚‹å ´åˆãªã©ã«æœ‰ç”¨ã§ã™ã€‚\n"
+" "
+
+msgid "no revisions specified"
+msgstr "リビジョン指定ãŒã‚りã¾ã›ã‚“"
+
+msgid "cannot commit over an applied mq patch"
+msgstr "MQ パッãƒé©ç”¨ä¸­ã¯ã‚³ãƒŸãƒƒãƒˆã‚’実施ã§ãã¾ã›ã‚“"
+
+msgid "source has mq patches applied"
+msgstr "元リãƒã‚¸ãƒˆãƒªã§ã¯ MQ パッãƒãŒé©ç”¨ä¸­ã§ã™"
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr "MQ ã®çŠ¶æ…‹ç®¡ç†ãƒ•ã‚¡ã‚¤ãƒ«ãŒæœªçŸ¥ã®ãƒªãƒ“ジョン %s ã‚’å‚ç…§ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr "ã‚¿ã‚° %s 㯠MQ パッãƒã®åŒåタグを上書ãã—ã¾ã™\n"
+
+msgid "cannot import over an applied patch"
+msgstr "パッãƒé©ç”¨ä¸­ã® import ã«ã‚ˆã‚‹å–り込ã¿ã¯ã§ãã¾ã›ã‚“"
+
+msgid "print first line of patch header"
+msgstr "パッãƒãƒ˜ãƒƒãƒ€ã®æœ€åˆã®è¡Œã‚’表示"
+
+msgid "hg qapplied [-s] [PATCH]"
+msgstr "hg qapplied [-s] [PATCH]"
+
+msgid "use pull protocol to copy metadata"
+msgstr "メタデータ複製㫠pull プロトコルを使用"
+
+msgid "do not update the new working directories"
+msgstr "æ–°è¦ä½œæ¥­é ˜åŸŸã®æ›´æ–°ã‚’抑止"
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr "éžåœ§ç¸®ã§ã®è»¢é€(LAN ã§ã®é«˜é€Ÿè»¢é€ç”¨)"
+
+msgid "location of source patch repository"
+msgstr "複製元パッãƒç®¡ç†é ˜åŸŸä½ç½®"
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr "hg qclone [OPTION]... SOURCE [DEST]"
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr "hg qcommit [OPTION]... [FILE]..."
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr "hg qdiff [OPTION]... [FILE]..."
+
+msgid "keep patch file"
+msgstr "パッãƒãƒ•ァイルã®å‰Šé™¤ã‚’抑止"
+
+msgid "stop managing a revision (DEPRECATED)"
+msgstr "指定リビジョンを管ç†å¯¾è±¡ã‹ã‚‰é™¤å¤–(éžæŽ¨å¥¨)"
+
+msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
+msgstr "hg qdelete [-k] [-r REV]... [PATCH]..."
+
+msgid "edit patch header"
+msgstr "パッãƒãƒ˜ãƒƒãƒ€å†…容ã®ç·¨é›†"
+
+msgid "keep folded patch files"
+msgstr "çµåˆå¯¾è±¡ãƒ‘ッãƒã®ãƒ‘ッãƒãƒ•ァイル削除を抑止"
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+
+msgid "overwrite any local changes"
+msgstr "作業領域中ã®å¤‰æ›´ã‚’上書ã"
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr "hg qgoto [OPTION]... PATCH"
+
+msgid "list all patches and guards"
+msgstr "å…¨ã¦ã®ãƒ‘ッãƒã®ã‚¬ãƒ¼ãƒ‰çжæ³ã‚’一覧表示"
+
+msgid "drop all guards"
+msgstr "å…¨ã¦ã®ã‚¬ãƒ¼ãƒ‰è¨­å®šã‚’破棄"
+
+msgid "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+msgstr "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+
+msgid "hg qheader [PATCH]"
+msgstr "hg qheader [PATCH]"
+
+msgid "import file in patch directory"
+msgstr "パッãƒç®¡ç†é ˜åŸŸä¸­ã®ãƒ•ァイルã‹ã‚‰å–り込ã¿"
+
+msgid "name of patch file"
+msgstr "パッãƒãƒ•ァイルå"
+
+msgid "overwrite existing files"
+msgstr "既存ファイルã®ä¸Šæ›¸ã"
+
+msgid "place existing revisions under mq control"
+msgstr "既存リビジョンを MQ 管ç†ä¸‹ã«ç§»è¡Œ"
+
+msgid "use git extended diff format"
+msgstr "git 拡張差分形å¼ã®ä½¿ç”¨"
+
+msgid "qpush after importing"
+msgstr "パッãƒå–り込ã¿å¾Œã«ãƒ‘ッãƒé©ç”¨(qpush)を実施"
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+
+msgid "create queue repository"
+msgstr "パッãƒç®¡ç†è‡ªèº«ã‚’ Mercurial ã§æ§‹æˆç®¡ç†"
+
+msgid "hg qinit [-c]"
+msgstr "hg qinit [-c]"
+
+msgid "import uncommitted changes into patch"
+msgstr "作業領域ã®å¤‰æ›´å†…容ã®ãƒ‘ッãƒã¸ã®å–り込ã¿"
+
+msgid "add \"From: <current user>\" to patch"
+msgstr "\"From: <ç¾ãƒ¦ãƒ¼ã‚¶å>\" をパッãƒã«è¿½åŠ "
+
+msgid "add \"From: <given user>\" to patch"
+msgstr "\"From: <指定ユーザå>\" をパッãƒã«è¿½åŠ "
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr "\"Date: <ç¾åœ¨æ™‚刻>\" をパッãƒã«è¿½åŠ "
+
+msgid "add \"Date: <given date>\" to patch"
+msgstr "\"Date: <指定日時>\" をパッãƒã«è¿½åŠ "
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+msgstr "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+
+msgid "hg qnext [-s]"
+msgstr "hg qnext [-s]"
+
+msgid "hg qprev [-s]"
+msgstr "hg qprev [-s]"
+
+msgid "pop all patches"
+msgstr "å…¨ã¦ã®ãƒ‘ッãƒã®é©ç”¨ã‚’解除"
+
+msgid "queue name to pop"
+msgstr "パッãƒè§£é™¤å…ˆã®ãƒ‘ッãƒç®¡ç†é ˜åŸŸå"
+
+msgid "forget any local changes"
+msgstr "作業領域中ã®å¤‰æ›´ã‚’破棄"
+
+msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+msgstr "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+
+msgid "apply if the patch has rejects"
+msgstr "パッãƒé©ç”¨ãŒæ‹’å¦ã•れã¦ã‚‚続行"
+
+msgid "list patch name in commit text"
+msgstr "コミットメッセージã¨ã—ã¦ãƒ‘ッãƒåを列挙"
+
+msgid "apply all patches"
+msgstr "å…¨ã¦ã®ãƒ‘ッãƒã‚’é©ç”¨"
+
+msgid "merge from another queue"
+msgstr "ä»–ã®ãƒ‘ッãƒç®¡ç†é ˜åŸŸã¨ã®ãƒžãƒ¼ã‚¸"
+
+msgid "merge queue name"
+msgstr "マージ対象ã®ãƒ‘ッãƒç®¡ç†é ˜åŸŸå"
+
+msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+msgstr "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+
+msgid "refresh only files already in the patch and specified files"
+msgstr "パッãƒå¯¾è±¡ã‹ã€æ˜Žç¤ºæŒ‡å®šã®ã‚ã£ãŸãƒ•ァイルã®ã¿ã‚’処ç†å¯¾è±¡ã«ã™ã‚‹"
+
+msgid "add/update \"From: <current user>\" in patch"
+msgstr "パッãƒä¸­ã® \"From:\" を「ç¾è¡Œãƒ¦ãƒ¼ã‚¶ã€ã§æ›´æ–°(ãªã„ã—追加)"
+
+msgid "add/update \"From: <given user>\" in patch"
+msgstr "パッãƒä¸­ã® \"From:\" ã‚’æŒ‡å®šãƒ¦ãƒ¼ã‚¶ã§æ›´æ–°(ãªã„ã—追加)"
+
+msgid "update \"Date: <current date>\" in patch (if present)"
+msgstr "パッãƒä¸­ã® \"Date:\" ã‚’ç¾åœ¨æ—¥æ™‚ã§æ›´æ–°"
+
+msgid "update \"Date: <given date>\" in patch (if present)"
+msgstr "パッãƒä¸­ã® \"Date:\" ã‚’æŒ‡å®šæ—¥æ™‚ã§æ›´æ–°"
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr "hg qrename PATCH1 [PATCH2]"
+
+msgid "delete save entry"
+msgstr "ä¿å­˜ã‚¨ãƒ³ãƒˆãƒªã®ç ´æ£„"
+
+msgid "update queue working directory"
+msgstr "パッãƒç®¡ç†é ˜åŸŸã®æ›´æ–°"
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr "hg qrestore [-d] [-u] REV"
+
+msgid "copy patch directory"
+msgstr "パッãƒç®¡ç†é ˜åŸŸã®è¤‡è£½"
+
+msgid "copy directory name"
+msgstr "複製先ディレクトリå"
+
+msgid "clear queue status file"
+msgstr "パッãƒçŠ¶æ…‹ãƒ•ã‚¡ã‚¤ãƒ«(status)ã®ã‚¯ãƒªã‚¢"
+
+msgid "force copy"
+msgstr "複製ã®å¼·è¡Œ"
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+
+msgid "disable all guards"
+msgstr "å…¨ã¦ã®ã‚¬ãƒ¼ãƒ‰è¨­å®šã‚’破棄"
+
+msgid "list all guards in series file"
+msgstr "å„パッãƒã«è¨­å®šã•れãŸã‚¬ãƒ¼ãƒ‰ã‚’一覧化"
+
+msgid "pop to before first guarded applied patch"
+msgstr "é©ç”¨å¯å¦ãŒå¤‰åŒ–ã™ã‚‹ãƒ‘ッãƒã®é©ç”¨ã‚’解除"
+
+msgid "pop, then reapply patches"
+msgstr "qpop 実施後ã«å†åº¦ãƒ‘ッãƒã‚’é©ç”¨"
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr "hg qselect [OPTION]... [GUARD]..."
+
+msgid "print patches not in series"
+msgstr "パッãƒç®¡ç†é ˜åŸŸä¸­ã®æœªçŸ¥ã®ãƒ‘ッãƒãƒ•ァイルを表示"
+
+msgid "hg qseries [-ms]"
+msgstr "hg qseries [-ms]"
+
+msgid "force removal with local changes"
+msgstr "作業領域ã«å¤‰æ›´ãŒã‚ã£ã¦ã‚‚削除を強行"
+
+msgid "bundle unrelated changesets"
+msgstr "無関係ã®ãƒªãƒ“ジョンをãƒãƒ³ãƒ‰ãƒ«åŒ–"
+
+msgid "no backups"
+msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—作æˆã®æŠ‘æ­¢"
+
+msgid "hg strip [-f] [-b] [-n] REV"
+msgstr "hg strip [-f] [-b] [-n] REV"
+
+msgid "hg qtop [-s]"
+msgstr "hg qtop [-s]"
+
+msgid "hg qunapplied [-s] [PATCH]"
+msgstr "hg qunapplied [-s] [PATCH]"
+
+msgid "finish all applied changesets"
+msgstr "å…¨ã¦ã®é©ç”¨ä¸­ãƒ‘ッãƒã‚’通常リビジョン化"
+
+msgid "hg qfinish [-a] [REV]..."
+msgstr "hg qfinish [-a] [REV]..."
+
+msgid ""
+"hooks for sending email notifications at commit/push time\n"
+"\n"
+"Subscriptions can be managed through hgrc. Default mode is to print\n"
+"messages to stdout, for testing and configuring.\n"
+"\n"
+"To use, configure notify extension and enable in hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # one email for each incoming changeset\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # batch emails when many changesets incoming at one time\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # config items go in here\n"
+"\n"
+" config items:\n"
+"\n"
+" REQUIRED:\n"
+" config = /path/to/file # file containing subscriptions\n"
+"\n"
+" OPTIONAL:\n"
+" test = True # print messages to stdout for testing\n"
+" strip = 3 # number of slashes to strip for url paths\n"
+" domain = example.com # domain to use if committer missing domain\n"
+" style = ... # style file to use when formatting email\n"
+" template = ... # template to use when formatting email\n"
+" incoming = ... # template to use when run as incoming hook\n"
+" changegroup = ... # template when run as changegroup hook\n"
+" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n"
+" maxsubject = 67 # truncate subject line longer than this\n"
+" diffstat = True # add a diffstat before the diff content\n"
+" sources = serve # notify if source of incoming changes in this "
+"list\n"
+" # (serve == ssh or http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # email address to send as if none given\n"
+" [web]\n"
+" baseurl = http://hgserver/... # root of hg web site for browsing commits\n"
+"\n"
+" notify config file has same format as regular hgrc. it has two\n"
+" sections so you can express subscriptions in whatever way is handier\n"
+" for you.\n"
+"\n"
+" [usersubs]\n"
+" # key is subscriber email, value is \",\"-separated list of glob "
+"patterns\n"
+" user@host = pattern\n"
+"\n"
+" [reposubs]\n"
+" # key is glob pattern, value is \",\"-separated list of subscriber "
+"emails\n"
+" pattern = user@host\n"
+"\n"
+" glob patterns are matched against path to repository root.\n"
+"\n"
+" if you like, you can put notify config file in repository that users\n"
+" can push changes to, they can manage their own subscriptions."
+msgstr ""
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr "%s: %d ä»¶ã®æ–°ã—ã„ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ"
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "notify: no subscribers to repository %s\n"
+msgstr ""
+
+#, python-format
+msgid "notify: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+msgid ""
+"browse command output with an external pager\n"
+"\n"
+"To set the pager that should be used, set the application variable:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"If no pager is set, the pager extensions uses the environment variable\n"
+"$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.\n"
+"\n"
+"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
+"setting:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"You can also enable the pager only for certain commands using\n"
+"pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"If pager.attend is present, pager.ignore will be ignored.\n"
+"\n"
+"To ignore global commands like \"hg version\" or \"hg help\", you have to\n"
+"specify them in the global .hgrc\n"
+msgstr ""
+
+msgid ""
+"interpret suffixes to refer to ancestor revisions\n"
+"\n"
+"This extension allows you to use git-style suffixes to refer to the\n"
+"ancestors of a specific revision.\n"
+"\n"
+"For example, if you can refer to a revision as \"foo\", then:\n"
+"\n"
+"- foo^N = Nth parent of foo\n"
+" foo^0 = foo\n"
+" foo^1 = first parent of foo\n"
+" foo^2 = second parent of foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nth first grandparent of foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = first parent of foo\n"
+" foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
+msgstr ""
+
+msgid ""
+"command to send changesets as (a series of) patch emails\n"
+"\n"
+"The series is started off with a \"[PATCH 0 of N]\" introduction, which\n"
+"describes the series as a whole.\n"
+"\n"
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using the\n"
+"first line of the changeset description as the subject text. The\n"
+"message contains two or three body parts:\n"
+"\n"
+" The changeset description.\n"
+"\n"
+" [Optional] The result of running diffstat on the patch.\n"
+"\n"
+" The patch itself, as generated by \"hg export\".\n"
+"\n"
+"Each message refers to the first in the series using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in threaded\n"
+"mail and news readers, and in mail archives.\n"
+"\n"
+"With the -d/--diffstat option, you will be prompted for each changeset\n"
+"with a diffstat summary and the changeset summary, so you can be sure\n"
+"you are sending the right changes.\n"
+"\n"
+"To configure other defaults, add a section like this to your hgrc\n"
+"file:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Then you can use the \"hg email\" command to mail a series of changesets\n"
+"as a patchbomb.\n"
+"\n"
+"To avoid sending patches prematurely, it is a good idea to first run\n"
+"the \"email\" command with the \"-n\" option (test only). You will be\n"
+"prompted for an email recipient address, a subject and an introductory\n"
+"message describing the patches of your patchbomb. Then when all is\n"
+"done, patchbomb messages are displayed. If the PAGER environment\n"
+"variable is set, your pager will be fired up once for each patchbomb\n"
+"message, so you can verify everything is alright.\n"
+"\n"
+"The -m/--mbox option is also very useful. Instead of previewing each\n"
+"patchbomb message in a pager or sending the messages directly, it will\n"
+"create a UNIX mailbox file with the patch emails. This mailbox file\n"
+"can be previewed with any mail user agent which supports UNIX mbox\n"
+"files, e.g. with mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"When you are previewing the patchbomb messages, you can use `formail'\n"
+"(a utility that is commonly installed as part of the procmail\n"
+"package), to send each message out:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"That should be all. Now your patchbomb is on its way out.\n"
+"\n"
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatible mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs\n"
+"directly from the commandline. See the [email] and [smtp] sections in\n"
+"hgrc(5) for details."
+msgstr ""
+"é›»å­ãƒ¡ãƒ¼ãƒ«ã«ã‚ˆã‚‹å¤‰æ›´å†…容パッãƒé€ä»˜ã®ã‚³ãƒžãƒ³ãƒ‰\n"
+"\n"
+"一連ã®ãƒ¡ãƒ¼ãƒ«ã¯ã€\"[PATCH 0 of N]\" ã‚’ Subject ãƒ˜ãƒƒãƒ€ã«æŒã¤ã€èª¬æ˜Žãƒ¡ãƒ¼ãƒ«\n"
+"ã‹ã‚‰å§‹ã¾ã‚Šã¾ã™ã€‚\n"
+"\n"
+"個々ã®ãƒ¡ãƒ¼ãƒ«ã® Subject ヘッダã¯ã€\"[PATCH M of N]\" ã§å§‹ã¾ã‚Šã€å¯¾å¿œã™ã‚‹\n"
+"リビジョンã®ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®æœ€åˆã®è¡Œã®å†…容ãŒè¨˜è¼‰ã•れã¾ã™ã€‚メールã®\n"
+"本文ã¯ã€ä»¥ä¸‹ã®æ§˜ãª2ãªã„ã—3ã®éƒ¨ä½ã‹ã‚‰æ§‹æˆã•れã¾ã™:\n"
+"\n"
+" - コミットメッセージ\n"
+"\n"
+" - パッãƒã®å·®åˆ†çµ±è¨ˆ(diffstat)çµæžœ [çœç•¥å¯èƒ½]\n"
+"\n"
+" - \"hg export\" å½¢å¼ã¨åŒæ§˜ã®ãƒ‘ッãƒå†…容\n"
+"\n"
+"個々ã®ãƒ¡ãƒ¼ãƒ«ã¯ã€In-Reply-To ãŠã‚ˆã³ References ヘッダを使用ã—ã¦ã€1通目ã®\n"
+"メールをå‚ç…§ã—ã¾ã™ã®ã§ã€ãƒ¡ãƒ¼ãƒ«ãƒªãƒ¼ãƒ€ãƒ¼ã‚„ニュースリーダーã§ã®å‚照時やã€\n"
+"メールアーカイブã«ãŠã„ã¦ã¯ã€ä¸€é€£ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã¨ã—ã¦æ‰±ã‚れã¾ã™ã€‚\n"
+"\n"
+"-d/--diffstat を指定ã—ãŸå ´åˆã€å·®åˆ†çµ±è¨ˆçµæžœã‚„コミットメッセージを伴ã£ã¦\n"
+"é€ä¿¡ã®æœ‰ç„¡ã®å•ã„åˆã‚ã›ãŒã‚りã¾ã™ã®ã§ã€ç¢ºèªã—ãªãŒã‚‰é€ä¿¡ã§ãã¾ã™ã€‚\n"
+"\n"
+"ä»¥ä¸‹ã®æ§˜ãªè¨˜è¿°ã‚’設定ファイルã«è¿½åŠ ã™ã‚‹ã“ã¨ã§ã€ç„¡æŒ‡å®šæ™‚ã®è¨­å®šã‚’変更ã§ã\n"
+"ã¾ã™:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"ã“ã“ã¾ã§è¨­å®šã§ããŸãªã‚‰ã€\"hg email\" コマンドを使用ã—ã¦ã€ä¸€é€£ã®\n"
+"リビジョンをパッãƒçˆ†å¼¾(patchbomb)ã¨ã—ã¦ãƒ¡ãƒ¼ãƒ«é€ä¿¡ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n"
+"\n"
+"ä¸å®Œå…¨ãªãƒ‘ッãƒã®é€ä¿¡ã‚’防ã上ã§ã€ã¾ãšã¯ \"-n\"(ï¼ã€Œè¡¨ç¤ºã®ã¿ã€)指定付ãã§\n"
+"\"email\" コマンドを実行ã™ã‚‹ã®ãŒãŠå‹§ã‚ã§ã™ã€‚ã“れを指定ã—ãŸå®Ÿè¡Œã®éš›ã«ã¯ã€\n"
+"é€ä¿¡å…ˆã‚¢ãƒ‰ãƒ¬ã‚¹ã‚„ã€ä¸€é€£ã®ãƒ‘ッãƒã‹ã‚‰æˆã‚‹ãƒ‘ッãƒçˆ†å¼¾ã®èª¬æ˜Žæ–‡ç­‰ã®å…¥åŠ›ãŒä¿ƒã•れ\n"
+"ã¾ã™ã€‚å¿…è¦ãªå…¥åŠ›ãŒå®Œäº†ã™ã‚‹ã¨ã€é€ä¿¡ã•れるメールã®å†…容ãŒè¡¨ç¤ºã•れã¾ã™ã€‚\n"
+"PAGER 環境変数ãŒè¨­å®šã•れã¦ã„ã‚‹å ´åˆã€ãƒ‘ッãƒçˆ†å¼¾ã‚’æ§‹æˆã™ã‚‹ãƒ¡ãƒ¼ãƒ«ã”ã¨ã«ã€\n"
+"環境変数ã«è¨­å®šã•れãŸãƒ—ログラムãŒèµ·å‹•ã•れã¾ã™ã®ã§ã€å†…容を確èªã™ã‚‹ã“ã¨ãŒ\n"
+"出æ¥ã¾ã™ã€‚\n"
+"\n"
+"-m/--mbox も有用ã§ã™ã€‚PAGER ã§ã®è¡¨ç¤ºã‚„メールé€ä¿¡ã®ä»£ã‚りã«ã€ãƒ‘ッãƒã®\n"
+"メールを格ç´ã—㟠UNIX mailbox å½¢å¼ã®ãƒ•ァイルを作æˆã—ã¾ã™ã€‚ã“ã®ãƒ•ァイルã¯\n"
+"UNIX mailbox å½¢å¼ãƒ•ァイルã«å¯¾å¿œã—ã¦ã„ã‚‹ä»»æ„ã®ãƒ„ールã§é–²è¦§ã™ã‚‹ã“ã¨ãŒã§ã\n"
+"ã¾ã™ã€‚例ãˆã° mutt ã¨ã„ã†ãƒ„ールã®å ´åˆ:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"パッãƒçˆ†å¼¾ã®å†…容を閲覧中ã«ã€`formail'(procmail パッケージã®ä¸€éƒ¨ã¨ã—ã¦\n"
+"大抵ã®ã‚·ã‚¹ãƒ†ãƒ ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„るユーティリティã§ã™)を使用ã—ã¦\n"
+"メールをé€ä¿¡ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"以上ã§å®Œäº†ã§ã™ã€‚ã“れã§ãƒ‘ッãƒçˆ†å¼¾ãŒé€ä¿¡ã•れã¾ã—ãŸã€‚\n"
+"\n"
+"設定ファイル㮠[email] セクション㧠method 指定を行ã†ã“ã¨ã§ã€sendmail\n"
+"互æ›ã®ãƒ¡ãƒ¼ãƒ«é€ä¿¡ãƒ—ログラムを指定ã™ã‚‹ã“ã¨ã‚‚ã§ãれã°ã€[smtp] セクションã«\n"
+"å¿…è¦ãªæƒ…報を記述ã™ã‚‹ã“ã¨ã§ã€å¤–部プログラムã®åŠ©ã‘を借りãšã« Mercurial ã‹ã‚‰\n"
+"直接パッãƒçˆ†å¼¾ã‚’é€ä¿¡ã™ã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚ã“れらã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã«é–¢ã™ã‚‹è©³ç´°ã¯\n"
+"設定ファイルã«é–¢ã™ã‚‹ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ(hgrc(5))ã‚’å‚ç…§ã—ã¦ãã ã•ã„。"
+
+msgid "Please enter a valid value.\n"
+msgstr "é©åˆ‡ãªå€¤ã‚’入力ã—ã¦ãã ã•ã„。\n"
+
+msgid "does the diffstat above look okay? "
+msgstr "上記ã®å·®åˆ†çµ±è¨ˆã§é–“é•ã„ã‚りã¾ã›ã‚“ã‹ï¼Ÿ "
+
+msgid "diffstat rejected"
+msgstr "差分統計ãŒå´ä¸‹ã•れã¾ã—ãŸ"
+
+msgid ""
+"send changesets by email\n"
+"\n"
+" By default, diffs are sent in the format generated by hg export,\n"
+" one per message. The series starts with a \"[PATCH 0 of N]\"\n"
+" introduction, which describes the series as a whole.\n"
+"\n"
+" Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+" the first line of the changeset description as the subject text.\n"
+" The message contains two or three parts. First, the changeset\n"
+" description. Next, (optionally) if the diffstat program is\n"
+" installed and -d/--diffstat is used, the result of running\n"
+" diffstat on the patch. Finally, the patch itself, as generated by\n"
+" \"hg export\".\n"
+"\n"
+" By default the patch is included as text in the email body for\n"
+" easy reviewing. Using the -a/--attach option will instead create\n"
+" an attachment for the patch. With -i/--inline an inline attachment\n"
+" will be created.\n"
+"\n"
+" With -o/--outgoing, emails will be generated for patches not found\n"
+" in the destination repository (or only those which are ancestors\n"
+" of the specified revisions if any are provided)\n"
+"\n"
+" With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+" single email containing a binary Mercurial bundle as an attachment\n"
+" will be sent.\n"
+"\n"
+" Examples:\n"
+"\n"
+" hg email -r 3000 # send patch 3000 only\n"
+" hg email -r 3000 -r 3001 # send patches 3000 and 3001\n"
+" hg email -r 3000:3005 # send patches 3000 through 3005\n"
+" hg email 3000 # send patch 3000 (deprecated)\n"
+"\n"
+" hg email -o # send all patches not in default\n"
+" hg email -o DEST # send all patches not in DEST\n"
+" hg email -o -r 3000 # send all ancestors of 3000 not in default\n"
+" hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST\n"
+"\n"
+" hg email -b # send bundle of all patches not in default\n"
+" hg email -b DEST # send bundle of all patches not in DEST\n"
+" hg email -b -r 3000 # bundle of all ancestors of 3000 not in "
+"default\n"
+" hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST\n"
+"\n"
+" Before using this command, you will need to enable email in your\n"
+" hgrc. See the [email] section in hgrc(5) for details.\n"
+" "
+msgstr ""
+"é›»å­ãƒ¡ãƒ¼ãƒ«ã«ã‚ˆã‚‹å¤‰æ›´å†…容ã®ãƒ‘ッãƒé€ä»˜\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šã®ç„¡ã„å ´åˆã€'hg export' ã®ç”Ÿæˆã™ã‚‹å·®åˆ†å½¢å¼ã§ã€ãƒªãƒ“ジョン毎ã«\n"
+" メールãŒé€ä¿¡ã•れã¾ã™ã€‚一連ã®ãƒ¡ãƒ¼ãƒ«ã¯ã€\"[PATCH 0 of N]\" ã‚’ Subject\n"
+" ãƒ˜ãƒƒãƒ€ã«æŒã¤ã€èª¬æ˜Žãƒ¡ãƒ¼ãƒ«ã‹ã‚‰å§‹ã¾ã‚Šã¾ã™ã€‚\n"
+"\n"
+" 個々ã®ãƒ¡ãƒ¼ãƒ«ã® Subject ヘッダã¯ã€\"[PATCH M of N]\" ã§å§‹ã¾ã‚Šã€å¯¾å¿œ\n"
+" ã™ã‚‹ãƒªãƒ“ジョンã®ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®æœ€åˆã®è¡Œã®å†…容ãŒè¨˜è¼‰ã•れã¾ã™ã€‚\n"
+" メール本文ã¯ã€2ãªã„ã—3ã®éƒ¨ä½ã‹ã‚‰æ§‹æˆã•れã¾ã™ã€‚最åˆã®éƒ¨ä½ã«ã¯ã‚³ãƒŸãƒƒãƒˆ\n"
+" メッセージã®ç¶šããŒé…ç½®ã•れã¾ã™ã€‚次ã®éƒ¨ä½ã«ã¯ã€diffstat コマンドãŒ\n"
+" 利用å¯èƒ½ã§ä¸”㤠-d/--diffstat ãŒæŒ‡å®šã•れãŸå ´åˆã«ã€ãƒ‘ッãƒã®å·®åˆ†çµ±è¨ˆãŒ\n"
+" é…ç½®ã•れã¾ã™ã€‚最後ã®éƒ¨ä½ã«ã¯ã€'hg export' ã®ç”Ÿæˆã™ã‚‹å·®åˆ†ã«ã‚ˆã‚‹\n"
+" パッãƒãŒé…ç½®ã•れã¾ã™ã€‚\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šã®ç„¡ã„å ´åˆã€ãƒ‘ッãƒã¯ãƒ¡ãƒ¼ãƒ«æœ¬æ–‡ä¸­ã«é€šå¸¸ãƒ†ã‚­ã‚¹ãƒˆã¨ã—ã¦åŸ‹ã‚è¾¼ã¾\n"
+" れã¾ã™ã€‚-a/--attach 指定ã«ã‚ˆã‚Šã€ãƒ‘ッãƒãŒæ·»ä»˜ãƒ•ァイル化ã•れã¾ã™ã€‚\n"
+" -i/--inline 指定ã«ã‚ˆã‚Šã€ã‚¤ãƒ³ãƒ©ã‚¤ãƒ³æ·»ä»˜ãƒ•ァイルã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" -o/--outgoing 指定ãŒã‚ã‚‹å ´åˆã€é€£æºå¯¾è±¡ãƒªãƒã‚¸ãƒˆãƒªã«å­˜åœ¨ã—ãªã„\n"
+" (ã‚ã‚‹ã„ã¯ã€æŒ‡å®šãƒªãƒ“ジョンã®å­å­«ã¨ãªã‚‹)リビジョンã®ãŸã‚ã®ãƒ‘ッãƒã®ã¿ãŒ\n"
+" メールã§é€ä¿¡ã•れã¾ã™ã€‚\n"
+"\n"
+" -b/--bundle 指定ãŒã‚ã‚‹å ´åˆã€å¯¾è±¡ãƒªãƒ“ジョンã®é¸æŠžã¯ --outgoing 指定\n"
+" 時ã¨åŒæ§˜ã«è¡Œã‚れã¾ã™ãŒã€Mercurial ã®ãƒãƒ³ãƒ‰ãƒ«å½¢å¼ãƒ•ァイルを添付\n"
+" ファイルã¨ã™ã‚‹å˜ä¸€ã®ãƒ¡ãƒ¼ãƒ«ã¨ã—ã¦é€ä¿¡ã•れã¾ã™ã€‚\n"
+"\n"
+" 実行例:\n"
+"\n"
+" hg email -r 3000 # リビジョン 3000 \n"
+" hg email -r 3000 -r 3001 # リビジョン 3000 ãŠã‚ˆã³ 3001\n"
+" hg email -r 3000:3005 # リビジョン 3000 ã‹ã‚‰ 3005 ã¾ã§\n"
+" hg email 3000 # リビジョン 3000 (éžæŽ¨å¥¨å½¢å¼)\n"
+"\n"
+" hg email -o # default ã«ç„¡ã„リビジョン\n"
+" hg email -o DEST # DEST ã«ç„¡ã„リビジョン\n"
+" hg email -o -r 3000 # default ã«ç„¡ã„ 3000 以後\n"
+" hg email -o -r 3000 DEST # DEST ã«ç„¡ã„ 3000 以後\n"
+"\n"
+" hg email -b # default ã«ç„¡ã„ã‚‚ã®ã‚’ bundle å½¢å¼ã§\n"
+" hg email -b DEST # DEST ã«ç„¡ã„ã‚‚ã®ã‚’ bundle å½¢å¼ã§\n"
+" hg email -b -r 3000 # default ã«ç„¡ã„ 3000 以後を bundle å½¢å¼ã§\n"
+" hg email -b -r 3000 DEST # DEST ã«ç„¡ã„ 3000 以後を bundle å½¢å¼ã§\n"
+"\n"
+" 本コマンドを使用ã™ã‚‹å‰ã«ã€è¨­å®šãƒ•ァイルã«é›»å­ãƒ¡ãƒ¼ãƒ«é–¢é€£è¨­å®šã‚’記述ã™ã‚‹\n"
+" å¿…è¦ãŒã‚りã¾ã™ã€‚設定ファイルã«é–¢ã™ã‚‹ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ(hgrc(5))ã‚’å‚ç…§ã—ã¦\n"
+" ãã ã•ã„。\n"
+" "
+
+msgid "specify at least one changeset with -r or -o"
+msgstr "-r åˆã¯ -o を使用ã—ã¦ãƒªãƒ“ジョンを指定ã—ã¦ãã ã•ã„"
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr "--bundle æŒ‡å®šã§æš—é»™ã«æœ‰åйã¨ãªã‚Šã¾ã™ã®ã§ --outgoing 指定ã¯ä¸è¦ã§ã™"
+
+msgid "too many destinations"
+msgstr "対象指定ãŒå¤šéŽãŽã§ã™"
+
+msgid "use only one form to specify the revision"
+msgstr "リビジョン指定ã¯å˜ä¸€ã®å½¢å¼ã§è¡Œã£ã¦ãã ã•ã„"
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series.\n"
+"\n"
+msgstr ""
+"\n"
+"一連ã®ãƒ‘ッãƒã®ãŸã‚ã®èª¬æ˜Žæ–‡ã‚’記述ã—ã¦ãã ã•ã„。\n"
+"\n"
+
+#, python-format
+msgid ""
+"This patch series consists of %d patches.\n"
+"\n"
+msgstr ""
+"一連ã®ãƒ‘ッãƒã¯ %d 個ã®ãƒ‘ッãƒã‹ã‚‰æ§‹æˆã•れã¦ã„ã¾ã™ã€‚\n"
+"\n"
+
+msgid "Final summary:\n"
+msgstr "çµ±è¨ˆçµæžœ:\n"
+
+msgid "Displaying "
+msgstr "表示中 "
+
+msgid "Writing "
+msgstr "書ã出ã—中 "
+
+msgid "Sending "
+msgstr "é€ä¿¡ä¸­ "
+
+msgid "send patches as attachments"
+msgstr "添付ファイルã¨ã—ã¦ãƒ‘ッãƒã‚’é€ä¿¡"
+
+msgid "send patches as inline attachments"
+msgstr "インライン添付ファイルã¨ã—ã¦ãƒ‘ッãƒã‚’é€ä¿¡"
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr "BCC 宛先ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹"
+
+msgid "email addresses of copy recipients"
+msgstr "CC 宛先ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹"
+
+msgid "add diffstat output to messages"
+msgstr "差分統計を出力ã«è¿½åŠ "
+
+msgid "use the given date as the sending date"
+msgstr "メール㮠Date ãƒ˜ãƒƒãƒ€å€¤ã«æŒ‡å®šæ—¥æ™‚を設定"
+
+msgid "use the given file as the series description"
+msgstr "指定ファイルã®å†…容を説明文ã¨ã—ã¦ä½¿ç”¨"
+
+msgid "email address of sender"
+msgstr "メール㮠From ヘッダ値"
+
+msgid "print messages that would be sent"
+msgstr "é€ä¿¡äºˆå®šã®ãƒ¡ãƒ¼ãƒ«ã®å†…容を表示"
+
+msgid "write messages to mbox file instead of sending them"
+msgstr "メールé€ä¿¡ã®ä»£ã‚りã«ã€mbox ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã出ã™"
+
+msgid "subject of first message (intro or single patch)"
+msgstr "説明文ãªã„ã—å˜ä¸€ãƒ‘ッãƒé€ä¿¡ãƒ¡ãƒ¼ãƒ«ã® Subject ヘッダ値"
+
+msgid "message identifier to reply to"
+msgstr "返信対象ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ID"
+
+msgid "email addresses of recipients"
+msgstr "TO 宛先ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹"
+
+msgid "omit hg patch header"
+msgstr "Mercurial 固有ã®ãƒ‘ッãƒãƒ˜ãƒƒãƒ€ã‚’çœç•¥"
+
+msgid "send changes not found in the target repository"
+msgstr "対象リãƒã‚¸ãƒˆãƒªã«ç„¡ã„リビジョンをパッãƒå½¢å¼ã§é€ä¿¡"
+
+msgid "send changes not in target as a binary bundle"
+msgstr "対象リãƒã‚¸ãƒˆãƒªã«ç„¡ã„リビジョンをãƒãƒ³ãƒ‰ãƒ«å½¢å¼ã§é€ä¿¡"
+
+msgid "name of the bundle attachment file"
+msgstr "ãƒãƒ³ãƒ‰ãƒ«å½¢å¼æ·»ä»˜ãƒ•ァイルã®ãƒ•ァイルå"
+
+msgid "a revision to send"
+msgstr "é€ä¿¡ã™ã‚‹ãƒªãƒ“ジョン"
+
+msgid "run even when remote repository is unrelated (with -b/--bundle)"
+msgstr "連æºå…ˆãŒç„¡é–¢ä¿‚ãªãƒªãƒã‚¸ãƒˆãƒªã§ã‚‚é€ä¿¡(-b/--bundle 指定時)"
+
+msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
+msgstr "連æºå…ˆæŒ‡å®šã®ä»£ã‚りã¨ãªã‚‹åŸºåº•リビジョン(-b/--bundle 指定時)"
+
+msgid "send an introduction email for a single patch"
+msgstr "説明文を独立ã—ãŸãƒ¡ãƒ¼ãƒ«ã§é€ä¿¡"
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr "hg email [OPTION]... [DEST]...\""
+
+msgid "command to delete untracked files from the working directory"
+msgstr "ä½œæ¥­é ˜åŸŸä¸­ã®æœªç™»éŒ²ãƒ•ァイルを削除ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰"
+
+msgid ""
+"removes files not tracked by Mercurial\n"
+"\n"
+" Delete files not known to Mercurial. This is useful to test local\n"
+" and uncommitted changes in an otherwise-clean source tree.\n"
+"\n"
+" This means that purge will delete:\n"
+" - Unknown files: files marked with \"?\" by \"hg status\"\n"
+" - Empty directories: in fact Mercurial ignores directories unless\n"
+" they contain files under source control management\n"
+" But it will leave untouched:\n"
+" - Modified and unmodified tracked files\n"
+" - Ignored files (unless --all is specified)\n"
+" - New files added to the repository (with \"hg add\")\n"
+"\n"
+" If directories are given on the command line, only files in these\n"
+" directories are considered.\n"
+"\n"
+" Be careful with purge, as you could irreversibly delete some files\n"
+" you forgot to add to the repository. If you only want to print the\n"
+" list of files that this program would delete, use the --print\n"
+" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr "%s を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+#, python-format
+msgid "warning: %s\n"
+msgstr "警告: %s\n"
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr "ファイル %s を削除ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr "ディレクトリ %s を削除ã—ã¦ã„ã¾ã™\n"
+
+msgid "abort if an error occurs"
+msgstr "エラーãŒç™ºç”Ÿã—ãŸå ´åˆã€ä¸­æ–­ã™ã‚‹"
+
+msgid "purge ignored files too"
+msgstr "無視ã—ãŸãƒ•ァイルも削除ã™ã‚‹"
+
+msgid "print filenames instead of deleting them"
+msgstr "ファイル削除ã®å¤‰ã‚りã«ãƒ•ァイルå表示を実施"
+
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr "ファイルåã‚’NUL文字(0x00)ã§çµ‚端(xargs -p/--print ã¨ã®ä½µç”¨å‘ã‘)"
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr "hg purge [OPTION]... [DIR]...\""
+
+msgid ""
+"command to move sets of revisions to a different ancestor\n"
+"\n"
+"This extension lets you rebase changesets in an existing Mercurial\n"
+"repository.\n"
+"\n"
+"For more information:\n"
+"http://mercurial.selenic.com/wiki/RebaseProject\n"
+msgstr ""
+"一連ã®ãƒªãƒ“ジョンを異ãªã‚‹å±¥æ­´ãƒ„リー上ã®ä½ç½®ã«ç§»å‹•ã•ã›ã‚‹ã‚³ãƒžãƒ³ãƒ‰\n"
+"\n"
+"本エクステンションã¯ã€æ—¢å­˜ã® Mercurial リãƒã‚¸ãƒˆãƒªã«ãŠã‘るリビジョンã®\n"
+"リベースをå¯èƒ½ã«ã—ã¾ã™ã€‚\n"
+"\n"
+"詳細ã¯ä»¥ä¸‹ã‚’å‚ç…§ã—ã¦ãã ã•ã„:\n"
+"http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject\n"
+
+msgid "first revision, do not change ancestor\n"
+msgstr "åˆæœŸãƒªãƒ“ジョンã®ãŸã‚ã€ç¥–先を変更ã—ã¾ã›ã‚“\n"
+
+msgid ""
+"move changeset (and descendants) to a different branch\n"
+"\n"
+" Rebase uses repeated merging to graft changesets from one part of\n"
+" history onto another. This can be useful for linearizing local\n"
+" changes relative to a master development tree.\n"
+"\n"
+" If a rebase is interrupted to manually resolve a merge, it can be\n"
+" continued with --continue/-c or aborted with --abort/-a.\n"
+" "
+msgstr ""
+"別ãªå±¥æ­´ä½ç½®ã¸ã®ãƒªãƒ“ジョン(ãŠã‚ˆã³ãã®å­å­«)ã®ç§»å‹•\n"
+"\n"
+" ã‚る履歴ä½ç½®ã‹ã‚‰åˆ¥ãªä½ç½®ã¸ã¨ãƒªãƒ“ジョンを移æ¤ã™ã‚‹ãŸã‚ã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯\n"
+" å復的ãªãƒžãƒ¼ã‚¸ã‚’行ãªã„ã¾ã™ã€‚ã“ã®æ©Ÿèƒ½ã¯ã€ä½œæ¥­é ˜åŸŸã«ãŠã‘ã‚‹æˆæžœã‚’開発\n"
+" 用ã®ãƒžã‚¹ã‚¿ãƒ¼ãƒªãƒã‚¸ãƒˆãƒªã«å映ã™ã‚‹éš›ã«ã€æžåˆ†ã‹ã‚Œã®ç„¡ã„状態ã«ã™ã‚‹ã‚ˆã†ãª\n"
+" å ´åˆã«æœ‰ç”¨ã§ã™ã€‚\n"
+"\n"
+" 手動マージã«ã‚ˆã‚‹è¡çªè§£æ¶ˆã®å¿…è¦ã‹ã‚‰ä¸­æ–­ã•れãŸå ´åˆã€--continue/-c ã§\n"
+" 処ç†ã‚’継続ã—ãŸã‚Šã€--abort/-a ã§å‡¦ç†ã‚’終了ã•ã›ãŸã‚Šã§ãã¾ã™ã€‚\n"
+" "
+
+msgid "cannot use both abort and continue"
+msgstr "--abort 㨠--continue ã¯ä½µç”¨ã§ãã¾ã›ã‚“"
+
+msgid "cannot use collapse with continue or abort"
+msgstr "--collapse 㯠--abort ã‚„ --continue ã¨ä½µç”¨ã§ãã¾ã›ã‚“"
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr "--abort ã‚„ --continue ã¯ã€ã‚Šãƒ“ジョン指定ã¨ä½µç”¨ã§ãã¾ã›ã‚“"
+
+msgid "cannot specify both a revision and a base"
+msgstr "--soruce 㨠--base ã¯ä½µç”¨ã§ãã¾ã›ã‚“"
+
+msgid "nothing to rebase\n"
+msgstr "リベースã®å¿…è¦ã¯ã‚りã¾ã›ã‚“\n"
+
+msgid "cannot use both keepbranches and extrafn"
+msgstr "--keepbranches 㨠--extrafn ã¯ä½µç”¨ã§ãã¾ã›ã‚“"
+
+msgid "rebase merging completed\n"
+msgstr "リベースã®ãƒžãƒ¼ã‚¸å‡¦ç†ãŒå®Œäº†\n"
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr "警告: ãƒªãƒ™ãƒ¼ã‚¹å…ƒã«æ–°è¦ãƒªãƒ“ジョンを検出ã—ãŸã®ã§ã€ç ´æ£„ã—ã¾ã›ã‚“\n"
+
+msgid "rebase completed\n"
+msgstr "リベース完了\n"
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr "%d 個ã®ãƒªãƒ“ジョンをスキップ\n"
+
+msgid " set parents\n"
+msgstr " 親リビジョンã®è¨­å®š\n"
+
+#, python-format
+msgid "rebasing %d:%s\n"
+msgstr " %d:%s ã®ãƒªãƒ™ãƒ¼ã‚¹ä¸­\n"
+
+#, python-format
+msgid " future parents are %d and %d\n"
+msgstr " リベース後ã®è¦ªãƒªãƒ“ジョン㯠%d 㨠%d\n"
+
+#, python-format
+msgid " update to %d:%s\n"
+msgstr " %d:%s ã¸ã¨æ›´æ–°\n"
+
+msgid " already in target\n"
+msgstr " æ—¢ã«å¯¾è±¡å†…\n"
+
+#, python-format
+msgid " merge against %d:%s\n"
+msgstr " %d:%s ã«å¯¾ã—ã¦ãƒžãƒ¼ã‚¸\n"
+
+msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgstr " 'hg resolve' ã§è¡çªè§£æ¶ˆã—ã¦ã‹ã‚‰ 'hg rebase --continue' ã—ã¦ãã ã•ã„"
+
+msgid "resuming interrupted rebase\n"
+msgstr "中断ã•れãŸãƒªãƒ™ãƒ¼ã‚¹ã®å†é–‹ä¸­\n"
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr "変更ãŒãªã„ã®ã§ã€ãƒªãƒ“ジョン %d をスキップ\n"
+
+#, python-format
+msgid "next revision set to %s\n"
+msgstr "次ã®ãƒªãƒ“ジョンを %s ã«è¨­å®š\n"
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr "親リビジョン㌠3 ã¤ã«ãªã‚‹ã®ã§ã€ãƒªãƒ“ジョン %d をベースã«ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "revision %d is an mq patch (%s), finalize it.\n"
+msgstr "リビジョン %d 㯠MQ パッãƒ(%s)ãªã®ã§ã€é€šå¸¸ãƒªãƒ“ジョン化\n"
+
+#, python-format
+msgid "import mq patch %d (%s)\n"
+msgstr "MQ パッム%d(%s) ã®å–り込ã¿\n"
+
+msgid "rebase status stored\n"
+msgstr "リベース状態ãŒä¿å­˜ã•れã¾ã—ãŸ\n"
+
+msgid "rebase status resumed\n"
+msgstr "リベース状態を復旧ã—ã¾ã—ãŸ\n"
+
+msgid "no rebase in progress"
+msgstr "進行中ã®ãƒªãƒ™ãƒ¼ã‚¹çŠ¶æ…‹ã¯ã‚りã¾ã›ã‚“"
+
+msgid "warning: new changesets detected on target branch, not stripping\n"
+msgstr "警告: æ–°è¦ãƒªãƒ“ジョンãŒå¯¾è±¡ãƒ–ランãƒã«æ¤œå‡ºã•れãŸã®ã§ã€ç ´æ£„ã—ã¾ã›ã‚“\n"
+
+msgid "rebase aborted\n"
+msgstr "リベースãŒä¸­æ–­ã•れã¾ã—ãŸ\n"
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr "MQ パッãƒä¸Šã¸ã®ãƒªãƒ™ãƒ¼ã‚¹ã¯ã§ãã¾ã›ã‚“"
+
+msgid "cannot rebase an ancestor"
+msgstr "先祖ã¸ã®ãƒªãƒ™ãƒ¼ã‚¹ã¯ã§ãã¾ã›ã‚“"
+
+msgid "cannot rebase a descendant"
+msgstr "å­å­«ã¸ã®ãƒªãƒ™ãƒ¼ã‚¹ã¯ã§ãã¾ã›ã‚“"
+
+msgid "already working on current\n"
+msgstr "æ—¢ã«ç¾è¡Œä½ç½®ã§ä½œæ¥­ä¸­\n"
+
+msgid "already working on the current branch\n"
+msgstr "æ—¢ã«ç¾è¡Œãƒ–ランãƒã§ä½œæ¥­ä¸­\n"
+
+#, python-format
+msgid "rebase onto %d starting from %d\n"
+msgstr "%d ã¸ã®ãƒªãƒ™ãƒ¼ã‚¹ã‚’ %d ã‹ã‚‰é–‹å§‹\n"
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr "複数ã®è¦ªã¨ã®é–¢ä¿‚ã‹ã‚‰ã€--collapse ã¯æŒ‡å®šã§ãã¾ã›ã‚“"
+
+msgid "--update and --rebase are not compatible, ignoring the update flag\n"
+msgstr "--update 㨠--rebase ã¯éžäº’æ›ã®ãŸã‚ã€--update ã¯ç„¡è¦–ã—ã¾ã™\n"
+
+msgid "rebase working directory to branch head"
+msgstr "作業領域をブランãƒãƒ˜ãƒƒãƒ‰ã«ãƒªãƒ™ãƒ¼ã‚¹"
+
+msgid "rebase from a given revision"
+msgstr "指定リビジョンをリベース"
+
+msgid "rebase from the base of a given revision"
+msgstr "指定リビジョンã‹ã‚‰å…ˆã‚’リベース"
+
+msgid "rebase onto a given revision"
+msgstr "ãƒªãƒ™ãƒ¼ã‚¹å…ˆãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŒ‡å®š"
+
+msgid "collapse the rebased revisions"
+msgstr "リベース後ã«ãƒªãƒ“ジョンを一体化"
+
+msgid "keep original revisions"
+msgstr "元リビジョンã®ç¶­æŒ"
+
+msgid "keep original branches"
+msgstr "元ブランãƒã®ç¶­æŒ"
+
+msgid "continue an interrupted rebase"
+msgstr "中断ã•れãŸãƒªãƒ™ãƒ¼ã‚¹ã‚’å†é–‹"
+
+msgid "abort an interrupted rebase"
+msgstr "中断ã•れãŸãƒªãƒ™ãƒ¼ã‚¹ã‚’中止"
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+msgstr ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+
+msgid "commands to interactively select changes for commit/qrefresh"
+msgstr "commit ã¾ãŸã¯ qrefresh 実行時ã«å¯¾è©±çš„ãªå¤‰æ›´é¸æŠžã‚’行ã†ã‚³ãƒžãƒ³ãƒ‰"
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr "ã“れã¯ãƒã‚¤ãƒŠãƒªãƒ•ァイルã«å¯¾ã™ã‚‹å¤‰æ›´ã§ã™(部分的ãªé¸æŠžã¯ä¸å¯èƒ½)\n"
+
+msgid "this is a binary file\n"
+msgstr "ã“れã¯ãƒã‚¤ãƒŠãƒªãƒ•ァイルã§ã™\n"
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr "%d 個ã®ãƒãƒ³ã‚¯ã€%d 行ã®å¤‰æ›´\n"
+
+msgid "[Ynsfdaq?]"
+msgstr "[Ynsfdaq?]"
+
+msgid "&Yes, record this change"
+msgstr "&Yes - ã“ã®å¤‰æ›´ã‚’記録ã—ã¾ã™"
+
+msgid "&No, skip this change"
+msgstr "&No - ã“ã®å¤‰æ›´ã‚’スキップã—ã¾ã™"
+
+msgid "&Skip remaining changes to this file"
+msgstr "&Skip - ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®æ®‹ã‚Šã®å¤‰æ›´ã‚’å…¨ã¦ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™"
+
+msgid "Record remaining changes to this &file"
+msgstr "&File - ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®æ®‹ã‚Šã®å¤‰æ›´ã‚’å…¨ã¦è¨˜éŒ²ã—ã¾ã™"
+
+msgid "&Done, skip remaining changes and files"
+msgstr "&Done - 残りã®å¤‰æ›´ãŠã‚ˆã³ãƒ•ァイルを全ã¦ã‚¹ã‚­ãƒƒãƒ—ã—ã¦çµ‚了ã—ã¾ã™"
+
+msgid "Record &all changes to all remaining files"
+msgstr "&All - 残りã®å¤‰æ›´ãŠã‚ˆã³ãƒ•ァイルを全ã¦è¨˜éŒ²ã—ã¾ã™"
+
+msgid "&Quit, recording no changes"
+msgstr "&Quit - 変更を記録ã—ãªã„ã§çµ‚了ã—ã¾ã™"
+
+msgid "&?"
+msgstr "&?"
+
+msgid "y"
+msgstr "y"
+
+msgid "?"
+msgstr "?"
+
+msgid "y - record this change"
+msgstr "y - ã“ã®å¤‰æ›´ã‚’記録ã—ã¾ã™"
+
+msgid "s"
+msgstr "s"
+
+msgid "f"
+msgstr "f"
+
+msgid "d"
+msgstr "d"
+
+msgid "a"
+msgstr "a"
+
+msgid "q"
+msgstr "q"
+
+msgid "user quit"
+msgstr "ãƒ¦ãƒ¼ã‚¶ã®æŒ‡ç¤ºã«ã‚ˆã‚Šçµ‚了ã—ã¾ã™"
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr "%s ã®å¤‰æ›´ç‚¹ã‚’調ã¹ã¾ã™ã‹?"
+
+msgid " and "
+msgstr " 㨠"
+
+#, python-format
+msgid "record this change to %r?"
+msgstr "ã“ã®å¤‰æ›´ã‚’ %r ã«è¨˜éŒ²ã—ã¾ã™ã‹?"
+
+#, python-format
+msgid "record change %d/%d to %r?"
+msgstr "ã“ã®å¤‰æ›´ (%d ä»¶ç›® / %d 件中) ã‚’ %r ã«è¨˜éŒ²ã—ã¾ã™ã‹?"
+
+msgid ""
+"interactively select changes to commit\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be candidates for recording.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" You will be prompted for whether to record changes to each\n"
+" modified file, and for files with multiple changes, for each\n"
+" change to use. For each query, the following responses are\n"
+" possible:\n"
+"\n"
+" y - record this change\n"
+" n - skip this change\n"
+"\n"
+" s - skip remaining changes to this file\n"
+" f - record remaining changes to this file\n"
+"\n"
+" d - done, skip remaining changes and files\n"
+" a - record all changes to all remaining files\n"
+" q - quit, recording no changes\n"
+"\n"
+" ? - display help"
+msgstr ""
+"コミットã™ã‚‹å†…容を対話的ã«é¸æŠžã—ã¾ã™\n"
+"\n"
+" ãƒ•ã‚¡ã‚¤ãƒ«ä¸€è¦§ãŒæŒ‡å®šã•れãªã‹ã£ãŸå ´åˆã¯ \"hg status\" ã§è¡¨ç¤ºã•れる\n"
+" å…¨ã¦ã®ãƒ•ァイルãŒè¨˜éŒ²ã®å¯¾è±¡ã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" -d/--date ã§ä½¿ç”¨ã™ã‚‹æ—¥æ™‚表記㯠'he help dates' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" 変更ã•れãŸãƒ•ァイルã®å¤‰æ›´ç®‡æ‰€ã”ã¨ã«è¨˜éŒ²ã™ã‚‹ã‹ã©ã†ã‹è³ªå•ã•れã¾ã™ã€‚\n"
+" ãれã«å¯¾ã—ã¦ä»¥ä¸‹ã®æ“作ãŒå¯èƒ½ã§ã™ï¼š\n"
+"\n"
+" y - ã“ã®å¤‰æ›´ã‚’記録ã—ã¾ã™\n"
+" n - ã“ã®å¤‰æ›´ã‚’スキップã—ã¾ã™\n"
+"\n"
+" s - ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®æ®‹ã‚Šã®å¤‰æ›´ã‚’å…¨ã¦ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™\n"
+" f - ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®æ®‹ã‚Šã®å¤‰æ›´ã‚’å…¨ã¦è¨˜éŒ²ã—ã¾ã™\n"
+"\n"
+" d - 残りã®å¤‰æ›´ãŠã‚ˆã³ãƒ•ァイルをスキップã—ã¦çµ‚了ã—ã¾ã™\n"
+" a - 残り全ã¦ã®ãƒ•ァイルã®å¤‰æ›´ã‚’記録ã—ã¾ã™\n"
+" q - 変更を記録ã—ãªã„ã§çµ‚了ã—ã¾ã™\n"
+"\n"
+" ? - ヘルプを表示ã—ã¾ã™"
+
+msgid "'mq' extension not loaded"
+msgstr "'mq' エクステンションãŒèª­ã¿è¾¼ã¾ã‚Œã¦ã„ã¾ã›ã‚“"
+
+msgid "running non-interactively, use commit instead"
+msgstr "éžå¯¾è©±çš„ã«å®Ÿè¡Œã™ã‚‹å ´åˆã¯ commit を使用ã—ã¦ãã ã•ã„"
+
+msgid "no changes to record\n"
+msgstr "記録å¯èƒ½ãªå¤‰æ›´ãŒã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "backup %r as %r\n"
+msgstr "%r ã‚’ %r ã¨ã—ã¦ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã—ã¾ã™\n"
+
+msgid "applying patch\n"
+msgstr "パッãƒã‚’é©ç”¨ä¸­\n"
+
+msgid "patch failed to apply"
+msgstr "パッãƒã®é©ç”¨ã«å¤±æ•—"
+
+#, python-format
+msgid "restoring %r to %r\n"
+msgstr "%r ã‹ã‚‰ %r ã«å¾©å…ƒä¸­\n"
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr "hg record [OPTION]... [FILE]..."
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr "hg qrecord [OPTION]... PATCH [FILE]..."
+
+msgid "share a common history between several working directories"
+msgstr ""
+
+msgid ""
+"create a new shared repository (experimental)\n"
+"\n"
+" Initialize a new repository and working directory that shares its\n"
+" history with another repository.\n"
+"\n"
+" NOTE: actions that change history such as rollback or moving the\n"
+" source may confuse sharers.\n"
+" "
+msgstr ""
+
+msgid "do not create a working copy"
+msgstr "ä½œæ¥­é ˜åŸŸã®æ›´æ–°ã‚’抑止ã—ã¾ã™"
+
+msgid "[-U] SOURCE [DEST]"
+msgstr "[-U] SOURCE [DEST]"
+
+msgid ""
+"command to transplant changesets from another branch\n"
+"\n"
+"This extension allows you to transplant patches from another branch.\n"
+"\n"
+"Transplanted patches are recorded in .hg/transplant/transplants, as a\n"
+"map from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+"別ブランãƒã‹ã‚‰ãƒ‘ッãƒã‚’ç§»æ¤ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰\n"
+"\n"
+"本エクステンションã¯ã€åˆ¥ãƒ–ランãƒã‹ã‚‰ã®ãƒ‘ッãƒã®ç§»æ¤ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚\n"
+"\n"
+"ç§»æ¤ã•れãŸãƒ‘ッãƒã®æƒ…å ±ã¯ã€ç§»æ¤å…ˆãƒªãƒ“ジョンã®ãƒãƒƒã‚·ãƒ¥å€¤ã‹ã‚‰ã€ç§»æ¤å…ƒ\n"
+"リãƒã‚¸ãƒˆãƒªã«ãŠã‘ã‚‹ãƒãƒƒã‚·ãƒ¥å€¤ã¸ã®å¤‰æ›ã¨ã—ã¦ã€.hg/transplant/transplants\n"
+"ã«è¨˜éŒ²ã•れã¾ã™ã€‚\n"
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr "ã™ã§ã«é©ç”¨ã—ãŸã‚Šãƒ“ジョン %s を飛ã°ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ %s:%s ã®ãƒžãƒ¼ã‚¸ã‚’飛ã°ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr "%s ã‚’ %s ã«ãƒžãƒ¼ã‚¸\n"
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr "%s ã‚’ %s ã«ç§»æ¤\n"
+
+#, python-format
+msgid "filtering %s\n"
+msgstr "%s をフィルタリング中\n"
+
+msgid "filter failed"
+msgstr "フィルターã«å¤±æ•—"
+
+msgid "can only omit patchfile if merging"
+msgstr "マージã®å ´åˆã®ã¿ãƒ‘ッãƒãƒ•ァイルをçœç•¥å¯èƒ½"
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr "%s: 空ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ"
+
+msgid "Fix up the merge and run hg transplant --continue"
+msgstr "è¡çªè§£æ¶ˆå¾Œã« 'hg transplant --continue' ã—ã¦ãã ã•ã„"
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr "%s ㌠%s ã¨ã—ã¦ç§»æ¤ã•れã¾ã—ãŸ\n"
+
+msgid "transplant log file is corrupt"
+msgstr "ç§»æ¤ãƒ­ã‚°ãƒ•ァイルãŒç ´æã—ã¦ã„ã¾ã™"
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr "作業領域ãŒç§»æ¤è¦ª %s ã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "commit failed"
+msgstr "コミットã«å¤±æ•—"
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’é©ç”¨ã—ã¾ã™ã‹? [ynmpcq?]:"
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+" Selected changesets will be applied on top of the current working\n"
+" directory with the log of the original changeset. If --log is\n"
+" specified, log messages will have a comment appended of the form:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" You can rewrite the changelog message with the --filter option.\n"
+" Its argument will be invoked with the current changelog message as\n"
+" $1 and the patch as $2.\n"
+"\n"
+" If --source/-s is specified, selects changesets from the named\n"
+" repository. If --branch/-b is specified, selects changesets from\n"
+" the branch holding the named revision, up to that revision. If\n"
+" --all/-a is specified, all changesets on the branch will be\n"
+" transplanted, otherwise you will be prompted to select the\n"
+" changesets you want.\n"
+"\n"
+" hg transplant --branch REVISION --all will rebase the selected\n"
+" branch (up to the named revision) onto your current working\n"
+" directory.\n"
+"\n"
+" You can optionally mark selected transplanted changesets as merge\n"
+" changesets. You will not be prompted to transplant any ancestors\n"
+" of a merged transplant, and you can merge descendants of them\n"
+" normally instead of transplanting them.\n"
+"\n"
+" If no merges or revisions are provided, hg transplant will start\n"
+" an interactive changeset browser.\n"
+"\n"
+" If a changeset application fails, you can fix the merge by hand\n"
+" and then resume where you left off by calling hg transplant\n"
+" --continue/-c.\n"
+" "
+msgstr ""
+"別ã®ãƒ–ランãƒã¸ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ç§»æ¤\n"
+"\n"
+" é¸æŠžã•れãŸãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã¯ã€å…ƒãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ã‚³ãƒŸãƒƒãƒˆãƒ­ã‚°ã¨ä¸€ç·’ã«\n"
+" ç¾åœ¨ã®ä½œæ¥­é ˜åŸŸä¸Šã«é©ç”¨ã•れã¾ã™ã€‚--log 指定ãŒã‚ã‚‹å ´åˆã€ä»¥ä¸‹ã®å½¢å¼ã®\n"
+" メッセージãŒè¿½åŠ ã•れã¾ã™:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" --filter ã«ã‚ˆã‚Šã‚³ãƒŸãƒƒãƒˆãƒ­ã‚°ã‚’改変ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚指定ã•れãŸå€¤ã¯\n"
+" コマンド起動ã«ä½¿ç”¨ã•れã€ç¬¬1引数ã«ã¯ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€ç¬¬2引数ã«ã¯\n"
+" パッãƒãŒæŒ‡å®šã•れã¾ã™ã€‚\n"
+"\n"
+" --source/-s ãŒæŒ‡å®šã•れãŸå ´åˆã€æŒ‡å®šã®ãƒªãƒã‚¸ãƒˆãƒªã‹ã‚‰ç§»æ¤ã•れã¾ã™ã€‚\n"
+" --branch/-b ãŒæŒ‡å®šã•れãŸå ´åˆã€æŒ‡å®šã®åå‰ã‚’æŒã¤ãƒ–ランãƒã‹ã‚‰ç§»æ¤\n"
+" ã•れã¾ã™ã€‚--all/-a ãŒæŒ‡å®šã•れãŸå ´åˆã€æŒ‡å®šã•れãŸãƒ–ランãƒä¸­ã®å…¨ã¦ã®\n"
+" ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆãŒç§»æ¤å¯¾å‡¦ã¨ãªã‚Šã€ãれ以外ã®å ´åˆã¯ç§»æ¤å¯¾è±¡ã¨ã™ã‚‹\n"
+" ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®å•ã„åˆã‚ã›ãŒã‚りã¾ã™ã€‚\n"
+"\n"
+" hg transplant --branch REVISION --all å½¢å¼ã§ã®èµ·å‹•ã®å ´åˆã€æŒ‡å®šã•れãŸ\n"
+" REVISION ã®å±žã™ã‚‹ãƒ–ランãƒä¸­ã®å…¨ã¦ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆãŒã€ç¾åœ¨ã®ä½œæ¥­é ˜åŸŸ\n"
+" 上ã«ç§»æ¤ã•れã¾ã™ã€‚\n"
+"\n"
+" é¸æŠžã—ãŸå¯¾è±¡ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ç§»æ¤ã‚’ã€ãƒžãƒ¼ã‚¸å®Ÿæ–½ã¨ã¿ãªã™ã“ã¨ã‚‚å¯èƒ½\n"
+" ã§ã™ã€‚ç§»æ¤ã®éš›ã«ãƒžãƒ¼ã‚¸å¯¾è±¡ãƒªãƒ“ジョンã«é–¢ã™ã‚‹å•ã„åˆã‚ã›ã¯ç„¡ãã€ç§»æ¤\n"
+" 後ã®ç§»æ¤å…ƒã®å­å­«ã«å¯¾ã—ã¦ã¯ã€ç§»æ¤ã§ã¯ãªã通常ã®ãƒžãƒ¼ã‚¸ãŒå¯èƒ½ã§ã™ã€‚\n"
+"\n"
+" マージ対象もリビジョン指定もãªã„å ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯å¯¾è©±çš„ã«ç§»æ¤ã‚’\n"
+" 行ãªã„ã¾ã™ã€‚\n"
+"\n"
+" ç§»æ¤ã«å¤±æ•—ã—ãŸå ´åˆã€æ‰‹å‹•ã§ã®è¡çªè§£æ¶ˆå¾Œã« --continue/-c を指定ã—ã¦\n"
+" 本コマンドをå†å®Ÿè¡Œã™ã‚‹ã“ã¨ã§ã€ä¸­æ–­ã•れãŸç§»æ¤ã‚’å†é–‹å¯èƒ½ã§ã™ã™ã€‚\n"
+" "
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr "--continue 㯠--branchã€--allã€--merge ã¨ä½µç”¨ã§ãã¾ã›ã‚“"
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr "å…ƒ URLã€ãƒ–ランãƒã‚¿ã‚°ã€ãƒªãƒ“ジョン指定ã®ã„ãšã‚Œã‚‚指定ã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "--all requires a branch revision"
+msgstr "--all 指定ã«ã¯ãƒ–ランãƒãƒªãƒ“ジョンãŒå¿…è¦ã§ã™"
+
+msgid "--all is incompatible with a revision list"
+msgstr "--all ã¨ãƒªãƒ“ジョン指定ã¯ä½µç”¨ã§ãã¾ã›ã‚“"
+
+msgid "no revision checked out"
+msgstr "ä½œæ¥­é ˜åŸŸãŒæœªæ›´æ–°ã§ã™"
+
+msgid "outstanding uncommitted merges"
+msgstr "ãƒžãƒ¼ã‚¸ãŒæœªã‚³ãƒŸãƒƒãƒˆã§ã™"
+
+msgid "outstanding local changes"
+msgstr "未コミットã®å¤‰æ›´ãŒã‚りã¾ã™"
+
+msgid "pull patches from REPOSITORY"
+msgstr "パッãƒå–り込ã¿å…ƒãƒªãƒã‚¸ãƒˆãƒªã®æŒ‡å®š"
+
+msgid "pull patches from branch BRANCH"
+msgstr "パッãƒå–り込ã¿å…ƒãƒ–ランãƒã®æŒ‡å®š"
+
+msgid "pull all changesets up to BRANCH"
+msgstr "指定ブランãƒã®å…¨ã¦ã‚’å–り込む"
+
+msgid "skip over REV"
+msgstr "指定リビジョンã®ã‚¹ã‚­ãƒƒãƒ—"
+
+msgid "merge at REV"
+msgstr "指定リビジョンã«ãŠã‘るマージ"
+
+msgid "append transplant info to log message"
+msgstr "コミットログã¸ã®ç§»æ¤æƒ…å ±ã®ä»˜ä¸Ž"
+
+msgid "continue last transplant session after repair"
+msgstr "中断ã•れãŸç›´å‰ã®ç§»æ¤ä½œæ¥­ã®å†é–‹"
+
+msgid "filter changesets through FILTER"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ãƒ•ィルタ指定"
+
+msgid ""
+"hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr ""
+"hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+
+msgid ""
+"allow the use of MBCS paths with problematic encodings\n"
+"\n"
+"Some MBCS encodings are not good for some path operations (i.e.\n"
+"splitting path, case conversion, etc.) with its encoded bytes. We call\n"
+"such a encoding (i.e. shift_jis and big5) as \"problematic encoding\".\n"
+"This extension can be used to fix the issue with those encodings by\n"
+"wrapping some functions to convert to Unicode string before path\n"
+"operation.\n"
+"\n"
+"This extension is useful for:\n"
+" * Japanese Windows users using shift_jis encoding.\n"
+" * Chinese Windows users using big5 encoding.\n"
+" * All users who use a repository with one of problematic encodings on\n"
+" case-insensitive file system.\n"
+"\n"
+"This extension is not needed for:\n"
+" * Any user who use only ASCII chars in path.\n"
+" * Any user who do not use any of problematic encodings.\n"
+"\n"
+"Note that there are some limitations on using this extension:\n"
+" * You should use single encoding in one repository.\n"
+" * You should set same encoding for the repository by locale or\n"
+" HGENCODING.\n"
+"\n"
+"Path encoding conversion are done between Unicode and\n"
+"encoding.encoding which is decided by Mercurial from current locale\n"
+"setting or HGENCODING.\n"
+msgstr ""
+"å•題ã®ã‚る文字コードã§ã®å¤šãƒã‚¤ãƒˆç¬¦å·åŒ–文字を使用ã—ãŸãƒ‘スåã®æœ‰åŠ¹åŒ–\n"
+"\n"
+"パスåã®å–り扱ã„(例: パスè¦ç´ ã®åˆ†å‰²ã€æ–‡å­—大å°å¤‰æ›ç­‰)上ã€ä¸é©åˆ‡ãªæ–‡å­—ã‚’\n"
+"å«ã‚€å¤šãƒã‚¤ãƒˆç¬¦å·åŒ–文字セット(MBCS)ãŒå­˜åœ¨ã—ã¾ã™ã€‚ã“ã“ã§ã¯ãã®ã‚ˆã†ãªæ–‡å­—\n"
+"セット(例: shift_jis ãŠã‚ˆã³ big5)を「å•題文字コードã€ã¨å‘¼ã³ã¾ã™ã€‚\n"
+"本エクステンションã¯ã€ãƒ‘スæ“作ã®å®Ÿæ–½å‰ã« unicode 文字列化ã™ã‚‹å‡¦ç†ã‚’\n"
+"割り込ã¾ã›ã‚‹ã“ã¨ã§ã€å•題文字コードã«ã‚ˆã£ã¦ç™ºç”Ÿã™ã‚‹éšœå®³ã‚’防ãŽã¾ã™ã€‚\n"
+"\n"
+"ã“ã®ã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³ã¯ä»¥ä¸‹ã®å ´åˆã«æœ‰ç”¨ã§ã™:\n"
+"\n"
+" * shift_jis 文字コードを使用ã™ã‚‹æ—¥æœ¬èªž Windows ã®ãƒ¦ãƒ¼ã‚¶\n"
+" * big5 文字コードを使用ã™ã‚‹ä¸­å›½èªž Windows ã®ãƒ¦ãƒ¼ã‚¶\n"
+" * 文字大å°ã‚’区別ã§ããªã„ファイルシステム上ã§ã€å•題文字コードを\n"
+" 使用ã—ãŸãƒªãƒã‚¸ãƒˆãƒªã‚’é‹ç”¨ã™ã‚‹ãƒ¦ãƒ¼ã‚¶\n"
+"\n"
+"ã“ã®ã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³ã¯ä»¥ä¸‹ã®å ´åˆã«ã¯ä¸è¦ã§ã™:\n"
+"\n"
+" * パスåã« ascii 文字ã—ã‹ä½¿ç”¨ã—ãªã„ユーザ\n"
+" * å•題文字コードを使用ã—ãªã„ユーザ\n"
+"\n"
+"ã“ã®ã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³ã®åˆ©ç”¨ã«ã¯å¹¾ã¤ã‹ã®åˆ¶é™ãŒã‚りã¾ã™:\n"
+"\n"
+" * リãƒã‚¸ãƒˆãƒªå†…ã§ã¯å˜ä¸€ã®æ–‡å­—コードを使用ã—ã¦ãã ã•ã„\n"
+" * ロケール設定ãªã‚Š HGENCODING 環境変数ãªã‚Šã®è¨­å®šã‚’ã€ãƒªãƒã‚¸ãƒˆãƒªã§\n"
+" 使用ã™ã‚‹æ–‡å­—コードã¨åŒã˜ã‚‚ã®ã«ã—ã¦ãã ã•ã„\n"
+"\n"
+"パスåã®æ–‡å­—コード変æ›ã¯ã€unicode ã¨ã€ãƒ­ã‚±ãƒ¼ãƒ«è¨­å®šãªã„ã— HGENCODING\n"
+"環境変数ã«ã‚ˆã£ã¦ Mercurial ãŒæ±ºå®šã™ã‚‹æ–‡å­—コードã¨ã®é–“ã§è¡Œãªã‚れã¾ã™ã€‚\n"
+
+#, python-format
+msgid "[win32mbcs] filename conversion fail with %s encoding\n"
+msgstr "[win32mbcs] 文字コード '%s' ã¨ã®é–“ã§ã®å¤‰æ›ã«å¤±æ•—\n"
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr "[win32mbcs] ã“ã®ãƒ—ラットフォームã§ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“。\n"
+
+#, python-format
+msgid "[win32mbcs] activated with encoding: %s\n"
+msgstr "[win32mbcs] 文字コード %s ã¨ã®é–“ã§ã®å¤‰æ›ã‚’有効化\n"
+
+msgid ""
+"perform automatic newline conversion\n"
+"\n"
+"To perform automatic newline conversion, use:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = cleverencode:\n"
+"# or ** = macencode:\n"
+"\n"
+"[decode]\n"
+"** = cleverdecode:\n"
+"# or ** = macdecode:\n"
+"\n"
+"If not doing conversion, to make sure you do not commit CRLF/CR by "
+"accident:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxncommit.cr = python:hgext.win32text.forbidcr\n"
+"\n"
+"To do the same check on a server to prevent CRLF/CR from being\n"
+"pushed or pulled:\n"
+"\n"
+"[hooks]\n"
+"pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxnchangegroup.cr = python:hgext.win32text.forbidcr\n"
+msgstr ""
+"改行形å¼ã®è‡ªå‹•変æ›\n"
+"\n"
+"改行形å¼ã®è‡ªå‹•変æ›ã‚’行ã†å ´åˆã€ä»¥ä¸‹ã®ã‚ˆã†ã«è¨­å®šã—ã¾ã™:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = cleverencode:\n"
+"# ãªã„ã— ** = macencode:\n"
+"\n"
+"[decode]\n"
+"** = cleverdecode:\n"
+"# ãªã„ã— ** = macdecode:\n"
+"\n"
+"変æ›ã¯ã—ãªã„ã‚‚ã®ã®ã€é–“é•ã£ãŸæ”¹è¡Œå½¢å¼ã§ã®ã‚³ãƒŸãƒƒãƒˆã‚’防止ã—ãŸã„å ´åˆã¯:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n"
+"# ãªã„ã— pretxncommit.cr = python:hgext.win32text.forbidcr\n"
+"\n"
+"æ„図ã›ã¬å±¥æ­´å映ã®é˜²æ­¢ã®ãŸã‚ã«ã€ã‚µãƒ¼ãƒå´ã§åŒæ§˜ã®ç¢ºèªã‚’行ã„ãŸã„å ´åˆã¯:\n"
+"\n"
+"[hooks]\n"
+"pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf\n"
+"# ãªã„ã— pretxnchangegroup.cr = python:hgext.win32text.forbidcr\n"
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+"警告: %s ã¯æ—¢ã«è¡Œæœ«ãŒ %s å½¢å¼ã§ã™\n"
+"ãã®ãŸã‚ win32text ã«ã‚ˆã‚‹è¡Œæœ«å½¢å¼å¤‰æ›ã¯ä¸è¦ã§ã™ã€‚\n"
+"次回㮠commit ã¾ã§ã«ã€Mercurial.ini ãªã‚Š %s ã«ãŠã‘ã‚‹ encode/decode 設定を\n"
+"見直ã™ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚\n"
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr "テキストファイルã®è¡Œæœ«å½¢å¼ %s ã«ã‚ˆã‚‹ commit ãªã„ã—å±¥æ­´åæ˜ ã‚’実施\n"
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr "リビジョン %s: %s\n"
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"and also consider adding:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+"\n"
+"åŒæ§˜ã®é–“é•ã„を防ãã«ã¯ã€ä»¥ä¸‹ã®è¨­å®šã‚’ Mercurial.ini ãªã„ã— .hg/hgrc ã«\n"
+"以下ã®è¨˜è¿°ã‚’追加ã—ã¦ãã ã•ã„:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"å¿…è¦ã§ã‚れã°ä»¥ä¸‹ã®è¨˜è¿°ã‚‚追加ã—ã¦ãã ã•ã„:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+
+msgid ""
+"discover and advertise repositories on the local network\n"
+"\n"
+"Zeroconf enabled repositories will be announced in a network without\n"
+"the need to configure a server or a service. They can be discovered\n"
+"without knowing their actual IP address.\n"
+"\n"
+"To allow other people to discover your repository using run \"hg serve\"\n"
+"in your repository.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"You can discover zeroconf enabled repositories by running \"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+msgstr ""
+
+msgid "archive prefix contains illegal components"
+msgstr "ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã®æŽ¥é ­è¾žãŒä¸æ­£ãªã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆã‚’å«ã¿ã¾ã™"
+
+msgid "cannot give prefix when archiving to files"
+msgstr "アーカイブã«ãƒ•ァイルを追加ã™ã‚‹ã¨ãã¯æŽ¥é ­è¾žã‚’æŒ‡å®šã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr "未知ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–種別 '%s'"
+
+msgid "invalid changegroup"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚°ãƒ«ãƒ¼ãƒ—ãŒä¸æ­£ã§ã™"
+
+msgid "unknown parent"
+msgstr "未知ã®è¦ª"
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr "%s:%d ã®ä¸€è²«æ€§ãƒã‚§ãƒƒã‚¯ã«å¤±æ•—"
+
+#, python-format
+msgid "%s: not a Mercurial bundle file"
+msgstr "%s: Mercurial ã«ãƒãƒ³ãƒ‰ãƒ«ã•れãŸãƒ•ァイルã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "%s: unknown bundle version"
+msgstr "%s: 未知ã®ãƒãƒ³ãƒ‰ãƒ«ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#, python-format
+msgid "%s: unknown bundle compression type"
+msgstr "%s: 未知ã®ãƒãƒ³ãƒ‰ãƒ«åœ§ç¸®æ–¹æ³•"
+
+msgid "cannot create new bundle repository"
+msgstr "ãƒãƒ³ãƒ‰ãƒ«ãƒªãƒã‚¸ãƒˆãƒªã®æ–°è¦ä½œæˆã¯ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgstr "予期ã—ãªã„ EOF (%d ãƒã‚¤ãƒˆã®ã¿èª­è¾¼æ¸ˆã€æœ¬å½“㯠%d ãƒã‚¤ãƒˆ)"
+
+msgid "empty username"
+msgstr "ユーザåãŒç©ºã§ã™"
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr "ユーザå %s ãŒæ”¹è¡Œã‚’å«ã‚“ã§ã„ã¾ã™"
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr "--message 㨠--logfile ã¯åŒæ™‚ã«æŒ‡å®šã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr "コミットメッセージ '%s' を読ã¿è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“: %s"
+
+msgid "limit must be a positive integer"
+msgstr "制é™ã¯æ­£æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid "limit must be positive"
+msgstr "制é™ã¯æ­£æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid "too many revisions specified"
+msgstr "ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŒ‡å®šãŒå¤šã™ãŽã¾ã™"
+
+#, python-format
+msgid "invalid format spec '%%%s' in output filename"
+msgstr "出力ファイルåã«ä¸æ­£ãªãƒ•ォーマット '%%%s' 指定"
+
+#, python-format
+msgid "adding %s\n"
+msgstr "%s を追加登録中\n"
+
+#, python-format
+msgid "removing %s\n"
+msgstr "%s を登録除外中\n"
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr "%s ã®å‰Šé™¤ã‚’ %s ã¸ã®ãƒ•ァイルå変更ã¨ã—ã¦è¨˜éŒ²ä¸­ (類似度 %d%%)\n"
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr "%s: コピー失敗 - ファイルã¯ç™»éŒ²ã•れã¦ã„ã¾ã›ã‚“\n"
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr "%s: コピー失敗 - 削除予定ã®ãƒ•ァイルã§ã™\n"
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr "%s: 上書ã失敗 - %s 㯠%s ã¨è¡çª\n"
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr "%s: 上書ãã—ã¾ã›ã‚“ - ファイルãŒå­˜åœ¨ã—ã¾ã™\n"
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr "%s: 作業コピーã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸ\n"
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr "%s: コピー失敗 - %s\n"
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr "%s ã‚’ %s ã«ç§»å‹•中\n"
+
+#, python-format
+msgid "copying %s to %s\n"
+msgstr "%s ã‚’ %s ã«ã‚³ãƒ”ー中\n"
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr "%s ã¯æœªã‚³ãƒŸãƒƒãƒˆãªã®ã§ã€%s ã®ã‚³ãƒ”ãƒ¼ãƒ‡ãƒ¼ã‚¿ã¯æ®‹ã‚Šã¾ã›ã‚“\n"
+
+msgid "no source or destination specified"
+msgstr "作業元もã—ãã¯ä½œæ¥­å…ˆã‚’指定ã—ã¦ã„ã¾ã›ã‚“"
+
+msgid "no destination specified"
+msgstr "作業先を指定ã—ã¦ã„ã¾ã›ã‚“"
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr "複数ã®ä½œæ¥­å…ƒã®å ´åˆã€ä½œæ¥­å…ˆã¯å­˜åœ¨ã™ã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr "作業先 %s ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "no files to copy"
+msgstr "コピーã™ã‚‹ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+msgid "(consider using --after)\n"
+msgstr "( --after を使ã£ã¦ã¿ã¦ã¯? )\n"
+
+#, python-format
+msgid "changeset: %d:%s\n"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ: %d:%s\n"
+
+#, python-format
+msgid "branch: %s\n"
+msgstr "ブランãƒ: %s\n"
+
+#, python-format
+msgid "tag: %s\n"
+msgstr "ã‚¿ã‚°: %s\n"
+
+#, python-format
+msgid "parent: %d:%s\n"
+msgstr "親: %d:%s\n"
+
+#, python-format
+msgid "manifest: %d:%s\n"
+msgstr "管ç†ãƒ•ァイル一覧: %d:%s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "ユーザ: %s\n"
+
+#, python-format
+msgid "date: %s\n"
+msgstr "日付: %s\n"
+
+msgid "files+:"
+msgstr "ファイル追加:"
+
+msgid "files-:"
+msgstr "ファイル削除:"
+
+msgid "files:"
+msgstr "ファイル:"
+
+#, python-format
+msgid "files: %s\n"
+msgstr "ファイル: %s\n"
+
+#, python-format
+msgid "copies: %s\n"
+msgstr "コピー %s\n"
+
+#, python-format
+msgid "extra: %s=%s\n"
+msgstr "ãã®ä»–: %s=%s\n"
+
+msgid "description:\n"
+msgstr "説明:\n"
+
+#, python-format
+msgid "summary: %s\n"
+msgstr "è¦ç´„: %s\n"
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr "%s: '%s' ã¨ã„ã†ã‚­ãƒ¼ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr "リビジョン %s ã‚’ %s ã§è¦‹ã¤ã‘ã¾ã—ãŸ\n"
+
+msgid "revision matching date not found"
+msgstr "リビジョンã«ä¸€è‡´ã™ã‚‹æ—¥ä»˜ãŒã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr "存在ã—ãªã„ファイルを追跡ã§ãã¾ã›ã‚“: \"%s\""
+
+#, python-format
+msgid "%s:%s copy source revision cannot be found!\n"
+msgstr "%s:%s コピー元ã®ãƒªãƒ“ジョンãŒã‚りã¾ã›ã‚“!\n"
+
+msgid "can only follow copies/renames for explicit filenames"
+msgstr "ファイルåãŒæ˜Žç¤ºã•れãŸå ´åˆã®ã¿è¤‡è£½/改åを追跡å¯èƒ½ã§ã™"
+
+msgid "HG: Enter commit message. Lines beginning with 'HG:' are removed."
+msgstr ""
+"HG: コミットメッセージを入力ã—ã¦ãã ã•ã„。 HG: ã§å§‹ã¾ã‚‹è¡Œã¯ç„¡è¦–ã•れã¾ã™ã€‚"
+
+msgid "HG: Leave message empty to abort commit."
+msgstr "HG: メッセージãŒç©ºã ã¨ã‚³ãƒŸãƒƒãƒˆã§ãã¾ã›ã‚“。"
+
+#, python-format
+msgid "HG: user: %s"
+msgstr "HG: ユーザ: %s"
+
+msgid "HG: branch merge"
+msgstr "HG: ブランãƒã®ãƒžãƒ¼ã‚¸"
+
+#, python-format
+msgid "HG: branch '%s'"
+msgstr "HG: ブランム'%s'"
+
+#, python-format
+msgid "HG: added %s"
+msgstr "HG: %s を追加"
+
+#, python-format
+msgid "HG: changed %s"
+msgstr "HG: %s を変更"
+
+#, python-format
+msgid "HG: removed %s"
+msgstr "HG: %s を削除"
+
+#
+msgid "HG: no files changed"
+msgstr "HG: ファイル変更ãªã—"
+
+msgid "empty commit message"
+msgstr "コミットメッセージãŒã‚りã¾ã›ã‚“"
+
+msgid ""
+"add the specified files on the next commit\n"
+"\n"
+" Schedule files to be version controlled and added to the\n"
+" repository.\n"
+"\n"
+" The files will be added to the repository at the next commit. To\n"
+" undo an add before that, see hg forget.\n"
+"\n"
+" If no names are given, add all files to the repository.\n"
+" "
+msgstr ""
+"指定ファイルã®è¿½åŠ ç™»éŒ²äºˆç´„\n"
+"\n"
+" æ§‹æˆç®¡ç†ã¸ã®ãƒ•ァイルã®è¿½åŠ ç™»éŒ²ã‚’äºˆç´„ã—ã¾ã™ã€‚\n"
+"\n"
+" 指定ã•れãŸãƒ•ã‚¡ã‚¤ãƒ«ã¯æ¬¡å›žã®ã‚³ãƒŸãƒƒãƒˆã‹ã‚‰æ§‹æˆç®¡ç†å¯¾è±¡ã¨ãªã‚Šã¾ã™ã€‚\n"
+" コミットå‰ã®è¿½åŠ ç™»éŒ²ã®å–り消ã—ã¯ã€'hg help revert' ã‚’å‚ç…§ã—ã¦\n"
+" ãã ã•ã„。\n"
+"\n"
+" ãƒ•ã‚¡ã‚¤ãƒ«åæŒ‡å®šãŒç„¡ã„å ´åˆã€ä½œæ¥­é ˜åŸŸä¸­ã®å…¨ãƒ•ァイルãŒå¯¾è±¡ã¨ãªã‚Šã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"add all new files, delete all missing files\n"
+"\n"
+" Add all new files and remove all missing files from the\n"
+" repository.\n"
+"\n"
+" New files are ignored if they match any of the patterns in\n"
+" .hgignore. As with add, these changes take effect at the next\n"
+" commit.\n"
+"\n"
+" Use the -s/--similarity option to detect renamed files. With a\n"
+" parameter > 0, this compares every removed file with every added\n"
+" file and records those similar enough as renames. This option\n"
+" takes a percentage between 0 (disabled) and 100 (files must be\n"
+" identical) as its parameter. Detecting renamed files this way can\n"
+" be expensive.\n"
+" "
+msgstr ""
+"æ–°è¦ãƒ•ァイルã®è¿½åŠ ç™»éŒ²ã€ãŠã‚ˆã³ä¸åœ¨ãƒ•ァイルã®ç™»éŒ²é™¤å¤–\n"
+"\n"
+" ä½œæ¥­é ˜åŸŸä¸­ã®æ–°è¦ãƒ•ァイルã®è¿½åŠ ç™»éŒ²ã€ãŠã‚ˆã³ä¸åœ¨ãƒ•ァイルã®ç™»éŒ²é™¤å¤–ã‚’\n"
+" 行ãªã„ã¾ã™ã€‚\n"
+"\n"
+" .hgignore ã«è¨˜è¿°ã•れãŸãƒ‘ターンã«åˆè‡´ã™ã‚‹æ–°è¦ãƒ•ァイルã¯ç„¡è¦–ã•れã¾ã™ã€‚\n"
+" 'hg add' ã¨åŒæ§˜ã«ã€å®Ÿè¡ŒåŠ¹æžœãŒç™ºæ®ã•れるã®ã¯æ¬¡å›žã‚³ãƒŸãƒƒãƒˆæ™‚点ã§ã™ã€‚\n"
+"\n"
+" ãƒ•ã‚¡ã‚¤ãƒ«ã®æ”¹åを検知ã™ã‚‹ã«ã¯ -s/--similarity を使用ã—ã¾ã™ã€‚0 より\n"
+" 大ããªå€¤ãŒæŒ‡å®šã•れãŸå ´åˆã€è¿½åŠ ãƒ»é™¤å¤–ãƒ•ã‚¡ã‚¤ãƒ«ã®å…¨ã¦ãŒæ¯”較ã•ã‚Œã€æ”¹åã¨\n"
+" ã¿ãªã›ã‚‹ã‹å¦ã‹ãŒåˆ¤å®šã•れã¾ã™ã€‚ã“ã®ã‚ªãƒ—ションã«ã¯ã€0(æ”¹åæ¯”較無効)\n"
+" ã‹ã‚‰ 100 (完全一致)ã¾ã§ã®ç¯„囲ã§ãƒ‘ーセンテージを指定ã—ã¾ã™ã€‚改å判定\n"
+" ã«ã¯å®Ÿè¡Œæ™‚é–“ã‚’è¦ã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n"
+" "
+
+msgid "similarity must be a number"
+msgstr "é¡žä¼¼åº¦ã¯æ•°å€¤ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid "similarity must be between 0 and 100"
+msgstr "類似度ã¯0ã‹ã‚‰100ã®é–“ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid ""
+"show changeset information by line for each file\n"
+"\n"
+" List changes in files, showing the revision id responsible for\n"
+" each line\n"
+"\n"
+" This command is useful for discovering when a change was made and\n"
+" by whom.\n"
+"\n"
+" Without the -a/--text option, annotate will avoid processing files\n"
+" it detects as binary. With -a, annotate will annotate the file\n"
+" anyway, although the results will probably be neither useful\n"
+" nor desirable.\n"
+" "
+msgstr ""
+"ファイル行毎ã®ãƒªãƒ“ジョン情報表示\n"
+"\n"
+" ファイルã®å„行毎ã«ã€ãã®å†…容ãŒç”±æ¥ã™ã‚‹ãƒªãƒ“ジョンIDを表示ã—ã¾ã™ã€‚\n"
+"\n"
+" 本コマンドã¯ã€å¤‰æ›´ã®å®Ÿæ–½è€…ãªã„ã—実施時期を特定ã™ã‚‹ã®ã«æœ‰ç”¨ã§ã™ã€‚\n"
+"\n"
+" -a/--text 指定ãŒç„¡ã„å ´åˆã€ãƒã‚¤ãƒŠãƒªã¨æ€ã—ãファイルã¯å‡¦ç†å¯¾è±¡ã‹ã‚‰\n"
+" 除外ã•れã¾ã™ã€‚-a æŒ‡å®šãŒæœ‰ã‚‹å ´åˆã€çµæžœã«é–¢ã‚らãšå…¨ã¦ã®ãƒ•ァイルãŒ\n"
+" 処ç†å¯¾è±¡ã¨ãªã‚Šã¾ã™ã€‚\n"
+" "
+
+msgid "at least one filename or pattern is required"
+msgstr "ファイルåãªã„ã—パターンを最低1ã¤æŒ‡å®šã—ã¦ãã ã•ã„"
+
+msgid "at least one of -n/-c is required for -l"
+msgstr "-l 指定時ã«ã¯ -n/-c ã®ã†ã¡æœ€ä½Žã§ã‚‚ã„ãšã‚Œã‹1ã¤ã®æŒ‡å®šãŒå¿…è¦ã§ã™"
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr "%s: ãƒã‚¤ãƒŠãƒªãƒ•ァイルã§ã™\n"
+
+msgid ""
+"create an unversioned archive of a repository revision\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use -r/--rev to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use -t/--type. Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see 'hg help export' for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use -p/--prefix to specify a format string for the\n"
+" prefix. The default is the basename of the archive, with suffixes\n"
+" removed.\n"
+" "
+msgstr ""
+"リãƒã‚¸ãƒˆãƒªå¤–ã¸ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã®ç”Ÿæˆ\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€ä½œæ¥­é ˜åŸŸã®è¦ªãƒªãƒ“ジョンãŒä½¿ç”¨ã•れã¾ã™ã€‚\n"
+" ä»–ã®ãƒªãƒ“ジョンを指定ã™ã‚‹å ´åˆã¯ -r/--rev を使用ã—ã¾ã™ã€‚\n"
+"\n"
+" 生æˆã™ã‚‹ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã®ç¨®åˆ¥ã‚’指定ã™ã‚‹å ´åˆã¯ã€-t/--type を使用ã—ã¾ã™ã€‚\n"
+" 使用å¯èƒ½ãªç¨®åˆ¥ã¯:\n"
+"\n"
+" \"files\": 展開済ã¿ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã®ã‚¤ãƒ¡ãƒ¼ã‚¸(無指定時)\n"
+" \"tar\" : éžåœ§ç¸®ã® tar アーカイブ形å¼\n"
+" \"tbz2\" : bzip2 圧縮㮠tar アーカイブ形å¼\n"
+" \"tgz\" : gzip 圧縮㮠tar アーカイブ形å¼\n"
+" \"uzip\" : éžåœ§ç¸®ã® zip アーカイブ形å¼\n"
+" \"zip\" : deflate 圧縮㮠zip アーカイブ形å¼\n"
+"\n"
+" アーカイブ生æˆå…ˆã¨ãªã‚‹ãƒ•ァイルåãªã„ã—ディレクトリåã®æŒ‡å®šã«ã¯\n"
+" ç½®æ›æŒ‡å®šã‚’使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ç½®æ›æŒ‡å®šã«é–¢ã™ã‚‹è©³ç´°ã¯ \n"
+" 'hg help export' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" アーカイブ生æˆã®éš›ã«ã¯ã€å±•é–‹æ™‚ã®æ ¼ç´å…ˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªåãŒè¨˜éŒ²ã•れã¾ã™ã€‚\n"
+" -p/--prefix ã«ã‚ˆã‚Šãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªåを指定ã§ãã¾ã™(ç½®æ›æŒ‡å®šå¯èƒ½)。特ã«\n"
+" 指定ãŒç„¡ã„å ´åˆã¯ã€ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–åã‹ã‚‰æ‹¡å¼µå­ã‚’除ã„ãŸã‚‚ã®ãŒè¨˜éŒ²ã•れã¾ã™ã€‚\n"
+" "
+
+msgid "no working directory: please specify a revision"
+msgstr "作業領域ã«ã‚ˆã‚‹æš—黙指定ãŒã§ãã¾ã›ã‚“ã®ã§ãƒªãƒ“ジョンを明示ã—ã¦ãã ã•ã„"
+
+msgid "repository root cannot be destination"
+msgstr "リãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆã‚’作æˆå…ˆã«æŒ‡å®šã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid "cannot archive plain files to stdout"
+msgstr "通常ファイルã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–å…ˆã«æ¨™æº–出力を指定ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid ""
+"reverse effect of earlier changeset\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you backout a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head.\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by hand.\n"
+" The result of this merge is not committed, as with a normal merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"以å‰ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã«ãŠã‘ã‚‹å¤‰æ›´ã®æ‰“ã¡æ¶ˆã—\n"
+"\n"
+" æ‰“ã¡æ¶ˆã—用ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’æ–°è¦ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã¨ã—ã¦ã‚³ãƒŸãƒƒãƒˆã—ã¾ã™ã€‚\n"
+" æ–°è¦ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã¯ã€æ‰“消ã—対象ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®å­ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ\n"
+" ã¨ã—ã¦ä½œæˆã•れã¾ã™ã€‚\n"
+"\n"
+" tip 以外ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’æ‰“ã¡æ¶ˆã™å ´åˆã€æ–°è¦ãƒ˜ãƒƒãƒ‰ãŒç”Ÿæˆã•れã¾ã™ã€‚\n"
+" ã“ã®ãƒ˜ãƒƒãƒ‰ã¯æ–°è¦ tip ã¨ãªã‚Šã¾ã™ã®ã§ã€ã“ã®æ‰“ã¡æ¶ˆã—ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã¨\n"
+" ä»–ã®ãƒ˜ãƒƒãƒ‰(é€šå¸¸ã¯æ‰“ã¡æ¶ˆã—実施å‰ã®ãƒ˜ãƒƒãƒ‰)をマージã—ã¦ãã ã•ã„。\n"
+"\n"
+" --merge 指定時ã¯ã€å‡¦ç†å®Ÿæ–½å‰ã«ä½œæ¥­é ˜åŸŸã®è¦ªãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆãŒè¨˜éŒ²ã•れã€\n"
+" 処ç†å®Ÿæ–½å¾Œã«æ–°ãŸãªãƒ˜ãƒƒãƒ‰ã¨ãã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆãŒãƒžãƒ¼ã‚¸ã•れã¾ã™ã€‚\n"
+" ã“れã«ã‚ˆã‚Šæ‰‹å‹•ãƒžãƒ¼ã‚¸ã®æ‰‹é–“ãŒçœã‘ã¾ã™ã€‚通常㮠merge ã¨åŒæ§˜ã«ã€\n"
+" ã“ã®ãƒžãƒ¼ã‚¸çµæžœã¯è‡ªå‹•çš„ã«ã¯ commit ã•れã¾ã›ã‚“。\n"
+"\n"
+" -d/--date ã¸ã®æŒ‡å®šã«é–¢ã—ã¦ã¯ã€'hg help dates' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid "please specify just one revision"
+msgstr "リビジョン指定ã¯1ã¤ã ã‘ã§ã™"
+
+msgid "please specify a revision to backout"
+msgstr "æ‰“ã¡æ¶ˆã—対象リビジョンを指定ã—ã¦ãã ã•ã„"
+
+msgid "cannot backout change on a different branch"
+msgstr "ç•°ãªã‚‹ãƒ–ランãƒã«å±žã™ã‚‹ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã‚’æ‰“ã¡æ¶ˆã™ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid "cannot backout a change with no parents"
+msgstr "親ã®ç„¡ã„ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã‚’æ‰“ã¡æ¶ˆã™ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid "cannot backout a merge changeset without --parent"
+msgstr "ãƒžãƒ¼ã‚¸ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æ‰“消ã—ã«ã¯ --parent 指定ãŒå¿…è¦ã§ã™"
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr "%s 㯠%s ã®è¦ªãƒªãƒ“ジョンã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr "éžãƒžãƒ¼ã‚¸ãƒªãƒ“ジョンã«ã¯ --parent を指定ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "Backed out changeset %s"
+msgstr "リビジョン %s ã®æ‰“ã¡æ¶ˆã—"
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr "リビジョン %s ã¯ãƒªãƒ“ジョン %s ã‚’æ‰“ã¡æ¶ˆã—ã¾ã™\n"
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr "リビジョン %s ã¨ãƒžãƒ¼ã‚¸ä¸­\n"
+
+msgid "the backout changeset is a new head - do not forget to merge\n"
+msgstr "æ‰“ã¡æ¶ˆã—リビジョンã«ã‚ˆã‚Šãƒ˜ãƒƒãƒ‰ãŒå¢—ãˆã¾ã™ - マージを忘れãšã«\n"
+
+msgid "(use \"backout --merge\" if you want to auto-merge)\n"
+msgstr "(自動的ã«ãƒžãƒ¼ã‚¸ã™ã‚‹å ´åˆã¯ \"backout --merge\" ã—ã¦ãã ã•ã„)\n"
+
+msgid ""
+"subdivision search of changesets\n"
+"\n"
+" This command helps to find changesets which introduce problems. To\n"
+" use, mark the earliest changeset you know exhibits the problem as\n"
+" bad, then mark the latest changeset which is free from the problem\n"
+" as good. Bisect will update your working directory to a revision\n"
+" for testing (unless the -U/--noupdate option is specified). Once\n"
+" you have performed tests, mark the working directory as good or\n"
+" bad, and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command, it will be used for automatic bisection.\n"
+" Its exit status will be used to mark revisions as good or bad:\n"
+" status 0 means good, 125 means to skip the revision, 127\n"
+" (command not found) will abort the bisection, and any other\n"
+" non-zero exit status means the revision is bad.\n"
+" "
+msgstr ""
+"リビジョンã®åˆ†å‰²æŽ¢ç´¢\n"
+"\n"
+" å•題発生契機ã¨ãªã‚‹ãƒªãƒ“ジョンã®ç‰¹å®šã‚’補助ã—ã¾ã™ã€‚使用開始ã®éš›ã«ã¯ã€\n"
+" å•題ãŒç™ºç”Ÿã™ã‚‹æ—¢çŸ¥ã®ãƒªãƒ“ジョンã®ã†ã¡ã€æœ€å¤ã®ã‚‚ã®ã‚’ bad ã¨ãƒžãƒ¼ã‚¯ã—ã€\n"
+" å•題ãŒç™ºç”Ÿã—ãªã„既知ã®ãƒªãƒ“ジョンã®ã†ã¡ã€æœ€æ–°ã®ã‚‚ã®ã‚’ good ã¨ãƒžãƒ¼ã‚¯\n"
+" ã—ã¾ã™ã€‚本コマンドã¯ã€æ¤œè¨¼å¯¾è±¡ãƒªãƒ“ジョンã§ä½œæ¥­é ˜åŸŸã‚’æ›´æ–°ã—ã¾ã™(-U/\n"
+" --noupdate 指定時除ã)。当該リビジョンを検証ã—ãŸãªã‚‰ã€bad ã‚ã‚‹ã„ã¯\n"
+" good ã§ãƒžãƒ¼ã‚¯ã—ã¦ãã ã•ã„。本コマンドã¯ã€æ¬¡ã®æ¤œè¨¼å€™è£œãƒªãƒ“ジョンã§\n"
+" 作業領域を更新ã™ã‚‹ã‹ã€å•題契機リビジョンを特定ã§ããŸæ—¨ã‚’出力ã—ã¾ã™ã€‚\n"
+"\n"
+" ã¦ã¿ã˜ã‹ãªæ‰‹é †ã¨ã—ã¦ã¯ã€ä½œæ¥­é ˜åŸŸã‚’æ›´æ–°ã›ãšã«ã€ãƒªãƒ“ジョン指定を使用\n"
+" ã—ã¦ãƒªãƒ“ジョンを good ãªã„ã— bad ã«ãƒžãƒ¼ã‚¯ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚\n"
+"\n"
+" ã‚³ãƒžãƒ³ãƒ‰ãŒæŒ‡å®šã•れãŸå ´åˆã€è‡ªå‹•çš„ãªãƒªãƒ“ジョン検証ã«ä½¿ç”¨ã•れã¾ã™ã€‚\n"
+" コマンドã®çµ‚了コードã¯ãƒªãƒ“ジョンã«å¯¾ã™ã‚‹ bad ãªã„ã— good ã®ãƒžãƒ¼ã‚¯ä»˜ã‘\n"
+" ã«ä½¿ç”¨ã•れã¾ã™ã€‚終了コード 0 㯠goodã€125 ã¯ã‚¹ã‚­ãƒƒãƒ—ã€127(コマンドãŒ\n"
+" 見ã¤ã‹ã‚‰ãªã„å ´åˆ)ã¯åˆ†å‰²æŽ¢ç´¢ä¸­æ–­ã€ãれ以外㮠0 より大ãã„終了コードã¯\n"
+" bad ã®ãƒžãƒ¼ã‚¯ä»˜ã‘ã¨ã¿ãªã•れã¾ã™ã€‚\n"
+" "
+
+msgid "The first good revision is:\n"
+msgstr "最åˆã® good ãªãƒªãƒ“ジョンã¯:\n"
+
+msgid "The first bad revision is:\n"
+msgstr "最åˆã® bad ãªãƒªãƒ“ジョンã¯:\n"
+
+msgid "Due to skipped revisions, the first good revision could be any of:\n"
+msgstr "検証çœç•¥ã«ã‚ˆã‚Šã€æœ€åˆã® good ãªãƒªãƒ“ジョンã¯ä»¥ä¸‹ã‹ã‚‰é¸æŠžå¯èƒ½ã§ã™:\n"
+
+msgid "Due to skipped revisions, the first bad revision could be any of:\n"
+msgstr "検証çœç•¥ã«ã‚ˆã‚Šã€æœ€åˆã® bad ãªãƒªãƒ“ジョンã¯ä»¥ä¸‹ã‹ã‚‰é¸æŠžå¯èƒ½ã§ã™:\n"
+
+msgid "cannot bisect (no known good revisions)"
+msgstr "分割探索出æ¥ã¾ã›ã‚“(good ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒæœªæŒ‡å®šã§ã™)"
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr "分割探索出æ¥ã¾ã›ã‚“(bad ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒæœªæŒ‡å®šã§ã™)"
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr "('hg bisect <cmd>' å½¢å¼ã®å®Ÿè¡Œã¯æŽ¨å¥¨ã•れã¾ã›ã‚“)\n"
+
+msgid "incompatible arguments"
+msgstr "䏿­£ãªå¼•æ•°ã®çµ„ã¿åˆã‚ã›ã§ã™"
+
+#, python-format
+msgid "cannot find executable: %s"
+msgstr "実行å¯èƒ½ãƒ•ァイル '%s' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, python-format
+msgid "failed to execute %s"
+msgstr "%s ã®å®Ÿè¡Œã«å¤±æ•—"
+
+#, python-format
+msgid "%s killed"
+msgstr "%s プロセスã¯ä¸­æ–­ã•れã¾ã—ãŸ"
+
+#, python-format
+msgid "Changeset %d:%s: %s\n"
+msgstr "リビジョン %d:%s: %s\n"
+
+#, python-format
+msgid "Testing changeset %s:%s (%s changesets remaining, ~%s tests)\n"
+msgstr "リビジョン %s:%s を検証中(検証残 %sã€æ¤œè¨¼æ¸ˆã¿ %s)\n"
+
+msgid ""
+"set or show the current branch name\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch will not exist\n"
+" in the repository until the next commit). Standard practice\n"
+" recommends that primary development take place on the 'default'\n"
+" branch.\n"
+"\n"
+" Unless -f/--force is specified, branch will not let you set a\n"
+" branch name that already exists, even if it's inactive.\n"
+"\n"
+" Use -C/--clean to reset the working directory branch to that of\n"
+" the parent of the working directory, negating a previous branch\n"
+" change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+"ブランãƒåã®è¨­å®šã€ãªã„ã—ç¾ãƒ–ランãƒåã®è¡¨ç¤º\n"
+"\n"
+" 引数無ã—ã®å ´åˆã€ç¾ãƒ–ランãƒåを表示ã—ã¾ã™ã€‚引数ãŒï¼‘ã¤æŒ‡å®šã•れãŸå ´åˆã€\n"
+" 作業領域ã®ãƒ–ランãƒåを設定ã—ã¾ã™(次回コミット時ã¾ã§ã€ãƒ–ランãƒã¯ç”Ÿæˆ\n"
+" ã•れã¾ã›ã‚“)。作業時ã«åŸºæœ¬ã¨ã™ã‚‹ãƒ–ランãƒã«ã¯ã€'default' ブランãƒã‚’\n"
+" 使用ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚\n"
+"\n"
+" -f/--force 指定ãŒç„¡ã„å ´åˆã€ä¾‹ãˆãれãŒéžã‚¢ã‚¯ãƒ†ã‚£ãƒ–ãªã‚‚ã®ã§ã‚ã£ã¦ã‚‚ã€\n"
+" 既存ブランãƒã¨åŒã˜åå‰ã¯è¨­å®šã§ãã¾ã›ã‚“。\n"
+"\n"
+" -C/--clean を指定ã™ã‚‹ã“ã¨ã§ã€ä»¥å‰ã®ãƒ–ランãƒå設定を無効ã«ã—ã¦ã€ä½œæ¥­\n"
+" 領域ã®è¦ªãƒªãƒ“ジョンã®ãƒ–ランãƒåã«æˆ»ã—ã¾ã™ã€‚\n"
+"\n"
+" 作業領域ã®å†…容を既存ブランãƒã®ã‚‚ã®ã§æ›´æ–°ã™ã‚‹å ´åˆã¯ 'hg update' ã‚’\n"
+" 使用ã—ã¦ãã ã•ã„。\n"
+" "
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr "作業領域ã®ãƒ–ランãƒã‚’ %s ã«ãƒªã‚»ãƒƒãƒˆ\n"
+
+msgid "a branch of the same name already exists (use --force to override)"
+msgstr "åŒåã®ãƒ–ランãƒãŒå­˜åœ¨ã—ã¾ã™(強行ã™ã‚‹å ´åˆã¯ --force 指定ãŒå¿…è¦ã§ã™)"
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr "作業領域をブランム%s ã«è¨­å®š\n"
+
+msgid ""
+"list repository named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If -a/--active is specified, only show active branches.\n"
+"\n"
+" A branch is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+"リãƒã‚¸ãƒˆãƒªä¸­ã®åå‰ä»˜ãブランãƒã®ä¸€è¦§\n"
+"\n"
+" リãƒã‚¸ãƒˆãƒªä¸­ã®åå‰ä»˜ãブランãƒã‚’ã€éžæ´»æ€§(inactive)ã‹å¦ã‹ã¨å…±ã«\n"
+" 一覧表示ã—ã¾ã™ã€‚-a/--active 指定時ã«ã¯ã€æ´»æ€§ã®ã‚‚ã®ã®ã¿ãŒè¡¨ç¤ºã•\n"
+" れã¾ã™ã€‚\n"
+"\n"
+" リãƒã‚¸ãƒˆãƒªä¸­ã«ãƒ˜ãƒƒãƒ‰ã‚’æŒã¤ãƒ–ランãƒã¯æ´»æ€§ã¨ã¿ãªã•れã¾ã™ã€‚\n"
+"\n"
+" 作業領域ã®å†…容を既存ブランãƒã®ã‚‚ã®ã§æ›´æ–°ã™ã‚‹å ´åˆã¯ 'hg update' ã‚’\n"
+" 使用ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid ""
+"create a changegroup file\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" -a/--all (or --base null).\n"
+"\n"
+" You can change compression method with the -t/--type option.\n"
+" The available compression methods are: none, bzip2, and\n"
+" gzip (by default, bundles are compressed using bzip2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means\n"
+" and applied to another repository with the unbundle or pull\n"
+" command. This is useful when direct push and pull are not\n"
+" available or when exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+msgstr ""
+"ãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイルã®ç”Ÿæˆ\n"
+"\n"
+" 連æºå¯¾è±¡ãƒªãƒã‚¸ãƒˆãƒªã«å­˜åœ¨ã—ãªã„ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æƒ…報をã¾ã¨ã‚ã¦ã€åœ§ç¸®\n"
+" 付ããƒãƒ³ãƒ‰ãƒ«ãƒ•ァイルを生æˆã—ã¾ã™ã€‚\n"
+"\n"
+" 連æºå¯¾è±¡ãƒªãƒã‚¸ãƒˆãƒªãŒæŒ‡å®šã•れãªã„å ´åˆã€1ã¤ä»¥ä¸Šã® --base ã§æŒ‡å®š\n"
+" ã•れãŸãƒªãƒ“ジョンをæŒã¤ãƒªãƒã‚¸ãƒˆãƒªãŒæƒ³å®šã•れã¾ã™ã€‚å…¨ã¦ã®ãƒªãƒ“ジョンを\n"
+" å«ã‚€ãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイルを生æˆã™ã‚‹ã«ã¯ã€-a/--all (ãªã„ã— --base null)ã‚’\n"
+" 指定ã—ã¾ã™ã€‚\n"
+"\n"
+" 圧縮方å¼ã‚’変更ã™ã‚‹å ´åˆã¯ -t/--type を使用ã—ã¾ã™ã€‚利用å¯èƒ½ãªåœ§ç¸®\n"
+" å½¢å¼ã¯ none(無圧縮), bzip2, gzip ã§ã™(無指定時㯠bzip2 圧縮)。\n"
+"\n"
+" ä»»æ„ã®æ–¹æ³•ã§è»¢é€ã—ãŸãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイルã¯ã€ä»–ã®ãƒªãƒã‚¸ãƒˆãƒªä¸Šã§\n"
+" 'hg unbundle' ãªã„ã— 'hg pull' ã«ã‚ˆã‚Šé©ç”¨å¯èƒ½ã§ã™ã€‚ãƒãƒ³ãƒ‰ãƒ«ã«ã‚ˆã‚‹\n"
+" 伿’­ã¯ã€ 'hg push/pull' ã«ã‚ˆã‚‹ç›´æŽ¥è»¢é€ãŒã§ããªã„å ´åˆã‚„ã€ãƒªãƒã‚¸ãƒˆãƒª\n"
+" 全体ã®å…¬é–‹ãŒæœ›ã¾ã—ãç„¡ã„å ´åˆã«æœ‰ç”¨ã§ã™ã€‚\n"
+"\n"
+" ãƒãƒ³ãƒ‰ãƒ«ã®é©ç”¨ã§ã¯ã€æ¨©é™è¨­å®šã€è¤‡è£½ï¼æ”¹åã€å¤‰æ›´å±¥æ­´ã¨ã„ã£ãŸæƒ…報を\n"
+" å«ã‚€å…¨ã¦ã®æ›´æ–°å†…容ãŒå–り込ã¾ã‚Œã¾ã™ã€‚\n"
+" "
+
+msgid "--base is incompatible with specifying a destination"
+msgstr "--base ã¨é€£æºå¯¾è±¡ã¯åŒæ™‚ã«ã¯æŒ‡å®šã§ãã¾ã›ã‚“"
+
+msgid "unknown bundle type specified with --type"
+msgstr "--type ã«æœªçŸ¥ã®ãƒãƒ³ãƒ‰ãƒ«ç¨®åˆ¥ãŒæŒ‡å®šã•れã¾ã—ãŸ"
+
+msgid ""
+"output the current or given revision of files\n"
+"\n"
+" Print the specified files as they were at the given revision. If\n"
+" no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repository root\n"
+" %p root-relative path name of file being printed\n"
+" "
+msgstr ""
+"指定ã•れãŸãƒªãƒ“ジョン時点ã®ãƒ•ァイル内容ã®å‡ºåŠ›\n"
+"\n"
+" 指定ã•れãŸãƒªãƒ“ジョンã«ãŠã‘ã‚‹ã€ãƒ•ァイル内容を出力ã—ã¾ã™ã€‚リビジョン\n"
+" 指定ãŒç„¡ã„å ´åˆã¯ä½œæ¥­é ˜åŸŸã®è¦ªãƒªãƒ“ジョンãŒã€ä½œæ¥­é ˜åŸŸã®æ›´æ–°å‰ãªã‚‰ tip\n"
+" ãŒä½¿ç”¨ã•れã¾ã™ã€‚\n"
+"\n"
+" 出力先指定(ç½®æ›æŒ‡å®šå¯èƒ½)ãŒã‚ã‚‹å ´åˆã€å‡ºåŠ›ã¯ãƒ•ァイルã«ä¿å­˜ã•れã¾ã™ã€‚\n"
+" ç½®æ›æŒ‡å®šã«ã¯ 'hg export' ã§å¯èƒ½ãªæŒ‡å®šã¨ã€ä»¥ä¸‹ã®ã‚‚ã®ã‚’指定ã§ãã¾ã™ã€‚\n"
+" \n"
+"\n"
+" %s 対象ファイルã®ãƒ™ãƒ¼ã‚¹å\n"
+" %d å¯¾è±¡ãƒ•ã‚¡ã‚¤ãƒ«ã®æ ¼ç´ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã€ãªã„ã— '.'\n"
+" %p 対象ファイルã®ãƒªãƒã‚¸ãƒˆãƒªãƒ«ãƒ¼ãƒˆã‹ã‚‰ã®ç›¸å¯¾ãƒ‘ス\n"
+" "
+
+msgid ""
+"make a copy of an existing repository\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" If you use the -r/--rev option to clone up to a specific revision,\n"
+" no subsequent revisions (including subsequent tags) will be\n"
+" present in the cloned repository. This option implies --pull, even\n"
+" on local repositories.\n"
+"\n"
+" By default, clone will check out the head of the 'default' branch.\n"
+" If the -U/--noupdate option is used, the new clone will contain\n"
+" only a repository (.hg) and no working copy (the working copy\n"
+" parent is the null revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Please see 'hg help urls' for important details about ssh:// URLs.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" "
+msgstr ""
+"既存リãƒã‚¸ãƒˆãƒªã®è¤‡è£½\n"
+"\n"
+" 既存リãƒã‚¸ãƒˆãƒªã‚’ã€æ–°è¦ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«è¤‡è£½ã—ã¾ã™ã€‚\n"
+"\n"
+" è¤‡è£½å…ˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒæŒ‡å®šã•れãªã„å ´åˆã€è¤‡è£½å…ƒã®ãƒ™ãƒ¼ã‚¹å(パスåã®\n"
+" 末尾è¦ç´ )を使用ã—ã¾ã™ã€‚\n"
+"\n"
+" å°†æ¥çš„㪠'hg pull' 実施ã«å‚™ãˆã¦ã€è¤‡è£½å…ˆãƒªãƒã‚¸ãƒˆãƒªã® .hg/hgrc \n"
+" ファイルã«ã¯ã€è¤‡è£½å…ƒãƒªãƒã‚¸ãƒˆãƒªä½ç½®ãŒ default å義ã§è¨˜éŒ²ã•れã¾ã™ã€‚\n"
+"\n"
+" -r/--rev ã«ã‚ˆã‚‹ãƒªãƒ“ジョン指定複製を行ãªã†å ´åˆã€è¤‡è£½å…ˆãƒªãƒã‚¸ãƒˆãƒªã«ã¯\n"
+" 指定リビジョン以後ã®ãƒªãƒ“ジョン(タグ付ã‘リビジョンå«ã‚€)ã¯è¤‡è£½ã•れã¾\n"
+" ã›ã‚“。リビジョン指定複製ã®å ´åˆã¯ã€åŒä¸€ãƒ•ァイルシステム上ã§ã®è¤‡è£½ã§\n"
+" ã‚ã£ã¦ã‚‚ã€æš—黙的㫠--pull 指定を伴ã„ã¾ã™ã€‚\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šã®ç„¡ã„å ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯ 'default' ブランãƒã®ãƒ˜ãƒƒãƒ‰ã§ä½œæ¥­\n"
+" 領域を更新ã—ã¾ã™ã€‚-U/--noupdate ãŒæŒ‡å®šã•れãŸå ´åˆã€æ–°è¦è¤‡è£½å…ˆã¯ã€\n"
+" 管ç†é ˜åŸŸ(.hg)ã®ã¿ã‚’ä¿æŒã—ã€ä½œæ¥­é ˜åŸŸã®æ›´æ–°ã¯è¡Œã‚れã¾ã›ã‚“(作業領域ã®\n"
+" 親リビジョン㯠null リビジョンã¨ãªã‚Šã¾ã™)。\n"
+"\n"
+" 有効ãªè¤‡è£½å…ƒæŒ‡å®šå½¢å¼ã¯ 'hg help urls' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" 複製先ã¨ã—㦠ssh:// URL å½¢å¼ã‚’指定ã™ã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ãŒã€é éš”ホスト\n"
+" ã§ã¯ã€.hg/hgrc ã®ä½œæˆã‚‚ã€ä½œæ¥­é ˜åŸŸã®æ›´æ–°ã‚‚行ã‚れã¾ã›ã‚“。ssh:// URL\n"
+" å½¢å¼ã®è©³ç´°ã«é–¢ã—ã¦ã¯ã€'hg help urls' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" 効率上ã®ç†ç”±ã‹ã‚‰ã€è¤‡è£½å…ƒï¼è¤‡è£½å…ˆãŒåŒä¸€ãƒ•ァイルシステム上ã«ã‚ã‚‹å ´åˆã€\n"
+" (リãƒã‚¸ãƒˆãƒªã®å†…部データã«å¯¾ã—ã¦ã®ã¿)ãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ãŒä½¿ç”¨ã•れã¾ã™ã€‚\n"
+" AFS ã‚’å«ã‚€å¹¾ã¤ã‹ã®ãƒ•ァイルシステムã¯ã€ãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯å®Ÿè£…ãŒä¸é©åˆ‡ã§ã‚ã‚‹\n"
+" ã«ã‚‚é–¢ã‚らãšã€ã‚¨ãƒ©ãƒ¼é€šçŸ¥ãŒã‚りã¾ã›ã‚“。ã“ã®ã‚ˆã†ãªå ´åˆã«ã¯ --pull ã‚’\n"
+" 指定ã™ã‚‹ã“ã¨ã§ã€ãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ã‚’抑止ã—ã¾ã™ã€‚\n"
+"\n"
+" リãƒã‚¸ãƒˆãƒªã®å†…部データã¨ä½œæ¥­é ˜åŸŸä¸­ã®ãƒ•ァイル全ã¦ã«å¯¾ã—ã¦ã€ãƒãƒ¼ãƒ‰\n"
+" リンクã«ã‚ˆã‚‹è¤‡è£½ã‚’作æˆã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®æ–¹æ³•ãŒä½¿ãˆã‚‹ã‹ã‚‚知れã¾ã›ã‚“。\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" ã“ã®æ–¹æ³•ã¯æœ€é€Ÿã®è¤‡è£½æ–¹æ³•ã‹ã‚‚ã—れã¾ã›ã‚“ãŒã€å¸¸ã«å®‰å…¨ã¨ã¯é™ã‚Šã¾ã›ã‚“。\n"
+" æ“作ã®å˜ä¸€æ€§ã¯ä¿éšœã•れã¾ã›ã‚“(REPO ã®è¤‡è£½ä¸­æ”¹å¤‰ã®é˜²æ­¢ã¯åˆ©ç”¨è€…責務)ã—ã€\n"
+" 利用ã™ã‚‹ã‚¨ãƒ‡ã‚£ã‚¿ãŒã€æ”¹å¤‰æ™‚ã«ãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ã‚’破棄ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™\n"
+" (Emacs ãŠã‚ˆã³å¤šãã® Linux 系ツールã¯ãã®ã‚ˆã†ã«æŒ¯èˆžã„ã¾ã™)。ã“ã®åˆ¶ç´„ã¯\n"
+" .hg ディレクトリé…下ã«ãƒ¡ã‚¿ãƒ‡ãƒ¼ã‚¿ã‚’é…ç½®ã™ã‚‹ã€MQ ã®ã‚ˆã†ãª\n"
+" エクステンションã¨ã¯ç›¸å®¹ã‚Œãªã„ã‚‚ã®ã§ã™ã€‚\n"
+"\n"
+" "
+
+msgid ""
+"commit the specified files or all outstanding changes\n"
+"\n"
+" Commit changes to the given files into the repository. Unlike a\n"
+" centralized RCS, this operation is a local operation. See hg push\n"
+" for a way to actively distribute your changes.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" filenames or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is\n"
+" started to prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"指定ファイルãªã„ã—å…¨ã¦ã®å¤‰æ›´å†…容ã®ãƒªãƒã‚¸ãƒˆãƒªã¸ã®è¨˜éŒ²\n"
+"\n"
+" 指定ã•れãŸãƒ•ァイルã®å¤‰æ›´å†…容を管ç†é ˜åŸŸã«è¨˜éŒ²(コミット)ã—ã¾ã™ã€‚\n"
+" RCS ã®ã‚ˆã†ãªä¸­å¤®é›†æ¨©çš„ãªãƒ„ールã¨ç•°ãªã‚Šã€ã“ã®æ“ä½œã¯æ‰‹å…ƒã®ç®¡ç†é ˜åŸŸã«\n"
+" 対ã™ã‚‹è¨˜éŒ²ã—ã‹è¡Œã„ã¾ã›ã‚“。変更を能動的ã«å…¬é–‹ã™ã‚‹æ–¹æ³•ã«é–¢ã—ã¦ã¯\n"
+" 'hg help push' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" ファイル指定ãŒçœç•¥ã•れãŸå ´åˆã€'hg status' ã«ã‚ˆã‚Šæ¤œå‡ºã•れる全ã¦ã®\n"
+" 変更内容ãŒã‚³ãƒŸãƒƒãƒˆã•れã¾ã™ã€‚\n"
+"\n"
+" 'hg merge' çµæžœã‚’コミットã™ã‚‹å ´åˆã€ãƒ•ァイルåãªã„ã— -I/-X ã®ã„ãšã‚Œã‚‚\n"
+" 指定ã—ãªã„ã§ãã ã•ã„。\n"
+"\n"
+" ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒæŒ‡å®šã•れãªã„å ´åˆã€è¨­å®šã«å¾“ã£ã¦ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸å…¥åŠ›ç”¨ã®\n"
+" プログラムãŒèµ·å‹•ã•れã¾ã™ã€‚\n"
+"\n"
+" -d/--date ã¸ã®æŒ‡å®šã«é–¢ã—ã¦ã¯ã€'hg help dates' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid "created new head\n"
+msgstr "æ–°è¦ãƒ˜ãƒƒãƒ‰ãŒå¢—ãˆã¾ã—ãŸ\n"
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr "コミット対象リビジョン %d:%s\n"
+
+msgid ""
+"mark files as copied for the next commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+"指定ã•れãŸãƒ•ァイルã®è¤‡è£½\n"
+"\n"
+" 対象ファイルãŒè¤‡è£½å…ƒã‹ã‚‰ã®è¤‡è£½ã§ã‚ã‚‹ã“ã¨ã‚’記録ã—ã¾ã™ã€‚複製先指定ãŒ\n"
+" ディレクトリã®å ´åˆã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªå†…ã«è¤‡è£½ãŒä½œæˆã•れã¾ã™ã€‚複製先指定ãŒ\n"
+" ファイルã®å ´åˆã€è¤‡è£½å…ƒã¯1ã¤ã—ã‹æŒ‡å®šã§ãã¾ã›ã‚“。\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€è¤‡è£½å…ƒãƒ•ァイルã®å†…容をæŒã¤è¤‡è£½å…ˆãƒ•ァイルを作業\n"
+" 領域ã«ä½œæˆã—ã¾ã™ã€‚-A/--after 指定ãŒã‚ã‚‹å ´åˆã€ã€Œè¤‡è£½ã€æ“作ã¯è¨˜éŒ²ã•れ\n"
+" ã¾ã™ãŒã€ãƒ•ァイルã®è¤‡è£½ã¯è¡Œã‚れã¾ã›ã‚“。\n"
+"\n"
+" 本コマンドã®å®Ÿè¡Œçµæžœã¯æ¬¡å›žã®ã‚³ãƒŸãƒƒãƒˆã®éš›ã«åŠ¹æžœã‚’ç™ºæ®ã—ã¾ã™ã€‚コミット\n"
+" å‰ã«è¤‡è£½æ“作をå–ã‚Šæ¶ˆã™æ–¹æ³•㯠'hg help revert' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr "指定範囲ã«ãŠã‘ã‚‹2ã¤ã®ãƒªãƒ“ジョンã®ç¥–å…ˆãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æ¤œç´¢"
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr "Mercurial リãƒã‚¸ãƒˆãƒªãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“(.hg ãŒä¸åœ¨ã§ã™)"
+
+msgid "either two or three arguments required"
+msgstr "2ãªã„ã—3ã®å¼•æ•°ãŒå¿…è¦ã§ã™"
+
+msgid "returns the completion list associated with the given command"
+msgstr "指定コマンドã®è£œå®Œãƒªã‚¹ãƒˆã®ä½œæˆ"
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr "指定リビジョン時点相当㮠dirstate ã®å†æ§‹ç¯‰"
+
+msgid "validate the correctness of the current dirstate"
+msgstr "ç¾æ™‚点㮠dirstate ã®æ•´åˆæ€§æ¤œè¨¼"
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr "%s ã®çŠ¶æ…‹ã¯ %s ã§ã™ãŒã€ç®¡ç†å¯¾è±¡ã§ã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr "%s ã®çŠ¶æ…‹ã¯ %s ã§ã™ãŒã€æ—¢ã«ç®¡ç†å¯¾è±¡ã«ãªã£ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr "%s ã®çŠ¶æ…‹ã¯ %s ã§ã™ãŒã€ç®¡ç†å¯¾è±¡ã§ã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr "%s ã¯ç®¡ç†å¯¾è±¡ã§ã™ãŒã€çŠ¶æ…‹ %s ã§ã™"
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr "親リビジョンã®ç®¡ç†æƒ…報㨠.hg/dirstate ã®é–“ã«ä¸æ•´åˆãŒã‚りã¾ã™"
+
+msgid ""
+"show combined config settings from all hgrc files\n"
+"\n"
+" With no arguments, print names and values of all config items.\n"
+"\n"
+" With one argument of the form section.name, print just the value\n"
+" of that config item.\n"
+"\n"
+" With multiple arguments, print names and values of all config\n"
+" items with matching section names.\n"
+"\n"
+" With --debug, the source (filename and line number) is printed\n"
+" for each config item.\n"
+" "
+msgstr ""
+"全設定ファイルã«ã‚ˆã‚‹æœ€çµ‚çš„ãªè¨­å®šå†…容ã®è¡¨ç¤º\n"
+"\n"
+" 引数指定ãŒç„¡ã„å ´åˆã€å…¨ã¦ã®è¨­å®šé …ç›®ã«å¯¾ã—ã¦ã€åå‰ã¨å€¤ã‚’表示ã—ã¾ã™ã€‚\n"
+"\n"
+" 'section.name' å½¢å¼ã«åˆè‡´ã™ã‚‹å¼•æ•°ã‚’1ã¤ã ã‘指定ã—ãŸå ´åˆã€ãã®è¨­å®šé …ç›®\n"
+" 値ã®ã¿ã‚’表示ã—ã¾ã™ã€‚\n"
+"\n"
+" 複数ã®å¼•æ•°ãŒæŒ‡å®šã•れãŸå ´åˆã€ãれらをセクションåã¨ã¿ãªã—ã€è©²å½“ã™ã‚‹\n"
+" セクションã®è¨­å®šé …目を全ã¦è¡¨ç¤ºã—ã¾ã™ã€‚\n"
+"\n"
+" --debug 指定ãŒã‚ã‚‹å ´åˆã€è¨­å®šé …目毎ã«è¨˜è¿°ä½ç½®(ファイルåã¨è¡Œç•ªå·)ãŒ\n"
+" 表示ã•れã¾ã™ã€‚\n"
+" "
+
+msgid "only one config item permitted"
+msgstr "複数ã®è¨­å®šé …目指定ã¯ç„¡åйã§ã™"
+
+msgid ""
+"manually set the parents of the current working directory\n"
+"\n"
+" This is useful for writing repository conversion tools, but should\n"
+" be used with care.\n"
+" "
+msgstr ""
+"作業領域ã®è¦ªãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æ‰‹å‹•設定\n"
+"\n"
+" 本コマンドã¯ãƒªãƒã‚¸ãƒˆãƒªå¤‰æ›ãƒ„ールã®ä½œæˆã«æœ‰ç”¨ã§ã™ãŒã€åˆ©ç”¨ã«ã¯æ³¨æ„ãŒ\n"
+" å¿…è¦ã§ã™ã€‚\n"
+" "
+
+msgid "show the contents of the current dirstate"
+msgstr "ç¾æ™‚点㮠dirstate 内容ã®è¡¨ç¤º"
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr "%s ã‹ã‚‰ %s ã«è¤‡è£½\n"
+
+msgid "dump the contents of a data file revision"
+msgstr "データファイルリビジョンã®å†…容表示"
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr "リビジョン指定 %s ã¯ä¸æ­£ã§ã™"
+
+msgid "parse and display a date"
+msgstr "日付ã®è§£æžãŠã‚ˆã³è¡¨ç¤º"
+
+msgid "dump the contents of an index file"
+msgstr "インデックスファイルã®å†…容表示"
+
+msgid "dump an index DAG as a graphviz dot file"
+msgstr "インデックス DAG ã® graphviz å‘ã‘ .dot ファイルを生æˆ"
+
+msgid "test Mercurial installation"
+msgstr "Mercurial ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã®æ¤œè¨¼"
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr "文字コード %s ã®æ¤œè¨¼ä¸­...\n"
+
+msgid " (check that your locale is properly set)\n"
+msgstr " (ロケール設定ã®å¦¥å½“性を確èªã—ã¦ãã ã•ã„)\n"
+
+msgid "Checking extensions...\n"
+msgstr "ã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³ã®æ¤œè¨¼ä¸­...\n"
+
+msgid " One or more extensions could not be found"
+msgstr " 見ã¤ã‹ã‚‰ãªã„エクステンションãŒã‚りã¾ã™"
+
+msgid " (check that you compiled the extensions)\n"
+msgstr " (エクステンションã®ã‚³ãƒ³ãƒ‘イル状æ³ã‚’確èªã—ã¦ãã ã•ã„)\n"
+
+msgid "Checking templates...\n"
+msgstr "ãƒ†ãƒ³ãƒ—ãƒ¬ãƒ¼ãƒˆã®æ¤œè¨¼ä¸­...\n"
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr " (テンプレートã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒä¸é©åˆ‡ãªã‚ˆã†ã§ã™)\n"
+
+msgid "Checking patch...\n"
+msgstr "パッãƒã®æ¤œè¨¼ä¸­...\n"
+
+msgid " patch call failed:\n"
+msgstr " パッãƒé©ç”¨ãŒå¤±æ•—\n"
+
+msgid " unexpected patch output!\n"
+msgstr " 想定ã¨ç•°ãªã‚‹ãƒ‘ッãƒå‡ºåŠ›ã§ã™\n"
+
+msgid " patch test failed!\n"
+msgstr " パッãƒé©ç”¨è©¦é¨“ãŒå¤±æ•—\n"
+
+msgid ""
+" (Current patch tool may be incompatible with patch, or misconfigured. "
+"Please check your .hgrc file)\n"
+msgstr " (ãƒ„ãƒ¼ãƒ«ãŒæœªå¯¾å¿œãªãƒ‘ッãƒå½¢å¼ã‹ã€è¨­å®šãƒŸã‚¹ã§ã™ã€‚設定確èªãŒå¿…è¦ã§ã™)\n"
+
+msgid ""
+" Internal patcher failure, please report this error to http://mercurial."
+"selenic.com/bts/\n"
+msgstr ""
+" 内部パッãƒãƒ„ãƒ¼ãƒ«ãŒæ©Ÿèƒ½ã—ã¾ã›ã‚“。\n"
+"http://mercurial.selenic.com/bts ã¸ã®ã‚¨ãƒ©ãƒ¼å ±å‘Šã«ã”å”力ãã ã•ã„\n"
+
+msgid "Checking commit editor...\n"
+msgstr "ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸å…¥åŠ›ç”¨ã‚¨ãƒ‡ã‚£ã‚¿ã®æ¤œè¨¼ä¸­...\n"
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr " エディタãŒèµ·å‹•ã§ãã¾ã›ã‚“(vi ã«ã‚‚ PATH ãŒé€šã£ã¦ã„ã¾ã›ã‚“)\n"
+
+msgid " (specify a commit editor in your .hgrc file)\n"
+msgstr " (コミットメッセージ用エディタを設定ファイルã§è¨­å®šã—ã¦ãã ã•ã„)\n"
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr " エディタ '%s' ã« PATH ãŒé€šã£ã¦ã„ã¾ã›ã‚“\n"
+
+msgid "Checking username...\n"
+msgstr "ユーザåã®æ¤œè¨¼ä¸­...\n"
+
+msgid " (specify a username in your .hgrc file)\n"
+msgstr " (設定ファイルã§ãƒ¦ãƒ¼ã‚¶åを設定ã—ã¦ãã ã•ã„)\n"
+
+msgid "No problems detected\n"
+msgstr "éšœå®³ã¯æ¤œå‡ºã•れã¾ã›ã‚“ã§ã—ãŸ\n"
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr "障害ãŒ%s件検出ã•れã¾ã—ãŸã€‚インストール内容を確èªã—ã¦ãã ã•ã„\n"
+
+msgid "dump rename information"
+msgstr "æ”¹åæƒ…å ±ã®è¡¨ç¤º"
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr "%s 㯠%s:%s ã§æ”¹åã•れã¾ã—ãŸ\n"
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr "%s ã¯æ”¹åã•れã¦ã„ã¾ã›ã‚“\n"
+
+msgid "show how files match on given patterns"
+msgstr "指定パターンã¸ã®ãƒ•ァイルåˆè‡´çжæ³ã®è¡¨ç¤º"
+
+msgid ""
+"diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a/--text option, diff will avoid generating diffs of\n"
+" files it detects as binary. With -a, diff will generate a diff\n"
+" anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. For more information, read 'hg help diffs'.\n"
+" "
+msgstr ""
+"作業領域全体(ãªã„ã—æŒ‡å®šãƒ•ァイル)ã®å·®åˆ†æŠ½å‡º\n"
+"\n"
+" 指定ã•れãŸãƒ•ァイルã«å¯¾ã—ã¦ã€ãƒªãƒ“ジョン間ã®å·®åˆ†ã‚’表示ã—ã¾ã™ã€‚\n"
+"\n"
+" 差分㯠unified diff å½¢å¼ã§è¡¨ç¤ºã•れã¾ã™ã€‚\n"
+"\n"
+" 備考: マージã«å¯¾ã™ã‚‹å·®åˆ†è¡¨ç¤ºãŒæœŸå¾…ã¨ç•°ãªã‚‹å ´åˆãŒã‚ã‚‹ã®ã¯ã€ç„¡æŒ‡å®šæ™‚ã«\n"
+" 比較対象ã¨ãªã‚‹ã®ãŒã€ä½œæ¥­é ˜åŸŸã®ç¬¬1親ã§ã‚ã‚‹ãŸã‚ã§ã™ã€‚\n"
+"\n"
+" リビジョンãŒ2ã¤æŒ‡å®šã•れãŸå ´åˆã€ä¸¡ãƒªãƒ“ジョン間ã®å·®åˆ†ãŒè¡¨ç¤ºã•れã¾ã™ã€‚\n"
+" リビジョンãŒ1ã¤æŒ‡å®šã•れãŸå ´åˆã€å½“該リビジョンã¨ä½œæ¥­é ˜åŸŸã®å†…å®¹ãŒæ¯”較\n"
+" ã•れã€ãƒªãƒ“ジョンãŒ1ã¤ã‚‚指定ã•れãªã„å ´åˆã¯ã€ä½œæ¥­é ˜åŸŸã®å†…容ã¨\n"
+" 親リビジョンã¨ãŒæ¯”較ã•れã¾ã™ã€‚\n"
+"\n"
+" -a/--text 指定ãŒç„¡ã„å ´åˆã€ãƒã‚¤ãƒŠãƒªã¨æ€ã—ãファイルã¯å‡¦ç†å¯¾è±¡ã‹ã‚‰\n"
+" 除外ã•れã¾ã™ã€‚-a æŒ‡å®šãŒæœ‰ã‚‹å ´åˆã€çµæžœã«é–¢ã‚らãšå…¨ã¦ã®ãƒ•ァイルãŒ\n"
+" 処ç†å¯¾è±¡ã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" git 拡張差分形å¼ã§è¡¨ç¤ºã™ã‚‹ã«ã¯ -g/--git を指定ã—ã¾ã™ã€‚詳細ã¯\n"
+" 'hg help diffs' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid ""
+"dump the header and diffs for one or more changesets\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a/--text option, export will avoid generating diffs\n"
+" of files it detects as binary. With -a, export will generate a\n"
+" diff anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. See 'hg help diffs' for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the\n"
+" second parent. It can be useful to review a merge.\n"
+" "
+msgstr ""
+"1ã¤ä»¥ä¸Šã®ãƒªãƒ“ジョンã«å¯¾ã™ã‚‹ãƒ˜ãƒƒãƒ€ãŠã‚ˆã³å¤‰æ›´å†…容ã®å‡ºåŠ›\n"
+"\n"
+" 1ã¤ä»¥ä¸Šã®ãƒªãƒ“ジョンã«å¯¾ã—ã¦ã€ãƒ˜ãƒƒãƒ€æƒ…å ±ãŠã‚ˆã³å¤‰æ›´å†…容を表示ã—ã¾ã™ã€‚\n"
+"\n"
+" ヘッダ情報ã«ã¯ä»¥ä¸‹ã®æƒ…å ±ãŒå«ã¾ã‚Œã¾ã™: \n"
+" 作æˆè€…/ãƒãƒƒã‚·ãƒ¥å€¤/親リビジョン/コミットログ\n"
+"\n"
+" 備考: 本コマンドãŒãƒžãƒ¼ã‚¸å®Ÿæ–½ãƒªãƒ“ジョンã«å¯¾ã—ã¦ã€æœŸå¾…ã¨ç•°ãªã‚‹å·®åˆ†ã‚’\n"
+" 出力ã™ã‚‹ã®ã¯ã€ç¬¬1親ã¨ã®å·®åˆ†ã®ã¿ã‚’出力ã™ã‚‹ãŸã‚ã§ã™ã€‚\n"
+"\n"
+" 出力先指定(ç½®æ›æŒ‡å®šå¯èƒ½)ãŒã‚ã‚‹å ´åˆã€å‡ºåŠ›ã¯ãƒ•ァイルã«ä¿å­˜ã•れã¾ã™ã€‚\n"
+" ç½®æ›æŒ‡å®šã¨ã—ã¦ä»¥ä¸‹ã®ã‚‚ã®ãŒä½¿ç”¨å¯èƒ½ã§ã™:\n"
+"\n"
+" %% \"%\" 文字ãã®ã‚‚ã®\n"
+" %H ãƒãƒƒã‚·ãƒ¥å€¤(40 æ¡ 16 進数)\n"
+" %N 生æˆã•れるファイルã®ç·æ•°\n"
+" %R リビジョン番å·\n"
+" %b 対象リãƒã‚¸ãƒˆãƒªã®ãƒ™ãƒ¼ã‚¹å\n"
+" %h 短縮形å¼ãƒãƒƒã‚·ãƒ¥å€¤(12 æ¡ 16 進数)\n"
+" %n 1ã‹ã‚‰å§‹ã¾ã‚‹ã‚¼ãƒ­è©°ã‚ã®é€šã—番å·\n"
+" %r ゼロ詰ã‚ã®ãƒªãƒ“ジョン番å·\n"
+"\n"
+" -a/--text 指定ãŒç„¡ã„å ´åˆã€ãƒã‚¤ãƒŠãƒªã¨æ€ã—ãファイルã¯å‡¦ç†å¯¾è±¡ã‹ã‚‰\n"
+" 除外ã•れã¾ã™ã€‚-a æŒ‡å®šãŒæœ‰ã‚‹å ´åˆã€çµæžœã«é–¢ã‚らãšå…¨ã¦ã®ãƒ•ァイルãŒ\n"
+" 処ç†å¯¾è±¡ã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" git 拡張差分形å¼ã§å‡ºåŠ›ã™ã‚‹ã«ã¯ -g/--git を指定ã—ã¾ã™ã€‚詳細ã¯\n"
+" 'hg help diffs' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" --switch-parent を指定ã™ã‚‹ã“ã¨ã§ã€æ¯”較対象ãŒç¬¬2親ã«ãªã‚Šã¾ã™ã€‚\n"
+" ã“れã¯ãƒžãƒ¼ã‚¸ã®ãƒ¬ãƒ“ューã®éš›ãªã©ã«æœ‰åйã§ã™ã€‚\n"
+" "
+
+msgid "export requires at least one changeset"
+msgstr "最低1ã¤ã®ãƒªãƒ“ジョン指定ãŒå¿…è¦ã§ã™"
+
+msgid "exporting patches:\n"
+msgstr "パッãƒã®ä½œæˆä¸­:\n"
+
+msgid "exporting patch:\n"
+msgstr "パッãƒã®ä½œæˆä¸­:\n"
+
+msgid ""
+"forget the specified files on the next commit\n"
+"\n"
+" Mark the specified files so they will no longer be tracked\n"
+" after the next commit.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history, and it does not delete them from the\n"
+" working directory.\n"
+"\n"
+" To undo a forget before the next commit, see hg add.\n"
+" "
+msgstr ""
+"次回コミットã«ãŠã‘る指定ファイルã®ç™»éŒ²é™¤å¤–\n"
+"\n"
+" æŒ‡å®šãƒ•ã‚¡ã‚¤ãƒ«ã®æ¬¡å›žã‚³ãƒŸãƒƒãƒˆã«ãŠã‘る登録除外を予約ã—ã¾ã™ã€‚\n"
+"\n"
+" 本コマンドã§ã®ç™»éŒ²é™¤å¤–ã¯ã€ç¾ãƒ–ランãƒã«ãŠã‘る登録除外ã®ã¿ã‚’æ„味ã—ã€\n"
+" 履歴ãã®ã‚‚ã®ã¯ä¿æŒã•れ続ã‘ã¾ã™ã—ã€ä½œæ¥­é ˜åŸŸã‹ã‚‰ã‚‚削除ã•れã¾ã›ã‚“。\n"
+"\n"
+" コミットå‰ã®ç™»éŒ²é™¤å¤–ã®å–り消ã—㯠'hg help add' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid "no files specified"
+msgstr "ãƒ•ã‚¡ã‚¤ãƒ«åæŒ‡å®šãŒã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "not removing %s: file is already untracked\n"
+msgstr "%s ã¯å‰Šé™¤ã•れã¾ã›ã‚“: æ—¢ã«æ§‹æˆç®¡ç†å¯¾è±¡ã§ã¯ã‚りã¾ã›ã‚“\n"
+
+msgid ""
+"search for a pattern in specified files and revisions\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which a\n"
+" match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+msgstr ""
+"特定ã®ãƒ‘ターンã«åˆè‡´ã™ã‚‹ãƒ•ァイルã¨ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æ¤œç´¢\n"
+"\n"
+" æ­£è¦è¡¨ç¾ã«åˆè‡´ã™ã‚‹ãƒ•ァイルをå«ã‚€ãƒªãƒ“ジョンを検索ã—ã¾ã™ã€‚\n"
+"\n"
+" æœ¬ã‚³ãƒžãƒ³ãƒ‰ã®æŒ™å‹•㯠Unix ã® grep ã¨ã¯ç•°ãªã‚Šã¾ã™ã€‚解釈å¯èƒ½ãªæ­£è¦è¡¨ç¾ã¯\n"
+" Python/Perl å½¢å¼ã®ã‚‚ã®ã ã‘ã§ã™ã€‚検索対象ã¯ãƒªãƒã‚¸ãƒˆãƒªå†…ã®ãƒ‡ãƒ¼ã‚¿ã®ã¿ã§ã€\n"
+" ä½œæ¥­é ˜åŸŸã¯æ¤œç´¢å¯¾è±¡ã«ã¯å«ã¾ã‚Œã¾ã›ã‚“。パターンã«åˆè‡´ã™ã‚‹å†…容ãŒç¾ã‚ŒãŸ\n"
+" リビジョンを表示ã—ã¾ã™ã€‚\n"
+"\n"
+" 指定ãŒç„¡ã„å ´åˆæœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯ã€ãƒ‘ターンã«åˆè‡´ã™ã‚‹å†…å®¹ãŒæœ€å°ã«ç¾ã‚ŒãŸ\n"
+" リビジョンをå„ファイル毎ã«è¡¨ç¤ºã—ã¾ã™ã€‚パターンã«åˆè‡´ã™ã‚‹å¤‰æ›´ã®ã‚ã£ãŸ\n"
+" å…¨ã¦ã®ãƒªãƒ“ジョンを表示ã™ã‚‹å ´åˆã€--all を指定ã—ã¾ã™(パターンåˆè‡´éƒ¨åˆ†ã«\n"
+" 対ã™ã‚‹å‰Šé™¤ã¯ \"-\"ã€è¿½åŠ ã¯ \"+\" ã‚’æ¤œç´¢çµæžœã«è¡¨ç¤ºã™ã‚‹ã“ã¨ã§åŒºåˆ¥)。\n"
+" "
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr "grep: '%s' ã¯ä¸æ­£ãªãƒ‘ターンã§ã™\n"
+
+msgid ""
+"show current repository heads or show branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" If one or more REV is given, the \"branch heads\" will be shown for\n"
+" the named branch associated with that revision. The name of the\n"
+" branch is called the revision's branch tag.\n"
+"\n"
+" Branch heads are revisions on a given named branch that do not have\n"
+" any descendants on the same branch. A branch head could be a true head\n"
+" or it could be the last changeset on a branch before a new branch\n"
+" was created. If none of the branch heads are true heads, the branch\n"
+" is considered inactive.\n"
+"\n"
+" If STARTREV is specified only those heads (or branch heads) that\n"
+" are descendants of STARTREV will be displayed.\n"
+" "
+msgstr ""
+"ç¾æ™‚点ã§ã®ãƒªãƒã‚¸ãƒˆãƒª(ãªã„ã—ブランãƒ)ã®ãƒ˜ãƒƒãƒ‰è¡¨ç¤º\n"
+"\n"
+" 引数指定ãŒç„¡ã„å ´åˆã€ãƒªãƒã‚¸ãƒˆãƒªä¸­ã®å…¨ã¦ã®ãƒ˜ãƒƒãƒ‰ã‚’表示ã—ã¾ã™ã€‚\n"
+"\n"
+" リãƒã‚¸ãƒˆãƒªã®ã€Œãƒ˜ãƒƒãƒ‰ã€ã¨ã¯ã€å­ãƒªãƒ“ジョンをæŒãŸãªã„リビジョンã®\n"
+" ã“ã¨ã‚’指ã—ã¾ã™ã€‚改変作業ã®å®Ÿæ–½ã‚„ã€update/merge コマンド実施ã®éš›ã«ã¯\n"
+" ã“ã®ãƒªãƒ“ジョンを対象ã¨ã™ã‚‹ã®ãŒä¸€èˆ¬çš„ã§ã™ã€‚\n"
+"\n"
+" 1ã¤ä»¥ä¸Šã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れãŸå ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯æŒ‡å®šãƒªãƒ“ジョンã®å±ž\n"
+" ã™ã‚‹åå‰ä»˜ãブランãƒã®ã€Œãƒ–ランãƒãƒ˜ãƒƒãƒ‰ã€ã‚’表示ã—ã¾ã™ã€‚\n"
+"\n"
+" ブランãƒã®ãƒ˜ãƒƒãƒ‰ã¨ã¯ã€å½“該ブランãƒã«å±žã—ã¤ã¤ã€ãã®ãƒ–ランãƒã«å±žã™ã‚‹\n"
+" å­ãƒªãƒ“ジョンをæŒãŸãªã„リビジョンã®ã“ã¨ã‚’指ã—ã¾ã™ã€‚ブランãƒãƒ˜ãƒƒãƒ‰ã¯\n"
+" 真ã®ãƒ˜ãƒƒãƒ‰ã§ã‚ã‚‹å ´åˆã¨ã€æ–°ãŸãªæžåˆ†ã‹ã‚Œã‚„マージã®ç›´å‰ã®ãƒªãƒ“ジョンã§\n"
+" ã‚ã‚‹å ´åˆã®ã„ãšã‚Œã‹ã§ã™ã€‚ã„ãšã‚Œã®ãƒ˜ãƒƒãƒ‰ã‚‚真ã®ãƒ˜ãƒƒãƒ‰ã§ç„¡ã„å ´åˆã€ãã®\n"
+" ブランãƒã¯éžã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã¨ã¿ãªã•れã¾ã™ã€‚\n"
+"\n"
+" é–‹å§‹ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れãŸå ´åˆã€æŒ‡å®šãƒªãƒ“ジョンã®å­å­«ã¨ãªã‚‹ãƒ˜ãƒƒãƒ‰\n"
+" ã®ã¿ãŒè¡¨ç¤ºã•れã¾ã™ã€‚\n"
+" "
+
+#, python-format
+msgid "no open branch heads on branch %s\n"
+msgstr "ブランム%s ã«ã¯ã‚ªãƒ¼ãƒ—ンãªãƒ˜ãƒƒãƒ‰ãŒã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "no changes on branch %s containing %s are reachable from %s\n"
+msgstr "ブランム%s ã®ãƒªãƒ“ジョンã¯(%s ã‚‚å«ã‚ã¦) %s ã‹ã‚‰åˆ°é”ã§ãã¾ã›ã‚“\n"
+
+#, python-format
+msgid "no changes on branch %s are reachable from %s\n"
+msgstr "ブランム%s ã®ãƒªãƒ“ジョン㯠%s ã‹ã‚‰åˆ°é”ã§ãã¾ã›ã‚“\n"
+
+msgid ""
+"show help for a given topic or a help overview\n"
+"\n"
+" With no arguments, print a list of commands with short help messages.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that\n"
+" topic."
+msgstr ""
+"指定ã•れãŸãƒˆãƒ”ックã®ãƒ˜ãƒ«ãƒ—ã‚„ã€ãƒ˜ãƒ«ãƒ—概è¦ã®è¡¨ç¤º\n"
+"\n"
+" 引数指定ãŒç„¡ã„å ´åˆã€ã‚³ãƒžãƒ³ãƒ‰ã®ä¸€è¦§ã¨æ¦‚è¦ã‚’表示ã—ã¾ã™ã€‚\n"
+"\n"
+" トピックやコマンドåãŒæŒ‡å®šã•れãŸå ´åˆã€æŒ‡å®šå¯¾è±¡ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚"
+
+msgid "global options:"
+msgstr "グローãƒãƒ«ã‚ªãƒ—ション:"
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr "全コマンドã®ä¸€è¦§ã¯ \"hg help\" ã§è¡¨ç¤ºã•れã¾ã™"
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr ""
+"全コマンドã®ä¸€è¦§ã¯ \"hg help\" ã§ã€ã‚³ãƒžãƒ³ãƒ‰è©³ç´°ã¯ \"hg -v\" ã§è¡¨ç¤ºã•れã¾ã™"
+
+#, python-format
+msgid "use \"hg -v help%s\" to show aliases and global options"
+msgstr "別åãŠã‚ˆã³ã‚°ãƒ­ãƒ¼ãƒãƒ«ã‚ªãƒ—ション㯠\"hg -v help%s\" ã§è¡¨ç¤ºã•れã¾ã™"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "グローãƒãƒ«ã‚ªãƒ—ション㯠\"hg -v help %s\" ã§è¡¨ç¤ºã•れã¾ã™"
+
+msgid ""
+"list of commands:\n"
+"\n"
+msgstr ""
+"コマンド一覧:\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"別å: %s\n"
+
+msgid "(no help text available)"
+msgstr "(ヘルプã¯ã‚りã¾ã›ã‚“)"
+
+msgid "options:\n"
+msgstr "オプション:\n"
+
+msgid "no commands defined\n"
+msgstr "コマンドãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“\n"
+
+msgid "enabled extensions:"
+msgstr "有効化ã•れã¦ã„るエクステンション:"
+
+msgid "no help text available"
+msgstr "ヘルプã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "%s extension - %s\n"
+msgstr "%s エクステンション - %s\n"
+
+msgid "Mercurial Distributed SCM\n"
+msgstr "Mercurial - 分散構æˆç®¡ç†ãƒ„ール\n"
+
+msgid ""
+"basic commands:\n"
+"\n"
+msgstr ""
+"基本コマンド:\n"
+"\n"
+
+msgid ""
+"\n"
+"additional help topics:\n"
+"\n"
+msgstr ""
+"\n"
+"追加ã®ãƒ˜ãƒ«ãƒ—トピック:\n"
+"\n"
+
+msgid ""
+"identify the working copy or specified revision\n"
+"\n"
+" With no revision, print a summary of the current state of the\n"
+" repository.\n"
+"\n"
+" Specifying a path to a repository root or Mercurial bundle will\n"
+" cause lookup to operate on that repository/bundle.\n"
+"\n"
+" This summary identifies the repository state using one or two\n"
+" parent hash identifiers, followed by a \"+\" if there are\n"
+" uncommitted changes in the working directory, a list of tags for\n"
+" this revision and a branch name for non-default branches.\n"
+" "
+msgstr ""
+"作業領域ãªã„ã—特定リビジョンã®è­˜åˆ¥æƒ…報表示\n"
+"\n"
+" リビジョン指定無ã—ã®èµ·å‹•ã®éš›ã«ã¯ã€ä½œæ¥­é ˜åŸŸã®çŠ¶æ…‹ã‚’è¡¨ç¤ºã—ã¾ã™ã€‚\n"
+"\n"
+" パス指定有りã§ã®èµ·å‹•ã®éš›ã«ã¯ã€ä»–ã®ãƒªãƒã‚¸ãƒˆãƒªãªã„ã—ãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイルã®\n"
+" 状態を表示ã—ã¾ã™ã€‚\n"
+"\n"
+" 本コマンドã®å‡ºåŠ›ã™ã‚‹è¦ç´„情報ã¯ã€1ã¤ãªã„ã—2ã¤ã®è¦ªãƒªãƒ“ジョンã®ãƒãƒƒã‚·ãƒ¥\n"
+" 値を使用ã—ã¦ã€ä½œæ¥­é ˜åŸŸã®çŠ¶æ…‹ã‚’è­˜åˆ¥ã—ã¾ã™ã€‚ä½œæ¥­é ˜åŸŸã«æœªã‚³ãƒŸãƒƒãƒˆã®\n"
+" 変更ãŒã‚ã‚‹å ´åˆã¯ \"+\"ã€å½“該リビジョンã«ã‚¿ã‚°ãŒä»˜ã„ã¦ã„ã‚‹å ´åˆã¯ã‚¿ã‚°ã®\n"
+" 一覧ã€default 以外ã®ãƒ–ランãƒã®å ´åˆã«ã¯ãƒ–ランãƒåãŒã€ãƒãƒƒã‚·ãƒ¥å€¤ã®å¾Œã«\n"
+" ç¶šãã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"import an ordered set of patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f/--force flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (to use the body part, it must have type\n"
+" text/plain or text/x-patch). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and\n"
+" description from patch override values from message headers and\n"
+" body. Values given on command line with -m/--message and -u/--user\n"
+" override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory to\n"
+" the parent of each patch before applying it, and will abort if the\n"
+" resulting changeset has a different ID than the one recorded in\n"
+" the patch. This may happen due to character set problems or other\n"
+" deficiencies in the text patch format.\n"
+"\n"
+" With -s/--similarity, hg will attempt to discover renames and\n"
+" copies in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use \"-\" as the patch name. If\n"
+" a URL is specified, the patch will be downloaded from it.\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"パッãƒã®é †æ¬¡å–り込ã¿\n"
+"\n"
+" 列挙ã•れãŸãƒ‘ッãƒã®å–り込ã¿ãŠã‚ˆã³ã‚³ãƒŸãƒƒãƒˆã‚’個別ã«è¡Œã„ã¾ã™ã€‚\n"
+"\n"
+" ä½œæ¥­é ˜åŸŸã«æœªã‚³ãƒŸãƒƒãƒˆã®å¤‰æ›´ãŒã‚ã‚‹å ´åˆã€-f/--force ãŒæŒ‡å®šã•れãªã„é™ã‚Š\n"
+" å–り込ã¿ã¯å®Ÿæ–½ã•れã¾ã›ã‚“。\n"
+"\n"
+" é›»å­ãƒ¡ãƒ¼ãƒ«ã‹ã‚‰ç›´æŽ¥ãƒ‘ッãƒã‚’å–り込むã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚添付ファイル\n"
+" å½¢å¼ã®ãƒ‘ッãƒã§ã‚ã£ã¦ã‚‚å–り込ã¿å¯èƒ½ã§ã™(text/plain ãªã„ã— \n"
+" text/x-patch åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“)。作æˆè€…ãŠã‚ˆã³ã‚³ãƒŸãƒƒãƒˆãƒ­ã‚°ãŒç„¡ã„\n"
+" å ´åˆã€é›»å­ãƒ¡ãƒ¼ãƒ«ã® From ãŠã‚ˆã³ Subject ヘッダ値ãŒä½¿ç”¨ã•れã¾ã™ã€‚\n"
+" 最åˆã®ãƒ‘ッãƒãƒ‡ãƒ¼ã‚¿ã«å…ˆç«‹ã¤ text/plain ボディã¯ã€ã‚³ãƒŸãƒƒãƒˆãƒ­ã‚°ã«è¿½è¨˜\n"
+" ã•れã¾ã™ã€‚\n"
+"\n"
+" 'hg export' ã«ã‚ˆã‚Šç”Ÿæˆã•れãŸãƒ‘ッãƒã‚’å–り込む場åˆã€é›»å­ãƒ¡ãƒ¼ãƒ«ã®\n"
+" ãƒ˜ãƒƒãƒ€ã‚„ãƒœãƒ‡ã‚£ã®æƒ…報よりもã€ãƒ‘ッãƒã«å«ã¾ã‚Œã‚‹æƒ…å ±ã®æ–¹ãŒå„ªå…ˆã—ã¾ã™ã€‚\n"
+" コマンドラインã§ã® -m/--message ãªã„ã— -u/--user 指定ã¯ã“れらよりも\n"
+" 優先ã—ã¾ã™ã€‚\n"
+"\n"
+" --exact ãŒæŒ‡å®šã•れãŸå ´åˆã€ä½œæ¥­é ˜åŸŸã‚’パッãƒã®è¦ªãƒªãƒ“ã‚¸ãƒ§ãƒ³ã«æ›´æ–°ã—ã¦\n"
+" ã‹ã‚‰ãƒ‘ッãƒã‚’é©ç”¨ã—ã¾ã™ãŒã€ä½œæˆã•れãŸãƒªãƒ“ジョンã®ãƒãƒƒã‚·ãƒ¥å€¤ãŒã€ãƒ‘ッãƒ\n"
+" ã«è¨˜éŒ²ã•れãŸå€¤ã¨ç•°ãªã‚‹å ´åˆã€å–り込ã¿ã¯å®Ÿæ–½ã•れã¾ã›ã‚“。ã“ã®ç¾è±¡ã¯ã€\n"
+" 利用ã™ã‚‹æ–‡å­—符å·åŒ–ã®å•題やã€ãƒ‘ッãƒã®ãƒ†ã‚­ã‚¹ãƒˆéƒ¨åˆ†ã®ä¸è¶³ãªã©ãŒåŽŸå› ã§\n"
+" 発生ã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n"
+"\n"
+" -s/--similarity ãŒæŒ‡å®šã•れãŸå ´åˆã€'hg addremove' ã¨åŒæ§˜ãªæ–¹é‡ã§ã€\n"
+" パッãƒã«ã‚ˆã‚‹å¤‰æ›´å†…容ã‹ã‚‰ã€æ”¹åや複製を検出ã—ã¾ã™ã€‚\n"
+"\n"
+" 標準入力ã‹ã‚‰ãƒ‘ッãƒã‚’å–り込むã«ã¯ã€ãƒ‘ッãƒåã« \"-\" を指定ã—ã¾ã™ã€‚\n"
+" URL ãŒæŒ‡å®šã•れãŸå ´åˆã€ãƒ‘ッãƒã‚’当該 URL ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ã¾ã™ã€‚\n"
+" -d/--date ã¸ã®æŒ‡å®šã«é–¢ã—ã¦ã¯ã€'hg help dates' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid "applying patch from stdin\n"
+msgstr "標準入力ã‹ã‚‰ã®ãƒ‘ッãƒã‚’é©ç”¨ä¸­\n"
+
+msgid "no diffs found"
+msgstr "差分ãŒã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid ""
+"message:\n"
+"%s\n"
+msgstr ""
+"メッセージ:\n"
+"%s\n"
+
+msgid "not a Mercurial patch"
+msgstr "Mercurial å‘ã‘ã®ãƒ‘ッãƒã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "patch is damaged or loses information"
+msgstr "パッãƒã«ã¯ç ´æãªã„ã—æƒ…å ±ã®æ¬ è½ãŒã‚りã¾ã™"
+
+msgid ""
+"show new changesets found in source\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would have been pulled\n"
+" if a pull at the time you issued this command.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the\n"
+" changesets twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+msgstr ""
+"指定リãƒã‚¸ãƒˆãƒªä¸­ã®æœªå–り込ã¿ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æ¤œç´¢\n"
+"\n"
+" ファイルパスや URLã€'hg pull' ã® default å–り込ã¿å¯¾è±¡ã«ã‚ˆã‚ŠæŒ‡å®š\n"
+" ã•れるリãƒã‚¸ãƒˆãƒªä¸­ã®ã€æœªå–り込ã¿ãƒªãƒ“ジョンを検索ã—ã¾ã™ã€‚\n"
+" ã“れらã¯ã€'hg pull' を実行ã—ãŸéš›ã®å–り込ã¿å¯¾è±¡ãƒªãƒ“ジョンã§ã™ã€‚\n"
+"\n"
+" é éš”ホストã®ãƒªãƒã‚¸ãƒˆãƒªã®å ´åˆã€--bundle を使用ã™ã‚‹ã“ã¨ã§ã€æœ¬ã‚³ãƒžãƒ³ãƒ‰\n"
+" 実行後㮠'hg pull' 実施ã®éš›ã«ã€å†åº¦ã®ãƒªãƒ“ジョン検索を抑止ã§ãã¾ã™ã€‚\n"
+"\n"
+" 対象リãƒã‚¸ãƒˆãƒªã®æŒ‡å®šå½¢å¼ã¯ 'hg help pull' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid ""
+"create a new repository in the given directory\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it will be created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"指定ã•れãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã®æ–°è¦ãƒªãƒã‚¸ãƒˆãƒªã®ä½œæˆ\n"
+"\n"
+" 指定ã•れãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ–°è¦ãƒªãƒã‚¸ãƒˆãƒªã‚’作æˆã—ã¾ã™ã€‚指定ã•れãŸ\n"
+" ディレクトリãŒå­˜åœ¨ã—ãªã„å ´åˆã«ã¯ã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’作æˆã—ã¾ã™ã€‚\n"
+"\n"
+" ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒæŒ‡å®šã•れãªã„å ´åˆã€ç¾ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒåˆæœŸåŒ–ã•れã¾ã™ã€‚\n"
+"\n"
+" 複製先ã¨ã—㦠ssh:// URL å½¢å¼ã‚’指定ã™ã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚\n"
+" 詳細ã«é–¢ã—ã¦ã¯ã€'hg help urls' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid ""
+"locate files matching specific patterns\n"
+"\n"
+" Print files under Mercurial control in the working directory whose\n"
+" names match the given patterns.\n"
+"\n"
+" By default, this command searches all directories in the working\n"
+" directory. To search just the current directory and its\n"
+" subdirectories, use \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints the names\n"
+" of all files under Mercurial control in the working directory.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the -0 option to both this command and \"xargs\". This\n"
+" will avoid the problem of \"xargs\" treating single filenames that\n"
+" contain whitespace as multiple filenames.\n"
+" "
+msgstr ""
+"指定ã•れãŸãƒ‘ターンã«åˆè‡´ã™ã‚‹åå‰ã‚’æŒã¤ãƒ•ァイルã®ç‰¹å®š\n"
+"\n"
+" æ§‹æˆç®¡ç†å¯¾è±¡ã¨ãªã‚‹ãƒ•ァイルã®ä¸­ã‹ã‚‰ã€æŒ‡å®šã•れãŸãƒ‘ターンã«åˆè‡´ã™ã‚‹\n"
+" åå‰ã®ãƒ•ァイルを特定ã—ã¾ã™ã€‚\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯æ§‹æˆç®¡ç†å¯¾è±¡ã¨ãªã‚‹ä½œæ¥­é ˜åŸŸä¸­ã®\n"
+" 全ディレクトリを検索対象ã¨ã—ã¾ã™ã€‚ç¾ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨ãã®é…下ã®ã¿ã‚’検索\n"
+" 対象ã¨ã™ã‚‹å ´åˆã¯ \"--include .\" を指定ã—ã¾ã™ã€‚\n"
+"\n"
+" パターン指定ãŒç„¡ã„å ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯æ§‹æˆç®¡ç†å¯¾è±¡ä¸‹ã«ã‚る作業領域中ã®\n"
+" å…¨ã¦ã®ãƒ•ァイルåを表示ã—ã¾ã™ã€‚\n"
+"\n"
+" 本コマンドã®å‡ºåŠ›ã‚’ \"xargs\" コマンドã¸ã¨æ¸¡ã™å ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¨\n"
+" \"xargs\" コマンドã®ä¸¡æ–¹ã« \"-0\" を指定ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚\n"
+" 空白文字をå«ã‚€å˜ä¸€ã®ãƒ•ァイルåã‚’ã€\"xargs\" ãŒè¤‡æ•°ã®ãƒ•ァイルåã«è§£é‡ˆ\n"
+" ã—ã¦ã—ã¾ã†å•題ã¯ã€ã“ã®ã‚ªãƒ—ションã«ã‚ˆã‚Šè§£æ¶ˆã•れã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a filename to follow history across\n"
+" renames and copies. --follow without a filename will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command prints revision number and changeset id,\n"
+" tags, non-trivial parents, user, date and time, and a summary for\n"
+" each commit. When the -v/--verbose switch is used, the list of\n"
+" changed files and full commit message are shown.\n"
+"\n"
+" NOTE: log -p/--patch may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, only files different from BOTH parents\n"
+" will appear in files:.\n"
+" "
+msgstr ""
+"リãƒã‚¸ãƒˆãƒªå…¨ä½“ãªã„ã—ファイルã®å¤‰æ›´å±¥æ­´ã®è¡¨ç¤º\n"
+"\n"
+" 特定ã®ãƒ•ァイルãªã„ã—リãƒã‚¸ãƒˆãƒªå…¨ä½“ã®å¤‰æ›´å±¥æ­´ã‚’表示ã—ã¾ã™ã€‚\n"
+"\n"
+" ファイルã®å±¥æ­´è¡¨ç¤ºã§ã¯ã€æ”¹åï¼è¤‡è£½æ™‚ã®å…ƒãƒ•ァイルã«ã¾ã§ã•ã‹ã®ã¼ã£ãŸ\n"
+" 履歴ã¯è¡¨ç¤ºã—ã¾ã›ã‚“。元ファイルã®å±¥æ­´ã‚’ã•ã‹ã®ã¼ã‚‹å ´åˆã¯ã€ãƒ•ァイル\n"
+" åã¨ä¸€ç·’ã« -f/--follow を使用ã—ã¾ã™ã€‚--follow 指定ã®éš›ã«ãƒ•ァイル\n"
+" åãŒæŒ‡å®šã•れãªã„å ´åˆã¯ã€é–‹å§‹ãƒªãƒ“ジョンã«é€£ãªã‚‹ãƒªãƒ“ジョンã®ã¿ã‚’表示\n"
+" ã—ã¾ã™ã€‚--follow-first 指定ã¯ã€ãƒžãƒ¼ã‚¸ãƒªãƒ“ジョンã«ãŠã„ã¦ç¬¬1親ã®å±¥æ­´\n"
+" ã®ã¿ã‚’ã•ã‹ã®ã¼ã‚Šã¾ã™ã€‚\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šã•れãªã„å ´åˆã€å¯¾è±¡ã¨ãªã‚‹ãƒªãƒ“ジョンã®ç¯„囲ã¯tip:0 ã¨ã¿ãªã•れ\n"
+" ã¾ã™ãŒã€--follow ãŒæŒ‡å®šã•れãŸå ´åˆã¯ã€ä½œæ¥­é ˜åŸŸã®è¦ªãƒªãƒ“ジョンãŒé–‹å§‹\n"
+" リビジョンã¨ã¿ãªã•れã¾ã™ã€‚\n"
+"\n"
+" -d/--date ã¸ã®æŒ‡å®šã«é–¢ã—ã¦ã¯ã€'hg help dates' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã¯ä»¥ä¸‹ã®æƒ…報を出力ã—ã¾ã™:\n"
+"\n"
+" リビジョン番å·ã€ãƒãƒƒã‚·ãƒ¥å€¤ã€ã‚¿ã‚°ã€(リビジョン番å·ã®é›¢ã‚ŒãŸ)\n"
+" 親リビジョンã€ä½œæˆè€…ã€ä½œæˆæ—¥æ™‚ãŠã‚ˆã³ã‚³ãƒŸãƒƒãƒˆãƒ­ã‚°ã®1行目\n"
+"\n"
+" -v/--verbose ãŒæŒ‡å®šã•れãŸå ´åˆã€å¤‰æ›´å¯¾è±¡ãƒ•ァイル一覧ã¨ã€ã‚³ãƒŸãƒƒãƒˆ\n"
+" ログã®å…¨æ–‡ã‚‚表示ã•れã¾ã™ã€‚\n"
+"\n"
+" 備考: マージ実施リビジョンã«å¯¾ã™ã‚‹ -p/--patch ãŒäºˆæœŸã›ã¬å‡ºåŠ›ã‚’ç”Ÿæˆ\n"
+" ã™ã‚‹ã®ã¯ã€å¸¸ã«ç¬¬1親ã¨ã®å·®åˆ†ã‚’表示ã™ã‚‹ãŸã‚ã§ã™ã€‚ファイル一覧ãŒäºˆæœŸ\n"
+" ã›ã¬å†…容ã¨ãªã‚‹ã®ã¯ã€ä¸¡æ–¹ã®è¦ªã¨ç•°ãªã‚‹ãƒ•ァイルãŒåˆ—挙ã•れるãŸã‚ã§ã™ã€‚\n"
+" "
+
+msgid ""
+"output the current or given revision of the project manifest\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the first parent of the working directory\n"
+" is used, or the null revision if no revision is checked out.\n"
+"\n"
+" With -v, print file permissions, symlink and executable bits.\n"
+" With --debug, print file revision hashes.\n"
+" "
+msgstr ""
+"ç¾æ™‚点ãªã„ã—æŒ‡å®šæ™‚点ã§ã®ãƒªãƒã‚¸ãƒˆãƒªãƒžãƒ‹ãƒ•ェストã®å‡ºåŠ›\n"
+"\n"
+" 指定リビジョンã«ãŠã‘ã‚‹æ§‹æˆç®¡ç†å¯¾è±¡ãƒ•ァイルã®ä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n"
+" リビジョン指定ãŒç„¡ã„å ´åˆã€ä½œæ¥­é ˜åŸŸã®(第1)親リビジョンã‹ã€\n"
+" ä½œæ¥­é ˜åŸŸã®æ›´æ–°å‰ãªã‚‰ null ãŒä½¿ç”¨ã•れã¾ã™ã€‚\n"
+"\n"
+" -v ãŒæŒ‡å®šã•れãŸå ´åˆã€ãƒ•ァイルアクセス権やシンボリックリンクã€\n"
+" 実行å¯èƒ½ãƒ“ットã¨ã„ã£ãŸã‚‚ã®ã‚‚表示ã•れã¾ã™ã€‚\n"
+" --debug ãŒæŒ‡å®šã•れãŸå ´åˆã€å„ファイルã®ãƒªãƒ“ジョンã®ãƒãƒƒã‚·ãƒ¥å€¤ãŒ\n"
+" 表示ã•れã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"merge working directory with another revision\n"
+"\n"
+" The current working directory is updated with all changes made in\n"
+" the requested revision since the last common predecessor revision.\n"
+"\n"
+" Files that changed between either parent are marked as changed for\n"
+" the next commit and a commit must be performed before any further\n"
+" updates to the repository are allowed. The next commit will have\n"
+" two parents.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other\n"
+" head, the other head is merged with by default. Otherwise, an\n"
+" explicit revision with which to merge with must be provided.\n"
+" "
+msgstr ""
+"作業領域ã®å†…容ã¨ä»–ã®ãƒªãƒ“ジョンã®ãƒžãƒ¼ã‚¸\n"
+"\n"
+" ç¾æ™‚点ã§ã®ä½œæ¥­é ˜åŸŸã®å†…å®¹ã‚’ã€æŒ‡å®šã•れãŸãƒªãƒ“ジョンã¸ã¨è‡³ã‚‹ã¾ã§ã®\n"
+" 共通ã®è¦ªãƒªãƒ“ジョンã‹ã‚‰ã®å¤‰æ›´å†…容ã¨ãƒžãƒ¼ã‚¸ã—ã¾ã™ã€‚\n"
+"\n"
+" 両方ã®è¦ªãƒªãƒ“ジョンã«å¯¾ã—ã¦å·®åˆ†ã®ã‚るファイルã¯ã€æ¬¡å›žã‚³ãƒŸãƒƒãƒˆã®éš›ã«ã¯\n"
+" 変更ã•れãŸã‚‚ã®ã¨ã—ã¦è¨˜éŒ²ã•れã¾ã™ã®ã§ã€å¿…è¦ä»¥ä¸Šã®å¤‰æ›´ãŒå®Ÿæ–½ã•れるå‰ã«\n"
+" コミットを実施ã—ã¦ãã ã•ã„。ã“ã®ã‚³ãƒŸãƒƒãƒˆæ™‚ã«ç”Ÿæˆã•れるリビジョンã¯ã€\n"
+" 親リビジョンを2ã¤æŒã¤ãƒªãƒ“ジョンã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" ãƒžãƒ¼ã‚¸å¯¾è±¡ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŒ‡å®šãŒç„¡ãã€ä½œæ¥­é ˜åŸŸã®è¦ªãƒªãƒ“ジョンãŒãƒ˜ãƒƒãƒ‰ã§ã€\n"
+" 且ã¤ç¾è¡Œãƒ–ランãƒãŒã‚‚ã†1ã¤ã ã‘ヘッドをæŒã¤å ´åˆã€ãã®ãƒ˜ãƒƒãƒ‰ãŒãƒžãƒ¼ã‚¸å¯¾è±¡\n"
+" ã¨ãªã‚Šã¾ã™ã€‚ãれ以外ã®å ´åˆã¯ã€æ˜Žç¤ºçš„ãªãƒªãƒ“ジョン指定ãŒå¿…è¦ã§ã™ã€‚\n"
+" "
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr "ブランム'%s' ã«ã¯ãƒ˜ãƒƒãƒ‰ãŒ %d ã‚りã¾ã™ - マージ対象を明示ã—ã¦ãã ã•ã„"
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr ""
+"ブランム'%s' ã«ã¯ãƒ˜ãƒƒãƒ‰ãŒ1ã—ã‹ã‚りã¾ã›ã‚“ - マージ対象を明示ã—ã¦ãã ã•ã„"
+
+msgid "there is nothing to merge"
+msgstr "マージã®å¿…è¦ãŒã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr "%s - \"hg update\" を使用ã—ã¦ãã ã•ã„"
+
+msgid ""
+"working dir not at a head rev - use \"hg update\" or merge with an explicit "
+"rev"
+msgstr ""
+"作業領域ã®è¦ªãƒªãƒ“ジョンã¯ãƒ˜ãƒƒãƒ‰ã§ã¯ã‚りã¾ã›ã‚“。\n"
+"リビジョンを明示ã—ã¦ã® \"hg update\" ãªã„ã—マージを実施ã—ã¦ãã ã•ã„。"
+
+msgid ""
+"show changesets not found in destination\n"
+"\n"
+" Show changesets not found in the specified destination repository\n"
+" or the default push location. These are the changesets that would\n"
+" be pushed if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+msgstr ""
+"連æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã«å«ã¾ã‚Œãªã„ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®è¡¨ç¤º\n"
+"\n"
+" 指定ã•れãŸé€£æºå…ˆãƒªãƒã‚¸ãƒˆãƒª(ãªã„ã—ã€ç„¡æŒ‡å®šæ™‚ã® hg push 先リãƒã‚¸ãƒˆãƒª)ã«\n"
+" å«ã¾ã‚Œãªã„ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’表示ã—ã¾ã™ã€‚ã“ã“ã§è¡¨ç¤ºã•れるãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã¯\n"
+" hg push 実施ã®éš›ã«ã€é€£æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã¸ã¨å映ã•れるãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã§ã™ã€‚\n"
+"\n"
+" 指定å¯èƒ½ãªãƒªãƒã‚¸ãƒˆãƒªæŒ‡å®šå½¢å¼ã¯ hg pull ã®ãƒ˜ãƒ«ãƒ—ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid ""
+"show the parents of the working directory or revision\n"
+"\n"
+" Print the working directory's parent revisions. If a revision is\n"
+" given via -r/--rev, the parent of that revision will be printed.\n"
+" If a file argument is given, the revision in which the file was\n"
+" last changed (before the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"作業領域(ãªã„ã—æŒ‡å®šãƒªãƒ“ジョン)ã®è¦ªãƒªãƒ“ジョンã®è¡¨ç¤º\n"
+"\n"
+" 作業領域ã®è¦ªãƒªãƒ“ジョンを表示ã—ã¾ã™ã€‚-r/--rev ã§ã®ãƒªãƒ“ジョン指定ãŒ\n"
+" ã‚ã‚‹å ´åˆã€æŒ‡å®šãƒªãƒ“ジョンã®è¦ªãƒªãƒ“ジョンを表示ã—ã¾ã™ã€‚ãƒ•ã‚¡ã‚¤ãƒ«ãŒæŒ‡å®š\n"
+" ã•れãŸå ´åˆã€(作業領域ã®è¦ªãƒªãƒ“ジョンã€ãªã„ã— --rev 指定ã®ãƒªãƒ“ジョン\n"
+" 以å‰ã®ã‚‚ã®ã§)ãã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’æœ€å¾Œã«æ›´æ–°ã—ãŸãƒªãƒ“ジョンを表示ã—ã¾ã™ã€‚\n"
+" "
+
+msgid "can only specify an explicit filename"
+msgstr "明示的ãªãƒ•ァイルåä»¥å¤–ã¯æŒ‡å®šã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr "'%s' ã¯ç®¡ç†å¯¾è±¡ã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid ""
+"show aliases for remote repositories\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given,\n"
+" show definition of all available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"連æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã®åˆ¥å一覧ã®è¡¨ç¤º\n"
+"\n"
+" 指定ã•れãŸã‚·ãƒ³ãƒœãƒ«åã«ç›¸å½“ã™ã‚‹é€£æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã‚’表示ã—ã¾ã™ã€‚\n"
+" シンボルåãŒæŒ‡å®šã•れãªã„å ´åˆã€å…¨ã¦ã®åˆ¥å定義ãŒè¡¨ç¤ºã•れã¾ã™ã€‚\n"
+"\n"
+" シンボル定義ã¯ã€/etc/mercurial/hgrc ãŠã‚ˆã³ $HOME/.hgrc 等㮠[paths]\n"
+" セクションã«è¨˜è¿°ã•れã¾ã™ã€‚作業領域ã§ã®å®Ÿè¡Œã®å ´åˆã¯ .hg/hgrc ã«ã‚‚記述\n"
+" å¯èƒ½ã§ã™ã€‚\n"
+"\n"
+" 詳細㯠'hg help urls' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid "not found!\n"
+msgstr "指定シンボルã¯ä¸æ˜Žã§ã™\n"
+
+msgid "not updating, since new heads added\n"
+msgstr "æ–°è¦ãƒ˜ãƒƒãƒ‰ãŒè¿½åŠ ã•れãŸãŸã‚ã€ä½œæ¥­é ˜åŸŸã¯æ›´æ–°ã—ã¾ã›ã‚“\n"
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr "(ヘッド一覧表示㯠'hg heads'ã€ãƒžãƒ¼ã‚¸å®Ÿæ–½ã¯ 'hg merge')\n"
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr "(ä½œæ¥­é ˜åŸŸã®æ›´æ–°ã¯ 'hg update')\n"
+
+msgid ""
+"pull changes from the specified source\n"
+"\n"
+" Pull changes from a remote repository to a local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to a local repository (the current one unless\n"
+" -R is specified). By default, this does not update the copy of the\n"
+" project in the working directory.\n"
+"\n"
+" Use hg incoming if you want to see what would have been added by a\n"
+" pull at the time you issued this command. If you then decide to\n"
+" added those changes to the repository, you should use pull -r X\n"
+" where X is the last changeset listed by hg incoming.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"指定リãƒã‚¸ãƒˆãƒªã‹ã‚‰ã®å¤‰æ›´å±¥æ­´ã®å–り込ã¿\n"
+"\n"
+" 連æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã‹ã‚‰æ‰‹å…ƒã®ãƒªãƒã‚¸ãƒˆãƒªã«å¤‰æ›´å±¥æ­´ã‚’å–り込ã¿ã¾ã™ã€‚\n"
+"\n"
+" パスや URL ã§æŒ‡å®šã•れる連æºå…ˆãƒªãƒã‚¸ãƒˆãƒªä¸­ã®ã€å…¨ã¦ã®ãƒªãƒ“ジョンãŒ\n"
+" (-R 指定ãŒç„¡ã„å ´åˆã¯ç¾åœ¨ã®)リãƒã‚¸ãƒˆãƒªã¸ã®å–り込ã¿å¯¾è±¡ã¨ãªã‚Šã¾ã™ã€‚\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã—ã¦ã‚‚ã€ä½œæ¥­é ˜åŸŸã®å†…å®¹ã¯æ›´æ–°\n"
+" ã•れã¾ã›ã‚“。\n"
+"\n"
+" 'hg incoming' を使用ã™ã‚‹ã“ã¨ã§ã€å®Ÿéš›ã®å–り込ã¿ã‚’ã›ãšã«ã€'hg pull' ã«\n"
+" よるå–り込ã¿å¯¾è±¡ã‚’確èªã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚表示ã•れãŸå†…容ã®å–り込ã¿ã‚’\n"
+" 決断ã—ãŸãªã‚‰ã°ã€å…ˆã«è¡¨ç¤ºã•ã‚ŒãŸæœ€å¾Œã®ãƒªãƒ“ジョンを '-r' ã®å¼•æ•°ã«ã—ã¦\n"
+" 'hg pull' を実行ã—ã¾ã—ょã†ã€‚\n"
+"\n"
+" 連æºå…ˆãŒçœç•¥ã•れãŸå ´åˆã€'default' パスãŒé€£æºå…ˆã¨ã—ã¦ä½¿ç”¨ã•れã¾ã™ã€‚\n"
+" 詳細㯠'hg help urls' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid ""
+"push changes to the specified destination\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It moves changes from\n"
+" the current repository to a different one. If the destination is\n"
+" local this is identical to a pull in that directory from the\n"
+" current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" user forgot to pull and merge before pushing.\n"
+"\n"
+" If -r/--rev is used, the named revision and all its ancestors will\n"
+" be pushed to the remote repository.\n"
+"\n"
+" Please see 'hg help urls' for important details about ssh://\n"
+" URLs. If DESTINATION is omitted, a default path will be used.\n"
+" "
+msgstr ""
+"指定リãƒã‚¸ãƒˆãƒªã¸ã®å¤‰æ›´å±¥æ­´ã®å映\n"
+"\n"
+" 手元ã®ãƒªãƒã‚¸ãƒˆãƒªã‹ã‚‰é€£æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã«å¤‰æ›´å±¥æ­´ã‚’åæ˜ ã—ã¾ã™ã€‚\n"
+"\n"
+" ã“れ㯠'hg pull' ã¨å¯¾ç§°çš„ãªæ“作ã§ã™ã€‚ç¾åœ¨ã®ãƒªãƒã‚¸ãƒˆãƒªã‹ã‚‰é€£æºå…ˆã¸ã¨\n"
+" å¤‰æ›´å±¥æ­´ã‚’åæ˜ ã•ã›ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚連æºå…ˆãŒåŒä¸€ãƒ›ã‚¹ãƒˆä¸Šã®ãƒªãƒã‚¸ãƒˆãƒª\n"
+" ã§ã‚れã°ã€é€£æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã«ãŠã„ã¦ã€ç¾ãƒªãƒã‚¸ãƒˆãƒªã«å¯¾ã™ã‚‹ 'hg pull'\n"
+" を行ã£ãŸå ´åˆã¨åŒä¸€ã®åŠ¹æžœã‚’æŒã¡ã¾ã™ã€‚\n"
+"\n"
+" 連æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã«ãƒ˜ãƒƒãƒ‰ãŒå¢—ãˆã‚‹å®Ÿè¡Œã¯ã€é€šå¸¸ã¯æ‹’çµ¶ã•れã¾ã™ã€‚\n"
+" ã“ã®ã‚ˆã†ãªå ´åˆã€å¤§æ¦‚㯠'hg push' å‰ã® 'hg pull' ãŠã‚ˆã³ 'hg merge'\n"
+" 実行を忘れã¦ã„ã‚‹ã“ã¨ãŒæ®†ã©ã§ã™ã€‚\n"
+"\n"
+" -r/--rev ãŒæŒ‡å®šã•れãŸå ´åˆã€æŒ‡å®šã•れãŸã‚‚ã®ã¨ã€ãã®ç¥–å…ˆã¨ãªã‚‹\n"
+" リビジョンãŒé€£æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã¸ã¨å映ã•れã¾ã™ã€‚\n"
+"\n"
+" ssh:// URL å½¢å¼ã®è©³ç´°ã«é–¢ã—ã¦ã¯ã€'hg help urls' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" 連æºå…ˆãŒçœç•¥ã•れãŸå ´åˆã€'default' パスãŒé€£æºå…ˆã¨ã—ã¦ä½¿ç”¨ã•れã¾ã™ã€‚\n"
+" "
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr "%s ã¸ã®å映中\n"
+
+msgid ""
+"roll back an interrupted transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an\n"
+" interrupted operation. It should only be necessary when Mercurial\n"
+" suggests it.\n"
+" "
+msgstr ""
+"中断ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®å–り消ã—\n"
+"\n"
+" commit ã‚„ pull ãŒä¸­æ–­ã•れãŸå ´åˆã®å¾©æ—§ã‚’行ã„ã¾ã™ã€‚\n"
+"\n"
+" 本コマンドã¯ã€æ“作ãŒä¸­æ–­ã•れãŸéš›ã®ãƒªãƒã‚¸ãƒˆãƒªçŠ¶æ…‹ã®ä¿®å¾©ã‚’行ã„ã¾ã™ã€‚\n"
+" 本コマンドã®å®Ÿè¡Œã¯ã€Mercurial ãŒå®Ÿè¡Œã‚’促ã—ãŸå ´åˆã®ã¿ã§å分ã§ã™ã€‚\n"
+" "
+
+msgid ""
+"remove the specified files on the next commit\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history. -A/--after can be used to remove only\n"
+" files that have already been deleted, -f/--force can be used to\n"
+" force deletion, and -Af can be used to remove files from the next\n"
+" revision without deleting them from the working directory.\n"
+"\n"
+" The following table details the behavior of remove for different\n"
+" file states (columns) and option combinations (rows). The file\n"
+" states are Added [A], Clean [C], Modified [M] and Missing [!]\n"
+" (as reported by hg status). The actions are Warn, Remove (from\n"
+" branch) and Delete (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+msgstr ""
+"次回コミットã«ãŠã‘る指定ファイルã®ç™»éŒ²é™¤å¤–\n"
+"\n"
+" æ§‹æˆç®¡ç†å¯¾è±¡ã‹ã‚‰ã®æŒ‡å®šãƒ•ァイルã®ç™»éŒ²é™¤å¤–を予約ã—ã¾ã™ã€‚\n"
+"\n"
+" 登録除外ã¯ç¾è¡Œãƒ–ランãƒã®ã¿ãŒå¯¾è±¡ã¨ãªã‚‹ãŸã‚ã€ä»–ã®ãƒ–ランãƒã«ãŠã„ã¦ã¯\n"
+" ファイルã¯å­˜ç¶šã—ç¶šã‘ã¾ã™ã€‚手動ã§å‰Šé™¤ã—ãŸãƒ•ァイルを登録除外ã™ã‚‹ã«ã¯\n"
+" -A/--after ã‚’ã€å¼·åˆ¶çš„ã«ç™»éŒ²é™¤å¤–ã™ã‚‹ã«ã¯ -f/--force ã‚’ã€ä½œæ¥­é ˜åŸŸä¸­ã®\n"
+" ファイルを削除ã™ã‚‹ã“ã¨ãªã登録除外ã™ã‚‹ã«ã¯ -Af を指定ã—ã¾ã™ã€‚\n"
+"\n"
+" ファイルã®çŠ¶æ…‹(横)ã¨ã‚ªãƒ—ション指定(縦)ã®çµ„ã¿åˆã‚ã›ã«ãŠã‘る挙動ã¯ã€\n"
+" 以下ã®ä¸€è¦§ã‚’å‚ç…§ã—ã¦ãã ã•ã„。ファイルã®çŠ¶æ…‹ã¯ã€'hg status' ãŒè¡¨ç¤º\n"
+" ã™ã‚‹ A(Add:追加登録)ã€C(Clean:改変無ã—)ã€M(Modified:改変有り)ãŠã‚ˆã³\n"
+" !(䏿˜Ž)ã§è¡¨ã—ã¾ã™ã€‚挙動㯠W(Warn:警告)ã€R(Remove:æ§‹æˆç®¡ç†ã‹ã‚‰ã®ç™»éŒ²\n"
+" 除外)ãŠã‚ˆã³ D(Delete:作業領域ã‹ã‚‰ã®å‰Šé™¤)ã§è¡¨ã—ã¾ã™ã€‚\n"
+"\n"
+" A C M !\n"
+" 無指定 W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" 指定ファイルã¯ã€æ¬¡å›žã®ã‚³ãƒŸãƒƒãƒˆã®éš›ã«ç™»éŒ²é™¤å¤–ã•れã¾ã™ã€‚コミットå‰ã«\n"
+" 登録除外をå–ã‚Šæ¶ˆã™æ–¹æ³•㯠'hg help revert' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+#, python-format
+msgid "not removing %s: file is untracked\n"
+msgstr "%s ã¯å‰Šé™¤ã•れã¾ã›ã‚“: æ§‹æˆç®¡ç†å¯¾è±¡ã§ã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "not removing %s: file %s (use -f to force removal)\n"
+msgstr ""
+"ファイル %s ã¯å‰Šé™¤ã•れã¾ã›ã‚“。\n"
+"%s (強行ã™ã‚‹å ´åˆã¯ -f を指定ã—ã¦ãã ã•ã„)XXXX\n"
+
+msgid "still exists"
+msgstr "ã¾ã ãƒ•ァイルãŒå­˜åœ¨ã—ã¦ã„ã¾ã™"
+
+msgid "is modified"
+msgstr "ファイルãŒå¤‰æ›´ã•れã¦ã„ã¾ã™"
+
+msgid "has been marked for add"
+msgstr "追加登録対象ã§ã™"
+
+msgid ""
+"rename files; equivalent of copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If dest\n"
+" is a directory, copies are put in that directory. If dest is a\n"
+" file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+"ãƒ•ã‚¡ã‚¤ãƒ«ã®æ”¹å(copy + remove ã¨ç­‰ä¾¡)\n"
+"\n"
+" 改åå…ƒã®è¤‡è£½ã¨ã—ã¦æ”¹å先を追加登録ã—ã€æ”¹å元を登録除外ã—ã¾ã™ã€‚\n"
+" 改åå…ˆãŒãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®å ´åˆã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªå†…ã«è¤‡è£½ãŒä½œæˆã•れã¾ã™ã€‚\n"
+" 改åå…ˆãŒãƒ•ァイルã®å ´åˆã€æ”¹åå…ƒã¯1ã¤ã—ã‹æŒ‡å®šã§ãã¾ã›ã‚“。\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€æ”¹å元ファイルã®å†…容をæŒã¤æ”¹å先ファイルを\n"
+" 作業領域ã«ä½œæˆã—ã¾ã™ã€‚-A/--after 指定ãŒã‚ã‚‹å ´åˆã€ã€Œæ”¹åã€æ“作ã¯\n"
+" 記録ã•れã¾ã™ãŒã€ãƒ•ァイルã®è¤‡è£½ã¯è¡Œã‚れã¾ã›ã‚“。\n"
+"\n"
+" 本コマンドã®å®Ÿè¡Œçµæžœã¯æ¬¡å›žã®ã‚³ãƒŸãƒƒãƒˆã®éš›ã«åŠ¹æžœã‚’ç™ºæ®ã—ã¾ã™ã€‚コミット\n"
+" å‰ã«æ”¹åæ“作をå–ã‚Šæ¶ˆã™æ–¹æ³•㯠'hg help revert' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid ""
+"retry file merges from a merge or update\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a/--all switch.\n"
+"\n"
+" If a conflict is resolved manually, please note that the changes\n"
+" will be overwritten if the merge is retried with resolve. The\n"
+" -m/--mark switch should be used to mark the file as resolved.\n"
+"\n"
+" This command also allows listing resolved files and manually\n"
+" indicating whether or not files are resolved. All files must be\n"
+" marked as resolved before a commit is permitted.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+msgstr ""
+"merge ã‚„ update ã«ãŠã‘るファイルマージã®å†å®Ÿæ–½\n"
+"\n"
+" è¡çªãŒã€Œæœªè§£æ¶ˆã€ã®ãƒ•ァイルã«å¯¾ã—ã€ç›´å‰ã® 'hg merge' ã‚„ 'hg update'\n"
+" 時点ã«ãŠã‘るファイルã®å†…容を用ã„ã¦ã€ç¶ºéº—ãªçŠ¶æ…‹ã‹ã‚‰ã®ãƒžãƒ¼ã‚¸å‡¦ç†ã‚’実施\n"
+" ã—ã¾ã™ã€‚è¡çªãŒã€Œæœªè§£æ¶ˆã€ãªå…¨ã¦ã®ãƒ•ァイルを実施対象ã«ã™ã‚‹å ´åˆã¯ã€\n"
+" -a/--all を指定ã—ã¾ã™ã€‚\n"
+"\n"
+" è¡çªã‚’手動ã§è§£æ¶ˆã—ãŸå ´åˆã€æœ¬ã‚³ãƒžãƒ³ãƒ‰ã§ãƒžãƒ¼ã‚¸å‡¦ç†ãŒå†å®Ÿè¡Œã•れるã¨ã€\n"
+" 手動ã§å¤‰æ›´ã—ãŸè§£æ¶ˆå†…容ãŒä¸Šæ›¸ãã•れã¦ã—ã¾ã„ã¾ã™ã€‚手動ã§è¡çªã‚’解消ã—ãŸ\n"
+" å ´åˆã€-m/--mark を指定ã—ã¦æœ¬ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã™ã‚‹ã“ã¨ã§ã€ãƒ•ァイルã®è¡çª\n"
+" 解消状態を「解消済ã¿ã€ã«ã—ã¦ãã ã•ã„。\n"
+"\n"
+" 本コマンドã¯ã€ãƒ•ァイルã®è¡çªè§£æ¶ˆçŠ¶æ…‹ã®ä¸€è¦§è¡¨ç¤ºã‚„ã€ã€Œè§£æ¶ˆæ¸ˆã¿ã€ï¼\n"
+" 「未解消ã€ã¨ã„ã£ãŸè¡çªè§£æ¶ˆçŠ¶æ…‹ã®æ‰‹å‹•変更もã§ãã¾ã™ã€‚å…¨ã¦ã®ãƒ•ァイルã®\n"
+" è¡çªè§£æ¶ˆçŠ¶æ…‹ãŒã€Œè§£æ¶ˆæ¸ˆã¿ã€ã«ãªã‚‹ã¾ã§ã¯ã€ã‚³ãƒŸãƒƒãƒˆãŒã§ãã¾ã›ã‚“。\n"
+"\n"
+" ファイルã®è¡çªè§£æ¶ˆçŠ¶æ…‹è¡¨ç¤ºã«ã¯ä»¥ä¸‹ã®è¨˜å·ãŒä½¿ç”¨ã•れã¾ã™:\n"
+" U = 未解消(Unresolved)\n"
+" R = 解消済ã¿(Resolved)\n"
+" "
+
+msgid "too many options specified"
+msgstr "オプション指定ãŒéŽå‰°ã§ã™"
+
+msgid "can't specify --all and patterns"
+msgstr "--all ã¨ãƒ‘ターンã¯åŒæ™‚ã«æŒ‡å®šå‡ºæ¥ã¾ã›ã‚“"
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr "å†ãƒžãƒ¼ã‚¸ã«ã¯ã€ãƒ•ァイルï¼ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‹ã€--all を指定ã—ã¦ãã ã•ã„"
+
+msgid ""
+"restore individual files or directories to an earlier state\n"
+"\n"
+" (Use update -r to check out earlier revisions, revert does not\n"
+" change the working directory parents.)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r/--rev option, revert the given files or directories\n"
+" to their contents as of a specific revision. This can be helpful\n"
+" to \"roll back\" some or all of an earlier change. See 'hg help\n"
+" dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable mode\n"
+" of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+msgstr ""
+"ファイルï¼ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªçŠ¶æ…‹ã®å¾©æ—§\n"
+"\n"
+" ('hg revert' ã¯ä½œæ¥­é ˜åŸŸã®è¦ªãƒªãƒ“ジョンを変更ã—ãªã„ã®ã§ã€ä½œæ¥­é ˜åŸŸã®\n"
+" 状態を以å‰ã®ç‰ˆã«æˆ»ã™å ´åˆã¯ã€'hg update' を使用ã—ã¦ãã ã•ã„)\n"
+"\n"
+" リビジョン指定ãŒç„¡ã„å ´åˆã€æŒ‡å®šã•れãŸãƒ•ァイルï¼ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’作業\n"
+" 領域ã®è¦ªãƒªãƒ“ジョン時点ã®å†…容ã¸ã¨å¾©æ—§ã—ã¾ã™ã€‚本コマンドã¯å¯¾è±¡\n"
+" ファイルã«å¯¾ã—ã¦ã€çŠ¶æ…‹ã‚’ã€Œæ”¹å¤‰ç„¡ã—ã€ã¨ã—ã€add/remove/copy/rename\n"
+" 実行ã®åŠ¹æžœã‚’æ‰“ã¡æ¶ˆã—ã¾ã™ã€‚作業領域ã®è¦ªãƒªãƒ“ジョンãŒ2ã¤ã‚ã‚‹å ´åˆã¯ã€\n"
+" ã©ã¡ã‚‰ã®å†…容ã§å¾©æ—§ã™ã‚‹ã®ã‹ã‚’æ˜Žç¤ºçš„ã«æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n"
+"\n"
+" -r/--rev ãŒæŒ‡å®šã•れãŸå ´åˆã€æŒ‡å®šã•れãŸãƒ•ァイルï¼ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’ã€\n"
+" 指定ã•れãŸãƒªãƒ“ジョン時点ã®å†…容ã¸ã¨å¾©æ—§ã—ã¾ã™ã€‚以å‰ã®å¤‰æ›´å†…容ã®ä¸€éƒ¨\n"
+" ãªã„ã—全部をå–り消ã™ç”¨é€”ã«ã‚‚使用ã§ãã¾ã™ã€‚-d/--date ã®æŒ‡å®šã«é–¢ã—ã¦ã¯\n"
+" 'hg help dates' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" 本コマンドã¯ä½œæ¥­é ˜åŸŸã®å†…容ã¯å¤‰æ›´ã—ã¾ã™ãŒã€å¤‰æ›´ã®ã‚³ãƒŸãƒƒãƒˆã‚„ã€ä½œæ¥­\n"
+" 領域ã®è¦ªãƒªãƒ“ジョンã¯å¤‰æ›´ã—ã¾ã›ã‚“。ãã®ãŸã‚ã€ä½œæ¥­é ˜åŸŸã®è¦ªãƒªãƒ“ジョン\n"
+" 以外ã®ãƒªãƒ“ジョンを指定ã—ã¦å¾©æ—§ã—ãŸå ´åˆã€å¾©æ—§å¾Œã®ãƒ•ァイルã®çŠ¶æ…‹ã¯\n"
+" 「改変有りã€ã¨ã—ã¦æ‰±ã‚れã¾ã™ã€‚\n"
+"\n"
+" ファイルãŒå‰Šé™¤ã•れã¦ã„ãŸå ´åˆã€ãƒ•ァイルã¯å¾©æ—§ã•れã¾ã™ã€‚実行権é™ãŒå¤‰æ›´\n"
+" ã•れã¦ã„ãŸå ´åˆã€å¤‰æ›´å‰ã®çŠ¶æ…‹ã«å¾©æ—§ã•れã¾ã™ã€‚\n"
+"\n"
+" å¾©æ—§å¯¾è±¡ãŒæŒ‡å®šã•れãŸå ´åˆã€æŒ‡å®šã•れãŸåå‰ã«åˆè‡´ã™ã‚‹å…¨ã¦ã®ãƒ•ァイルãŒ\n"
+" 復旧対象ã¨ãªã‚Šã¾ã™ã€‚å¾©æ—§å¯¾è±¡ãŒæŒ‡å®šã•れãªã‹ã£ãŸå ´åˆã¯ã€ã„ãšã‚Œã®\n"
+" ファイルも復旧ã•れã¾ã›ã‚“。\n"
+"\n"
+" 改変ã•れãŸãƒ•ァイルã®å¾©æ—§ã§ã¯ã€å¾©æ—§å‰ã®å†…容㌠.orig æ‹¡å¼µå­ã‚’付ã‘ãŸ\n"
+" ファイルã«ä¿å­˜ã•れã¾ã™ã€‚ã“ã®ä¿å­˜ã¯ --no-backup ã§ç„¡åŠ¹åŒ–ã•れã¾ã™ã€‚\n"
+" "
+
+msgid "you can't specify a revision and a date"
+msgstr "ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã¨æ—¥æ™‚ã¯åŒæ™‚ã«ã¯æŒ‡å®šå‡ºæ¥ã¾ã›ã‚“"
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr "復旧ã«ã¯ã€ãƒ•ァイルï¼ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‹ã€--all を指定ã—ã¦ãã ã•ã„"
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr "%s ã®è¿½åŠ ç™»éŒ²ã‚’å–り消ã—中\n"
+
+#, python-format
+msgid "reverting %s\n"
+msgstr "%s ã®å¾©æ—§ä¸­\n"
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr "%s ã®å¾©æ—§ä¸­\n"
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr "ç¾è¡Œç‰ˆã® %s ã‚’ %s ã«ä¿å­˜ä¸­\n"
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr "ファイル %s ã¯ç®¡ç†å¯¾è±¡ã§ã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr "%s ã«ã¯æ”¹å¤‰ã®å¿…è¦ãŒã‚りã¾ã›ã‚“\n"
+
+msgid ""
+"roll back the last transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time. This command does not alter\n"
+" the working directory.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+msgstr ""
+"ç›´å‰ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®å·»ã戻ã—\n"
+"\n"
+" 本コマンドã®ä½¿ç”¨ã«ã¯æ³¨æ„ãŒå¿…è¦ã§ã™ã€‚å·»ãæˆ»ã—ã¯ï¼‘段階é™ã‚Šã§ã€å·»ã\n"
+" 戻ã—ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®å†å®Ÿæ–½ã¯ã§ãã¾ã›ã‚“。本コマンドã¯ã€ç›´å‰ã®\n"
+" トランザクション実施時点㮠dirstate を復元ã—ã€ãã®æ™‚点以後ã®å¤‰æ›´ã¯\n"
+" å…¨ã¦å¤±ã‚れã¾ã™ã€‚\n"
+"\n"
+" トランザクションã¨ã¯ã€æ–°è¦ãƒªãƒ“ジョンã®ä½œæˆã€ãªã„ã—外部ã‹ã‚‰ã®æ—¢å­˜\n"
+" リビジョンã®å–り込ã¿ã«è¦ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã®åŠ¹æžœã‚’ä¸€æ‹¬åŒ–ã™ã‚‹ã‚‚ã®ã§ã™ã€‚\n"
+" 例ãˆã°ã€ä»¥ä¸‹ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ã„ãšã‚Œã‚‚トランザクションを形æˆã™ã‚‹ã‚‚ã®ã§ã€\n"
+" ãã®åŠ¹æžœã¯æœ¬ã‚³ãƒžãƒ³ãƒ‰ã«ã‚ˆã‚Šå·»ã戻ã—å¯èƒ½ã§ã™ã€‚\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (rollback å¯èƒ½ãªã®ã¯å映先リãƒã‚¸ãƒˆãƒªå´)\n"
+" unbundle\n"
+"\n"
+" 本コマンドã¯ã€å…¬é–‹ãƒªãƒã‚¸ãƒˆãƒªã§ã®å®Ÿè¡Œã‚’想定ã—ã¦ã„ã¾ã›ã‚“。他ã®ãƒ¦ãƒ¼ã‚¶\n"
+" ã‹ã‚‰ 'hg pull' å¯èƒ½ãªçŠ¶æ…‹ã«ãªã£ã¦ã—ã¾ã£ãŸãªã‚‰ã€å…¬é–‹ãƒªãƒã‚¸ãƒˆãƒªã§ã®\n"
+" rollback ã¯(æ—¢ã«ä»–ã®ãƒ¦ãƒ¼ã‚¶ã«ã‚ˆã£ã¦è¤‡è£½ã•れã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ã®ã§)\n"
+" 効果をæŒã¡ã¾ã›ã‚“。ãã®ä¸Šã€ãƒªãƒã‚¸ãƒˆãƒªã‹ã‚‰ã®æƒ…報読ã¿å–りã«éš›ã—ã¦ã€\n"
+" ç«¶åˆãŒç™ºç”Ÿã—å¾—ã¾ã™ã€‚例ãˆã°ã€é€²è¡Œä¸­ã®ãƒªãƒã‚¸ãƒˆãƒªã‹ã‚‰ã®å–り込ã¿ãŒã€\n"
+" å·»ãæˆ»ã—ã«ã‚ˆã£ã¦å¤±æ•—ã—ã¦ã—ã¾ã†å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"print the root (top) of the current working directory\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+msgstr ""
+"作業領域ã®ãƒ«ãƒ¼ãƒˆ(最上ä½)ディレクトリä½ç½®ã®è¡¨ç¤º\n"
+"\n"
+" 作業領域ã®ãƒ«ãƒ¼ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä½ç½®ã‚’表示ã—ã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"export the repository via HTTP\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+" files.\n"
+" "
+msgstr ""
+"HTTP 経由ã§ã®ãƒªãƒã‚¸ãƒˆãƒªã®å…¬é–‹\n"
+"\n"
+" リãƒã‚¸ãƒˆãƒªå‚照㨠'hg pull' ã®ãŸã‚ã® HTTP サーãƒã‚’èµ·å‹•ã—ã¾ã™ã€‚\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šãŒç„¡ã„å ´åˆã€ã‚µãƒ¼ãƒã¯ã‚¢ã‚¯ã‚»ã‚¹ãƒ­ã‚°ã‚’標準出力ã«ã€ã‚¨ãƒ©ãƒ¼ã‚’\n"
+" 標準エラー出力ã«è¡¨ç¤ºã—ã¾ã™ã€‚ログをファイルã«è¨˜éŒ²ã™ã‚‹å ´åˆã¯ã€\n"
+" -A/--accesslog ã‚„ -E/--errorlog ã§æŒ‡å®šã—ã¾ã™ã€‚\n"
+" "
+
+#, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr "http://%s%s/%s ã§å¾…ã¡å—ã‘é–‹å§‹(ãƒã‚¤ãƒ³ãƒ‰å…ˆã¯ %s:%d)\n"
+
+msgid ""
+"show changed files in the working directory\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" the source of a copy/move operation, are not listed unless\n"
+" -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.\n"
+" Unless options described with \"show only ...\" are given, the\n"
+" options -mardu are used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/--ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the differences between them are\n"
+" shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = missing (deleted by non-hg command, but still tracked)\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = origin of the previous file listed as A (added)\n"
+" "
+msgstr ""
+"作業領域ã®ãƒ•ァイルæ“作状æ³ã®è¡¨ç¤º\n"
+"\n"
+" 作業領域ã®ãƒ•ァイル状態を表示ã—ã¾ã™ã€‚åå‰(パターン)指定ã®ã‚ã‚‹å ´åˆã€\n"
+" ãã®åå‰ã«åˆè‡´ã™ã‚‹ãƒ•ァイルã®ã¿ãŒè¡¨ç¤ºã•れã¾ã™ã€‚変更無ã—(clean)ã€\n"
+" 無視(ignored)ãªã„ã—複製(copy)・改å(rename)ã®å…ƒãƒ•ァイルã«é–¢ã—ã¦ã¯ã€\n"
+" ãれãžã‚Œ -c/--cleanã€-i/--ignored ãªã„ã— -C/--copy ãŒæŒ‡å®šã•れるã‹ã€\n"
+" -A/--all ãŒæŒ‡å®šã•れãªã„é™ã‚Šè¡¨ç¤ºã•れã¾ã›ã‚“ã€‚è¡¨ç¤ºå¯¾è±¡é¸æŠžã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒ\n"
+" 何も指定ã•れãªã„å ´åˆã€-m -a -r -d -u ãŒæŒ‡å®šã•れãŸã‚‚ã®ã¨ã¿ãªã—ã¾ã™ã€‚\n"
+"\n"
+" -q/--quiet 指定ãŒã‚ã‚‹å ´åˆã€-u/--unknown ãªã„ã— -i/-ignored ãŒæ˜Žç¤º\n"
+" çš„ã«æŒ‡å®šã•れãªã„é™ã‚Šã€æ§‹æˆç®¡ç†å¯¾è±¡å¤–ã®ãƒ•ァイルã¯è¡¨ç¤ºã•れã¾ã›ã‚“。\n"
+"\n"
+" 備考:権é™è¨­å®šã®å¤‰æ›´ã‚„マージãŒè¡Œã‚れãŸå ´åˆã€å·®åˆ†è¡¨ç¤ºã‹ã‚‰æœŸå¾…ã•れる\n"
+" çµæžœã¨ã¯ç•°ãªã‚‹çŠ¶æ…‹ãŒè¡¨ç¤ºã•れるå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚標準的ãªå·®åˆ†å½¢å¼ã¯\n"
+" 権é™å¤‰æ›´ã®æƒ…報をå«ã¿ã¾ã›ã‚“ã—ã€ãƒžãƒ¼ã‚¸ã®éš›ã«ã¯ä¸€æ–¹ã®è¦ªãƒªãƒ“ジョンã¨ã®\n"
+" 差分ã—ã‹è¡¨ç¤ºã—ã¾ã›ã‚“。\n"
+"\n"
+" 1ã¤ã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れãŸå ´åˆã€æ¯”較元リビジョンã¨ã—ã¦æ‰±ã‚れã¾ã™ã€‚\n"
+" 2ã¤ã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れãŸå ´åˆã€ä¸¡ãƒªãƒ“ジョン間ã§çŠ¶æ…‹æ¯”è¼ƒã•れã¾ã™ã€‚\n"
+"\n"
+" ファイルã®çŠ¶æ…‹ã‚’è¡¨ã™è¨˜å·ã¯ä»¥ä¸‹ã®é€šã‚Š:\n"
+" M = 改変有り(Modified)\n"
+" A = 追加登録予定(Added)\n"
+" R = 登録除外予定(Removed)\n"
+" C = 変更無ã—(Clean)\n"
+" ! = æ§‹æˆç®¡ç†å¯¾è±¡ã«ã‚‚é–¢ã‚らãšä½œæ¥­é ˜åŸŸã«ãƒ•ァイルãŒç„¡ã„(missing)\n"
+" ? = æ§‹æˆç®¡ç†å¯¾è±¡å¤–(unknown)\n"
+" I = 無視(Ignored)\n"
+" = ç›´å‰ã«è¡¨ç¤ºã•れる新è¦ç™»éŒ²äºˆå®šãƒ•ァイルã®è¤‡è£½å…ƒ\n"
+" "
+
+msgid ""
+"add one or more tags for the current or given revision\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is\n"
+" used, or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"ç¾ãƒªãƒ“ジョンãªã„ã—æŒ‡å®šãƒªãƒ“ジョンã¸ã®ã‚¿ã‚°ã®ä»˜ä¸Ž\n"
+"\n"
+" 特定ã®ãƒªãƒ“ジョンã«ã€æŒ‡å®šã•れãŸåå‰ã‚’付ã‘ã¾ã™ã€‚\n"
+"\n"
+" リãƒã‚¸ãƒˆãƒªä¸­ã®ç‰¹å®šã®ãƒªãƒ“ジョンã«ä»˜ã‘られãŸåå‰ã§ã‚ã‚‹ã‚¿ã‚°ã¯ã€ãƒªãƒ“ジョン\n"
+" é–“ã§ã®æ¯”較やã€é‡è¦ãªãƒªãƒ“ジョンã®å‚ç…§ã€åˆã¯ãƒªãƒªãƒ¼ã‚¹ã®éš›ã®åˆ†å²ç‚¹ã«å¯¾ã™ã‚‹\n"
+" ç›®å°ã¨ã„ã£ãŸç”¨é€”ãªã©ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n"
+"\n"
+" ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れãªã„å ´åˆã€ä½œæ¥­é ˜åŸŸã®è¦ªãƒªãƒ“ジョンã‹ã€ä½œæ¥­é ˜åŸŸæ›´æ–°å‰\n"
+" ãªã‚‰ tip ãŒã‚¿ã‚°ä»˜ã‘ã®å¯¾è±¡ã¨ãªã‚Šã¾ã™ã€‚\n"
+"\n"
+" 分散構æˆç®¡ç†ã«ãŠã‘るタグ付ã‘ã®é›†ç´„を容易ã«ã™ã‚‹ãŸã‚ã«ã€æ§‹æˆç®¡ç†ä¸‹ã«ã‚ã‚‹\n"
+" ä»–ã®ãƒ•ァイルã¨åŒæ§˜ã«ã€ã‚¿ã‚°ã®æƒ…報㯠\".hgtags\" ファイルã§ç®¡ç†ã•れã€\n"
+" å¿…è¦ã§ã‚ã‚Œã°æ‰‹å‹•ã§ã®ç·¨é›†ã‚‚å¯èƒ½ã§ã™ã€‚ローカルタグ㯠'.hg/localtags' ã§\n"
+" 管ç†ã•れã¾ã™(リãƒã‚¸ãƒˆãƒªé–“ã§å…±æœ‰ã•れるã“ã¨ã¯ã‚りã¾ã›ã‚“)\n"
+"\n"
+" -d/--date ã¸ã®æŒ‡å®šã«é–¢ã—ã¦ã¯ã€'hg help dates' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid "tag names must be unique"
+msgstr "ã‚¿ã‚°åãŒé‡è¤‡ã—ã¦ã„ã¾ã™"
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr "ã‚¿ã‚°å '%s' ã¯ã‚·ã‚¹ãƒ†ãƒ ã§äºˆç´„ã•れã¦ã„ã¾ã™"
+
+msgid "--rev and --remove are incompatible"
+msgstr "--rev 㨠--remove ã¯åŒæ™‚ã«ä½¿ç”¨ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr "ã‚¿ã‚° '%s' ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+
+#, python-format
+msgid "tag '%s' is not a global tag"
+msgstr "ã‚¿ã‚° '%s' ã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«ãªã‚¿ã‚°ã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "tag '%s' is not a local tag"
+msgstr "ã‚¿ã‚° '%s' ã¯ãƒ­ãƒ¼ã‚«ãƒ«ãªã‚¿ã‚°ã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "Removed tag %s"
+msgstr "ã‚¿ã‚° %s ã®å‰Šé™¤"
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr "ã‚¿ã‚° '%s' ã¯å­˜åœ¨ã—ã¾ã™(強行ã™ã‚‹å ´åˆã¯ -f を指定ã—ã¦ãã ã•ã„)"
+
+#, python-format
+msgid "Added tag %s for changeset %s"
+msgstr "リビジョン %s ã¸ã‚¿ã‚° %s を付与"
+
+msgid ""
+"list repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose\n"
+" switch is used, a third column \"local\" is printed for local tags.\n"
+" "
+msgstr ""
+"リãƒã‚¸ãƒˆãƒªä¸­ã®ã‚¿ã‚°ä¸€è¦§ã®è¡¨ç¤º\n"
+"\n"
+" 本コマンドã¯ã€é€šå¸¸ã®ã‚¿ã‚°ãŠã‚ˆã³ãƒ­ãƒ¼ã‚«ãƒ«ã‚¿ã‚°ã®ä¸¡æ–¹ã‚’一覧表示ã—ã¾ã™ã€‚\n"
+" -v/--verbose ãŒæŒ‡å®šã•れãŸå ´åˆã€ãƒ­ãƒ¼ã‚«ãƒ«ã‚¿ã‚°ã®è­˜åˆ¥æƒ…報用㫠\"local\"\n"
+" カラムãŒè¿½åŠ è¡¨ç¤ºã•れã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"show the tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the changeset\n"
+" most recently added to the repository (and therefore the most\n"
+" recently changed head).\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+msgstr ""
+"tip リビジョンã®è¡¨ç¤º\n"
+"\n"
+" tip リビジョン(一般ã«ã¯å˜ã« tip ã¨è¡¨è¨˜)ã¨ã¯ã€ãƒªãƒã‚¸ãƒˆãƒªãŠã„ã¦æœ€ã‚‚\n"
+" æ–°ã—ã追加ã•れãŸãƒªãƒ“ジョンã§ã‚ã‚‹ã¨åŒæ™‚ã«ã€æœ€ã‚‚æ–°ã—ã変更ã•れãŸãƒ˜ãƒƒãƒ‰\n"
+" ã®ã“ã¨ã§ã‚‚ã‚りã¾ã™ã€‚\n"
+"\n"
+" コミットã—ãŸç›´å¾Œã§ã‚れã°ã€ç”Ÿæˆã•れãŸãƒªãƒ“ジョン㌠tip ã¨ãªã‚Šã¾ã™ã€‚\n"
+" ä»–ã®ãƒªãƒã‚¸ãƒˆãƒªã‹ã‚‰å¤‰æ›´å±¥æ­´ã®å–り込ã¿ã‚’ã—ãŸç›´å¾Œã§ã‚れã°ã€é€£æºå…ˆ\n"
+" リãƒã‚¸ãƒˆãƒªã§ã® tip ãŒç¾ãƒªãƒã‚¸ãƒˆãƒªã® tip ã¨ãªã‚Šã¾ã™ã€‚\"tip\" ã‚¿ã‚°ã¯\n"
+" 特別ãªã‚¿ã‚°ã§ã€æ”¹åã‚„ã€ä»–ã®ãƒªãƒ“ジョンã¸ã®ä»˜ã‘替ãˆã¯ã§ãã¾ã›ã‚“。\n"
+" "
+
+msgid ""
+"apply one or more changegroup files\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+msgstr ""
+"ãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイルã®é©ç”¨\n"
+"\n"
+" hg bundle コマンドã§ç”Ÿæˆã•れãŸãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイルをé©ç”¨ã—ã¾ã™ã€‚\n"
+" "
+
+msgid ""
+"update working directory\n"
+"\n"
+" Update the repository's working directory to the specified\n"
+" revision, or the tip of the current branch if none is specified.\n"
+" Use null as the revision to remove the working copy (like 'hg\n"
+" clone -U').\n"
+"\n"
+" When the working directory contains no uncommitted changes, it\n"
+" will be replaced by the state of the requested revision from the\n"
+" repository. When the requested revision is on a different branch,\n"
+" the working directory will additionally be switched to that\n"
+" branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C/--clean to\n"
+" discard them, forcibly replacing the state of the working\n"
+" directory with the requested revision. Alternately, use -c/--check\n"
+" to abort.\n"
+"\n"
+" When there are uncommitted changes and option -C/--clean is not\n"
+" used, and the parent revision and requested revision are on the\n"
+" same branch, and one of them is an ancestor of the other, then the\n"
+" new working directory will contain the requested revision merged\n"
+" with the uncommitted changes. Otherwise, the update will fail with\n"
+" a suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use\n"
+" revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"ä½œæ¥­é ˜åŸŸã®æ›´æ–°\n"
+"\n"
+" 指定ã•れãŸãƒªãƒ“ジョン(指定ãŒç„¡ã„å ´åˆã¯ç¾ãƒ–ランãƒã®æœ€æ–°ãƒªãƒ“ジョン)\n"
+" 時点ã®å†…容ã§ã€ä½œæ¥­é ˜åŸŸã‚’æ›´æ–°ã—ã¾ã™ã€‚作業領域中ã®ãƒ•ァイルを削除ã™ã‚‹\n"
+" å ´åˆã¯ã€ãƒªãƒ“ジョン㫠null を指定ã—ã¾ã™('hg clone -U' ã¨åŒç­‰)。\n"
+"\n"
+" ä½œæ¥­é ˜åŸŸä¸­ã«æœªã‚³ãƒŸãƒƒãƒˆã®å¤‰æ›´ãŒç„¡ã„å ´åˆã¯ã€ãƒªãƒã‚¸ãƒˆãƒªã«è¨˜éŒ²ã•れã¦\n"
+" ã„る指定リビジョン時点ã®å†…容ã§ã€ä½œæ¥­é ˜åŸŸãŒæ›´æ–°ã•れã¾ã™ã€‚指定リビジョン\n"
+" ãŒä½œæ¥­é ˜åŸŸã®è¦ªãƒªãƒ“ジョンã¨ç•°ãªã‚‹ãƒ–ランãƒã®ã‚‚ã®ã§ã‚ã‚‹å ´åˆã€ä½œæ¥­é ˜åŸŸã¯\n"
+" 別ブランãƒã¸ã¨ç§»è¡Œã—ã¾ã™ã€‚\n"
+"\n"
+" 未コミットã®å¤‰æ›´ãŒæœ‰ã‚‹å ´åˆã€-C/--clean を指定ã™ã‚‹ã“ã¨ã§ã€å¤‰æ›´å†…容を\n"
+" 破棄ã—ã€æŒ‡å®šãƒªãƒ“ジョン時点ã®å†…容ã§ä½œæ¥­é ˜åŸŸã‚’å¼·åˆ¶çš„ã«æ›´æ–°ã™ã‚‹ã“ã¨ãŒ\n"
+" ã§ãã¾ã™ã€‚\n"
+"\n"
+" 未コミットã®å¤‰æ›´ãŒæœ‰ã‚Šã€ä¸”㤠-C/--clean ãŒæŒ‡å®šã•れãªã‹ã£ãŸå ´åˆã¯ã€\n"
+" 作業領域ã®è¦ªãƒªãƒ“ã‚¸ãƒ§ãƒ³ã¨æŒ‡å®šãƒªãƒ“ジョンãŒåŒä¸€ãƒ–ランãƒã«å±žã—ã€ä¸”ã¤\n"
+" 両方ã®å±¥æ­´ãŒç›´ç³»ã«ã‚ãŸã‚‹é–¢ä¿‚ã§ã‚る時ã«é™ã‚Šã€æœªã‚³ãƒŸãƒƒãƒˆã®å¤‰æ›´å†…容ã¨\n"
+" 指定リビジョンをマージã—ãŸçµæžœã§ä½œæ¥­é ˜åŸŸãŒæ›´æ–°ã•れã¾ã™ã€‚ãれ以外ã®\n"
+" å ´åˆã¯ 'hg merge' ãªã„ã— 'hg update -C' ã®ä½¿ç”¨ã‚’促ã—ãŸä¸Šã§ã‚³ãƒžãƒ³ãƒ‰\n"
+" 実行ã¯å¤±æ•—ã—ã¾ã™ã€‚\n"
+"\n"
+" 特定ã®ãƒ•ァイルを以å‰ã®çŠ¶æ…‹ã«æˆ»ã™å ´åˆã¯ 'hg revert' を使用ã—ã¾ã™ã€‚\n"
+"\n"
+" -d/--date ã¸ã®æŒ‡å®šã«é–¢ã—ã¦ã¯ã€'hg help dates' ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+" "
+
+msgid "uncommitted local changes"
+msgstr "ä½œæ¥­é ˜åŸŸã«æœªã‚³ãƒŸãƒƒãƒˆã®å¤‰æ›´ãŒã‚りã¾ã™"
+
+msgid ""
+"verify the integrity of the repository\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+msgstr ""
+"リãƒã‚¸ãƒˆãƒªã®æ•´åˆæ€§æ¤œè¨¼\n"
+"\n"
+" ç¾ãƒªãƒã‚¸ãƒˆãƒªã®æ•´åˆæ€§ã‚’検証ã—ã¾ã™ã€‚\n"
+"\n"
+" 本コマンドã¯ã€ãƒªãƒã‚¸ãƒˆãƒªã®æ•´åˆæ€§ã«é–¢ã™ã‚‹åºƒç¯„ãªæ¤œè¨¼ã‚’行ã„ã¾ã™ã€‚\n"
+" å¤‰æ›´è¨˜éŒ²ãƒ»ãƒžãƒ‹ãƒ•ã‚§ã‚¹ãƒˆãƒ»å„æ§‹æˆç®¡ç†å¯¾è±¡ãƒ•ァイルã«ãŠã‘ã‚‹ãƒãƒƒã‚·ãƒ¥å€¤ãŠã‚ˆã³\n"
+" ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã€ç›¸äº’関連付ã‘ãŠã‚ˆã³ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ç­‰ã®æ•´åˆæ€§ãŒæ¤œè¨¼ã•れã¾ã™ã€‚\n"
+" "
+
+msgid "output version and copyright information"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŠã‚ˆã³è‘—作権情報ã®è¡¨ç¤º"
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr "Mercurial - 分散構æˆç®¡ç†ãƒ„ール(ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s)\n"
+
+msgid ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"\n"
+"著作権 (C) 2005-2009 Matt Mackall <mpm@selenic.com> 他\n"
+"本製å“ã¯ãƒ•リーソフトウェアã§ã™ã€‚é ’å¸ƒï¼æ”¹å¤‰ã®éš›ã¯ãƒ©ã‚¤ã‚»ãƒ³ã‚¹æ¡é …ã‚’ãŠèª­ã¿\n"
+"ãã ã•ã„。市場é©åˆæ€§ã‚„特定用途ã¸ã®å¯å¦ã‚’å«ã‚ã€æœ¬è£½å“ã¯ç„¡ä¿è¨¼ã§ã™ã€‚\n"
+
+msgid "repository root directory or symbolic path name"
+msgstr "リãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆä½ç½®ã€ãªã„ã—パス定義å"
+
+msgid "change working directory"
+msgstr "作業領域ã®å¤‰æ›´"
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr "å•ã„åˆã‚ã›ã‚’ã›ãšã€ç¢ºèªäº‹é …ã¯å…¨ã¦ 'yes' ã¨ã¿ãªã™"
+
+msgid "suppress output"
+msgstr "出力を抑止"
+
+msgid "enable additional output"
+msgstr "付加的ãªå‡ºåŠ›ã‚’æœ‰åŠ¹åŒ–"
+
+msgid "set/override config option"
+msgstr "オプション設定を指定ï¼ä¸Šæ›¸ã"
+
+msgid "enable debugging output"
+msgstr "デãƒãƒƒã‚°å‡ºåŠ›ã‚’æœ‰åŠ¹åŒ–"
+
+msgid "start debugger"
+msgstr "デãƒãƒƒã‚¬ã‚’é–‹å§‹"
+
+msgid "set the charset encoding"
+msgstr "文字エンコーディング"
+
+msgid "set the charset encoding mode"
+msgstr "文字エンコーディングモード"
+
+msgid "print traceback on exception"
+msgstr "例外浮æšã®éš›ã«ãƒˆãƒ¬ãƒ¼ã‚¹ãƒãƒƒã‚¯ã‚’表示"
+
+msgid "time how long the command takes"
+msgstr "ã‚³ãƒžãƒ³ãƒ‰å®Ÿè¡Œã®æ‰€è¦æ™‚間を計測"
+
+msgid "print command execution profile"
+msgstr "コマンド実行ã®ãƒ—ロファイルを表示"
+
+msgid "output version information and exit"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦çµ‚了"
+
+msgid "display help and exit"
+msgstr "ヘルプ情報を表示ã—ã¦çµ‚了"
+
+msgid "do not perform actions, just print output"
+msgstr "実施予定ã®å‡¦ç†å†…容ã®è¡¨ç¤ºã®ã¿ã§å‡¦ç†å®Ÿæ–½ã¯æŠ‘æ­¢"
+
+msgid "specify ssh command to use"
+msgstr "SSH 連æºã§ä½¿ç”¨ã™ã‚‹ ssh コマンド"
+
+msgid "specify hg command to run on the remote side"
+msgstr "é éš”ホストå´ã§å®Ÿè¡Œã•れる hg コマンド"
+
+msgid "include names matching the given patterns"
+msgstr "パターンã«åˆè‡´ã—ãŸãƒ•ァイルを処ç†å¯¾è±¡ã«è¿½åŠ "
+
+msgid "exclude names matching the given patterns"
+msgstr "パターンã«åˆè‡´ã—ãŸãƒ•ァイルを処ç†å¯¾è±¡ã‹ã‚‰é™¤å¤–"
+
+msgid "use <text> as commit message"
+msgstr "コミットメッセージ"
+
+msgid "read commit message from <file>"
+msgstr "コミットメッセージをファイルã‹ã‚‰èª­ã¿è¾¼ã¿"
+
+msgid "record datecode as commit date"
+msgstr "記録ã•れる日時情報"
+
+msgid "record the specified user as committer"
+msgstr "記録ã•れる作æˆè€…情報"
+
+msgid "display using template map file"
+msgstr "当該スタイルã§è¡¨ç¤ºã‚’カスタマイズ"
+
+msgid "display with template"
+msgstr "当該テンプレートã§è¡¨ç¤ºã‚’カスタマイズ"
+
+msgid "do not show merges"
+msgstr "マージ実施リビジョンã®è¡¨ç¤ºæŠ‘æ­¢"
+
+msgid "treat all files as text"
+msgstr "全ファイルをテキストファイルã¨ä»®å®š"
+
+msgid "don't include dates in diff headers"
+msgstr "差分表示ã®éš›ã«æ—¥ä»˜æƒ…報を抑止"
+
+msgid "show which function each change is in"
+msgstr "差分表示ã®éš›ã«é–¢æ•°å情報を表示"
+
+msgid "ignore white space when comparing lines"
+msgstr "差分判定ã®éš›ã«ç©ºç™½æ–‡å­—を無視"
+
+msgid "ignore changes in the amount of white space"
+msgstr "差分判定ã®éš›ã«ç©ºç™½æ–‡å­—ã®æ•°ã‚’無視"
+
+msgid "ignore changes whose lines are all blank"
+msgstr "差分判定ã®éš›ã«ç©ºç™½è¡Œã‚’無視"
+
+msgid "number of lines of context to show"
+msgstr "差分コンテキストã®è¡Œæ•°"
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr "ãƒ•ã‚¡ã‚¤ãƒ«æ”¹åæŽ¨å®šã®éš›ã®é¡žä¼¼åº¦(0 以上 100 以下)"
+
+msgid "[OPTION]... [FILE]..."
+msgstr "[OPTION]... [FILE]..."
+
+msgid "annotate the specified revision"
+msgstr "当該リビジョン時点ã§ã®ç”±æ¥æƒ…報を表示"
+
+msgid "follow file copies and renames"
+msgstr "è¤‡è£½ï¼æ”¹å元ファイルã®å±¥æ­´ã‚‚追跡"
+
+msgid "list the author (long with -v)"
+msgstr "ユーザåを表示(-v 指定時ã¯è©³ç´°è¡¨ç¤º)"
+
+msgid "list the date (short with -q)"
+msgstr "日付を表示(-q 指定時ã¯ç°¡ç•¥è¡¨ç¤º)"
+
+msgid "list the revision number (default)"
+msgstr "リビジョン番å·ã‚’表示(既定動作)"
+
+msgid "list the changeset"
+msgstr "ãƒãƒƒã‚·ãƒ¥å€¤ã‚’表示"
+
+msgid "show line number at the first appearance"
+msgstr "ç”±æ¥ãƒªãƒ“ジョンã§ã®åˆå‡ºæ™‚ã®è¡Œç•ªå·ã‚’表示"
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+
+msgid "do not pass files through decoders"
+msgstr "デコード処ç†ã‚’回é¿"
+
+msgid "directory prefix for files in archive"
+msgstr "アーカイブファイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªå‰ç½®è©ž"
+
+msgid "revision to distribute"
+msgstr "アーカイブ対象リビジョン"
+
+msgid "type of distribution to create"
+msgstr "アーカイブ種別"
+
+msgid "[OPTION]... DEST"
+msgstr "[OPTION]... DEST"
+
+msgid "merge with old dirstate parent after backout"
+msgstr "æ‰“ã¡æ¶ˆã—リビジョンをç¾è¦ªãƒªãƒ“ジョンã¨ãƒžãƒ¼ã‚¸"
+
+msgid "parent to choose when backing out merge"
+msgstr "æ‰“ã¡æ¶ˆã—リビジョンã¨ã®ãƒžãƒ¼ã‚¸å¯¾è±¡"
+
+msgid "revision to backout"
+msgstr "æ‰“ã¡æ¶ˆã—対象リビジョン"
+
+msgid "[OPTION]... [-r] REV"
+msgstr "[OPTION]... [-r] REV"
+
+msgid "reset bisect state"
+msgstr "探索状態ã®ãƒªã‚»ãƒƒãƒˆ"
+
+msgid "mark changeset good"
+msgstr "å¯¾è±¡ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŽ¢ç´¢çŠ¶æ…‹ã‚’ good 化"
+
+msgid "mark changeset bad"
+msgstr "å¯¾è±¡ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŽ¢ç´¢çŠ¶æ…‹ã‚’ bad 化"
+
+msgid "skip testing changeset"
+msgstr "対象リビジョンã®åˆ¤å®šä½œæ¥­ã‚’çœç•¥"
+
+msgid "use command to check changeset state"
+msgstr "good/bad 判定用コマンド"
+
+msgid "do not update to target"
+msgstr "対象リビジョンã«ã‚ˆã‚‹ä½œæ¥­é ˜åŸŸå†…å®¹ã®æ›´æ–°ã‚’抑止"
+
+msgid "[-gbsr] [-c CMD] [REV]"
+msgstr "[-gbsr] [-c CMD] [REV]"
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr "åŒå既存ブランãƒãŒå­˜åœ¨ã™ã‚‹å ´åˆã§ã‚‚ブランãƒä½œæˆã‚’実施"
+
+msgid "reset branch name to parent branch name"
+msgstr "ブランãƒå設定を解消ã—ã€è¦ªãƒªãƒ“ジョンã®ãƒ–ランãƒã«æˆ»ã‚‹"
+
+msgid "[-fC] [NAME]"
+msgstr "[-fC] [NAME]"
+
+msgid "show only branches that have unmerged heads"
+msgstr "未マージãªãƒ˜ãƒƒãƒ‰ã‚’æŒã¤ãƒ–ランãƒã®ã¿ã‚’表示"
+
+msgid "[-a]"
+msgstr "[-a]"
+
+msgid "run even when remote repository is unrelated"
+msgstr "連æºå…ˆãŒç„¡é–¢ä¿‚ãªãƒªãƒã‚¸ãƒˆãƒªã§ã‚‚実行"
+
+msgid "a changeset up to which you would like to bundle"
+msgstr "ãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイルã«å«ã‚る上é™ã®ãƒªãƒ“ジョン"
+
+msgid "a base changeset to specify instead of a destination"
+msgstr "連æºå…ˆæŒ‡å®šã®ä»£ã‚りã¨ãªã‚‹åŸºåº•リビジョン"
+
+msgid "bundle all changesets in the repository"
+msgstr "リãƒã‚¸ãƒˆãƒªä¸­ã®å…¨ãƒªãƒ“ジョンをãƒãƒ³ãƒ‰ãƒ«ã«å«ã‚ã‚‹"
+
+msgid "bundle compression type to use"
+msgstr "ãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイルã®åœ§ç¸®å½¢å¼"
+
+msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+
+msgid "print output to file with formatted name"
+msgstr "ファイル内容ã®ä¿å­˜å…ˆ"
+
+msgid "print the given revision"
+msgstr "出力対象リビジョン"
+
+msgid "apply any matching decode filter"
+msgstr "デコード処ç†ã‚’実施"
+
+msgid "[OPTION]... FILE..."
+msgstr "[OPTION]... FILE..."
+
+msgid "the clone will only contain a repository (no working copy)"
+msgstr "管ç†é ˜åŸŸã®ã¿ã®è¤‡è£½(ä½œæ¥­é ˜åŸŸã®æ›´æ–°ç„¡ã—)"
+
+msgid "a changeset you would like to have after cloning"
+msgstr "複製ã«ãŠã‘る上é™ã®ãƒªãƒ“ジョン"
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr "[OPTION]... SOURCE [DEST]"
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr "コミットå‰ã«ã€æ–°è¦ï¼ä¸åœ¨ãƒ•ァイルを登録ï¼é™¤å¤–"
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr "ブランãƒã‚’閉鎖ã—ã€ãƒ–ランãƒä¸€è¦§ã§ã®è¡¨ç¤ºã‹ã‚‰é™¤å¤–"
+
+msgid "record a copy that has already occurred"
+msgstr "手動ã§è¤‡è£½æ¸ˆã¿ã®ãƒ•ァイルã«å¯¾ã—ã¦ã€è¤‡è£½ã®æ—¨ã‚’記録"
+
+msgid "forcibly copy over an existing managed file"
+msgstr "åŒåã®ç™»éŒ²æ¸ˆã¿ãƒ•ァイルãŒå­˜åœ¨ã—ã¦ã‚‚複製を実施"
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr "[OPTION]... [SOURCE]... DEST"
+
+msgid "[INDEX] REV1 REV2"
+msgstr "[INDEX] REV1 REV2"
+
+msgid "[COMMAND]"
+msgstr "[COMMAND]"
+
+msgid "show the command options"
+msgstr "当該コマンドã®ã‚ªãƒ—ション一覧ã®è¡¨ç¤º"
+
+msgid "[-o] CMD"
+msgstr "[-o] CMD"
+
+msgid "try extended date formats"
+msgstr "拡張日時形å¼ã®ä½¿ç”¨"
+
+msgid "[-e] DATE [RANGE]"
+msgstr "[-e] DATE [RANGE]"
+
+msgid "FILE REV"
+msgstr "FILE REV"
+
+msgid "[PATH]"
+msgstr "[PATH]"
+
+msgid "FILE"
+msgstr "FILE"
+
+msgid "revision to rebuild to"
+msgstr "冿§‹ç¯‰å¯¾è±¡ãƒªãƒ“ジョン"
+
+msgid "[-r REV] [REV]"
+msgstr "[-r REV] [REV]"
+
+msgid "revision to debug"
+msgstr "デãƒãƒƒã‚°å¯¾è±¡ãƒªãƒ“ジョン"
+
+msgid "[-r REV] FILE"
+msgstr "[-r REV] FILE"
+
+msgid "REV1 [REV2]"
+msgstr "REV1 [REV2]"
+
+msgid "do not display the saved mtime"
+msgstr "記録ã•れ㟠mtime 情報ã®è¡¨ç¤ºæŠ‘æ­¢"
+
+msgid "[OPTION]..."
+msgstr "[OPTION]..."
+
+msgid "revision to check"
+msgstr "確èªå¯¾è±¡ãƒªãƒ“ジョン"
+
+msgid "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+msgstr "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+
+msgid "diff against the second parent"
+msgstr "第2親ã¨ã®å·®åˆ†ã‚’使用"
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr "[OPTION]... [-o OUTFILESPEC] REV..."
+
+msgid "end fields with NUL"
+msgstr "å„フィールドã®åŒºåˆ‡ã‚Šã«NUL文字(0x00)を使用"
+
+msgid "print all revisions that match"
+msgstr "åˆè‡´ã™ã‚‹ãƒªãƒ“ジョンを全ã¦è¡¨ç¤º"
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr "複製元や改åå…ƒã®å±¥æ­´ã‚‚é¡ã‚‹"
+
+msgid "ignore case when matching"
+msgstr "å¤§æ–‡å­—å°æ–‡å­—を無視ã—ã¦æ¤œç´¢"
+
+msgid "print only filenames and revisions that match"
+msgstr "åˆè‡´ã®éš›ã«ãƒ•ァイルåã¨ãƒªãƒ“ジョンã®ã¿ã‚’表示"
+
+msgid "print matching line numbers"
+msgstr "åˆè‡´ã—ãŸè¡Œç•ªå·ã‚’表示"
+
+msgid "search in given revision range"
+msgstr "当該リビジョン範囲を検索"
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr "[OPTION]... PATTERN [FILE]..."
+
+msgid "show only heads which are descendants of REV"
+msgstr "当該リビジョンã®å­å­«ã¨ãªã‚‹ãƒ˜ãƒƒãƒ‰ã®ã¿ã‚’表示"
+
+msgid "show only the active heads from open branches"
+msgstr "アクティブãªãƒ–ランãƒã®ãƒ˜ãƒƒãƒ‰ã®ã¿ã‚’表示"
+
+msgid "show normal and closed heads"
+msgstr "通常ã®é–‰ã˜ãŸãƒ˜ãƒƒãƒ‰ã‚’表示"
+
+msgid "[-r STARTREV] [REV]..."
+msgstr "[-r STARTREV] [REV]..."
+
+msgid "[TOPIC]"
+msgstr "[TOPIC]"
+
+msgid "identify the specified revision"
+msgstr "当該リビジョンã®è­˜åˆ¥æƒ…報を表示"
+
+msgid "show local revision number"
+msgstr "リビジョン番å·ã‚’表示"
+
+msgid "show global revision id"
+msgstr "ãƒãƒƒã‚·ãƒ¥å€¤ã‚’表示"
+
+msgid "show branch"
+msgstr "ブランãƒåを表示"
+
+msgid "show tags"
+msgstr "タグを表示"
+
+msgid "[-nibt] [-r REV] [SOURCE]"
+msgstr "[-nibt] [-r REV] [SOURCE]"
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr "パスè¦ç´ é™¤åŽ»æ•°(patch コマンドã®åŒåオプションã¨åŒæ©Ÿèƒ½)"
+
+msgid "base path"
+msgstr "基底パス"
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr "ä½œæ¥­é ˜åŸŸä¸­ã®æœªã‚³ãƒŸãƒƒãƒˆå¤‰æ›´ã®ç¢ºèªã‚’çœç•¥"
+
+msgid "don't commit, just update the working directory"
+msgstr "ä½œæ¥­é ˜åŸŸã®æ›´æ–°ã®ã¿ã§ã€ã‚³ãƒŸãƒƒãƒˆå®Ÿæ–½ã‚’抑止"
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr "パッãƒä½œæˆæ™‚ã¨åŒã˜è¦ªãƒªãƒ“ジョンã«å¯¾ã—ã¦é©ç”¨"
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr "パッãƒä¸­ã®ãƒ–ãƒ©ãƒ³ãƒæƒ…報を利用(--exact 指定時ã¯è‡ªå‹•é©ç”¨)"
+
+msgid "[OPTION]... PATCH..."
+msgstr "[OPTION]... PATCH..."
+
+msgid "show newest record first"
+msgstr "æ–°ã—ã„リビジョンã‹ã‚‰å…ˆã«è¡¨ç¤º"
+
+msgid "file to store the bundles into"
+msgstr "ãƒãƒ³ãƒ‰ãƒ«ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ã出ã—å…ˆ"
+
+msgid "a specific revision up to which you would like to pull"
+msgstr "å–り込ã¿å¯¾è±¡ã¨ã™ã‚‹ä¸Šé™ã®ãƒªãƒ“ジョン"
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-e CMD] [--remotecmd CMD] [DEST]"
+
+msgid "search the repository as it stood at REV"
+msgstr "当該リビジョン時点ã®ãƒ•ァイル一覧ã‹ã‚‰æ¤œç´¢"
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr "ファイルåã‚’NUL文字(0x00)ã§çµ‚端(xargs ã¨ã®ä½µç”¨å‘ã‘)"
+
+msgid "print complete paths from the filesystem root"
+msgstr "ファイルシステムã®ãƒ«ãƒ¼ãƒˆã‹ã‚‰ã®çµ¶å¯¾ãƒ‘スã§è¡¨ç¤º"
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr "[OPTION]... [PATTERN]..."
+
+msgid "only follow the first parent of merge changesets"
+msgstr "マージã®éš›ã«ã¯ç¬¬1親ã®ã¿ã‚’é¡ã‚‹"
+
+msgid "show revisions matching date spec"
+msgstr "指定日時ã«åˆè‡´ã™ã‚‹ãƒªãƒ“ジョンを表示"
+
+msgid "show copied files"
+msgstr "複製ã•れãŸãƒ•ァイルを表示"
+
+msgid "do case-insensitive search for a keyword"
+msgstr "キーワードã«ã‚ˆã‚‹æ¤œç´¢(å¤§æ–‡å­—å°æ–‡å­—ã¯ç„¡è¦–)"
+
+msgid "include revisions where files were removed"
+msgstr "ファイルãŒç™»éŒ²é™¤å¤–ã•れãŸãƒªãƒ“ジョンをå«ã‚ã‚‹"
+
+msgid "show only merges"
+msgstr "マージ実施リビジョンã®ã¿ã‚’表示"
+
+msgid "revisions committed by user"
+msgstr "当該ユーザã«ã‚ˆã£ã¦ã‚³ãƒŸãƒƒãƒˆã•れãŸãƒªãƒ“ジョンを表示"
+
+msgid "show only changesets within the given named branch"
+msgstr "当該åå‰ä»˜ãブランãƒã«å±žã™ã‚‹ãƒªãƒ“ジョンを表示"
+
+msgid "do not display revision or any of its ancestors"
+msgstr "当該リビジョンã¨ãã®ç¥–å…ˆã®è¡¨ç¤ºã‚’抑止"
+
+msgid "[OPTION]... [FILE]"
+msgstr "[OPTION]... [FILE]"
+
+msgid "revision to display"
+msgstr "表示対象リビジョン"
+
+msgid "[-r REV]"
+msgstr "[-r REV]"
+
+msgid "force a merge with outstanding changes"
+msgstr "ä½œæ¥­é ˜åŸŸä¸­ã®æœªã‚³ãƒŸãƒƒãƒˆå¤‰æ›´ã”ã¨ãƒžãƒ¼ã‚¸ã‚’実施"
+
+msgid "revision to merge"
+msgstr "マージ対象リビジョン"
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr "マージ対象リビジョンã®ç¢ºèª(マージ処ç†ã¯æœªå®Ÿæ–½)"
+
+msgid "[-f] [[-r] REV]"
+msgstr "[-f] [[-r] REV]"
+
+msgid "a specific revision up to which you would like to push"
+msgstr "åæ˜ å¯¾è±¡ã¨ã™ã‚‹ä¸Šé™ã®ãƒªãƒ“ジョン"
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+
+msgid "show parents from the specified revision"
+msgstr "当該リビジョンã®è¦ªãƒªãƒ“ジョンを表示"
+
+msgid "[-r REV] [FILE]"
+msgstr "[-r REV] [FILE]"
+
+msgid "[NAME]"
+msgstr "[NAME]"
+
+msgid "update to new tip if changesets were pulled"
+msgstr "æ–°è¦å–り込ã¿ã®éš›ã«ã¯ä½œæ¥­é ˜åŸŸã‚’ tip ã§æ›´æ–°"
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+
+msgid "force push"
+msgstr "åæ˜ å…ˆã«ãƒ˜ãƒƒãƒ‰ãŒå¢—ãˆã‚‹å ´åˆã§ã‚‚実施"
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+
+msgid "record delete for missing files"
+msgstr "手動ã§å‰Šé™¤æ¸ˆã¿ã®ãƒ•ァイルã«å¯¾ã—ã¦ã€ç™»éŒ²é™¤å¤–ã®æ—¨ã‚’記録"
+
+msgid "remove (and delete) file even if added or modified"
+msgstr "追加登録ï¼å¤‰æ›´å¯¾è±¡ã§ã‚ã£ã¦ã‚‚登録除外(ファイルã¯å‰Šé™¤)"
+
+msgid "record a rename that has already occurred"
+msgstr "æ‰‹å‹•ã§æ”¹å済ã¿ã®ãƒ•ァイルã«å¯¾ã—ã¦ã€æ”¹åã®æ—¨ã‚’記録"
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr "[OPTION]... SOURCE... DEST"
+
+msgid "remerge all unresolved files"
+msgstr "è¡çªæœªè§£æ¶ˆã®å…¨ãƒ•ァイルをå†ãƒžãƒ¼ã‚¸"
+
+msgid "list state of files needing merge"
+msgstr "マージã®å¿…è¦ãªãƒ•ァイルã®è§£æ¶ˆçŠ¶æ…‹ä¸€è¦§"
+
+msgid "mark files as resolved"
+msgstr "当該ファイルをè¡çªè§£æ¶ˆæ¸ˆã¿çŠ¶æ…‹ã«è¨­å®š"
+
+msgid "unmark files as resolved"
+msgstr "当該ファイルをè¡çªæœªè§£æ¶ˆçŠ¶æ…‹ã«è¨­å®š"
+
+msgid "revert all changes when no arguments given"
+msgstr "引数指定ãŒç„¡ã„å ´åˆã«ã€å…¨ãƒ•ァイルã®å†…容を復旧"
+
+msgid "tipmost revision matching date"
+msgstr "å½“è©²æ—¥æ™‚ã®æœ€æ–°ãƒªãƒ“ジョンを使用"
+
+msgid "revision to revert to"
+msgstr "当該リビジョンã®å†…容ã§å¾©æ—§"
+
+msgid "do not save backup copies of files"
+msgstr "å–り消ã—実施å‰å†…容ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を抑止"
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr "[OPTION]... [-r REV] [NAME]..."
+
+msgid "name of access log file to write to"
+msgstr "ã‚¢ã‚¯ã‚»ã‚¹ãƒ­ã‚°ã®æ›¸ã出ã—先ファイル"
+
+msgid "name of error log file to write to"
+msgstr "ã‚¨ãƒ©ãƒ¼ãƒ­ã‚°ã®æ›¸ã出ã—先ファイル"
+
+msgid "port to listen on (default: 8000)"
+msgstr "è¦æ±‚å—ã‘付ã‘ãƒãƒ¼ãƒˆç•ªå·(既定値: 8000)"
+
+msgid "address to listen on (default: all interfaces)"
+msgstr "è¦æ±‚å—ã‘付ã‘アドレス(既定値: 全インタフェース)"
+
+msgid "prefix path to serve from (default: server root)"
+msgstr "公開パスå‰ç½®è©ž(既定値: ルート)"
+
+msgid "name to show in web pages (default: working directory)"
+msgstr "表示å(既定値: 作業領域ã®ãƒ‘ス)"
+
+msgid "name of the webdir config file (serve more than one repository)"
+msgstr "webdir 設定ファイルä½ç½®(複数リãƒã‚¸ãƒˆãƒªã®å…¬é–‹)"
+
+msgid "for remote clients"
+msgstr "(ホスト間連æºã§ã®å†…部用途å‘ã‘)"
+
+msgid "web templates to use"
+msgstr "当該テンプレートã§è¡¨ç¤ºã‚’カスタマイズ"
+
+msgid "template style to use"
+msgstr "当該スタイルã§è¡¨ç¤ºã‚’カスタマイズ"
+
+msgid "use IPv6 in addition to IPv4"
+msgstr "IPv4 ã«åŠ ãˆã¦ IPv6 を使用"
+
+msgid "SSL certificate file"
+msgstr "SSL 証明書ファイル"
+
+msgid "show untrusted configuration options"
+msgstr "ä¿¡é ¼ã§ããªã„設定項目も表示"
+
+msgid "[-u] [NAME]..."
+msgstr "[-u] [NAME]..."
+
+msgid "show status of all files"
+msgstr "å…¨ã¦ã®çŠ¶æ…‹ã‚’è¡¨ç¤º"
+
+msgid "show only modified files"
+msgstr "変更ã•れãŸãƒ•ァイルを表示"
+
+msgid "show only added files"
+msgstr "追加登録ã•れãŸãƒ•ァイルを表示"
+
+msgid "show only removed files"
+msgstr "登録除外ã•れãŸãƒ•ァイルを表示"
+
+msgid "show only deleted (but tracked) files"
+msgstr "削除ã•れãŸãƒ•ァイル(ç™»éŒ²é™¤å¤–ã¯æœªå®Ÿæ–½)を表示"
+
+msgid "show only files without changes"
+msgstr "変更ã®ç„¡ã„ファイルを表示"
+
+msgid "show only unknown (not tracked) files"
+msgstr "æ§‹æˆç®¡ç†å¯¾è±¡å¤–ã®ãƒ•ァイルを表示"
+
+msgid "show only ignored files"
+msgstr "無視対象ã®ãƒ•ァイルを表示"
+
+msgid "hide status prefix"
+msgstr "状態記å·ã®è¡¨ç¤ºã‚’抑止"
+
+msgid "show source of copied files"
+msgstr "複製元ファイルを表示"
+
+msgid "show difference from revision"
+msgstr "当該リビジョンã¨ã®å·®åˆ†ã§çŠ¶æ…‹ã‚’åˆ¤å®š"
+
+msgid "replace existing tag"
+msgstr "既存ã®ã‚¿ã‚°ã‚’ç½®ãæ›ãˆ"
+
+msgid "make the tag local"
+msgstr "ローカルタグã¨ã—ã¦ä½œæˆ"
+
+msgid "revision to tag"
+msgstr "タグ付ã‘対象リビジョン"
+
+msgid "remove a tag"
+msgstr "ã‚¿ã‚°ã®å‰Šé™¤"
+
+msgid "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+
+msgid "[-p]"
+msgstr "[-p]"
+
+msgid "update to new tip if changesets were unbundled"
+msgstr "æ–°è¦å–り込ã¿ã®éš›ã«ã¯ä½œæ¥­é ˜åŸŸã‚’ tip ã§æ›´æ–°"
+
+msgid "[-u] FILE..."
+msgstr "[-u] FILE..."
+
+msgid "overwrite locally modified files (no backup)"
+msgstr "作業領域中ã®å†…容を上書ã(ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—作æˆç„¡ã—)"
+
+msgid "check for uncommitted changes"
+msgstr "未コミット変更を確èª"
+
+msgid "[-C] [-d DATE] [[-r] REV]"
+msgstr "[-C] [-d DATE] [[-r] REV]"
+
+#, python-format
+msgid "config error at %s:%d: '%s'"
+msgstr "%s:%d:設定エラー:%s"
+
+msgid "not found in manifest"
+msgstr "マニフェストã«ã‚りã¾ã›ã‚“"
+
+msgid "branch name not in UTF-8!"
+msgstr "ブランãƒå㌠UTF-8 ã§ã¯ã‚りã¾ã›ã‚“!"
+
+#, python-format
+msgid " searching for copies back to rev %d\n"
+msgstr "リビジョン %d ã¾ã§é¡ã£ã¦ã‚³ãƒ”ーを探索中\n"
+
+#, python-format
+msgid ""
+" unmatched files in local:\n"
+" %s\n"
+msgstr ""
+" ローカルã§ç…§åˆã«å¤±æ•—ã—ãŸãƒ•ァイル:\n"
+" %s\n"
+
+#, python-format
+msgid ""
+" unmatched files in other:\n"
+" %s\n"
+msgstr ""
+" 連æºå…ˆã§ç…§åˆã«å¤±æ•—ã—ãŸãƒ•ァイル:\n"
+" %s\n"
+
+msgid " all copies found (* = to merge, ! = divergent):\n"
+msgstr " 全コピー発見 (* = マージ, ! = 分å²):\n"
+
+msgid " checking for directory renames\n"
+msgstr " ディレクトリåã®å¤‰æ›´ã‚’確èªã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid " dir %s -> %s\n"
+msgstr " ディレクトリ %s -> %s\n"
+
+#, python-format
+msgid " file %s -> %s\n"
+msgstr " ファイル %s -> %s\n"
+
+msgid "working directory state appears damaged!"
+msgstr "作業領域ã®çŠ¶æ…‹ç®¡ç†ã«å•題ãŒã‚りã¾ã™!"
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr "'\\n' 㨠'\\r' ã¯ãƒ•ァイルåã§ä½¿ç”¨ã—ãªã„ã§ãã ã•ã„: %r"
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr "ディレクトリ %r ã¯æ—¢ã«ç®¡ç†å¯¾è±¡ã«å«ã¾ã‚Œã¦ã„ã¾ã™"
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr "ç®¡ç†æƒ…報中ã®ãƒ•ァイル %r 㯠%r ã«ã‚ˆã£ã¦ç ´å£Šã•れã¾ã™"
+
+#, python-format
+msgid "not in dirstate: %s\n"
+msgstr "%s ã¯ç®¡ç†æƒ…報中ã«ã‚りã¾ã›ã‚“\n"
+
+msgid "unknown"
+msgstr "未知"
+
+msgid "character device"
+msgstr "キャラクタデãƒã‚¤ã‚¹"
+
+msgid "block device"
+msgstr "ブロックデãƒã‚¤ã‚¹"
+
+msgid "fifo"
+msgstr "FIFO(パイプ)"
+
+msgid "socket"
+msgstr "ソケット"
+
+msgid "directory"
+msgstr "ディレクトリ"
+
+#, python-format
+msgid "unsupported file type (type is %s)"
+msgstr "未サãƒãƒ¼ãƒˆã®ãƒ•ァイル種別(%s)"
+
+#, python-format
+msgid "abort: %s\n"
+msgstr "中止: %s\n"
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+" %s\n"
+msgstr ""
+"hg: コマンド指定 '%s' ã¯æ›–昧ã§ã™:\n"
+" %s\n"
+
+#, python-format
+msgid "hg: %s\n"
+msgstr "hg: %s\n"
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr "%s ã®ãƒ­ãƒƒã‚¯è§£æ”¾å¾…ã¡ã‚’断念"
+
+#, python-format
+msgid "lock held by %s"
+msgstr "%s ã«ã‚ˆã‚‹ãƒ­ãƒƒã‚¯ä¿æŒ"
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr "中止: %s: %s\n"
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr "中止: %s ã®ãƒ­ãƒƒã‚¯ã«å¤±æ•—: %s\n"
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr "hg %s: %s\n"
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr "中止: %s!\n"
+
+#, python-format
+msgid "abort: %s"
+msgstr "中止: %s"
+
+msgid " empty string\n"
+msgstr " 空文字列\n"
+
+msgid "killed!\n"
+msgstr "強制終了ã•れã¾ã—ãŸ!\n"
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr "hg: 未知ã®ã‚³ãƒžãƒ³ãƒ‰ '%s'\n"
+
+#, python-format
+msgid "abort: could not import module %s!\n"
+msgstr "中断: モジュール %s ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—!\n"
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr "(エクステンションã®ã‚³ãƒ³ãƒ‘イルを忘れã¦ã„ã¾ã›ã‚“ã‹?)\n"
+
+msgid "(is your Python install correct?)\n"
+msgstr "(Python ã¯æ­£ã—ãインストールã•れã¦ã„ã¾ã™ã‹?)\n"
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr "中止: エラー: %s\n"
+
+msgid "broken pipe\n"
+msgstr "パイプ破壊(EPIPE)\n"
+
+msgid "interrupted!\n"
+msgstr "中断ã•れã¾ã—ãŸ!\n"
+
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+"\n"
+"パイプ破壊(EPIPE)\n"
+
+msgid "abort: out of memory\n"
+msgstr "中断: メモリä¸è¶³\n"
+
+msgid "** unknown exception encountered, details follow\n"
+msgstr "** 予期ã›ã¬ä¾‹å¤–ãŒæµ®æšã•れã¾ã—ãŸ\n"
+
+msgid "** report bug details to http://mercurial.selenic.com/bts/\n"
+msgstr "** 障害詳細を http://mercurial.selenic.com/bts ã«å ±å‘Šã—ã¦ãã ã•ã„\n"
+
+msgid "** or mercurial@selenic.com\n"
+msgstr "** ãªã„ã— mercurial@selenic.com ã«å ±å‘Šã—ã¦ãã ã•ã„\n"
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr "** Mercurial - 分散構æˆç®¡ç†(ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s)\n"
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr "** 読ã¿è¾¼ã¿æ¸ˆã¿ã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³: %s\n"
+
+#, python-format
+msgid "no definition for alias '%s'\n"
+msgstr "'%s' を別åã«æŒã¤ã‚³ãƒžãƒ³ãƒ‰ã¯ã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "alias '%s' resolves to unknown command '%s'\n"
+msgstr "'%s' ãŒæœªçŸ¥ã®ã‚³ãƒžãƒ³ãƒ‰ '%s' ã®åˆ¥åã¨ã¿ãªã•れã¾ã—ãŸ\n"
+
+#, python-format
+msgid "alias '%s' resolves to ambiguous command '%s'\n"
+msgstr "'%s' ãŒæ›–昧ãªã‚³ãƒžãƒ³ãƒ‰ '%s' ã®åˆ¥åã¨ã¿ãªã•れã¾ã—ãŸ\n"
+
+#, python-format
+msgid "alias '%s' shadows command\n"
+msgstr "別å '%s' ã¯æ—¢å­˜ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’éš ã—ã¾ã™\n"
+
+#, python-format
+msgid "malformed --config option: %s"
+msgstr "䏿­£ãª --config 指定: %s"
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr "エクステンション '%s' ãŒã‚³ãƒžãƒ³ãƒ‰ã‚’上書ãã—ã¾ã™: %s\n"
+
+msgid "Option --config may not be abbreviated!"
+msgstr "--config æŒ‡å®šå€¤ãŒæœªè§£æžã®å¯èƒ½æ€§ãŒã‚りã¾ã™!"
+
+msgid "Option --cwd may not be abbreviated!"
+msgstr "--cwd æŒ‡å®šå€¤ãŒæœªè§£æžã®å¯èƒ½æ€§ãŒã‚りã¾ã™!"
+
+msgid ""
+"Option -R has to be separated from other options (e.g. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr "-R ã¯ç‹¬ç«‹è¨˜è¿°(例: '-dR' ã¯ä¸å¯)ã€--repository ã®ç•¥è¨˜ã¯ --repo ã®ã¿"
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr "æ‰€è¦æ™‚é–“: 実時間 %.3f ç§’ (ユーザ %.3f+%.3f システム %.3f+%.3f)\n"
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr "リãƒã‚¸ãƒˆãƒª '%s' ã¯ãƒ­ãƒ¼ã‚«ãƒ«ãƒªãƒã‚¸ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "invalid arguments"
+msgstr "引数ãŒä¸æ­£ã§ã™"
+
+#, python-format
+msgid "unrecognized profiling format '%s' - Ignored\n"
+msgstr "䏿­£ãªãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«å½¢å¼ '%s' を無視ã—ã¾ã™\n"
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+"lsprof ãŒåˆ©ç”¨ã§ãã¾ã›ã‚“ - http://codespeak.net/svn/user/arigo/hack/misc/"
+"lsprof/ ã‹ã‚‰ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„"
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr "*** %s ã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã«å¤±æ•— (%s): %s\n"
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr "*** %s ã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã«å¤±æ•—: %s\n"
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr "マージツール %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n"
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr "ツール %s ã¯ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ã‚’扱ãˆã¾ã›ã‚“\n"
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr "ツール %s ã¯ãƒã‚¤ãƒŠãƒªã‚’扱ãˆã¾ã›ã‚“\n"
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr "ツール %s 㯠GUI ãŒå¿…è¦ã§ã™\n"
+
+#, python-format
+msgid "picked tool '%s' for %s (binary %s symlink %s)\n"
+msgstr "%s ã®ãƒžãƒ¼ã‚¸ç”¨ã« '%s' ãŒé¸æŠž(ãƒã‚¤ãƒŠãƒª %s シンボリックリンク %s)\n"
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+" %s ã®ãƒžãƒ¼ã‚¸ã«é©åˆ‡ãªãƒ„ールãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n"
+"ã©ã†ã—ã¾ã™ã‹? 作業領域ã®å†…容:(l)ocalã€ãƒžãƒ¼ã‚¸å¯¾è±¡ã®å†…容:(o)ther"
+
+msgid "&Local"
+msgstr "&Local"
+
+msgid "&Other"
+msgstr "&Other"
+
+msgid "l"
+msgstr "l"
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr "%s 㨠%s ã‚’ %s ã«ãƒžãƒ¼ã‚¸ä¸­\n"
+
+#, python-format
+msgid "merging %s\n"
+msgstr "%s をマージ中\n"
+
+#, python-format
+msgid "my %s other %s ancestor %s\n"
+msgstr "作業領域 %s マージ対象 %s 共通祖先 %s\n"
+
+msgid " premerge successful\n"
+msgstr " 事å‰ãƒžãƒ¼ã‚¸æˆåŠŸ\n"
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+" ãƒžãƒ¼ã‚¸çµæžœãƒ•ァイル %s ã¯æœªå¤‰æ›´ã«è¦‹ãˆã¾ã™\n"
+"マージæˆåŠŸã¨ã¿ãªã—ã¾ã™ã‹? (yn)"
+
+msgid "&No"
+msgstr "&No"
+
+msgid "&Yes"
+msgstr "&Yes"
+
+msgid "n"
+msgstr "n"
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr "%s ã®ãƒžãƒ¼ã‚¸ã«å¤±æ•—!\n"
+
+#, python-format
+msgid "Inconsistent state, %s:%s is good and bad"
+msgstr "状態ãŒçŸ›ç›¾ - %s:%s ã¯åˆ¤å®šä¸èƒ½"
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr "未知ã®åˆ†å²ç¨®é¡ž %s"
+
+msgid ""
+"\n"
+" Mercurial has the ability to add new features through the use of\n"
+" extensions. Extensions may add new commands, add options to\n"
+" existing commands, change the default behavior of commands, or\n"
+" implement hooks.\n"
+"\n"
+" Extensions are not loaded by default for a variety of reasons:\n"
+" they can increase startup overhead; they may be meant for\n"
+" advanced usage only; they may provide potentially dangerous\n"
+" abilities (such as letting you destroy or modify history); they\n"
+" might not be ready for prime time; or they may alter some\n"
+" usual behaviors of stock Mercurial. It is thus up to the user to\n"
+" activate extensions as needed.\n"
+"\n"
+" To enable the \"foo\" extension, either shipped with Mercurial\n"
+" or in the Python search path, create an entry for it in your\n"
+" hgrc, like this:\n"
+"\n"
+" [extensions]\n"
+" foo =\n"
+"\n"
+" You may also specify the full path to an extension:\n"
+"\n"
+" [extensions]\n"
+" myfeature = ~/.hgext/myfeature.py\n"
+"\n"
+" To explicitly disable an extension enabled in an hgrc of broader\n"
+" scope, prepend its path with !:\n"
+"\n"
+" [extensions]\n"
+" # disabling extension bar residing in /path/to/extension/bar.py\n"
+" hgext.bar = !/path/to/extension/bar.py\n"
+" # ditto, but no path was supplied for extension baz\n"
+" hgext.baz = !\n"
+" "
+msgstr ""
+"\n"
+" Mercurial ã«ã¯ã€æ–°è¦æ©Ÿèƒ½ã‚’「エクステンションã€ã¨ã„ã†æ©Ÿæ§‹ã‚’用ã„ã¦\n"
+" 追加ã™ã‚‹ä»•組ã¿ãŒå‚™ã‚ã£ã¦ã„ã¾ã™ã€‚エクステンションã§ã¯ã€ã‚³ãƒžãƒ³ãƒ‰ã®\n"
+" æ–°è¦è¿½åŠ ã€æ—¢å­˜ã‚³ãƒžãƒ³ãƒ‰ã¸ã®ã‚ªãƒ—ションã®è¿½åŠ ã€ã‚³ãƒžãƒ³ãƒ‰ã®æŒ™å‹•ã®å¤‰æ›´ã€\n"
+" フックã®å®Ÿè£…ã¨ã„ã£ãŸã“ã¨ãŒå¯èƒ½ã§ã™ã€‚\n"
+"\n"
+" 様々ãªäº‹æƒ…ã‹ã‚‰ã€ç‰¹ã«æŒ‡å®šã®ç„¡ã„å ´åˆã«ã¯ã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³ã¯èª­ã¿è¾¼ã¾ã‚Œ\n"
+" ã¾ã›ã‚“。付加的ãªèª­ã¿è¾¼ã¿ã¯ã€èµ·å‹•時間ã®å¢—加をæ„味ã—ã¾ã™ã€‚上級用途\n"
+" é™å®šã®ã‚‚ã®ã‚‚ã‚りã¾ã™ã€‚(履歴ã®ç ´å£Šã‚„改変ãªã©ã®)潜在的ãªå±é™ºæ€§ã‚’æŒã¤\n"
+" å ´åˆã‚‚ã‚りã¾ã™ã€‚実験的ãªã‚‚ã®ã§ã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。ã“れã¾ã§ã®\n"
+" Mercurial ã®æŒ¯ã‚‹èˆžã„を変ãˆã¦ã—ã¾ã†ã‹ã‚‚ã—れã¾ã›ã‚“。エクステンションを\n"
+" å¿…è¦ã«å¿œã˜ã¦æœ‰åŠ¹åŒ–ã™ã‚‹ã®ã¯åˆ©ç”¨è€…ã®è²¬å‹™ã§ã™ã€‚\n"
+"\n"
+" \"foo\" ã¨ã„ã†ã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³ã‚’有効化ã™ã‚‹ã«ã¯ã€Mercurial åŒæ¢±ã®\n"
+" ã‚‚ã®ã§ã‚ã‚ã†ã¨ã€Python ã®æ¤œç´¢ãƒ‘ス中ã®ã‚‚ã®ã§ã‚ã‚ã†ã¨ã€è¨­å®šãƒ•ァイル\n"
+" ã«ãŠã„ã¦ä»¥ä¸‹ã®ã‚ˆã†ãªè¨˜è¿°ãŒå¿…è¦ã§ã™ã€‚\n"
+"\n"
+" [extensions]\n"
+" foo =\n"
+"\n"
+" エクステンションã¸ã®ãƒ•ルパスを記述ã™ã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚\n"
+"\n"
+" [extensions]\n"
+" myfeature = ~/.hgext/myfeature.py\n"
+"\n"
+" 明示的ã«ã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³ã‚’無効化ã™ã‚‹å ´åˆã€é©åˆ‡ãªè¨­å®šãƒ•ァイルã«ãŠã„ã¦\n"
+" パス指定ã®å†’é ­ã« '!' を付与ã—ã¾ã™ã€‚\n"
+"\n"
+" [extensions]\n"
+" # /path/to/extension/bar.py ã«ã‚るエクステンション bar ã®ç„¡åŠ¹åŒ–\n"
+" hgext.bar = !/path/to/extension/bar.py\n"
+" # ã“ã¡ã‚‰ã¯ãƒ‘ス指定無ã—ã§ã® baz エクステンションã®ç„¡åŠ¹åŒ–\n"
+" hgext.baz = !\n"
+" "
+
+msgid "disabled extensions:"
+msgstr "無効化ã•れã¦ã„るエクステンション:"
+
+msgid "Date Formats"
+msgstr "日時表記"
+
+msgid ""
+"\n"
+" Some commands allow the user to specify a date, e.g.:\n"
+" * backout, commit, import, tag: Specify the commit date.\n"
+" * log, revert, update: Select revision(s) by date.\n"
+"\n"
+" Many date formats are valid. Here are some examples:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n"
+" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n"
+" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n"
+" \"Dec 6\" (midnight)\n"
+" \"13:18\" (today assumed)\n"
+" \"3:39\" (3:39AM assumed)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Lastly, there is Mercurial's internal format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" This is the internal representation format for dates. unixtime is\n"
+" the number of seconds since the epoch (1970-01-01 00:00 UTC).\n"
+" offset is the offset of the local timezone, in seconds west of UTC\n"
+" (negative if the timezone is east of UTC).\n"
+"\n"
+" The log command also accepts date ranges:\n"
+"\n"
+" \"<{datetime}\" - at or before a given date/time\n"
+" \">{datetime}\" - on or after a given date/time\n"
+" \"{datetime} to {datetime}\" - a date range, inclusive\n"
+" \"-{days}\" - within a given number of days of today\n"
+" "
+msgstr ""
+"\n"
+" 以下ã®ã‚³ãƒžãƒ³ãƒ‰ã§æ—¥æ™‚指定ãŒå¯èƒ½ã§ã™:\n"
+" * backout, commit, import, tag: ã‚³ãƒŸãƒƒãƒˆæ—¥æ™‚ã®æŒ‡å®š\n"
+" * log, revert, update: 日時ã«ã‚ˆã‚‹ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŒ‡å®š\n"
+"\n"
+" æœ‰åŠ¹ãªæ—¥æ™‚指定形å¼ã¯æ²¢å±±ã‚りã¾ã™ã€‚以下ã«ã„ãã¤ã‹ã®ä¾‹ã‚’示ã—ã¾ã™ã€‚\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (「ローカルタイムゾーンã€ã‚’想定)\n"
+" \"Dec 6 13:18 -0600\" (「今年ã€ã‚’想定ã€ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã¯ã‚ªãƒ•セット指定)\n"
+" \"Dec 6 13:18 UTC\" (UTC ãŠã‚ˆã³ GMT 㯠+0000 ã®åˆ¥å)\n"
+" \"Dec 6\" (「åˆå‰0時ã€ã‚’想定)\n"
+" \"13:18\" (「本日ã€ã‚’想定)\n"
+" \"3:39\" (「3:39AMã€ã‚’想定)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 å½¢å¼)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (2006年12月6日)\n"
+"\n"
+" 最後ã«ã€Mercurial 固有ã®å†…部形å¼ã‚’示ã—ã¾ã™ã€‚\n"
+"\n"
+" \"1165432709 0\" (2006年12月6日 13:18:29 UTC)\n"
+"\n"
+" ã“ã‚Œã¯æ—¥æ™‚ã®å†…部表ç¾å½¢å¼ã§ã™ã€‚基点ã¨ãªã‚‹ 1970å¹´1月1æ—¥ 00:00 UTC ã‹ã‚‰ã®\n"
+" 経éŽç§’数を表㙠unixtime å½¢å¼éƒ¨åˆ†ã¨ã€ãƒ­ãƒ¼ã‚«ãƒ«ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã®ã‚ªãƒ•セット値\n"
+" (UTC よりもæ±å´ã®åœ°åŸŸã¯è² å€¤)を表ã™ã‚ªãƒ•セット部分ã‹ã‚‰æ§‹æˆã•れã¦ã„ã¾ã™ã€‚\n"
+"\n"
+" log コマンドã«ã¯ã€æ—¥æ™‚範囲指定å¯èƒ½ã§ã™:\n"
+"\n"
+" \"<{date}\" - 指定日時以å‰(指定日時å«ã‚€)\n"
+" \">{date}\" - 指定日時以後(指定日時å«ã‚€)\n"
+" \"{date} to {date}\" - 指定日時範囲(指定日時å«ã‚€)\n"
+" \"-{days}\" - 本日ã‹ã‚‰æŒ‡å®šæ—¥æ•°ä»¥å†…\n"
+" "
+
+msgid "File Name Patterns"
+msgstr "ファイルåパターン"
+
+msgid ""
+"\n"
+" Mercurial accepts several notations for identifying one or more\n"
+" files at a time.\n"
+"\n"
+" By default, Mercurial treats filenames as shell-style extended\n"
+" glob patterns.\n"
+"\n"
+" Alternate pattern notations must be specified explicitly.\n"
+"\n"
+" To use a plain path name without any pattern matching, start it\n"
+" with \"path:\". These path names must completely match starting at\n"
+" the current repository root.\n"
+"\n"
+" To use an extended glob, start a name with \"glob:\". Globs are\n"
+" rooted at the current directory; a glob such as \"*.c\" will only\n"
+" match files in the current directory ending with \".c\".\n"
+"\n"
+" The supported glob syntax extensions are \"**\" to match any string\n"
+" across path separators and \"{a,b}\" to mean \"a or b\".\n"
+"\n"
+" To use a Perl/Python regular expression, start a name with \"re:\".\n"
+" Regexp pattern matching is anchored at the root of the repository.\n"
+"\n"
+" Plain examples:\n"
+"\n"
+" path:foo/bar a name bar in a directory named foo in the root of\n"
+" the repository\n"
+" path:path:name a file or directory named \"path:name\"\n"
+"\n"
+" Glob examples:\n"
+"\n"
+" glob:*.c any name ending in \".c\" in the current directory\n"
+" *.c any name ending in \".c\" in the current directory\n"
+" **.c any name ending in \".c\" in any subdirectory of the\n"
+" current directory including itself.\n"
+" foo/*.c any name ending in \".c\" in the directory foo\n"
+" foo/**.c any name ending in \".c\" in any subdirectory of foo\n"
+" including itself.\n"
+"\n"
+" Regexp examples:\n"
+"\n"
+" re:.*\\.c$ any name ending in \".c\", anywhere in the repository\n"
+"\n"
+" "
+msgstr ""
+"\n"
+" Mercurial ã«ã¯ã€ãƒ•ァイルを特定ã™ã‚‹ãƒ‘ターン指定方法ãŒè¤‡æ•°ã‚りã¾ã™ã€‚\n"
+"\n"
+" ç‰¹ã«æŒ‡å®šã®ç„¡ã„å ´åˆã€Mercurial ã¯æŒ‡å®šã•れãŸãƒ•ァイルåã«å¯¾ã—ã¦ã€\n"
+" shell å½¢å¼ã®æ‹¡å¼µãƒ¯ã‚¤ãƒ«ãƒ‰ã‚«ãƒ¼ãƒ‰åˆè‡´ã‚’行ã„ã¾ã™ã€‚\n"
+"\n"
+" 別ãªå½¢å¼ã§ã®ãƒ‘ターン記述ã®éš›ã«ã¯ã€æ˜Žç¤ºçš„ã«ç¨®åˆ¥ã‚’指定ã—ã¦ãã ã•ã„。\n"
+"\n"
+" パターンåˆè‡´ã‚’行ã‚ãšã«ã€æŒ‡å®šã•れãŸåå‰ã‚’ãã®ã¾ã¾ä½¿ç”¨ã™ã‚‹å ´åˆã€\n"
+" åå‰ã®å‰ã« \"path:\" を記述ã—ã¾ã™ã€‚ã“ã®å½¢å¼ã‚’使用ã™ã‚‹å ´åˆã€\n"
+" リãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆã‹ã‚‰ã®ãƒ‘スã¨å®Œå…¨ã«ä¸€è‡´ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。\n"
+"\n"
+" 拡張ワイルドカードåˆè‡´ã®å ´åˆã€åå‰ã®å‰ã« \"glob:\" を記述ã—ã¾ã™ã€‚ã“ã®\n"
+" å½¢å¼ã§ã¯ã€ç¾ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‹ã‚‰ã®ç›¸å¯¾ã«ãªã‚Šã¾ã™ã®ã§ã€\"*.c\" パターンã¯\n"
+" 末尾㌠\"*.c\" ã§çµ‚ã‚ã‚‹ç¾ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªä¸­ã®ãƒ•ァイルã¨ã®ã¿åˆè‡´ã—ã¾ã™ã€‚\n"
+"\n"
+" ãƒ¯ã‚¤ãƒ«ãƒ‰ã‚«ãƒ¼ãƒ‰ã®æ‹¡å¼µæ–‡æ³•ã«ã¯ã€ãƒ‘ス区切りもå«ã‚ãŸä»»æ„ã®æ–‡å­—列ã¨åˆè‡´ã™ã‚‹\n"
+" \"**\" ã¨ã€\"a ãªã„ã— b\" ã‚’æ„味ã™ã‚‹ \"{a,b}\" ã¨ã„ã†å½¢å¼ãŒã‚りã¾ã™ã€‚\n"
+"\n"
+" Perl/Python å½¢å¼ã®æ­£è¦è¡¨ç¾ã®å ´åˆã€åå‰ã®å‰ã« \"re:\" を記述ã—ã¾ã™ã€‚\n"
+" æ­£è¦è¡¨ç¾å½¢å¼ã§ã¯ã€ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆã‹ã‚‰ã®åˆè‡´ã‚’æ„味ã™ã‚‹ \"^\" 指定ãŒ\n"
+" パターン先頭ã«è‡ªå‹•çš„ã«ä»˜ä¸Žã•れã¾ã™(訳注: .hgignore ã§ã®æŒ‡å®šã§ã¯ä»˜ä¸Ž\n"
+" 「ã•れã¾ã›ã‚“ã€ã®ã§æ³¨æ„ãŒå¿…è¦ã§ã™)。\n"
+"\n"
+" パターンåˆè‡´æœªä½¿ç”¨ä¾‹:\n"
+"\n"
+" path:foo/bar リãƒã‚¸ãƒˆãƒªãƒ«ãƒ¼ãƒˆç›´ä¸‹ã® foo ディレクトリ中㮠bar\n"
+" path:path:name \"path:name\" ã¨ã„ã†åå‰\n"
+"\n"
+" ワイルドカード指定例:\n"
+"\n"
+" glob:*.c ç¾ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªç›´ä¸‹ã§ã€åå‰ãŒ \".c\" ã§çµ‚ã‚ã‚‹ã‚‚ã®\n"
+" *.c ç¾ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªç›´ä¸‹ã§ã€åå‰ãŒ \".c\" ã§çµ‚ã‚ã‚‹ã‚‚ã®\n"
+" **.c ç¾ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãªã„ã—ãã®é…下ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ãŠã„ã¦ã€\n"
+" åå‰ãŒ \".c\" ã§çµ‚ã‚ã‚‹ã‚‚ã®\n"
+" foo/*.c foo ディレクトリ直下ã§ã€åå‰ãŒ \".c\" ã§çµ‚ã‚ã‚‹ã‚‚ã®\n"
+" foo/**.c foo ディレクトリãªã„ã—ãã®é…下ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ãŠã„ã¦ã€\n"
+" åå‰ãŒ \".c\" ã§çµ‚ã‚ã‚‹ã‚‚ã®\n"
+"\n"
+" æ­£è¦è¡¨ç¾æŒ‡å®šä¾‹:\n"
+"\n"
+" re:.*\\.c$ 作業領域中ã®ä»»æ„ã®ä½ç½®ã§ã€åå‰ãŒ \".c\" ã§çµ‚ã‚ã‚‹ã‚‚ã®\n"
+"\n"
+" "
+
+msgid "Environment Variables"
+msgstr "環境変数"
+
+msgid ""
+"\n"
+"HG::\n"
+" Path to the 'hg' executable, automatically passed when running\n"
+" hooks, extensions or external tools. If unset or empty, this is\n"
+" the hg executable's name if it's frozen, or an executable named\n"
+" 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+" Windows) is searched.\n"
+"\n"
+"HGEDITOR::\n"
+" This is the name of the editor to run when committing. See EDITOR.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" This overrides the default locale setting detected by Mercurial.\n"
+" This setting is used to convert data including usernames,\n"
+" changeset descriptions, tag names, and branches. This setting can\n"
+" be overridden with the --encoding command-line option.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" This sets Mercurial's behavior for handling unknown characters\n"
+" while transcoding user input. The default is \"strict\", which\n"
+" causes Mercurial to abort if it can't map a character. Other\n"
+" settings include \"replace\", which replaces unknown characters, and\n"
+" \"ignore\", which drops them. This setting can be overridden with\n"
+" the --encodingmode command-line option.\n"
+"\n"
+"HGMERGE::\n"
+" An executable to use for resolving merge conflicts. The program\n"
+" will be executed with three arguments: local file, remote file,\n"
+" ancestor file.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" A list of files or directories to search for hgrc files. Item\n"
+" separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
+" platform default search path is used. If empty, only the .hg/hgrc\n"
+" from the current repository is read.\n"
+"\n"
+" For each element in HGRCPATH:\n"
+" * if it's a directory, all files ending with .rc are added\n"
+" * otherwise, the file itself will be added\n"
+"\n"
+"HGUSER::\n"
+" This is the string used as the author of a commit. If not set,\n"
+" available values will be considered in this order:\n"
+"\n"
+" * HGUSER (deprecated)\n"
+" * hgrc files from the HGRCPATH\n"
+" * EMAIL\n"
+" * interactive prompt\n"
+" * LOGNAME (with '@hostname' appended)\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"LOGNAME::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"VISUAL::\n"
+" This is the name of the editor to use when committing. See EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Sometimes Mercurial needs to open a text file in an editor for a\n"
+" user to modify, for example when writing commit messages. The\n"
+" editor it uses is determined by looking at the environment\n"
+" variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+" non-empty one is chosen. If all of them are empty, the editor\n"
+" defaults to 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" This is used by Python to find imported modules and may need to be\n"
+" set appropriately if this Mercurial is not installed system-wide.\n"
+" "
+msgstr ""
+"\n"
+"HG::\n"
+" 'hg' コマンドã¸ã®ãƒ‘ス。フックï¼ã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³ãªã„ã—外部ツールã®èµ·å‹•ã®\n"
+" éš›ã«è‡ªå‹•çš„ã«è¨­å®šã•れã¾ã™ã€‚未設定や空ã®å ´åˆã¯ã€frozen å½¢å¼ã®\n"
+" hg 実行å¯èƒ½ãƒ•ァイルã®åå‰ã‹è¨­å®šã•れるã‹ã€'hg' ã¨ã„ã†åå‰ã®å®Ÿè¡Œå¯èƒ½\n"
+" ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ¤œç´¢ã•れã¾ã™(Windows ã®å ´åˆã€PATHEXT 環境変数ã«è¨­å®šã•れãŸ\n"
+" COM/EXE/BAT/CMD ç­‰ã®æ‹¡å¼µå­ä»˜ã)。\n"
+"\n"
+"HGEDITOR::\n"
+" コミットã®éš›ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸å…¥åŠ›ã‚’è¡Œã†ãŸã‚ã®ã‚¨ãƒ‡ã‚£ã‚¿ã®åå‰ã€‚EDITOR 環境変数\n"
+" ã«ã¤ã„ã¦ã‚‚å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+" (推奨ã•れãªã„ç’°å¢ƒå¤‰æ•°ã€‚è¨­å®šãƒ•ã‚¡ã‚¤ãƒ«çµŒç”±ã§æŒ‡å®šã—ã¦ãã ã•ã„。)\n"
+"\n"
+"HGENCODING::\n"
+" Mercurial ã«ã‚ˆã‚‹ãƒ­ã‚±ãƒ¼ãƒ«è‡ªå‹•検出ã®ä¸Šæ›¸ã。ã“ã®è¨­å®šã¯ã€ãƒ¦ãƒ¼ã‚¶åã€\n"
+" コミットメッセージã€ã‚¿ã‚°åãŠã‚ˆã³ãƒ–ランãƒåを内部データ形å¼ã«å¤‰æ›ã™ã‚‹\n"
+" éš›ã«ä½¿ç”¨ã•れã¾ã™ã€‚ã“ã®ç’°å¢ƒå¤‰æ•°è¨­å®šã¯ã€ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã§ã® --encoding\n"
+" 使用ã«ã‚ˆã‚Šã€æ›´ã«ä¸Šæ›¸ãã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n"
+"\n"
+"HGENCODINGMODE::\n"
+" ユーザã‹ã‚‰ã®æŒ‡å®šå€¤ã‚’内部データ形å¼ã«å¤‰æ›ã™ã‚‹éš›ã«ã€æŒ‡å®šã®ç¬¦å·åŒ–ã¨\n"
+" åˆè‡´ã—ãªã„æ–‡å­—ãŒæ¤œå‡ºã•れãŸå ´åˆã® Mercurial ã®æŒ™å‹•ã®æŒ‡å®šã€‚無指定時ã¯ã€\n"
+" 「指定ã®ç¬¦å·åŒ–ã¨åˆè‡´ã—ãªã„å ´åˆã¯å‡¦ç†ä¸­æ–­ã€ã‚’æ„味ã™ã‚‹ \"strict\" ãŒæŒ‡å®š\n"
+" ã•れãŸã‚‚ã®ã¨ã¿ãªã—ã¾ã™ã€‚ä»–ã«ã¯ã€ã€ŒæœªçŸ¥ã®æ–‡å­—ã®ç½®ãæ›ãˆã€ã‚’æ„味ã™ã‚‹\n"
+" \"replace\" ã¨ã€ã€ŒæœªçŸ¥ã®æ–‡å­—ã®åˆ‡ã‚Šæ¨ã¦ã€ã‚’æ„味ã™ã‚‹ \"ignore\" ãŒæŒ‡å®š\n"
+" 出æ¥ã¾ã™ã€‚ã“ã®ç’°å¢ƒå¤‰æ•°è¨­å®šã¯ã€ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã§ã® --encodingmode\n"
+" 使用ã«ã‚ˆã‚Šã€æ›´ã«ä¸Šæ›¸ãã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n"
+"\n"
+"HGMERGE::\n"
+" マージã®éš›ã®è¡çªè§£æ¶ˆã«ä½¿ç”¨ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã€‚指定ã•れãŸã‚³ãƒžãƒ³ãƒ‰ã®èµ·å‹•ã«ã¯ã€\n"
+" 作業領域ã®ãƒ•ァイルã€åˆ¥ãƒªãƒ“ジョンã®ãƒ•ァイルã€ä¸¡è€…ã®è¦ªãƒªãƒ“ジョンã®\n"
+" ファイルを表ã™3ã¤ã®å¼•æ•°ãŒæŒ‡å®šã•れã¾ã™ã€‚\n"
+"\n"
+" (推奨ã•れãªã„ç’°å¢ƒå¤‰æ•°ã€‚è¨­å®šãƒ•ã‚¡ã‚¤ãƒ«çµŒç”±ã§æŒ‡å®šã—ã¦ãã ã•ã„。)\n"
+"\n"
+"HGRCPATH::\n"
+" 設定ファイル読込ã®ãŸã‚ã®ã€ãƒ•ァイルãªã„ã—ディレクトリã®ä¸€è¦§ã®æŒ‡å®šã€‚\n"
+" 一覧è¦ç´ ã®åŒºåˆ‡ã‚Šè¨˜å·ã¯ã€Unix ãªã‚‰ \":\"ã€WIndows ãªã‚‰ \";\" ã§ã™ã€‚\n"
+" HGRCPATH 環境変数ãŒè¨­å®šã•れã¦ã„ãªã„å ´åˆã€å„稼åƒç’°å¢ƒã«å¿œã˜ãŸ\n"
+" 読ã¿è¾¼ã¿å…ˆã‹ã‚‰èª­ã¿è¾¼ã¾ã‚Œã¾ã™ã€‚空ã®å€¤ãŒè¨­å®šã•れã¦ã„ã‚‹å ´åˆã€\n"
+" ç¾ãƒªãƒã‚¸ãƒˆãƒªã® .hg/hgrc ã®ã¿ãŒèª­ã¿è¾¼ã¾ã‚Œã¾ã™ã€‚\n"
+"\n"
+" 指定ã•れãŸä¸€è¦§ã®å„è¦ç´ ã«å¯¾ã—ã¦ã€ä»¥ä¸‹ã®ã‚ˆã†ã«æŒ¯èˆžã„ã¾ã™:\n"
+" * ディレクトリãªã‚‰ã€é…下㮠\".rc\" ã§çµ‚ã‚ã‚‹åå‰ã®ãƒ•ァイルを読ã¿è¾¼ã‚€\n"
+" * ファイルãªã‚‰ã€ãã®ãƒ•ァイル自身を読ã¿è¾¼ã‚€\n"
+"\n"
+"HGUSER::\n"
+" ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆä½œæˆè€…ã¨ã—ã¦ã‚³ãƒŸãƒƒãƒˆæ™‚ã«è¨˜éŒ²ã™ã‚‹åå‰ã®æŒ‡å®šã€‚\n"
+" 作æˆè€…åã¨ã—ã¦æŽ¡ç”¨ã•ã‚Œã‚‹å€¤ã®æ±ºå®šé †åºã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™ã€‚\n"
+"\n"
+" * HGUSER 環境変数値(推奨ã•れã¾ã›ã‚“)\n"
+" * (HGRCPATH ç’°å¢ƒå¤‰æ•°ã§æŒ‡å®šã•れる)設定ファイル中ã®è¨­å®š\n"
+" * EMAIL 環境変数値\n"
+" * 対話的ãªå…¥åŠ›\n"
+" * LOGNAME 環境変数値('@hostname' ãŒä»˜ä¸Žã•れã¾ã™)\n"
+"\n"
+" (推奨ã•れãªã„ç’°å¢ƒå¤‰æ•°ã€‚è¨­å®šãƒ•ã‚¡ã‚¤ãƒ«çµŒç”±ã§æŒ‡å®šã—ã¦ãã ã•ã„。)\n"
+"\n"
+"EMAIL::\n"
+" ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆä½œæˆè€…ã¨ã—ã¦ã“ã®ç’°å¢ƒå¤‰æ•°å€¤ãŒè¨˜éŒ²ã•れるå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n"
+" 詳細㯠HGUSER ã®è¨˜è¿°ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+"LOGNAME::\n"
+" ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆä½œæˆè€…ã¨ã—ã¦ã“ã®ç’°å¢ƒå¤‰æ•°å€¤ãŒè¨˜éŒ²ã•れるå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n"
+" 詳細㯠HGUSER ã®è¨˜è¿°ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+"VISUAL::\n"
+" コミット時ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’編集ã™ã‚‹ã‚¨ãƒ‡ã‚£ã‚¿åã®æŒ‡å®šã€‚EDITOR 環境変数\n"
+" ã«ã¤ã„ã¦ã‚‚å‚ç…§ã—ã¦ãã ã•ã„。\n"
+"\n"
+"EDITOR::\n"
+" コミット時ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ã‚ˆã†ã«ã€ã‚¨ãƒ‡ã‚£ã‚¿ã§ãƒ•ァイルを開ãã€ãƒ¦ãƒ¼ã‚¶ã«ã‚ˆã‚‹\n"
+" 編集を促ã™çжæ³ãŒã‚りã¾ã™ã€‚ãã“ã§ä½¿ç”¨ã•れるエディタã¯ã€HGEDITORã€VISUAL\n"
+" ã‚ã‚‹ã„㯠EDITOR 環境変数ã«è¨­å®šã•れãŸã‚‚ã®ã‚’(ã“ã®é †åºã§)使用ã—ã¾ã™ã€‚\n"
+" 最åˆã®ç©ºã§ç„¡ã„値ã«è¨­å®šã•れãŸç’°å¢ƒå¤‰æ•°ã®å€¤ã‚’使用ã—ã¾ã™ã€‚ã„ãšã‚Œã‚‚未設定\n"
+" (ã‚ã‚‹ã„ã¯ç©º)ã®å ´åˆã¯ã€'vi' ãŒä½¿ç”¨ã•れã¾ã™ã€‚\n"
+"\n"
+"PYTHONPATH::\n"
+" Mercurial ãŒå½“該システムã®å…±æœ‰é ˜åŸŸã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ãªã„å ´åˆã€\n"
+" Python ãŒå¿…è¦ãªãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’読ã¿è¾¼ã‚€ãŸã‚ã«ã¯ã€ã“ã®ç’°å¢ƒå¤‰æ•°ã®è¨­å®šãŒ\n"
+" å¿…è¦ã§ã™ã€‚\n"
+" "
+
+msgid "Specifying Single Revisions"
+msgstr "å˜ä¸€ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŒ‡å®š"
+
+msgid ""
+"\n"
+" Mercurial supports several ways to specify individual revisions.\n"
+"\n"
+" A plain integer is treated as a revision number. Negative integers\n"
+" are treated as topological offsets from the tip, with -1 denoting\n"
+" the tip. As such, negative numbers are only useful if you've\n"
+" memorized your local tree numbers and want to save typing a single\n"
+" digit. This editor suggests copy and paste.\n"
+"\n"
+" A 40-digit hexadecimal string is treated as a unique revision\n"
+" identifier.\n"
+"\n"
+" A hexadecimal string less than 40 characters long is treated as a\n"
+" unique revision identifier, and referred to as a short-form\n"
+" identifier. A short-form identifier is only valid if it is the\n"
+" prefix of exactly one full-length identifier.\n"
+"\n"
+" Any other string is treated as a tag name, which is a symbolic\n"
+" name associated with a revision identifier. Tag names may not\n"
+" contain the \":\" character.\n"
+"\n"
+" The reserved name \"tip\" is a special tag that always identifies\n"
+" the most recent revision.\n"
+"\n"
+" The reserved name \"null\" indicates the null revision. This is the\n"
+" revision of an empty repository, and the parent of revision 0.\n"
+"\n"
+" The reserved name \".\" indicates the working directory parent. If\n"
+" no working directory is checked out, it is equivalent to null. If\n"
+" an uncommitted merge is in progress, \".\" is the revision of the\n"
+" first parent.\n"
+" "
+msgstr ""
+"\n"
+" Mercurial ã¯ã€å€‹ã€…ã®ãƒªãƒ“ジョンを識別ã™ã‚‹è¨˜æ³•ã‚’å¹¾ã¤ã‹ç”¨æ„ã—ã¦ã„ã¾ã™ã€‚\n"
+"\n"
+" 整数値ã¯ã€ã€Œãƒªãƒ“ジョン番å·ã€ã¨ã¿ãªã•れã¾ã™ã€‚負値ã¯ã€tip ã‹ã‚‰ã®è·é›¢ã‚’\n"
+" 表ã—ã€-1 㯠tip 自身を表ã—ã¾ã™ã€‚è² å€¤ã®æŒ‡å®šã¯ã€æ‰‹å…ƒã®ãƒªãƒã‚¸ãƒˆãƒªä¸­ã®\n"
+" 履歴é·ç§»ã‚’把æ¡ã—ã¦ã„ã‚‹éš›ã«ã€å…¥åŠ›ã‚’çœåŠ›åŒ–ã—ãŸã„å ´åˆã«ã®ã¿æœ‰åйã§ã™ã€‚\n"
+" 負値ã®åˆ©ç”¨ã¯ã‚ã¾ã‚ŠãŠå‹§ã‚ã§ãã¾ã›ã‚“。\n"
+"\n"
+" 40æ¡ã®16進文字列ã¯ã€ä¸€æ„ãªã€Œãƒªãƒ“ジョン識別å­ã€ã¨ã¿ãªã•れã¾ã™ã€‚\n"
+"\n"
+" 40æ¡æœªæº€ã®16進文字列ã¯ã€ä¸€æ„ãªã€Œãƒªãƒ“ジョン識別å­ã€ã®çŸ­ç¸®å½¢å¼ã¨\n"
+" ã¿ãªã•れã¾ã™ã€‚短縮形å¼ã®è­˜åˆ¥å­ã¯ã€å޳坆ã«1ã¤ã®å®Œå…¨é•·ã®è­˜åˆ¥å­ã¨ã ã‘\n"
+" 剿–¹ä¸€è‡´ã™ã‚‹å ´åˆã«ã®ã¿æœ‰åйã§ã™ã€‚\n"
+"\n"
+" ãã‚Œä»¥å¤–ã®æ–‡å­—列ã¯ã€ãƒªãƒ“ジョン識別å­ã«é–¢é€£ä»˜ã‘られãŸã€Œã‚¿ã‚°åã€ã¨\n"
+" ã¿ãªã•れã¾ã™ã€‚ã‚¿ã‚°å㯠\":\" ã‚’å«ã‚“ã§ã„ãªã„ã‹ã‚‚ã—れãªã„。\n"
+"\n"
+" 「最新ã®ãƒªãƒ“ジョンã€ã‚’示ã™ãŸã‚ã®åå‰ \"tip\" ã¯ã€ç‰¹åˆ¥ãªåå‰ã¨ã—ã¦äºˆç´„\n"
+" ã•れã¦ã„ã¾ã™ã€‚\n"
+"\n"
+" 「空リビジョンã€ã‚’示ã™ãŸã‚ã®åå‰ \"null\" ã¯ã€ç‰¹åˆ¥ãªåå‰ã¨ã—ã¦äºˆç´„\n"
+" ã•れã¦ãŠã‚Šã€ãƒªãƒ“ジョン 0 ã®è¦ªã¯ \"null\" リビジョンã§ã™ã€‚\n"
+"\n"
+" 「作業領域ã®è¦ªãƒªãƒ“ジョンã€ã‚’示ã™ãŸã‚ã®åå‰ \".\" ã¯ã€ç‰¹åˆ¥ãªåå‰ã¨ã—ã¦\n"
+" 予約ã•れã¦ã„ã¾ã™ã€‚ä½œæ¥­é ˜åŸŸãŒæœªæ›´æ–°ã®å ´åˆã¯ã€\"null\" 指定ã¨ç­‰ä¾¡ã§ã™ã€‚\n"
+" 未コミットã®ãƒžãƒ¼ã‚¸ä¸­ã®å ´åˆã€\".\" ã¯ç¬¬1親リビジョンを指ã—ã¾ã™ã€‚\n"
+" "
+
+msgid "Specifying Multiple Revisions"
+msgstr "è¤‡æ•°ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æŒ‡å®š"
+
+msgid ""
+"\n"
+" When Mercurial accepts more than one revision, they may be\n"
+" specified individually, or provided as a topologically continuous\n"
+" range, separated by the \":\" character.\n"
+"\n"
+" The syntax of range notation is [BEGIN]:[END], where BEGIN and END\n"
+" are revision identifiers. Both BEGIN and END are optional. If\n"
+" BEGIN is not specified, it defaults to revision number 0. If END\n"
+" is not specified, it defaults to the tip. The range \":\" thus means\n"
+" \"all revisions\".\n"
+"\n"
+" If BEGIN is greater than END, revisions are treated in reverse\n"
+" order.\n"
+"\n"
+" A range acts as a closed interval. This means that a range of 3:5\n"
+" gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+" "
+msgstr ""
+"\n"
+" Mercurial ãŒè¤‡æ•°ã®ãƒªãƒ“ジョン指定をå—ã‘付ã‘ã‚‹å ´åˆã®æŒ‡å®šæ–¹æ³•ã¯ã€\n"
+" 個々ã®ãƒªãƒ“ジョンをãれãžã‚ŒæŒ‡å®šã™ã‚‹æ–¹æ³•以外ã«ã‚‚ã€\":\" を区切り\n"
+" 記å·ã«ã—ãŸç¯„囲指定ã«ã‚ˆã‚‹æ–¹æ³•ãŒã‚りã¾ã™ã€‚\n"
+"\n"
+" ç¯„å›²è¡¨è¨˜ã®æ–‡æ³•ã¯ã€\"[é–‹å§‹]:[終了]\" ã¨ã„ã†ã‚‚ã®ã§ã€\"é–‹å§‹\"・\"終了\"\n"
+" 部分ã«ã¯ãれãžã‚Œãƒªãƒ“ã‚¸ãƒ§ãƒ³è­˜åˆ¥ç”¨ã®æƒ…å ±ãŒè¨˜è¿°ã•れã¾ã™ã€‚\n"
+" \"é–‹å§‹\"・\"終了\" ã¯ãれãžã‚Œçœç•¥å¯èƒ½ã§ã™ã€‚\"é–‹å§‹\" 部分ãŒ\n"
+" 記述ã•れãªã„å ´åˆã€ãƒªãƒ“ã‚¸ãƒ§ãƒ³ç•ªå· 0 ãŒè¨˜è¿°ã•れãŸã‚‚ã®ã¨ã¿ãªã•れã¾ã™ã€‚\n"
+" \"終了\" 部分ãŒè¨˜è¿°ã•れãªã„å ´åˆã€tip ãŒè¨˜è¿°ã•れãŸã‚‚ã®ã¨ã¿ãªã•れã¾ã™ã€‚\n"
+" 以上ã®ã“ã¨ã‹ã‚‰ã€\":\" ã¨ã„ã†è¨˜è¿°ã¯ \"全リビジョン\" を指ã—ã¾ã™ã€‚\n"
+"\n"
+" \"é–‹å§‹\" 指定㌠\"終了\" 指定よりも後ã®ãƒªãƒ“ジョンã§ã‚ã‚‹å ´åˆã€é€†é †æŒ‡å®š\n"
+" ã¨ã¿ãªã•れã¾ã™ã€‚\n"
+"\n"
+" 範囲指定㯠\"閉区間\" ã¨ã¿ãªã•れã¾ã™ã€‚ã¤ã¾ã‚Šã€3:5 ã¨ã„ã†ç¯„囲指定ã¯\n"
+" 3, 4, 5 ã®æŒ‡å®šã¨ç­‰ä¾¡ã§ã™ã€‚åŒæ§˜ã« 9:6 ã¨ã„ã†æŒ‡å®šã¯ 9, 8, 7, 6 ã®æŒ‡å®šã¨\n"
+" 等価ã§ã™ã€‚\n"
+" "
+
+msgid "Diff Formats"
+msgstr "差分形å¼"
+
+msgid ""
+"\n"
+" Mercurial's default format for showing changes between two\n"
+" versions of a file is compatible with the unified format of GNU\n"
+" diff, which can be used by GNU patch and many other standard\n"
+" tools.\n"
+"\n"
+" While this standard format is often enough, it does not encode the\n"
+" following information:\n"
+"\n"
+" - executable status and other permission bits\n"
+" - copy or rename information\n"
+" - changes in binary files\n"
+" - creation or deletion of empty files\n"
+"\n"
+" Mercurial also supports the extended diff format from the git VCS\n"
+" which addresses these limitations. The git diff format is not\n"
+" produced by default because a few widespread tools still do not\n"
+" understand this format.\n"
+"\n"
+" This means that when generating diffs from a Mercurial repository\n"
+" (e.g. with \"hg export\"), you should be careful about things like\n"
+" file copies and renames or other things mentioned above, because\n"
+" when applying a standard diff to a different repository, this\n"
+" extra information is lost. Mercurial's internal operations (like\n"
+" push and pull) are not affected by this, because they use an\n"
+" internal binary format for communicating changes.\n"
+"\n"
+" To make Mercurial produce the git extended diff format, use the\n"
+" --git option available for many commands, or set 'git = True' in\n"
+" the [diff] section of your hgrc. You do not need to set this\n"
+" option when importing diffs in this format or using them in the mq\n"
+" extension.\n"
+" "
+msgstr ""
+"\n"
+" 無指定時㫠Mercurial ãŒ2ã¤ã®ãƒªãƒ“ジョンを比較ã—ã¦å·®åˆ†è¡¨ç¤ºã™ã‚‹éš›ã®å½¢å¼ã¯\n"
+" GNU diff ã® unified å½¢å¼äº’æ›ã®ã‚‚ã®ã§ã€GNU patch ã‚’ã¯ã˜ã‚ã¨ã™ã‚‹å¤šãã®\n"
+" 標準的ãªãƒ„ールã§ä½¿ç”¨ã§ãã‚‹ã‚‚ã®ã§ã™ã€‚\n"
+"\n"
+" ã“ã®æ¨™æº–çš„ãªå½¢å¼ã¯æ¦‚ã­å分ãªã®ã§ã™ãŒã€ä»¥ä¸‹ã®ã‚ˆã†ãªæƒ…å ±ã¯å«ã¾ã‚Œã¾ã›ã‚“:\n"
+"\n"
+" - 実行å¯å¦ãŠã‚ˆã³æ¨©é™è¨­å®š\n"
+" - è¤‡è£½ï¼æ”¹å情報\n"
+" - ãƒã‚¤ãƒŠãƒªãƒ•ァイルã®å¤‰æ›´\n"
+" - 空ファイルã®ä½œæˆï¼å‰Šé™¤\n"
+"\n"
+" Mercurial ã¯ã€åˆ¥ã®æ§‹æˆç®¡ç†ãƒ„ールã§ã‚ã‚‹ git ã«ç”±æ¥ã™ã‚‹æ‹¡å¼µå·®åˆ†å½¢å¼ã«ã‚‚\n"
+" 対応ã—ã¦ãŠã‚Šã€ã“ã®å½¢å¼ã¯å¾“æ¥ã®å·®åˆ†å½¢å¼ã®æŒã¤å…ˆã®åˆ¶é™ã‚’解消ã—ã¦ã„ã¾ã™ã€‚\n"
+" 但ã—ã€æ™®åŠã—ã¦ã„るツールã®å¹¾ã¤ã‹ãŒ git 差分形å¼ã«å¯¾å¿œã—ã¦ã„ãªã„ãŸã‚ã€\n"
+" Mercurial ã¯æŒ‡å®šãŒç„¡ã„å ´åˆã¯ã“ã®å½¢å¼ã§ã¯å‡ºåŠ›ã—ã¾ã›ã‚“。\n"
+"\n"
+" ã¤ã¾ã‚Šã€Mercurial ãŒ(\"hg export\" ç­‰ã§)生æˆã—ãŸæ¨™æº–ã®å·®åˆ†å½¢å¼ã¯ã€\n"
+" ä»–ã®ãƒªãƒã‚¸ãƒˆãƒªã«å¯¾ã—ã¦é©ç”¨ã—ãŸå ´åˆã€ä¸Šè¿°ã—ãŸæƒ…å ±ã®æ¬ è½ãŒã‚ã‚‹ã“ã¨ã‹ã‚‰ã€\n"
+" ファイルã®è¤‡è£½ãƒ»æ”¹åã‚’ã¯ã˜ã‚ã¨ã™ã‚‹ä¸Šè¨˜ã®åˆ¶é™ã«é¡žã™ã‚‹æ“作ã«é–¢ã—ã¦ã¯ã€\n"
+" å分注æ„ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚push ã‚„ pull ã®ã‚ˆã†ã«ã€Mercurial ã®\n"
+" 内部形å¼ã§å®Ÿæ–½ã•れるæ“作ã«é–¢ã—ã¦ã¯ã€ãƒã‚¤ãƒŠãƒªå½¢å¼ã§å¤‰æ›´æƒ…å ±ã®æŽˆå—を行ã†\n"
+" ã“ã¨ã‹ã‚‰ã€æƒ…å ±ã®æ¬ è½ã«é–¢ã—ã¦ã¯å¿ƒé…ã™ã‚‹å¿…è¦ã¯ã‚りã¾ã›ã‚“。\n"
+"\n"
+" Mercurial ã‹ã‚‰ git 拡張差分形å¼ã®å‡ºåŠ›ã‚’å¾—ã‚‹ã«ã¯ã€å—ç†å¯èƒ½ãªã‚³ãƒžãƒ³ãƒ‰ã«\n"
+" 対ã—㦠--git を指定ã™ã‚‹ã‹ã€è¨­å®šãƒ•ァイル㮠[diff] セクションã«\n"
+" 'git = True' 記述を追加ã—ã¦ãã ã•ã„。hg import ã‚„ mq エクステンションを\n"
+" 使用ã™ã‚‹å ´åˆã¯ã€ã“ã®æŒ‡å®šã¯ä¸è¦ã§ã™ã€‚\n"
+" "
+
+msgid "Template Usage"
+msgstr "テンプレートã®åˆ©ç”¨"
+
+msgid ""
+"\n"
+" Mercurial allows you to customize output of commands through\n"
+" templates. You can either pass in a template from the command\n"
+" line, via the --template option, or select an existing\n"
+" template-style (--style).\n"
+"\n"
+" You can customize output for any \"log-like\" command: log,\n"
+" outgoing, incoming, tip, parents, heads and glog.\n"
+"\n"
+" Three styles are packaged with Mercurial: default (the style used\n"
+" when no explicit preference is passed), compact and changelog.\n"
+" Usage:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" A template is a piece of text, with markup to invoke variable\n"
+" expansion:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings in curly braces are called keywords. The availability of\n"
+" keywords depends on the exact context of the templater. These\n"
+" keywords are usually available for templating a log-like command:\n"
+"\n"
+" - author: String. The unmodified author of the changeset.\n"
+" - branches: String. The name of the branch on which the changeset\n"
+" was committed. Will be empty if the branch name was default.\n"
+" - date: Date information. The date when the changeset was committed.\n"
+" - desc: String. The text of the changeset description.\n"
+" - diffstat: String. Statistics of changes with the following\n"
+" format: \"modified files: +added/-removed lines\"\n"
+" - files: List of strings. All files modified, added, or removed by\n"
+" this changeset.\n"
+" - file_adds: List of strings. Files added by this changeset.\n"
+" - file_mods: List of strings. Files modified by this changeset.\n"
+" - file_dels: List of strings. Files removed by this changeset.\n"
+" - node: String. The changeset identification hash, as a\n"
+" 40-character hexadecimal string.\n"
+" - parents: List of strings. The parents of the changeset.\n"
+" - rev: Integer. The repository-local changeset revision number.\n"
+" - tags: List of strings. Any tags associated with the changeset.\n"
+"\n"
+" The \"date\" keyword does not produce human-readable output. If you\n"
+" want to use a date in your output, you can use a filter to process\n"
+" it. Filters are functions which return a string based on the input\n"
+" variable. You can also use a chain of filters to get the desired\n"
+" output:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" List of filters:\n"
+"\n"
+" - addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
+" every line except the last.\n"
+" - age: Date. Returns a human-readable date/time difference between\n"
+" the given date/time and the current date/time.\n"
+" - basename: Any text. Treats the text as a path, and returns the\n"
+" last component of the path after splitting by the path\n"
+" separator (ignoring trailing separators). For example,\n"
+" \"foo/bar/baz\" becomes \"baz\" and \"foo/bar//\" becomes \"bar"
+"\".\n"
+" - stripdir: Treat the text as path and strip a directory level, if\n"
+" possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\".\n"
+" - date: Date. Returns a date in a Unix date format, including\n"
+" the timezone: \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - domain: Any text. Finds the first string that looks like an\n"
+" email address, and extracts just the domain component.\n"
+" Example: 'User <user@example.com>' becomes 'example.com'.\n"
+" - email: Any text. Extracts the first string that looks like an\n"
+" email address. Example: 'User <user@example.com>' becomes\n"
+" 'user@example.com'.\n"
+" - escape: Any text. Replaces the special XML/XHTML characters \"&\",\n"
+" \"<\" and \">\" with XML entities.\n"
+" - fill68: Any text. Wraps the text to fit in 68 columns.\n"
+" - fill76: Any text. Wraps the text to fit in 76 columns.\n"
+" - firstline: Any text. Returns the first line of text.\n"
+" - nonempty: Any text. Returns '(none)' if the string is empty.\n"
+" - hgdate: Date. Returns the date as a pair of numbers:\n"
+" \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
+" - isodate: Date. Returns the date in ISO 8601 format.\n"
+" - localdate: Date. Converts a date to local date.\n"
+" - obfuscate: Any text. Returns the input text rendered as a\n"
+" sequence of XML entities.\n"
+" - person: Any text. Returns the text before an email address.\n"
+" - rfc822date: Date. Returns a date using the same format used\n"
+" in email headers.\n"
+" - short: Changeset hash. Returns the short form of a changeset\n"
+" hash, i.e. a 12-byte hexadecimal string.\n"
+" - shortdate: Date. Returns a date like \"2006-09-18\".\n"
+" - strip: Any text. Strips all leading and trailing whitespace.\n"
+" - tabindent: Any text. Returns the text, with every line except\n"
+" the first starting with a tab character.\n"
+" - urlescape: Any text. Escapes all \"special\" characters. For\n"
+" example, \"foo bar\" becomes \"foo%20bar\".\n"
+" - user: Any text. Returns the user portion of an email address.\n"
+" "
+msgstr ""
+"\n"
+" Mercurial ã§ã¯ã€ãƒ†ãƒ³ãƒ—レート機能ã«ã‚ˆã£ã¦ã‚³ãƒžãƒ³ãƒ‰ã®å‡ºåŠ›ã‚’ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚º\n"
+" ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚コマンドラインã‹ã‚‰ã®æŒ‡å®šã§ã¯ã€--template ã«ã‚ˆã‚‹\n"
+" テンプレート指定ã¨ã€--style ã«ã‚ˆã‚‹ã‚¹ã‚¿ã‚¤ãƒ«æŒ‡å®šã®ä¸¡æ–¹ãŒä½¿ç”¨ã§ãã¾ã™ã€‚\n"
+"\n"
+" 「log çš„ã€ãªå‡ºåŠ›ã‚’è¡Œã†ä»¥ä¸‹ã®ã‚³ãƒžãƒ³ãƒ‰ã®å‡ºåŠ›ã‚’ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºå¯èƒ½ã§ã™:\n"
+" log, outgoing, incoming, tip, parents, heads, glog\n"
+"\n"
+" Mercurial ã«ã¯(æ˜Žç¤ºçš„ãªæŒ‡å®šãŒç„¡ã„å ´åˆã«ä½¿ç”¨ã•れる)defaultã€compact\n"
+" ãŠã‚ˆã³ changelog ã®3ã¤ã®ã‚¹ã‚¿ã‚¤ãƒ«è¨­å®šãŒåŒæ¢±ã•れã¦ã„ã¾ã™ã€‚利用方法ã¯:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" テンプレートã¨ã¯ã€å¤‰æ•°å±•開マークアップ機能を備ãˆãŸãƒ†ã‚­ã‚¹ãƒˆã§ã™ã€‚\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" 波括弧ã§å›²ã¾ã‚ŒãŸéƒ¨åˆ†ã¯ã€Œã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã€ã¨å‘¼ã°ã‚Œã¾ã™ã€‚キーワード利用ã®\n"
+" å¯å¦ã¯ã€ãƒ†ãƒ³ãƒ—レートã®åˆ©ç”¨ã•れる状æ³ã«ä¾å­˜ã—ã¾ã™ã€‚以下ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã¯\n"
+" log çš„ãªã‚³ãƒžãƒ³ãƒ‰ã§ã®ãƒ†ãƒ³ãƒ—レート利用ã®éš›ã«ã¯å¸¸ã«ä½¿ç”¨å¯èƒ½ã§ã™ã€‚\n"
+"\n"
+" - author: 文字列。リビジョンã®ä½œè€…å(記録情報ãã®ã¾ã¾)。\n"
+" - branches: 文字列。リビジョンã®å±žã™ã‚‹ãƒ–ランãƒå。所属ブランãƒãŒ\n"
+" default ã®å ´åˆã¯ç©ºæ–‡å­—列。\n"
+" - date: 日時情報。リビジョンãŒè¨˜éŒ²ã•ã‚ŒãŸæ—¥æ™‚。\n"
+" - desc: 文字列。リビジョンã®ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€‚\n"
+" - diffstat: 文字列。以下ã®å½¢å¼ã§ã®å¤‰æ›´æ¦‚è¦ã€‚\n"
+" \"変更対象ファイル: +追加行数/-削除行数\"\n"
+" - files: 文字列列挙。当該リビジョンã§ã®ã€å¤‰æ›´ï¼è¿½åŠ ç™»éŒ²ãªã„ã—\n"
+" 登録除外ファイルã®ä¸€è¦§ã€‚\n"
+" - file_adds: 文字列列挙。当該リビジョンã§ã®è¿½åŠ ãƒ•ã‚¡ã‚¤ãƒ«ä¸€è¦§ã€‚\n"
+" - file_mods: 文字列列挙。当該リビジョンã§ã®å¤‰æ›´ãƒ•ァイル一覧。\n"
+" - file_dels: 文字列列挙。当該リビジョンã§ã®ç™»éŒ²é™¤å¤–ファイル一覧。\n"
+" - node: 文字列。リビジョン識別用㮠40 æ¡ 16 進数ãƒãƒƒã‚·ãƒ¥å€¤ã€‚\n"
+" - parents: 文字列列挙。リビジョンã®è¦ªã€‚\n"
+" - rev: 整数。å„リãƒã‚¸ãƒˆãƒªå›ºæœ‰ã®ãƒªãƒ“ジョン番å·ã€‚\n"
+" - tags: 文字列列挙。当該リビジョンã«ä»˜ä¸Žã•れãŸã‚¿ã‚°ã®ä¸€è¦§ã€‚\n"
+"\n"
+" \"date\" キーワードã®å‡ºåŠ›ã¯å¯èª­å½¢å¼ã§ã¯ã‚りã¾ã›ã‚“ã€‚å‡ºåŠ›ã«æ—¥æ™‚情報を\n"
+" å«ã‚ãŸã„å ´åˆã€å¯èª­åŒ–ã™ã‚‹ãŸã‚ã«ã€Œãƒ•ィルターã€ã‚’使用ã—ã¾ã™ã€‚\n"
+" 「フィルターã€ã¨ã¯ã€æŒ‡å®šå€¤ã«åŸºã¥ã„ã¦æ–‡å­—列を生æˆã™ã‚‹æ©Ÿèƒ½ã§ã™ã€‚複数ã®\n"
+" フィルターを連ã­ã‚‹ã“ã¨ã§ã€æ§˜ã€…ãªå‡ºåŠ›ã‚’å¾—ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" フィルター一覧(入力ã¨ã€ãれã«å¯¾ã™ã‚‹å‡ºåŠ›):\n"
+"\n"
+" - addbreaks: 文字列。最終行を除ãå„行ã®è¡Œæœ«ã« XHTML ã® \n"
+" \"<br />\" タグを追加ã—ã¾ã™ã€‚\n"
+" - age: 日時情報。与ãˆã‚‰ã‚ŒãŸæ—¥æ™‚ã¨ã€ç¾åœ¨æ—¥æ™‚ã¨ã®å·®åˆ†ã‚’表ã™\n"
+" å¯èª­å½¢å¼ã®æ–‡å­—列を生æˆã—ã¾ã™ã€‚\n"
+" - basename: 文字列。与ãˆã‚‰ã‚ŒãŸæ–‡å­—列をパスã¨ã¿ãªã—ã€ãƒ‘ス区切りã§\n"
+" åŒºåˆ‡ã‚‰ã‚ŒãŸæœ€å¾Œã®è¦ç´ ã ã‘ã‚’å–り出ã—ã¾ã™(末尾パス\n"
+" 区切りã¯ç„¡è¦–ã•れã¾ã™)。例ãˆã°ã€\"foo/bar/baz\" ã¯\n"
+" \"baz\" ã«ã€\"foo/bar//\" 㯠\"bar\" ã«ãªã‚Šã¾ã™ã€‚\n"
+" - stripdir: 文字列。与ãˆã‚‰ã‚ŒãŸæ–‡å­—列をパスã¨ã¿ãªã—ã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n"
+" è¦ç´ ãŒã‚れã°ãれをå–り除ãã¾ã™ã€‚例ãˆã°ã€\"foo\"\n"
+" ãŠã‚ˆã³ \"foo/bar\" 㯠\"foo\" ã¨ãªã‚Šã¾ã™ã€‚\n"
+" - date: 日時情報。タイムゾーンをå«ã‚“ã ã€Unix ã® date コマンド\n"
+" å½¢å¼ã§å¯èª­åŒ–ã—ã¾ã™: \"Mon Sep 04 15:13:13 2006 0700\"\n"
+" - domain: æ–‡å­—åˆ—ã€‚ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨æ€ã—ãæœ€åˆã®æ–‡å­—列部分ã‹ã‚‰\n"
+" ドメイン部分ã ã‘ã‚’å–り出ã—ã¾ã™ã€‚例ãˆã°ã€\n"
+" 'User <user@example.com>' 㯠'example.com' ã§ã™ã€‚\n"
+" - email: æ–‡å­—åˆ—ã€‚ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨æ€ã—ãæœ€åˆã®éƒ¨åˆ†ã‚’å–り出ã—ã¾ã™ã€‚\n"
+" 例ãˆã° 'User <user@example.com>' ã¯\n"
+" 'user@example.com' ã¨ãªã‚Šã¾ã™ã€‚\n"
+" - escape: 文字列。XML/XHTML ã®ç‰¹æ®Šæ–‡å­—ã§ã‚ã‚‹ \"&\"ã€\"<\" ãŠã‚ˆã³\n"
+" \">\" ã‚’ XML ã®ã‚¨ãƒ³ãƒ†ã‚£ãƒ†ã‚£å½¢å¼ã«å¤‰æ›ã—ã¾ã™ã€‚\n"
+" - fill68: 文字列。68 æ¡ã«åŽã¾ã‚‹ã‚ˆã†ã«æ–‡å­—列を折り返ã—ã¾ã™ã€‚\n"
+" - fill76: 文字列。76 æ¡ã«åŽã¾ã‚‹ã‚ˆã†ã«æ–‡å­—列を折り返ã—ã¾ã™ã€‚\n"
+" - firstline: 文字列。最åˆã®è¡Œã®ã¿ã‚’å–り出ã—ã¾ã™ã€‚\n"
+" - nonempty: 文字列。与ãˆã‚‰ã‚ŒãŸæ–‡å­—列ãŒç©ºã®å ´åˆ '(none)'ã¨ãªã‚Šã¾ã™ã€‚\n"
+" - hgdate: 日時情報。Unix タイムスタンプã¨ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã‚ªãƒ•セット\n"
+" ã«ã‚ˆã‚‹æ•°å€¤å¯¾å½¢å¼ã§å¯èª­åŒ–ã—ã¾ã™: \"1157407993 25200\"\n"
+" - isodate: 日時情報。ISO 8601 å½¢å¼ã§å¯èª­åŒ–ã—ã¾ã™ã€‚\n"
+" - localdate: 日時情報。ローカル日時ã§å¯èª­åŒ–ã—ã¾ã™ã€‚\n"
+" - obfuscate: 文字列。全ã¦ã®æ–‡å­—ã‚’ XML エンティティ形å¼ã«å¤‰æ›ã—ã¾ã™ã€‚\n"
+" - person: 文字列。メールアドレス直å‰ã®éƒ¨åˆ†ã ã‘ã‚’å–り出ã—ã¾ã™ã€‚\n"
+" - rfc822date:日時情報。メールã®ãƒ˜ãƒƒãƒ€ã¨åŒå½¢å¼ã§å¯èª­åŒ–ã—ã¾ã™ã€‚\n"
+" - short: リビジョンãƒãƒƒã‚·ãƒ¥ 値。12 æ¡ç¨‹åº¦ã®çŸ­ç¸®å½¢å¼ã«ã—ã¾ã™ã€‚\n"
+" - shortdate: 日時情報。\"2006-09-18\" å½¢å¼ã§å¯èª­åŒ–ã—ã¾ã™ã€‚\n"
+" - strip: æ–‡å­—åˆ—ã€‚å…ˆé ­ï¼æœ«å°¾ã®ç©ºç™½æ–‡å­—ã‚’å–り除ãã¾ã™ã€‚\n"
+" - tabindent: 文字列。先頭行以外をタブ文字ã§å­—下ã’ã—ã¾ã™ã€‚\n"
+" - urlescape: 文字列。全ã¦ã®ã€Œç‰¹æ®Šã€æ–‡å­—を変æ›ã—ã¾ã™ã€‚\n"
+" 例ãˆã° \"foo bar\" 㯠\"foo%20bar\" ã¨ãªã‚Šã¾ã™ã€‚\n"
+" - user: 文字列。メールアドレスã®ãƒ¦ãƒ¼ã‚¶å部分をå–り出ã—ã¾ã™ã€‚\n"
+" "
+
+msgid "URL Paths"
+msgstr "URLã®ãƒ‘ス指定"
+
+msgid ""
+"\n"
+" Valid URLs are of the form:\n"
+"\n"
+" local/filesystem/path (or file://local/filesystem/path)\n"
+" http://[user[:pass]@]host[:port]/[path]\n"
+" https://[user[:pass]@]host[:port]/[path]\n"
+" ssh://[user[:pass]@]host[:port]/[path]\n"
+"\n"
+" Paths in the local filesystem can either point to Mercurial\n"
+" repositories or to bundle files (as created by 'hg bundle' or\n"
+" 'hg incoming --bundle').\n"
+"\n"
+" An optional identifier after # indicates a particular branch, tag,\n"
+" or changeset to use from the remote repository.\n"
+"\n"
+" Some features, such as pushing to http:// and https:// URLs are\n"
+" only possible if the feature is explicitly enabled on the remote\n"
+" Mercurial server.\n"
+"\n"
+" Some notes about using SSH with Mercurial:\n"
+" - SSH requires an accessible shell account on the destination\n"
+" machine and a copy of hg in the remote path or specified with as\n"
+" remotecmd.\n"
+" - path is relative to the remote user's home directory by default.\n"
+" Use an extra slash at the start of a path to specify an absolute "
+"path:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial doesn't use its own compression via SSH; the right\n"
+" thing to do is to configure it in your ~/.ssh/config, e.g.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternatively specify \"ssh -C\" as your ssh command in your hgrc\n"
+" or with the --ssh command line option.\n"
+"\n"
+" These URLs can all be stored in your hgrc with path aliases under\n"
+" the [paths] section like so:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" You can then use the alias for any command that uses a URL (for\n"
+" example 'hg pull alias1' would pull from the 'alias1' path).\n"
+"\n"
+" Two path aliases are special because they are used as defaults\n"
+" when you do not provide the URL to a command:\n"
+"\n"
+" default:\n"
+" When you create a repository with hg clone, the clone command\n"
+" saves the location of the source repository as the new\n"
+" repository's 'default' path. This is then used when you omit\n"
+" path from push- and pull-like commands (including incoming and\n"
+" outgoing).\n"
+"\n"
+" default-push:\n"
+" The push command will look for a path named 'default-push', and\n"
+" prefer it over 'default' if both are defined.\n"
+" "
+msgstr ""
+"\n"
+" 有効㪠URL 指定ã¯ä»¥ä¸‹ã®å½¢å¼ã§ã™:\n"
+"\n"
+" local/filesystem/path (ãªã„ã— file://local/filesystem/path)\n"
+" http://[user[:pass]@]host[:port]/[path]\n"
+" https://[user[:pass]@]host[:port]/[path]\n"
+" ssh://[user[:pass]@]host[:port]/[path]\n"
+"\n"
+" ローカルファイルシステム上ã®ãƒ‘ã‚¹ãŒæŒ‡ã™å…ˆã¯ Mercurial ã®ãƒªãƒã‚¸ãƒˆãƒªã§ã‚‚ã€\n"
+" ãƒãƒ³ãƒ‰ãƒ«ãƒ•ァイル('hg bundle' ãªã„ã— 'hg incoming --bundle' ã§ç”Ÿæˆ)ã§ã‚‚\n"
+" æ§‹ã„ã¾ã›ã‚“。\n"
+"\n"
+" é éš”ホスト上ã®é€£æºå…ˆãƒªãƒã‚¸ãƒˆãƒªæŒ‡å®šã®å ´åˆã€'#' 記å·ã«ç¶šã‘ã¦è­˜åˆ¥å­ã‚’指定\n"
+" ã™ã‚‹ã“ã¨ã§ã€ç‰¹å®šã®ãƒ–ランãƒã€ã‚¿ã‚°ãªã„ã—ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’指定ã™ã‚‹ã“ã¨ãŒ\n"
+" 出æ¥ã¾ã™ã€‚\n"
+"\n"
+" http:// ã‚„ https:// å½¢å¼ã® URL ã§æŒ‡å®šã•れる連æºå…ˆã¸ã® push ã®æ§˜ãª\n"
+" 機能ã®ã†ã¡ã®å¹¾ã¤ã‹ã¯ã€ãã®æ©Ÿèƒ½ãŒé€£æºå…ˆã® Mercurial サーãƒå´ã§æ˜Žç¤ºçš„ã«\n"
+" 利用å¯èƒ½ã«ãªã£ã¦ã„ã‚‹å ´åˆã«é™ã‚Šä½¿ç”¨å¯èƒ½ã§ã™ã€‚\n"
+"\n"
+" Mercurial 㨠SSH を併用ã™ã‚‹å ´åˆã®æ³¨æ„点:\n"
+" - SSH アクセス先ホスト上ã«ã€shell アカウント㨠hg コマンドãŒå¿…è¦ã§ã™ã€‚\n"
+" hg コマンドãŒã‚¢ã‚¯ã‚»ã‚¹å…ˆãƒ›ã‚¹ãƒˆã® PATH 設定ã§åˆ©ç”¨å¯èƒ½ã«ãªã£ã¦ã„ãªã„\n"
+" å ´åˆã¯ã€--remotecmd ã§æ˜Žç¤ºçš„ã«æŒ‡å®šã—ã¦ãã ã•ã„。\n"
+" - URL 中ã®ãƒ‘ス指定ã¯ã€ã‚¢ã‚¯ã‚»ã‚¹å…ˆãƒ›ã‚¹ãƒˆä¸Šã®ãƒ¦ãƒ¼ã‚¶ã®ãƒ›ãƒ¼ãƒ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n"
+" ã‹ã‚‰ã®ç›¸å¯¾ãƒ‘スã¨ã¿ãªã•れã¾ã™ã€‚絶対パスを指定ã™ã‚‹å ´åˆã¯ã€ãƒ‘スã®å…ˆé ­ã«\n"
+" æ›´ã«ã‚¹ãƒ©ãƒƒã‚·ãƒ¥('/')を付与ã—ã¦ãã ã•ã„。\n"
+" 例: ssh://example.com//tmp/repository\n"
+" - SSH 連æºã®éš›ã«ã¯ Mercurial ã¯è‡ªèº«ã®åœ§ç¸®å‡¦ç†ã‚’行ã„ã¾ã›ã‚“。以下ã®ã‚ˆã†ã«\n"
+" ~/.ssh/config 等㧠SSH ã®åœ§ç¸®å®Ÿæ–½ã‚’指示ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" ã‚ã‚‹ã„ã¯ã€è¨­å®šãƒ•ァイルã«ãŠã‘ã‚‹ ssh コマンド指定やã€ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã§ã®\n"
+" --ssh ã«å¯¾ã—ã¦ã€'ssh -C' を指定ã™ã‚‹æ–¹æ³•ã‚‚ã‚りã¾ã™ã€‚\n"
+"\n"
+" 連æºå…ˆ URL ã¯ã€è¨­å®šãƒ•ァイル㮠[paths] セクションã§ã€åˆ¥åを付ã‘ã¦è¨˜è¿°\n"
+" ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" URL 指定ãŒå¿…è¦ãªã‚³ãƒžãƒ³ãƒ‰ã«å¯¾ã—ã¦ã¯ã€åˆ¥åを指定ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™\n"
+" (例ãˆã°ã€'hg pull alias1' 㯠alias1 ã®æŒ‡ã™å…ˆã‹ã‚‰å¤‰æ›´ã‚’å–り込ã¿ã¾ã™)。\n"
+"\n"
+" コマンド㫠URL を指定ã—ãªã‹ã£ãŸå ´åˆã«ã€æš—é»™ã®é€£æºå…ˆã¨ã—ã¦ä½¿ç”¨ã•れる\n"
+" é‡è¦ãªåˆ¥åãŒ2ã¤ã‚りã¾ã™ã€‚\n"
+"\n"
+" default:\n"
+" 'hg clone' ã«ã‚ˆã£ã¦è¤‡è£½ã—ãŸå ´åˆã€æ–°è¦ãƒªãƒã‚¸ãƒˆãƒªã® 'default' ã¨ã—ã¦\n"
+" 複製元リãƒã‚¸ãƒˆãƒªã® URL ãŒä¿å­˜ã•れã¾ã™ã€‚\n"
+" 以後ã€é€£æºå…ˆã‚’çœç•¥ã—㦠'hg push' ã‚„ 'hg pull' ã«é¡žã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã‚’\n"
+" 実行ã—ãŸéš›ã«ã¯ã€ã“ã® URL ãŒé€£æºå…ˆã¨ã—ã¦ä½¿ç”¨ã•れã¾ã™ã€‚\n"
+"\n"
+" default-push:\n"
+" 'hg push' ã¯ã€'default-push' ã®åˆ¥åã§å®šç¾©ã•れる URL を探ã—ã¾ã™ã€‚\n"
+" 'default' ãŒå®šç¾©ã•れã¦ã„ã‚‹å ´åˆã§ã‚‚ã€'default-push' ãŒå®šç¾©ã•れã¦ã„れã°\n"
+" ã“ã¡ã‚‰ãŒå„ªå…ˆã•れã¾ã™ã€‚\n"
+" "
+
+msgid "Using additional features"
+msgstr "付加機能ã®ä½¿ç”¨"
+
+msgid "can only share local repositories"
+msgstr "共有å¯èƒ½ãªã®ã¯ãƒ­ãƒ¼ã‚«ãƒ«ãƒªãƒã‚¸ãƒˆãƒªã®ã¿ã§ã™"
+
+msgid "destination already exists"
+msgstr "複製先 '%s' ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
+
+msgid "updating working directory\n"
+msgstr "ä½œæ¥­é ˜åŸŸã®æ›´æ–°ä¸­\n"
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr "複製先ディレクトリ: %s\n"
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr "複製先 '%s' ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
+
+#, python-format
+msgid "destination '%s' is not empty"
+msgstr "複製先 '%s' ã¯ç©ºã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr "指定ã®è¤‡è£½å…ƒã§ã¯ã€ãƒªãƒ“ジョン指定付ãã§ã®è¤‡è£½ãŒã§ãã¾ã›ã‚“"
+
+msgid "clone from remote to remote not supported"
+msgstr "リモートã‹ã‚‰ãƒªãƒ¢ãƒ¼ãƒˆã®è¤‡è£½ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“"
+
+msgid "updated"
+msgstr "æ›´æ–°"
+
+msgid "merged"
+msgstr "マージ"
+
+msgid "removed"
+msgstr "削除"
+
+msgid "unresolved"
+msgstr "è¡çªæœªè§£æ±º"
+
+#, python-format
+msgid "%d files %s"
+msgstr "%d 個ã®ãƒ•ァイルãŒ%s"
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr "'hg resolve' ã§ãƒžãƒ¼ã‚¸ã®è¡çªã‚’解消ã—ã¦ãã ã•ã„\n"
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to "
+"abandon\n"
+msgstr "'hg resolve' ã§å†åº¦è¡çªè§£æ¶ˆã™ã‚‹ã‹ã€'hg up --clean' ã§å¤‰æ›´ç ´æ£„を。\n"
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr "(ãƒžãƒ¼ã‚¸çµæžœã® commit を忘れãšã«)\n"
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr "%s/.hg/hgrc ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—: %s\n"
+
+msgid "SSL support is unavailable"
+msgstr "SSL サãƒãƒ¼ãƒˆãŒåˆ©ç”¨ã§ãã¾ã›ã‚“"
+
+msgid "IPv6 is not available on this system"
+msgstr "ã“ã®ã‚·ã‚¹ãƒ†ãƒ ã§ã¯ IPv6 を利用ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr "'%s:%d' ã§ã®ã‚µãƒ¼ãƒèµ·å‹•ã«å¤±æ•—: %s"
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr "フック %s:%s 呼ã³å‡ºã—中\n"
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr "フック %s ã¯ä¸æ­£ã§ã™(モジュール中㫠\"%s\" ãŒã‚りã¾ã›ã‚“)"
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr "フック %s ã¯ä¸æ­£ã§ã™(\"%s\" ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—)"
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr "フック %s ã¯ä¸æ­£ã§ã™(\"%s\" ã¯æœªå®šç¾©ã§ã™)"
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr "フック %s ã¯ä¸æ­£ã§ã™(\"%s\" ã¯å‘¼ã³å‡ºã—å¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“)"
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr "エラー: フック %s ã®å¤±æ•—: %s\n"
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr "エラー: フック %s ã«ã‚ˆã‚‹ä¾‹å¤–æµ®æš: %s\n"
+
+#, python-format
+msgid "%s hook failed"
+msgstr "フック %s ã®å¤±æ•—"
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr "警告: フック %s ã®å¤±æ•—\n"
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr "フック %s: %s ã®å®Ÿè¡Œä¸­\n"
+
+#, python-format
+msgid "%s hook %s"
+msgstr "%s フック %s"
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr "警告: %s フック %s\n"
+
+msgid "connection ended unexpectedly"
+msgstr "予期ã›ã¬æŽ¥ç¶šçµ‚了"
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr "URL è¦ç´  \"%s\" ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+
+#, python-format
+msgid "using %s\n"
+msgstr "%s を用ã„ã¾ã™\n"
+
+#, python-format
+msgid "capabilities: %s\n"
+msgstr "機能: %s\n"
+
+msgid "operation not supported over http"
+msgstr "http リãƒã‚¸ãƒˆãƒªã§ã¯ä½¿ç”¨ã§ããªã„機能を必è¦ã¨ã—ã¦ã„ã¾ã™"
+
+#, python-format
+msgid "sending %s command\n"
+msgstr "コマンド %s é€ä¿¡ä¸­\n"
+
+#, python-format
+msgid "sending %s bytes\n"
+msgstr "%s ãƒã‚¤ãƒˆã®ãƒ‡ãƒ¼ã‚¿é€ä¿¡ä¸­\n"
+
+msgid "authorization failed"
+msgstr "èªè¨¼ã«å¤±æ•—"
+
+#, python-format
+msgid "http error while sending %s command\n"
+msgstr "コマンド %s é€ä¿¡ä¸­ã® HTTP エラー\n"
+
+msgid "http error, possibly caused by proxy setting"
+msgstr "HTTP エラー(ãŠãらãプロキシー設定ã«èµ·å› )"
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr "実際㮠URL: %s\n"
+
+#, python-format
+msgid "requested URL: '%s'\n"
+msgstr "è¦æ±‚ URL: '%s'\n"
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr "'%s' 㯠Mercurial リãƒã‚¸ãƒˆãƒªå½¢å¼ã¨ã¯æ€ã‚れã¾ã›ã‚“"
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr "'%s' ã¯å£Šã‚ŒãŸ Content-Type ヘッダ(%s)ã‚’é€ä¿¡ã—ã¾ã—ãŸ"
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr "'%s' ã¯æ–°ã—ã„プロトコル %s を使ã„ã¾ã™"
+
+msgid "look up remote revision"
+msgstr "連æºå…ˆã§ã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã®æ¤œç´¢"
+
+msgid "unexpected response:"
+msgstr "未知ã®å¿œç­”:"
+
+msgid "look up remote changes"
+msgstr "連æºå…ˆã§ã®å¤‰æ›´ã®æ¤œç´¢"
+
+msgid "push failed (unexpected response):"
+msgstr "å±¥æ­´åæ˜ ã«å¤±æ•—(未知ã®ãƒ¬ã‚¹ãƒãƒ³ã‚¹):"
+
+#, python-format
+msgid "push failed: %s"
+msgstr "å±¥æ­´åæ˜ ã«å¤±æ•—: %s"
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr "SSL 㨠HTTPS をサãƒãƒ¼ãƒˆã—㟠Python ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "cannot create new http repository"
+msgstr "http リãƒã‚¸ãƒˆãƒªã®æ–°è¦ä½œæˆã¯ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "%s: ignoring invalid syntax '%s'\n"
+msgstr "%s: æ–‡æ³•ä¸æ­£ã® '%s' を無視ã—ã¾ã™\n"
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr "読込ä¸å¯ã® ignore ファイル '%s' をスキップã—ã¾ã™: %s\n"
+
+#, python-format
+msgid "repository %s not found"
+msgstr "リãƒã‚¸ãƒˆãƒª '%s' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, python-format
+msgid "repository %s already exists"
+msgstr "%sã¨ã„ã†ãƒªãƒã‚¸ãƒˆãƒªã¯æ—¢ã«å­˜åœ¨ã—ã¦ã„ã¾ã™"
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr "必須機能 '%s' ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+
+#, python-format
+msgid ".hg/sharedpath points to nonexistent directory %s"
+msgstr ".hg/sharedpath ã®å‚ç…§å…ˆ %s ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr "%r ã¯ã‚¿ã‚°åã«ä½¿ç”¨ã§ãã¾ã›ã‚“"
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr "作業領域㮠.hgtags ãŒå¤‰æ›´ã•れã¦ã„ã¾ã™ï¼ˆæ‰‹å‹•ã§ã‚³ãƒŸãƒƒãƒˆã—ã¦ãã ã•ã„)"
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr "%s %s行目: %s\n"
+
+msgid "cannot parse entry"
+msgstr "エントリを読ã¿è¾¼ã‚ã¾ã›ã‚“"
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr "'%s' ã¨ã„ã†ãƒŽãƒ¼ãƒ‰ã¯ãƒ•ォーマットãŒä¸é©åˆ‡ã§ã™"
+
+#, python-format
+msgid "working directory has unknown parent '%s'!"
+msgstr "作業領域ã®è¦ª '%s' ãŒæœªçŸ¥ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™!"
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr "'%s' ã¯æœªçŸ¥ã®ãƒªãƒ“ジョンã§ã™"
+
+#, python-format
+msgid "filtering %s through %s\n"
+msgstr "%s ã‚’ %s ã§å‡¦ç†ä¸­\n"
+
+msgid "journal already exists - run hg recover"
+msgstr "ã‚¸ãƒ£ãƒ¼ãƒŠãƒ«ãŒæ—¢ã«å­˜åœ¨ã—ã¦ã„ã¾ã™ã€‚ hg recoverを実行ã—ã¦ãã ã•ã„"
+
+msgid "rolling back interrupted transaction\n"
+msgstr "中断ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ロールãƒãƒƒã‚¯ã—ã¦ã„ã¾ã™\n"
+
+msgid "no interrupted transaction available\n"
+msgstr "中断ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ã‚りã¾ã›ã‚“\n"
+
+msgid "rolling back last transaction\n"
+msgstr "最新ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ロールãƒãƒƒã‚¯ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "Named branch could not be reset, current branch still is: %s\n"
+msgstr "åå‰ã¤ãブランãƒã¯ãƒªã‚»ãƒƒãƒˆã§ãã¾ã›ã‚“ã®ã§ã€%s ã®ã¾ã¾ã§ã™\n"
+
+msgid "no rollback information available\n"
+msgstr "利用å¯èƒ½ãªãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯æƒ…å ±ãŒã‚りã¾ã›ã‚“\n"
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr "%s ã®ãƒ­ãƒƒã‚¯ (%rãŒä¿æŒ) ã®è§£æ”¾ã‚’å¾…ã£ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "repository %s"
+msgstr "リãƒã‚¸ãƒˆãƒª '%s'"
+
+#, python-format
+msgid "working directory of %s"
+msgstr "%s ã®ä½œæ¥­é ˜åŸŸ"
+
+#, python-format
+msgid " %s: searching for copy revision for %s\n"
+msgstr "%s: コピー時点㮠%s を検索中\n"
+
+#, python-format
+msgid " %s: copy %s:%s\n"
+msgstr "%s: コピー %s:%s\n"
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr "マージã®éƒ¨åˆ†ã‚³ãƒŸãƒƒãƒˆã¯ã§ãã¾ã›ã‚“(ファイルåï¼ãƒ‘ã‚¿ãƒ¼ãƒ³ã¯æŒ‡å®šã§ãã¾ã›ã‚“)"
+
+msgid "file not found!"
+msgstr "ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“!"
+
+msgid "no match under directory!"
+msgstr "ディレクトé…下ã«ä¸€è‡´ã™ã‚‹ã‚‚ã®ãŒã‚りã¾ã›ã‚“!"
+
+msgid "file not tracked!"
+msgstr "ãƒ•ã‚¡ã‚¤ãƒ«ã¯æœªç™»éŒ²ã§ã™!"
+
+msgid "nothing changed\n"
+msgstr "変更ãªã—\n"
+
+msgid "unresolved merge conflicts (see hg resolve)"
+msgstr "未解決ã®è¡çªãŒæ®‹ã£ã¦ã„ã¾ã™ (hg resolveã‚’å‚ç…§ã—ã¦ãã ã•ã„)"
+
+#, python-format
+msgid "committing subrepository %s\n"
+msgstr "副リãƒã‚¸ãƒˆãƒª %s ã§ã®ã‚³ãƒŸãƒƒãƒˆä¸­\n"
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr "%s ã®ã‚³ãƒŸãƒƒãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ!\n"
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr "%s ã¯ã‚りã¾ã›ã‚“!\n"
+
+#, python-format
+msgid ""
+"%s: files over 10MB may cause memory and performance problems\n"
+"(use 'hg revert %s' to unadd the file)\n"
+msgstr ""
+"%s: 10MBã‚’è¶…ãˆã‚‹ãƒ•ァイルã¯ãƒ¡ãƒ¢ãƒªã‚„性能ã®å•題è¦å› ã¨ãªã‚Šå¾—ã¾ã™\n"
+"(ファイルã®ç™»éŒ²ã‚’解除ã™ã‚‹ã«ã¯ 'hg revert %s')\n"
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr "%s ã¯è¿½åŠ ç™»éŒ²ã•れã¾ã›ã‚“: ファイルã¨ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ã®ã¿ç™»éŒ²å¯èƒ½\n"
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr "%s ã¯ç™»éŒ²æ¸ˆã§ã™!\n"
+
+#, python-format
+msgid "%s not added!\n"
+msgstr "%s ã¯è¿½åŠ ç™»éŒ²ã•れã¾ã›ã‚“\n"
+
+#, python-format
+msgid "%s still exists!\n"
+msgstr "%s ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ!\n"
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr "%s ã¯ç®¡ç†ã•れã¦ã„ã¾ã›ã‚“!\n"
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr "%s ã¯å‰Šé™¤ã•れã¾ã›ã‚“ã§ã—ãŸ!\n"
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr "コピー失敗: %s ã¯ãƒ•ァイルã§ã‚‚シンボリックリンクã§ã‚‚ã‚りã¾ã›ã‚“\n"
+
+msgid "searching for changes\n"
+msgstr "変更点を探索中\n"
+
+#, python-format
+msgid "examining %s:%s\n"
+msgstr "%s:%s ã‚’ãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™\n"
+
+msgid "branch already found\n"
+msgstr "ブランãƒã¯ã™ã§ã«è¦‹ã¤ã‹ã£ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "found incomplete branch %s:%s\n"
+msgstr "ä¸å®Œå…¨ãªãƒ–ランãƒ: %s:%s\n"
+
+#, python-format
+msgid "found new changeset %s\n"
+msgstr "æ–°ã—ã„ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ '%s' を発見\n"
+
+#, python-format
+msgid "request %d: %s\n"
+msgstr "リクエスト %d: %s\n"
+
+#, python-format
+msgid "received %s:%s\n"
+msgstr "%s:%s ã‚’å—ä¿¡\n"
+
+#, python-format
+msgid "narrowing %d:%d %s\n"
+msgstr "%d:%d %s を探索中\n"
+
+#, python-format
+msgid "found new branch changeset %s\n"
+msgstr "æ–°ã—ã„ブランãƒã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ %s を発見\n"
+
+#, python-format
+msgid "narrowed branch search to %s:%s\n"
+msgstr "ブランãƒã®æŽ¢ç´¢ã‚’ %s:%s ã¸çµžã‚Šã¾ã—ãŸ\n"
+
+msgid "already have changeset "
+msgstr "æ—¢ã«ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆãŒã‚りã¾ã™ "
+
+msgid "warning: repository is unrelated\n"
+msgstr "警告: 無関係ãªãƒªãƒã‚¸ãƒˆãƒªã§ã™\n"
+
+msgid "repository is unrelated"
+msgstr "無関係ãªãƒªãƒã‚¸ãƒˆãƒªã§ã™"
+
+msgid "found new changesets starting at "
+msgstr "以下を起点ã¨ã™ã‚‹æ–°è¦å¤‰æ›´ã®æ¤œå‡º: "
+
+#, python-format
+msgid "%d total queries\n"
+msgstr "åˆè¨ˆ %d ã®ã‚¯ã‚¨ãƒª\n"
+
+msgid "common changesets up to "
+msgstr "以下を終点ã¨ã™ã‚‹å…±é€šå±¥æ­´: "
+
+msgid "requesting all changes\n"
+msgstr "å…¨ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’å–得中\n"
+
+msgid ""
+"Partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr "連æºå…ˆã® changegroupsubset 機能未対応ã«ã‚ˆã‚Šã€éƒ¨åˆ†å–り込ã¿ã§ãã¾ã›ã‚“。"
+
+#, python-format
+msgid "abort: push creates new remote branch '%s'!\n"
+msgstr "中断: åæ˜ ã«ã‚ˆã£ã¦é€£æºå…ˆã«æ–°ã—ã„ブランム'%s' ãŒä½œæˆã•れã¾ã™!\n"
+
+msgid "abort: push creates new remote heads!\n"
+msgstr "中断: åæ˜ ã«ã‚ˆã£ã¦é€£æºå…ˆã«æ–°ã—ã„ヘッドãŒä½œæˆã•れã¾ã™!\n"
+
+msgid "(did you forget to merge? use push -f to force)\n"
+msgstr "(ãƒžãƒ¼ã‚¸ã¯æ¸ˆã‚“ã§ã„ã¾ã™ã‹? push -f ã§å¼·åˆ¶å®Ÿè¡Œã§ãã¾ã™)\n"
+
+msgid "note: unsynced remote changes!\n"
+msgstr "注æ„: 連æºå…ˆã§ã®å¤‰æ›´ç‚¹ãŒå–り込ã¾ã‚Œã¦ã„ã¾ã›ã‚“!\n"
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr "%d 個ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ\n"
+
+msgid "list of changesets:\n"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆä¸€è¦§ï¼š\n"
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr "%s ã«å¯¾ã™ã‚‹ãƒªãƒ“ジョンログãŒç©ºãªã„ã—ä¸åœ¨ã§ã™"
+
+#, python-format
+msgid "add changeset %s\n"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ %s を追加\n"
+
+msgid "adding changesets\n"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’追加中\n"
+
+msgid "received changelog group is empty"
+msgstr "å—ä¿¡ã—ãŸå¤‰æ›´å±¥æ­´ã¯ç©ºã§ã™"
+
+msgid "adding manifests\n"
+msgstr "マニフェストを追加中\n"
+
+msgid "adding file changes\n"
+msgstr "ファイルã®å¤‰æ›´ã‚’追加中\n"
+
+#, python-format
+msgid "adding %s revisions\n"
+msgstr "%s 個ã®ãƒªãƒ“ジョンを追加中\n"
+
+msgid "received file revlog group is empty"
+msgstr "ファイルã®ãƒªãƒ“ジョンログãŒç©ºã§ã™"
+
+#, python-format
+msgid " (%+d heads)"
+msgstr "(%+d個ã®ãƒ˜ãƒƒãƒ‰ï¼‰"
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr "%d ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆ(%d ã®å¤‰æ›´ã‚’ %d ファイルã«é©ç”¨)を追加%s\n"
+
+msgid "updating the branch cache\n"
+msgstr "ブランãƒã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’更新中\n"
+
+msgid "Unexpected response from remote server:"
+msgstr "連æºå…ˆã®ã‚µãƒ¼ãƒã‹ã‚‰äºˆæœŸã—ãªã„返信: "
+
+msgid "operation forbidden by server"
+msgstr "ãã®å‡¦ç†ã¯ã‚µãƒ¼ãƒã§ç¦æ­¢ã•れã¦ã„ã¾ã™"
+
+msgid "locking the remote repository failed"
+msgstr "連æºå…ˆãƒªãƒã‚¸ãƒˆãƒªã‚’ロックã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "the server sent an unknown error code"
+msgstr "サーãƒãŒæœªçŸ¥ã®ã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’è¿”å´ã—ã¾ã—ãŸ"
+
+msgid "streaming all changes\n"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‚’転é€ä¸­\n"
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr "%d 個ã®ãƒ•ァイル転é€(ãƒ‡ãƒ¼ã‚¿é‡ %s)\n"
+
+#, python-format
+msgid "adding %s (%s)\n"
+msgstr "%s を追加ã—ã¦ã„ã¾ã™ï¼ˆ%s)\n"
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr "%s ã‚’ %.1f ç§’ã§é€ä¿¡ã—ã¾ã—ãŸï¼ˆ%s/秒)\n"
+
+msgid "no [smtp]host in hgrc - cannot send mail"
+msgstr "設定ファイル㫠[smtp] host 指定ãŒã‚りã¾ã›ã‚“ - メールé€ä¿¡ã«å¤±æ•—"
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr "メールé€ä¿¡ä¸­: SMTP ホスト %sã€ãƒãƒ¼ãƒˆç•ªå· %s\n"
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr "TLS を利用ã§ãã¾ã›ã‚“: Python SSL サãƒãƒ¼ãƒˆãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "(using tls)\n"
+msgstr "(TLS を使用中)\n"
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr "(%s ã¨ã—ã¦ãƒ¡ãƒ¼ãƒ«ã‚µãƒ¼ãƒã®èªè¨¼ä¸­)\n"
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr "メールé€ä¿¡ä¸­: %s\n"
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr "ãƒ¡ãƒ¼ãƒ«è»¢é€æ–¹å¼ã® 'smtp' 指定ã«ã‚‚é–¢ã‚らãšã€SMTP ãƒ›ã‚¹ãƒˆãŒæœªè¨­å®šã§ã™"
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr "メール転é€ã‚³ãƒžãƒ³ãƒ‰ã§æŒ‡å®šã•れãŸãƒ—ログラム %r ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr "䏿­£ãªæ–‡å­—セットを無視ã—ã¾ã™: %s\n"
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr "䏿­£ãªãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹: %s"
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr "䏿­£ãªãƒ­ãƒ¼ã‚«ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹: %s"
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr "マニフェストã‹ã‚‰ %s を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr "差分コンテキストã§ã®è¡Œæ•°æŒ‡å®šãŒä¸æ­£ã§ã™: %r"
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr "未登録ファイル %s ã¯æŒ‡å®šãƒªãƒ“ジョンã§ã®è¨˜éŒ²å†…容ã¨ç•°ãªã‚Šã¾ã™"
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr "ファイルåã®æ–‡å­—大å°ã®å•題㧠%s 㨠%s ãŒè¡çªã—ã¾ã™"
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+"ファイル %s ã®ãƒ“ット設定ã«è¡çªãŒã‚りã¾ã™\n"
+"ã©ã®è¨­å®šã«ã—ã¾ã™ã‹ï¼Ÿç„¡åй:(n)one, 実行å¯èƒ½:e(x)ec, リンク:sym(l)ink"
+
+msgid "&None"
+msgstr "ãªã— (&N)"
+
+msgid "E&xec"
+msgstr "実行 (&X)"
+
+msgid "Sym&link"
+msgstr "シンボリックリンク (&L)"
+
+msgid "resolving manifests\n"
+msgstr "管ç†ãƒ•ァイル一覧を解決ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid " overwrite %s partial %s\n"
+msgstr " 上書ã:%s, 対象é™å®š:%s\n"
+
+#, python-format
+msgid " ancestor %s local %s remote %s\n"
+msgstr " 祖先 %s ローカル %s リモート %s\n"
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+"変更ã—ãŸãƒ•ァイル %s ã¯åˆ¥ãƒªãƒ“ジョンã§ç™»éŒ²é™¤å¤–ã•れã¦ã„ã¾ã™\n"
+"ã©ã¡ã‚‰ã‚’採用ã—ã¾ã™ã‹ï¼Ÿå¤‰æ›´:(c)hange, 登録除外:(d)elete"
+
+msgid "&Changed"
+msgstr "&Changed"
+
+msgid "&Delete"
+msgstr "&Delete"
+
+msgid "c"
+msgstr "c"
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+"リモートã§å¤‰æ›´ã•れ㟠%s ã¯ãƒ­ãƒ¼ã‚«ãƒ«ã§å‰Šé™¤ã•れã¦ã„ã¾ã™\n"
+"変更ã•れãŸã‚‚ã®(c)hangedを使用ã—ã¾ã™ã‹?ãれã¨ã‚‚削除(d)eleteã—ã¾ã™ã‹?"
+
+msgid "&Deleted"
+msgstr "&Deleted"
+
+#, python-format
+msgid "preserving %s for resolve of %s\n"
+msgstr "%s ã®ä¿å­˜ä¸­(%s ã®è¡çªè§£æ¶ˆç”¨)\n"
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr "%s ã®å‰Šé™¤ã«å¤±æ•—: %s!\n"
+
+#, python-format
+msgid "getting %s\n"
+msgstr "%s ã‚’å–å¾—ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr "%s ã‹ã‚‰ %s ã«è¤‡è£½ä¸­\n"
+
+#, python-format
+msgid "warning: detected divergent renames of %s to:\n"
+msgstr "警告: %s ã®æ”¹åå…ˆãŒç•°ãªã‚Šã¾ã™:\n"
+
+#, python-format
+msgid "branch %s not found"
+msgstr "ブランム%s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+msgid "can't merge with ancestor"
+msgstr "祖先ã¨ãƒžãƒ¼ã‚¸ã§ãã¾ã›ã‚“"
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr "マージã¯ä¸è¦ã§ã™('hg update' ã‹ 'hg heads' を使用ã—ã¦ãã ã•ã„)"
+
+msgid "outstanding uncommitted changes (use 'hg status' to list changes)"
+msgstr "未コミット変更ãŒã‚りã¾ã™('hg status' ã§å¤‰æ›´ä¸€è¦§è¡¨ç¤ºå¯èƒ½)"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C' to discard changes)"
+msgstr "ブランãƒã®æ¨ªæ–­(マージã™ã‚‹ã‹ã€'hg update -C' ã§å¤‰æ›´ã‚’破棄ã§ãã¾ã™)"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C')"
+msgstr "ブランãƒã®æ¨ªæ–­(マージã™ã‚‹ã‹ã€'hg update -C' ã§å¤‰æ›´ã‚’破棄ã§ãã¾ã™)"
+
+msgid "crosses named branches (use 'hg update -C' to discard changes)"
+msgstr "åå‰ä»˜ãブランãƒã®æ¨ªæ–­('hg update -C' ã§å¤‰æ›´ã‚’破棄ã§ãã¾ã™)"
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr "%s を作æˆã§ãã¾ã›ã‚“: 作業先ã«ã™ã§ã«å­˜åœ¨ã—ã¾ã™"
+
+#, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr "%s を作æˆã§ãã¾ã›ã‚“: ディレクトリを作æˆã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "found patch at byte %d\n"
+msgstr "%d ãƒã‚¤ãƒˆç›®ã«ãƒ‘ッãƒãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ\n"
+
+msgid "patch generated by hg export\n"
+msgstr "hg export ã«ã¦ãƒ‘ッãƒã‚’生æˆã—ã¾ã—ãŸ\n"
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr "パッãƒé©ç”¨å¯¾è±¡ã® '%s' ãŒä¸åœ¨ã§ã™\n"
+
+#, python-format
+msgid "patching file %s\n"
+msgstr "ファイル %s をパッãƒé©ç”¨ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr "%d 個ã®ãƒãƒ³ã‚¯(ç·æ•° %d)ãŒé©ç”¨å¤±æ•— -- 失敗ãƒãƒ³ã‚¯ã¯ %s ã«ä¿å­˜\n"
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr "䏿­£ãªãƒãƒ³ã‚¯: #%d %s (%d %d %d %d)"
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr "ファイル %s ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™\n"
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d line).\n"
+msgstr "ãƒãƒ³ã‚¯ #%d ã®é©ç”¨æˆåŠŸ:%d 行目 %s 補正行数 %d\n"
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d lines).\n"
+msgstr "ãƒãƒ³ã‚¯ #%d ã®é©ç”¨æˆåŠŸ:%d 行目 %s 補正行数 %d\n"
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr "ãƒãƒ³ã‚¯ #%d ã®é©ç”¨å¤±æ•—:%d 行目\n"
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr "䏿­£ãªãƒãƒ³ã‚¯: #%d"
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr "䏿­£ãªãƒãƒ³ã‚¯: #%d 元テキスト %d 行目"
+
+msgid "could not extract binary patch"
+msgstr "ãƒã‚¤ãƒŠãƒªãƒ‘ッãƒã®é©ç”¨ã«å¤±æ•—"
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr "ãƒã‚¤ãƒŠãƒªãƒ‘ッãƒã®ã‚µã‚¤ã‚ºä¸æ­£: 実サイズ %d, 想定サイズ %d"
+
+#, python-format
+msgid "unable to strip away %d dirs from %s"
+msgstr "%d 個ã®ãƒ‘スè¦ç´ é™¤å¤–ã«å¤±æ•—:%s"
+
+msgid "undefined source and destination files"
+msgstr "パッãƒå¯¾è±¡ã®ãƒ•ァイルåãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
+
+#, python-format
+msgid "malformed patch %s %s"
+msgstr "䏿­£ãªãƒ‘ッãƒ: %s %s"
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr "サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„パーサã®çŠ¶æ…‹ã§ã™: %s"
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr "patch コマンドãŒå¤±æ•—: %s"
+
+#, python-format
+msgid "Unsupported line endings type: %s"
+msgstr "未サãƒãƒ¼ãƒˆã®è¡Œæœ«ç¨®åˆ¥: %s"
+
+#, python-format
+msgid "no valid hunks found; trying with %r instead\n"
+msgstr "有効ãªãƒãƒ³ã‚¯ãŒã‚りã¾ã›ã‚“: %r ã§å†è©¦è¡Œä¸­\n"
+
+#, python-format
+msgid "exited with status %d"
+msgstr "終了コード %d ã§çµ‚了ã—ã¾ã—ãŸ"
+
+#, python-format
+msgid "killed by signal %d"
+msgstr "%d ã®ã‚·ã‚°ãƒŠãƒ«ã§å¼·åˆ¶çµ‚了ã—ã¾ã—ãŸ"
+
+#, python-format
+msgid "stopped by signal %d"
+msgstr "%d ã®ã‚·ã‚°ãƒŠãƒ«ã§åœæ­¢ã—ã¾ã—ãŸ"
+
+msgid "invalid exit code"
+msgstr "終了コードãŒä¸æ­£ã§ã™"
+
+#, python-format
+msgid "saving bundle to %s\n"
+msgstr "ãƒãƒ³ãƒ‰ãƒ«ã‚’ %s ã«ä¿å­˜ä¸­\n"
+
+msgid "adding branch\n"
+msgstr "ブランãƒã‚’追加中\n"
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr "%s ã§ãã¾ã›ã‚“。機能 %s ã¯ãƒªãƒ¢ãƒ¼ãƒˆãƒªãƒã‚¸ãƒˆãƒªã§ã¯æœªã‚µãƒãƒ¼ãƒˆã§ã™"
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr "%r ã¯æœªçŸ¥ã®åœ§ç¸®å½¢å¼ã§ã™"
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr "インデックス %s: %#04x ã¯æœªçŸ¥ã®ãƒ•ラグã§ã™(フォーマット v0)"
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr "インデックス %s: %#04x ã¯æœªçŸ¥ã®ãƒ•ラグã§ã™(revlogng)"
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr "インデックス %s: %d ã¯æœªçŸ¥ã®ãƒ•ォーマットã§ã™"
+
+#, python-format
+msgid "index %s is corrupted"
+msgstr "インデックス %s ã¯ç ´æã—ã¦ã„ã¾ã™"
+
+msgid "no node"
+msgstr "ノードãŒã‚りã¾ã›ã‚“"
+
+msgid "ambiguous identifier"
+msgstr "曖昧ãªè­˜åˆ¥å­ã§ã™"
+
+msgid "no match found"
+msgstr "該当ã™ã‚‹ ID ã¯ã‚りã¾ã›ã‚“ã§ã—ãŸ"
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr "%x ã¯äº’æ›æ€§ã®ãªã„リビジョンフラグã§ã™"
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr "トランザクション中㫠%s ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "unknown base"
+msgstr "未知ã®ãƒ™ãƒ¼ã‚¹ãƒªãƒ“ジョン"
+
+msgid "consistency error adding group"
+msgstr "グループã®è¿½åŠ ã«å¤±æ•—"
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr "%s ã¯ãƒã‚¤ãƒŠãƒªãƒ•ァイルã®ã‚ˆã†ã§ã™ã€‚"
+
+msgid "can only specify two labels."
+msgstr "ラベルã¯äºŒã¤ã®ã¿æŒ‡å®šå¯ã€‚"
+
+msgid "warning: conflicts during merge.\n"
+msgstr "警告: マージ中ã«è¡çªã‚’発見。\n"
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr "URL %s ã®è§£æžã«å¤±æ•—"
+
+msgid "could not create remote repo"
+msgstr "é éš”ホストã¨ã®é€£æºã«å¤±æ•—"
+
+msgid "remote: "
+msgstr "é éš”ホスト: "
+
+msgid "no suitable response from remote hg"
+msgstr "é éš”ホストã®å¿œç­”ãŒä¸é©åˆ‡"
+
+#, python-format
+msgid "push refused: %s"
+msgstr "å±¥æ­´åæ˜ ãŒæ‹’å¦ã•れã¾ã—ãŸ: %s"
+
+msgid "unsynced changes"
+msgstr "未å–り込ã¿ã®å¤‰æ›´ãŒã‚りã¾ã™"
+
+msgid "cannot lock static-http repository"
+msgstr "static-http リãƒã‚¸ãƒˆãƒªã¯ãƒ­ãƒƒã‚¯ã§ãã¾ã›ã‚“"
+
+msgid "cannot create new static-http repository"
+msgstr "static-http リãƒã‚¸ãƒˆãƒªã®æ–°è¦ä½œæˆã¯ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr "ファイルåキャッシュã«ä¸æ­£ãªã‚¨ãƒ³ãƒˆãƒª: %s 行目"
+
+msgid "scanning\n"
+msgstr "走査中\n"
+
+#, python-format
+msgid "%d files, %d bytes to transfer\n"
+msgstr "%d 個ã®ãƒ•ァイルã€%d ãƒã‚¤ãƒˆã®é€ä¿¡\n"
+
+#, python-format
+msgid "sending %s (%d bytes)\n"
+msgstr "%s ã®é€ä¿¡ä¸­(%d ãƒã‚¤ãƒˆ)\n"
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?"
+msgstr ""
+
+msgid "&Remote"
+msgstr "&Remote"
+
+msgid "r"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed subrepository %s which remote removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+"ローカル副リãƒã‚¸ãƒˆãƒªã§å¤‰æ›´ã—ãŸãƒ•ァイル %s ã¯ä»–æ–¹ã§ç™»éŒ²é™¤å¤–ã•れã¦ã„ã¾ã™\n"
+"ã©ã¡ã‚‰ã‚’採用ã—ã¾ã™ã‹ï¼Ÿå¤‰æ›´:(c)hange, 登録除外:(d)elete"
+
+#, python-format
+msgid ""
+" remote changed subrepository %s which local removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+"ローカル副リãƒã‚¸ãƒˆãƒªã§ç™»éŒ²é™¤å¤–ã•れãŸãƒ•ァイル %s ã¯ä»–æ–¹ã§å¤‰æ›´ã•れã¦ã„ã¾ã™\n"
+"ã©ã¡ã‚‰ã‚’採用ã—ã¾ã™ã‹ï¼Ÿå¤‰æ›´:(c)hange, 登録除外:(d)elete"
+
+#, python-format
+msgid "removing subrepo %s\n"
+msgstr "副リãƒã‚¸ãƒˆãƒªã® %s を登録除外中\n"
+
+#, python-format
+msgid "pulling subrepo %s\n"
+msgstr "副リãƒã‚¸ãƒˆãƒªã« %s ã‹ã‚‰å–り込ã¿ä¸­\n"
+
+#, python-format
+msgid "pushing subrepo %s\n"
+msgstr "副リãƒã‚¸ãƒˆãƒªã‚’ %s ã¸å映中\n"
+
+msgid "unmatched quotes"
+msgstr "引用符ã®å¯¾å¿œé–¢ä¿‚ãŒä¸æ­£ã§ã™"
+
+#, python-format
+msgid "error expanding '%s%%%s'"
+msgstr "'%s%%%s' 展開ã®å¤±æ•—"
+
+#, python-format
+msgid "unknown filter '%s'"
+msgstr "'%s' ã¯æœªçŸ¥ã®ãƒ•ィルタã§ã™"
+
+#, python-format
+msgid "style not found: %s"
+msgstr "スタイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
+
+#, python-format
+msgid "template file %s: %s"
+msgstr "テンプレートファイル %s: %s"
+
+msgid "cannot use transaction when it is already committed/aborted"
+msgstr "æ—¢ã«å®Œäº†/中止ã•れã¦ã„ã‚‹ãŸã‚トランザクションを利用ã§ãã¾ã›ã‚“"
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr "%s ã®åˆ‡ã‚Šè©°ã‚ã«å¤±æ•—\n"
+
+msgid "transaction abort!\n"
+msgstr "トランザクションを中断ã—ã¾ã™!\n"
+
+msgid "rollback completed\n"
+msgstr "ロールãƒãƒƒã‚¯ã‚’完了ã—ã¾ã—ãŸ\n"
+
+msgid "rollback failed - please run hg recover\n"
+msgstr "ロールãƒãƒƒã‚¯ã«å¤±æ•—ã—ã¾ã—㟠- 'hg recover' ã—ã¦ãã ã•ã„\n"
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr "ä¿¡é ¼ã§ããªã„ファイル %s (ä¿¡é ¼ã§ããªã„ユーザ %s, グループ %s)\n"
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr "無視ã—ã¾ã—ãŸ: %s\n"
+
+#, python-format
+msgid "ignoring untrusted configuration option %s.%s = %s\n"
+msgstr "ä¿¡é ¼ã§ããªã„設定ファイル中㮠'%s.%s = %s' 設定を無視\n"
+
+#, python-format
+msgid "%s.%s not a boolean ('%s')"
+msgstr "%s.%s ã®å€¤ '%s' ã¯çœŸå½å€¤ã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "enter a commit username:"
+msgstr "コミットã™ã‚‹ãƒ¦ãƒ¼ã‚¶åを入力ã—ã¦ãã ã•ã„:"
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr "ユーザåãŒä¸æ˜Žã®ãŸã‚ã€'%s' を使用\n"
+
+msgid "Please specify a username."
+msgstr "ユーザåを指定ã—ã¦ãã ã•ã„。"
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr "ユーザå %s ã¯æ”¹è¡Œã‚’å«ã‚“ã§ã„ã¾ã™\n"
+
+msgid "unrecognized response\n"
+msgstr "èªè­˜ã§ããªã„レスãƒãƒ³ã‚¹\n"
+
+msgid "response expected"
+msgstr "レスãƒãƒ³ã‚¹ãŒã‚りã¾ã›ã‚“"
+
+msgid "password: "
+msgstr "パスワード: "
+
+msgid "edit failed"
+msgstr "編集ã«å¤±æ•—"
+
+msgid "http authorization required"
+msgstr "HTTP èªè¨¼ã«å¤±æ•—"
+
+msgid "http authorization required\n"
+msgstr "HTTP èªè¨¼ã‚’è¦æ±‚ã—ã¾ã—ãŸ\n"
+
+#, python-format
+msgid "realm: %s\n"
+msgstr "èªè¨¼é ˜åŸŸ: %s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "ユーザ: %s\n"
+
+msgid "user:"
+msgstr "ユーザ:"
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr "HTTP èªè¨¼: ユーザå %s, パスワード %s\n"
+
+#, python-format
+msgid "proxying through http://%s:%s\n"
+msgstr "プロキシ 'http://%s:%s' を経由ã—ã¦ã„ã¾ã™\n"
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr "コマンド '%s' 失敗: %s"
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr "パスã«ä¸æ­£ãªã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆãŒã‚りã¾ã™: %s"
+
+#, python-format
+msgid "path %r is inside repo %r"
+msgstr "パス %r ã¯ãƒªãƒã‚¸ãƒˆãƒª %r 内ã«ã‚りã¾ã™"
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr "パス %r ã¯ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ '%r' ãŒå«ã¾ã‚Œã¦ã„ã¾ã™"
+
+msgid "Hardlinks not supported"
+msgstr "ãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“"
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr "%r ã¸ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ã§ãã¾ã›ã‚“: %s"
+
+#, python-format
+msgid "invalid date: %r "
+msgstr "䏿­£ãªæ—¥ä»˜: %r "
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr "日付ãŒ32ビットを超ãˆã¦ã„ã¾ã™: %d"
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr "ã‚り得ãªã„タイムゾーン: %d"
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr "䏿­£ãªæ—¥ä»˜ã®æŒ‡å®šã§ã™: %s"
+
+#, python-format
+msgid "%.0f GB"
+msgstr "%.0f GB"
+
+#, python-format
+msgid "%.1f GB"
+msgstr "%.1f GB"
+
+#, python-format
+msgid "%.2f GB"
+msgstr "%.2f GB"
+
+#, python-format
+msgid "%.0f MB"
+msgstr "%.0f MB"
+
+#, python-format
+msgid "%.1f MB"
+msgstr "%.1f MB"
+
+#, python-format
+msgid "%.2f MB"
+msgstr "%.2f MB"
+
+#, python-format
+msgid "%.0f KB"
+msgstr "%.0f KB"
+
+#, python-format
+msgid "%.1f KB"
+msgstr "%.1f KB"
+
+#, python-format
+msgid "%.2f KB"
+msgstr "%.2f KB"
+
+#, python-format
+msgid "%.0f bytes"
+msgstr "%.0f ãƒã‚¤ãƒˆ"
+
+msgid "cannot verify bundle or remote repos"
+msgstr "ローカルリãƒã‚¸ãƒˆãƒªä»¥å¤–ã¯æ¤œè¨¼ã§ãã¾ã›ã‚“"
+
+msgid "interrupted"
+msgstr "中断ã•れã¾ã—ãŸ"
+
+#, python-format
+msgid "empty or missing %s"
+msgstr "%s ã¯ã€ç©ºã‹è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr "データ長: %d ãƒã‚¤ãƒˆ"
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr "ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®æ‹¡å¼µãƒ‡ãƒ¼ã‚¿: %d ãƒã‚¤ãƒˆ"
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr "警告: `%s' 㯠revlog å½¢å¼ 1 ã§ã™"
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr "警告: `%s' 㯠revlog å½¢å¼ 0 ã§ã™"
+
+#, python-format
+msgid "rev %d points to nonexistent changeset %d"
+msgstr "リビジョン %d ã¯æœªçŸ¥ã®ãƒªãƒ“ジョン %d ã‚’å‚ç…§ã—ã¦ã„ã¾ã™"
+
+#, python-format
+msgid "rev %d points to unexpected changeset %d"
+msgstr "リビジョン %d ã¯æƒ³å®šå¤–ã®ãƒªãƒ“ジョン %d ã‚’å‚ç…§ã—ã¦ã„ã¾ã™"
+
+#, python-format
+msgid " (expected %s)"
+msgstr " (想定対象 %s)"
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr "未知ã®ç¬¬1親 %s ã‚’æŒã¤ %s"
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr "未知ã®ç¬¬2親 %s ã‚’æŒã¤ %s"
+
+#, python-format
+msgid "checking parents of %s"
+msgstr "%s ã®è¦ªã‚’検証中"
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr "%d ã¨é‡è¤‡ã™ã‚‹ãƒªãƒ“ジョン %d ãŒã‚りã¾ã™"
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr "リãƒã‚¸ãƒˆãƒªã¯ revlog å½¢å¼ %d ã§ã™\n"
+
+msgid "checking changesets\n"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã®ç¢ºèªä¸­\n"
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr "リビジョン %s ã®å±•開中"
+
+msgid "checking manifests\n"
+msgstr "管ç†ãƒ•ァイル一覧ã®ç¢ºèªä¸­\n"
+
+#, python-format
+msgid "%s not in changesets"
+msgstr "リビジョン %s ã¯æœªçŸ¥ã®ãƒªãƒ“ジョンã§ã™"
+
+msgid "file without name in manifest"
+msgstr "åå‰ã‚’æŒãŸãªã„ファイルãŒã‚りã¾ã™"
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr "管ç†å¯¾è±¡ä¸€è¦§ã®å·®åˆ† %s ã®èª­ã¿è¾¼ã¿ä¸­"
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã¨ãƒžãƒ‹ãƒ•ェストã«ã‚ˆã‚‹ãƒ•ァイルã®ã‚¯ãƒ­ã‚¹ãƒã‚§ãƒƒã‚¯ä¸­\n"
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr "未知ã®ãƒžãƒ‹ãƒ•ェスト %s ãŒå‚ç…§ã•れã¦ã„ã¾ã™"
+
+msgid "in changeset but not in manifest"
+msgstr "マニフェストã‹ã‚‰å‚ç…§ã•れã¦ã„ãªã„ファイル"
+
+msgid "in manifest but not in changeset"
+msgstr "ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã‹ã‚‰å‚ç…§ã•れã¦ã„ãªã„ファイル"
+
+msgid "checking files\n"
+msgstr "ファイルã®ç¢ºèªä¸­\n"
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr "ファイルå '%s' ã®ãƒ‡ã‚³ãƒ¼ãƒ‰ã«å¤±æ•—"
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr "䏿­£ãª revlog! (%s)"
+
+msgid "missing revlog!"
+msgstr "revlog ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“!"
+
+#, python-format
+msgid "%s not in manifests"
+msgstr "%s ã¯ç®¡ç†å¯¾è±¡ã§ã¯ã‚りã¾ã›ã‚“"
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr "展開後サイズ %s ã¯æƒ³å®šå¤–ã§ã™(期待値:%s)"
+
+#, python-format
+msgid "unpacking %s"
+msgstr "%s ã®å±•開中"
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr "複製元 revlog %s:%s ã¯ã€ç©ºã‹è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s"
+msgstr "警告: %s@%s: 複製元リビジョン㌠nullid %s:%s"
+
+#, python-format
+msgid "checking rename of %s"
+msgstr "%s ã®æ”¹åを確èªä¸­"
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr "管ç†å¯¾è±¡ä¸€è¦§ä¸­ã® %s ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr "警告: revlog '%s' ã¯ã©ã“ã‹ã‚‰ã‚‚å‚ç…§ã•れã¦ã„ã¾ã›ã‚“"
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr "%d 個ã®ãƒ•ァイルã€%d ä»¶ã®ãƒã‚§ãƒ³ã‚¸ã‚»ãƒƒãƒˆã€åˆè¨ˆ %d ä»¶ã®ãƒªãƒ“ジョン\n"
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr "警告㌠%d ä»¶ã‚りã¾ã™!\n"
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr "䏿•´åˆãŒ %d ä»¶ã‚りã¾ã™!\n"
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr "(最åˆã®ä¸æ•´åˆã¯ %d ã®æ¨¡æ§˜)\n"
+
+msgid "user name not available - set USERNAME environment variable"
+msgstr "ユーザåãŒåˆ©ç”¨ã§ãã¾ã›ã‚“ - 環境変数 USERNAME を設定ã—ã¦ãã ã•ã„"
diff --git a/sys/src/cmd/hg/i18n/pt_BR.po b/sys/src/cmd/hg/i18n/pt_BR.po
new file mode 100644
index 000000000..43635083e
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/pt_BR.po
@@ -0,0 +1,11609 @@
+# Brazilian Portuguese translations for Mercurial
+# Traduções do Mercurial para português do Brasil
+# Copyright (C) 2009 Matt Mackall and others
+#
+# Translators:
+# Diego Oliveira <diego@diegooliveira.com>
+# Wagner Bruna <wbruna@softwareexpress.com.br>
+#
+# Translation dictionary:
+#
+# archive pacote
+# branch ramificar (v.), ramo (s.)
+# bundle bundle
+# changeset changeset
+# commit consolidar (v.), consolidação (s.)
+# default default (branch ou path), padrão
+# diff diff
+# head cabeça
+# hook gancho
+# merge mesclar (v.), mesclagem (s.)
+# patch patch
+# pull trazer
+# push enviar
+# revision revisão
+# tag etiqueta
+# tip tip (tag), ponta
+# update atualizar (v.), atualização (s.)
+# working directory diretório de trabalho
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial\n"
+"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
+"POT-Creation-Date: 2009-06-08 11:30-0300\n"
+"PO-Revision-Date: 2009-04-16 14:29-0300\n"
+"Last-Translator: Wagner Bruna <wbruna@yahoo.com>\n"
+"Language-Team: Brazilian Portuguese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: KBabel 1.11.4\n"
+"X-Poedit-Country: BRAZIL\n"
+"X-Poedit-Language: Portuguese\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (padrão: %s)"
+
+msgid "OPTIONS"
+msgstr "OPÇÕES"
+
+msgid "COMMANDS"
+msgstr "COMANDOS"
+
+msgid " options:\n"
+msgstr " opções:\n"
+
+#, python-format
+msgid ""
+" aliases: %s\n"
+"\n"
+msgstr ""
+" apelidos: %s\n"
+"\n"
+
+msgid ""
+"hooks for controlling repository access\n"
+"\n"
+"This hook makes it possible to allow or deny write access to portions\n"
+"of a repository when receiving incoming changesets.\n"
+"\n"
+"The authorization is matched based on the local user name on the\n"
+"system where the hook runs, and not the committer of the original\n"
+"changeset (since the latter is merely informative).\n"
+"\n"
+"The acl hook is best used along with a restricted shell like hgsh,\n"
+"preventing authenticating users from doing anything other than\n"
+"pushing or pulling. The hook is not safe to use if users have\n"
+"interactive shell access, as they can then disable the hook.\n"
+"Nor is it safe if remote users share an account, because then there\n"
+"is no way to distinguish them.\n"
+"\n"
+"To use this hook, configure the acl extension in your hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.acl =\n"
+"\n"
+" [hooks]\n"
+" pretxnchangegroup.acl = python:hgext.acl.hook\n"
+"\n"
+" [acl]\n"
+" # Check whether the source of incoming changes is in this list\n"
+" # (\"serve\" == ssh or http, \"push\", \"pull\", \"bundle\")\n"
+" sources = serve\n"
+"\n"
+"The allow and deny sections take a subtree pattern as key (with a\n"
+"glob syntax by default), and a comma separated list of users as\n"
+"the corresponding value. The deny list is checked before the allow\n"
+"list is.\n"
+"\n"
+" [acl.allow]\n"
+" # If acl.allow is not present, all users are allowed by default.\n"
+" # An empty acl.allow section means no users allowed.\n"
+" docs/** = doc_writer\n"
+" .hgtags = release_engineer\n"
+"\n"
+" [acl.deny]\n"
+" # If acl.deny is not present, no users are refused by default.\n"
+" # An empty acl.deny section means all users allowed.\n"
+" glob pattern = user4, user5\n"
+" ** = user6\n"
+msgstr ""
+"ganchos para controlar o acesso a um repositório\n"
+"\n"
+"Este gancho possibilita permitir ou recusar acesso de escrita a\n"
+"porções de um repositório ao receber changesets.\n"
+"\n"
+"A autorização é feita com relação ao nome de usuário local no sistema\n"
+"onde o gancho é executado, e não ao autor do changeset original (já\n"
+"que este é meramente informativo).\n"
+"\n"
+"O gancho acl funciona melhor se você usar um shell restrito (como\n"
+"por exemplo o hgsh), impedindo que usuários autenticados usem outros\n"
+"comandos além de push e pull. Ele não é seguro se os usuários tiverem\n"
+"acesso a um shell interativo, pois eles então poderão desabilitar o\n"
+"gancho. Também não é seguro se usuários remotos compartilharem uma\n"
+"conta local, pois não haverá maneira de distingüí-los.\n"
+"\n"
+"Para usar, configure a extensão acl em seu hgrc da seguinte forma:\n"
+"\n"
+" [extensions]\n"
+" hgext.acl =\n"
+"\n"
+" [hooks]\n"
+" pretxnchangegroup.acl = python:hgext.acl.hook\n"
+"\n"
+" [acl]\n"
+" # verifica se a origem de changesets está nessa lista\n"
+" # (\"serve\" == ssh ou http, \"push\", \"pull\", \"bundle\")\n"
+" sources = serve\n"
+"\n"
+"As seções allow (permissões) e deny (restrições) usam um padrão de\n"
+"sub-árvore como chave (a sintaxe padrão é a glob), e uma lista de\n"
+"usuários separada por vírgulas como valor correspondente. A lista de\n"
+"restrições é verificada antes da lista de permissões.\n"
+"\n"
+" [acl.allow]\n"
+" # Se acl.allow não estiver presente, todos os usuários são\n"
+" # por padrão permitidos\n"
+" # uma acl.allow vazia faz com que nenhum usuário seja permitido\n"
+" docs/** = doc_writer\n"
+" .hgtags = release_engineer\n"
+"\n"
+" [acl.deny]\n"
+" # Se acl.deny não estiver presente, nenhum usuário é recusado\n"
+" # por padrão\n"
+" # Uma acl.deny vazia faz com que todos os usuários sejam permitidos\n"
+" glob pattern = user4, user5\n"
+" ** = user6\n"
+
+#, python-format
+msgid "acl: %s not enabled\n"
+msgstr "acl: %s desabilitado\n"
+
+#, python-format
+msgid "acl: %s enabled, %d entries for user %s\n"
+msgstr "acl: %s habilitado, %d entradas para o usuário %s\n"
+
+#, python-format
+msgid "config error - hook type \"%s\" cannot stop incoming changesets"
+msgstr ""
+"erro de configuração - tipo de gancho \"%s\" não pode interromper a chegada "
+"dos changesets"
+
+#, python-format
+msgid "acl: changes have source \"%s\" - skipping\n"
+msgstr "acl: mudanças têm origem \"%s\" - omitindo\n"
+
+#, python-format
+msgid "acl: user %s denied on %s\n"
+msgstr "acl: usuário %s negado em %s\n"
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr "acl: acesso negado para o changeset %s"
+
+#, python-format
+msgid "acl: user %s not allowed on %s\n"
+msgstr "acl: usuário %s não permitido em %s\n"
+
+#, python-format
+msgid "acl: allowing changeset %s\n"
+msgstr "acl: permitindo changeset %s\n"
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+"Bookmarks are local movable markers to changesets. Every bookmark\n"
+"points to a changeset identified by its hash. If you commit a\n"
+"changeset that is based on a changeset that has a bookmark on it,\n"
+"the bookmark shifts to the new changeset.\n"
+"\n"
+"It is possible to use bookmark names in every revision lookup\n"
+"(e.g. hg merge, hg update).\n"
+"\n"
+"By default, when several bookmarks point to the same changeset, they\n"
+"will all move forward together. It is possible to obtain a more\n"
+"git-like experience by adding the following configuration option to\n"
+"your .hgrc:\n"
+"\n"
+" [bookmarks]\n"
+" track.current = True\n"
+"\n"
+"This will cause Mercurial to track the bookmark that you are currently\n"
+"using, and only update it. This is similar to git's approach to\n"
+"branching.\n"
+msgstr ""
+"rastreia uma linha de desenvolvimento com marcadores móveis\n"
+"marcadores do Mercurial\n"
+"\n"
+"Marcadores são ponteiros locais móveis para changesets. Todo\n"
+"marcador aponta para um changeset identificado por seu hash. Se você\n"
+"consolidar um changeset que se baseie em um changeset que contenha um\n"
+"marcador, o marcador é transferido para o novo changeset.\n"
+"\n"
+"É possível utilizar nomes de marcadores em toda referência a revisões\n"
+"(por exemplo: hg merge, hg update).\n"
+"\n"
+"Por padrão, quando vários marcadores apontam para o mesmo changeset,\n"
+"todos serão movidos para a frente juntos. É possível obter um\n"
+"funcionamento mais semelhante ao do sistema git com a adição das\n"
+"seguintes opções de configuração ao seu .hgrc:\n"
+"\n"
+" [bookmarks]\n"
+" track.current = True\n"
+"\n"
+"Isto fará com que o Mercurial rastreie o marcador que você estiver\n"
+"usando no momento, e apenas o atualize. Isto é semelhante à abordagem\n"
+"do git para ramos.\n"
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+" Bookmarks are pointers to certain commits that move when\n"
+" committing. Bookmarks are local. They can be renamed, copied and\n"
+" deleted. It is possible to use bookmark names in 'hg merge' and\n"
+" 'hg update' to merge and update respectively to a given bookmark.\n"
+"\n"
+" You can use 'hg bookmark NAME' to set a bookmark on the working\n"
+" directory's parent revision with the given name. If you specify\n"
+" a revision using -r REV (where REV may be an existing bookmark),\n"
+" the bookmark is assigned to that revision.\n"
+" "
+msgstr ""
+"rastreia uma linha de desenvolvimento com marcadores móveis\n"
+"\n"
+" Marcadores são ponteiros para certas consolidações que se movem\n"
+" quando novas consolidações forem feitas. Marcadores são locais.\n"
+" Eles podem ser renomeados, copiados e removidos. É possível usar\n"
+" o nome de um marcador em 'hg merge' e 'hg update' para\n"
+" respectivamente mesclar ou atualizar para um marcador dado.\n"
+"\n"
+" Você pode usar 'hg bookmark NOME' para definir um marcador na\n"
+" revisão do diretório de trabalho com o nome informado. Se você\n"
+" especificar a revisão usando -r REV (onde REV pode ser o nome de\n"
+" um marcador existente), o marcador é apontado para tal revisão.\n"
+" "
+
+msgid "a bookmark of this name does not exist"
+msgstr "não existe um marcador com esse nome"
+
+msgid "a bookmark of the same name already exists"
+msgstr "já existe um marcador com o mesmo nome"
+
+msgid "new bookmark name required"
+msgstr "requerido nome do novo marcador"
+
+msgid "bookmark name required"
+msgstr "requerido nome do marcador"
+
+msgid "bookmark name cannot contain newlines"
+msgstr "o nome do marcador não pode conter novas linhas"
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr "um marcador não pode ter o mesmo nome de um ramo existente"
+
+msgid "force"
+msgstr "forçar"
+
+msgid "revision"
+msgstr "revisão"
+
+msgid "delete a given bookmark"
+msgstr "apaga o marcador pedido"
+
+msgid "rename a given bookmark"
+msgstr "renomeia um marcador"
+
+msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
+msgstr "hg bookmarks [-f] [-d] [-m NOME] [-r REV] [NOME]"
+
+msgid ""
+"hooks for integrating with the Bugzilla bug tracker\n"
+"\n"
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
+"bug status.\n"
+"\n"
+"The hook updates the Bugzilla database directly. Only Bugzilla\n"
+"installations using MySQL are supported.\n"
+"\n"
+"The hook relies on a Bugzilla script to send bug change notification\n"
+"emails. That script changes between Bugzilla versions; the\n"
+"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
+"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
+"be run by Mercurial as the user pushing the change; you will need to\n"
+"ensure the Bugzilla install file permissions are set appropriately.\n"
+"\n"
+"Configuring the extension:\n"
+"\n"
+" [bugzilla]\n"
+"\n"
+" host Hostname of the MySQL server holding the Bugzilla\n"
+" database.\n"
+" db Name of the Bugzilla database in MySQL. Default 'bugs'.\n"
+" user Username to use to access MySQL server. Default 'bugs'.\n"
+" password Password to use to access MySQL server.\n"
+" timeout Database connection timeout (seconds). Default 5.\n"
+" version Bugzilla version. Specify '3.0' for Bugzilla versions\n"
+" 3.0 and later, '2.18' for Bugzilla versions from 2.18\n"
+" and '2.16' for versions prior to 2.18.\n"
+" bzuser Fallback Bugzilla user name to record comments with, if\n"
+" changeset committer cannot be found as a Bugzilla user.\n"
+" bzdir Bugzilla install directory. Used by default notify.\n"
+" Default '/var/www/html/bugzilla'.\n"
+" notify The command to run to get Bugzilla to send bug change\n"
+" notification emails. Substitutes from a map with 3\n"
+" keys, 'bzdir', 'id' (bug id) and 'user' (committer\n"
+" bugzilla email). Default depends on version; from 2.18\n"
+" it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
+" %(id)s %(user)s\".\n"
+" regexp Regular expression to match bug IDs in changeset commit\n"
+" message. Must contain one \"()\" group. The default\n"
+" expression matches 'Bug 1234', 'Bug no. 1234', 'Bug\n"
+" number 1234', 'Bugs 1234,5678', 'Bug 1234 and 5678' and\n"
+" variations thereof. Matching is case insensitive.\n"
+" style The style file to use when formatting comments.\n"
+" template Template to use when formatting comments. Overrides\n"
+" style if specified. In addition to the usual Mercurial\n"
+" keywords, the extension specifies:\n"
+" {bug} The Bugzilla bug ID.\n"
+" {root} The full pathname of the Mercurial\n"
+" repository.\n"
+" {webroot} Stripped pathname of the Mercurial\n"
+" repository.\n"
+" {hgweb} Base URL for browsing Mercurial\n"
+" repositories.\n"
+" Default 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip The number of slashes to strip from the front of {root}\n"
+" to produce {webroot}. Default 0.\n"
+" usermap Path of file containing Mercurial committer ID to\n"
+" Bugzilla user ID mappings. If specified, the file\n"
+" should contain one mapping per line,\n"
+" \"committer\"=\"Bugzilla user\". See also the [usermap]\n"
+" section.\n"
+"\n"
+" [usermap]\n"
+" Any entries in this section specify mappings of Mercurial\n"
+" committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl Base URL for browsing Mercurial repositories. Reference\n"
+" from templates as {hgweb}.\n"
+"\n"
+"Activating the extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # run bugzilla hook on every change pulled or pushed in here\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Example configuration:\n"
+"\n"
+"This example configuration is for a collection of Mercurial\n"
+"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
+"installation in /opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Commits add a comment to the Bugzilla bug record of the form:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+msgstr ""
+"ganchos para integração com um bug tracker Bugzilla\n"
+"\n"
+"Essa extensão adiciona comentários a bugs do Bugzilla quando\n"
+"forem encontrados changesets que se refiram a esses bugs pelo ID.\n"
+"Esse gancho não muda o estado do bug.\n"
+"\n"
+"Esse gancho atualiza diretamente o banco de dados do Bugzilla.\n"
+"Apenas instalações do Bugzilla utilizando MySQL são suportadas.\n"
+"\n"
+"O gancho se baseia em um script do Bugzilla para enviar emails de\n"
+"notificação de alterações de bugs. Esse script muda entre versões do\n"
+"Bugzilla; o script 'processmail' usado antes da 2.18 é substituído na\n"
+"2.18 e subseqüentes por 'config/sendbugmail.pl'. Note que esse script\n"
+"será executado pelo Mercurial assim que o usuário enviar o changeset;\n"
+"você terá que assegurar que as permissões de arquivo da instalação\n"
+"do Bugzilla estejam configuradas apropriadamente.\n"
+"\n"
+"Configuração da extensão:\n"
+"\n"
+" [bugzilla]\n"
+"\n"
+" host Nome do servidor do MySQL que contém o banco de dados\n"
+" do Bugzilla.\n"
+" db Nome do banco de dados do Bugzilla no MySQL. O padrão\n"
+" é 'bugs'.\n"
+" user Nome de usuário para acessar o servidor MySQL. O\n"
+" padrão é 'bugs'.\n"
+" password Senha para acessar o servidor do MySQL.\n"
+" timeout Tempo de espera máximo para conexão com o banco de\n"
+" dados (em segundos). O padrão é 5.\n"
+" version Versão do Bugzilla. Especifique '3.0' para versões do\n"
+" Bugzilla 3.0 e posteriores, '2.18' para a versão 2.18\n"
+" e '2.16' para versões anteriores à 2.18.\n"
+" bzuser Nome de usuário no Bugzilla utilizado para gravar os\n"
+" comentários se o autor do changeset não for encontrado\n"
+" como um usuário do Bugzilla.\n"
+" bzdir Diretório de instalação do Bugzilla. Usado pelo notify\n"
+" padrão. Seu valor padrão é '/var/www/html/bugzilla'.\n"
+" notify O comando que deve ser executado para o Bugzilla\n"
+" enviar o email de notificação de alterações.\n"
+" Substituído de uma mapa com 3 entradas, 'bzdir', 'id'\n"
+" (bug id) e 'user' (email do submetedor do bugzilla).\n"
+" O padrão depende da versão; na 2.18 é\n"
+" \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
+" %(id)s %(user)s\".\n"
+" regexp Expressão regular para encontrar os IDs dos bugs na\n"
+" mensagem de consolidação do changeset. Deve conter um\n"
+" grupo de \"()\". A expressão padrão encontra\n"
+" 'Bug 1234', 'Bug no. 1234', 'Bug number 1234',\n"
+" 'Bugs 1234,5678', 'Bug 1234 and 5678' e variações. A\n"
+" equivalência não é sensível a maiúsculas e minúsculas.\n"
+" style O arquivo de estilo usado para formatar os\n"
+" comentários.\n"
+" template O template usado para formatar os comentários.\n"
+" Sobrepõe style se especificado. Além das palavras\n"
+" chave do Mercurial, a extensão define:\n"
+" {bug} O ID do bug no Bugzilla.\n"
+" {root} O caminho completo do repositório do\n"
+" Mercurial.\n"
+" {webroot} O caminho do repositório do Mercurial.\n"
+" {hgweb} URL base para visualizar o repositório\n"
+" do Mercurial via http.\n"
+" Padrão 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip O número de barras que devem ser retiradas do início\n"
+" do {root} para produzir o {webroot}. Padrão 0.\n"
+" usermap Caminho para o arquivo que contem o mapeamento do\n"
+" consolidador do Mercurial para o ID do usuário do\n"
+" Bugzilla. Se especificado, o arquivo deve conter um\n"
+" mapeamento por linha, \"committer\"=\"Bugzilla user\".\n"
+" Veja também a sessão [usermap].\n"
+"\n"
+" [usermap]\n"
+" Quaisquer entradas nessa sessão especificam mapeamentos de IDs\n"
+" dos consolidadores do Mercurial para IDs de usuário do Bugzilla.\n"
+" Veja também [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl URL base para visualização de repositórios do\n"
+" Mercurial. Usada em modelos como {hgweb}.\n"
+"\n"
+"Para ativar a extensão:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # executa o gancho bugzilla a cada mudança trazida\n"
+" # para cá\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Exemplo de configuração:\n"
+"\n"
+"Este exemplo de configuração é para uma coleção de repositórios do\n"
+"Mercurial em /var/local/hg/repos/ usada com uma instalação local do\n"
+"Bugzilla 3.2 em /opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Consolidações adicionam um comentário ao registro de bug do Bugzilla\n"
+"com a forma:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr "conectando a %s:%s como %s, senha %s\n"
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr "consulta: %s %s\n"
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr "falha na consulta: %s %s\n"
+
+msgid "unknown database schema"
+msgstr "esquema de banco de dados desconhecido"
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr "o bug %d já sabe sobre o changeset %s\n"
+
+msgid "telling bugzilla to send mail:\n"
+msgstr "falando para o bugzilla enviar email:\n"
+
+#, python-format
+msgid " bug %s\n"
+msgstr " bug %s\n"
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr "rodando comando de notificação %s\n"
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr "comando de notificação do bugzilla %s"
+
+msgid "done\n"
+msgstr "feito\n"
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr "procurando usuário %s\n"
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr "não é possível encontrar o id do usuário no bugzilla para %s"
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr "não é possível encontrar o id do usuário no bugzilla para %s ou %s"
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr "versão %s do bugzilla não suportada"
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+"changeset {node|short} no repositório {root} refere-se ao bug {bug}.\n"
+"detalhes:\n"
+"\t{desc|tabindent}"
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr "indisponível suporte ao mysql no python: %s"
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr "gancho do tipo %s não passa um id de changeset"
+
+#, python-format
+msgid "database error: %s"
+msgstr "erro de banco de dados: %s"
+
+msgid "command to display child changesets"
+msgstr "comando para exibir changesets filhos"
+
+msgid ""
+"show the children of the given or working directory revision\n"
+"\n"
+" Print the children of the working directory's revisions. If a\n"
+" revision is given via -r/--rev, the children of that revision will\n"
+" be printed. If a file argument is given, revision in which the\n"
+" file was last changed (after the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"exibe os filhos da revisão pedida ou do diretório de trabalho\n"
+"\n"
+" Imprime os filhos das revisões do diretório de trabalho. Se uma\n"
+" revisão for dada por -r/--rev, imprime os filhos dessa revisão.\n"
+" Se for passado um arquivo como parâmetro, a revisão na qual esse\n"
+" arquivo foi modificado por último (após a revisão do diretório\n"
+" de trabalho ou da passada em --rev) será impressa.\n"
+" "
+
+msgid "show children of the specified revision"
+msgstr "exibe o filho de uma revisão especifica"
+
+msgid "hg children [-r REV] [FILE]"
+msgstr "hg children [-r REV] [ARQUIVO]"
+
+msgid "command to display statistics about repository history"
+msgstr "comando para mostrar estatísticas do histórico do repositório"
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr "Revisão %d é uma mesclagem, ignorando...\n"
+
+#, python-format
+msgid "generating stats: %d%%"
+msgstr "gerando estatísticas: %d%%"
+
+msgid ""
+"histogram of changes to the repository\n"
+"\n"
+" This command will display a histogram representing the number\n"
+" of changed lines or revisions, grouped according to the given\n"
+" template. The default template will group changes by author.\n"
+" The --dateformat option may be used to group the results by\n"
+" date instead.\n"
+"\n"
+" Statistics are based on the number of changed lines, or\n"
+" alternatively the number of matching revisions if the\n"
+" --changesets option is specified.\n"
+"\n"
+" Examples:\n"
+"\n"
+" # display count of changed lines for every committer\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # display daily activity graph\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # display activity of developers by month\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # display count of lines changed in every year\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" It is possible to map alternate email addresses to a main address\n"
+" by providing a file using the following format:\n"
+"\n"
+" <alias email> <actual email>\n"
+"\n"
+" Such a file may be specified with the --aliases option, otherwise a\n"
+" .hgchurn file will be looked for in the working directory root.\n"
+" "
+msgstr ""
+"histograma de mudanças do repositório\n"
+"\n"
+" Este comando exibe um histograma representando o número de linhas\n"
+" alteradas ou revisões, agrupadas de acordo com o modelo pedido.\n"
+" O modelo padrão agrupa mudanças por autor. Alternativamente, a\n"
+" opção --dateformat pode ser usada para agrupar os resultados por\n"
+" data.\n"
+"\n"
+" As estatísticas se baseiam no número de linhas modificadas, ou\n"
+" alternativamente no número de revisões, se for usada a opção\n"
+" --changesets.\n"
+"\n"
+" Exemplos:\n"
+"\n"
+" # exibe a contagem de linhas modificadas para cada autor\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # exibe o gráfico de atividades diárias\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # exibe atividades dos desenvolvedores por mês\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # exibe a contagem de linhas modificadas a cada ano\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" É possível mapear endereços de email alternativos para um\n"
+" endereço principal provendo um arquivo usando o seguinte\n"
+" formato:\n"
+"\n"
+" <email alternativo> <email principal>\n"
+"\n"
+" Esse arquivo pode ser especificado com a opção --aliases; de\n"
+" outro modo, será usado um arquivo .hgchurn no raiz do diretório\n"
+" de trabalho, se existir.\n"
+" "
+
+#, python-format
+msgid "assuming %i character terminal\n"
+msgstr "assumindo terminal de %i caracteres\n"
+
+msgid "count rate for the specified revision or range"
+msgstr "conta a freqüência para uma revisão ou faixa especificada"
+
+msgid "count rate for revisions matching date spec"
+msgstr "conta a freqüência das revisões que casem com a data especificada"
+
+msgid "template to group changesets"
+msgstr "modelo para agrupar os changesets"
+
+msgid "strftime-compatible format for grouping by date"
+msgstr "formato compatível com o strftime para agrupar por data"
+
+msgid "count rate by number of changesets"
+msgstr "conta a freqüência pelo numero de changesets"
+
+msgid "sort by key (default: sort by count)"
+msgstr "ordenar pela chave (padrão: ordenar pela contagem)"
+
+msgid "file with email aliases"
+msgstr "arquivo com apelidos de email"
+
+msgid "show progress"
+msgstr "exibir progresso"
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+msgstr "hg churn [-d DATA] [-r REVISÃO] [--aliases ARQUIVO] [--progress] [ARQUIVO]"
+
+msgid ""
+"colorize output from some commands\n"
+"\n"
+"This extension modifies the status command to add color to its output\n"
+"to reflect file status, the qseries command to add color to reflect\n"
+"patch status (applied, unapplied, missing), and to diff-related\n"
+"commands to highlight additions, removals, diff headers, and trailing\n"
+"whitespace.\n"
+"\n"
+"Other effects in addition to color, like bold and underlined text, are\n"
+"also available. Effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes). This module also provides the\n"
+"render_text function, which can be used to add effects to any text.\n"
+"\n"
+"Default effects may be overridden from the .hgrc file:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' turns off all effects\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+msgstr ""
+"colore a saída de alguns comandos\n"
+"\n"
+"Essa extensão colore a saída dos comandos para realçar diversas\n"
+"informações: no comando status, reflete os estados dos arquivos; no\n"
+"comando qseries, reflete os estados dos patches (aplicado,\n"
+"não-aplicado, faltando); e para comandos relacionados com diff,\n"
+"destaca adições, remoções, cabeçalhos de diffs e espaços em branco\n"
+"no final das linhas.\n"
+"\n"
+"Outros efeitos adicionais às cores, como negrito e sublinhado,\n"
+"também estão disponíveis. Os efeitos são desenhados com a função de\n"
+"controle ECMA-48 SGR (também conhecidos como códigos de escape ANSI).\n"
+"Esse modulo também provê a função render_text, que pode ser utilizada\n"
+"para adicionar efeitos a qualquer texto.\n"
+"\n"
+"Os efeitos padrão podem ser sobrepostos pelo arquivo .hgrc:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' desliga todos os efeitos\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+
+msgid "when to colorize (always, auto, or never)"
+msgstr ""
+"quando colorir (\"always\": sempre, \"never\": nunca ou \"auto\": "
+"automaticamente)"
+
+msgid "don't colorize output"
+msgstr "não colore a saída"
+
+#, python-format
+msgid "ignoring unknown color/effect %r (configured in color.%s)\n"
+msgstr "ignorando cor/efeito desconhecido %r (configurado em color.%s)\n"
+
+msgid "import revisions from foreign VCS repositories into Mercurial"
+msgstr "importa revisões de repositórios de outros sistemas para o Mercurial"
+
+msgid ""
+"convert a foreign SCM repository to a Mercurial one.\n"
+"\n"
+" Accepted source formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Accepted destination formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (history on branches is not preserved)\n"
+"\n"
+" If no revision is given, all revisions will be converted.\n"
+" Otherwise, convert will only import up to the named revision\n"
+" (given in a format understood by the source).\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source with '-hg' appended. If the destination\n"
+" repository doesn't exist, it will be created.\n"
+"\n"
+" By default, all sources except Mercurial will use\n"
+" --branchsort. Mercurial uses --sourcesort to preserve original\n"
+" revision numbers order. Sort modes have the following effects:\n"
+" --branchsort: convert from parent to child revision when\n"
+" possible, which means branches are usually converted one after\n"
+" the other. It generates more compact repositories.\n"
+" --datesort: sort revisions by date. Converted repositories have\n"
+" good-looking changelogs but are often an order of magnitude\n"
+" larger than the same ones generated by --branchsort.\n"
+" --sourcesort: try to preserve source revisions order, only\n"
+" supported by Mercurial sources.\n"
+"\n"
+" If <REVMAP> isn't given, it will be put in a default location\n"
+" (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file\n"
+" that maps each source commit ID to the destination ID for that\n"
+" revision, like so:\n"
+" <source ID> <destination ID>\n"
+"\n"
+" If the file doesn't exist, it's automatically created. It's\n"
+" updated on each commit copied, so convert-repo can be interrupted\n"
+" and can be run repeatedly to copy new commits.\n"
+"\n"
+" The [username mapping] file is a simple text file that maps each\n"
+" source commit author to a destination commit author. It is handy\n"
+" for source SCMs that use unix logins to identify authors (eg:\n"
+" CVS). One line per author mapping and the line format is:\n"
+" srcauthor=whatever string you want\n"
+"\n"
+" The filemap is a file that allows filtering and remapping of files\n"
+" and directories. Comment lines start with '#'. Each line can\n"
+" contain one of the following directives:\n"
+"\n"
+" include path/to/file\n"
+"\n"
+" exclude path/to/file\n"
+"\n"
+" rename from/file to/file\n"
+"\n"
+" The 'include' directive causes a file, or all files under a\n"
+" directory, to be included in the destination repository, and the\n"
+" exclusion of all other files and directories not explicitly included.\n"
+" The 'exclude' directive causes files or directories to be omitted.\n"
+" The 'rename' directive renames a file or directory. To rename from\n"
+" a subdirectory into the root of the repository, use '.' as the\n"
+" path to rename to.\n"
+"\n"
+" The splicemap is a file that allows insertion of synthetic\n"
+" history, letting you specify the parents of a revision. This is\n"
+" useful if you want to e.g. give a Subversion merge two parents, or\n"
+" graft two disconnected series of history together. Each entry\n"
+" contains a key, followed by a space, followed by one or two\n"
+" comma-separated values. The key is the revision ID in the source\n"
+" revision control system whose parents should be modified (same\n"
+" format as a key in .hg/shamap). The values are the revision IDs\n"
+" (in either the source or destination revision control system) that\n"
+" should be used as the new parents for that node.\n"
+"\n"
+" The branchmap is a file that allows you to rename a branch when it is\n"
+" being brought in from whatever external repository. When used in\n"
+" conjunction with a splicemap, it allows for a powerful combination\n"
+" to help fix even the most badly mismanaged repositories and turn them\n"
+" into nicely structured Mercurial repositories. The branchmap contains\n"
+" lines of the form \"original_branch_name new_branch_name\".\n"
+" \"original_branch_name\" is the name of the branch in the source\n"
+" repository, and \"new_branch_name\" is the name of the branch is the\n"
+" destination repository. This can be used to (for instance) move code\n"
+" in one repository from \"default\" to a named branch.\n"
+"\n"
+" Mercurial Source\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (boolean)\n"
+" ignore integrity errors when reading. Use it to fix Mercurial\n"
+" repositories with missing revlogs, by converting from and to\n"
+" Mercurial.\n"
+" --config convert.hg.saverev=False (boolean)\n"
+" store original revision ID in changeset (forces target IDs to\n"
+" change)\n"
+" --config convert.hg.startrev=0 (hg revision identifier)\n"
+" convert start revision and its descendants\n"
+"\n"
+" CVS Source\n"
+" ----------\n"
+"\n"
+" CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+" to indicate the starting point of what will be converted. Direct\n"
+" access to the repository files is not needed, unless of course the\n"
+" repository is :local:. The conversion uses the top level directory\n"
+" in the sandbox to find the CVS repository, and then uses CVS rlog\n"
+" commands to find files to convert. This means that unless a\n"
+" filemap is given, all files under the starting directory will be\n"
+" converted, and that any directory reorganization in the CVS\n"
+" sandbox is ignored.\n"
+"\n"
+" Because CVS does not have changesets, it is necessary to collect\n"
+" individual commits to CVS and merge them into changesets. CVS\n"
+" source uses its internal changeset merging code by default but can\n"
+" be configured to call the external 'cvsps' program by setting:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" This option is deprecated and will be removed in Mercurial 1.4.\n"
+"\n"
+" The options shown are the defaults.\n"
+"\n"
+" Internal cvsps is selected by setting\n"
+" --config convert.cvsps=builtin\n"
+" and has a few more configurable options:\n"
+" --config convert.cvsps.cache=True (boolean)\n"
+" Set to False to disable remote log caching, for testing and\n"
+" debugging purposes.\n"
+" --config convert.cvsps.fuzz=60 (integer)\n"
+" Specify the maximum time (in seconds) that is allowed\n"
+" between commits with identical user and log message in a\n"
+" single changeset. When very large files were checked in as\n"
+" part of a changeset then the default may not be long\n"
+" enough.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will insert a dummy revision merging the branch on\n"
+" which this log message occurs to the branch indicated in\n"
+" the regex.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will add the most recent revision on the branch\n"
+" indicated in the regex as the second parent of the\n"
+" changeset.\n"
+"\n"
+" The hgext/convert/cvsps wrapper script allows the builtin\n"
+" changeset merging code to be run without doing a conversion. Its\n"
+" parameters and output are similar to that of cvsps 2.1.\n"
+"\n"
+" Subversion Source\n"
+" -----------------\n"
+"\n"
+" Subversion source detects classical trunk/branches/tags layouts.\n"
+" By default, the supplied \"svn://repo/path/\" source URL is\n"
+" converted as a single branch. If \"svn://repo/path/trunk\" exists it\n"
+" replaces the default branch. If \"svn://repo/path/branches\" exists,\n"
+" its subdirectories are listed as possible branches. If\n"
+" \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
+" converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
+" can be overridden with following options. Set them to paths\n"
+" relative to the source URL, or leave them blank to disable auto\n"
+" detection.\n"
+"\n"
+" --config convert.svn.branches=branches (directory name)\n"
+" specify the directory containing branches\n"
+" --config convert.svn.tags=tags (directory name)\n"
+" specify the directory containing tags\n"
+" --config convert.svn.trunk=trunk (directory name)\n"
+" specify the name of the trunk branch\n"
+"\n"
+" Source history can be retrieved starting at a specific revision,\n"
+" instead of being integrally converted. Only single branch\n"
+" conversions are supported.\n"
+"\n"
+" --config convert.svn.startrev=0 (svn revision number)\n"
+" specify start Subversion revision.\n"
+"\n"
+" Perforce Source\n"
+" ---------------\n"
+"\n"
+" The Perforce (P4) importer can be given a p4 depot path or a\n"
+" client specification as source. It will convert all files in the\n"
+" source to a flat Mercurial repository, ignoring labels, branches\n"
+" and integrations. Note that when a depot path is given you then\n"
+" usually should specify a target directory, because otherwise the\n"
+" target may be named ...-hg.\n"
+"\n"
+" It is possible to limit the amount of source history to be\n"
+" converted by specifying an initial Perforce revision.\n"
+"\n"
+" --config convert.p4.startrev=0 (perforce changelist number)\n"
+" specify initial Perforce revision.\n"
+"\n"
+"\n"
+" Mercurial Destination\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (boolean)\n"
+" dispatch source branches in separate clones.\n"
+" --config convert.hg.tagsbranch=default (branch name)\n"
+" tag revisions branch name\n"
+" --config convert.hg.usebranchnames=True (boolean)\n"
+" preserve branch names\n"
+"\n"
+" "
+msgstr ""
+"converte um repositório de um outro sistema em um do Mercurial.\n"
+"\n"
+" Formatos de origem aceitos [identificadores]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Formatos de destino aceitos [identificadores]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (histórico em ramos não é preservado)\n"
+"\n"
+" Se não for dada nenhuma revisão, todas serão convertidas. Caso,\n"
+" contrário, a conversão irá importar apenas até a revisão nomeada\n"
+" (dada num formato entendido pela origem).\n"
+"\n"
+" Se não for especificado o nome do diretório de destino, o padrão\n"
+" será o nome base com '-hg' anexado. Se o repositório de destino\n"
+" não existir, ele será criado.\n"
+"\n"
+" Por padrão, a conversão de todas as origens exceto do Mercurial\n"
+" usará --branchsort. O Mercurial usa --sourcesort para preservar\n"
+" a ordem de números de revisão original. Modos de ordenação têm\n"
+" os seguintes efeitos:\n"
+" --branchsort: converte de revisão pai para filha quando\n"
+" possível, o que faz com que ramos sejam usualmente\n"
+" convertidos um após o outro. Esta opção gera repositórios\n"
+" mais compactos.\n"
+" --datesort: ordena revisões por data. Os repositórios\n"
+" convertidos tendem a ter changelogs de boa aparência, mas\n"
+" algumas vezes são uma ordem de grandeza maiores que os\n"
+" mesmos gerados por --branchsort.\n"
+" --sourcesort: tenta preservar a ordem de revisões da origem,\n"
+" suportada apenas pela origem Mercurial.\n"
+"\n"
+" Se não for dado o <REVMAP>, ele será posto em um local padrão\n"
+" (<destino>/.hg/shamap). O <REVMAP> é um simples arquivo texto\n"
+" que mapeia cada ID de commit da origem para o ID de destino para\n"
+" aquela revisão, da seguinte forma:\n"
+" <ID origem> <ID destino>\n"
+"\n"
+" Se o arquivo não existir, será automaticamente criado. Ele é\n"
+" atualizado a cada commit copiado, assim a conversão pode ser\n"
+" interrompida e executada repetidamente para copiar novos commits.\n"
+"\n"
+" O arquivo [mapa de nome de usuário] é um arquivo texto simples\n"
+" que mapeia cada autor de commit da origem para um autor de commit\n"
+" no destino. Isso é uma ajuda para sistemas de origem que utilizam\n"
+" logins unix para identificar os autores (ex: CVS). Uma linha por\n"
+" mapeamento de autor no formato:\n"
+" autor_origem=qualquer string que você quiser\n"
+"\n"
+" O filemap é um arquivo que permite filtrar e remapear arquivos e\n"
+" diretórios. Linhas de comentário iniciam com '#'. Cada linha\n"
+" pode conter uma das seguintes diretivas:\n"
+"\n"
+" include caminho/para/o/arquivo\n"
+"\n"
+" exclude caminho/para/o/arquivo\n"
+"\n"
+" rename arquivo/origem to arquivo/destino\n"
+"\n"
+" A diretiva 'include' faz com que um arquivo, ou todos os arquivos\n"
+" em um diretório, sejam incluídos no repositório de destino, e\n"
+" também exclui todos os outros arquivos e diretórios não incluídos\n"
+" explicitamente. A diretiva 'exclude' faz com que os arquivos e\n"
+" diretórios sejam omitidos. A diretiva 'rename' renomeia um\n"
+" arquivo ou diretório. Para renomear de um subdiretório para o\n"
+" raiz do repositório, use '.' como caminho de destino.\n"
+"\n"
+" O splicemap é um arquivo que permite a inserção de histórico\n"
+" sintético, permitindo que você especifique os pais de uma\n"
+" revisão. Isto é útil se você por exemplo quiser que um merge do\n"
+" Subversion tenha dois pais, ou para juntar duas linhas desconexas\n"
+" de histórico. Cada entrada contém uma chave, seguida de um\n"
+" espaço, seguido de um ou mais valores separados por vírgulas. A\n"
+" chave é o identificador de revisão no sistema de controle de\n"
+" versão de origem cujos pais devam ser modificados (mesmo formato\n"
+" de uma chave em .hg/shamap). Os valores são os identificadores de\n"
+" revisão (no sistema de origem ou no de destino) que devem ser\n"
+" usados como os novos pais daquele nó.\n"
+"\n"
+" O branchmap é um arquivo que permite a renomeação de um ramo\n"
+" quando este for trazido de um repositório externo qualquer. Se\n"
+" usado em conjunto com um splicemap, fornece uma poderosa\n"
+" combinação que auxilia o conserto de repositórios mal\n"
+" gerenciados, transformando-os em repositórios Mercurial\n"
+" estruturados apropriadamente. O branchmap contém linhas da forma\n"
+" \"nome_ramo_original nome_novo_ramo\". \"nome_ramo_original\" é\n"
+" o nome do ramo no repositório de origem, e \"nome_novo_ramo\" é\n"
+" o nome do ramo no repositório de destino. Isto pode ser usado\n"
+" para por exemplo mover código em um repositório de \"default\"\n"
+" para um ramo nomeado.\n"
+"\n"
+" Origem Mercurial\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (booleana)\n"
+" ignora erros de integridade ao ler. Use-a para corrigir\n"
+" repositórios do Mercurial com revlogs faltando, através da\n"
+" conversão para outro repositório do Mercurial.\n"
+" --config convert.hg.saverev=False (booleana)\n"
+" armazena o identificador de revisão original no changeset\n"
+" (isso força o identificador de destino a mudar)\n"
+" --config convert.hg.startrev=0 (id de revisão do hg)\n"
+" converte a revisão inicial e seus descendentes\n"
+"\n"
+" Origem CVS\n"
+" ----------\n"
+"\n"
+" A origem CVS usará uma cópia local do CVS para indicar o ponto\n"
+" inicial do que será convertido. Não é necessário acesso direto ao\n"
+" repositório, a não ser é claro que o repositório seja :local:. A\n"
+" conversão usa o diretório do topo da cópia local para encontrar\n"
+" o repositório CVS, e em seguida o comando CVS rlog para encontrar\n"
+" os arquivos a serem convertidos. Isto quer dizer que a não ser\n"
+" que um filemap seja dado, todos os arquivos sob o diretório de\n"
+" início serão convertidos, e que qualquer reorganização na cópia\n"
+" local do CVS é ignorada.\n"
+"\n"
+" Como o CVS não possui changesets, é necessário coletar commits\n"
+" individuais do CVS e mesclá-los em changesets. A origem CVS usa\n"
+" seu código interno de mesclagem por padrão, mas pode ser\n"
+" configurada para chamar o utilitário externo 'cvsps' definindo:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" Esta opção é obsoleta e será removida no Mercurial 1.4.\n"
+"\n"
+" As opções exibidas são os valores padrão.\n"
+"\n"
+" O cvsps interno é selecionado com\n"
+" --config convert.cvsps=builtin\n"
+" e possui algumas outras opções de configuração:\n"
+" --config convert.cvsps.cache=True (booleana)\n"
+" Defina como False para desabilitar o cache do log\n"
+" remoto, para teste ou depuração.\n"
+" --config convert.cvsps.fuzz=60 (inteiro)\n"
+" Especifica o tempo máximo (em segundos) permitido entre\n"
+" commits com usuário e mensagem de log em um único\n"
+" changeset. Se arquivos muito grandes forem armazenados\n"
+" como parte de um changeset, o padrão pode não ser\n"
+" suficiente.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Especifica uma expressão regular com a qual mensagens de\n"
+" log de commit são verificadas. Se um casamento for\n"
+" encontrado, a conversão inserirá uma revisão artificial\n"
+" mesclando o ramo onde essa mensagem de log aparece ao\n"
+" ramo indicado na expressão regular.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Especifica uma expressão regular com a qual mensagens de\n"
+" log de commit são verificadas. Se um casamento for\n"
+" encontrado, a conversão inserirá a revisão mais recente\n"
+" do ramo indicado na expressão regular como segundo pai do\n"
+" changeset.\n"
+"\n"
+" O script hgext/convert/cvsps permite que o código de mesclagem\n"
+" interno seja executado fora do processo de conversão. Seus\n"
+" parâmetros e saída são semelhantes aos do cvsps 2.1.\n"
+"\n"
+" Origem Subversion\n"
+" -----------------\n"
+"\n"
+" A origem Subversion detecta a organização clássica\n"
+" trunk/branches/tags . Por padrão, a URL de origem\n"
+" \"svn://repo/path/\" fornecida é convertida como um único ramo.\n"
+" Se \"svn://repo/path/trunk\" existir, irá substituir o ramo\n"
+" default. Se \"svn://repo/path/branches\" existir, seus\n"
+" subdiretórios serão listados como possíveis ramos. Se\n"
+" \"svn://repo/path/tags\" existir, será consultado para tags\n"
+" referenciando ramos convertidos. Os valores padrão \"trunk\",\n"
+" \"branches\" e \"tags\" podem ser sobrepostos pelas seguintes\n"
+" opções. Defina-os como caminhos relativos à URL de origem, ou\n"
+" deixe-os em branco para desabilitar a auto-detecção.\n"
+"\n"
+" --config convert.svn.branches=branches (nome de diretório)\n"
+" especifica o diretório contendo ramos\n"
+" --config convert.svn.tags=tags (nome de diretório)\n"
+" especifica o diretório contendo tags\n"
+" --config convert.svn.trunk=trunk (nome de diretório)\n"
+" especifica o nome do ramo trunk\n"
+"\n"
+" O histórico de origem pode ser recuperado a partir de uma revisão\n"
+" específica, ao invés de ser convertido integralmente. Apenas\n"
+" conversões de um único ramo são suportadas.\n"
+"\n"
+" --config convert.svn.startrev=0 (número de revisão svn)\n"
+" especifica a revisão inicial do Subversion.\n"
+"\n"
+" Origem Perforce\n"
+" ---------------\n"
+"\n"
+" O importador Perforce (P4) pode receber um caminho de depot p4 ou\n"
+" uma especificação de cliente como origem. Ele irá converter todos\n"
+" os arquivos da origem para um repositório achatado do Mercurial,\n"
+" ignorando labels, branches e integrações. Note que quando é dado\n"
+" um caminho de depot você precisa tipicamente especificar um\n"
+" diretório de destino, caso contrário o destino pode ser chamado\n"
+" ...-hg.\n"
+"\n"
+" É possível limitar a quantidade de histórico de origem a ser\n"
+" convertida especificando uma revisão inicial do Perforce.\n"
+"\n"
+" --config convert.p4.startrev=0 (número de changelist p4)\n"
+" especifica a revisão inicial do Perforce.\n"
+"\n"
+"\n"
+" Destino Mercurial\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (booleana)\n"
+" separa ramos da origem em diferentes clones.\n"
+" --config convert.hg.tagsbranch=default (nome de ramo)\n"
+" nome do ramo para revisões de etiqueta\n"
+" --config convert.hg.usebranchnames=True (booleana)\n"
+" preserva nomes de ramo\n"
+"\n"
+" "
+
+msgid ""
+"create changeset information from CVS\n"
+"\n"
+" This command is intended as a debugging tool for the CVS to\n"
+" Mercurial converter, and can be used as a direct replacement for\n"
+" cvsps.\n"
+"\n"
+" Hg debugcvsps reads the CVS rlog for current directory (or any\n"
+" named directory) in the CVS repository, and converts the log to a\n"
+" series of changesets based on matching commit log entries and\n"
+" dates."
+msgstr ""
+"cria uma informação de changeset do CVS\n"
+"\n"
+" Esse comando serve como ferramenta de depuração para o conversor\n"
+" do CVS para o Mercurial e pode ser usado como um substituto\n"
+" direto do cvsps.\n"
+"\n"
+" Hg debugcvsps lê o rlog do CVS para o diretório atual (ou\n"
+" qualquer diretório nomeado) no repositório do CVS e converte o\n"
+" log em uma série de changesets baseado na correspondência das\n"
+" entradas no log de commit e datas."
+
+msgid "username mapping filename"
+msgstr "arquivo de mapeamento de nomes de usuário"
+
+msgid "destination repository type"
+msgstr "tipo de repositório de destino"
+
+msgid "remap file names using contents of file"
+msgstr "arquivo de mapeamento de nomes de arquivo"
+
+msgid "import up to target revision REV"
+msgstr "importa até a revisão REV do alvo"
+
+msgid "source repository type"
+msgstr "tipo de repositório de origem"
+
+msgid "splice synthesized history into place"
+msgstr "junta o histórico sintetizado no lugar"
+
+msgid "change branch names while converting"
+msgstr "muda nomes de ramos durante a conversão"
+
+msgid "try to sort changesets by branches"
+msgstr "tenta ordenar os changesets por ramos"
+
+msgid "try to sort changesets by date"
+msgstr "tenta ordenar os changesets por data"
+
+msgid "preserve source changesets order"
+msgstr "preserva a ordem de changesets da origem"
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr "hg convert [OPÇÃO]... ORIGEM [DESTINO [REVMAP]]"
+
+msgid "only return changes on specified branches"
+msgstr "só retorna changesets no ramo especificado"
+
+msgid "prefix to remove from file names"
+msgstr "prefixo para remover dos nomes dos arquivos"
+
+msgid "only return changes after or between specified tags"
+msgstr "só retorna alterações anteriores ou entre as tags especificadas"
+
+msgid "update cvs log cache"
+msgstr "atualiza a cache do log do cvs"
+
+msgid "create new cvs log cache"
+msgstr "cria uma nova cache de log do cvs"
+
+msgid "set commit time fuzz in seconds"
+msgstr "define o valor de indistinção da hora de consolidação em segundos"
+
+msgid "specify cvsroot"
+msgstr "especifica o cvsroot"
+
+msgid "show parent changesets"
+msgstr "exibe os pais do changesets"
+
+msgid "show current changeset in ancestor branches"
+msgstr "exibe o changeset atual nos ramos ancestrais"
+
+msgid "ignored for compatibility"
+msgstr "ignorada para compatibilidade"
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr "hg debugcvsps [OPÇÃO]... [CAMINHO]..."
+
+msgid ""
+"warning: lightweight checkouts may cause conversion failures, try with a "
+"regular branch instead.\n"
+msgstr ""
+"aviso: checkouts \"lightweight\" podem causar falhas de conversão, tente com "
+"um branch comum.\n"
+
+msgid "bzr source type could not be determined\n"
+msgstr "o tipo de origem bzr não pôde ser determinado\n"
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr "%s não é uma revisão válida no ramo atual"
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr "%s não está mais disponível em %s"
+
+#, python-format
+msgid "%s.%s symlink has no target"
+msgstr "%s.%s link simbólico não possui alvo"
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr "não foi possível encontrar ferramenta \"%s\" necessária"
+
+#, python-format
+msgid "running: %s\n"
+msgstr "executando: %s\n"
+
+#, python-format
+msgid "%s error:\n"
+msgstr "erro no comando %s:\n"
+
+#, python-format
+msgid "syntax error in %s(%d): key/value pair expected"
+msgstr "erro de sintaxe em %s(%d): esperado par chave/valor"
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr "não foi possível abrir arquivo de mapeamento %r: %s"
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr "%s: repositório ausente ou não suportado"
+
+#, python-format
+msgid "convert: %s\n"
+msgstr "convert: %s\n"
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr "%s: tipo de repositório desconhecido"
+
+#, python-format
+msgid "unknown sort mode: %s"
+msgstr "modo de ordenação desconhecido: %s"
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr "ciclo detectado entre %s e %s"
+
+msgid "not all revisions were sorted"
+msgstr "nem todas as revisões foram ordenadas"
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr "Escrevendo arquivo de mapeamento de autor %s\n"
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr "Ignorando linha inválida no arquivo de mapeamento de autor %s: %s\n"
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr "mapeando autor %s para %s\n"
+
+#, python-format
+msgid "overriding mapping for author %s, was %s, will be %s\n"
+msgstr "sobrepondo mapeamento para autor %s, era %s, será %s\n"
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr "associados %s como pais de %s\n"
+
+msgid "scanning source...\n"
+msgstr "decodificando entrada...\n"
+
+msgid "sorting...\n"
+msgstr "ordenando...\n"
+
+msgid "converting...\n"
+msgstr "convertendo...\n"
+
+#, python-format
+msgid "source: %s\n"
+msgstr "origem: %s\n"
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr "assumindo destino %s\n"
+
+msgid "more than one sort mode specified"
+msgstr "mais de um modo de ordenação especificado"
+
+msgid "--sourcesort is not supported by this data source"
+msgstr "--sourcesort não é suportado para esta origem de dados"
+
+msgid ""
+"warning: support for external cvsps is deprecated and will be removed in "
+"Mercurial 1.4\n"
+msgstr ""
+"aviso: o suporte para o cvsps externo é obsoleto e será removido no "
+"Mercurial 1.4\n"
+
+#, python-format
+msgid "revision %s is not a patchset number or date"
+msgstr "revisão %s não é um número de patchset ou data"
+
+msgid "using builtin cvsps\n"
+msgstr "usando cvsps interno\n"
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr "conectando em %s\n"
+
+msgid "CVS pserver authentication failed"
+msgstr "autenticação pserver do CVS falhou"
+
+#, python-format
+msgid "unexpected response from CVS server (expected \"Valid-requests\", but got %r)"
+msgstr ""
+"resposta inesperada do servidor CVS (\"Valid-requests\" esperada, %r "
+"recebida)"
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr "%d bytes faltando no arquivo remoto"
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr "servidor cvs: %s\n"
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr "resposta do CVS desconhecida: %s"
+
+msgid "collecting CVS rlog\n"
+msgstr "coletando rlog do CVS\n"
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr "lendo cache de log do CVS %s\n"
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr "cache possui %d entradas de log\n"
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr "erro lendo cache: %r\n"
+
+#, python-format
+msgid "running %s\n"
+msgstr "executando %s\n"
+
+#, python-format
+msgid "prefix=%r directory=%r root=%r\n"
+msgstr "prefixo=%r diretório=%r raiz=%r\n"
+
+msgid "RCS file must be followed by working file"
+msgstr "arquivo RCS deve ser seguido de um arquivo de trabalho"
+
+msgid "must have at least some revisions"
+msgstr "deve possuir ao menos algumas revisões"
+
+msgid "expected revision number"
+msgstr "número de revisão esperado"
+
+msgid "revision must be followed by date line"
+msgstr "revisão deve ser seguida por uma linha de data"
+
+#, python-format
+msgid "found synthetic revision in %s: %r\n"
+msgstr "revisão sintética encontrada em %s:%r\n"
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr "escrevendo cache do log do CVS %s\n"
+
+#, python-format
+msgid "%d log entries\n"
+msgstr "%d entradas de log\n"
+
+msgid "creating changesets\n"
+msgstr "criando changesets\n"
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr "um changeset sintético não pode ter múltiplos pais"
+
+#, python-format
+msgid ""
+"warning: CVS commit message references non-existent branch %r:\n"
+"%s\n"
+msgstr ""
+"aviso: a mensagem de commit do CVS se refere a um branch inexistente %r:\n"
+"%s\n"
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr "%d entradas de changeset\n"
+
+#, python-format
+msgid "darcs version 2.1 or newer needed (found %r)"
+msgstr "necessária versão do darcs 2.1 ou posterior (%r encontrada)"
+
+msgid "Python ElementTree module is not available"
+msgstr "módulo ElementTree do Python não está disponível"
+
+#, python-format
+msgid "cleaning up %s\n"
+msgstr "limpando %s\n"
+
+msgid "internal calling inconsistency"
+msgstr "inconsistência interna de chamadas"
+
+msgid "errors in filemap"
+msgstr "erros no filemap"
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr "%s:%d: %r já faz parte da lista %s\n"
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr "%s:%d: diretiva desconhecida %r\n"
+
+msgid "source repository doesn't support --filemap"
+msgstr "repositório de origem não suporta --filemap"
+
+#, python-format
+msgid "%s does not look like a GNU Arch repo"
+msgstr "%s não parece ser um repositório do GNU Arch"
+
+msgid "cannot find a GNU Arch tool"
+msgstr "não é possível encontrar uma ferramenta do GNU Arch"
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr "analisando versão da árvore %s...\n"
+
+#, python-format
+msgid "tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr ""
+"análise da árvore parou porque esta aponta para um arquivo não registrado %"
+"s...\n"
+
+#, python-format
+msgid "applying revision %s...\n"
+msgstr "aplicando revisão %s...\n"
+
+#, python-format
+msgid "computing changeset between %s and %s...\n"
+msgstr "computando changeset entre %s e %s...\n"
+
+#, python-format
+msgid "obtaining revision %s...\n"
+msgstr "obtendo revisão %s...\n"
+
+#, python-format
+msgid "analyzing revision %s...\n"
+msgstr "analisando revisão %s...\n"
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr "não foi possível decodificar cat-log de %s"
+
+#, python-format
+msgid "%s is not a local Mercurial repo"
+msgstr "%s não é um repositório local do Mercurial"
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr "iniciando repositório de destino %s\n"
+
+msgid "run hg sink pre-conversion action\n"
+msgstr "executa ação pré-conversão do destino hg\n"
+
+msgid "run hg sink post-conversion action\n"
+msgstr "executa ação pós-conversão do destino hg\n"
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr "trazendo de %s para %s\n"
+
+msgid "filtering out empty revision\n"
+msgstr "filtrando revisão vazia\n"
+
+msgid "updating tags\n"
+msgstr "atualizando tags\n"
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr "%s não é uma revisão inicial válida"
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr "ignorando: %s\n"
+
+msgid "run hg source pre-conversion action\n"
+msgstr "executa ação pré-conversão da origem hg\n"
+
+msgid "run hg source post-conversion action\n"
+msgstr "executa ação pós-conversão da origem hg\n"
+
+#, python-format
+msgid "%s does not look like a monotone repo"
+msgstr "%s não parece um repositório do Monotone"
+
+#, python-format
+msgid "copying file in renamed directory from '%s' to '%s'"
+msgstr "copiando arquivo em diretório renomeado de '%s' para '%s'"
+
+msgid "reading p4 views\n"
+msgstr "lendo 'p4 views'\n"
+
+msgid "collecting p4 changelists\n"
+msgstr "coletando changelists do p4\n"
+
+msgid "Subversion python bindings could not be loaded"
+msgstr "Os módulos Python para o Subversion não puderam ser carregados"
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr ""
+"Encontrados módulos Python para o Subversion %d.%d, requerida a versão 1.4 "
+"ou posterior"
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr ""
+"Módulos Python para o Subversion são antigos demais, requerida a versão 1.4 "
+"ou posterior"
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr "svn: revisão %s não é um inteiro"
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr "svn: revisão inicial %s não é um inteiro"
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr "nenhuma revisão encontrada no módulo %s"
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr "%s esperado em %r, mas não encontrado"
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr "encontrado %s em %r\n"
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr "ignorando ramo vazio %s\n"
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr "encontrado ramo %s em %d\n"
+
+msgid "svn: start revision is not supported with more than one branch"
+msgstr "svn: revisão inicial não é suportada com mais de um ramo"
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr "svn: nenhuma revisão encontrada após revisão inicial %d"
+
+#, python-format
+msgid "no tags found at revision %d\n"
+msgstr "nenhuma tag encontrada na revisão %d\n"
+
+#, python-format
+msgid "ignoring foreign branch %r\n"
+msgstr "ignorado ramo estrangeiro %r\n"
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr "%s não encontrado até revisão %d"
+
+#, python-format
+msgid "branch renamed from %s to %s at %d\n"
+msgstr "ramo renomeado de %s para %s em %d\n"
+
+#, python-format
+msgid "reparent to %s\n"
+msgstr "pai mudado para %s\n"
+
+#, python-format
+msgid "copied to %s from %s@%s\n"
+msgstr "copiado para %s a partir de %s@%s\n"
+
+#, python-format
+msgid "gone from %s\n"
+msgstr "ido de %s\n"
+
+#, python-format
+msgid "entry %s\n"
+msgstr "entrada %s\n"
+
+#, python-format
+msgid "unknown path in revision %d: %s\n"
+msgstr "caminho desconhecido na revisão %d: %s\n"
+
+#, python-format
+msgid "mark %s came from %s:%d\n"
+msgstr "marcador %s veio de %s:%d\n"
+
+#, python-format
+msgid "parsing revision %d (%d changes)\n"
+msgstr "decodificando revisão %d (%d mudanças)\n"
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr "encontrado pai do ramo %s em %d: %s\n"
+
+msgid "no copyfrom path, don't know what to do.\n"
+msgstr "sem caminho copyfrom, não sei o que fazer.\n"
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr "obtendo log da revisão para \"%s\" de %d até %d\n"
+
+#, python-format
+msgid "revision %d has no entries\n"
+msgstr "revisão %d não tem entradas\n"
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr "svn: ramo não tem a revisão %s"
+
+#, python-format
+msgid "%r is not under %r, ignoring\n"
+msgstr "%r não está abaixo de %r, ignorando\n"
+
+#, python-format
+msgid "initializing svn repo %r\n"
+msgstr "iniciando repositório svn %r\n"
+
+#, python-format
+msgid "initializing svn wc %r\n"
+msgstr "iniciando svn wc %r\n"
+
+msgid "unexpected svn output:\n"
+msgstr "saída do svn inesperada:\n"
+
+msgid "unable to cope with svn output"
+msgstr "incapaz de lidar com saída do svn"
+
+msgid "XXX TAGS NOT IMPLEMENTED YET\n"
+msgstr "XXX TAGS AINDA NÃO IMPLEMENTADAS\n"
+
+msgid ""
+"command to allow external programs to compare revisions\n"
+"\n"
+"The `extdiff' Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working directory. The external diff\n"
+"programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare.\n"
+"\n"
+"The `extdiff' extension also allows to configure new diff commands, so\n"
+"you do not need to type \"hg extdiff -p kdiff3\" always.\n"
+"\n"
+" [extdiff]\n"
+" # add new command that runs GNU diff(1) in 'context diff' mode\n"
+" cdiff = gdiff -Nprc5\n"
+" ## or the old way:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # add new command called vdiff, runs kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # add new command called meld, runs meld (no need to name twice)\n"
+" meld =\n"
+"\n"
+" # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+" # (see http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Non English user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" "
+"in\n"
+" # your .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"You can use -I/-X and list of file or directory names like normal \"hg\n"
+"diff\" command. The `extdiff' extension makes snapshots of only needed\n"
+"files, so running the external diff program will actually be pretty\n"
+"fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+"comando que usa programas externos para comparar revisões\n"
+"\n"
+"A extensão `extdiff' do Mercurial permite o uso de programas externos\n"
+"para comparar revisões ou revisões e a cópia local. Os programas de\n"
+"diff externos são chamados com um conjunto configurável de opções e\n"
+"dois argumentos: caminhos para diretórios contendo cópias temporárias\n"
+"dos arquivos a serem comparados.\n"
+"\n"
+"A extensão `extdiff' também permite configurar novos comandos\n"
+"de diff, de modo que você não precise sempre digitar\n"
+"\"hg extdiff -p kdiff3\".\n"
+"\n"
+" [extdiff]\n"
+" # adiciona um novo comando que executa o GNU diff(1) em modo\n"
+" # 'context diff'\n"
+" cdiff = gdiff -Nprc5\n"
+" ## ou do modo antigo:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # adiciona um novo comando chamado vdiff, executa o kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # adiciona um novo comando chamado meld, executa o meld\n"
+" # (não é necessário nomeá-lo duas vezes)\n"
+" meld =\n"
+"\n"
+" # adiciona um novo comando chamado vimdiff, executa gvimdiff\n"
+" # com o plugin DirDiff\n"
+" #(veja http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Esteja certo de colocar \"let g:DirDiffDynamicDiffText = 1\"\n"
+" # em seu .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"Você pode usar -I/-X e uma lista de nomes de arquivos ou diretórios\n"
+"como no comando \"hg diff\" normal. A extensão `extdiff' faz cópias\n"
+"temporárias apenas dos arquivos necessários, de modo que a execução\n"
+"do diff externo seja rápida (ao menos mais rápida que comparar a\n"
+"árvore completa).\n"
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr "fazendo fotografia de %d arquivos da revisão %s\n"
+
+#, python-format
+msgid "making snapshot of %d files from working directory\n"
+msgstr "fazendo fotografia de %d arquivos do diretório de trabalho\n"
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr "não é possível especificar simultaneamente --rev e --change"
+
+#, python-format
+msgid "running %r in %s\n"
+msgstr "executando %r no %s\n"
+
+#, python-format
+msgid "file changed while diffing. Overwriting: %s (src: %s)\n"
+msgstr ""
+"arquivo modificado durante execução do diff. Sobrescrevendo: %s (origem: %"
+"s)\n"
+
+msgid "cleaning up temp directory\n"
+msgstr "limpando o diretório temporário\n"
+
+msgid ""
+"use external program to diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files, using\n"
+" an external program. The default program used is diff, with\n"
+" default options \"-Npru\".\n"
+"\n"
+" To select a different program, use the -p/--program option. The\n"
+" program will be passed the names of two directories to compare. To\n"
+" pass additional options to the program, use -o/--option. These\n"
+" will be passed before the names of the directories to compare.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent."
+msgstr ""
+"usa um programa externo para exibir diffs do repositório ou arquivos\n"
+"\n"
+" Mostra diferenças entre revisões para os arquivos especificados,\n"
+" usando um programa externo. O programa padrão usado é o diff, com\n"
+" as opções padrão \"-Npru\".\n"
+"\n"
+" Para selecionar um programa diferente, use a opção -p/--program.\n"
+" Ao programa serão passados os nomes de dois diretórios para\n"
+" comparar. Para passar opções adicionais para o programa, use a\n"
+" opção -o/--option. Estas serão passadas antes dos nomes dos\n"
+" diretórios a serem comparados.\n"
+"\n"
+" Quando dois argumentos de revisão forem dados, são exibidas as\n"
+" mudanças entre essas revisões. Se apenas uma revisão for\n"
+" especificada, tal revisão será comparada com o diretório de\n"
+" trabalho, e se nenhuma revisão for especificada, os arquivos do\n"
+" diretório de trabalho serão comparados com seu pai."
+
+msgid "comparison program to run"
+msgstr "programa de comparação a executar"
+
+msgid "pass option to comparison program"
+msgstr "passa opções para o programa de comparação"
+
+msgid "change made by revision"
+msgstr "mudança feita pela revisão"
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr "hg extdiff [OPÇÃO]... [ARQUIVO]..."
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr "hg %s [OPÇÃO]... [ARQUIVO]..."
+
+msgid "pull, update and merge in one command"
+msgstr "pull, update e merge em um comando"
+
+msgid ""
+"pull changes from a remote repository, merge new changes if needed.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository.\n"
+"\n"
+" If the pulled changes add a new branch head, the head is\n"
+" automatically merged, and the result of the merge is committed.\n"
+" Otherwise, the working directory is updated to include the new\n"
+" changes.\n"
+"\n"
+" When a merge occurs, the newly pulled changes are assumed to be\n"
+" \"authoritative\". The head of the new changes is used as the first\n"
+" parent, with local changes as the second. To switch the merge\n"
+" order, use --switch-parent.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"traz mudanças de um repositório remoto, mesclando se necessário\n"
+"\n"
+" Este comando localiza todas as mudanças do repositório na URL ou\n"
+" caminho especificado e as adiciona ao repositório local.\n"
+"\n"
+" Se as mudanças trazidas adicionarem uma nova cabeça de ramo, essa\n"
+" cabeça será automaticamente mesclada, e o resultado da mesclagem\n"
+" será consolidado. Caso contrário, o diretório de trabalho será\n"
+" atualizado para incluir as novas mudanças.\n"
+"\n"
+" Quando ocorre uma mesclagem, assume-se que as novas mudanças\n"
+" trazidas sejam \"autoritativas\". A nova cabeça é usada como\n"
+" primeiro pai, e as mudanças locais como o segundo. Para mudar a\n"
+" ordem de mesclagem, use --switch-parent.\n"
+"\n"
+" Veja 'hg help dates' para uma lista de formatos válidos para\n"
+" -d/--date.\n"
+" "
+
+msgid "working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+"o diretório de trabalho não está na tip do ramo (use \"hg update\" para "
+"obter a tip do ramo)"
+
+msgid "outstanding uncommitted merge"
+msgstr "mesclagem não consolidada pendente"
+
+msgid "outstanding uncommitted changes"
+msgstr "alterações não consolidadas pendentes"
+
+msgid "working directory is missing some files"
+msgstr "estão faltando alguns arquivos no diretório de trabalho"
+
+msgid "multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr "múltiplas cabeças nesse ramo (use \"hg heads .\" e \"hg merge\" para mesclar"
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr "trazendo revisões de %s\n"
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+"O outro repositório não suporta busca por revisão, portanto uma revisão não "
+"pode ser especificada."
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+"não mesclando com %d outros novas cabeças de ramo (use \"hg heads .\" e \"hg "
+"merge\" para mescla-los)\n"
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr "atualizando para %d:%s\n"
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr "mesclando com %d:%s\n"
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr "novo changeset %d:%s mescla alterações remotas com local\n"
+
+msgid "a specific revision you would like to pull"
+msgstr "uma revisão específica que você gostaria de trazer"
+
+msgid "edit commit message"
+msgstr "editar mensagem de consolidação"
+
+msgid "edit commit message (DEPRECATED)"
+msgstr "editar mensagem de consolidação (OBSOLETO)"
+
+msgid "switch parents when merging"
+msgstr "troca de pais quando mesclando"
+
+msgid "hg fetch [SOURCE]"
+msgstr "hg fetch [ORIGEM]"
+
+msgid "commands to sign and verify changesets"
+msgstr "comando para assinar e verificar changesets"
+
+msgid "error while verifying signature"
+msgstr "erro verificando assinatura"
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr "Assinatura %s ruim de \"%s\"\n"
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr "%s Nota: A assinatura expirou (assinado por: \"%s\")\n"
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr "%s Nota: Esta chave expirou (assinada por: \"%s\")\n"
+
+msgid "list signed changesets"
+msgstr "lista os changesets assinados"
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr "nó %s:%d não existe\n"
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr ""
+"verifica todas as assinaturas que podem existir para uma revisão em "
+"particular"
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr "Assinatura inválida para %s\n"
+
+msgid ""
+"add a signature for the current or given revision\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"adiciona uma assinatura para a revisão atual ou pedida\n"
+"\n"
+" Se não for dada uma versão, será usado o pai do diretório de\n"
+" trabalho, ou a tip se o diretório de trabalho não estiver em\n"
+" nenhuma revisão.\n"
+"\n"
+" Veja 'hg help dates' para uma lista de formatos validos para\n"
+" -d/--date.\n"
+" "
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr "mesclagem não consolidada - por favor forneça uma revisão específica"
+
+msgid "Error while signing"
+msgstr "Erro ao assinar"
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+"a cópia de trabalho de .hgsigs foi mudada (por favor consolide .hgsigs "
+"manualmente ou use --force)"
+
+msgid "unknown signature version"
+msgstr "versão de assinatura desconhecida"
+
+msgid "make the signature local"
+msgstr "torna a assinatura local"
+
+msgid "sign even if the sigfile is modified"
+msgstr "assina mesmo se o arquivo de assinatura está modificado"
+
+msgid "do not commit the sigfile after signing"
+msgstr "não consolida o arquivo de assinaturas após assinar"
+
+msgid "the key id to sign with"
+msgstr "o id da chave com a qual assinar"
+
+msgid "commit message"
+msgstr "mensagem de consolidação"
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr "hg sign [OPÇÃO]... [REVISÃO]..."
+
+msgid "hg sigcheck REVISION"
+msgstr "hg sigcheck REVISÃO"
+
+msgid "hg sigs"
+msgstr "hg sigs"
+
+msgid ""
+"command to view revision graphs from a shell\n"
+"\n"
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ASCII representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+"comando para exibir grafos de revisão em terminais modo texto\n"
+"\n"
+"Esta extensão adiciona uma opção --graph aos comandos incoming,\n"
+"outgoing e log. Quando esta opção for passada, também será mostrada\n"
+"uma representação ASCII do grafo de revisões.\n"
+
+#, python-format
+msgid "--graph option is incompatible with --%s"
+msgstr "a opção --graph é incompatível com --%s"
+
+msgid ""
+"show revision history alongside an ASCII revision graph\n"
+"\n"
+" Print a revision history alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+"mostra histórico de revisões ao lado de um grafo ASCII de revisões\n"
+"\n"
+" Imprime um histórico de revisões ao lado de um grafo de revisões\n"
+" desenhado com caracteres ASCII.\n"
+"\n"
+" Nós impressos como um caractere @ são pais do diretório de\n"
+" trabalho.\n"
+" "
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr "comparando com %s\n"
+
+msgid "no changes found\n"
+msgstr "nenhuma alteração encontrada\n"
+
+msgid "show the revision DAG"
+msgstr "mostra o grafo de revisões"
+
+msgid "limit number of changes displayed"
+msgstr "número limite de mudanças exibidas"
+
+msgid "show patch"
+msgstr "mostra o patch"
+
+msgid "show the specified revision or range"
+msgstr "mostra a revisão ou seqüência de revisões especificada"
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr "hg glog [OPÇÃO]... [ARQUIVO]"
+
+msgid ""
+"hooks for integrating with the CIA.vc notification service\n"
+"\n"
+"This is meant to be run as a changegroup or incoming hook.\n"
+"To configure it, set the following options in your hgrc:\n"
+"\n"
+"[cia]\n"
+"# your registered CIA user name\n"
+"user = foo\n"
+"# the name of the project in CIA\n"
+"project = foo\n"
+"# the module (subproject) (optional)\n"
+"#module = foo\n"
+"# Append a diffstat to the log message (optional)\n"
+"#diffstat = False\n"
+"# Template to use for log messages (optional)\n"
+"#template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"# Style to use (optional)\n"
+"#style = foo\n"
+"# The URL of the CIA notification service (optional)\n"
+"# You can use mailto: URLs to send by email, eg\n"
+"# mailto:cia@cia.vc\n"
+"# Make sure to set email.from if you do this.\n"
+"#url = http://cia.vc/\n"
+"# print message instead of sending it (optional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# one of these:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# If you want hyperlinks (optional)\n"
+"baseurl = http://server/path/to/repo\n"
+msgstr ""
+"ganchos para integração com o serviço de notificação CIA.vc\n"
+"\n"
+"Isto deve ser executado como um gancho changegroup ou incoming.\n"
+"Para configurá-lo, defina as seguintes opções em seu hgrc:\n"
+"\n"
+"[cia]\n"
+"# seu nome de usuário CIA registrado\n"
+"user = foo\n"
+"# o nome do projeto CIA\n"
+"project = foo\n"
+"# o módulo (subprojeto) (opcional)\n"
+"#module = foo\n"
+"# Anexa um diffstat à mensagem de log (opcional)\n"
+"#diffstat = False\n"
+"# Modelo a ser usado em mensagens de log (opcional)\n"
+"#template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"# Estilo a ser usado (opcional)\n"
+"#style = foo\n"
+"# A URL do serviço de notificação CIA (opcional)\n"
+"# Você pode usar URLs mailto: para enviar por e-mail, por exemplo\n"
+"# mailto:cia@cia.vc\n"
+"# Certifique-se de definir email.from se você fizer isso.\n"
+"#url = http://cia.vc/\n"
+"# imprime a mensagem ao invés de enviá-la (opcional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# um destes:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# Se você desejar hyperlinks (opcional)\n"
+"baseurl = http://server/path/to/repo\n"
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr "hgcia: enviando atualização para %s\n"
+
+msgid "email.from must be defined when sending by email"
+msgstr "email.from deve estar definido ao enviar por e-mail"
+
+msgid "cia: no user specified"
+msgstr "cia: nenhum usuário especificado"
+
+msgid "cia: no project specified"
+msgstr "cia: nenhum projeto especificado"
+
+msgid ""
+"browse the repository in a graphical way\n"
+"\n"
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not\n"
+"distributed with Mercurial.)\n"
+"\n"
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to Mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and the extension is shipped in the hgext\n"
+"repository, and needs to be enabled.\n"
+"\n"
+"The hg view command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can specify\n"
+"the path to hgk in your .hgrc file:\n"
+"\n"
+" [hgk]\n"
+" path=/location/of/hgk\n"
+"\n"
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions."
+msgstr ""
+"visualiza o repositório em modo gráfico\n"
+"\n"
+"A extensão hgk permite visualizar o histórico de um repositório\n"
+"graficamente. Ela requer o Tcl/Tk versão 8.4 ou posterior. (Tcl/Tk\n"
+"não é distribuído com o Mercurial.)\n"
+"\n"
+"hgk consiste de duas partes: um script Tcl que faz a exibição e\n"
+"consulta de informações, e uma extensão do Mercurial chamada hgk.py,\n"
+"que provê ganchos para o hgk obter informações. O hgk pode ser\n"
+"encontrado no diretório contrib, e o hgk.py pode ser encontrado no\n"
+"diretório hgext (e precisa ser habilitado).\n"
+"\n"
+"O comando hg view irá lançar o script Tcl hgk. Para esse comando\n"
+"funcionar, hgk deve estar em seu caminho de busca. Alternativamente,\n"
+"você pode especificar o caminho para o hgk em seu arquivo .hgrc:\n"
+"\n"
+" [hgk]\n"
+" path=/localização/do/hgk\n"
+"\n"
+"O hgk pode usar a extensão extdiff para visualizar revisões.\n"
+"Assumindo que você já configurou o comando vdiff da extdiff, basta\n"
+"adicionar:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Os menus de contexto das revisões vão agora mostrar entradas\n"
+"adicionais para disparar o vdiff em revisões selecionadas."
+
+msgid "diff trees from two commits"
+msgstr "calcula a diferença entre duas revisões"
+
+msgid "output common ancestor information"
+msgstr "exibe informação de ancestral comum"
+
+msgid "cat a specific revision"
+msgstr "copia para a saída uma revisão específica"
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr "cat-file: tipo ou revisão não fornecido\n"
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr "abortando; hg cat-file entende apenas commits\n"
+
+msgid "parse given revisions"
+msgstr "decodifica as revisões dadas"
+
+msgid "print revisions"
+msgstr "imprime as revisões"
+
+msgid "print extension options"
+msgstr "imprime opções da extensão"
+
+msgid "start interactive history viewer"
+msgstr "inicia um visualizador de histórico interativo"
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr "hg view [-l LIMITE] [SEQUÊNCIADEREVISÕES]"
+
+msgid "generate patch"
+msgstr "gera patch"
+
+msgid "recursive"
+msgstr "recursivo"
+
+msgid "pretty"
+msgstr "bonito"
+
+msgid "stdin"
+msgstr "stdin"
+
+msgid "detect copies"
+msgstr "detecta cópias"
+
+msgid "search"
+msgstr "procura"
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr "hg git-diff-tree [OPÇÃO]... NÓ1 NÓ2 [ARQUIVO]..."
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr "hg debug-cat-file [OPÇÃO]... TIPO ARQUIVO"
+
+msgid "hg debug-config"
+msgstr "hg debug-config"
+
+msgid "hg debug-merge-base REV REV"
+msgstr "hg debug-merge-base REV REV"
+
+msgid "ignored"
+msgstr "ignorado"
+
+msgid "hg debug-rev-parse REV"
+msgstr "hg debug-rev-parse REV"
+
+msgid "header"
+msgstr "cabeçalho"
+
+msgid "topo-order"
+msgstr "ordem topológica"
+
+msgid "parents"
+msgstr "pais"
+
+msgid "max-count"
+msgstr "número máximo"
+
+msgid "hg debug-rev-list [OPTION]... REV..."
+msgstr "hg debug-rev-list [OPÇÃO]... REV..."
+
+msgid ""
+"syntax highlighting for hgweb (requires Pygments)\n"
+"\n"
+"It depends on the Pygments syntax highlighting library:\n"
+"http://pygments.org/\n"
+"\n"
+"There is a single configuration option:\n"
+"\n"
+"[web]\n"
+"pygments_style = <style>\n"
+"\n"
+"The default is 'colorful'.\n"
+msgstr ""
+"realce de sintaxe para o hgweb (requer Pygments)\n"
+"\n"
+"Esta extensão depende da biblioteca Pygments de realce de sintaxe:\n"
+"http://pygments.org/\n"
+"\n"
+"Há uma única opção de configuração:\n"
+"\n"
+"[web]\n"
+"pygments_style = <estilo>\n"
+"\n"
+"O padrão é 'colorful'.\n"
+
+msgid "accelerate status report using Linux's inotify service"
+msgstr "acelera informações de status usando o serviço inotify do Linux"
+
+msgid "start an inotify server for this repository"
+msgstr "inicia um servidor inotify para este repositório"
+
+msgid ""
+"debugging information for inotify extension\n"
+"\n"
+" Prints the list of directories being watched by the inotify server.\n"
+" "
+msgstr ""
+"informação de depuração para a extensão inotify\n"
+"\n"
+" Imprime a lista de diretórios monitorados pelo servidor inotify.\n"
+" "
+
+msgid "directories being watched:\n"
+msgstr "diretórios monitorados:\n"
+
+msgid "run server in background"
+msgstr "executa o servidor em segundo plano"
+
+msgid "used internally by daemon mode"
+msgstr "usado internamente pelo modo daemon"
+
+msgid "minutes to sit idle before exiting"
+msgstr "minutos a aguardar antes de sair"
+
+msgid "name of file to write process ID to"
+msgstr "nome do arquivo no qual escrever o ID do processo"
+
+msgid "hg inserve [OPTION]..."
+msgstr "hg inserve [OPÇÃO]..."
+
+msgid "(found dead inotify server socket; removing it)\n"
+msgstr "(encontrado socket de um servidor inotify morto; removendo-o)\n"
+
+msgid "(starting inotify server)\n"
+msgstr "(iniciando servidor inotify)\n"
+
+#, python-format
+msgid "could not start inotify server: %s\n"
+msgstr "não foi possível iniciar servidor inotify: %s\n"
+
+#, python-format
+msgid "could not talk to new inotify server: %s\n"
+msgstr "não foi possível falar com o novo servidor inotify: %s\n"
+
+msgid "(inotify server not running)\n"
+msgstr "(servidor inotify não está em execução)\n"
+
+#, python-format
+msgid "failed to contact inotify server: %s\n"
+msgstr "falha ao contatar servidor inotify: %s\n"
+
+msgid "received empty answer from inotify server"
+msgstr "resposta vazia recebida do servidor inotify"
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr "(inotify: recebida resposta de uma versão de servidor incompatível %d)\n"
+
+#, python-format
+msgid "(inotify: received '%s' response when expecting '%s')\n"
+msgstr "(inotify: recebida resposta '%s' quando '%s' era esperada)\n"
+
+msgid "this system does not seem to support inotify"
+msgstr "esse sistema parece não suportar inotify"
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr "*** o limite atual por usuário do número de inotify watches é %s\n"
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr ""
+"*** este limite é muito baixo para acompanhar cada diretório neste "
+"repositório\n"
+
+msgid "*** counting directories: "
+msgstr "*** contando diretórios: "
+
+#, python-format
+msgid "found %d\n"
+msgstr "encontrado %d\n"
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr "*** para elevar o limite de %d para %d (rode como root):\n"
+
+#, python-format
+msgid "*** echo %d > %s\n"
+msgstr "*** echo %d > %s\n"
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr ""
+"impossível observar %s até que o limite de observação do inotify seja "
+"alcançado"
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr "serviço inotify indisponível: %s"
+
+#, python-format
+msgid "watching %r\n"
+msgstr "observando %r\n"
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr "observando diretórios sobre %r\n"
+
+#, python-format
+msgid "status: %r dir(%d) -> %s\n"
+msgstr "situação: %r dir(%d) -> %s\n"
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr "situação: %r %s -> %s\n"
+
+#, python-format
+msgid "%s dirstate reload\n"
+msgstr "%s recarga de dirstate\n"
+
+#, python-format
+msgid "%s end dirstate reload\n"
+msgstr "%s fim da recarga de dirstate\n"
+
+msgid "rescanning due to .hgignore change\n"
+msgstr "varrendo novamente por mudança no .hgignore\n"
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr "evento %s: criado %s\n"
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr "evento %s: cancelado %s\n"
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr "evento %s: modificado %s\n"
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr "sistema de arquivos contendo %s foi desmontado\n"
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr "%s legível: %d bytes\n"
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr "%s abaixo do limiar - removendo o registro\n"
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr "%s lendo %d eventos\n"
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr "%s registrando novamente com %d bytes legíveis\n"
+
+#, python-format
+msgid "could not start server: %s"
+msgstr "não foi possível iniciar servidor: %s"
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr "respondendo consulta para %r\n"
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr "recebida consulta de versão de cliente incompatível %d\n"
+
+#, python-format
+msgid "unrecognized query type: %s\n"
+msgstr "tipo de consulta não reconhecido: %s\n"
+
+msgid "finished setup\n"
+msgstr "setup encerrado\n"
+
+msgid ""
+"expand expressions into changelog and summaries\n"
+"\n"
+"This extension allows the use of a special syntax in summaries,\n"
+"which will be automatically expanded into links or any other\n"
+"arbitrary expression, much like InterWiki does.\n"
+"\n"
+"A few example patterns (link to bug tracking, etc.) that may\n"
+"be used in your hgrc:\n"
+"\n"
+" [interhg]\n"
+" issues = s!issue(\\d+)!<a href=\"http://bts/issue\\1\">issue\\1</a>!\n"
+" bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2\">\\1</a>!"
+"i\n"
+" boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!\n"
+msgstr ""
+"expande expressões no changelog e sumários\n"
+"\n"
+"Esta extensão permite o uso de uma sintaxe especial em sumários,\n"
+"que será expandida automaticamente para links ou qualquer outra\n"
+"expressão arbitrária, de modo muito semelhante ao que o InterWiki\n"
+"faz.\n"
+"\n"
+"Alguns exemplos de padrões (link para bug tracking, etc.) que podem\n"
+"ser usados em seu hgrc:\n"
+"\n"
+" [interhg]\n"
+" issues = s!issue(\\d+)!<a href=\"http://bts/issue\\1\">issue\\1</a>!\n"
+" bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2\">\\1</a>!"
+"i\n"
+" boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!\n"
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr "interhg: padrão inválido para %s: %s\n"
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr "interhg: expressão regular inválida para %s: %s\n"
+
+msgid ""
+"expand keywords in tracked files\n"
+"\n"
+"This extension expands RCS/CVS-like or self-customized $Keywords$ in\n"
+"tracked text files selected by your configuration.\n"
+"\n"
+"Keywords are only expanded in local repositories and not stored in the\n"
+"change history. The mechanism can be regarded as a convenience for the\n"
+"current user or for archive distribution.\n"
+"\n"
+"Configuration is done in the [keyword] and [keywordmaps] sections of\n"
+"hgrc files.\n"
+"\n"
+"Example:\n"
+"\n"
+" [keyword]\n"
+" # expand keywords in every python file except those matching \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Note: the more specific you are in your filename patterns\n"
+" the less you lose speed in huge repositories.\n"
+"\n"
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run \"hg kwdemo\".\n"
+"\n"
+"An additional date template filter {date|utcdate} is provided.\n"
+"\n"
+"The default template mappings (view with \"hg kwdemo -d\") can be\n"
+"replaced with customized keywords and templates. Again, run \"hg\n"
+"kwdemo\" to control the results of your config changes.\n"
+"\n"
+"Before changing/disabling active keywords, run \"hg kwshrink\" to avoid\n"
+"the risk of inadvertently storing expanded keywords in the change\n"
+"history.\n"
+"\n"
+"To force expansion after enabling it, or a configuration change, run\n"
+"\"hg kwexpand\".\n"
+"\n"
+"Also, when committing with the record extension or using mq's qrecord,\n"
+"be aware that keywords cannot be updated. Again, run \"hg kwexpand\" on\n"
+"the files in question to update keyword expansions after all changes\n"
+"have been checked in.\n"
+"\n"
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map\n"
+"\"Log = {desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+"expande palavras chave em arquivos rastreados\n"
+"\n"
+"Esta extensão expande palavras chave RCS/CVS ou customizáveis\n"
+"($Keywords$) em arquivos texto rastreados selecionados em sua\n"
+"configuração.\n"
+"\n"
+"Palavras chave são expandidas apenas em repositórios locais e não\n"
+"são guardadas no histórico de mudanças. O mecanismo pode ser\n"
+"considerado como uma conveniência para o usuário local ou para\n"
+"distribuição em arquivos.\n"
+"\n"
+"A configuração é feita nas seções [keyword] e [keywordmaps] de\n"
+"arquivos hgrc.\n"
+"\n"
+"Exemplo:\n"
+"\n"
+" [keyword]\n"
+" # expande palavras chave em todo arquivo python exceto\n"
+" # naqueles que casarem com \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Nota: quanto mais específico você for em seus padrões de arquivo\n"
+" menos velocidade será perdida em repositórios muito grandes.\n"
+"\n"
+"Para uma demonstração da expansão e do mapeamento de modelos em\n"
+"[keywordmaps] execute \"hg kwdemo\".\n"
+"\n"
+"É fornecido um filtro {date|utcdate} adicional para modelos.\n"
+"\n"
+"Os mapeamentos de modelo padrões (veja com \"hg kwdemo -d\") podem\n"
+"ser substituídos com palavras chave customizáveis e modelos.\n"
+"Novamente, execute \"hg kwdemo\" para controlar os resultados de\n"
+" suas mudanças na configuração.\n"
+"\n"
+"Antes de mudar ou desabilitar palavras chave ativas, execute \"hg\n"
+"kwshrink\" para evitar o risco de inadvertidamente guardar no\n"
+"histórico palavras chave expandidas.\n"
+"\n"
+"Para forçar a expansão após habilitação, ou após uma mudança de\n"
+"configuração, execute \"hg kwexpand\".\n"
+"\n"
+"Além disso, ao consolidar usando a extensão record ou o comando\n"
+"qrecord da extensão mq, tenha em mente que palavras chave não podem\n"
+"ser expandidas. Novamente, execute \"hg kwexpand\" nos arquivos em\n"
+"questão para atualizar expansões de palavras chave após todas as\n"
+"mudanças terem sido selecionadas.\n"
+"\n"
+"Expansões que alcancem mais de uma linha, e expansões incrementais\n"
+"como CVS' $Log$, não são suportadas. Um modelo de expansão\n"
+"\"Log = {desc}\" expande para a primeira linha da descrição do\n"
+"changeset.\n"
+
+#, python-format
+msgid "overwriting %s expanding keywords\n"
+msgstr "sobrescrevendo %s palavras chave em expansão\n"
+
+#, python-format
+msgid "overwriting %s shrinking keywords\n"
+msgstr "sobrescrevendo %s palavras chave em redução\n"
+
+msgid "[keyword] patterns cannot match"
+msgstr "padrões [keyword] não podem casar"
+
+msgid "no [keyword] patterns configured"
+msgstr "nenhum padrão [keyword] configurado"
+
+msgid ""
+"print [keywordmaps] configuration and an expansion example\n"
+"\n"
+" Show current, custom, or default keyword template maps and their\n"
+" expansions.\n"
+"\n"
+" Extend current configuration by specifying maps as arguments and\n"
+" optionally by reading from an additional hgrc file.\n"
+"\n"
+" Override current keyword template maps with \"default\" option.\n"
+" "
+msgstr ""
+"imprime a configuração [keywordmaps] e um exemplo de expansão\n"
+"\n"
+" Mostra os mapeamentos de modelo de palavras chave atual,\n"
+" customizado ou padrão, e suas expansões.\n"
+"\n"
+" Amplia a configuração atual com a especificação de mapas como\n"
+" argumentos e opcionalmente lendo de um arquivo hgrc adicional.\n"
+"\n"
+" Sobrepõe mapas de modelo de palavras chave atuais com opções\n"
+" \"default\".\n"
+" "
+
+#, python-format
+msgid "creating temporary repository at %s\n"
+msgstr "criando repositório temporário em %s\n"
+
+#, python-format
+msgid ""
+"\n"
+"\tconfig using %s keyword template maps\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"%s keywords written to %s:\n"
+msgstr ""
+"\n"
+"%s palavras chave escritas em %s:\n"
+
+msgid "unhooked all commit hooks\n"
+msgstr "removidos os registros de todos os ganchos de consolidação\n"
+
+#, python-format
+msgid ""
+"\n"
+"\t%s keywords expanded%s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"removing temporary repository %s\n"
+msgstr ""
+"\n"
+"removendo repositório temporário %s\n"
+
+msgid ""
+"expand keywords in the working directory\n"
+"\n"
+" Run after (re)enabling keyword expansion.\n"
+"\n"
+" kwexpand refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+"expande palavras chave no diretório de trabalho\n"
+"\n"
+" Execute após (re)habilitar expansão de palavras chave.\n"
+"\n"
+" kwexpand se recusa a rodar se forem passados arquivos com\n"
+" mudanças locais.\n"
+" "
+
+msgid ""
+"show files configured for keyword expansion\n"
+"\n"
+" List which files in the working directory are matched by the\n"
+" [keyword] configuration patterns.\n"
+"\n"
+" Useful to prevent inadvertent keyword expansion and to speed up\n"
+" execution by including only files that are actual candidates\n"
+" for expansion.\n"
+"\n"
+" See \"hg help keyword\" on how to construct patterns both for\n"
+" inclusion and exclusion of files.\n"
+"\n"
+" Use -u/--untracked to list untracked files as well.\n"
+"\n"
+" With -a/--all and -v/--verbose the codes used to show the status\n"
+" of files are:\n"
+" K = keyword expansion candidate\n"
+" k = keyword expansion candidate (untracked)\n"
+" I = ignored\n"
+" i = ignored (untracked)\n"
+" "
+msgstr ""
+"mostra arquivos configurados para expansão de palavras chave\n"
+"\n"
+" Lista quais arquivos no diretório de trabalho correspondem a\n"
+" padrões de configuração em [keyword].\n"
+"\n"
+" Útil para prevenir expansão indesejada de palavras chave e para\n"
+" acelerar a execução examinando apenas arquivos candidatos à\n"
+" expansão.\n"
+"\n"
+" Veja \"hg help keyword\" para saber como construir padrões tanto\n"
+" para inclusão como para exclusão de arquivos.\n"
+"\n"
+" Use -u/--untracked para listar também arquivos não rastreados.\n"
+"\n"
+" Com -a/--all e -v/--verbose os códigos usados para mostrar o\n"
+" status dos arquivos são:\n"
+" K = candidato à expansão de palavras chave\n"
+" k = candidato à expansão de palavras chave (não rastreado)\n"
+" I = ignorado\n"
+" i = ignorado (não rastreado)\n"
+" "
+
+msgid ""
+"revert expanded keywords in the working directory\n"
+"\n"
+" Run before changing/disabling active keywords or if you experience\n"
+" problems with \"hg import\" or \"hg merge\".\n"
+"\n"
+" kwshrink refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+"reverte palavras chave expandidas no diretório de trabalho\n"
+"\n"
+" Execute antes de mudar ou desabilitar palavras chave ativas ou\n"
+" se você tiver problemas com \"hg import\" ou \"hg merge\".\n"
+"\n"
+" kwshrink se recusa a rodar se forem passados arquivos contendo\n"
+" mudanças locais.\n"
+" "
+
+msgid "show default keyword template maps"
+msgstr "exibe os mapas de modelos de teclado padrão"
+
+msgid "read maps from rcfile"
+msgstr "lê o mapeamento do arquivo rc"
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr "hg kwdemo [-d] [-f ARQUIVORC] [MAPADEMODELOS]..."
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr "hg kwexpand [OPÇÃO]... [ARQUIVO]..."
+
+msgid "show keyword status flags of all files"
+msgstr "mostra indicadores de estado de palavras chave para todos os arquivos"
+
+msgid "show files excluded from expansion"
+msgstr "mostra arquivos excluídos da expansão"
+
+msgid "additionally show untracked files"
+msgstr "mostra também arquivos não rastreados"
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr "hg kwfiles [OPÇÃO]... [ARQUIVO]..."
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr "hg kwshrink [OPÇÃO]... [ARQUIVO]..."
+
+msgid ""
+"manage a stack of patches\n"
+"\n"
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches).\n"
+"\n"
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets.\n"
+"\n"
+"Common tasks (use \"hg help command\" for more details):\n"
+"\n"
+"prepare repository to work with patches qinit\n"
+"create new patch qnew\n"
+"import existing patch qimport\n"
+"\n"
+"print patch series qseries\n"
+"print applied patches qapplied\n"
+"print name of top applied patch qtop\n"
+"\n"
+"add known patch to applied stack qpush\n"
+"remove patch from applied stack qpop\n"
+"refresh contents of top applied patch qrefresh\n"
+msgstr ""
+"gerencia uma pilha de patches\n"
+"\n"
+"Esta extensão lhe permite trabalhar com uma pilha de patches em um\n"
+"repositório do Mercurial. Ela gerencia duas pilhas de patches - todos\n"
+"os patches conhecidos, e patches aplicados (subconjunto dos patches\n"
+"conhecidos.).\n"
+"\n"
+"Patches conhecidos são representados como arquivos de patch no\n"
+"diretório .hg/patches . Patches aplicados são tanto arquivos de\n"
+"patch como changesets.\n"
+"\n"
+"Tarefas comuns (use \"hg help comando\" para mais detalhes):\n"
+"\n"
+"prepara um repositório para trabalhar com patches qinit\n"
+"cria um novo patch qnew\n"
+"importa um patch existente qimport\n"
+"\n"
+"imprime a série de patches qseries\n"
+"imprime patches aplicados qapplied\n"
+"imprime o nome do patch aplicado do topo qtop\n"
+"\n"
+"adiciona um patch conhecido à pilha de aplicados qpush\n"
+"remove um patch da pilha de aplicados qpop\n"
+"renova o conteúdo do patch aplicado do topo qrefresh\n"
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr "%s aparece mais de uma vez em %s"
+
+msgid "guard cannot be an empty string"
+msgstr "uma guarda não pode ser uma string vazia"
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr "a guarda %r inicia com um caractere inválido: %r"
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr "caractere inválido na guarda %r: %r"
+
+#, python-format
+msgid "active guards: %s\n"
+msgstr "guardas ativas: %s\n"
+
+#, python-format
+msgid "guard %r too short"
+msgstr "guarda %r muito curta"
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr "a guarda %r inicia com um caractere inválido"
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr "permitindo %s - nenhuma guarda em efeito\n"
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr "permitindo %s - nenhuma guarda negativa que case\n"
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr "permitindo %s - guardada por %r\n"
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr "omitindo %s - guardada por %r\n"
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr "omitindo %s - nenhuma guarda que case\n"
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr "erro ao remover desfazimento: %s\n"
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr "a aplicação do patch %s falhou"
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr "o patch não funcionou, mesclando %s\n"
+
+#, python-format
+msgid "update returned %d"
+msgstr "update retornou %d"
+
+msgid "repo commit failed"
+msgstr "consolidação no repositório falhou"
+
+#, python-format
+msgid "unable to read %s"
+msgstr "impossível ler %s"
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr "o patch %s não existe\n"
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr "o patch %s não está aplicado\n"
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr "o patch falhou, impossível continuar (tente -v)\n"
+
+#, python-format
+msgid "applying %s\n"
+msgstr "aplicando %s\n"
+
+#, python-format
+msgid "unable to read %s\n"
+msgstr "impossível ler %s\n"
+
+#, python-format
+msgid "imported patch %s\n"
+msgstr "patch %s importado\n"
+
+#, python-format
+msgid ""
+"\n"
+"imported patch %s"
+msgstr ""
+"\n"
+"patch %s importado"
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr "o patch %s é vazio\n"
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr "o patch falhou, rejeitos deixados no diretório de trabalho\n"
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr "discrepância encontrada ao aplicar patch, parando\n"
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr "a revisão %d não é gerenciada"
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr "não se pode apagar a revisão %d acima de patches aplicados"
+
+#, python-format
+msgid "patch %s finalized without changeset message\n"
+msgstr "patch %s finalizado sem a mensagem de changeset\n"
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr "qdelete exige ao menos uma revisão ou nome de patch"
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr "não se pode remover o patch %s aplicado"
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr "o patch %s não está no arquivo series"
+
+msgid "no patches applied"
+msgstr "nenhum patch aplicado"
+
+msgid "working directory revision is not qtip"
+msgstr "a revisão do diretório de trabalho não é a qtip"
+
+msgid "local changes found, refresh first"
+msgstr "mudanças locais encontradas, você deve primeiro renovar"
+
+msgid "local changes found"
+msgstr "mudanças locais encontradas"
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr "\"%s\" não pode ser usado como nome de um patch"
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr "o patch \"%s\" já existe"
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr "erro removendo %s\n"
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr "o nome de patch \"%s\" é ambíguo:\n"
+
+#, python-format
+msgid "patch %s not in series"
+msgstr "o patch %s não está na série"
+
+msgid "(working directory not at a head)\n"
+msgstr "(diretório de trabalho não está em uma cabeça)\n"
+
+msgid "no patches in series\n"
+msgstr "nenhum patch na série\n"
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr "não se pode empilhar para um patch anterior: %s"
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr "qpush: %s já está no topo\n"
+
+#, python-format
+msgid "guarded by %r"
+msgstr "guardado por %r"
+
+msgid "no matching guards"
+msgstr "nenhuma guarda com nome semelhante"
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr "não se pode empilhar '%s' - %s\n"
+
+msgid "all patches are currently applied\n"
+msgstr "todos os patches estão aplicados nesse momento\n"
+
+msgid "patch series already fully applied\n"
+msgstr "série de patches já completamente aplicada\n"
+
+msgid "cleaning up working directory..."
+msgstr "limpando diretório de trabalho..."
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr "erros ao aplicar, por favor conserte e renove %s\n"
+
+#, python-format
+msgid "now at: %s\n"
+msgstr "agora em: %s\n"
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr "o patch %s não está aplicado"
+
+msgid "no patches applied\n"
+msgstr "nenhum patch aplicado\n"
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr "qpop: %s já está no topo\n"
+
+msgid "qpop: forcing dirstate update\n"
+msgstr "qpop: forçando atualização do dirstate\n"
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr "tentando desempilhar nó desconhecido %s"
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr "desempilhar removeria uma revisão não gerenciada por esta fila de patches"
+
+msgid "deletions found between repo revs"
+msgstr "remoções encontradas entre revisões do repositório"
+
+msgid "patch queue now empty\n"
+msgstr "a fila de patches agora está vazia\n"
+
+msgid "cannot refresh a revision with children"
+msgstr "não se pode renovar uma revisão com filhos"
+
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to "
+"recover)\n"
+msgstr ""
+"renovação interrompida enquanto o patch foi desempilhado! (revert --all, "
+"qpush para recuperar)\n"
+
+msgid "patch queue directory already exists"
+msgstr "o diretório de fila de patches já existe"
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr "o patch %s não está no arquivo series"
+
+msgid "No saved patch data found\n"
+msgstr "Nenhum dado salvo de patches encontrado\n"
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr "restaurando o estado: %s\n"
+
+msgid "save entry has children, leaving it alone\n"
+msgstr "entrada de salvamento tem filhos, deixando-a como está\n"
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr "removendo entrada de salvamento %s\n"
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr "pais do repositório da fila salvos: %s %s\n"
+
+msgid "queue directory updating\n"
+msgstr "atualizando diretório da fila\n"
+
+msgid "Unable to load queue repository\n"
+msgstr "Incapaz de carregar o repositório da fila\n"
+
+msgid "save: no patches applied, exiting\n"
+msgstr "save: nenhum patch aplicado, saindo\n"
+
+msgid "status is already saved\n"
+msgstr "o estado já foi salvo\n"
+
+msgid "hg patches saved state"
+msgstr "estado de hg patches salvo"
+
+msgid "repo commit failed\n"
+msgstr "consolidação no repositório falhou\n"
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr "o patch %s já está no arquivo series"
+
+msgid "option \"-r\" not valid when importing files"
+msgstr "opção \"-r\" inválida ao importar arquivos"
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr "opção \"-n\" inválida ao importar múltiplos patches"
+
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr "a revisão %d é raiz de mais de um ramo"
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr "revisão %d já gerenciada"
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr "a revisão %d não é o pai da fila"
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr "a revisão %d tem filhos não gerenciados"
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr "não se pode importar a revisão de mesclagem %d"
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr "a revisão %d não é pai de %d"
+
+msgid "-e is incompatible with import from -"
+msgstr "-e é incompatível com a importação de -"
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr "o patch %s não existe"
+
+msgid "need --name to import a patch from -"
+msgstr "--name é necessário ao importar um patch de -"
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr "adicionando %s ao arquivo series\n"
+
+msgid ""
+"remove patches from queue\n"
+"\n"
+" The patches must not be applied, and at least one patch is required. "
+"With\n"
+" -k/--keep, the patch files are preserved in the patch directory.\n"
+"\n"
+" To stop managing a patch and move it into permanent history,\n"
+" use the qfinish command."
+msgstr ""
+"remove patches da fila\n"
+"\n"
+" Os patches não devem estar aplicados, e ao menos um patch deve\n"
+" ser passado. Com -k/--keep, os arquivos de patch serão\n"
+" preservados no diretório de patches.\n"
+"\n"
+" Para parar de gerenciar um patch e movê-lo para o histórico\n"
+" permanente, use o comando qfinish."
+
+msgid "print the patches already applied"
+msgstr "imprime os patches já aplicados"
+
+msgid "print the patches not yet applied"
+msgstr "imprime os patches ainda não aplicados"
+
+msgid ""
+"import a patch\n"
+"\n"
+" The patch is inserted into the series after the last applied\n"
+" patch. If no patches have been applied, qimport prepends the patch\n"
+" to the series.\n"
+"\n"
+" The patch will have the same name as its source file unless you\n"
+" give it a new one with -n/--name.\n"
+"\n"
+" You can register an existing patch inside the patch directory with\n"
+" the -e/--existing flag.\n"
+"\n"
+" With -f/--force, an existing patch of the same name will be\n"
+" overwritten.\n"
+"\n"
+" An existing changeset may be placed under mq control with -r/--rev\n"
+" (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+" With -g/--git, patches imported with --rev will use the git diff\n"
+" format. See the diffs help topic for information on why this is\n"
+" important for preserving rename/copy information and permission\n"
+" changes.\n"
+"\n"
+" To import a patch from standard input, pass - as the patch file.\n"
+" When importing from standard input, a patch name must be specified\n"
+" using the --name flag.\n"
+" "
+msgstr ""
+"importa um patch\n"
+"\n"
+" O patch é inserido na série após o último patch aplicado. Se\n"
+" não houver nenhum patch aplicado, qimport adiciona o novo patch\n"
+" no começo da série.\n"
+"\n"
+" O patch terá o mesmo nome que seu arquivo de origem, a não ser\n"
+" que você lhe dê um novo nome usando -n/--name.\n"
+"\n"
+" Você pode registrar um patch já existente no diretório de\n"
+" patches usando a opção -e/--existing.\n"
+"\n"
+" Com -f/--force, um patch existente de mesmo nome será\n"
+" sobrescrito.\n"
+"\n"
+" Um changeset existente pode ser colocado sob o controle da mq\n"
+" com -r/--rev (por exemplo, qimport --rev tip -n patch colocará a\n"
+" tip sob o controle da mq). Com -g/--git, os patches importados\n"
+" com --rev usarão o formato git diff. Veja o tópico de ajuda diff\n"
+" para informações sobre por que isso é importante para preservar\n"
+" informação de cópia e renomeação e mudanças de permissão.\n"
+"\n"
+" Para importar um patch da entrada padrão, passe - como o arquivo\n"
+" do patch. Ao importar da entrada padrão, um nome de patch deve\n"
+" ser especificado usando a opção --name.\n"
+" "
+
+msgid ""
+"init a new queue repository\n"
+"\n"
+" The queue repository is unversioned by default. If\n"
+" -c/--create-repo is specified, qinit will create a separate nested\n"
+" repository for patches (qinit -c may also be run later to convert\n"
+" an unversioned patch repository into a versioned one). You can use\n"
+" qcommit to commit changes to this queue repository."
+msgstr ""
+"cria um novo repositório de fila\n"
+"\n"
+" O repositório de fila é por padrão não versionado. Se for\n"
+" especificado -c/--create-repo, qinit criará um repositório\n"
+" separado aninhado para patches (qinit -c pode ser também\n"
+" executado posteriormente para converter um repositório de\n"
+" patches não versionado em um versionado). Você pode usar\n"
+" qcommit para consolidar mudanças neste repositório de fila."
+
+msgid ""
+"clone main and patch repository at same time\n"
+"\n"
+" If source is local, destination will have no patches applied. If\n"
+" source is remote, this command can not check if patches are\n"
+" applied in source, so cannot guarantee that patches are not\n"
+" applied in destination. If you clone remote repository, be sure\n"
+" before that it has no patches applied.\n"
+"\n"
+" Source patch repository is looked for in <src>/.hg/patches by\n"
+" default. Use -p <url> to change.\n"
+"\n"
+" The patch directory must be a nested Mercurial repository, as\n"
+" would be created by qinit -c.\n"
+" "
+msgstr ""
+"clona os repositórios principal e de fila ao mesmo tempo\n"
+"\n"
+" Se a origem for local, o destino não terá patches aplicados. Se\n"
+" a origem for remota, este comando não pode verificar se patches\n"
+" estão aplicados na origem, então não pode garantir que os patches\n"
+" não estarão aplicados no destino. Se você clonar um repositório\n"
+" remoto, certifique-se primeiro que ele não tenha patches\n"
+" aplicados.\n"
+"\n"
+" O repositório de patches da origem é procurado por padrão em\n"
+" <origem>/.hg/patches . Use -p <url> para mudar.\n"
+"\n"
+" O diretório de patches deve ser um repositório aninhado do\n"
+" Mercurial, como criado por qinit -c.\n"
+" "
+
+msgid "versioned patch repository not found (see qinit -c)"
+msgstr "repositório versionado de patches não encontrado (veja qinit -c)"
+
+msgid "cloning main repository\n"
+msgstr "clonando repositório principal\n"
+
+msgid "cloning patch repository\n"
+msgstr "clonando o repositório de patches\n"
+
+msgid "stripping applied patches from destination repository\n"
+msgstr "removendo patches aplicados do repositório de destino\n"
+
+msgid "updating destination repository\n"
+msgstr "atualizando repositório de destino\n"
+
+msgid "commit changes in the queue repository"
+msgstr "consolida mudanças no repositório da fila"
+
+msgid "print the entire series file"
+msgstr "imprime todo o arquivo series"
+
+msgid "print the name of the current patch"
+msgstr "imprime o nome do patch atual"
+
+msgid "print the name of the next patch"
+msgstr "imprime o nome do próximo patch"
+
+msgid "all patches applied\n"
+msgstr "todos os patches aplicados\n"
+
+msgid "print the name of the previous patch"
+msgstr "imprime o nome do patch anterior"
+
+msgid "only one patch applied\n"
+msgstr "apenas um patch aplicado\n"
+
+msgid ""
+"create a new patch\n"
+"\n"
+" qnew creates a new patch on top of the currently-applied patch (if\n"
+" any). It will refuse to run if there are any outstanding changes\n"
+" unless -f/--force is specified, in which case the patch will be\n"
+" initialized with them. You may also use -I/--include,\n"
+" -X/--exclude, and/or a list of files after the patch name to add\n"
+" only changes to matching files to the new patch, leaving the rest\n"
+" as uncommitted modifications.\n"
+"\n"
+" -u/--user and -d/--date can be used to set the (given) user and\n"
+" date, respectively. -U/--currentuser and -D/--currentdate set user\n"
+" to current user and date to current date.\n"
+"\n"
+" -e/--edit, -m/--message or -l/--logfile set the patch header as\n"
+" well as the commit message. If none is specified, the header is\n"
+" empty and the commit message is '[mq]: PATCH'.\n"
+"\n"
+" Use the -g/--git option to keep the patch in the git extended diff\n"
+" format. Read the diffs help topic for more information on why this\n"
+" is important for preserving permission changes and copy/rename\n"
+" information.\n"
+" "
+msgstr ""
+"cria um novo patch\n"
+"\n"
+" qnew cria um novo patch no topo do patch aplicado no momento (se\n"
+" houver). Ele se recusará a rodar se houver qualquer mudança\n"
+" pendente; a não ser que -f seja especificado, e nesse caso o\n"
+" patch será inicializado com essas mudanças. Você pode também usar\n"
+" -I/--include, -X/--exclude, e/ou uma lista de arquivos após o\n"
+" nome do patch para adicionar ao novo patch apenas mudanças em\n"
+" arquivos que casarem , mantendo as restantes como modificações\n"
+" não consolidadas.\n"
+"\n"
+" -u/--user e -d/--date podem ser usados para definir o usuário\n"
+" e data pedidos, respectivamente. -U/--currentuser e\n"
+" -D/--currentdate definem o usuário para o usuário atual e a\n"
+" data para a data atual.\n"
+"\n"
+" -e/--edit, -m/--message ou -l/--logfile definem o cabeçalho\n"
+" do patch, bem como a mensagem de consolidação. Se não forem\n"
+" especificados, o cabeçalho estará vazio e a mensagem de\n"
+" consolidação será '[mq]: PATCH'.\n"
+"\n"
+" Use a opção -g/--git para manter o patch no formato estendido git\n"
+" diff. Leia o tópico de ajuda diffs para mais informações sobre\n"
+" por que isso é importante para preservar mudanças de permissão\n"
+" e informações de cópia e renomeação.\n"
+" "
+
+msgid ""
+"update the current patch\n"
+"\n"
+" If any file patterns are provided, the refreshed patch will\n"
+" contain only the modifications that match those patterns; the\n"
+" remaining modifications will remain in the working directory.\n"
+"\n"
+" If -s/--short is specified, files currently included in the patch\n"
+" will be refreshed just like matched files and remain in the patch.\n"
+"\n"
+" hg add/remove/copy/rename work as usual, though you might want to\n"
+" use git-style patches (-g/--git or [diff] git=1) to track copies\n"
+" and renames. See the diffs help topic for more information on the\n"
+" git diff format.\n"
+" "
+msgstr ""
+"atualiza o patch atual\n"
+"\n"
+" Se qualquer padrão de arquivos for fornecido, o patch renovado\n"
+" conterá apenas as modificações em arquivos que casarem com esses\n"
+" padrões; as modificações restantes permanecerão no diretório de\n"
+" trabalho.\n"
+"\n"
+" Se -s/--short for especificado, os arquivos incluídos no momento\n"
+" no patch serão renovados da mesma forma que arquivos que casarem,\n"
+" e permanecerão no patch.\n"
+"\n"
+" hg add/remove/copy/rename funciona normalmente, mas você pode\n"
+" querer usar patches estilo git (/g--git ou [diff] git=1) para\n"
+" rastrear cópias e renomeações. Veja o tópico de ajuda diffs para\n"
+" mais informações sobre o formato git diff.\n"
+" "
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr "opção \"-e\" incompatível com \"-m\" ou \"-l\""
+
+msgid ""
+"diff of the current patch and subsequent modifications\n"
+"\n"
+" Shows a diff which includes the current patch as well as any\n"
+" changes which have been made in the working directory since the\n"
+" last refresh (thus showing what the current patch would become\n"
+" after a qrefresh).\n"
+"\n"
+" Use 'hg diff' if you only want to see the changes made since the\n"
+" last qrefresh, or 'hg export qtip' if you want to see changes made\n"
+" by the current patch without including changes made since the\n"
+" qrefresh.\n"
+" "
+msgstr ""
+"diff do patch atual e modificações subseqüentes\n"
+"\n"
+" Mostra um diff que inclui o patch atual bem como quaisquer\n"
+" mudanças que tiverem sido feitas no diretório de trabalho desde\n"
+" a última renovação (mostrando assim como ficaria o patch atual\n"
+" após um qrefresh).\n"
+"\n"
+" Use 'hg diff' se você quiser apenas ver as mudanças feitas desde\n"
+" o último qrefresh, ou 'hg export qtip' se você quiser ver\n"
+" mudanças feitas pelo patch atual sem incluir as mudanças feitas\n"
+" desde o último qrefresh.\n"
+" "
+
+msgid ""
+"fold the named patches into the current patch\n"
+"\n"
+" Patches must not yet be applied. Each patch will be successively\n"
+" applied to the current patch in the order given. If all the\n"
+" patches apply successfully, the current patch will be refreshed\n"
+" with the new cumulative patch, and the folded patches will be\n"
+" deleted. With -k/--keep, the folded patch files will not be\n"
+" removed afterwards.\n"
+"\n"
+" The header for each folded patch will be concatenated with the\n"
+" current patch header, separated by a line of '* * *'."
+msgstr ""
+"incorpora os patches pedidos no patch atual\n"
+"\n"
+" Os patches não devem estar aplicados. Cada patch será\n"
+" sucessivamente aplicado ao patch atual na ordem dada. Se todos\n"
+" os patches forem aplicados com sucesso, o patch atual será\n"
+" renovado com o novo patch cumulativo, e os patches incorporados\n"
+" serão apagados. Com -k/--keep, os patches incorporados não serão\n"
+" removidos em seguida.\n"
+"\n"
+" O cabeçalho de cada patch incorporado será concatenado com o\n"
+" cabeçalho do patch atual, separado por uma linha de '* * *'."
+
+msgid "qfold requires at least one patch name"
+msgstr "qfold requer ao menos um nome de patch"
+
+msgid "No patches applied"
+msgstr "Nenhum patch aplicado"
+
+#, python-format
+msgid "Skipping already folded patch %s"
+msgstr "Omitindo patch %s já incorporado"
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr "qfold não pode incorporar o patch %s já aplicado"
+
+#, python-format
+msgid "Error folding patch %s"
+msgstr "Erro incorporando patch %s"
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr "empilha ou desempilha patches até que o patch nomeado esteja no topo"
+
+msgid ""
+"set or print guards for a patch\n"
+"\n"
+" Guards control whether a patch can be pushed. A patch with no\n"
+" guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+" pushed only if the qselect command has activated it. A patch with\n"
+" a negative guard (\"-foo\") is never pushed if the qselect command\n"
+" has activated it.\n"
+"\n"
+" With no arguments, print the currently active guards.\n"
+" With arguments, set guards for the named patch.\n"
+" NOTE: Specifying negative guards now requires '--'.\n"
+"\n"
+" To set guards on another patch:\n"
+" hg qguard -- other.patch +2.6.17 -stable\n"
+" "
+msgstr ""
+"define ou imprime guardas para um patch\n"
+"\n"
+" Guardas controlam se um patch pode ser empilhado. Um patch sem\n"
+" guardas sempre será empilhado. Um patch com uma guarda positiva\n"
+" (\"+foo\") é empilhado apenas se ela tiver sido ativada pelo\n"
+" comando qselect. Um patch com uma guarda negativa (\"-foo\")\n"
+" nunca será empilhado se ela tiver sido ativada pelo comando\n"
+" qselect.\n"
+"\n"
+" Sem argumentos, imprime as guardas ativas no momento. Com\n"
+" parâmetros, define guardas para o patch pedido.\n"
+" NOTA: A especificação de guardas negativas agora exige '--'.\n"
+"\n"
+" Para definir guardas em um outro patch:\n"
+" hg qguard -- outro.patch +2.6.17 -stable\n"
+" "
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr "não se pode misturar -l/--list com opções ou argumentos"
+
+msgid "no patch to work with"
+msgstr "nenhum patch com o qual trabalhar"
+
+#, python-format
+msgid "no patch named %s"
+msgstr "nenhum patch de nome %s"
+
+msgid "print the header of the topmost or specified patch"
+msgstr "imprime o cabeçalho do último patch ou do patch pedido"
+
+msgid ""
+"push the next patch onto the stack\n"
+"\n"
+" When -f/--force is applied, all local changes in patched files\n"
+" will be lost.\n"
+" "
+msgstr ""
+"empilha o próximo patch na pilha\n"
+"\n"
+" Se -f/--force for pedido, todas as mudanças locais em arquivos\n"
+" modificados pelo patch serão perdidas.\n"
+" "
+
+msgid "no saved queues found, please use -n\n"
+msgstr "nenhuma fila salva encontrada, por favor use -n\n"
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr "mesclando com fila em: %s\n"
+
+msgid ""
+"pop the current patch off the stack\n"
+"\n"
+" By default, pops off the top of the patch stack. If given a patch\n"
+" name, keeps popping off patches until the named patch is at the\n"
+" top of the stack.\n"
+" "
+msgstr ""
+"desempilha o patch atual da pilha\n"
+"\n"
+" Por padrão, desempilha o topo da pilha de patches. Se for\n"
+" passado um nome, desempilha sucessivamente os patches até que\n"
+" o patch com esse nome esteja no topo da pilha.\n"
+" "
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr "usando fila de patches: %s\n"
+
+msgid ""
+"rename a patch\n"
+"\n"
+" With one argument, renames the current patch to PATCH1.\n"
+" With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+"renomeia um patch\n"
+"\n"
+" Com um argumento, renomeia o patch atual para PATCH1.\n"
+" Com dois argumentos, renomeia PATCH1 para PATCH2."
+
+#, python-format
+msgid "%s already exists"
+msgstr "%s já existe"
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr "Um patch de nome %s já existe no arquivo series"
+
+msgid "restore the queue state saved by a revision"
+msgstr "restaura o estado da fila salvo por uma revisão"
+
+msgid "save current queue state"
+msgstr "salva o estado atual da fila"
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr "o destino %s existe e não é um diretório"
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr "o destino %s existe, use -f para forçar"
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr "copia %s para %s\n"
+
+msgid ""
+"strip a revision and all its descendants from the repository\n"
+"\n"
+" If one of the working directory's parent revisions is stripped, the\n"
+" working directory will be updated to the parent of the stripped\n"
+" revision.\n"
+" "
+msgstr ""
+"remove do repositório uma revisão e todos os seus descendentes\n"
+"\n"
+" Se um ancestral da revisão do diretório de trabalho for removido,\n"
+" o diretório de trabalho será atualizado para o pai da revisão\n"
+" removida.\n"
+" "
+
+msgid ""
+"set or print guarded patches to push\n"
+"\n"
+" Use the qguard command to set or print guards on patch, then use\n"
+" qselect to tell mq which guards to use. A patch will be pushed if\n"
+" it has no guards or any positive guards match the currently\n"
+" selected guard, but will not be pushed if any negative guards\n"
+" match the current guard. For example:\n"
+"\n"
+" qguard foo.patch -stable (negative guard)\n"
+" qguard bar.patch +stable (positive guard)\n"
+" qselect stable\n"
+"\n"
+" This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+" it has a negative match) but push bar.patch (because it has a\n"
+" positive match).\n"
+"\n"
+" With no arguments, prints the currently active guards.\n"
+" With one argument, sets the active guard.\n"
+"\n"
+" Use -n/--none to deactivate guards (no other arguments needed).\n"
+" When no guards are active, patches with positive guards are\n"
+" skipped and patches with negative guards are pushed.\n"
+"\n"
+" qselect can change the guards on applied patches. It does not pop\n"
+" guarded patches by default. Use --pop to pop back to the last\n"
+" applied patch that is not guarded. Use --reapply (which implies\n"
+" --pop) to push back to the current patch afterwards, but skip\n"
+" guarded patches.\n"
+"\n"
+" Use -s/--series to print a list of all guards in the series file\n"
+" (no other arguments needed). Use -v for more information."
+msgstr ""
+"define ou imprime guardas de empilhamento de patches\n"
+"\n"
+" Use o comando qguard para definir ou imprimir guardas no patch,\n"
+" depois use qselect para dizer à mq quais guardas usar. Um patch\n"
+" será empilhado se ele não tiver guardas ou se qualquer guarda\n"
+" positiva casar com a guarda atual, mas não será empilhado se\n"
+" qualquer guarda negativa casar com a guarda atual. Por exemplo:\n"
+"\n"
+" qguard foo.patch -stable (guarda negativa)\n"
+" qguard bar.patch +stable (guarda positiva)\n"
+" qselect stable\n"
+"\n"
+" Isso ativa a guarda \"stable\". mq omitirá o patch foo (porque\n"
+" ele tem um casamento negativo) mas empilhará o patch bar (porque\n"
+" ele tem um casamento positivo).\n"
+"\n"
+" Sem argumentos, imprime as guardas ativas no momento. Com um\n"
+" argumento, define a guarda ativa.\n"
+"\n"
+" Use -n/--none para desativar guardas (nenhum outro argumento\n"
+" é necessário). Se nenhuma guarda estiver ativa, patches com\n"
+" guardas positivas são omitidos e patches com guardas negativas\n"
+" são empilhados.\n"
+"\n"
+" qselect pode mudar as guardas em patches aplicados. Ele por\n"
+" padrão não desempilha patches guardados. Use --pop para\n"
+" desempilhar até o último patch aplicado que não esteja guardado.\n"
+" Use --reapply (que implica --pop) para empilhar novamente para o\n"
+" patch atual em seguida, omitindo patches guardados.\n"
+"\n"
+" Use -s/--series para imprimir uma lista de todas as guardas no\n"
+" arquivo series (nenhum outro argumento necessário). Use -v para\n"
+" mais informações."
+
+msgid "guards deactivated\n"
+msgstr "guardas desativadas\n"
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr "número de patches sem guarda e não aplicados mudou de %d para %d\n"
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr "número de patches com guarda e aplicados mudou de %d para %d\n"
+
+msgid "guards in series file:\n"
+msgstr "guardas no arquivo series:\n"
+
+msgid "no guards in series file\n"
+msgstr "nenhuma guarda no arquivo series\n"
+
+msgid "active guards:\n"
+msgstr "guardas ativas:\n"
+
+msgid "no active guards\n"
+msgstr "nenhuma guarda ativa\n"
+
+msgid "popping guarded patches\n"
+msgstr "desempilhando patches com guarda\n"
+
+msgid "reapplying unguarded patches\n"
+msgstr "reaplicando patches sem guarda\n"
+
+msgid ""
+"move applied patches into repository history\n"
+"\n"
+" Finishes the specified revisions (corresponding to applied\n"
+" patches) by moving them out of mq control into regular repository\n"
+" history.\n"
+"\n"
+" Accepts a revision range or the -a/--applied option. If --applied\n"
+" is specified, all applied mq revisions are removed from mq\n"
+" control. Otherwise, the given revisions must be at the base of the\n"
+" stack of applied patches.\n"
+"\n"
+" This can be especially useful if your changes have been applied to\n"
+" an upstream repository, or if you are about to push your changes\n"
+" to upstream.\n"
+" "
+msgstr ""
+"move patches aplicados para o histórico do repositório\n"
+"\n"
+" Encerra as revisões especificadas (que correspondem a patches\n"
+" aplicados) tirando-as do controle da mq e convertendo-as em\n"
+" histórico comum do repositório.\n"
+"\n"
+" Aceita uma seqüência de revisões ou a opção -a/--applied. Se\n"
+" --applied for especificado, todas as revisões mq aplicadas serão\n"
+" removidas do controle da mq. De outro modo, as revisões pedidas\n"
+" devem estar na base da pilha de patches aplicados.\n"
+"\n"
+" Isto pode ser especialmente útil se suas mudanças foram aplicadas\n"
+" a um repositório upstream, ou se você pretender enviar essas\n"
+" mudanças para upstream.\n"
+" "
+
+msgid "no revisions specified"
+msgstr "nenhuma revisão especificada"
+
+msgid "cannot commit over an applied mq patch"
+msgstr "não se pode consolidar sobre um patch mq aplicado"
+
+msgid "source has mq patches applied"
+msgstr "a origem tem patches mq aplicados"
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr "arquivo de estado da mq se refere ao nó desconhecido %s\n"
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr "A etiqueta %s se sobrepõe ao patch mq de mesmo nome\n"
+
+msgid "cannot import over an applied patch"
+msgstr "não se pode importar sobre um patch aplicado"
+
+msgid "print first line of patch header"
+msgstr "imprime a primeira linha do cabeçalho do patch"
+
+msgid "hg qapplied [-s] [PATCH]"
+msgstr "hg qapplied [-s] [PATCH]"
+
+msgid "use pull protocol to copy metadata"
+msgstr "usa o protocolo pull para copiar metadados"
+
+msgid "do not update the new working directories"
+msgstr "não atualiza os novos diretórios de trabalho"
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr "usa transferência não comprimida (mais rápido em LANs)"
+
+msgid "location of source patch repository"
+msgstr "localização do repositório de origem de patches"
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr "hg qclone [OPÇÃO]... ORIGEM [DEST]"
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr "hg qcommit [OPÇÃO]... [ARQUIVO]..."
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr "hg qdiff [OPÇÃO]... [ARQUIVO]..."
+
+msgid "keep patch file"
+msgstr "mantém o arquivo de patch"
+
+msgid "stop managing a revision (DEPRECATED)"
+msgstr "deixa de gerenciar uma revisão (OBSOLETO)"
+
+msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
+msgstr "hg qdelete [-k] [-r REV]... [PATCH]..."
+
+msgid "edit patch header"
+msgstr "edita o cabeçalho do patch"
+
+msgid "keep folded patch files"
+msgstr "mantém os arquivos dos patches incorporados"
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr "hg qfold [-e] [-k] [-m TEXTO] [-l ARQUIVO] PATCH..."
+
+msgid "overwrite any local changes"
+msgstr "sobrescreve qualquer alteração local"
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr "hg qgoto [OPÇÃO]... PATCH"
+
+msgid "list all patches and guards"
+msgstr "lista todos os patches e guardas"
+
+msgid "drop all guards"
+msgstr "descarta todas as guardas"
+
+msgid "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+msgstr "hg qguard [-l] [-n] -- [PATCH] [+GUARDA]... [-GUARDA]..."
+
+msgid "hg qheader [PATCH]"
+msgstr "hg qheader [PATCH]"
+
+msgid "import file in patch directory"
+msgstr "importa um arquivo do diretório de patches"
+
+msgid "name of patch file"
+msgstr "nome do arquivo de patch"
+
+msgid "overwrite existing files"
+msgstr "sobrescreve arquivos existentes"
+
+msgid "place existing revisions under mq control"
+msgstr "põe revisões existentes sob controle da mq"
+
+msgid "use git extended diff format"
+msgstr "usa o formato estendido de diff do git"
+
+msgid "qpush after importing"
+msgstr "executa qpush após importar"
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr "hg qimport [-e] [-n NOME] [-f] [-g] [-P] [-r REV]... ARQUIVO..."
+
+msgid "create queue repository"
+msgstr "cria o repositório da fila"
+
+msgid "hg qinit [-c]"
+msgstr "hg qinit [-c]"
+
+msgid "import uncommitted changes into patch"
+msgstr "importa para o patch mudanças não consolidadas"
+
+msgid "add \"From: <current user>\" to patch"
+msgstr "adiciona \"From: <usuário atual>\" ao patch"
+
+msgid "add \"From: <given user>\" to patch"
+msgstr "adiciona \"From: <usuário fornecido>\" ao patch"
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr "adiciona \"Date: <data atual>\" ao patch"
+
+msgid "add \"Date: <given date>\" to patch"
+msgstr "adiciona \"Date: <data fornecida>\" ao patch"
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+msgstr "hg qnew [-e] [-m TEXTO] [-l ARQUIVO] [-f] PATCH [ARQUIVO]..."
+
+msgid "hg qnext [-s]"
+msgstr "hg qnext [-s]"
+
+msgid "hg qprev [-s]"
+msgstr "hg qprev [-s]"
+
+msgid "pop all patches"
+msgstr "desempilha todos os patches"
+
+msgid "queue name to pop"
+msgstr "nome da fila para desempilhar"
+
+msgid "forget any local changes"
+msgstr "descarta qualquer mudança local"
+
+msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+msgstr "hg qpop [-a] [-n NOME] [-f] [PATCH | ÃNDICE]"
+
+msgid "apply if the patch has rejects"
+msgstr "aplica se o patch tiver partes rejeitadas"
+
+msgid "list patch name in commit text"
+msgstr "lista o nome do patch no texto de consolidação"
+
+msgid "apply all patches"
+msgstr "aplica todos os patches"
+
+msgid "merge from another queue"
+msgstr "mescla com outra fila"
+
+msgid "merge queue name"
+msgstr "nome da fila de mesclagem"
+
+msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+msgstr "hg qpush [-f] [-l] [-a] [-m] [-n NOME] [PATCH | ÃNDICE]"
+
+msgid "refresh only files already in the patch and specified files"
+msgstr "renova apenas os arquivos especificados ou que já estão no patch"
+
+msgid "add/update \"From: <current user>\" in patch"
+msgstr "adiciona/atualiza \"From: <usuário atual>\" no patch"
+
+msgid "add/update \"From: <given user>\" in patch"
+msgstr "adiciona/atualiza \"From: <usuário fornecido>\" no patch"
+
+msgid "update \"Date: <current date>\" in patch (if present)"
+msgstr "atualiza \"Date: <data atual>\" no patch (se presente)"
+
+msgid "update \"Date: <given date>\" in patch (if present)"
+msgstr "atualiza \"Date: <data fornecida>\" no patch (se presente)"
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr "hg qrefresh [-I] [-X] [-e] [-m TEXTO] [-l ARQUIVO] [-s] [ARQUIVO]..."
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr "hg qrename PATCH1 [PATCH2]"
+
+msgid "delete save entry"
+msgstr "apaga entrada salva"
+
+msgid "update queue working directory"
+msgstr "atualiza o diretório de trabalho da fila"
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr "hg qrestore [-d] [-u] REV"
+
+msgid "copy patch directory"
+msgstr "copia o diretório do patch"
+
+msgid "copy directory name"
+msgstr "copia o nome do diretório"
+
+msgid "clear queue status file"
+msgstr "limpa o arquivo de estado da fila"
+
+msgid "force copy"
+msgstr "força a cópia"
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr "hg qsave [-m TEXTO] [-l ARQUIVO] [-c] [-n NOME] [-e] [-f]"
+
+msgid "disable all guards"
+msgstr "desabilita todas as guardas"
+
+msgid "list all guards in series file"
+msgstr "lista todas as guardas no arquivo series"
+
+msgid "pop to before first guarded applied patch"
+msgstr "desempilha até antes do primeiro patch aplicado com guarda"
+
+msgid "pop, then reapply patches"
+msgstr "desempilha, e em seguida reaplica os patches"
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr "hg qselect [OPÇÃO]... [GUARDA]..."
+
+msgid "print patches not in series"
+msgstr "imprime os patches que não estão na série"
+
+msgid "hg qseries [-ms]"
+msgstr "hg qseries [-ms]"
+
+msgid "force removal with local changes"
+msgstr "força remoção com mudanças locais"
+
+msgid "bundle unrelated changesets"
+msgstr "armazena no bundle changesets não relacionados"
+
+msgid "no backups"
+msgstr "nenhuma cópia de segurança"
+
+msgid "hg strip [-f] [-b] [-n] REV"
+msgstr "hg strip [-f] [-b] [-n] REV"
+
+msgid "hg qtop [-s]"
+msgstr "hg qtop [-s]"
+
+msgid "hg qunapplied [-s] [PATCH]"
+msgstr "hg qunapplied [-s] [PATCH]"
+
+msgid "finish all applied changesets"
+msgstr "encerra todos os changesets aplicados"
+
+msgid "hg qfinish [-a] [REV]..."
+msgstr "hg qfinish [-a] [REV]..."
+
+msgid ""
+"hooks for sending email notifications at commit/push time\n"
+"\n"
+"Subscriptions can be managed through hgrc. Default mode is to print\n"
+"messages to stdout, for testing and configuring.\n"
+"\n"
+"To use, configure notify extension and enable in hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # one email for each incoming changeset\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # batch emails when many changesets incoming at one time\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # config items go in here\n"
+"\n"
+" config items:\n"
+"\n"
+" REQUIRED:\n"
+" config = /path/to/file # file containing subscriptions\n"
+"\n"
+" OPTIONAL:\n"
+" test = True # print messages to stdout for testing\n"
+" strip = 3 # number of slashes to strip for url paths\n"
+" domain = example.com # domain to use if committer missing domain\n"
+" style = ... # style file to use when formatting email\n"
+" template = ... # template to use when formatting email\n"
+" incoming = ... # template to use when run as incoming hook\n"
+" changegroup = ... # template when run as changegroup hook\n"
+" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n"
+" maxsubject = 67 # truncate subject line longer than this\n"
+" diffstat = True # add a diffstat before the diff content\n"
+" sources = serve # notify if source of incoming changes in this "
+"list\n"
+" # (serve == ssh or http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # email address to send as if none given\n"
+" [web]\n"
+" baseurl = http://hgserver/... # root of hg web site for browsing commits\n"
+"\n"
+" notify config file has same format as regular hgrc. it has two\n"
+" sections so you can express subscriptions in whatever way is handier\n"
+" for you.\n"
+"\n"
+" [usersubs]\n"
+" # key is subscriber email, value is \",\"-separated list of glob "
+"patterns\n"
+" user@host = pattern\n"
+"\n"
+" [reposubs]\n"
+" # key is glob pattern, value is \",\"-separated list of subscriber "
+"emails\n"
+" pattern = user@host\n"
+"\n"
+" glob patterns are matched against path to repository root.\n"
+"\n"
+" if you like, you can put notify config file in repository that users\n"
+" can push changes to, they can manage their own subscriptions."
+msgstr ""
+"gancho para enviar notificações por e-mail em commit/push\n"
+"\n"
+"Assinantes podem ser gerenciados através de hgrc. O modo padrão é\n"
+"imprimir as mensagens para stdout, para testes e configuração.\n"
+"\n"
+"Para usar, configure e habilite a extensão notify no hgrc, dessa\n"
+"forma:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # um e-mail para cada changeset que chegar\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # e-mails em lote quando muitos changesets chegarem de uma vez\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # ítens de configuração vão aqui\n"
+"\n"
+" itens de configuração:\n"
+"\n"
+" NECESSÃRIOS:\n"
+" config = /caminho/arquivo # arquivo contendo assinantes\n"
+"\n"
+" OPCIONAIS:\n"
+" test = True # imprime mensagens para stdout para teste\n"
+" strip = 3 # número de barras a remover de URLs\n"
+" domain = example.com # domínio a usar se autor não tiver domínio\n"
+" style = ... # arquivo de estilo para formatar o e-mail\n"
+" template = ... # modelo para formatar o e-mail\n"
+" incoming = ... # modelo ao rodar como gancho de entrada\n"
+" changegroup = ... # modelo ao rodar como gancho changegroup\n"
+" maxdiff = 300 # no. máximo de linhas de diff incluídas\n"
+" # (0=nenhuma, -1=todas)\n"
+" maxsubject = 67 # trunca linhas de assunto maiores que isso\n"
+" diffstat = True # adiciona um diffstat antes do diff\n"
+" sources = serve # notifica se a fonte de mudanças recebidas\n"
+" # estiver nessa lista\n"
+" # (serve == ssh ou http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # endereço de e-mail de envio se não houver\n"
+" [web]\n"
+" baseurl = http://hgserver/... # raiz do web site hg para\n"
+" # visualizar consolidações\n"
+"\n"
+" o arquivo de configuração do notify tem o mesmo formato que um\n"
+" hgrc comum. Possui duas seções, com isso você pode exprimir as\n"
+" assinaturas do modo mais conveniente para você.\n"
+"\n"
+" [usersubs]\n"
+" # a chave é o e-mail do assinante, o valor é uma lista separada\n"
+" # por vírgulas de padrões glob\n"
+" user@host = padrão,padrão\n"
+"\n"
+" [reposubs]\n"
+" # a chave é o padrão glob, o valor é uma lista separada por\n"
+" # vírgulas de e-mails dos assinantes\n"
+" padrão = user@host\n"
+"\n"
+" padrões glob são casados com o caminho da raiz do repositório.\n"
+"\n"
+" se você quiser, você pode colocar o arquivo de configuração do\n"
+" notify em um repositório com acesso de envio para os usuários,\n"
+" de modo que eles possam gerenciar suas próprias assinaturas."
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr "%s: %d novos changesets"
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr "notify: enviando a %d assinantes %d mudanças\n"
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):\n"
+"\n"
+msgstr ""
+"\n"
+"diffs (truncados de %d para %d linhas):\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):\n"
+"\n"
+msgstr ""
+"\n"
+"diffs (%d linhas):\n"
+"\n"
+
+#, python-format
+msgid "notify: no subscribers to repository %s\n"
+msgstr "notify: nenhum assinante do repositório %s\n"
+
+#, python-format
+msgid "notify: changes have source \"%s\" - skipping\n"
+msgstr "notify: mudanças têm origem \"%s\" - omitindo\n"
+
+msgid ""
+"browse command output with an external pager\n"
+"\n"
+"To set the pager that should be used, set the application variable:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"If no pager is set, the pager extensions uses the environment variable\n"
+"$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.\n"
+"\n"
+"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
+"setting:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"You can also enable the pager only for certain commands using\n"
+"pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"If pager.attend is present, pager.ignore will be ignored.\n"
+"\n"
+"To ignore global commands like \"hg version\" or \"hg help\", you have to\n"
+"specify them in the global .hgrc\n"
+msgstr ""
+"visualiza a saída do comando com um pager externo\n"
+"\n"
+"Para definir o pager a ser usado, defina a variável de aplicação:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"Se nenhum pager estiver definido, as extensões de pager usa a variável\n"
+"ambiente $PAGER. Se nem pager.pager nem $PAGER estiverem definidas,\n"
+"nenhum pager será usado.\n"
+"\n"
+"Se você notar mensagens de erro \"PIPE QUEBRADO\" (ou\n"
+"\"BROKEN PIPE\"), você pode desabilitá-las definindo:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"Você pode desabilitar o pager para certos comandos adicionando-os\n"
+"à lista pager.ignore:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"Você também pode habilitar o pager para apenas certos comandos\n"
+"usando pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"Se pager.attend estiver presente, pager.ignore será ignorado.\n"
+"\n"
+"Para ignorar comandos globais como \"hg version\" ou \"hg help\",\n"
+"você precisa especificá-los no .hgrc global.\n"
+
+msgid ""
+"interpret suffixes to refer to ancestor revisions\n"
+"\n"
+"This extension allows you to use git-style suffixes to refer to the\n"
+"ancestors of a specific revision.\n"
+"\n"
+"For example, if you can refer to a revision as \"foo\", then:\n"
+"\n"
+"- foo^N = Nth parent of foo\n"
+" foo^0 = foo\n"
+" foo^1 = first parent of foo\n"
+" foo^2 = second parent of foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nth first grandparent of foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = first parent of foo\n"
+" foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
+msgstr ""
+"interpreta sufixos para referência a revisões ancestrais\n"
+"\n"
+"Esta extensão lhe permite usar sufixos estilo git para se referir\n"
+"aos ancestrais de uma revisão específica.\n"
+"\n"
+"Por exemplo, se você puder se referir a uma revisão com \"foo\",\n"
+"então:\n"
+"\n"
+"- foo^N = N-ésimo pai de foo\n"
+" foo^0 = foo\n"
+" foo^1 = primeiro pai de foo\n"
+" foo^2 = segundo pai de foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = N-ésimo avô de foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = primeiro pai de foo\n"
+" foo~2 = foo^1^1 = foo^^ = primeiro pai do primeiro pai de foo\n"
+
+msgid ""
+"command to send changesets as (a series of) patch emails\n"
+"\n"
+"The series is started off with a \"[PATCH 0 of N]\" introduction, which\n"
+"describes the series as a whole.\n"
+"\n"
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using the\n"
+"first line of the changeset description as the subject text. The\n"
+"message contains two or three body parts:\n"
+"\n"
+" The changeset description.\n"
+"\n"
+" [Optional] The result of running diffstat on the patch.\n"
+"\n"
+" The patch itself, as generated by \"hg export\".\n"
+"\n"
+"Each message refers to the first in the series using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in threaded\n"
+"mail and news readers, and in mail archives.\n"
+"\n"
+"With the -d/--diffstat option, you will be prompted for each changeset\n"
+"with a diffstat summary and the changeset summary, so you can be sure\n"
+"you are sending the right changes.\n"
+"\n"
+"To configure other defaults, add a section like this to your hgrc\n"
+"file:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Then you can use the \"hg email\" command to mail a series of changesets\n"
+"as a patchbomb.\n"
+"\n"
+"To avoid sending patches prematurely, it is a good idea to first run\n"
+"the \"email\" command with the \"-n\" option (test only). You will be\n"
+"prompted for an email recipient address, a subject and an introductory\n"
+"message describing the patches of your patchbomb. Then when all is\n"
+"done, patchbomb messages are displayed. If the PAGER environment\n"
+"variable is set, your pager will be fired up once for each patchbomb\n"
+"message, so you can verify everything is alright.\n"
+"\n"
+"The -m/--mbox option is also very useful. Instead of previewing each\n"
+"patchbomb message in a pager or sending the messages directly, it will\n"
+"create a UNIX mailbox file with the patch emails. This mailbox file\n"
+"can be previewed with any mail user agent which supports UNIX mbox\n"
+"files, e.g. with mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"When you are previewing the patchbomb messages, you can use `formail'\n"
+"(a utility that is commonly installed as part of the procmail\n"
+"package), to send each message out:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"That should be all. Now your patchbomb is on its way out.\n"
+"\n"
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatible mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs\n"
+"directly from the commandline. See the [email] and [smtp] sections in\n"
+"hgrc(5) for details."
+msgstr ""
+"comando para enviar changesets como uma série de e-mails de patch\n"
+"\n"
+"A série é iniciada por uma introdução \"[PATCH 0 of N]\", que\n"
+"descreve a série como um todo.\n"
+"\n"
+"Cada e-mail de patch tem uma linha Assunto com a forma\n"
+"\"[PATCH M of N] ...\", usando a primeira linha da descrição do\n"
+"changeset como texto do assunto. A mensagem contém dois ou três\n"
+"corpos:\n"
+"\n"
+" A descrição do changeset.\n"
+"\n"
+" [Opcional] O resultado da execução de diffstat no patch.\n"
+"\n"
+" O patch em si, como gerado por \"hg export\".\n"
+"\n"
+"Cada mensagem faz referência à primeira da série usando os cabeçalhos\n"
+"In-Reply-To e References, de modo que as mensagens aparecerão como\n"
+"uma seqüência em e-mails organizados por conversação e leitores de\n"
+"notícias, além de mail archives.\n"
+"\n"
+"Com a opção -d/--diffstat, para cada changeset você será consultado\n"
+"interativamente com um resumo do diffstat e o resumo do changeset,\n"
+"para que você tenha certeza de enviar as mudanças corretas.\n"
+"\n"
+"Para configurar outros padrões, adicione uma seção como esta em seu\n"
+"arquivo hgrc:\n"
+"\n"
+" [email]\n"
+" from = Meu Nome <meu@email>\n"
+" to = destinatario1, destinatario2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Então você poderá usar o comando \"hg email\" para enviar por e-mail\n"
+"uma série de changesets como uma \"patchbomb\".\n"
+"\n"
+"Para evitar o envio de patches de forma prematura, é uma boa idéia\n"
+"executar o comando \"email\" com a opção \"-n\" (somente teste).\n"
+"Será pedido um endereço de e-mail de destino, um assunto e uma\n"
+"mensagem introdutória descrevendo os patches de seu patchbomb.\n"
+"Quando tudo estiver feito, as mensagens do patchbomb serão\n"
+"exibidas. Se a variável de ambiente PAGER estiver definida, seu\n"
+"visualizador será executado uma vez para cada mensagem do patchbomb,\n"
+"para que você possa verificar se tudo está certo.\n"
+"\n"
+"A opção -m/--mbox também é bem útil. Ao invés de visualizar as\n"
+"mensagens como texto ou enviá-las diretamente, o comando irá criar\n"
+"um arquivo de mailbox UNIX com os e-mails de patch. Este arquivo de\n"
+"mailbox pode ser visualizado com qualquer cliente de e-mails que\n"
+"suporte arquivos mbox UNIX, por exemplo o mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"Ao rever cada mensagem do patchbomb, você pode usar `formail' (um\n"
+"utilitário comumente instalado como parte do pacote procmail) para\n"
+"enviar cada mensagem:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"Isto deve ser o bastante. Agora seu patchbomb está a caminho.\n"
+"\n"
+"Você também pode tanto configurar a opção method na seção email\n"
+"para um programa de envio de e-mails compatível com o sendmail\n"
+"como preencher a seção [smtp] para que a extensão patchbomb possa\n"
+"automaticamente enviar patchbombs diretamente da linha de comando.\n"
+"Veja as seções [email] e [smtp] na página de manual hgrc(5) para\n"
+"mais detalhes."
+
+msgid "Please enter a valid value.\n"
+msgstr "Por favor, entre um valor válido.\n"
+
+msgid "does the diffstat above look okay? "
+msgstr "o diffstat abaixo parece bom? "
+
+msgid "diffstat rejected"
+msgstr "diffstat rejeitado"
+
+msgid ""
+"send changesets by email\n"
+"\n"
+" By default, diffs are sent in the format generated by hg export,\n"
+" one per message. The series starts with a \"[PATCH 0 of N]\"\n"
+" introduction, which describes the series as a whole.\n"
+"\n"
+" Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+" the first line of the changeset description as the subject text.\n"
+" The message contains two or three parts. First, the changeset\n"
+" description. Next, (optionally) if the diffstat program is\n"
+" installed and -d/--diffstat is used, the result of running\n"
+" diffstat on the patch. Finally, the patch itself, as generated by\n"
+" \"hg export\".\n"
+"\n"
+" By default the patch is included as text in the email body for\n"
+" easy reviewing. Using the -a/--attach option will instead create\n"
+" an attachment for the patch. With -i/--inline an inline attachment\n"
+" will be created.\n"
+"\n"
+" With -o/--outgoing, emails will be generated for patches not found\n"
+" in the destination repository (or only those which are ancestors\n"
+" of the specified revisions if any are provided)\n"
+"\n"
+" With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+" single email containing a binary Mercurial bundle as an attachment\n"
+" will be sent.\n"
+"\n"
+" Examples:\n"
+"\n"
+" hg email -r 3000 # send patch 3000 only\n"
+" hg email -r 3000 -r 3001 # send patches 3000 and 3001\n"
+" hg email -r 3000:3005 # send patches 3000 through 3005\n"
+" hg email 3000 # send patch 3000 (deprecated)\n"
+"\n"
+" hg email -o # send all patches not in default\n"
+" hg email -o DEST # send all patches not in DEST\n"
+" hg email -o -r 3000 # send all ancestors of 3000 not in default\n"
+" hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST\n"
+"\n"
+" hg email -b # send bundle of all patches not in default\n"
+" hg email -b DEST # send bundle of all patches not in DEST\n"
+" hg email -b -r 3000 # bundle of all ancestors of 3000 not in "
+"default\n"
+" hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST\n"
+"\n"
+" Before using this command, you will need to enable email in your\n"
+" hgrc. See the [email] section in hgrc(5) for details.\n"
+" "
+msgstr ""
+"envia changesets por e-mail\n"
+"\n"
+" Por padrão, diffs são enviados no formato gerado por hg export,\n"
+" um por mensagem. A série inicia com uma introdução\n"
+" \"[PATCH 0 of N]\", que descreve a série como um todo.\n"
+"\n"
+" Cada e-mail de patch tem uma linha Assunto com a forma\n"
+" \"[PATCH M of N] ...\", usando a primeira linha da descrição do\n"
+" changeset como texto do assunto. A mensagem contém duas ou três\n"
+" partes. Em primeiro lugar, a descrição do changeset. Em seguida\n"
+" (opcionalmente), se o programa diffstat estiver instalado e a\n"
+" opção -d/--diffstat for usada, o resultado da execução de\n"
+" diffstat no patch. Por fim, o patch em si, como gerado por\n"
+" \"hg export\".\n"
+"\n"
+" Por padrão o patch é incluído como texto no corpo do e-mail para\n"
+" facilitar a revisão. A opção -a/--attach pode ser usada para ao\n"
+" invés disso criar um anexo para o patch. Com a opção -i/--inline\n"
+" um anexo inline será criado.\n"
+"\n"
+" Com -o/--outgoing, e-mails serão gerados para patches não\n"
+" encontrados no repositório de destino (ou apenas aqueles que\n"
+" forem ancestrais das revisões, se estas forem especificadas)\n"
+"\n"
+" Com -b/--bundle, os changesets são selecionados assim como em\n"
+" --outgoing, mas um único e-mail contendo em anexo um bundle\n"
+" binário do Mercurial será enviado.\n"
+"\n"
+" Exemplos:\n"
+"\n"
+" hg email -r 3000 # envia apenas o patch\n"
+" hg email -r 3000 -r 3001 # envia os patches 3000 e 3001\n"
+" hg email -r 3000:3005 # envia os patches de 3000 até 3005\n"
+" hg email 3000 # envia o patch 3000 (obsoleto)\n"
+"\n"
+" hg email -o # envia todos os patches não presentes\n"
+" # no destino padrão\n"
+" hg email -o DEST # envia todos os patches não presentes\n"
+" # em DEST\n"
+" hg email -o -r 3000 # envia todos os ancestrais de 3000 não\n"
+" # presentes no destino padrão\n"
+" hg email -o -r 3000 DEST # envia todos os ancestrais de 3000 não\n"
+" # presentes em DEST\n"
+"\n"
+" hg email -b # envia um bundle de todos os patches\n"
+" # não presentes no destino padrão\n"
+" hg email -b DEST # envia um bundle de todos os patches\n"
+" # não presentes em DEST\n"
+" hg email -b -r 3000 # um bundle de todos os ancestrais de\n"
+" # 3000 não presentes no destino padrão\n"
+" hg email -b -r 3000 DEST # um bundle de todos os ancestrais de\n"
+" # 3000 não presentes em DEST\n"
+"\n"
+" Antes de usar este comando, você precisará habilitar e-mail em\n"
+" seu hgrc. Veja a seção [email] em hgrc(5) para mais detalhes.\n"
+" "
+
+msgid "specify at least one changeset with -r or -o"
+msgstr "especifique ao menos um changeset com -r ou -o"
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr "modo é sempre --outgoing com --bundle; não especifique --outgoing novamente"
+
+msgid "too many destinations"
+msgstr "muitos destinos"
+
+msgid "use only one form to specify the revision"
+msgstr "use apenas uma forma de especificar a revisão"
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series.\n"
+"\n"
+msgstr ""
+"\n"
+"Escreve a mensagem introdutória para a série de patches.\n"
+"\n"
+
+#, python-format
+msgid ""
+"This patch series consists of %d patches.\n"
+"\n"
+msgstr ""
+"Esta série de patches consiste de %d patches.\n"
+"\n"
+
+msgid "Final summary:\n"
+msgstr "Sumário final:\n"
+
+msgid "Displaying "
+msgstr "Exibindo "
+
+msgid "Writing "
+msgstr "Escrevendo "
+
+msgid "Sending "
+msgstr "Enviando "
+
+msgid "send patches as attachments"
+msgstr "envia patches como anexos"
+
+msgid "send patches as inline attachments"
+msgstr "envia patches como anexos embutidos"
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr "endereços de e-mail de destinatários para cópia oculta"
+
+msgid "email addresses of copy recipients"
+msgstr "endereços de e-mail de destinatários para cópia"
+
+msgid "add diffstat output to messages"
+msgstr "adiciona a saída do diffstat a mensagens"
+
+msgid "use the given date as the sending date"
+msgstr "usa a data dada como data de envio"
+
+msgid "use the given file as the series description"
+msgstr "usa o arquivo dado como descrição da série"
+
+msgid "email address of sender"
+msgstr "endereço de email do remetente"
+
+msgid "print messages that would be sent"
+msgstr "imprime mensagens que seriam enviadas"
+
+msgid "write messages to mbox file instead of sending them"
+msgstr "escreve mensagens para arquivo mbox ao invés de enviá-las"
+
+msgid "subject of first message (intro or single patch)"
+msgstr "assunto da primeira mensagem (introdução ou único patch)"
+
+msgid "message identifier to reply to"
+msgstr "identificador de mensagem para a qual responder"
+
+msgid "email addresses of recipients"
+msgstr "endereços de e-mail dos destinatários"
+
+msgid "omit hg patch header"
+msgstr "omite o cabeçalho do hg patch"
+
+msgid "send changes not found in the target repository"
+msgstr "envia mudanças não encontradas no repositório alvo"
+
+msgid "send changes not in target as a binary bundle"
+msgstr "envia mudanças que não estão no alvo como um bundle binário"
+
+msgid "name of the bundle attachment file"
+msgstr "nome do arquivo bundle anexado"
+
+msgid "a revision to send"
+msgstr "a revisão a enviar"
+
+msgid "run even when remote repository is unrelated (with -b/--bundle)"
+msgstr "executa mesmo se o repositório não for relacionado (com -b/--bundle)"
+
+msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
+msgstr "um changeset base especificado ao invés de um destino (com -b/--bundle)"
+
+msgid "send an introduction email for a single patch"
+msgstr "manda um e-mail introdutório para um patch único"
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr "hg email [OPÇÃO]... [DEST]..."
+
+msgid "command to delete untracked files from the working directory"
+msgstr "comando para apagar do diretório de trabalho arquivos não rastreados"
+
+msgid ""
+"removes files not tracked by Mercurial\n"
+"\n"
+" Delete files not known to Mercurial. This is useful to test local\n"
+" and uncommitted changes in an otherwise-clean source tree.\n"
+"\n"
+" This means that purge will delete:\n"
+" - Unknown files: files marked with \"?\" by \"hg status\"\n"
+" - Empty directories: in fact Mercurial ignores directories unless\n"
+" they contain files under source control management\n"
+" But it will leave untouched:\n"
+" - Modified and unmodified tracked files\n"
+" - Ignored files (unless --all is specified)\n"
+" - New files added to the repository (with \"hg add\")\n"
+"\n"
+" If directories are given on the command line, only files in these\n"
+" directories are considered.\n"
+"\n"
+" Be careful with purge, as you could irreversibly delete some files\n"
+" you forgot to add to the repository. If you only want to print the\n"
+" list of files that this program would delete, use the --print\n"
+" option.\n"
+" "
+msgstr ""
+"remove arquivos não rastreados pelo Mercurial\n"
+"\n"
+" Apaga arquivos não rastreados pelo Mercurial. Isso é útil para\n"
+" testar mudanças locais e não gravadas em uma árvore que contenha\n"
+" apenas essas mudanças.\n"
+"\n"
+" Isto quer dizer que purge irá apagar:\n"
+" - Arquivos não conhecidos: arquivos marcados com \"?\" em\n"
+" \"hg status\"\n"
+" - Diretórios vazios: de fato o Mercurial ignora diretórios a\n"
+" não ser que eles contenham arquivos versionados\n"
+" Mas deixará como estão:\n"
+" - Arquivos versionados, modificados ou não\n"
+" - Arquivos ignorados (a não ser que --all seja especificado)\n"
+" - Novos arquivos adicionados ao repositório (com \"hg add\")\n"
+"\n"
+" Se diretórios forem passados na linha de comando, apenas arquivos\n"
+" nesses diretórios serão considerados.\n"
+"\n"
+" Tenha cuidado com o comando purge, pois você pode remover de\n"
+" forma irreversível alguns arquivos que você esqueceu de adicionar\n"
+" ao repositório. Se você deseja apenas imprimir a lista de\n"
+" arquivos que este programa iria apagar, use a opção --print.\n"
+" "
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr "%s não pode ser removido"
+
+#, python-format
+msgid "warning: %s\n"
+msgstr "aviso: %s\n"
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr "Removendo arquivo %s\n"
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr "Removendo diretório %s\n"
+
+msgid "abort if an error occurs"
+msgstr "aborta se ocorrer um erro"
+
+msgid "purge ignored files too"
+msgstr "remove também arquivos ignorados"
+
+msgid "print filenames instead of deleting them"
+msgstr "imprime os nomes de arquivo ao invés de removê-los"
+
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr "termina nomes de arquivo com NUL, para uso com xargs (implica -p/--print)"
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr "hg purge [OPÇÃO]... [DIR]..."
+
+msgid ""
+"command to move sets of revisions to a different ancestor\n"
+"\n"
+"This extension lets you rebase changesets in an existing Mercurial\n"
+"repository.\n"
+"\n"
+"For more information:\n"
+"http://mercurial.selenic.com/wiki/RebaseProject\n"
+msgstr ""
+"comando para mover conjuntos de revisões para um ancestral diferente\n"
+"\n"
+"Esta extensão lhe permite rebasear changesets em um repositório\n"
+"existente do Mercurial.\n"
+"\n"
+"Para mais informações:\n"
+"http://mercurial.selenic.com/wiki/RebaseProject\n"
+
+msgid "first revision, do not change ancestor\n"
+msgstr "primeira revisão, não mude o ancestral\n"
+
+msgid ""
+"move changeset (and descendants) to a different branch\n"
+"\n"
+" Rebase uses repeated merging to graft changesets from one part of\n"
+" history onto another. This can be useful for linearizing local\n"
+" changes relative to a master development tree.\n"
+"\n"
+" If a rebase is interrupted to manually resolve a merge, it can be\n"
+" continued with --continue/-c or aborted with --abort/-a.\n"
+" "
+msgstr ""
+"move o changeset (e descendentes) para um ramo diferente\n"
+"\n"
+" Rebase usa mesclagens repetidamente para migrar changesets de uma\n"
+" parte do histórico para outra. Isto pode ser útil para linearizar\n"
+" mudanças locais relativas a uma árvore mestra de desenvolvimento.\n"
+"\n"
+" Se um rebaseamento for interrompido para resolver uma mesclagem\n"
+" manualmente, ele pode ser continuado com --continue/-c ou abortado\n"
+" com --abort/-a.\n"
+" "
+
+msgid "cannot use both abort and continue"
+msgstr "não se pode usar abort e continue simultaneamente"
+
+msgid "cannot use collapse with continue or abort"
+msgstr "não se pode usar collapse com continue ou abort"
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr "abort e continue não permitem especificar revisões"
+
+msgid "cannot specify both a revision and a base"
+msgstr "não se pode especificar ao mesmo tempo uma revisão e uma base"
+
+msgid "nothing to rebase\n"
+msgstr "nada para rebasear\n"
+
+msgid "cannot use both keepbranches and extrafn"
+msgstr "não se pode usar keepbranches e extrafn simultaneamente"
+
+msgid "rebase merging completed\n"
+msgstr "mesclagem de rebaseamento completada\n"
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr "aviso: novos changesets detectados no ramo de origem, strip não realizado\n"
+
+msgid "rebase completed\n"
+msgstr "rebaseamento completado\n"
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr "%d revisões foram omitidas\n"
+
+msgid " set parents\n"
+msgstr " define pais\n"
+
+#, python-format
+msgid "rebasing %d:%s\n"
+msgstr "rebaseando %d:%s\n"
+
+#, python-format
+msgid " future parents are %d and %d\n"
+msgstr " futuros pais são %d e %d\n"
+
+#, python-format
+msgid " update to %d:%s\n"
+msgstr " atualização para %d:%s\n"
+
+msgid " already in target\n"
+msgstr " já no alvo\n"
+
+#, python-format
+msgid " merge against %d:%s\n"
+msgstr " mesclando com %d:%s\n"
+
+msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgstr ""
+"corrija conflitos não resolvidos com hg resolve e então execute hg rebase --"
+"continue"
+
+msgid "resuming interrupted rebase\n"
+msgstr "retomando rebaseamento interrompido\n"
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr "nenhuma mudança, revisão %d omitida\n"
+
+#, python-format
+msgid "next revision set to %s\n"
+msgstr "próxima revisão definida como %s\n"
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr "não se pode usar a revisão %d como base, o resultado teria 3 pais"
+
+#, python-format
+msgid "revision %d is an mq patch (%s), finalize it.\n"
+msgstr "revisão %d é um patch mq (%s), finalize-o.\n"
+
+#, python-format
+msgid "import mq patch %d (%s)\n"
+msgstr "importa patch mq %d (%s)\n"
+
+msgid "rebase status stored\n"
+msgstr "estado de rebaseamento armazenado\n"
+
+msgid "rebase status resumed\n"
+msgstr "estado de rebaseamento retomado\n"
+
+msgid "no rebase in progress"
+msgstr "nenhum rebaseamento em progresso"
+
+msgid "warning: new changesets detected on target branch, not stripping\n"
+msgstr "aviso: novos changesets detectados no ramo alvo, strip não realizado\n"
+
+msgid "rebase aborted\n"
+msgstr "rebaseamento abortado\n"
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr "não se pode rebasear para um patch mq aplicado"
+
+msgid "cannot rebase an ancestor"
+msgstr "não se pode rebasear um ancestral"
+
+msgid "cannot rebase a descendant"
+msgstr "não se pode rebasear um descendente"
+
+msgid "already working on current\n"
+msgstr "já trabalhando no atual\n"
+
+msgid "already working on the current branch\n"
+msgstr "já trabalhando no ramo atual\n"
+
+#, python-format
+msgid "rebase onto %d starting from %d\n"
+msgstr "rebaseamento para %d iniciando de %d\n"
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr "incapaz de colapsar, há mais de um pai externo"
+
+msgid "--update and --rebase are not compatible, ignoring the update flag\n"
+msgstr "--update e --rebase não são compatíveis, opção --update ignorada\n"
+
+msgid "rebase working directory to branch head"
+msgstr "rebaseia o diretório de trabalho para a cabeça do ramo"
+
+msgid "rebase from a given revision"
+msgstr "rebaseia a partir de uma revisão dada"
+
+msgid "rebase from the base of a given revision"
+msgstr "rebaseia a partir da base de uma revisão dada"
+
+msgid "rebase onto a given revision"
+msgstr "rebaseia para a revisão dada"
+
+msgid "collapse the rebased revisions"
+msgstr "colapsa as revisões rebaseadas"
+
+msgid "keep original revisions"
+msgstr "mantém revisões originais"
+
+msgid "keep original branches"
+msgstr "mantém ramos originais"
+
+msgid "continue an interrupted rebase"
+msgstr "continua um rebaseamento interrompido"
+
+msgid "abort an interrupted rebase"
+msgstr "aborta um rebaseamento interrompido"
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+msgstr ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+
+msgid "commands to interactively select changes for commit/qrefresh"
+msgstr "comandos para selecionar interativamente mudanças em um commit ou qrefresh"
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr "isto modifica um arquivo binário (tudo ou nada)\n"
+
+msgid "this is a binary file\n"
+msgstr "este é um arquivo binário\n"
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr "%d trechos, %d linhas modificadas\n"
+
+msgid "[Ynsfdaq?]"
+msgstr "[Ynsfdaq?]"
+
+msgid "&Yes, record this change"
+msgstr "(&Y) sim, grava esta mudança"
+
+msgid "&No, skip this change"
+msgstr "(&N) não, descarta essa mudança"
+
+msgid "&Skip remaining changes to this file"
+msgstr "(&S) descarta mudanças restantes neste arquivo"
+
+msgid "Record remaining changes to this &file"
+msgstr "(&F) grava as mudanças restantes deste arquivo"
+
+msgid "&Done, skip remaining changes and files"
+msgstr "(&D) terminado, descarta mudanças e arquivos restantes"
+
+msgid "Record &all changes to all remaining files"
+msgstr "(&A) grava todas as mudanças dos arquivos restantes"
+
+msgid "&Quit, recording no changes"
+msgstr "(&Q) encerra, sem gravar nenhuma mudança"
+
+msgid "&?"
+msgstr "&?"
+
+msgid "y"
+msgstr "y"
+
+msgid "?"
+msgstr "?"
+
+msgid "y - record this change"
+msgstr "y - grava esta mudança"
+
+msgid "s"
+msgstr "s"
+
+msgid "f"
+msgstr "f"
+
+msgid "d"
+msgstr "d"
+
+msgid "a"
+msgstr "a"
+
+msgid "q"
+msgstr "q"
+
+msgid "user quit"
+msgstr "usuário encerrou"
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr "examinar mudanças em %s?"
+
+msgid " and "
+msgstr " e "
+
+#, python-format
+msgid "record this change to %r?"
+msgstr "gravar esta mudança em %r?"
+
+#, python-format
+msgid "record change %d/%d to %r?"
+msgstr "gravar mudança %d/%d em %r?"
+
+msgid ""
+"interactively select changes to commit\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be candidates for recording.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" You will be prompted for whether to record changes to each\n"
+" modified file, and for files with multiple changes, for each\n"
+" change to use. For each query, the following responses are\n"
+" possible:\n"
+"\n"
+" y - record this change\n"
+" n - skip this change\n"
+"\n"
+" s - skip remaining changes to this file\n"
+" f - record remaining changes to this file\n"
+"\n"
+" d - done, skip remaining changes and files\n"
+" a - record all changes to all remaining files\n"
+" q - quit, recording no changes\n"
+"\n"
+" ? - display help"
+msgstr ""
+"seleção interativa de alterações para consolidação\n"
+"\n"
+" Se for omitida uma lista de arquivos, todas as alterações\n"
+" informadas por \"hg status\" serão candidatas para gravação.\n"
+"\n"
+" Veja 'hg help dates' para obter uma lista de todos os formatos\n"
+" válidos para -d/--date.\n"
+"\n"
+" Você poderá selecionar interativamente a gravação de cada\n"
+" arquivo modificado, além de cada alteração dentro dos arquivos\n"
+" (no caso de arquivos com mais de uma alteração). Para cada\n"
+" consulta, as seguintes respostas são possíveis:\n"
+"\n"
+" y - grava essa alteração\n"
+" n - omite a alteração\n"
+"\n"
+" s - omite as alterações restantes desse arquivo\n"
+" f - grava as alterações restantes desse arquivo\n"
+"\n"
+" d - omite alterações e arquivos restantes\n"
+" a - grava todas as alterações em todos os arquivos restantes\n"
+" q - aborta, sem gravar qualquer alteração\n"
+"\n"
+" ? - exibe o texto de ajuda"
+
+msgid "'mq' extension not loaded"
+msgstr "extensão 'mq' não carregada"
+
+msgid "running non-interactively, use commit instead"
+msgstr "não está executando interativamente, use commit"
+
+msgid "no changes to record\n"
+msgstr "nenhuma mudança a ser gravada\n"
+
+#, python-format
+msgid "backup %r as %r\n"
+msgstr "fazendo uma cópia de segurança de %r em %r\n"
+
+msgid "applying patch\n"
+msgstr "aplicando patch\n"
+
+msgid "patch failed to apply"
+msgstr "aplicação do patch falhou"
+
+#, python-format
+msgid "restoring %r to %r\n"
+msgstr "restaurando %r a %r\n"
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr "hg record [OPÇÃO]... [ARQUIVO]..."
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr "hg qrecord [OPÇÃO]... PATCH [ARQUIVO]..."
+
+msgid "share a common history between several working directories"
+msgstr "compartilha histórico comum entre vários diretórios de trabalho"
+
+msgid ""
+"create a new shared repository (experimental)\n"
+"\n"
+" Initialize a new repository and working directory that shares its\n"
+" history with another repository.\n"
+"\n"
+" NOTE: actions that change history such as rollback or moving the\n"
+" source may confuse sharers.\n"
+" "
+msgstr ""
+"cria um novo repositório compartilhado (experimental)\n"
+"\n"
+" Inicializa um novo repositório e diretório de trabalho que\n"
+" compartilha seu histórico com outro repositório.\n"
+"\n"
+" NOTA: ações que mudem o histórico, como rollback ou mover a\n"
+" origem, podem confundir repositórios compartilhados.\n"
+" "
+
+msgid "do not create a working copy"
+msgstr "não cria uma cópia de trabalho"
+
+msgid "[-U] SOURCE [DEST]"
+msgstr "[-U] ORIGEM [DEST]"
+
+msgid ""
+"command to transplant changesets from another branch\n"
+"\n"
+"This extension allows you to transplant patches from another branch.\n"
+"\n"
+"Transplanted patches are recorded in .hg/transplant/transplants, as a\n"
+"map from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+"comando para transplantar changesets de um outro ramo\n"
+"\n"
+"Esta extensão lhe permite transplantar patches de outro ramo.\n"
+"\n"
+"Patches transplantados são gravados em .hg/transplant/transplants,\n"
+"como um mapeamento de um hash de changeset para seu hash no\n"
+"repositório de origem.\n"
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr "omitindo revisão %s já aplicada\n"
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr "omitindo changeset de mesclagem %s:%s\n"
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr "%s mesclado em %s\n"
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr "%s transplantado para %s\n"
+
+#, python-format
+msgid "filtering %s\n"
+msgstr "filtrando %s\n"
+
+msgid "filter failed"
+msgstr "filtro falhou"
+
+msgid "can only omit patchfile if merging"
+msgstr "só é possível omitir arquivo de patch em uma mesclagem"
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr "%s: changeset vazio"
+
+msgid "Fix up the merge and run hg transplant --continue"
+msgstr "Conserte a mesclagem e execute hg transplant --continue"
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr "%s transplantado em %s\n"
+
+msgid "transplant log file is corrupt"
+msgstr "arquivo de log de transplante corrompido"
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr "diretório de trabalho não está no pai do transplante %s"
+
+msgid "commit failed"
+msgstr "falha ao consolidar"
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr "aplicar changeset? [ynmpcq?]:"
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+" Selected changesets will be applied on top of the current working\n"
+" directory with the log of the original changeset. If --log is\n"
+" specified, log messages will have a comment appended of the form:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" You can rewrite the changelog message with the --filter option.\n"
+" Its argument will be invoked with the current changelog message as\n"
+" $1 and the patch as $2.\n"
+"\n"
+" If --source/-s is specified, selects changesets from the named\n"
+" repository. If --branch/-b is specified, selects changesets from\n"
+" the branch holding the named revision, up to that revision. If\n"
+" --all/-a is specified, all changesets on the branch will be\n"
+" transplanted, otherwise you will be prompted to select the\n"
+" changesets you want.\n"
+"\n"
+" hg transplant --branch REVISION --all will rebase the selected\n"
+" branch (up to the named revision) onto your current working\n"
+" directory.\n"
+"\n"
+" You can optionally mark selected transplanted changesets as merge\n"
+" changesets. You will not be prompted to transplant any ancestors\n"
+" of a merged transplant, and you can merge descendants of them\n"
+" normally instead of transplanting them.\n"
+"\n"
+" If no merges or revisions are provided, hg transplant will start\n"
+" an interactive changeset browser.\n"
+"\n"
+" If a changeset application fails, you can fix the merge by hand\n"
+" and then resume where you left off by calling hg transplant\n"
+" --continue/-c.\n"
+" "
+msgstr ""
+"transplanta changesets de outro ramo\n"
+"\n"
+" Os changesets selecionados serão aplicados sobre o diretório de\n"
+" trabalho atual com o log do changeset original. Se --log for\n"
+" especificado, mensagens de log terão anexado um comentário da\n"
+" forma:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" Você pode reescrever a mensagem de changelog com a opção\n"
+" --filter . Seu argumento será chamado com a mensagem atual de\n"
+" changelog em $1 e o patch em $2.\n"
+"\n"
+" Se --source/-s for especificado, seleciona changesets do\n"
+" repositório pedido. Se --branch/-b for especificado, seleciona\n"
+" changesets do ramo que contém a revisão especificada, até essa\n"
+" revisão. Se --all/-a for especificado, todos os changesets do\n"
+" ramo serão transplantados, de outro modo os changesets a serem\n"
+" transplantados serão pedidos interativamente.\n"
+"\n"
+" hg transplant --branch REVISÃO --all irá reposicionar o ramo\n"
+" selecionado (até a revisão pedida) no seu diretório de trabalho\n"
+" atual.\n"
+"\n"
+" Você pode opcionalmente marcar os changesets selecionados para\n"
+" transplante como changesets de mesclagem. Os ancestrais de um\n"
+" transplante de mesclagem não serão pedidos interativamente, e\n"
+" você pode mesclar descendentes dele normalmente ao invés de\n"
+" transplantá-los.\n"
+"\n"
+" Se mesclagens ou revisões não forem fornecidas, hg transplant\n"
+" irá iniciar um visualizador interativo de changesets.\n"
+"\n"
+" Se a aplicação de um changeset falhar, você pode corrigir\n"
+" a mesclagem manualmente e em seguida usar hg transplant\n"
+" -c/--continue para retomar o transplante.\n"
+" "
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr "--continue é incompatível com branch, all ou merge"
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr "URL de origem, nome de ramo ou lista de revisões não fornecidas"
+
+msgid "--all requires a branch revision"
+msgstr "--all exige uma revisão de ramo"
+
+msgid "--all is incompatible with a revision list"
+msgstr "--all é incompatível com uma lista de revisões"
+
+msgid "no revision checked out"
+msgstr "nenhuma revisão posicionada"
+
+msgid "outstanding uncommitted merges"
+msgstr "mesclagens pendentes não consolidadas"
+
+msgid "outstanding local changes"
+msgstr "alterações locais pendentes"
+
+msgid "pull patches from REPOSITORY"
+msgstr "traz patches do REPOSITÓRIO"
+
+msgid "pull patches from branch BRANCH"
+msgstr "traz patches do ramo RAMO"
+
+msgid "pull all changesets up to BRANCH"
+msgstr "traz todos os changesets até RAMO"
+
+msgid "skip over REV"
+msgstr "omite revisão REV"
+
+msgid "merge at REV"
+msgstr "mesclagem em REV"
+
+msgid "append transplant info to log message"
+msgstr "anexa informações de transplante à mensagem de log"
+
+msgid "continue last transplant session after repair"
+msgstr "continua a última sessão de transplante após reparos"
+
+msgid "filter changesets through FILTER"
+msgstr "filtra changesets através de FILTRO"
+
+msgid "hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr "hg transplant [-s REPOSITÓRIO] [-b RAMO [-a]] [-p REV] [-m REV] [REV]..."
+
+msgid ""
+"allow the use of MBCS paths with problematic encodings\n"
+"\n"
+"Some MBCS encodings are not good for some path operations (i.e.\n"
+"splitting path, case conversion, etc.) with its encoded bytes. We call\n"
+"such a encoding (i.e. shift_jis and big5) as \"problematic encoding\".\n"
+"This extension can be used to fix the issue with those encodings by\n"
+"wrapping some functions to convert to Unicode string before path\n"
+"operation.\n"
+"\n"
+"This extension is useful for:\n"
+" * Japanese Windows users using shift_jis encoding.\n"
+" * Chinese Windows users using big5 encoding.\n"
+" * All users who use a repository with one of problematic encodings on\n"
+" case-insensitive file system.\n"
+"\n"
+"This extension is not needed for:\n"
+" * Any user who use only ASCII chars in path.\n"
+" * Any user who do not use any of problematic encodings.\n"
+"\n"
+"Note that there are some limitations on using this extension:\n"
+" * You should use single encoding in one repository.\n"
+" * You should set same encoding for the repository by locale or\n"
+" HGENCODING.\n"
+"\n"
+"Path encoding conversion are done between Unicode and\n"
+"encoding.encoding which is decided by Mercurial from current locale\n"
+"setting or HGENCODING.\n"
+msgstr ""
+"permite o uso de caminhos MBCS com codificação problemática.\n"
+"\n"
+"Algumas codificações MBCS não são boas para certas operações de\n"
+"manipulação de caminhos (por exemplo, quebrar o caminho, conversão\n"
+"de maiúsculas / minúsculas, etc.) com seus bytes codificados.\n"
+"Chamamos tais codificações (por exemplo, shift_jis e big5) de\n"
+"\"codificações problemáticas\". Esta extensão pode ser usada para\n"
+"corrigir esses problemas encapsulando algumas funções para as\n"
+"converter em strings Unicode antes das operações de caminho.\n"
+"\n"
+"Esta extensão é útil para:\n"
+" * usuários do Windows em japonês usando codificação shift_jis.\n"
+" * usuários do Windows em chinês usando codificação big5.\n"
+" * Qualquer usuário que usam um repositório com codificação\n"
+" problemática em sistemas de arquivo insensíveis a\n"
+" maiúsculas / minúsculas.\n"
+"\n"
+"Esta extensão não é necessária para:\n"
+" * Qualquer usuário que use apenas caracteres ASCII em caminhos.\n"
+" * Qualquer usuário que não use uma codificação problemática.\n"
+"\n"
+"Note que há algumas limitações no uso desta extensão:\n"
+" * Você deve usar uma única codificação em um repositório.\n"
+" * Você deve definir a mesma codificação com o locale ou HGENCODING.\n"
+"\n"
+"Conversões de codificação de caminhos são feitas entre Unicode e\n"
+"encoding.encoding que é decidida pelo Mercurial a partir de\n"
+"configurações de locale atuais ou HGENCODING.\n"
+
+#, python-format
+msgid "[win32mbcs] filename conversion failed with %s encoding\n"
+msgstr "[win32mbcs] conversão de nome de arquivo falhou com codificação %s\n"
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr "[win32mbcs] não se pode ativar nesta plataforma.\n"
+
+#, python-format
+msgid "[win32mbcs] activated with encoding: %s\n"
+msgstr "[win32mbcs] ativado com codificação: %s\n"
+
+msgid ""
+"perform automatic newline conversion\n"
+"\n"
+"To perform automatic newline conversion, use:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = cleverencode:\n"
+"# or ** = macencode:\n"
+"\n"
+"[decode]\n"
+"** = cleverdecode:\n"
+"# or ** = macdecode:\n"
+"\n"
+"If not doing conversion, to make sure you do not commit CRLF/CR by "
+"accident:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxncommit.cr = python:hgext.win32text.forbidcr\n"
+"\n"
+"To do the same check on a server to prevent CRLF/CR from being\n"
+"pushed or pulled:\n"
+"\n"
+"[hooks]\n"
+"pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxnchangegroup.cr = python:hgext.win32text.forbidcr\n"
+msgstr ""
+"faz conversão automática de tipo de quebras de linha\n"
+"\n"
+"Para fazer conversão automática de quebras de linha, use:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = cleverencode:\n"
+"# or ** = macencode:\n"
+"\n"
+"[decode]\n"
+"** = cleverdecode:\n"
+"# or ** = macdecode:\n"
+"\n"
+"Se a conversão não estiver sendo feita, para garantir que você não\n"
+"consolide CRLF/CR acidentalmente:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxncommit.cr = python:hgext.win32text.forbidcr\n"
+"\n"
+"Para fazer a mesma verificação em um servidor para impedir que\n"
+"CRLF/CR sejam enviados ou trazidos:\n"
+"\n"
+"[hooks]\n"
+"pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxnchangegroup.cr = python:hgext.win32text.forbidcr\n"
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+"AVISO: %s já tem quebras de linha %s\n"
+"e não precisa da conversão de fim de linha do plugin win32text.\n"
+"Antes da próxima consolidação, por favor reconsidere suas\n"
+"configurações de encode/decode em\n"
+"Mercurial.ini ou %s.\n"
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr ""
+"Tentativa de consolidação ou push de arquivo(s) texto usando quebras de "
+"linha %s\n"
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr "em %s: %s\n"
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"and also consider adding:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+"\n"
+"Para prevenir esse engano no seu repositório local,\n"
+"adicione ao Mercurial.ini ou .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"e considere também a adição de:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+
+msgid ""
+"discover and advertise repositories on the local network\n"
+"\n"
+"Zeroconf enabled repositories will be announced in a network without\n"
+"the need to configure a server or a service. They can be discovered\n"
+"without knowing their actual IP address.\n"
+"\n"
+"To allow other people to discover your repository using run \"hg serve\"\n"
+"in your repository.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"You can discover zeroconf enabled repositories by running \"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+msgstr ""
+"descobre e anuncia repositórios na rede local\n"
+"\n"
+"Repositórios que habilitarem zeroconf serão anunciados numa rede\n"
+"sem a necessidade de configurar um servidor ou serviço. Eles podem\n"
+"ser descobertos sem o conhecimento de seus respectivos endereços IP.\n"
+"\n"
+"Para permitir que outras pessoas encontrem seu repositório execute\n"
+"\"hg serve\" em seu repositório.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"Você pode encontrar repositórios com zeroconf habilitado executando\n"
+"\"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+
+msgid "archive prefix contains illegal components"
+msgstr "prefixo de arquivo contém componentes ilegais"
+
+msgid "cannot give prefix when archiving to files"
+msgstr "não é possível fornecer prefixo ao arquivar para arquivos"
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr "tipo de arquivo '%s' desconhecido"
+
+msgid "invalid changegroup"
+msgstr "changegroup inválido"
+
+msgid "unknown parent"
+msgstr "pai desconhecido"
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr "checagem de integridade falhou em %s:%d"
+
+#, python-format
+msgid "%s: not a Mercurial bundle file"
+msgstr "%s: não é um arquivo de bundle do Mercurial"
+
+#, python-format
+msgid "%s: unknown bundle version"
+msgstr "%s: versão de bundle desconhecida"
+
+#, python-format
+msgid "%s: unknown bundle compression type"
+msgstr "%s: tipo de compressão de bundle desconhecido"
+
+msgid "cannot create new bundle repository"
+msgstr "não é possível criar novo repositório de bundle"
+
+#, python-format
+msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgstr "fim de arquivo prematuro lendo trecho (%d bytes obtidos, %d esperados)"
+
+msgid "empty username"
+msgstr "nome de usuário vazio"
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr "nome de usuário %s contém uma quebra de linha"
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr "opções --message e --logfile são mutuamente exclusivas"
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr "não é possível ler mensagem de consolidação '%s': %s"
+
+msgid "limit must be a positive integer"
+msgstr "o limite deve ser um inteiro positivo"
+
+msgid "limit must be positive"
+msgstr "o limite deve ser positivo"
+
+msgid "too many revisions specified"
+msgstr "especificadas revisões demais"
+
+#, python-format
+msgid "invalid format spec '%%%s' in output filename"
+msgstr "especificador inválido de formato '%%%s' no nome de arquivo de saída"
+
+#, python-format
+msgid "adding %s\n"
+msgstr "adicionando %s\n"
+
+#, python-format
+msgid "removing %s\n"
+msgstr "removendo %s\n"
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr "gravando remoção de %s como renomeação para %s (%d%% de similaridade)\n"
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr "%s: não copiado - o arquivo não é gerenciado\n"
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr "%s: não copiado - o arquivo foi marcado para remoção\n"
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr "%s: não sobrescrito - %s colide com %s\n"
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr "%s: não sobrescrito - arquivo existe\n"
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr "%s: apagado na cópia de trabalho\n"
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr "%s: impossível copiar - %s\n"
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr "movendo %s para %s\n"
+
+#, python-format
+msgid "copying %s to %s\n"
+msgstr "copiando %s para %s\n"
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+"%s ainda não foi consolidado, então dados de cópia não serão guardados para %"
+"s.\n"
+
+msgid "no source or destination specified"
+msgstr "nenhuma origem ou destino especificado"
+
+msgid "no destination specified"
+msgstr "nenhum destino especificado"
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr "com várias origens o destino deve ser um diretório existente"
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr "o destino %s não é um diretório"
+
+msgid "no files to copy"
+msgstr "nenhum arquivo para copiar"
+
+msgid "(consider using --after)\n"
+msgstr "(considere usar --after)\n"
+
+#, python-format
+msgid "changeset: %d:%s\n"
+msgstr "changeset: %d:%s\n"
+
+#, python-format
+msgid "branch: %s\n"
+msgstr "ramo: %s\n"
+
+#, python-format
+msgid "tag: %s\n"
+msgstr "etiqueta: %s\n"
+
+#, python-format
+msgid "parent: %d:%s\n"
+msgstr "pai: %d:%s\n"
+
+#, python-format
+msgid "manifest: %d:%s\n"
+msgstr "manifesto: %d:%s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "usuário: %s\n"
+
+#, python-format
+msgid "date: %s\n"
+msgstr "data: %s\n"
+
+msgid "files+:"
+msgstr "arquivos+:"
+
+msgid "files-:"
+msgstr "arquivos-:"
+
+msgid "files:"
+msgstr "arquivos:"
+
+#, python-format
+msgid "files: %s\n"
+msgstr "arquivos: %s\n"
+
+#, python-format
+msgid "copies: %s\n"
+msgstr "cópias: %s\n"
+
+#, python-format
+msgid "extra: %s=%s\n"
+msgstr "extra: %s=%s\n"
+
+msgid "description:\n"
+msgstr "descrição:\n"
+
+#, python-format
+msgid "summary: %s\n"
+msgstr "sumário: %s\n"
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr "%s: nenhuma chave nomeada '%s'"
+
+#, python-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr "Encontrada revisão %s de %s\n"
+
+msgid "revision matching date not found"
+msgstr "revisão com data equivalente não encontrada"
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr "não é possível seguir arquivo inexistente: \"%s\""
+
+#, python-format
+msgid "%s:%s copy source revision cannot be found!\n"
+msgstr "%s:%s revisão fonte da cópia não pode ser encontrada!\n"
+
+msgid "can only follow copies/renames for explicit filenames"
+msgstr ""
+"é possível acompanhar cópias/renomeações apenas para nomes de arquivo "
+"explícitos"
+
+msgid "HG: Enter commit message. Lines beginning with 'HG:' are removed."
+msgstr ""
+"HG: Edite a mensagem de consolidação.\n"
+"HG: Linhas começadas por 'HG:' serão removidas."
+
+msgid "HG: Leave message empty to abort commit."
+msgstr "HG: Deixe a mensagem vazia para abortar a consolidação."
+
+#, python-format
+msgid "HG: user: %s"
+msgstr "HG: usuário: %s"
+
+msgid "HG: branch merge"
+msgstr "HG: mesclagem de ramos"
+
+#, python-format
+msgid "HG: branch '%s'"
+msgstr "HG: ramo '%s'"
+
+#, python-format
+msgid "HG: subrepo %s"
+msgstr "HG: subrepo %s"
+
+#, python-format
+msgid "HG: added %s"
+msgstr "HG: adicionou %s"
+
+#, python-format
+msgid "HG: changed %s"
+msgstr "HG: modificou %s"
+
+#, python-format
+msgid "HG: removed %s"
+msgstr "HG: removeu %s"
+
+msgid "HG: no files changed"
+msgstr "HG: nenhum arquivo mudou"
+
+msgid "empty commit message"
+msgstr "mensagem de consolidação vazia"
+
+msgid ""
+"add the specified files on the next commit\n"
+"\n"
+" Schedule files to be version controlled and added to the\n"
+" repository.\n"
+"\n"
+" The files will be added to the repository at the next commit. To\n"
+" undo an add before that, see hg forget.\n"
+"\n"
+" If no names are given, add all files to the repository.\n"
+" "
+msgstr ""
+"adiciona os arquivos especificados na próxima consolidação\n"
+"\n"
+" Agenda arquivos para serem adicionados ao controle de versão\n"
+" e ao repositório.\n"
+"\n"
+" Os arquivos serão adicionados ao repositório na próxima\n"
+" consolidação. Para desfazer uma adição antes disso, veja\n"
+" hg forget.\n"
+"\n"
+" Se nomes não forem dados, adiciona todos os arquivos ao\n"
+" repositório.\n"
+" "
+
+msgid ""
+"add all new files, delete all missing files\n"
+"\n"
+" Add all new files and remove all missing files from the\n"
+" repository.\n"
+"\n"
+" New files are ignored if they match any of the patterns in\n"
+" .hgignore. As with add, these changes take effect at the next\n"
+" commit.\n"
+"\n"
+" Use the -s/--similarity option to detect renamed files. With a\n"
+" parameter > 0, this compares every removed file with every added\n"
+" file and records those similar enough as renames. This option\n"
+" takes a percentage between 0 (disabled) and 100 (files must be\n"
+" identical) as its parameter. Detecting renamed files this way can\n"
+" be expensive.\n"
+" "
+msgstr ""
+"adiciona arquivos novos e remove arquivos faltando\n"
+"\n"
+" Adiciona ao repositório todos os arquivos novos, e remove do\n"
+" repositório todos os arquivos ausentes.\n"
+"\n"
+" Novos arquivos são ignorados se casarem com qualquer dos padrões\n"
+" em .hgignore. Assim como em add, estas mudanças fazem efeito na\n"
+" próxima consolidação.\n"
+"\n"
+" Use a opção -s/--similarity para detectar arquivos renomeados.\n"
+" Com um parâmetro > 0, compara cada arquivo removido com cada\n"
+" arquivo adicionado e grava como renomeações aqueles semelhantes o\n"
+" bastante. Esta opção usa uma porcentagem entre 0 (desabilitada)\n"
+" e 100 (arquivos devem ser idênticos) como parâmetro. Detectar\n"
+" desta maneira arquivos renomeados pode ser uma operação cara.\n"
+" "
+
+msgid "similarity must be a number"
+msgstr "similaridade deve ser um número"
+
+msgid "similarity must be between 0 and 100"
+msgstr "similaridade deve ser um número entre 0 e 100"
+
+msgid ""
+"show changeset information by line for each file\n"
+"\n"
+" List changes in files, showing the revision id responsible for\n"
+" each line\n"
+"\n"
+" This command is useful for discovering when a change was made and\n"
+" by whom.\n"
+"\n"
+" Without the -a/--text option, annotate will avoid processing files\n"
+" it detects as binary. With -a, annotate will annotate the file\n"
+" anyway, although the results will probably be neither useful\n"
+" nor desirable.\n"
+" "
+msgstr ""
+"mostra informação de changeset por linha para cada arquivo\n"
+"\n"
+" Lista as mudanças em arquivos, mostrando o identificador de\n"
+" revisão responsável por cada linha\n"
+"\n"
+" Este comando é útil para descobrir quando uma mudança foi feita\n"
+" e por quem.\n"
+"\n"
+" Sem a opção -a/--text, annotate evitará processar arquivos\n"
+" detectados como binários. Com -a, annotate irá executar de\n"
+" qualquer maneira, embora os resultados provavelmente não serão\n"
+" úteis.\n"
+" "
+
+msgid "at least one filename or pattern is required"
+msgstr "exigido ao menos um nome de arquivo ou padrão"
+
+msgid "at least one of -n/-c is required for -l"
+msgstr "ao menos uma das opções -n/-c é exigida para -l"
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr "%s: arquivo binário\n"
+
+msgid ""
+"create an unversioned archive of a repository revision\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use -r/--rev to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use -t/--type. Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see 'hg help export' for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use -p/--prefix to specify a format string for the\n"
+" prefix. The default is the basename of the archive, with suffixes\n"
+" removed.\n"
+" "
+msgstr ""
+"cria um pacote não versionado contendo uma revisão do repositório\n"
+"\n"
+" Por padrão, a revisão usada é o pai do diretório de trabalho; use\n"
+" -r/--rev para especificar uma outra revisão.\n"
+"\n"
+" Para especificar o tipo de pacote a ser criado, use -t/--type.\n"
+" Tipos válidos são:\n"
+"\n"
+" \"files\" (padrão): um diretório cheio de arquivos\n"
+" \"tar\": pacote tar, não comprimido\n"
+" \"tbz2\": pacote tar, comprimido com bzip2\n"
+" \"tgz\": pacote tar, comprimido com gzip\n"
+" \"uzip\": pacote zip, não comprimido\n"
+" \"zip\": pacote zip, comprimido com deflate\n"
+"\n"
+" O nome exato do pacote de destino ou diretório é dado por uma\n"
+" string de formatação; veja 'hg help export' para detalhes.\n"
+"\n"
+" Cada membro adicionado ao pacote tem um diretório de prefixo\n"
+" adicionado. Use -p/--prefix para especificar uma string de\n"
+" formatação para o prefixo. O padrão é o nome base do pacote,\n"
+" com sufixos removidos.\n"
+" "
+
+msgid "no working directory: please specify a revision"
+msgstr "sem cópia de trabalho: por favor especifique uma revisão"
+
+msgid "repository root cannot be destination"
+msgstr "o raiz do repositório não pode ser o destino"
+
+msgid "cannot archive plain files to stdout"
+msgstr "não se pode empacotar arquivos simples na saída padrão"
+
+msgid ""
+"reverse effect of earlier changeset\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you backout a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head.\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by hand.\n"
+" The result of this merge is not committed, as with a normal merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"anula o efeito de um changeset anterior\n"
+"\n"
+" Consolida a anulação das mudanças como um novo changeset. O novo\n"
+" changeset é um filho do changeset anulado.\n"
+"\n"
+" Se você anular um changeset diferente da tip, uma nova cabeça é\n"
+" criada. Esta cabeça será a nova tip e você deve mesclar esse\n"
+" changeset de anulação com outra cabeça.\n"
+"\n"
+" A opção --merge lembra do pai do diretório de trabalho antes do\n"
+" início da anulação, e mescla a nova cabeça com esse changeset\n"
+" logo em seguida. Isso poupa o trabalho de fazer uma mesclagem\n"
+" manual. O resultado da mesclagem não é gravado, assim como em uma\n"
+" mesclagem normal.\n"
+"\n"
+" Veja 'hg help dates' para uma lista de formatos válidos para\n"
+" -d/--date.\n"
+" "
+
+msgid "please specify just one revision"
+msgstr "por favor especifique apenas uma revisão"
+
+msgid "please specify a revision to backout"
+msgstr "por favor especifique uma revisão a ser anulada"
+
+msgid "cannot backout change on a different branch"
+msgstr "não se pode anular uma mudança em um ramo diferente"
+
+msgid "cannot backout a change with no parents"
+msgstr "não se pode anular uma mudança sem pais"
+
+msgid "cannot backout a merge changeset without --parent"
+msgstr "não se pode anular um changeset de mesclagem sem --parent"
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr "%s não é um pai de %s"
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr "não se pode usar --parent num changeset que não seja uma mesclagem"
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr "o changeset %s anula o changeset %s\n"
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr "mesclando com changeset %s\n"
+
+msgid "the backout changeset is a new head - do not forget to merge\n"
+msgstr "o changeset de anulação é uma nova cabeça - não esqueça de mesclar\n"
+
+msgid "(use \"backout --merge\" if you want to auto-merge)\n"
+msgstr "(use \"backout --merge\" se você quiser mesclar automaticamente)\n"
+
+msgid ""
+"subdivision search of changesets\n"
+"\n"
+" This command helps to find changesets which introduce problems. To\n"
+" use, mark the earliest changeset you know exhibits the problem as\n"
+" bad, then mark the latest changeset which is free from the problem\n"
+" as good. Bisect will update your working directory to a revision\n"
+" for testing (unless the -U/--noupdate option is specified). Once\n"
+" you have performed tests, mark the working directory as good or\n"
+" bad, and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command, it will be used for automatic bisection.\n"
+" Its exit status will be used to mark revisions as good or bad:\n"
+" status 0 means good, 125 means to skip the revision, 127\n"
+" (command not found) will abort the bisection, and any other\n"
+" non-zero exit status means the revision is bad.\n"
+" "
+msgstr ""
+"busca changesets por subdivisão\n"
+"\n"
+" Este comando ajuda a encontrar changesets que introduziram\n"
+" problemas. Para usá-lo, marque como ruim o changeset mais antigo\n"
+" que apresentar o problema, e como bom o mais recente que não\n"
+" apresentar o problema. O comando bisect irá atualizar seu\n"
+" diretório de trabalho para uma revisão a ser testada (a não ser\n"
+" que a opção -U/--noupdate seja especificada). Uma vez que você\n"
+" tenha realizado os testes, marque o diretório de trabalho como\n"
+" ruim ou bom e bisect irá ou atualizar para outro changeset\n"
+" candidato ou informar que encontrou a revisão ruim.\n"
+"\n"
+" Como um atalho, você pode também usar o parâmetro de revisão para\n"
+" marcar uma revisão como boa ou ruim sem obtê-la primeiro.\n"
+"\n"
+" Se você fornecer um comando ele será usado para bissecção\n"
+" automática. Seu código de saída será usado para marcar revisões\n"
+" como boas ou ruins: o código de saída 0 marcará a revisão como\n"
+" boa, 125 omitirá a revisão, 127 (comando não encontrado)\n"
+" abortará a bissecção, e qualquer outro código maior que 0\n"
+" marcará a revisão como ruim.\n"
+" "
+
+msgid "The first good revision is:\n"
+msgstr "A primeira revisão boa é:\n"
+
+msgid "The first bad revision is:\n"
+msgstr "A primeira revisão ruim é:\n"
+
+msgid "Due to skipped revisions, the first good revision could be any of:\n"
+msgstr ""
+"Devido a revisões omitidas, a primeira revisão boa pode ser qualquer uma "
+"entre:\n"
+
+msgid "Due to skipped revisions, the first bad revision could be any of:\n"
+msgstr ""
+"Devido a revisões omitidas, a primeira revisão ruim pode ser qualquer uma "
+"entre:\n"
+
+msgid "cannot bisect (no known good revisions)"
+msgstr "não é possível fazer o bisect (nenhuma revisão boa conhecida)"
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr "não é possível fazer o bisect (nenhuma revisão ruim conhecida)"
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr "(uso 'hg bisect <cmd>' é obsoleto)\n"
+
+msgid "incompatible arguments"
+msgstr "argumentos incompatíveis"
+
+#, python-format
+msgid "cannot find executable: %s"
+msgstr "não foi possível encontrar executável: %s"
+
+#, python-format
+msgid "failed to execute %s"
+msgstr "falhou ao executar %s"
+
+#, python-format
+msgid "%s killed"
+msgstr "%s morto"
+
+#, python-format
+msgid "Changeset %d:%s: %s\n"
+msgstr "Changeset %d:%s: %s\n"
+
+#, python-format
+msgid "Testing changeset %s:%s (%s changesets remaining, ~%s tests)\n"
+msgstr "Testando o changeset %s:%s (%s changesets restando, ~%s testes)\n"
+
+msgid ""
+"set or show the current branch name\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch will not exist\n"
+" in the repository until the next commit). Standard practice\n"
+" recommends that primary development take place on the 'default'\n"
+" branch.\n"
+"\n"
+" Unless -f/--force is specified, branch will not let you set a\n"
+" branch name that already exists, even if it's inactive.\n"
+"\n"
+" Use -C/--clean to reset the working directory branch to that of\n"
+" the parent of the working directory, negating a previous branch\n"
+" change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch. Use\n"
+" 'hg commit --close-branch' to mark this branch as closed.\n"
+" "
+msgstr ""
+"define ou mostra o nome de ramo atual\n"
+"\n"
+" Sem argumentos, mostra o nome de ramo atual. Com um argumento,\n"
+" define o nome de ramo do diretório de trabalho (o ramo não\n"
+" existirá no repositório até a próxima consolidação). Recomenda-se\n"
+" usar o ramo 'default' como ramo primário de desenvolvimento.\n"
+"\n"
+" A não ser que -f/--force seja especificado, o comando branch não\n"
+" deixará você definir um nome de ramo que já existe, mesmo que\n"
+" tal ramo esteja inativo.\n"
+"\n"
+" Use -C/--clean para redefinir o ramo do diretório de trabalho\n"
+" para o ramo do pai do diretório de trabalho, desfazendo uma\n"
+" mudança de ramo anterior.\n"
+"\n"
+" Use o comando 'hg update' para alternar para um ramo existente.\n"
+" Use 'hg commit --close-branch' para marcar este ramo como\n"
+" fechado.\n"
+" "
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr "redefine o diretório de trabalho para o ramo %s\n"
+
+msgid "a branch of the same name already exists (use --force to override)"
+msgstr "um ramo de mesmo nome já existe (use --force para forçar)"
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr "diretório de trabalho marcado como ramo %s\n"
+
+msgid ""
+"list repository named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If -c/--closed is specified, also list branches which have\n"
+" been marked closed (see hg commit --close-branch).\n"
+"\n"
+" If -a/--active is specified, only show active branches. A branch\n"
+" is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+"lista os ramos nomeados do repositório\n"
+"\n"
+" Lista os ramos nomeados do repositório, indicando quais são\n"
+" inativos. Se -c/--closed for especificado, exibe também ramos\n"
+" marcados como fechados (veja hg commit --close-branch).\n"
+"\n"
+" Se -a/--active for especificado, mostra apenas ramos ativos. Um\n"
+" ramo é considerado ativo se contém cabeças de repositório.\n"
+"\n"
+" Use o comando 'hg update' para trocar para um ramo existente.\n"
+" "
+
+msgid ""
+"create a changegroup file\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" -a/--all (or --base null).\n"
+"\n"
+" You can change compression method with the -t/--type option.\n"
+" The available compression methods are: none, bzip2, and\n"
+" gzip (by default, bundles are compressed using bzip2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means\n"
+" and applied to another repository with the unbundle or pull\n"
+" command. This is useful when direct push and pull are not\n"
+" available or when exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+msgstr ""
+"cria um arquivo de changegroup (coleção de changesets)\n"
+"\n"
+" Gera um arquivo de changegroup contendo changesets não\n"
+" encontrados no outro repositório.\n"
+"\n"
+" Se um repositório de destino não for especificado, assume que o\n"
+" destino tem todos os nós especificados por um ou mais parâmetros\n"
+" --base. Para criar um bundle contendo todos os changesets, use\n"
+" -a/--all (ou --base null).\n"
+"\n"
+" Você pode mudar o método de compressão aplicado com a opção\n"
+" -t/--type. Os métodos de compressão disponíveis são: none\n"
+" (nenhum), bzip2 e gzip (por padrão, bundles são comprimidos\n"
+" usando bzip2).\n"
+"\n"
+" O arquivo bundle pode então ser transferido usando métodos\n"
+" convencionais e aplicado a outro repositório com os comandos\n"
+" unbundle ou pull. Isto pode ser útil caso o acesso direto para\n"
+" push e pull não estiver disponível ou se exportar um repositório\n"
+" completo não for desejável.\n"
+"\n"
+" A aplicação de um bundle preserva todo o conteúdo dos changesets,\n"
+" incluindo permissões, informação de cópia/renomeação, e histórico\n"
+" de revisões.\n"
+" "
+
+msgid "--base is incompatible with specifying a destination"
+msgstr "--base é incompatível com uma especificação de destino"
+
+msgid "unknown bundle type specified with --type"
+msgstr "tipo de bundle especificado por --type desconhecido"
+
+msgid ""
+"output the current or given revision of files\n"
+"\n"
+" Print the specified files as they were at the given revision. If\n"
+" no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repository root\n"
+" %p root-relative path name of file being printed\n"
+" "
+msgstr ""
+"mostra o conteúdo de um arquivo na revisão atual ou pedida\n"
+"\n"
+" Imprime o conteúdo dos arquivos especificados na revisão pedida.\n"
+" Se a revisão não for dada, o pai do diretório de trabalho é usado,\n"
+" ou a tip se nenhuma revisão estiver obtida.\n"
+"\n"
+" A saída pode ser para um arquivo, e nesse caso o nome do arquivo é\n"
+" dado através de uma string de formatação.As regras de formatação\n"
+" são as mesmas que as do comando export, com as seguintes adições:\n"
+"\n"
+" %s nome base do arquivo impresso\n"
+" %d diretório do arquivo impresso, ou '.' se no raiz do\n"
+" repositório\n"
+" %p caminho do arquivo impresso relativo à raiz\n"
+" "
+
+msgid ""
+"make a copy of an existing repository\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" If you use the -r/--rev option to clone up to a specific revision,\n"
+" no subsequent revisions (including subsequent tags) will be\n"
+" present in the cloned repository. This option implies --pull, even\n"
+" on local repositories.\n"
+"\n"
+" By default, clone will check out the head of the 'default' branch.\n"
+" If the -U/--noupdate option is used, the new clone will contain\n"
+" only a repository (.hg) and no working copy (the working copy\n"
+" parent is the null revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Please see 'hg help urls' for important details about ssh:// URLs.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" "
+msgstr ""
+"cria uma cópia de um repositório existente\n"
+"\n"
+" Cria uma cópia de um repositório existente em um novo diretório.\n"
+"\n"
+" Se um diretório de destino não for especificado, será usado o\n"
+" nome base da origem.\n"
+"\n"
+" A localização da origem é adicionada ao arquivo .hg/hgrc do novo\n"
+" repositório, como o padrão a ser usado para futuros comandos\n"
+" pull.\n"
+"\n"
+" Se você usar a opção -r/--rev para clonar até uma revisão\n"
+" específica, nenhuma revisão subseqüente (nem mesmo tags\n"
+" subseqüentes) estará presente no repositório clonado. Essa\n"
+" opção implica --pull, mesmo em repositórios locais.\n"
+"\n"
+" Por padrão, o comando clone irá posicionar a cópia de trabalho na\n"
+" cabeça do ramo 'default'. Se a opção -U/--noupdate for usada, o\n"
+" novo clone irá conter apenas um repositório (diretório .hg) e\n"
+" nenhuma cópia de trabalho (o pai da cópia de trabalho será a\n"
+" revisão null).\n"
+"\n"
+" Veja 'hg help urls' para formatos válidos da origem.\n"
+"\n"
+" É possível especificar uma URL ssh:// como destino, mas o\n"
+" .hg/hgrc e a cópia de trabalho não serão criados do lado remoto.\n"
+" Por favor veja 'hg help URLs' para detalhes importantes sobre\n"
+" URLs ssh:// .\n"
+"\n"
+" Por eficiência, hardlinks são usados para a clonagem sempre que a\n"
+" origem e o destino estiverem no mesmo sistema de arquivos (note\n"
+" que isso se aplica apenas aos dados do repositório, e não aos\n"
+" arquivos da cópia de trabalho). Alguns sistemas de arquivo, como\n"
+" o AFS, implementam hardlinks incorretamente, mas não informam\n"
+" erros. Nesses casos, use a opção --pull para evitar o uso de\n"
+" hardlinks.\n"
+"\n"
+" Em alguns casos, você pode clonar repositórios e arquivos da\n"
+" cópia de trabalho usando hardlinks completos com\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" Este é o jeito mais rápido de clonar, mas não é sempre seguro. A\n"
+" operação não é atômica (garantir que REPO não seja modificado\n"
+" durante a operação é sua responsabilidade) e você deve ter\n"
+" certeza que seu editor quebre hardlinks (o Emacs e muitos\n"
+" utilitários do kernel Linux fazem isso). Além disso, esse modo de\n"
+" criar um clone não é compatível com certas extensões que colocam\n"
+" seus metadados sob o diretório hg, como a mq.\n"
+"\n"
+" "
+
+msgid ""
+"commit the specified files or all outstanding changes\n"
+"\n"
+" Commit changes to the given files into the repository. Unlike a\n"
+" centralized RCS, this operation is a local operation. See hg push\n"
+" for a way to actively distribute your changes.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" filenames or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is\n"
+" started to prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"consolida os arquivos pedidos ou todas as mudanças por gravar\n"
+"\n"
+" Consolida no repositório local mudanças nos arquivos dados. Ao\n"
+" contrário do que ocorre um sistema de controle de versão\n"
+" centralizado, esta operação é local. Veja hg push para um modo\n"
+" de distribuir ativamente suas mudanças.\n"
+"\n"
+" Se não for passada uma lista de arquivos, todas as mudanças\n"
+" informadas por \"hg status\" serão gravadas.\n"
+"\n"
+" Se você estiver consolidando o resultado de uma mesclagem, não\n"
+" forneça nenhum nome de arquivo ou filtros -I/-X .\n"
+"\n"
+" Se uma mensagem de consolidação não for especificada, o editor\n"
+" configurado será iniciado para editar uma mensagem.\n"
+"\n"
+" Veja 'hg help dates' para uma lista de formatos válidos para\n"
+" -d/--date.\n"
+" "
+
+msgid "nothing changed\n"
+msgstr "nada mudou\n"
+
+msgid "created new head\n"
+msgstr "nova cabeça criada\n"
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr "consolidado o changeset %d:%s\n"
+
+msgid ""
+"mark files as copied for the next commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+"marca arquivos como copiados para a próxima consolidação\n"
+"\n"
+" Marca dest como tendo cópias de arquivos de origem. Se dest for\n"
+" um diretório, cópias são colocadas nesse diretório. Se dest for\n"
+" um arquivo, só pode haver uma origem.\n"
+"\n"
+" Por padrão, este comando copia os conteúdos de arquivos como\n"
+" estão no diretório de trabalho. Se chamado com a opção\n"
+" -A/--after, a operação é gravada, mas nenhuma cópia é feita.\n"
+"\n"
+" Este comando faz efeito na próxima consolidação. para desfazer\n"
+" uma cópia antes disso, veja hg revert.\n"
+" "
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr "encontra a revisão ancestral de duas revisões no índice dado"
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr "Não há um repositório do Mercurial aqui (.hg não encontrado)"
+
+msgid "either two or three arguments required"
+msgstr "ou dois ou três argumentos necessários"
+
+msgid "returns the completion list associated with the given command"
+msgstr "devolve a lista de complementos associada ao comando dado"
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr "reconstrói o dirstate como ele pareceria para a revisão dada"
+
+msgid "validate the correctness of the current dirstate"
+msgstr "valida a exatidão do dirstate atual"
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr "%s no estado %s, mas não no manifest1\n"
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr "%s no estado %s, mas também no manifest1\n"
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr "%s no estado %s, mas não em qualquer manifesto\n"
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr "%s no manifest1, mas listado como estado %s"
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr ".hg/dirstate inconsistente com manifesto do pai atual"
+
+msgid ""
+"show combined config settings from all hgrc files\n"
+"\n"
+" With no arguments, print names and values of all config items.\n"
+"\n"
+" With one argument of the form section.name, print just the value\n"
+" of that config item.\n"
+"\n"
+" With multiple arguments, print names and values of all config\n"
+" items with matching section names.\n"
+"\n"
+" With --debug, the source (filename and line number) is printed\n"
+" for each config item.\n"
+" "
+msgstr ""
+"exibe opções de configuração de todos os arquivos hgrc combinados\n"
+"\n"
+" Sem argumentos, imprime nomes e valores de todos os itens de\n"
+" configuração.\n"
+"\n"
+" Com um argumento da forma 'seção.nome', imprime apenas o valor\n"
+" desse item de configuração.\n"
+"\n"
+" Com múltiplos argumentos, imprime nomes e valores de todos os\n"
+" itens de configuração que casarem com os nomes de seção.\n"
+"\n"
+" Com --debug, é mostrada a origem (nome de arquivo e número da\n"
+" linha) para cada item de configuração.\n"
+" "
+
+msgid "only one config item permitted"
+msgstr "apenas um item de configuração permitido"
+
+msgid ""
+"manually set the parents of the current working directory\n"
+"\n"
+" This is useful for writing repository conversion tools, but should\n"
+" be used with care.\n"
+" "
+msgstr ""
+"muda manualmente os pais do diretório de trabalho atual\n"
+"\n"
+" Isto é útil para escrever utilitários de conversão de repositórios, mas\n"
+" deve ser usado com cuidado.\n"
+" "
+
+msgid "show the contents of the current dirstate"
+msgstr "mostra o conteúdo do dirstate atual"
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr "cópia: %s -> %s\n"
+
+msgid "dump the contents of a data file revision"
+msgstr "exibe o conteúdo de uma revisão de dados de arquivo"
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr "identificador de revisão inválido %s"
+
+msgid "parse and display a date"
+msgstr "decodifica e exibe uma data"
+
+msgid "dump the contents of an index file"
+msgstr "extrai o conteúdo de um arquivo de índice"
+
+msgid "dump an index DAG as a graphviz dot file"
+msgstr "extrai os dados de um índice DAG como um arquivo .dot do graphviz"
+
+msgid "test Mercurial installation"
+msgstr "testa a instalação do Mercurial"
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr "Verificando codificação (%s)...\n"
+
+msgid " (check that your locale is properly set)\n"
+msgstr " (verifique se seu locale está configurado propriamente)\n"
+
+msgid "Checking extensions...\n"
+msgstr "Verificando extensões...\n"
+
+msgid " One or more extensions could not be found"
+msgstr " Uma ou mais extensões não puderam ser encontradas"
+
+msgid " (check that you compiled the extensions)\n"
+msgstr " (verifique se você compilou as extensões)\n"
+
+msgid "Checking templates...\n"
+msgstr "Verificando modelos...\n"
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr " (modelos parecem ter sido instalados incorretamente)\n"
+
+msgid "Checking patch...\n"
+msgstr "Verificando patch...\n"
+
+msgid " patch call failed:\n"
+msgstr " chamada de patch falhou:\n"
+
+msgid " unexpected patch output!\n"
+msgstr " saída de patch inesperada!\n"
+
+msgid " patch test failed!\n"
+msgstr " patch de teste falhou!\n"
+
+msgid ""
+" (Current patch tool may be incompatible with patch, or misconfigured. "
+"Please check your .hgrc file)\n"
+msgstr ""
+" (O utilitário de patch atual pode ser incompatível com o patch, ou pode "
+"estar configurado incorretamente. Por favor verifique seu arquivo .hgrc)\n"
+
+msgid ""
+" Internal patcher failure, please report this error to http://mercurial."
+"selenic.com/bts/\n"
+msgstr ""
+" Falha do sistema interno de patches, por favor informe esse erro em http://"
+"mercurial.selenic.com/bts/\n"
+
+msgid "Checking commit editor...\n"
+msgstr "Verificando editor para consolidação...\n"
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr ""
+" Nenhum editor para consolidação configurado, e não foi possível encontrar "
+"'vi' no PATH\n"
+
+msgid " (specify a commit editor in your .hgrc file)\n"
+msgstr " (especifique um editor para consolidação em seu arquivo .hgrc)\n"
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr " Não é possível localizar editor '%s' no PATH\n"
+
+msgid "Checking username...\n"
+msgstr "Verificando nome de usuário...\n"
+
+msgid " (specify a username in your .hgrc file)\n"
+msgstr " (especifique um nome de usuário em seu arquivo .hgrc)\n"
+
+msgid "No problems detected\n"
+msgstr "Nenhum problema detectado\n"
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr "%s problemas detectados, por favor verifique sua instalação!\n"
+
+msgid "dump rename information"
+msgstr "exibe informações de renomeação"
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr "%s renomeado de %s:%s\n"
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr "%s não renomeado\n"
+
+msgid "show how files match on given patterns"
+msgstr "mostra como os arquivos casam com os padrões pedidos"
+
+msgid ""
+"diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a/--text option, diff will avoid generating diffs of\n"
+" files it detects as binary. With -a, diff will generate a diff\n"
+" anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. For more information, read 'hg help diffs'.\n"
+" "
+msgstr ""
+"exibe um diff do repositório (ou arquivos selecionados)\n"
+"\n"
+" Mostra diferenças entre revisões para os arquivos especificados.\n"
+"\n"
+" Diferenças entre arquivos são mostradas usando o formato\n"
+" \"unified diff\".\n"
+"\n"
+" NOTA: diff pode gerar resultados inesperados para mesclagens, já\n"
+" que por padrão irá comparar com o primeiro pai do diretório de\n"
+" trabalho se uma revisão não for especificada.\n"
+"\n"
+" Quando dois argumentos de revisão forem dados, as mudanças entre\n"
+" essas revisões são mostradas. Se apenas uma revisão for\n"
+" especificada, tal revisão será comparada com o diretório de\n"
+" trabalho, e se não for especificada uma revisão, os arquivos do\n"
+" diretório de trabalho serão comparados com seu pai.\n"
+"\n"
+" Sem a opção -a/--text, diff evitará gerar diffs de arquivos que\n"
+" detectar como binários. Com -a, diff irá gerar um diff de\n"
+" qualquer maneira, provavelmente com resultados não desejados.\n"
+"\n"
+" Use a opção -g/--git para gerar diffs no formato estendido\n"
+" \"git diff\". Leia 'hg help diffs' para mais informações.\n"
+" "
+
+msgid ""
+"dump the header and diffs for one or more changesets\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a/--text option, export will avoid generating diffs\n"
+" of files it detects as binary. With -a, export will generate a\n"
+" diff anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. See 'hg help diffs' for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the\n"
+" second parent. It can be useful to review a merge.\n"
+" "
+msgstr ""
+"exibe o cabeçalho e diffs para um ou mais changesets\n"
+"\n"
+" Imprime o cabeçalho de changeset e diffs para uma ou mais\n"
+" revisões.\n"
+"\n"
+" A informação exibida no cabeçalho de changeset é: autor, hash do\n"
+" changeset, pai(s) e comentário de consolidação.\n"
+"\n"
+" NOTA: export pode gerar saída de diff inesperada para changesets\n"
+" de mesclagem, já que irá comparar o changeset de mesclagem apenas\n"
+" com seu primeiro pai.\n"
+"\n"
+" A saída pode ser gerada em um arquivo, e nesse caso o nome do\n"
+" arquivo é dado usando uma string de formato. As regras de\n"
+" formatação são como segue:\n"
+"\n"
+" %% caractere \"%\" literal\n"
+" %H hash do changeset (40 bytes hexadecimais)\n"
+" %N número de patches gerados\n"
+" %R número de revisão do changeset\n"
+" %b nome base do repositório onde o export é realizado\n"
+" %h hash de forma curta do changeset (12 bytes hexadecimais)\n"
+" %n número seqüencial completado com zeros, começando em 1\n"
+" %r número de revisão do changeset completado com zeros\n"
+"\n"
+" Sem a opção -a/--text, export evitará gerar diffs de arquivos\n"
+" detectados como binários. Com -a, export gerará um diff de\n"
+" qualquer maneira, provavelmente com resultados não desejados.\n"
+"\n"
+" Use a opção -g/--git para gerar diffs no formato estendido\n"
+" \"git diff\". Veja 'hg help diffs' para mais informações.\n"
+"\n"
+" Com a opção --switch-parent, o diff será feito em relação ao\n"
+" segundo pai. Isso pode ser útil para avaliar uma mesclagem.\n"
+" "
+
+msgid "export requires at least one changeset"
+msgstr "export exige ao menos um changeset"
+
+msgid "exporting patches:\n"
+msgstr "exportando patches:\n"
+
+msgid "exporting patch:\n"
+msgstr "exportando patch:\n"
+
+msgid ""
+"forget the specified files on the next commit\n"
+"\n"
+" Mark the specified files so they will no longer be tracked\n"
+" after the next commit.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history, and it does not delete them from the\n"
+" working directory.\n"
+"\n"
+" To undo a forget before the next commit, see hg add.\n"
+" "
+msgstr ""
+"esquece os arquivos especificados na próxima consolidação\n"
+"\n"
+" Marca os arquivos especificados de modo que não serão mais\n"
+" rastreados após a próxima consolidação.\n"
+"\n"
+" Isto remove arquivos apenas do ramo atual,e não de todo o\n"
+" histórico do projeto, nem os apaga do diretório de trabalho.\n"
+"\n"
+" Para desfazer um forget antes da próxima consolidação, veja\n"
+" hg add.\n"
+" "
+
+msgid "no files specified"
+msgstr "nenhum arquivo especificado"
+
+#, python-format
+msgid "not removing %s: file is already untracked\n"
+msgstr "%s não removido: arquivo já não é rastreado\n"
+
+msgid ""
+"search for a pattern in specified files and revisions\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which a\n"
+" match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+msgstr ""
+"procura por um padrão nos arquivos e revisões especificados\n"
+"\n"
+" Procura em revisões e arquivos por uma expressão regular.\n"
+"\n"
+" Este comando se comporta de modo diferente do grep do Unix. Ele\n"
+" aceita apenas expressões regulares Python/Perl. Ele procura no\n"
+" histórico do repositório, não no diretório de trabalho. Ele\n"
+" sempre imprime o número da revisão onde um casamento aparece.\n"
+"\n"
+" Por padrão, grep imprime uma saída apenas para a primeira revisão\n"
+" de um arquivo no qual ele encontra um casamento. Para fazê-lo\n"
+" imprimir todas as revisões que contenham uma mudança no casamento\n"
+" (\"-\" para um casamento que se torna um não-casamento, ou \"+\"\n"
+" para um não-casamento que se torna um casamento), use a opção\n"
+" --all .\n"
+" "
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr "grep: padrão de busca inválido: %s\n"
+
+msgid ""
+"show current repository heads or show branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" If one or more REV is given, the \"branch heads\" will be shown for\n"
+" the named branch associated with that revision. The name of the\n"
+" branch is called the revision's branch tag.\n"
+"\n"
+" Branch heads are revisions on a given named branch that do not have\n"
+" any descendants on the same branch. A branch head could be a true head\n"
+" or it could be the last changeset on a branch before a new branch\n"
+" was created. If none of the branch heads are true heads, the branch\n"
+" is considered inactive. If -c/--closed is specified, also show branch\n"
+" heads marked closed (see hg commit --close-branch).\n"
+"\n"
+" If STARTREV is specified only those heads (or branch heads) that\n"
+" are descendants of STARTREV will be displayed.\n"
+" "
+msgstr ""
+"mostra as cabeças atuais do repositório ou cabeças de ramo\n"
+"\n"
+" Sem argumentos, mostra todas as cabeças do repositório.\n"
+"\n"
+" \"Cabeças\" do repositório são changesets que não têm nenhum\n"
+" changeset filho. Elas são onde o desenvolvimento geralmente\n"
+" acontece e são os alvos costumeiros para operações update e\n"
+" merge.\n"
+"\n"
+" Se um ou mais argumentos REV forem dados, as \"cabeças de ramo\"\n"
+" serão mostradas para os ramos nomeados associados a tais\n"
+" revisões. O nome do ramo é chamado de etiqueta de ramo da\n"
+" revisão.\n"
+"\n"
+" Cabeças de ramo são revisões em um determinado ramo nomeado que\n"
+" não têm nenhum descendente nesse mesmo ramo. Uma cabeça de\n"
+" ramo pode ser uma cabeça verdadeira ou pode ser o último\n"
+" changeset em um ramo antes que um novo ramo nomeado fosse criado.\n"
+" Se nenhuma das cabeças de ramo forem cabeças verdadeiras, o ramo\n"
+" é considerado inativo. Se -c/--closed for especificado, mostra\n"
+" também cabeças de ramos marcados como fechados (veja hg commit\n"
+" --close-branch).\n"
+"\n"
+" Se REVINICIAL for especificada, serão mostradas apenas cabeças\n"
+" (ou cabeças de ramo) descendentes de REVINICIAL.\n"
+" "
+
+msgid "you must specify a branch to use --closed"
+msgstr "você deve especificar um ramo para usar --closed"
+
+#, python-format
+msgid "no open branch heads on branch %s\n"
+msgstr "nenhuma cabeça de ramo aberta no ramo %s\n"
+
+#, python-format
+msgid "no changes on branch %s containing %s are reachable from %s\n"
+msgstr "nenhuma mudança no ramo %s contendo %s pode ser alcançada a partir de %s\n"
+
+#, python-format
+msgid "no changes on branch %s are reachable from %s\n"
+msgstr "nenhuma mudança no ramo %s pode ser alcançada a partir de %s\n"
+
+msgid ""
+"show help for a given topic or a help overview\n"
+"\n"
+" With no arguments, print a list of commands with short help messages.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that\n"
+" topic."
+msgstr ""
+"exibe o texto de ajuda geral ou de um tópico pedido\n"
+"\n"
+" Sem argumentos, imprime uma lista de comandos com textos curtos\n"
+" de ajuda.\n"
+"\n"
+" Dado um tópico, extensão, ou nome de comando, imprime o texto de\n"
+" ajuda para esse tópico."
+
+msgid "global options:"
+msgstr "opções globais:"
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr "use \"hg help\" para a lista completa de comandos"
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr "use \"hg help\" para a lista completa de comandos ou \"hg -v\" para detalhes"
+
+#, python-format
+msgid "use \"hg -v help%s\" to show aliases and global options"
+msgstr "use \"hg -v help%s\" para mostrar apelidos de comandos e opções globais"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "use \"hg -v help %s\" para mostrar opções globais"
+
+msgid ""
+"list of commands:\n"
+"\n"
+msgstr ""
+"lista de comandos:\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"apelidos: %s\n"
+
+msgid "(no help text available)"
+msgstr "(texto de ajuda não disponível)"
+
+msgid "options:\n"
+msgstr "opções:\n"
+
+msgid "no commands defined\n"
+msgstr "nenhum comando definido\n"
+
+msgid "enabled extensions:"
+msgstr "extensões habilitadas:"
+
+msgid "no help text available"
+msgstr "texto de ajuda não disponível"
+
+#, python-format
+msgid "%s extension - %s\n"
+msgstr "extensão %s - %s\n"
+
+msgid "Mercurial Distributed SCM\n"
+msgstr "Sistema de controle de versão distribuído Mercurial\n"
+
+msgid ""
+"basic commands:\n"
+"\n"
+msgstr ""
+"comandos básicos:\n"
+"\n"
+
+msgid ""
+"\n"
+"additional help topics:\n"
+"\n"
+msgstr ""
+"\n"
+"tópicos adicionais de ajuda:\n"
+"\n"
+
+msgid ""
+"identify the working copy or specified revision\n"
+"\n"
+" With no revision, print a summary of the current state of the\n"
+" repository.\n"
+"\n"
+" Specifying a path to a repository root or Mercurial bundle will\n"
+" cause lookup to operate on that repository/bundle.\n"
+"\n"
+" This summary identifies the repository state using one or two\n"
+" parent hash identifiers, followed by a \"+\" if there are\n"
+" uncommitted changes in the working directory, a list of tags for\n"
+" this revision and a branch name for non-default branches.\n"
+" "
+msgstr ""
+"identifica a cópia de trabalho ou revisão especificada\n"
+"\n"
+" Sem a revisão, imprime um sumário do estado atual do repositório.\n"
+"\n"
+" Especificar um caminho para a raiz de um repositório ou para um\n"
+" arquivo bundle do Mercurial faz com que a busca opere em tal\n"
+" repositório ou bundle.\n"
+"\n"
+" Este sumário identifica o estado do repositório usando um ou dois\n"
+" identificadores de hash dos pais, seguidos por um \"+\" se houver\n"
+" mudanças não gravadas no diretório de trabalho, uma lista de\n"
+" etiquetas para esta revisão e um nome de ramo para ramos\n"
+" diferentes do default.\n"
+" "
+
+msgid ""
+"import an ordered set of patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f/--force flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (to use the body part, it must have type\n"
+" text/plain or text/x-patch). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and\n"
+" description from patch override values from message headers and\n"
+" body. Values given on command line with -m/--message and -u/--user\n"
+" override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory to\n"
+" the parent of each patch before applying it, and will abort if the\n"
+" resulting changeset has a different ID than the one recorded in\n"
+" the patch. This may happen due to character set problems or other\n"
+" deficiencies in the text patch format.\n"
+"\n"
+" With -s/--similarity, hg will attempt to discover renames and\n"
+" copies in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use \"-\" as the patch name. If\n"
+" a URL is specified, the patch will be downloaded from it.\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"importa um conjunto ordenado de patches\n"
+"\n"
+" Importa uma lista de patches e consolida cada um individualmente.\n"
+"\n"
+" Se houver mudanças não gravadas no diretório de trabalho, import\n"
+" irá abortar, a não ser que a opção -f/--force seja passada.\n"
+"\n"
+" Você pode importar um patch direto de uma mensagem de e-mail. São\n"
+" aceitos até mesmo patches anexados (para poder usar o o corpo da\n"
+" mensagem, ele deve ser do tipo text/plain ou text/x-patch). Os\n"
+" cabeçalhos From e Subject da mensagem são usados como autor e\n"
+" mensagem de consolidação, respectivamente. Todas as partes\n"
+" text/plain antes do primeiro diff são adicionadas à mensagem de\n"
+" consolidação.\n"
+"\n"
+" Se o patch importado foi gerado por hg export, o usuário e\n"
+" descrição do patch são usados ao invés dos cabeçalhos e corpo da\n"
+" mensagem. Valores passados na linha de comando com -m/--message e\n"
+" -u/--user são usados no lugar destes.\n"
+"\n"
+" Se --exact for especificado, import irá posicionar o diretório de\n"
+" trabalho no pai de cada patch antes de aplicá-lo, e irá abortar\n"
+" se o changeset resultante tiver um ID diferente do gravado no\n"
+" patch. Isso pode acontecer por problemas de conjunto de\n"
+" caracteres ou outras deficiências no formato de texto de patch.\n"
+"\n"
+" Com -s/--similarity, hg irá tentar determinar renomeações e\n"
+" cópias no patch do mesmo modo que o comando 'addremove'.\n"
+"\n"
+" Para ler um patch da entrada padrão, use \"-\" como nome do\n"
+" patch. Se uma URL for especificada, o patch será obtido a partir\n"
+" dela. Veja 'hg help dates' para uma lista de formatos válidos\n"
+" para -d/--date.\n"
+" "
+
+msgid "applying patch from stdin\n"
+msgstr "aplicando patch da entrada padrão\n"
+
+msgid "no diffs found"
+msgstr "nenhum diff encontrado"
+
+#, python-format
+msgid ""
+"message:\n"
+"%s\n"
+msgstr ""
+"mensagem:\n"
+"%s\n"
+
+msgid "not a Mercurial patch"
+msgstr "não é um patch do Mercurial"
+
+msgid "patch is damaged or loses information"
+msgstr "o patch está danificado ou perde informação"
+
+msgid ""
+"show new changesets found in source\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would have been pulled\n"
+" if a pull at the time you issued this command.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the\n"
+" changesets twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+msgstr ""
+"mostra novos changesets encontrados na origem\n"
+"\n"
+" Mostra novos changesets encontrados no caminho/URL especificado\n"
+" ou na localização de pull padrão. Estes são os changesets que\n"
+" seriam trazidos se um pull fosse executado.\n"
+"\n"
+" Para repositórios remotos, a opção --bundle evita baixar os\n"
+" changesets duas vezes se o comando incoming for seguido por um\n"
+" pull.\n"
+"\n"
+" Veja pull para detalhes sobre formatos válidos da origem.\n"
+" "
+
+msgid ""
+"create a new repository in the given directory\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it will be created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"cria um novo repositório no diretório pedido\n"
+"\n"
+" Inicializa um novo repositório no diretório dado. Se o diretório\n"
+" não existir, ele será criado.\n"
+"\n"
+" Se o diretório não for dado, o diretório atual será usado.\n"
+"\n"
+" É possível especificar uma URL ssh:// como destino.\n"
+" Veja 'hg help urls' para mais informações.\n"
+" "
+
+msgid ""
+"locate files matching specific patterns\n"
+"\n"
+" Print files under Mercurial control in the working directory whose\n"
+" names match the given patterns.\n"
+"\n"
+" By default, this command searches all directories in the working\n"
+" directory. To search just the current directory and its\n"
+" subdirectories, use \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints the names\n"
+" of all files under Mercurial control in the working directory.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the -0 option to both this command and \"xargs\". This\n"
+" will avoid the problem of \"xargs\" treating single filenames that\n"
+" contain whitespace as multiple filenames.\n"
+" "
+msgstr ""
+"localiza arquivos que casem com os padrões especificados\n"
+"\n"
+" Imprime todos os arquivos sob o controle do Mercurial no\n"
+" diretório de trabalho cujos nomes casem com os padrões\n"
+" fornecidos.\n"
+"\n"
+" Por padrão, este comando procura em todos os diretórios no\n"
+" diretório de trabalho. Para procurar apenas no diretório\n"
+" atual e subdiretórios, use \"--include .\".\n"
+"\n"
+" Se não forem passados padrões, este comando imprime os nomes\n"
+" de todos os arquivos sob o controle do Mercurial no diretório\n"
+" de trabalho.\n"
+"\n"
+" Se você quiser passar a saída desse comando para o comando\n"
+" \"xargs\", use a opção -0 tanto para este comando como para o\n"
+" \"xargs\". Isso irá evitar que \"xargs\" trate nomes de arquivo\n"
+" contendo espaços como múltiplos nomes de arquivo.\n"
+" "
+
+msgid ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a filename to follow history across\n"
+" renames and copies. --follow without a filename will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command prints revision number and changeset id,\n"
+" tags, non-trivial parents, user, date and time, and a summary for\n"
+" each commit. When the -v/--verbose switch is used, the list of\n"
+" changed files and full commit message are shown.\n"
+"\n"
+" NOTE: log -p/--patch may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, only files different from BOTH parents\n"
+" will appear in files:.\n"
+" "
+msgstr ""
+"mostra o histórico de revisões do repositório ou de arquivos\n"
+"\n"
+" Imprime o histórico de revisões dos arquivos especificados ou do\n"
+" projeto como um todo.\n"
+"\n"
+" O histórico de arquivos é mostrado sem que informações de cópia e\n"
+" renomeação sejam seguidas. Use -f/--follow para seguir o\n"
+" histórico através de renomeações e cópias. --follow sem um nome\n"
+" de arquivo irá mostrar apenas ancestrais ou descendentes da\n"
+" revisão de início. --follow-first segue apenas o primeiro pai em\n"
+" revisões de mesclagem.\n"
+"\n"
+" Se um intervalo de revisões não for pedido, o padrão é tip:0 a\n"
+" não ser que --follow seja pedido; nesse caso, o pai do diretório\n"
+" de trabalho é usado como revisão inicial.\n"
+"\n"
+" Veja 'hg help dates' para uma lista de formatos válidos para\n"
+" -d/--date.\n"
+"\n"
+" Por padrão este comando mostra o número e identificador do\n"
+" changeset, etiquetas, pais não triviais, usuário, data e hora,\n"
+" e um resumo de cada consolidação. Se a opção -v/--verbose for\n"
+" usada, são mostradas a lista de arquivos modificados e a\n"
+" mensagem de consolidação completa.\n"
+"\n"
+" NOTA: log -p/--patch pode gerar saídas de diff inesperadas para\n"
+" mesclagens, pois irá comparar o changeset de mesclagem apenas\n"
+" com seu primeiro pai. Além disso, apenas arquivos diferentes de\n"
+" AMBOS os pais aparecerão na lista de arquivos.\n"
+"\n"
+" "
+
+msgid ""
+"output the current or given revision of the project manifest\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the first parent of the working directory\n"
+" is used, or the null revision if no revision is checked out.\n"
+"\n"
+" With -v, print file permissions, symlink and executable bits.\n"
+" With --debug, print file revision hashes.\n"
+" "
+msgstr ""
+"mostra a revisão atual ou pedida do manifesto do projeto\n"
+"\n"
+" Imprime uma lista de arquivos sob controle de versão para a\n"
+" revisão pedida. Se a revisão não for especificada, o primeiro pai\n"
+" do diretório de trabalho será usado, ou a revisão null se nenhuma\n"
+" revisão estiver selecionada.\n"
+"\n"
+" Com a opção -v, imprime permissões de arquivo, links simbólicos\n"
+" e bits de execução. Com a opção --debug, imprime os hashes de\n"
+" revisão de arquivo.\n"
+" "
+
+msgid ""
+"merge working directory with another revision\n"
+"\n"
+" The current working directory is updated with all changes made in\n"
+" the requested revision since the last common predecessor revision.\n"
+"\n"
+" Files that changed between either parent are marked as changed for\n"
+" the next commit and a commit must be performed before any further\n"
+" updates to the repository are allowed. The next commit will have\n"
+" two parents.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other\n"
+" head, the other head is merged with by default. Otherwise, an\n"
+" explicit revision with which to merge with must be provided.\n"
+" "
+msgstr ""
+"mescla o diretório de trabalho com outra revisão\n"
+"\n"
+" O diretório de trabalho é atualizado com todas as mudanças feitas\n"
+" na revisão pedida desde a última revisão predecessora comum.\n"
+"\n"
+" Arquivos que mudarem com relação a qualquer dos pais são\n"
+" marcados como modificados para a próxima consolidação, e esta\n"
+" deve ser feita antes que qualquer outra atualização seja\n"
+" permitida. Essa próxima consolidação terá dois pais.\n"
+"\n"
+" Se a revisão não for especificada, o pai do diretório de trabalho\n"
+" for uma revisão cabeça, e o ramo atual contiver exatamente uma\n"
+" outra cabeça, a outra cabeça será usada para a mesclagem. Caso\n"
+" contrário, uma revisão com a qual mesclar deve ser fornecida\n"
+" explicitamente.\n"
+" "
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr "o ramo '%s' tem %d cabeças - por favor mescle com uma revisão específica"
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr ""
+"o ramo '%s' tem apenas uma cabeça - por favor mescle com uma revisão "
+"específica"
+
+msgid "there is nothing to merge"
+msgstr "não há nada para mesclar"
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr "%s - use \"hg update\""
+
+msgid ""
+"working dir not at a head rev - use \"hg update\" or merge with an explicit "
+"rev"
+msgstr ""
+"diretório de trabalho não está em uma cabeça - use \"hg update\" ou mescle "
+"com uma revisão explícita"
+
+msgid ""
+"show changesets not found in destination\n"
+"\n"
+" Show changesets not found in the specified destination repository\n"
+" or the default push location. These are the changesets that would\n"
+" be pushed if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+msgstr ""
+"mostra changesets não encontrados no destino\n"
+"\n"
+" Mostra changesets não encontrados no repositório de destino\n"
+" especificado ou na localização padrão de push. Estes são os\n"
+" changesets que seriam enviados se um push fosse pedido.\n"
+"\n"
+" Veja pull para detalhes do formato do destino.\n"
+" "
+
+msgid ""
+"show the parents of the working directory or revision\n"
+"\n"
+" Print the working directory's parent revisions. If a revision is\n"
+" given via -r/--rev, the parent of that revision will be printed.\n"
+" If a file argument is given, the revision in which the file was\n"
+" last changed (before the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"mostra os pais do diretório de trabalho ou da revisão\n"
+"\n"
+" Imprime as revisões pai do diretório de trabalho. Se uma revisão\n"
+" for passada com -r/--rev, o pai dessa revisão será impresso. Se\n"
+" um arquivo for passado, será impressa a revisão na qual esse\n"
+" arquivo foi mudado por último (anterior à revisão do diretório de\n"
+" trabalho ou ao argumento --rev, se passado).\n"
+" "
+
+msgid "can only specify an explicit filename"
+msgstr "só é possível especificar um nome de arquivo explícito"
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr "'%s' não encontrado no manifesto!"
+
+msgid ""
+"show aliases for remote repositories\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given,\n"
+" show definition of all available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"mostra apelidos de repositórios remotos\n"
+"\n"
+" Mostra a definição do caminho simbólico NOME. Se nenhum nome for\n"
+" fornecido, mostra todas as definições de nomes disponíveis.\n"
+"\n"
+" Nomes de caminho são definidos na seção [paths] de\n"
+" /etc/mercurial/hgrc e $HOME/.hgrc. Se executado em um\n"
+" repositório, .hg/hgrc também será usado.\n"
+"\n"
+" Veja 'hg help urls' para mais informações.\n"
+" "
+
+msgid "not found!\n"
+msgstr "não encontrado!\n"
+
+msgid "not updating, since new heads added\n"
+msgstr "não foi feita a atualização, já que novas cabeças foram acrescentadas\n"
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr "(execute 'hg heads' para ver cabeças, 'hg merge' para mesclar)\n"
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr "(execute 'hg update' para obter uma cópia de trabalho)\n"
+
+msgid ""
+"pull changes from the specified source\n"
+"\n"
+" Pull changes from a remote repository to a local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to a local repository (the current one unless\n"
+" -R is specified). By default, this does not update the copy of the\n"
+" project in the working directory.\n"
+"\n"
+" Use hg incoming if you want to see what would have been added by a\n"
+" pull at the time you issued this command. If you then decide to\n"
+" added those changes to the repository, you should use pull -r X\n"
+" where X is the last changeset listed by hg incoming.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"traz mudanças da origem especificada\n"
+"\n"
+" Traz mudanças de um repositório remoto para um local.\n"
+"\n"
+" Este comando localiza todas as mudanças do repositório no\n"
+" caminho ou URL especificado e as adiciona a um repositório\n"
+" local (o atual, a não ser que a opção -R seja especificada).\n"
+" Por padrão, ele não atualiza a cópia do projeto no diretório\n"
+" de trabalho.\n"
+"\n"
+" Use hg incoming se você quiser ver o que seria adicionado pelo\n"
+" comando pull. Se você então decidir adicionar tais mudanças ao\n"
+" repositório, você deve usar 'pull -r X', onde X é o último\n"
+" changeset listado por hg incoming.\n"
+"\n"
+" Se ORIGEM for omitida, o caminho 'default' será usado. Veja\n"
+" 'hg help urls' para mais informações.\n"
+" "
+
+msgid ""
+"push changes to the specified destination\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It moves changes from\n"
+" the current repository to a different one. If the destination is\n"
+" local this is identical to a pull in that directory from the\n"
+" current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" user forgot to pull and merge before pushing.\n"
+"\n"
+" If -r/--rev is used, the named revision and all its ancestors will\n"
+" be pushed to the remote repository.\n"
+"\n"
+" Please see 'hg help urls' for important details about ssh://\n"
+" URLs. If DESTINATION is omitted, a default path will be used.\n"
+" "
+msgstr ""
+"envia mudanças para o destino especificado\n"
+"\n"
+" Envia mudanças do repositório local para o destino dado.\n"
+"\n"
+" Esta é a operação simétrica à pull. Ela copia mudanças do\n"
+" repositório atual para um outro. Se o destino for local, esta\n"
+" operação é idêntica a um pull do diretório atual feito no outro\n"
+" repositório.\n"
+"\n"
+" Por padrão, push se recusará a rodar se detectar que o resultado\n"
+" aumentaria o número de cabeças remotas. Isto geralmente indica\n"
+" que o usuário esqueceu de trazer e mesclar as alterações antes de\n"
+" enviá-las.\n"
+"\n"
+" Se -r/--rev for usado, a revisão pedida e todos os seus\n"
+" ancestrais serão enviados para o repositório remoto.\n"
+"\n"
+" Por favor veja 'hg help urls' para detalhes importantes sobre\n"
+" URLs ssh:// . Se DESTINO for omitido, um caminho padrão será\n"
+" usado.\n"
+" "
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr "enviando revisões para %s\n"
+
+msgid ""
+"roll back an interrupted transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an\n"
+" interrupted operation. It should only be necessary when Mercurial\n"
+" suggests it.\n"
+" "
+msgstr ""
+"desfaz uma transação interrompida\n"
+"\n"
+" Recupera uma consolidação ou pull interrompido.\n"
+"\n"
+" Este comando tenta consertar o estado do repositório após uma\n"
+" operação interrompida. Deve ser necessário apenas se o Mercurial\n"
+" sugeri-lo.\n"
+" "
+
+msgid ""
+"remove the specified files on the next commit\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history. -A/--after can be used to remove only\n"
+" files that have already been deleted, -f/--force can be used to\n"
+" force deletion, and -Af can be used to remove files from the next\n"
+" revision without deleting them from the working directory.\n"
+"\n"
+" The following table details the behavior of remove for different\n"
+" file states (columns) and option combinations (rows). The file\n"
+" states are Added [A], Clean [C], Modified [M] and Missing [!]\n"
+" (as reported by hg status). The actions are Warn, Remove (from\n"
+" branch) and Delete (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+msgstr ""
+"remove os arquivos pedidos na próxima consolidação\n"
+"\n"
+" Agenda os arquivos indicados para remoção do repositório.\n"
+"\n"
+" Isto apenas remove arquivos do ramo atual, e não de todo o\n"
+" histórico do projeto. -A/--after pode ser usado para remover\n"
+" apenas arquivos já removidos do diretório de trabalho,\n"
+" -f/--force pode ser usado para forçar a remoção, e -Af pode ser\n"
+" usado para remover os arquivos da próxima revisão sem removê-los\n"
+" do diretório de trabalho.\n"
+"\n"
+" A seguinte tabela detalha o comportamento do comando remove para\n"
+" diferentes estados dos arquivos (colunas) e combinações de opções\n"
+" (linhas). Os estados dos arquivos são: adicionados [A],\n"
+" limpos [C], modificados [M] ou faltando [!] (conforme informado\n"
+" por hg status). As ações são W (aviso), R (remove do ramo) e D\n"
+" (remove do diretório de trabalho).\n"
+"\n"
+" A C M !\n"
+" nada W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" Este comando agenda os arquivos para serem removidos na próxima\n"
+" consolidação. Para desfazer uma remoção antes disso, veja\n"
+" hg revert.\n"
+" "
+
+#, python-format
+msgid "not removing %s: file is untracked\n"
+msgstr "arquivo %s não removido: arquivo não rastreado\n"
+
+#, python-format
+msgid "not removing %s: file %s (use -f to force removal)\n"
+msgstr "arquivo %s não removido: %s (use -f para forçar a remoção)\n"
+
+msgid "still exists"
+msgstr "ainda existe"
+
+msgid "is modified"
+msgstr "alterado"
+
+msgid "has been marked for add"
+msgstr "foi marcado para adição"
+
+msgid ""
+"rename files; equivalent of copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If dest\n"
+" is a directory, copies are put in that directory. If dest is a\n"
+" file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+"renomeia arquivos; equivalente a uma cópia seguida de remoção\n"
+"\n"
+" Marca dest como cópia da origem; marca as origens como removidas.\n"
+" Se dest for um diretório, as cópias serão colocadas nesse\n"
+" diretório. Se dest for um arquivo, só pode haver uma origem.\n"
+"\n"
+" Por padrão, este comando copia o conteúdo dos arquivos do modo\n"
+" como estão no diretório de trabalho. Se chamado com -A/--after, a\n"
+" operação é gravada, mas a cópia não é realizada.\n"
+"\n"
+" Este comando faz efeito na próxima consolidação. Para desfazer\n"
+" uma renomeação antes disso, veja hg revert.\n"
+" "
+
+msgid ""
+"retry file merges from a merge or update\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a/--all switch.\n"
+"\n"
+" If a conflict is resolved manually, please note that the changes\n"
+" will be overwritten if the merge is retried with resolve. The\n"
+" -m/--mark switch should be used to mark the file as resolved.\n"
+"\n"
+" This command also allows listing resolved files and manually\n"
+" indicating whether or not files are resolved. All files must be\n"
+" marked as resolved before a commit is permitted.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+msgstr ""
+"tenta mesclar novamente arquivos em uma mesclagem ou atualização\n"
+"\n"
+" Este comando irá de forma limpa tentar mesclar novamente arquivos\n"
+" não resolvidos usando revisões de arquivo preservadas do último\n"
+" update ou merge. Para tentar resolver todos os arquivos não\n"
+" resolvidos, use a opção -a/--all.\n"
+"\n"
+" Se um conflito foi resolvido manualmente, por favor note que as\n"
+" alterações serão sobrescritas se a mesclagem for repetida usando\n"
+" resolve. A opção -m/--mark deve ser usada para marcar o arquivo\n"
+" como resolvido.\n"
+"\n"
+" Este comando também permite listar arquivos resolvidos e\n"
+" manualmente marcar arquivos como resolvidos ou não. Todos os\n"
+" arquivos devem ser marcados como resolvidos para que a\n"
+" consolidação seja aceita.\n"
+"\n"
+" Os códigos usados para mostrar o estado dos arquivos são:\n"
+" U = não resolvido\n"
+" R = resolvido\n"
+" "
+
+msgid "too many options specified"
+msgstr "opções demais especificadas"
+
+msgid "can't specify --all and patterns"
+msgstr "não é possível especificar --all e padrões"
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr ""
+"nenhum arquivo ou diretório especificado; use --all para refazer a mesclagem "
+"de todos os arquivos"
+
+msgid ""
+"restore individual files or directories to an earlier state\n"
+"\n"
+" (Use update -r to check out earlier revisions, revert does not\n"
+" change the working directory parents.)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r/--rev option, revert the given files or directories\n"
+" to their contents as of a specific revision. This can be helpful\n"
+" to \"roll back\" some or all of an earlier change. See 'hg help\n"
+" dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable mode\n"
+" of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+msgstr ""
+"restaura arquivos ou diretórios para um estado anterior\n"
+"\n"
+" (Use update -r para obter revisões anteriores, revert não altera\n"
+" os pais do diretório de trabalho.)\n"
+"\n"
+" Se não for pedida uma revisão, reverte os arquivos ou diretórios\n"
+" pedidos para o conteúdo que eles possuíam no pai do diretório de\n"
+" trabalho. Isto restaura o conteúdo do arquivos afetados para um\n"
+" estado inalterado e reverte adições, remoções, cópias e\n"
+" renomeações. Se o diretório de trabalho tiver dois pais, você\n"
+" deve especificar explicitamente a revisão para a qual reverter.\n"
+"\n"
+" Com a opção -r/--rev, reverte os arquivos ou diretórios dados\n"
+" para seus conteúdos na revisão pedida. Isso pode ser útil para\n"
+" \"desfazer\" algumas ou todas as mudanças anteriores.\n"
+"\n"
+" Veja 'hg help dates' para uma lista de formatos válidos para\n"
+" -d/--date.\n"
+"\n"
+" O comando revert apenas modifica o diretório de trabalho. Ele não\n"
+" grava nenhuma mudança, nem muda o pai do diretório de trabalho.\n"
+" Se você reverter para uma revisão diferente do pai do diretório\n"
+" de trabalho, os arquivos revertidos irão portanto aparecer como\n"
+" modificados.\n"
+"\n"
+" Se um arquivo tiver sido removido, será restaurado. Se o bit de\n"
+" execução de um arquivo for modificado, ele será restaurado.\n"
+"\n"
+" Se nomes forem fornecidos, todos os arquivos que casarem com\n"
+" esses nomes serão revertidos. Se não forem passados argumentos,\n"
+" nenhum arquivo será revertido.\n"
+"\n"
+" Arquivos modificados são gravados com um sufixo .orig antes da\n"
+" reversão. Para desabilitar essas cópias, use --no-backup.\n"
+" "
+
+msgid "you can't specify a revision and a date"
+msgstr "você não pode especificar uma revisão e uma data"
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr ""
+"nenhum arquivo ou diretório especificado; use --all para reverter o "
+"repositório todo"
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr "esquecendo %s\n"
+
+#, python-format
+msgid "reverting %s\n"
+msgstr "revertendo %s\n"
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr "revertendo remoção de %s\n"
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr "gravando versão atual de %s como %s\n"
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr "arquivo não gerenciado: %s\n"
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr "nenhuma mudança necessária para %s\n"
+
+msgid ""
+"roll back the last transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time. This command does not alter\n"
+" the working directory.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+msgstr ""
+"desfaz a última transação\n"
+"\n"
+" Este comando deve ser usado com cuidado. Há apenas um nível de\n"
+" rollback, e não há maneira de desfazê-lo. Ele irá também restaurar\n"
+" o dirstate ao do momento da última transação, descartando qualquer\n"
+" mudança de dirstate desde aquele momento. Este comando não altera\n"
+" o diretório de trabalho.\n"
+"\n"
+" Transações são usadas para encapsular os efeitos de todos os comandos\n"
+" que criam novos changesets ou propagam changesets existentes para o\n"
+" repositório. Por exemplo, os seguintes comandos são transacionais,\n"
+" e seus efeitos podem ser revertidos com rollback:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (com este repositório como destino)\n"
+" unbundle\n"
+"\n"
+" Este comando não deve ser usado em repositórios públicos. Uma vez que\n"
+" as mudanças sejam visíveis para serem trazidas por outros usuários, um\n"
+" desfazimento local se torna inefetivo (alguém pode já ter feito um pull\n"
+" das mudanças). Além disso, erros de concorrência são possíveis para\n"
+" leitores do repositório: por exemplo, um pull em andamento pode falhar\n"
+" se um rollback for executado.\n"
+" "
+
+msgid ""
+"print the root (top) of the current working directory\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+msgstr ""
+"imprime o raiz (topo) do diretório de trabalho atual\n"
+"\n"
+" Imprime o diretório raiz do repositório atual.\n"
+" "
+
+msgid ""
+"export the repository via HTTP\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+" files.\n"
+" "
+msgstr ""
+"exporta o repositório por HTTP\n"
+"\n"
+" Inicia um visualizador e servidor de pull local via HTTP.\n"
+"\n"
+" Por padrão, o servidor faz logs de acesso para stdout e erros para\n"
+" stderr. Use as opções -A/--accesslog e -E/--errorlog para gravar o\n"
+" log em arquivos.\n"
+" "
+
+#, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr "ouvindo em http://%s%s/%s (associado a %s:%d)\n"
+
+msgid ""
+"show changed files in the working directory\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" the source of a copy/move operation, are not listed unless\n"
+" -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.\n"
+" Unless options described with \"show only ...\" are given, the\n"
+" options -mardu are used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/--ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the differences between them are\n"
+" shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = missing (deleted by non-hg command, but still tracked)\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = origin of the previous file listed as A (added)\n"
+" "
+msgstr ""
+"exibe arquivos alterados no diretório de trabalho\n"
+"\n"
+" Exibe o estado dos arquivos no repositório. Se nomes forem\n"
+" fornecidos, apenas arquivos que casarem serão exibidos. Arquivos\n"
+" sem modificações, ignorados ou origens de uma cópia ou renomeação\n"
+" não são listados, a não ser que -c/--clean (sem modificações),\n"
+" -i/--ignored (ignorados), -C/--copies (cópias) ou -A/-all (todos)\n"
+" sejam passados. A não ser que as opções descritas como \"mostra\n"
+" apenas ...\" sejam passadas, as opções -mardu serão usadas.\n"
+"\n"
+" A opção -q/--quiet esconde arquivos não rastreados (desconhecidos\n"
+" ou ignorados) a não ser que estes sejam pedidos explicitamente\n"
+" com -u/--unknown (desconhecidos) ou -i/--ignored (ignorados).\n"
+"\n"
+" NOTA: o comando status pode aparentemente discordar do comando\n"
+" diff se ocorrer uma mudança de permissões ou uma mesclagem. O\n"
+" formato diff padrão não informa mudanças de permissão e o\n"
+" comando diff informa apenas mudanças relativas a um pai da\n"
+" mesclagem.\n"
+"\n"
+" Se uma revisão for dada, será usada como revisão base. Se duas\n"
+" revisões forem dadas, serão mostradas as diferenças entre elas.\n"
+"\n"
+" Os códigos usados para exibir o estado dos arquivos são:\n"
+" M = modificado\n"
+" A = adicionado\n"
+" R = removido\n"
+" C = limpo (sem modificações)\n"
+" ! = faltando (removido por um outro programa, mas ainda\n"
+" rastreado pelo Mercurial)\n"
+" ? = não rastreado\n"
+" I = ignorado\n"
+" = origem do arquivo anterior listado como A (adicionado)\n"
+" "
+
+msgid ""
+"add one or more tags for the current or given revision\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is\n"
+" used, or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"adiciona uma ou mais etiquetas à revisão atual ou pedida\n"
+"\n"
+" Nomeia uma determinada revisão usando <nome>.\n"
+"\n"
+" 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.\n"
+"\n"
+" Se a revisão não for fornecida, será usada a revisão pai do\n"
+" diretório de trabalho, ou a tip se a cópia de trabalho não\n"
+" estiver em uma revisão.\n"
+"\n"
+" 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"
+" locais (não compartilhadas entre repositórios).\n"
+"\n"
+" Veja 'hg help dates' para uma lista de formatos válidos para\n"
+" -d/--date.\n"
+" "
+
+msgid "tag names must be unique"
+msgstr "nomes de etiqueta devem ser únicos"
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr "o nome '%s' é reservado"
+
+msgid "--rev and --remove are incompatible"
+msgstr "--rev e --remove são incompatíveis"
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr "etiqueta '%s' não existe"
+
+#, python-format
+msgid "tag '%s' is not a global tag"
+msgstr "etiqueta '%s' não é uma etiqueta global"
+
+#, python-format
+msgid "tag '%s' is not a local tag"
+msgstr "etiqueta '%s' não é uma etiqueta local"
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr "etiqueta '%s' já existe (use -f para forçar)"
+
+msgid ""
+"list repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose\n"
+" switch is used, a third column \"local\" is printed for local tags.\n"
+" "
+msgstr ""
+"lista as etiquetas do repositório\n"
+"\n"
+" Lista tanto etiquetas regulares como locais. Se a opção\n"
+" -v/--verbose for usada, uma terceira coluna \"local\" é impressa\n"
+" para etiquetas locais.\n"
+" "
+
+msgid ""
+"show the tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the changeset\n"
+" most recently added to the repository (and therefore the most\n"
+" recently changed head).\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+msgstr ""
+"exibe a revisão mais recente\n"
+"\n"
+" A revisão tip (tipicamente chamada apenas de tip) é a revisão\n"
+" adicionada mais recentemente ao repositório (e portanto a cabeça\n"
+" modificada mais recentemente.\n"
+"\n"
+" Se você acabou de fazer uma consolidação, essa consolidação será\n"
+" a tip. Se você acabou de trazer revisões de outro repositório, a\n"
+" tip desse repositório será a tip do atual. A etiqueta \"tip\" é\n"
+" especial e não pode ser renomeada ou atribuída a outro\n"
+" changeset.\n"
+" "
+
+msgid ""
+"apply one or more changegroup files\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+msgstr ""
+"aplica um ou mais arquivos de changegroup\n"
+"\n"
+" Aplica um ou mais arquivos comprimidos de changegroup gerados pelo\n"
+" comando bundle.\n"
+" "
+
+msgid ""
+"update working directory\n"
+"\n"
+" Update the repository's working directory to the specified\n"
+" revision, or the tip of the current branch if none is specified.\n"
+" Use null as the revision to remove the working copy (like 'hg\n"
+" clone -U').\n"
+"\n"
+" When the working directory contains no uncommitted changes, it\n"
+" will be replaced by the state of the requested revision from the\n"
+" repository. When the requested revision is on a different branch,\n"
+" the working directory will additionally be switched to that\n"
+" branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C/--clean to\n"
+" discard them, forcibly replacing the state of the working\n"
+" directory with the requested revision. Alternately, use -c/--check\n"
+" to abort.\n"
+"\n"
+" When there are uncommitted changes and option -C/--clean is not\n"
+" used, and the parent revision and requested revision are on the\n"
+" same branch, and one of them is an ancestor of the other, then the\n"
+" new working directory will contain the requested revision merged\n"
+" with the uncommitted changes. Otherwise, the update will fail with\n"
+" a suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use\n"
+" revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"atualiza o diretório de trabalho\n"
+"\n"
+" Atualiza o diretório de trabalho do repositório para a revisão\n"
+" pedida, ou a tip do ramo atual se a revisão não for especificada.\n"
+" Use null como revisão para remover a cópia de trabalho (como\n"
+" 'hg clone -U').\n"
+"\n"
+" Se o diretório de trabalho não contiver mudanças não\n"
+" consolidadas, será substituído pelo estado da revisão pedida do\n"
+" repositório. Quando a revisão pedida estiver em um outro ramo, o\n"
+" diretório de trabalho também será mudado para tal ramo.\n"
+"\n"
+" Se houver mudanças não consolidadas, use a opção -C/--clean para\n"
+" descartá-las, forçando a substituição do estado do diretório de\n"
+" trabalho pela revisão pedida. Alternativamente, use -c/--check\n"
+" para abortar.\n"
+"\n"
+" Se houver mudanças não consolidadas, a opção -C/--clean não for\n"
+" usada, a revisão pai e a revisão pedida estiverem no mesmo ramo e\n"
+" uma delas for ancestral da outra, o novo diretório de trabalho\n"
+" irá conter a revisão pedida mesclada às mudanças não consolidadas.\n"
+" Caso contrário, a atualização irá falhar exibindo uma sugestão\n"
+" para usar o comando 'merge' ou 'update -C'.\n"
+"\n"
+" Se você quiser atualizar apenas um arquivo para uma revisão\n"
+" anterior, use o comando 'revert'.\n"
+"\n"
+" Veja 'hg help dates' para uma lista de formatos válidos para\n"
+" -d/--date.\n"
+" "
+
+msgid "uncommitted local changes"
+msgstr "alterações locais pendentes"
+
+msgid ""
+"verify the integrity of the repository\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+msgstr ""
+"verifica a integridade do repositório\n"
+"\n"
+" Verifica a integridade do repositório atual.\n"
+"\n"
+" Isto irá realizar uma verificação ampla da integridade do\n"
+" repositório, validando os hashes e checksums de cada entrada\n"
+" no changelog, manifesto, e arquivos rastreados, bem como a\n"
+" integridade de seus índices e ligações cruzadas.\n"
+" "
+
+msgid "output version and copyright information"
+msgstr "exibe versão e informação de copyright"
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr "Sistema de controle de versão distribuído Mercurial (versão %s)\n"
+
+msgid ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> e outros\n"
+"Este software é livre; veja os fontes para condições de cópia. Não\n"
+"há garantias, nem mesmo de adequação para qualquer propósito em\n"
+"particular.\n"
+
+msgid "repository root directory or symbolic path name"
+msgstr "diretório raiz do repositório ou nome de caminho simbólico"
+
+msgid "change working directory"
+msgstr "muda o diretório de trabalho"
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr "não solicita entrada, assume 'sim' para qualquer resposta necessária"
+
+msgid "suppress output"
+msgstr "suprime saída"
+
+msgid "enable additional output"
+msgstr "habilita saída adicional"
+
+msgid "set/override config option"
+msgstr "define/sobrepõe opção de configuração"
+
+msgid "enable debugging output"
+msgstr "habilita saída de depuração"
+
+msgid "start debugger"
+msgstr "inicia depurador"
+
+msgid "set the charset encoding"
+msgstr "define a codificação de caracteres"
+
+msgid "set the charset encoding mode"
+msgstr "define o modo de codificação de conjunto de caracteres"
+
+msgid "print traceback on exception"
+msgstr "imprime traceback em exceções"
+
+msgid "time how long the command takes"
+msgstr "mede o tempo de execução de cada comando"
+
+msgid "print command execution profile"
+msgstr "exibe profile de execução de comando"
+
+msgid "output version information and exit"
+msgstr "exibe informação de versão e sai"
+
+msgid "display help and exit"
+msgstr "exibe ajuda e sai"
+
+msgid "do not perform actions, just print output"
+msgstr "não realiza ações, apenas imprime a saída"
+
+msgid "specify ssh command to use"
+msgstr "especifica comando ssh a ser usado"
+
+msgid "specify hg command to run on the remote side"
+msgstr "especifica comando hg para executar do lado remoto"
+
+msgid "include names matching the given patterns"
+msgstr "inclui nomes que casem com os padrões fornecidos"
+
+msgid "exclude names matching the given patterns"
+msgstr "exclui nomes que casem com os padrões fornecidos"
+
+msgid "use <text> as commit message"
+msgstr "usa <texto> como mensagem de consolidação"
+
+msgid "read commit message from <file>"
+msgstr "lê a mensagem de consolidação de um arquivo"
+
+msgid "record datecode as commit date"
+msgstr "grava código de data como data de consolidação"
+
+msgid "record the specified user as committer"
+msgstr "grava o usuário pedido como autor da consolidação"
+
+msgid "display using template map file"
+msgstr "exibe usando arquivo de mapeamento de modelo"
+
+msgid "display with template"
+msgstr "exibe usando modelo"
+
+msgid "do not show merges"
+msgstr "não mostra mesclagens"
+
+msgid "treat all files as text"
+msgstr "trata todos os arquivos como texto"
+
+msgid "don't include dates in diff headers"
+msgstr "não inclui datas nos cabeçalhos de diff"
+
+msgid "show which function each change is in"
+msgstr "mostra em qual função está cada mudança"
+
+msgid "ignore white space when comparing lines"
+msgstr "ignora espaços em branco ao comparar linhas"
+
+msgid "ignore changes in the amount of white space"
+msgstr "ignora mudanças na quantidade de espaços em branco"
+
+msgid "ignore changes whose lines are all blank"
+msgstr "ignora mudanças cujas linhas sejam todas brancas"
+
+msgid "number of lines of context to show"
+msgstr "número de linhas de contexto a serem mostradas"
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr "infere arquivos renomeados por similaridade (0<=s<=100)"
+
+msgid "[OPTION]... [FILE]..."
+msgstr "[OPÇÃO]... [ARQUIVO]..."
+
+msgid "annotate the specified revision"
+msgstr "faz um annotate da revisão especificada"
+
+msgid "follow file copies and renames"
+msgstr "segue cópias e renomeações"
+
+msgid "list the author (long with -v)"
+msgstr "lista o autor (formato longo com -v)"
+
+msgid "list the date (short with -q)"
+msgstr "lista a data (formato curto com -q)"
+
+msgid "list the revision number (default)"
+msgstr "lista o número de revisão (padrão)"
+
+msgid "list the changeset"
+msgstr "lista o changeset"
+
+msgid "show line number at the first appearance"
+msgstr "exibe números de linha na primeira ocorrência"
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+
+msgid "do not pass files through decoders"
+msgstr "não passar arquivos por decodificadores"
+
+msgid "directory prefix for files in archive"
+msgstr "prefixo de diretório para arquivos armazenados"
+
+msgid "revision to distribute"
+msgstr "revisão a ser distribuída"
+
+msgid "type of distribution to create"
+msgstr "tipo de distribuição a ser criada"
+
+msgid "[OPTION]... DEST"
+msgstr "[OPÇÃO]... DEST"
+
+msgid "merge with old dirstate parent after backout"
+msgstr "mesclar com pai do dirstate anterior após o backout"
+
+msgid "parent to choose when backing out merge"
+msgstr "pai a ser escolhido ao fazer o backout de mesclagem"
+
+msgid "revision to backout"
+msgstr "revisão para fazer o backout"
+
+msgid "[OPTION]... [-r] REV"
+msgstr "[OPÇÃO]... [-r] REV"
+
+msgid "reset bisect state"
+msgstr "reinicia estado do bisect"
+
+msgid "mark changeset good"
+msgstr "marca changeset bom"
+
+msgid "mark changeset bad"
+msgstr "marca changeset ruim"
+
+msgid "skip testing changeset"
+msgstr "descartando changeset de teste"
+
+msgid "use command to check changeset state"
+msgstr "usa o comando para verificar o estado do changeset"
+
+msgid "do not update to target"
+msgstr "não atualiza para o alvo"
+
+msgid "[-gbsr] [-c CMD] [REV]"
+msgstr "[-gbsr] [-c CMD] [REV]"
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr "especifica nome do ramo mesmo se ocultar um ramo existente"
+
+msgid "reset branch name to parent branch name"
+msgstr "especifica o nome do ramo como o nome do ramo do pai"
+
+msgid "[-fC] [NAME]"
+msgstr "[-fC] [NOME]"
+
+msgid "show only branches that have unmerged heads"
+msgstr "mostra apenas ramos que possuem cabeças não mescladas"
+
+msgid "show normal and closed branches"
+msgstr "mostra ramos normais e fechados"
+
+msgid "[-a]"
+msgstr "[-a]"
+
+msgid "run even when remote repository is unrelated"
+msgstr "execute mesmo se o repositório remoto não for relacionado"
+
+msgid "a changeset up to which you would like to bundle"
+msgstr "um changeset até o qual você gostaria de armazenar no bundle"
+
+msgid "a base changeset to specify instead of a destination"
+msgstr "um changeset base a ser especificado ao invés de um destino"
+
+msgid "bundle all changesets in the repository"
+msgstr "cria um bundle com todos os changesets no repositório"
+
+msgid "bundle compression type to use"
+msgstr "tipo de compressão de bundle a ser usada"
+
+msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr "[-f] [-a] [-r REV]... [--base REV]... ARQUIVO [DEST]"
+
+msgid "print output to file with formatted name"
+msgstr "imprime a saída para o arquivo com o nome formatado"
+
+msgid "print the given revision"
+msgstr "imprime a revisão dada"
+
+msgid "apply any matching decode filter"
+msgstr "aplica qualquer filtro de decodificação que case"
+
+msgid "[OPTION]... FILE..."
+msgstr "[OPÇÃO]... ARQUIVO..."
+
+msgid "the clone will only contain a repository (no working copy)"
+msgstr "o clone irá conter apenas um repositório (sem cópia de trabalho)"
+
+msgid "a changeset you would like to have after cloning"
+msgstr "um changeset que você gostaria de ter após a clonagem"
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr "[OPÇÃO]... ORIGEM [DEST]"
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr ""
+"marca arquivos novos/ausentes como adicionados/removidos antes da "
+"consolidação"
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr "marca um ramo como fechado, escondendo-o da lista de ramos"
+
+msgid "record a copy that has already occurred"
+msgstr "grava uma cópia que já ocorreu"
+
+msgid "forcibly copy over an existing managed file"
+msgstr "força cópia sobre um arquivo não gerenciado existente"
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr "[OPÇÃO]... [ORIGEM]... DEST"
+
+msgid "[INDEX] REV1 REV2"
+msgstr "[ÃNDICE] REV1 REV2"
+
+msgid "[COMMAND]"
+msgstr "[COMANDO]"
+
+msgid "show the command options"
+msgstr "exibe opções dos comandos"
+
+msgid "[-o] CMD"
+msgstr "[-o] CMD"
+
+msgid "try extended date formats"
+msgstr "tenta formatos de data estendidos"
+
+msgid "[-e] DATE [RANGE]"
+msgstr "[-e] DATA [INTERVALO]"
+
+msgid "FILE REV"
+msgstr "ARQUIVO REV"
+
+msgid "[PATH]"
+msgstr "[CAMINHO]"
+
+msgid "FILE"
+msgstr "ARQUIVO"
+
+msgid "revision to rebuild to"
+msgstr "revisão para a qual reconstruir"
+
+msgid "[-r REV] [REV]"
+msgstr "[-r REV] [REV]"
+
+msgid "revision to debug"
+msgstr "revisão a ser depurada"
+
+msgid "[-r REV] FILE"
+msgstr "[-r REV] ARQUIVO"
+
+msgid "REV1 [REV2]"
+msgstr "REV1 [REV2]"
+
+msgid "do not display the saved mtime"
+msgstr "não exibe o mtime armazenado"
+
+msgid "[OPTION]..."
+msgstr "[OPÇÃO]..."
+
+msgid "revision to check"
+msgstr "revisão para verificar"
+
+msgid "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+msgstr "[OPÇÃO]... [-r REV1 [-r REV2]] [ARQUIVO]..."
+
+msgid "diff against the second parent"
+msgstr "faz o diff com o segundo pai"
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr "[OPÇÃO]... [-o PADRÃOARQSAÃDA] REV..."
+
+msgid "end fields with NUL"
+msgstr "termina campos com NUL"
+
+msgid "print all revisions that match"
+msgstr "imprime todas as revisões que casarem"
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr ""
+"acompanha histórico de changeset, ou histórico de arquivo através de cópias "
+"e renomeações"
+
+msgid "ignore case when matching"
+msgstr "ignora maiúsculas/minúsculas ao casar"
+
+msgid "print only filenames and revisions that match"
+msgstr "imprime apenas nomes de arquivo e revisões que casarem"
+
+msgid "print matching line numbers"
+msgstr "imprime número de linhas que casarem"
+
+msgid "search in given revision range"
+msgstr "procura no intervalo de revisões dado"
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr "[OPÇÃO]... PADRÃO [ARQUIVO]..."
+
+msgid "show only heads which are descendants of REV"
+msgstr "mostra apenas cabeças descendentes de REV"
+
+msgid "show only the active branch heads from open branches"
+msgstr "mostra apenas as cabeças de ramo ativas de ramos abertos"
+
+msgid "show normal and closed branch heads"
+msgstr "mostra cabeças de ramo normais e fechadas"
+
+msgid "[-r STARTREV] [REV]..."
+msgstr "[-r REVINICIAL] [REV]..."
+
+msgid "[TOPIC]"
+msgstr "[TÓPICO]"
+
+msgid "identify the specified revision"
+msgstr "identifica a revisão especificada"
+
+msgid "show local revision number"
+msgstr "exibe número local de revisão"
+
+msgid "show global revision id"
+msgstr "exibe identificador global de revisão"
+
+msgid "show branch"
+msgstr "exibe ramo"
+
+msgid "show tags"
+msgstr "exibe etiquetas"
+
+msgid "[-nibt] [-r REV] [SOURCE]"
+msgstr "[-nibt] [-r REV] [ORIGEM]"
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr ""
+"opção de remoção de diretório para o patch. Tem o mesmo significado da opção "
+"correspondente do utilitário patch"
+
+msgid "base path"
+msgstr "caminho base"
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr "não faz verificação de mudanças ainda não consolidadas"
+
+msgid "don't commit, just update the working directory"
+msgstr "não consolida, apenas atualiza o diretório de trabalho"
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr "aplica o patch aos nós a partir dos quais ele foi gerado"
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr "usa qualquer informação de ramo no patch (implicada por --exact)"
+
+msgid "[OPTION]... PATCH..."
+msgstr "[OPÇÃO]... PATCH..."
+
+msgid "show newest record first"
+msgstr "mostra registros mais novos primeiro"
+
+msgid "file to store the bundles into"
+msgstr "arquivo no qual armazenar os bundles"
+
+msgid "a specific revision up to which you would like to pull"
+msgstr "uma revisão específica até a qual você gostaria de trazer"
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr "[-p] [-n] [-M] [-f] [-r REV]... [--bundle ARQUIVO] [ORIGEM]"
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-e CMD] [--remotecmd CMD] [DEST]"
+
+msgid "search the repository as it stood at REV"
+msgstr "procura no repositório como se estivesse em REV"
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr "termina nomes de arquivo com NUL, para uso com xargs"
+
+msgid "print complete paths from the filesystem root"
+msgstr "imprime caminhos completos a partir do raiz do sistema de arquivos"
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr "[OPÇÃO]... [PADRÃO]..."
+
+msgid "only follow the first parent of merge changesets"
+msgstr "acompanha apenas o primeiro pai de changesets de mesclagem"
+
+msgid "show revisions matching date spec"
+msgstr "mostra revisões que casem com a especificação de data"
+
+msgid "show copied files"
+msgstr "mostra arquivos copiados"
+
+msgid "do case-insensitive search for a keyword"
+msgstr "faz uma busca insensível a maiúsculas / minúsculas por uma palavra chave"
+
+msgid "include revisions where files were removed"
+msgstr "inclui revisões nas quais arquivos foram removidos"
+
+msgid "show only merges"
+msgstr "mostra apenas mesclagens"
+
+msgid "revisions committed by user"
+msgstr "revisões de autoria do usuário"
+
+msgid "show only changesets within the given named branch"
+msgstr "mostra apenas changesets dentro do ramo nomeado especificado"
+
+msgid "do not display revision or any of its ancestors"
+msgstr "não exibe revisão ou qualquer de seus ancestrais"
+
+msgid "[OPTION]... [FILE]"
+msgstr "[OPÇÃO]... [ARQUIVO]"
+
+msgid "revision to display"
+msgstr "revisão a ser exibida"
+
+msgid "[-r REV]"
+msgstr "[-r REV]"
+
+msgid "force a merge with outstanding changes"
+msgstr "força uma mesclagem com mudanças ainda não consideradas"
+
+msgid "revision to merge"
+msgstr "revisão a ser mesclada"
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr "avalia revisões a serem mescladas (a mesclagem não é executada)"
+
+msgid "[-f] [[-r] REV]"
+msgstr "[-f] [[-r] REV]"
+
+msgid "a specific revision up to which you would like to push"
+msgstr "uma revisão específica até a qual você gostaria de enviar"
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+
+msgid "show parents from the specified revision"
+msgstr "mostra pais da revisão especificada"
+
+msgid "[-r REV] [FILE]"
+msgstr "[-r REV] [ARQUIVO]"
+
+msgid "[NAME]"
+msgstr "[NOME]"
+
+msgid "update to new tip if changesets were pulled"
+msgstr "atualiza para nova tip se changesets forem trazidos"
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [ORIGEM]"
+
+msgid "force push"
+msgstr "força um push"
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+
+msgid "record delete for missing files"
+msgstr "grava remoção de arquivos faltando"
+
+msgid "remove (and delete) file even if added or modified"
+msgstr "remove (e apaga) o arquivo mesmo se foi adicionado ou modificado"
+
+msgid "record a rename that has already occurred"
+msgstr "grava uma renomeação que já ocorreu"
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr "[OPÇÃO]... ORIGEM... DESTINO"
+
+msgid "remerge all unresolved files"
+msgstr "mescla novamente todos os arquivos não solucionados"
+
+msgid "list state of files needing merge"
+msgstr "lista estado de arquivos que precisam ser mesclados"
+
+msgid "mark files as resolved"
+msgstr "marca arquivos como solucionados"
+
+msgid "unmark files as resolved"
+msgstr "desmarca arquivos como solucionados"
+
+msgid "revert all changes when no arguments given"
+msgstr "se parâmetros não forem fornecidos, reverte todas as mudanças"
+
+msgid "tipmost revision matching date"
+msgstr "revisão mais recente que casa com a data"
+
+msgid "revision to revert to"
+msgstr "revisão para a qual reverter"
+
+msgid "do not save backup copies of files"
+msgstr "não grava backups de arquivos"
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr "[OPÇÃO]... [-r REV] [NOME]..."
+
+msgid "name of access log file to write to"
+msgstr "nome do arquivo de log de acesso a ser escrito"
+
+msgid "name of error log file to write to"
+msgstr "nome do arquivo de log de erros a ser escrito"
+
+msgid "port to listen on (default: 8000)"
+msgstr "porta onde escutar (padrão: 8000)"
+
+msgid "address to listen on (default: all interfaces)"
+msgstr "endereço onde escutar (padrão: todas as interfaces)"
+
+msgid "prefix path to serve from (default: server root)"
+msgstr "caminho de prefixo a ser servido (padrão: raiz do servidor)"
+
+msgid "name to show in web pages (default: working directory)"
+msgstr "nome a ser exibido em páginas web (padrão: diretório de trabalho)"
+
+msgid "name of the webdir config file (serve more than one repository)"
+msgstr ""
+"nome do arquivo de configuração do webdir (para servir mais de um "
+"repositório)"
+
+msgid "for remote clients"
+msgstr "para clientes remotos"
+
+msgid "web templates to use"
+msgstr "modelo web a ser usado"
+
+msgid "template style to use"
+msgstr "estilo de modelo a ser usado"
+
+msgid "use IPv6 in addition to IPv4"
+msgstr "usa IPv6 além de IPv4"
+
+msgid "SSL certificate file"
+msgstr "arquivo de certificado de SSL"
+
+msgid "show untrusted configuration options"
+msgstr "mostra opções de configuração não confiáveis"
+
+msgid "[-u] [NAME]..."
+msgstr "[-u] [NOME]..."
+
+msgid "show status of all files"
+msgstr "mostra status de todos os arquivos"
+
+msgid "show only modified files"
+msgstr "mostra apenas arquivos modificados"
+
+msgid "show only added files"
+msgstr "mostra apenas arquivos adicionados"
+
+msgid "show only removed files"
+msgstr "mostra apenas arquivos removidos"
+
+msgid "show only deleted (but tracked) files"
+msgstr "mostra apenas arquivos removidos (mas rastreados)"
+
+msgid "show only files without changes"
+msgstr "mostra apenas arquivos sem mudanças"
+
+msgid "show only unknown (not tracked) files"
+msgstr "mostra apenas arquivos desconhecidos (não rastreados)"
+
+msgid "show only ignored files"
+msgstr "mostra apenas arquivos ignorados"
+
+msgid "hide status prefix"
+msgstr "esconde prefixo de status"
+
+msgid "show source of copied files"
+msgstr "mostra a origem de arquivos copiados"
+
+msgid "show difference from revision"
+msgstr "mostra diferença a partir da revisão"
+
+msgid "replace existing tag"
+msgstr "substitui etiqueta existente"
+
+msgid "make the tag local"
+msgstr "torna a etiqueta local"
+
+msgid "revision to tag"
+msgstr "revisão a receber a etiqueta"
+
+msgid "remove a tag"
+msgstr "remove uma etiqueta"
+
+msgid "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr "[-l] [-m TEXTO] [-d DATA] [-u USUÃRIO] [-r REV] NOME..."
+
+msgid "[-p]"
+msgstr "[-p]"
+
+msgid "update to new tip if changesets were unbundled"
+msgstr "atualiza para nova tip se changesets forem extraídos do bundle"
+
+msgid "[-u] FILE..."
+msgstr "[-u] ARQUIVO..."
+
+msgid "overwrite locally modified files (no backup)"
+msgstr "sobrescreve arquivos locais modificados (sem backup)"
+
+msgid "check for uncommitted changes"
+msgstr "verifica mudanças ainda não consolidadas"
+
+msgid "[-C] [-d DATE] [[-r] REV]"
+msgstr "[-C] [-d DATA] [[-r] REV]"
+
+#, python-format
+msgid "config error at %s:%d: '%s'"
+msgstr "erro de configuração em %s:%d: '%s'"
+
+msgid "not found in manifest"
+msgstr "não encontrado no manifesto"
+
+msgid "branch name not in UTF-8!"
+msgstr "nome do ramo não está em UTF-8!"
+
+#, python-format
+msgid " searching for copies back to rev %d\n"
+msgstr " procurando por cópias para trás até a revisão %d\n"
+
+#, python-format
+msgid ""
+" unmatched files in local:\n"
+" %s\n"
+msgstr ""
+" arquivo não encontrado localmente:\n"
+" %s\n"
+
+#, python-format
+msgid ""
+" unmatched files in other:\n"
+" %s\n"
+msgstr ""
+" arquivos não encontrados no outro:\n"
+" %s\n"
+
+msgid " all copies found (* = to merge, ! = divergent):\n"
+msgstr " todas as cópias encontradas (* = para mesclar, ! = divergente):\n"
+
+msgid " checking for directory renames\n"
+msgstr " procurando por diretórios renomeados\n"
+
+#, python-format
+msgid " dir %s -> %s\n"
+msgstr " dir %s -> %s\n"
+
+#, python-format
+msgid " file %s -> %s\n"
+msgstr " arquivo %s -> %s\n"
+
+msgid "working directory state appears damaged!"
+msgstr "estado do diretório de trabalho parece danificado!"
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr "'\\n' e '\\r' proibidos em nomes de arquivos: %r"
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr "diretório %r já está em dirstate"
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr "o arquivo %r em dirstate colide com %r"
+
+#, python-format
+msgid "not in dirstate: %s\n"
+msgstr "não em dirstate: %s\n"
+
+msgid "unknown"
+msgstr "desconhecido"
+
+msgid "character device"
+msgstr "dispositivo de caracteres"
+
+msgid "block device"
+msgstr "dispositivo de bloco"
+
+msgid "fifo"
+msgstr "fifo"
+
+msgid "socket"
+msgstr "socket"
+
+msgid "directory"
+msgstr "diretório"
+
+#, python-format
+msgid "unsupported file type (type is %s)"
+msgstr "tipo de arquivo não suportado (o tipo é %s)"
+
+#, python-format
+msgid "abort: %s\n"
+msgstr "abortado: %s\n"
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+" %s\n"
+msgstr ""
+"hg: o comando '%s' é ambíguo:\n"
+" %s\n"
+
+#, python-format
+msgid "hg: %s\n"
+msgstr "hg: %s\n"
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr "tempo limite excedido esperando por trava de %s"
+
+#, python-format
+msgid "lock held by %s"
+msgstr "travado por %s"
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr "abortado: %s: %s\n"
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr "abortado: impossível travar %s: %s\n"
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr "hg %s: %s\n"
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr "abortado: %s!\n"
+
+#, python-format
+msgid "abort: %s"
+msgstr "abortado: %s"
+
+msgid " empty string\n"
+msgstr " string vazia\n"
+
+msgid "killed!\n"
+msgstr "morto!\n"
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr "hg: comando '%s' desconhecido\n"
+
+#, python-format
+msgid "abort: could not import module %s!\n"
+msgstr "abortado: não foi possível importar o módulo %s!\n"
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr "(você esqueceu de compilar extensões?)\n"
+
+msgid "(is your Python install correct?)\n"
+msgstr "(sua instalação do Python está correta?)\n"
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr "abortado: erro: %s\n"
+
+msgid "broken pipe\n"
+msgstr "pipe quebrado\n"
+
+msgid "interrupted!\n"
+msgstr "interrompido!\n"
+
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+"\n"
+"pipe quebrado\n"
+
+msgid "abort: out of memory\n"
+msgstr "abortado: sem memória\n"
+
+msgid "** unknown exception encountered, details follow\n"
+msgstr "** exceção desconhecida encontrada, segue detalhes\n"
+
+msgid "** report bug details to http://mercurial.selenic.com/bts/\n"
+msgstr "** reporte detalhes de problemas para http://mercurial.selenic.com/bts/\n"
+
+msgid "** or mercurial@selenic.com\n"
+msgstr "** ou mercurial@selenic.com\n"
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr "** Mercurial SCM Distribuído (versão %s)\n"
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr "** Extensões carregadas: %s\n"
+
+#, python-format
+msgid "no definition for alias '%s'\n"
+msgstr "nenhuma definição para o apelido '%s'\n"
+
+#, python-format
+msgid "alias '%s' resolves to unknown command '%s'\n"
+msgstr "apelido '%s' indica comando desconhecido '%s'\n"
+
+#, python-format
+msgid "alias '%s' resolves to ambiguous command '%s'\n"
+msgstr "apelido '%s' indica comando ambíguo '%s'\n"
+
+#, python-format
+msgid "alias '%s' shadows command\n"
+msgstr "apelido '%s' oculta o comando\n"
+
+#, python-format
+msgid "malformed --config option: %s"
+msgstr "opção --config mal formada: %s"
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr "a extensão '%s' sobrepõe o comando: %s\n"
+
+msgid "Option --config may not be abbreviated!"
+msgstr "A opção --config não pode ser abreviada!"
+
+msgid "Option --cwd may not be abbreviated!"
+msgstr "A opção --cwd não pode ser abreviada!"
+
+msgid ""
+"Option -R has to be separated from other options (e.g. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr ""
+"A opção -R deve ser separada de outras opções (por exemplo, não usar -qR) e "
+"--repository pode ser abreviada apenas como --repo!"
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr "Tempo: real %.3f segs (user %.3f+%.3f sys %.3f+%.3f)\n"
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr "o repositório '%s' não é local"
+
+msgid "invalid arguments"
+msgstr "argumentos inválidos"
+
+#, python-format
+msgid "unrecognized profiling format '%s' - Ignored\n"
+msgstr "formato de profiling '%s' não reconhecido - Ignorado\n"
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+"lsprof não disponível - instale de http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr "*** falha ao importar a extensão %s de %s: %s\n"
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr "*** falha ao importar a extensão %s: %s\n"
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr "não foi possível encontrar ferramenta de mesclagem %s\n"
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr "a ferramenta %s não pode tratar links simbólicos\n"
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr "a ferramenta %s não pode tratar binários\n"
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr "a ferramenta %s requer uma interface gráfica (GUI)\n"
+
+#, python-format
+msgid "picked tool '%s' for %s (binary %s symlink %s)\n"
+msgstr "escolhida ferramenta '%s' para %s (binário %s link simbólico %s)\n"
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+" nenhuma ferramenta encontrada para mesclar %s\n"
+"manter (l)ocal ou usar (o)utro?"
+
+msgid "&Local"
+msgstr "&Local"
+
+msgid "&Other"
+msgstr "&Outra"
+
+msgid "l"
+msgstr "l"
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr "mesclando %s e %s para %s\n"
+
+#, python-format
+msgid "merging %s\n"
+msgstr "mesclando %s\n"
+
+#, python-format
+msgid "my %s other %s ancestor %s\n"
+msgstr "meu %s outro %s ancestral %s\n"
+
+msgid " premerge successful\n"
+msgstr " prémesclagem com sucesso\n"
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+" arquivo de saída %s parece não ter modificações\n"
+"a mesclagem teve sucesso (sn)?"
+
+msgid "&No"
+msgstr "(&N) não"
+
+msgid "&Yes"
+msgstr "(&Y) sim"
+
+msgid "n"
+msgstr "n"
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr "mesclagem de %s falhou!\n"
+
+#, python-format
+msgid "Inconsistent state, %s:%s is good and bad"
+msgstr "Estado inconsistente, %s:%s é bom e ruim"
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr "tipo desconhecido de bisect %s"
+
+msgid ""
+"\n"
+" Mercurial has the ability to add new features through the use of\n"
+" extensions. Extensions may add new commands, add options to\n"
+" existing commands, change the default behavior of commands, or\n"
+" implement hooks.\n"
+"\n"
+" Extensions are not loaded by default for a variety of reasons:\n"
+" they can increase startup overhead; they may be meant for\n"
+" advanced usage only; they may provide potentially dangerous\n"
+" abilities (such as letting you destroy or modify history); they\n"
+" might not be ready for prime time; or they may alter some\n"
+" usual behaviors of stock Mercurial. It is thus up to the user to\n"
+" activate extensions as needed.\n"
+"\n"
+" To enable the \"foo\" extension, either shipped with Mercurial\n"
+" or in the Python search path, create an entry for it in your\n"
+" hgrc, like this:\n"
+"\n"
+" [extensions]\n"
+" foo =\n"
+"\n"
+" You may also specify the full path to an extension:\n"
+"\n"
+" [extensions]\n"
+" myfeature = ~/.hgext/myfeature.py\n"
+"\n"
+" To explicitly disable an extension enabled in an hgrc of broader\n"
+" scope, prepend its path with !:\n"
+"\n"
+" [extensions]\n"
+" # disabling extension bar residing in /path/to/extension/bar.py\n"
+" hgext.bar = !/path/to/extension/bar.py\n"
+" # ditto, but no path was supplied for extension baz\n"
+" hgext.baz = !\n"
+" "
+msgstr ""
+"\n"
+" O Mercurial possui um mecanismo para adicionar novas\n"
+" funcionalidades através do uso de extensões. Extensões podem\n"
+" adicionar novos comandos, adicionar novas opções a comandos\n"
+" existentes ou implementar ganchos.\n"
+"\n"
+" Extensões não são carregadas por padrão por diversas razões:\n"
+" elas podem aumentar o tempo de início ou execução; podem ser\n"
+" destinadas apenas a uso avançado; podem fornecer funcionalidade\n"
+" potencialmente perigosa (por exemplo, modificar ou destruir o\n"
+" histórico); podem ainda não estar prontas para uso geral; ou\n"
+" podem alterar o comportamento padrão do Mercurial. Cabe ao\n"
+" usuário ativar extensões como desejar.\n"
+"\n"
+" Para habilitar a extensão \"foo\", tanto se for distribuída com\n"
+" o Mercurial como estiver no caminho de busca do Python, crie uma\n"
+" entrada para ela em seu hgrc, da seguinte forma:\n"
+"\n"
+" [extensions]\n"
+" foo =\n"
+"\n"
+" Você também pode especificar o caminho completo para uma\n"
+" extensão:\n"
+"\n"
+" [extensions]\n"
+" myfeature = ~/.hgext/myfeature.py\n"
+"\n"
+" Para desabilitar explicitamente uma extensão habilitada em um\n"
+" hgrc de escopo mais amplo, prefixe seu caminho com !:\n"
+"\n"
+" [extensions]\n"
+" # desabilita a extensão bar localizada em\n"
+" # /caminho/para/extensao/bar.py\n"
+" hgext.bar = !/caminho/para/extensao/bar.py\n"
+" # o mesmo, se um caminho não foi fornecido para a\n"
+" # extensão baz\n"
+" hgext.baz = !\n"
+" "
+
+msgid "disabled extensions:"
+msgstr "extensões desabilitadas:"
+
+msgid "Date Formats"
+msgstr "Formatos de datas"
+
+msgid ""
+"\n"
+" Some commands allow the user to specify a date, e.g.:\n"
+" * backout, commit, import, tag: Specify the commit date.\n"
+" * log, revert, update: Select revision(s) by date.\n"
+"\n"
+" Many date formats are valid. Here are some examples:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n"
+" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n"
+" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n"
+" \"Dec 6\" (midnight)\n"
+" \"13:18\" (today assumed)\n"
+" \"3:39\" (3:39AM assumed)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Lastly, there is Mercurial's internal format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" This is the internal representation format for dates. unixtime is\n"
+" the number of seconds since the epoch (1970-01-01 00:00 UTC).\n"
+" offset is the offset of the local timezone, in seconds west of UTC\n"
+" (negative if the timezone is east of UTC).\n"
+"\n"
+" The log command also accepts date ranges:\n"
+"\n"
+" \"<{datetime}\" - at or before a given date/time\n"
+" \">{datetime}\" - on or after a given date/time\n"
+" \"{datetime} to {datetime}\" - a date range, inclusive\n"
+" \"-{days}\" - within a given number of days of today\n"
+" "
+msgstr ""
+"\n"
+" Alguns comandos permitem ao usuário especificar uma data:\n"
+" * backout, commit, import, tag: a data de consolidação.\n"
+" * log, revert, update: Selecionar revisões por data.\n"
+"\n"
+" Muitos formatos de data são válidos. Eis alguns exemplos:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (assumido fuso horário local)\n"
+" \"Dec 6 13:18 -0600\" (ano atual, defasagem de horário local\n"
+" fornecida)\n"
+" \"Dec 6 13:18 UTC\" (UTC e GMT são apelidos para +0000)\n"
+" \"Dec 6\" (meia noite)\n"
+" \"13:18\" (data corrente assumida)\n"
+" \"3:39\" (hora assumida 3:39AM)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (formato ISO 8601)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" E por fim, há um formato interno do Mercurial:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" Este é o formato interno de representação de datas. unixtime é\n"
+" o número de segundos desde a epoch (1970-01-01 00:00 UTC). offset\n"
+" é a defasagem do fuso horário local, em segundos a oeste de UTC\n"
+" (negativo para fusos horários a leste de UTC).\n"
+"\n"
+" O comando log também aceita intervalos de data:\n"
+"\n"
+" \"<{date}\" - na data fornecida, ou anterior\n"
+" \">{date}\" - na data fornecida, ou posterior\n"
+" \"{date} to {date}\" - um intervalo de data, incluindo os\n"
+" extremos\n"
+" \"-{days}\" - dentro de um certo número de dias contados de hoje\n"
+" "
+
+msgid "File Name Patterns"
+msgstr "Padrões de nome de arquivo"
+
+msgid ""
+"\n"
+" Mercurial accepts several notations for identifying one or more\n"
+" files at a time.\n"
+"\n"
+" By default, Mercurial treats filenames as shell-style extended\n"
+" glob patterns.\n"
+"\n"
+" Alternate pattern notations must be specified explicitly.\n"
+"\n"
+" To use a plain path name without any pattern matching, start it\n"
+" with \"path:\". These path names must completely match starting at\n"
+" the current repository root.\n"
+"\n"
+" To use an extended glob, start a name with \"glob:\". Globs are\n"
+" rooted at the current directory; a glob such as \"*.c\" will only\n"
+" match files in the current directory ending with \".c\".\n"
+"\n"
+" The supported glob syntax extensions are \"**\" to match any string\n"
+" across path separators and \"{a,b}\" to mean \"a or b\".\n"
+"\n"
+" To use a Perl/Python regular expression, start a name with \"re:\".\n"
+" Regexp pattern matching is anchored at the root of the repository.\n"
+"\n"
+" Plain examples:\n"
+"\n"
+" path:foo/bar a name bar in a directory named foo in the root of\n"
+" the repository\n"
+" path:path:name a file or directory named \"path:name\"\n"
+"\n"
+" Glob examples:\n"
+"\n"
+" glob:*.c any name ending in \".c\" in the current directory\n"
+" *.c any name ending in \".c\" in the current directory\n"
+" **.c any name ending in \".c\" in any subdirectory of the\n"
+" current directory including itself.\n"
+" foo/*.c any name ending in \".c\" in the directory foo\n"
+" foo/**.c any name ending in \".c\" in any subdirectory of foo\n"
+" including itself.\n"
+"\n"
+" Regexp examples:\n"
+"\n"
+" re:.*\\.c$ any name ending in \".c\", anywhere in the repository\n"
+"\n"
+" "
+msgstr ""
+"\n"
+" O Mercurial aceita diversas notações para identificar um ou mais\n"
+" arquivos de uma vez.\n"
+"\n"
+" Por padrão, o Mercurial trata nomes de arquivo como padrões\n"
+" estendidos de glob do shell.\n"
+"\n"
+" Notações alternativas de padrões devem ser especificadas\n"
+" explicitamente.\n"
+"\n"
+" Para usar um nome simples de caminho sem qualquer casamento de\n"
+" padrões, comece o nome com \"path:\". Estes nomes de caminho\n"
+" devem bater completamente, a partir da raiz do repositório\n"
+" atual.\n"
+"\n"
+" Para usar um glob estendido, comece um nome com \"glob:\". Globs\n"
+" têm como raiz o diretório corrente; um glob como \"*.c\" baterá\n"
+" com arquivos terminados em \".c\" apenas no diretório corrente.\n"
+"\n"
+" As sintaxes de extensão do glob suportadas são \"**\" para bater\n"
+" com qualquer string incluindo separadores de caminho, e \"{a,b}\"\n"
+" para significar \"a ou b\".\n"
+"\n"
+" Para usar uma expressão regular Perl/Python, comece um nome com\n"
+" \"re:\". O casamento de padrões por expressão regular é feito a\n"
+" partir do raiz do repositório.\n"
+"\n"
+" Exemplos simples:\n"
+"\n"
+" path:foo/bar o nome bar em um diretório chamado foo no raiz do\n"
+" repositório\n"
+" path:path:name um arquivo ou diretório chamado \"path:name\"\n"
+"\n"
+" Exemplos de glob:\n"
+"\n"
+" glob:*.c qualquer nome terminado por \".c\" no diretório\n"
+" atual\n"
+" *.c qualquer nome terminado por \".c\" no diretório\n"
+" atual\n"
+" **.c qualquer nome terminado por \".c\" no diretório\n"
+" atual ou em qualquer subdiretório\n"
+" foo/*.c qualquer nome terminado por \".c\" no diretório\n"
+" foo\n"
+" foo/**.c qualquer nome terminado por \".c\" no diretório\n"
+" foo ou em qualquer subdiretório\n"
+"\n"
+" Exemplos de regexp:\n"
+"\n"
+" re:.*\\.c$ qualquer nome terminado por \".c\", em qualquer\n"
+" lugar no repositório\n"
+"\n"
+" "
+
+msgid "Environment Variables"
+msgstr "Variáveis de ambiente"
+
+msgid ""
+"\n"
+"HG::\n"
+" Path to the 'hg' executable, automatically passed when running\n"
+" hooks, extensions or external tools. If unset or empty, this is\n"
+" the hg executable's name if it's frozen, or an executable named\n"
+" 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+" Windows) is searched.\n"
+"\n"
+"HGEDITOR::\n"
+" This is the name of the editor to run when committing. See EDITOR.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" This overrides the default locale setting detected by Mercurial.\n"
+" This setting is used to convert data including usernames,\n"
+" changeset descriptions, tag names, and branches. This setting can\n"
+" be overridden with the --encoding command-line option.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" This sets Mercurial's behavior for handling unknown characters\n"
+" while transcoding user input. The default is \"strict\", which\n"
+" causes Mercurial to abort if it can't map a character. Other\n"
+" settings include \"replace\", which replaces unknown characters, and\n"
+" \"ignore\", which drops them. This setting can be overridden with\n"
+" the --encodingmode command-line option.\n"
+"\n"
+"HGMERGE::\n"
+" An executable to use for resolving merge conflicts. The program\n"
+" will be executed with three arguments: local file, remote file,\n"
+" ancestor file.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" A list of files or directories to search for hgrc files. Item\n"
+" separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
+" platform default search path is used. If empty, only the .hg/hgrc\n"
+" from the current repository is read.\n"
+"\n"
+" For each element in HGRCPATH:\n"
+" * if it's a directory, all files ending with .rc are added\n"
+" * otherwise, the file itself will be added\n"
+"\n"
+"HGUSER::\n"
+" This is the string used as the author of a commit. If not set,\n"
+" available values will be considered in this order:\n"
+"\n"
+" * HGUSER (deprecated)\n"
+" * hgrc files from the HGRCPATH\n"
+" * EMAIL\n"
+" * interactive prompt\n"
+" * LOGNAME (with '@hostname' appended)\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"LOGNAME::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"VISUAL::\n"
+" This is the name of the editor to use when committing. See EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Sometimes Mercurial needs to open a text file in an editor for a\n"
+" user to modify, for example when writing commit messages. The\n"
+" editor it uses is determined by looking at the environment\n"
+" variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+" non-empty one is chosen. If all of them are empty, the editor\n"
+" defaults to 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" This is used by Python to find imported modules and may need to be\n"
+" set appropriately if this Mercurial is not installed system-wide.\n"
+" "
+msgstr ""
+"\n"
+"HG::\n"
+" Caminho para o executável 'hg', automaticamente passado na\n"
+" execução de ganchos, extensões ou ferramentas externas. Se não\n"
+" definido ou vazio, um executável chamado 'hg' (com a extensão\n"
+" com/exe/bat/cmd no Windows) é procurado.\n"
+"\n"
+"HGEDITOR::\n"
+" Este é o nome do editor usado em consolidações. Veja EDITOR.\n"
+"\n"
+" (obsoleto, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" É usado no lugar da configuração padrão de locale detectada\n"
+" pelo Mercurial. Essa configuração é usada para converter dados\n"
+" como nomes de usuário, descrições de changesets, nomes de\n"
+" etiqueta e ramos. Essa configuração pode ser sobreposta com a\n"
+" opção --encoding na linha de comando.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" Essa configuração ajusta o comportamento do Mercurial no\n"
+" tratamento de caracteres desconhecidos, ao codificar entradas do\n"
+" usuário. O padrão é \"strict\", o que faz com que o Mercurial\n"
+" aborte se ele não puder traduzir um caractere. Outros valores\n"
+" incluem \"replace\", que substitui caracteres desconhecidos, e\n"
+" \"ignore\", que os descarta. Essa configuração pode ser\n"
+" sobreposta com a opção --encodingmode na linha de comando.\n"
+"\n"
+"HGMERGE::\n"
+" Um executável a ser usado para solucionar conflitos de mesclagem.\n"
+" O programa será executado com três argumentos: arquivo local,\n"
+" arquivo remoto, arquivo ancestral.\n"
+"\n"
+" (obsoleta, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" Uma lista de arquivos ou diretórios onde procurar arquivos hgrc.\n"
+" O separador de itens é \":\" em Unix, \";\" no Windows. Se\n"
+" HGRCPATH não estiver definido, o caminho de busca padrão da\n"
+" plataforma será usado. Se vazio, será lido apenas .hg/hgrc no\n"
+" repositório atual.\n"
+"\n"
+" Para cada elemento no path que for um diretório, todas as\n"
+" entradas no diretório terminadas por \".rc\" serão adicionadas\n"
+" ao path. Caso contrário, o próprio elemento será adicionado ao\n"
+" path.\n"
+"\n"
+"HGUSER::\n"
+" Esta é a string usada para o autor de uma consolidação.\n"
+"\n"
+" (obsoleto, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" Se HGUSER não estiver definido, este valor será usado como autor\n"
+" para consolidações.\n"
+"\n"
+"LOGNAME::\n"
+" Se nem HGUSER nem EMAIL estiverem definidos, LOGNAME será usado\n"
+" (com '@hostname' anexado) como o autor de uma consolidação.\n"
+"\n"
+"VISUAL::\n"
+" Este é o nome do editor a ser usado em consolidações. Veja\n"
+" EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Algumas vezes o Mercurial precisa abrir em um editor um arquivo\n"
+" texto para ser modificado por um usuário, por exemplo ao escrever\n"
+" mensagens de consolidação. O editor usado é determinado pela\n"
+" consulta às variáveis de ambiente HGEDITOR, VISUAL e EDITOR,\n"
+" nessa ordem. O primeiro valor não vazio é escolhido. Se todos\n"
+" estiverem vazios, o editor será o 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" Isto é usado pelo Python para localizar módulos importados, e\n"
+" pode precisar ser ajustado apropriadamente se o Mercurial não\n"
+" estiver instalado para o sistema todo.\n"
+" "
+
+msgid "Specifying Single Revisions"
+msgstr "Especificação de revisões únicas"
+
+msgid ""
+"\n"
+" Mercurial supports several ways to specify individual revisions.\n"
+"\n"
+" A plain integer is treated as a revision number. Negative integers\n"
+" are treated as topological offsets from the tip, with -1 denoting\n"
+" the tip. As such, negative numbers are only useful if you've\n"
+" memorized your local tree numbers and want to save typing a single\n"
+" digit. This editor suggests copy and paste.\n"
+"\n"
+" A 40-digit hexadecimal string is treated as a unique revision\n"
+" identifier.\n"
+"\n"
+" A hexadecimal string less than 40 characters long is treated as a\n"
+" unique revision identifier, and referred to as a short-form\n"
+" identifier. A short-form identifier is only valid if it is the\n"
+" prefix of exactly one full-length identifier.\n"
+"\n"
+" Any other string is treated as a tag name, which is a symbolic\n"
+" name associated with a revision identifier. Tag names may not\n"
+" contain the \":\" character.\n"
+"\n"
+" The reserved name \"tip\" is a special tag that always identifies\n"
+" the most recent revision.\n"
+"\n"
+" The reserved name \"null\" indicates the null revision. This is the\n"
+" revision of an empty repository, and the parent of revision 0.\n"
+"\n"
+" The reserved name \".\" indicates the working directory parent. If\n"
+" no working directory is checked out, it is equivalent to null. If\n"
+" an uncommitted merge is in progress, \".\" is the revision of the\n"
+" first parent.\n"
+" "
+msgstr ""
+"\n"
+" O Mercurial aceita diversas notações para identificar revisões\n"
+" individuais.\n"
+"\n"
+" Um simples inteiro é tratado como um número de revisão. Inteiros\n"
+" negativos são tratados como contados topologicamente a partir da\n"
+" tip, com -1 denotando a tip. Assim, números negativos são úteis\n"
+" apenas se você memorizou os números de sua árvore local e quiser\n"
+" evitar digitar um único caractere. Este editor sugere copiar e\n"
+" colar.\n"
+"\n"
+" Uma string hexadecimal de 40 dígitos é tratada como um\n"
+" identificador único de revisão.\n"
+"\n"
+" Uma string hexadecimal de menos de 40 caracteres é tratada como\n"
+" um identificador único de revisão, e referida como um\n"
+" identificador curto. Um identificador curto é válido apenas se\n"
+" for o prefixo de um identificador completo.\n"
+"\n"
+" Qualquer outra string é tratada como um nome de etiqueta, que é\n"
+" um nome simbólico associado a um identificador de revisão. Nomes\n"
+" de etiqueta não podem conter o caractere \":\".\n"
+"\n"
+" O nome reservado \"tip\" é uma etiqueta especial que sempre\n"
+" identifica a revisão mais recente.\n"
+"\n"
+" O nome reservado \"null\" indica a revisão nula. Essa é a revisão\n"
+" de um repositório vazio, e a revisão pai da revisão 0.\n"
+"\n"
+" O nome reservado \".\" indica a revisão pai do diretório de\n"
+" trabalho. Se nenhum diretório de trabalho estiver selecionado,\n"
+" será equivalente a null. Se uma mesclagem estiver em progresso,\n"
+" \".\" será a revisão do primeiro pai.\n"
+" "
+
+msgid "Specifying Multiple Revisions"
+msgstr "Especificação de múltiplas revisões"
+
+msgid ""
+"\n"
+" When Mercurial accepts more than one revision, they may be\n"
+" specified individually, or provided as a topologically continuous\n"
+" range, separated by the \":\" character.\n"
+"\n"
+" The syntax of range notation is [BEGIN]:[END], where BEGIN and END\n"
+" are revision identifiers. Both BEGIN and END are optional. If\n"
+" BEGIN is not specified, it defaults to revision number 0. If END\n"
+" is not specified, it defaults to the tip. The range \":\" thus means\n"
+" \"all revisions\".\n"
+"\n"
+" If BEGIN is greater than END, revisions are treated in reverse\n"
+" order.\n"
+"\n"
+" A range acts as a closed interval. This means that a range of 3:5\n"
+" gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+" "
+msgstr ""
+"\n"
+" Quando o Mercurial aceita mais de uma revisão, elas podem ser\n"
+" especificadas individualmente, ou fornecidas como uma seqüência\n"
+" topologicamente contínua, separadas pelo caractere \":\".\n"
+"\n"
+" A sintaxe da notação de seqüência é [INÃCIO]:[FIM], onde INÃCIO\n"
+" e FIM são identificadores de revisão. Tanto INÃCIO como FIM são\n"
+" opcionais. Se INÃCIO não for especificado, terá como valor padrão\n"
+" a revisão número 0. Se FIM não for especificado, terá como valor\n"
+" padrão a revisão tip. A seqüência \":\" portanto significa\n"
+" \"todas as revisões\".\n"
+"\n"
+" Se INÃCIO for maior que FIM, as revisões são tratadas na ordem\n"
+" inversa.\n"
+"\n"
+" Uma seqüência age como um intervalo fechado. Isso quer dizer que\n"
+" uma seqüência 3:5 nos dá 3, 4 e 5. De forma semelhante, uma\n"
+" seqüência 4:2 nos dá 4, 3, e 2.\n"
+" "
+
+msgid "Diff Formats"
+msgstr "Formatos de diff"
+
+msgid ""
+"\n"
+" Mercurial's default format for showing changes between two\n"
+" versions of a file is compatible with the unified format of GNU\n"
+" diff, which can be used by GNU patch and many other standard\n"
+" tools.\n"
+"\n"
+" While this standard format is often enough, it does not encode the\n"
+" following information:\n"
+"\n"
+" - executable status and other permission bits\n"
+" - copy or rename information\n"
+" - changes in binary files\n"
+" - creation or deletion of empty files\n"
+"\n"
+" Mercurial also supports the extended diff format from the git VCS\n"
+" which addresses these limitations. The git diff format is not\n"
+" produced by default because a few widespread tools still do not\n"
+" understand this format.\n"
+"\n"
+" This means that when generating diffs from a Mercurial repository\n"
+" (e.g. with \"hg export\"), you should be careful about things like\n"
+" file copies and renames or other things mentioned above, because\n"
+" when applying a standard diff to a different repository, this\n"
+" extra information is lost. Mercurial's internal operations (like\n"
+" push and pull) are not affected by this, because they use an\n"
+" internal binary format for communicating changes.\n"
+"\n"
+" To make Mercurial produce the git extended diff format, use the\n"
+" --git option available for many commands, or set 'git = True' in\n"
+" the [diff] section of your hgrc. You do not need to set this\n"
+" option when importing diffs in this format or using them in the mq\n"
+" extension.\n"
+" "
+msgstr ""
+"\n"
+" O formato padrão do Mercurial para exibir mudanças entre duas\n"
+" versões de um arquivo é compatível com o formato unified do GNU\n"
+" diff, que pode ser usado pelo GNU patch e muitos outros\n"
+" utilitários padrão.\n"
+"\n"
+" Apesar de esse formato padrão ser muitas vezes suficiente, ele\n"
+" não codifica as seguintes informações:\n"
+"\n"
+" - bits de execução e permissão\n"
+" - informação de cópia ou renomeação\n"
+" - mudanças em arquivos binários\n"
+" - criação ou remoção de arquivos vazios\n"
+"\n"
+" O Mercurial também suporta o formato diff estendido do VCS git\n"
+" que trata dessas limitações. O formato git diff não é\n"
+" produzido por padrão porque há muito poucas ferramentas que\n"
+" entendem esse formato.\n"
+"\n"
+" Isso quer dizer que ao gerar diffs de um repositório do Mercurial\n"
+" (por exemplo, com \"hg export\"), você deve tomar cuidado com por\n"
+" exemplo cópias e renomeações de arquivos ou outras coisas\n"
+" mencionadas acima, porque essa informação extra é perdida ao\n"
+" aplicar um diff padrão em um outro repositório. As operações\n"
+" internas do Mercurial (como push e pull) não são afetadas por\n"
+" isso, porque usam um formato binário interno para comunicar\n"
+" mudanças.\n"
+"\n"
+" Para fazer com que o Mercurial produza o formato estendido git\n"
+" diff, use a opção --git disponível para vários comandos, ou\n"
+" defina 'git = True' na seção [diff] de seu hgrc. Você não precisa\n"
+" definir essa opção para importar diffs nesse formato, nem para\n"
+" usá-lo com a extensão mq.\n"
+" "
+
+msgid "Template Usage"
+msgstr "Uso de modelos"
+
+msgid ""
+"\n"
+" Mercurial allows you to customize output of commands through\n"
+" templates. You can either pass in a template from the command\n"
+" line, via the --template option, or select an existing\n"
+" template-style (--style).\n"
+"\n"
+" You can customize output for any \"log-like\" command: log,\n"
+" outgoing, incoming, tip, parents, heads and glog.\n"
+"\n"
+" Three styles are packaged with Mercurial: default (the style used\n"
+" when no explicit preference is passed), compact and changelog.\n"
+" Usage:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" A template is a piece of text, with markup to invoke variable\n"
+" expansion:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings in curly braces are called keywords. The availability of\n"
+" keywords depends on the exact context of the templater. These\n"
+" keywords are usually available for templating a log-like command:\n"
+"\n"
+" - author: String. The unmodified author of the changeset.\n"
+" - branches: String. The name of the branch on which the changeset\n"
+" was committed. Will be empty if the branch name was default.\n"
+" - date: Date information. The date when the changeset was committed.\n"
+" - desc: String. The text of the changeset description.\n"
+" - diffstat: String. Statistics of changes with the following\n"
+" format: \"modified files: +added/-removed lines\"\n"
+" - files: List of strings. All files modified, added, or removed by\n"
+" this changeset.\n"
+" - file_adds: List of strings. Files added by this changeset.\n"
+" - file_mods: List of strings. Files modified by this changeset.\n"
+" - file_dels: List of strings. Files removed by this changeset.\n"
+" - node: String. The changeset identification hash, as a\n"
+" 40-character hexadecimal string.\n"
+" - parents: List of strings. The parents of the changeset.\n"
+" - rev: Integer. The repository-local changeset revision number.\n"
+" - tags: List of strings. Any tags associated with the changeset.\n"
+"\n"
+" The \"date\" keyword does not produce human-readable output. If you\n"
+" want to use a date in your output, you can use a filter to process\n"
+" it. Filters are functions which return a string based on the input\n"
+" variable. You can also use a chain of filters to get the desired\n"
+" output:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" List of filters:\n"
+"\n"
+" - addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
+" every line except the last.\n"
+" - age: Date. Returns a human-readable date/time difference between\n"
+" the given date/time and the current date/time.\n"
+" - basename: Any text. Treats the text as a path, and returns the\n"
+" last component of the path after splitting by the path\n"
+" separator (ignoring trailing separators). For example,\n"
+" \"foo/bar/baz\" becomes \"baz\" and \"foo/bar//\" becomes \"bar"
+"\".\n"
+" - stripdir: Treat the text as path and strip a directory level, if\n"
+" possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\".\n"
+" - date: Date. Returns a date in a Unix date format, including\n"
+" the timezone: \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - domain: Any text. Finds the first string that looks like an\n"
+" email address, and extracts just the domain component.\n"
+" Example: 'User <user@example.com>' becomes 'example.com'.\n"
+" - email: Any text. Extracts the first string that looks like an\n"
+" email address. Example: 'User <user@example.com>' becomes\n"
+" 'user@example.com'.\n"
+" - escape: Any text. Replaces the special XML/XHTML characters \"&\",\n"
+" \"<\" and \">\" with XML entities.\n"
+" - fill68: Any text. Wraps the text to fit in 68 columns.\n"
+" - fill76: Any text. Wraps the text to fit in 76 columns.\n"
+" - firstline: Any text. Returns the first line of text.\n"
+" - nonempty: Any text. Returns '(none)' if the string is empty.\n"
+" - hgdate: Date. Returns the date as a pair of numbers:\n"
+" \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
+" - isodate: Date. Returns the date in ISO 8601 format.\n"
+" - localdate: Date. Converts a date to local date.\n"
+" - obfuscate: Any text. Returns the input text rendered as a\n"
+" sequence of XML entities.\n"
+" - person: Any text. Returns the text before an email address.\n"
+" - rfc822date: Date. Returns a date using the same format used\n"
+" in email headers.\n"
+" - short: Changeset hash. Returns the short form of a changeset\n"
+" hash, i.e. a 12-byte hexadecimal string.\n"
+" - shortdate: Date. Returns a date like \"2006-09-18\".\n"
+" - strip: Any text. Strips all leading and trailing whitespace.\n"
+" - tabindent: Any text. Returns the text, with every line except\n"
+" the first starting with a tab character.\n"
+" - urlescape: Any text. Escapes all \"special\" characters. For\n"
+" example, \"foo bar\" becomes \"foo%20bar\".\n"
+" - user: Any text. Returns the user portion of an email address.\n"
+" "
+msgstr ""
+"\n"
+" O Mercurial permite que você personalize a saída de comandos\n"
+" usando modelos. Você pode tanto passar um modelo pela linha de\n"
+" comando, usando a opção --template, como selecionar um\n"
+" modelo-estilo existente (--style).\n"
+"\n"
+" Você pode personalizar a saída de qualquer comando semelhante\n"
+" ao log: log, outgoing, incoming, tip, parents, heads e glog.\n"
+"\n"
+" Três estilos são incluídos na distribuição do Mercurial: default\n"
+" (o estilo usado quando nenhuma preferência for passada), compact\n"
+" e changelog. Uso:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" Um modelo é um texto com marcações que invocam expansão de\n"
+" variáveis:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings entre chaves são chamadas palavras chave. A\n"
+" disponibilidade de palavras chave depende do contexto exato do\n"
+" modelador. Estas palavras chave estão comumente disponíveis para\n"
+" modelar comandos semelhantes ao log:\n"
+"\n"
+" - author: String. O autor do changeset, sem modificações.\n"
+" - branches: String. O nome do ramo no qual o changeset foi\n"
+" consolidado. Será vazio se o nome do ramo for default.\n"
+" - date: Informação de data. A data de consolidação do changeset.\n"
+" - desc: String. O texto da descrição do changeset.\n"
+" - diffstat: String. Estatísticas de mudanças no seguinte\n"
+" formato: \"modified files: +added/-removed lines\"\n"
+" - files: Lista de strings. Todos os arquivos modificados,\n"
+" adicionados ou removidos por este changeset.\n"
+" - file_adds: Lista de strings. Arquivos adicionados por este\n"
+" changeset.\n"
+" - file_mods: Lista de strings. Arquivos modificados por este\n"
+" changeset.\n"
+" - file_dels: Lista de strings. Arquivos removidos por este\n"
+" changeset.\n"
+" - node: String. O hash de identificação do changeset, como uma\n"
+" string hexadecimal de 40 caracteres.\n"
+" - parents: Lista de strings. Os pais do changeset.\n"
+" - rev: Inteiro. O número de revisão do changeset no\n"
+" repositório local.\n"
+" - tags: Lista de strings. Quaisquer etiquetas associadas ao\n"
+" changeset.\n"
+"\n"
+" A palavra chave \"date\" não produz saída legível para humanos.\n"
+" Se você quiser usar uma data em sua saída, você pode usar um\n"
+" filtro para processá-la. Filtros são funções que devolvem uma\n"
+" string baseada na variável de entrada. Você também pode encadear\n"
+" filtros para obter a saída desejada:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" Lista de filtros:\n"
+"\n"
+" - addbreaks: Qualquer texto. Adiciona uma tag XHTML \"<br />\"\n"
+" antes do fim de cada linha, exceto a última.\n"
+" - age: Data. Devolve uma diferença de data/tempo legível entre\n"
+" a data/hora dada e a data/hora atual.\n"
+" - basename: Qualquer texto. Trata o texto como um caminho, e\n"
+" devolve o último componente do caminho após quebrá-lo\n"
+" usando o separador de caminhos (ignorando separadores à\n"
+" direita). Por exemple, \"foo/bar/baz\" se torna \"baz\"\n"
+" e \"foo/bar//\" se torna \"bar\".\n"
+" - date: Data. Devolve uma data em um formato de data Unix,\n"
+" incluindo a diferença de fuso horário:\n"
+" \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - stripdir: Trata o texto como um caminho e remove um nível\n"
+" de diretório, se possível. Por exemplo, \"foo\" e\n"
+" \"foo/bar\" se tornam \"foo\".\n"
+" - domain: Qualquer texto. Encontra a primeira string que se\n"
+" pareça com um endereço de e-mail, e extrai apenas a parte\n"
+" do domínio. Por exemplo:\n"
+" 'User <user@example.com>' se torna 'example.com'.\n"
+" - email: Qualquer texto. Extrai a primeira string que se pareça\n"
+" com um endereço de e-mail. Por exemplo:\n"
+" 'User <user@example.com>' se torna 'user@example.com'.\n"
+" - escape: Qualquer texto. Substitui os caracteres especiais\n"
+" XML/XHTML \"&\", \"<\" e \">\" por entidades XML.\n"
+" - fill68: Qualquer texto. Quebra o texto para caber em 68\n"
+" colunas.\n"
+" - fill76: Qualquer texto. Quebra o texto para caber em 76\n"
+" colunas.\n"
+" - firstline: Qualquer texto. Devolve a primeira linha do texto.\n"
+" - nonempty: Qualquer texto. Devolve (none) se o texto for vazio.\n"
+" - hgdate: Data. Devolve a data como um par de números:\n"
+" \"1157407993 25200\" (timestamp Unix, defasagem de fuso)\n"
+" - isodate: Data. Devolve a data em formato ISO 8601.\n"
+" - localdate: Data. Converte para data local.\n"
+" - obfuscate: Qualquer texto. Devolve o texto de entrada\n"
+" renderizado como uma seqüência de entidades XML.\n"
+" - person: Qualquer texto. Devolve o texto antes de um endereço\n"
+" de e-mail.\n"
+" - rfc822date: Data. Devolve uma data usando o mesmo formato\n"
+" utilizado em cabeçalhos de e-mail.\n"
+" - short: Hash do changeset. Devolve a forma curta do hash de\n"
+" um changeset, ou seja, uma string hexadecimal de 12 bytes.\n"
+" - shortdate: Data. Devolve uma data como \"2006-09-18\".\n"
+" - strip: Qualquer texto. Remove todos os espaços em branco no\n"
+" início e no final do texto.\n"
+" - tabindent: Qualquer texto. Devolve o texto todo, com a adição\n"
+" de um caractere de tabulação ao início de cada linha,\n"
+" exceto da primeira.\n"
+" - urlescape: Qualquer texto. Codifica todos os caracteres\n"
+" \"especiais\". Por exemplo, \"foo bar\" se torna\n"
+" \"foo%20bar\".\n"
+" - user: Qualquer texto. Devolve a parte do usuário de um\n"
+" endereço de e-mail.\n"
+" "
+
+msgid "URL Paths"
+msgstr "Caminhos URL"
+
+msgid ""
+"\n"
+" Valid URLs are of the form:\n"
+"\n"
+" local/filesystem/path[#revision]\n"
+" file://local/filesystem/path[#revision]\n"
+" http://[user[:pass]@]host[:port]/[path][#revision]\n"
+" https://[user[:pass]@]host[:port]/[path][#revision]\n"
+" ssh://[user[:pass]@]host[:port]/[path][#revision]\n"
+"\n"
+" Paths in the local filesystem can either point to Mercurial\n"
+" repositories or to bundle files (as created by 'hg bundle' or\n"
+" 'hg incoming --bundle').\n"
+"\n"
+" An optional identifier after # indicates a particular branch, tag,\n"
+" or changeset to use from the remote repository. See also 'hg help\n"
+" revisions'.\n"
+"\n"
+" Some features, such as pushing to http:// and https:// URLs are\n"
+" only possible if the feature is explicitly enabled on the remote\n"
+" Mercurial server.\n"
+"\n"
+" Some notes about using SSH with Mercurial:\n"
+" - SSH requires an accessible shell account on the destination\n"
+" machine and a copy of hg in the remote path or specified with as\n"
+" remotecmd.\n"
+" - path is relative to the remote user's home directory by default.\n"
+" Use an extra slash at the start of a path to specify an absolute "
+"path:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial doesn't use its own compression via SSH; the right\n"
+" thing to do is to configure it in your ~/.ssh/config, e.g.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternatively specify \"ssh -C\" as your ssh command in your hgrc\n"
+" or with the --ssh command line option.\n"
+"\n"
+" These URLs can all be stored in your hgrc with path aliases under\n"
+" the [paths] section like so:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" You can then use the alias for any command that uses a URL (for\n"
+" example 'hg pull alias1' would pull from the 'alias1' path).\n"
+"\n"
+" Two path aliases are special because they are used as defaults\n"
+" when you do not provide the URL to a command:\n"
+"\n"
+" default:\n"
+" When you create a repository with hg clone, the clone command\n"
+" saves the location of the source repository as the new\n"
+" repository's 'default' path. This is then used when you omit\n"
+" path from push- and pull-like commands (including incoming and\n"
+" outgoing).\n"
+"\n"
+" default-push:\n"
+" The push command will look for a path named 'default-push', and\n"
+" prefer it over 'default' if both are defined.\n"
+" "
+msgstr ""
+"\n"
+" URLs válidas são da forma:\n"
+"\n"
+" caminho/no/sistema/de/arquivos/local[#revisão]\n"
+" file://caminho/no/sistema/de/arquivos/local[#revisão]\n"
+" http://[usuário[:senha]@]servidor[:porta]/[caminho][#revisão]\n"
+" https://[usuário[:senha]@]servidor[:porta]/[caminho][#revisão]\n"
+" ssh://[usuário[:senha]@]servidor[:porta]/[caminho][#revisão]\n"
+"\n"
+" Caminhos no sistema de arquivos local podem tanto apontar para\n"
+" repositórios do Mercurial como para arquivos bundle (criados por\n"
+" 'hg bundle' ou 'hg incoming --bundle').\n"
+"\n"
+" Um identificador opcional após # indica um ramo, etiqueta ou\n"
+" changeset do repositório remoto a ser usado. Veja também 'hg\n"
+" help revisions'.\n"
+"\n"
+" Certas funcionalidades, como o push para URLs http:// e https://\n"
+" são possíveis apenas se forem explicitamente habilitadas no\n"
+" servidor remoto do Mercurial.\n"
+"\n"
+" Algumas notas sobre o uso de SSH com o Mercurial:\n"
+" - o SSH necessita de uma conta shell acessível na máquina de\n"
+" destino e uma cópia do hg no caminho de execução remoto ou\n"
+" especificado em remotecmd.\n"
+" - o caminho é por padrão relativo ao diretório home do usuário\n"
+" remoto.\n"
+" Use uma barra extra no início de um caminho para especificar um\n"
+" caminho absoluto:\n"
+" ssh://exemplo.com//tmp/repositorio\n"
+" - o Mercurial não usa sua própria compressão via SSH; a coisa\n"
+" certa a fazer é configurá-la em seu ~/.ssh/config, por exemplo:\n"
+" Host *.minharedelocal.exemplo.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternativamente especifique \"ssh -C\" como seu comando ssh\n"
+" em seu hgrc ou pela opção de linha de comando --ssh .\n"
+"\n"
+" Estas URLs podem ser todas armazenadas em seu hgrc com apelidos\n"
+" de caminho na seção [paths] , da seguinte forma:\n"
+" [paths]\n"
+" apelido1 = URL1\n"
+" apelido2 = URL2\n"
+" ...\n"
+"\n"
+" Você pode então usar o apelido em qualquer comando que receba uma\n"
+" URL (por exemplo 'hg pull apelido1' iria trazer revisões do\n"
+" caminho 'alias1').\n"
+"\n"
+" Dois apelidos de caminho são especiais por serem usados como\n"
+" valores padrão quando você não fornece a URL para um comando:\n"
+"\n"
+" default:\n"
+" Quando você cria um repositório com hg clone, o comando clone\n"
+" grava a localização do repositório de origem como o novo\n"
+" caminho 'default' do repositório. Ele é então usado quando você\n"
+" omitir o caminho de comandos semelhantes ao push e ao pull\n"
+" (incluindo incoming e outgoing).\n"
+"\n"
+" default-push:\n"
+" O comando push procurará por um caminho chamado 'default-push',\n"
+" e o usará ao invés de 'default' se ambos estiverem definidos.\n"
+" "
+
+msgid "Using additional features"
+msgstr "Usando funcionalidades adicionais"
+
+msgid "can only share local repositories"
+msgstr "só é possível compartilhar repositórios locais"
+
+msgid "destination already exists"
+msgstr "o destino já existe"
+
+msgid "updating working directory\n"
+msgstr "atualizando diretório de trabalho\n"
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr "diretório de destino: %s\n"
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr "o destino '%s' já existe"
+
+#, python-format
+msgid "destination '%s' is not empty"
+msgstr "o destino '%s' não está vazio"
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr ""
+"repositório de origem não suporta busca de revisões, portanto não suporta "
+"clonar por revisão"
+
+msgid "clone from remote to remote not supported"
+msgstr "clone de origem remota para destino remoto não suportado"
+
+msgid "updated"
+msgstr "atualizados"
+
+msgid "merged"
+msgstr "mesclados"
+
+msgid "removed"
+msgstr "removidos"
+
+msgid "unresolved"
+msgstr "não resolvidos"
+
+#, python-format
+msgid "%d files %s"
+msgstr "%d arquivos %s"
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr "use 'hg resolve' para mesclar novamente arquivos não resolvidos\n"
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to "
+"abandon\n"
+msgstr ""
+"use 'hg resolve' para mesclar novamente arquivos não resolvidos ou 'hg up --"
+"clean' para abandonar\n"
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr "(mesclagem de ramo, não esqueça de consolidar)\n"
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr "erro ao ler %s/.hg/hgrc: %s\n"
+
+msgid "SSL support is unavailable"
+msgstr "Suporte a SSL indisponível"
+
+msgid "IPv6 is not available on this system"
+msgstr "IPv6 indisponível nesse sistema"
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr "não é possível iniciar o servidor em '%s:%d': %s"
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr "invocando gancho %s: %s\n"
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr "gancho %s inválido(\"%s\" não está em um módulo)"
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr "gancho %s é inválido (falhou o import de \"%s\")"
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr "gancho %s é inválido (\"%s\" não definido)"
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr "gancho %s é inválido (\"%s\" não é executável)"
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr "erro: gancho %s falhou: %s\n"
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr "erro: gancho %s lançou uma exceção: %s\n"
+
+#, python-format
+msgid "%s hook failed"
+msgstr "gancho %s falhou"
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr "aviso: gancho %s falhou\n"
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr "executando gancho %s: %s\n"
+
+#, python-format
+msgid "%s hook %s"
+msgstr "gancho %s %s"
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr "aviso: gancho %s %s\n"
+
+msgid "connection ended unexpectedly"
+msgstr "conexão terminou inesperadamente"
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr "componente de URL não suportado: \"%s\""
+
+#, python-format
+msgid "using %s\n"
+msgstr "usando %s\n"
+
+#, python-format
+msgid "capabilities: %s\n"
+msgstr "funcionalidades: %s\n"
+
+msgid "operation not supported over http"
+msgstr "operação não suportada sobre http"
+
+#, python-format
+msgid "sending %s command\n"
+msgstr "enviando comando %s\n"
+
+#, python-format
+msgid "sending %s bytes\n"
+msgstr "enviando %s bytes\n"
+
+msgid "authorization failed"
+msgstr "autorização falhou"
+
+#, python-format
+msgid "http error while sending %s command\n"
+msgstr "erro http ao enviar comando %s\n"
+
+msgid "http error, possibly caused by proxy setting"
+msgstr "erro http, possivelmente causado pela configuração de proxy"
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr "URL real é %s\n"
+
+#, python-format
+msgid "requested URL: '%s'\n"
+msgstr "URL pedida: '%s'\n"
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr "'%s' não parece ser um repositório hg"
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr "'%s' enviou um cabeçalho Content-Type inválido (%s)"
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr "'%s' usa protocolo mais novo %s"
+
+msgid "look up remote revision"
+msgstr "procurar revisão remota"
+
+msgid "unexpected response:"
+msgstr "resposta inesperada:"
+
+msgid "look up remote changes"
+msgstr "procurar mudanças remotas"
+
+msgid "push failed (unexpected response):"
+msgstr "o push falhou (resposta inesperada):"
+
+#, python-format
+msgid "push failed: %s"
+msgstr "o push falhou: %s"
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr "suporte do Python a SSL e HTTPS não está instalado"
+
+msgid "cannot create new http repository"
+msgstr "impossível criar novo repositório http"
+
+#, python-format
+msgid "%s: ignoring invalid syntax '%s'\n"
+msgstr "%s: ignorando sintaxe inválida '%s'\n"
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr "desconsiderando arquivo ignore ilegível '%s': %s\n"
+
+#, python-format
+msgid "repository %s not found"
+msgstr "repositório %s não encontrado"
+
+#, python-format
+msgid "repository %s already exists"
+msgstr "repositório %s já existe"
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr "requisito '%s' não suportado"
+
+#, python-format
+msgid ".hg/sharedpath points to nonexistent directory %s"
+msgstr ".hg/sharedpath aponta para diretório %s inexistente"
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr "%r não pode ser usado em um nome de etiqueta"
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr ""
+"a cópia de trabalho de .hgtags foi modificada (por favor consolide .hgtags "
+"manualmente)"
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr "%s, linha %s: %s\n"
+
+msgid "cannot parse entry"
+msgstr "não é possível decodificar entrada"
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr "nó '%s' não é bem formado"
+
+#, python-format
+msgid "working directory has unknown parent '%s'!"
+msgstr "diretório de trabalho tem pai desconhecido '%s'!"
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr "revisão desconhecida '%s'"
+
+#, python-format
+msgid "filtering %s through %s\n"
+msgstr "filtrando %s através de %s\n"
+
+msgid "journal already exists - run hg recover"
+msgstr "journal já existe - execute hg recover"
+
+msgid "rolling back interrupted transaction\n"
+msgstr "desfazendo transação interrompida\n"
+
+msgid "no interrupted transaction available\n"
+msgstr "nenhuma transação interrompida disponível\n"
+
+msgid "rolling back last transaction\n"
+msgstr "desfazendo última transação\n"
+
+#, python-format
+msgid "Named branch could not be reset, current branch still is: %s\n"
+msgstr "O ramo nomeado não pode ser redefinido, o ramo corrente ainda é: %s\n"
+
+msgid "no rollback information available\n"
+msgstr "nenhuma informação de desfazimento disponível\n"
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr "esperando pelo bloqueio em %s feito por %r\n"
+
+#, python-format
+msgid "repository %s"
+msgstr "repositório %s"
+
+#, python-format
+msgid "working directory of %s"
+msgstr "diretório de trabalho de %s"
+
+#, python-format
+msgid " %s: searching for copy revision for %s\n"
+msgstr " %s: procurando por revisão de cópia para %s\n"
+
+#, python-format
+msgid " %s: copy %s:%s\n"
+msgstr " %s: cópia %s:%s\n"
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr ""
+"não é possível consolidar parcialmente uma mesclagem (não especifique "
+"arquivos ou padrões)"
+
+msgid "file not found!"
+msgstr "arquivo não encontrado!"
+
+msgid "no match under directory!"
+msgstr "nenhuma correspondência sob o diretório!"
+
+msgid "file not tracked!"
+msgstr "arquivo não rastreado!"
+
+msgid "unresolved merge conflicts (see hg resolve)"
+msgstr "conflitos de mesclagem não resolvidos (veja hg resolve)"
+
+#, python-format
+msgid "committing subrepository %s\n"
+msgstr "consolidando sub-repositório %s\n"
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr "problemas ao consolidar %s!\n"
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr "%s não existe!\n"
+
+#, python-format
+msgid ""
+"%s: files over 10MB may cause memory and performance problems\n"
+"(use 'hg revert %s' to unadd the file)\n"
+msgstr ""
+"%s: arquivos acima de 10MB podem causar problemas de memória e desempenho\n"
+"(use 'hg revert %s' para reverter a adição do arquivo)\n"
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr "%s não adicionado: apenas arquivos e links simbólicos suportados no momento\n"
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr "%s já rastreado!\n"
+
+#, python-format
+msgid "%s not added!\n"
+msgstr "%s não adicionado!\n"
+
+#, python-format
+msgid "%s still exists!\n"
+msgstr "%s ainda existe!\n"
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr "%s não rastreado!\n"
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr "%s não removido!\n"
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr "cópia falhou: %s não é um arquivo ou um link simbólico\n"
+
+msgid "searching for changes\n"
+msgstr "procurando por mudanças\n"
+
+#, python-format
+msgid "examining %s:%s\n"
+msgstr "examinando %s:%s\n"
+
+msgid "branch already found\n"
+msgstr "ramo já encontrado\n"
+
+#, python-format
+msgid "found incomplete branch %s:%s\n"
+msgstr "encontrado ramo incompleto %s:%s\n"
+
+#, python-format
+msgid "found new changeset %s\n"
+msgstr "encontrado novo changeset %s\n"
+
+#, python-format
+msgid "request %d: %s\n"
+msgstr "pedido %d: %s\n"
+
+#, python-format
+msgid "received %s:%s\n"
+msgstr "recebido %s:%s\n"
+
+#, python-format
+msgid "narrowing %d:%d %s\n"
+msgstr "estreitando %d:%d %s\n"
+
+#, python-format
+msgid "found new branch changeset %s\n"
+msgstr "encontrado novo changeset de ramo %s\n"
+
+#, python-format
+msgid "narrowed branch search to %s:%s\n"
+msgstr "estreitou a busca de ramos para %s:%s\n"
+
+msgid "already have changeset "
+msgstr "já possui o changeset "
+
+msgid "warning: repository is unrelated\n"
+msgstr "aviso: repositório não é relacionado\n"
+
+msgid "repository is unrelated"
+msgstr "repositório não é relacionado"
+
+msgid "found new changesets starting at "
+msgstr "encontrados novos changesets com início em "
+
+#, python-format
+msgid "%d total queries\n"
+msgstr "%d consultas no total\n"
+
+msgid "common changesets up to "
+msgstr "changesets comuns até "
+
+msgid "requesting all changes\n"
+msgstr "pedindo todas as mudanças\n"
+
+msgid ""
+"Partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr ""
+"Pull parcial não pode ser feito porque o outro repositório não suporta "
+"'changegroupsubset'."
+
+#, python-format
+msgid "abort: push creates new remote branch '%s'!\n"
+msgstr "abortado: push cria novo ramo remoto '%s'!\n"
+
+msgid "abort: push creates new remote heads!\n"
+msgstr "abortado: push cria novas cabeças remotas!\n"
+
+msgid "(did you forget to merge? use push -f to force)\n"
+msgstr "(você esqueceu de mesclar? Use push -f para forçar)\n"
+
+msgid "note: unsynced remote changes!\n"
+msgstr "aviso: mudanças remotas não sincronizadas!\n"
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr "%d changesets encontrados\n"
+
+msgid "list of changesets:\n"
+msgstr "lista de changesets:\n"
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr "revlog vazio ou não encontrado para %s"
+
+#, python-format
+msgid "add changeset %s\n"
+msgstr "adicionando changeset %s\n"
+
+msgid "adding changesets\n"
+msgstr "adicionando changesets\n"
+
+msgid "received changelog group is empty"
+msgstr "grupo de changelogs recebido é vazio"
+
+msgid "adding manifests\n"
+msgstr "adicionando manifestos\n"
+
+msgid "adding file changes\n"
+msgstr "adicionando mudanças em arquivos\n"
+
+#, python-format
+msgid "adding %s revisions\n"
+msgstr "adicionando %s revisões\n"
+
+msgid "received file revlog group is empty"
+msgstr "grupo recebido de arquivos revlog vazio"
+
+#, python-format
+msgid " (%+d heads)"
+msgstr " (%+d cabeças)"
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr "adicionados %d changesets com %d mudanças em %d arquivos%s\n"
+
+msgid "updating the branch cache\n"
+msgstr "atualizando o cache de ramos\n"
+
+msgid "Unexpected response from remote server:"
+msgstr "Resposta inesperada do servidor remoto:"
+
+msgid "operation forbidden by server"
+msgstr "operação não permitida pelo servidor"
+
+msgid "locking the remote repository failed"
+msgstr "o bloqueio do repositório remoto falhou"
+
+msgid "the server sent an unknown error code"
+msgstr "o servidor enviou um código de erro desconhecido"
+
+msgid "streaming all changes\n"
+msgstr "encadeando todas as mudanças\n"
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr "%d arquivos para transferir, %s de dados\n"
+
+#, python-format
+msgid "adding %s (%s)\n"
+msgstr "adicionando %s (%s)\n"
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr "transferidos %s em %.1f segundos (%s/s)\n"
+
+msgid "no [smtp]host in hgrc - cannot send mail"
+msgstr "nenhum servidor smtp ('host' em '[smtp]') no hgrc - impossível enviar e-mail"
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr "enviando e-mail: servidor smtp %s, porta %s\n"
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr "impossível usar TLS: suporte Python a SSL não instalado"
+
+msgid "(using tls)\n"
+msgstr "(usando tls)\n"
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr "(autenticando com o servidor de e-mail como %s)\n"
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr "enviando e-mail: %s\n"
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr ""
+"smtp especificado como transporte de e-mail, mas o servidor smtp não foi "
+"configurado"
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr "%r especificado como um transporte de e-mail, mas não encontrado no PATH"
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr "ignorando sendcharset inválido: %s\n"
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr "endereço de e-mail inválido: %s"
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr "endereço local inválido: %s"
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr "falha ao remover %s do manifesto"
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr "o número de linhas de contexto de diff deve ser um inteiro, e não %r"
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr ""
+"arquivo não versionado no diretório de trabalho difere do arquivo na revisão "
+"pedida: '%s'"
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr "conflito de maiúsculas e minúsculas entre %s e %s"
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+" modo conflitante para %s\n"
+"(n)enhum, e(x)ecutável ou (l)ink simbólico?"
+
+msgid "&None"
+msgstr "&Nenhum"
+
+msgid "E&xec"
+msgstr "E&xecutável"
+
+msgid "Sym&link"
+msgstr "&Link simbólico"
+
+msgid "resolving manifests\n"
+msgstr "examinando manifestos\n"
+
+#, python-format
+msgid " overwrite %s partial %s\n"
+msgstr " sobrescrito %s parcial %s\n"
+
+#, python-format
+msgid " ancestor %s local %s remote %s\n"
+msgstr " ancestral %s local %s remoto %s\n"
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+" local alterou %s, que a remota removeu\n"
+"use (c) a versão alterada, ou (d) apague?"
+
+msgid "&Changed"
+msgstr "(&C) alterada"
+
+msgid "&Delete"
+msgstr "(&D) apagar"
+
+msgid "c"
+msgstr "c"
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+"remota mudou %s, apagada pela local\n"
+"use (c) a versão alterada, ou (d) deixe apagada?"
+
+msgid "&Deleted"
+msgstr "(&D) apagada"
+
+#, python-format
+msgid "preserving %s for resolve of %s\n"
+msgstr "preservando %s para resolução de %s\n"
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr "update falhou ao remover %s: %s!\n"
+
+#, python-format
+msgid "getting %s\n"
+msgstr "obtendo %s\n"
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr "obtendo %s para %s\n"
+
+#, python-format
+msgid "warning: detected divergent renames of %s to:\n"
+msgstr "aviso: detectadas renomeações divergentes de %s para:\n"
+
+#, python-format
+msgid "branch %s not found"
+msgstr "ramo %s não encontrado"
+
+msgid "can't merge with ancestor"
+msgstr "não é possível mesclar com ancestral"
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr "nada para mesclar (use 'hg update' ou verifique 'hg heads')"
+
+msgid "outstanding uncommitted changes (use 'hg status' to list changes)"
+msgstr ""
+"alterações não consolidadas pendentes (use 'hg status' para listar as "
+"mudanças)"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C' to discard changes)"
+msgstr "atravessa ramos (use 'hg merge', ou 'hg update -C' para descartar mudanças)"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C')"
+msgstr "atravessa ramos (use 'hg merge' ou 'hg update -C')"
+
+msgid "crosses named branches (use 'hg update -C' to discard changes)"
+msgstr "atravessa ramos nomeados (use 'hg update -C' para descartar mudanças)"
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr "impossível criar %s: destino já existe"
+
+#, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr "impossível criar %s: impossível criar diretório de destino"
+
+#, python-format
+msgid "found patch at byte %d\n"
+msgstr "encontrado patch no byte %d\n"
+
+msgid "patch generated by hg export\n"
+msgstr "patch criado por hg export\n"
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr "incapaz de localizar '%s' para modificação\n"
+
+#, python-format
+msgid "patching file %s\n"
+msgstr "modificando arquivo %s\n"
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr "%d de %d trechos FALHARAM -- gravando rejeitados no arquivo %s\n"
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr "trecho ruim #%d %s (%d %d %d %d)"
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr "arquivo %s já existe\n"
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d line).\n"
+msgstr "Trecho #%d aplicado com sucesso em %d %s(distância %d linha).\n"
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d lines).\n"
+msgstr "Trecho #%d aplicado com sucesso em %d %s(distância %d linhas).\n"
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr "Trecho #%d FALHOU em %d\n"
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr "trecho ruim #%d"
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr "trecho ruim #%d antiga linha de texto %d"
+
+msgid "could not extract binary patch"
+msgstr "não foi possível extrair o patch binário"
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr "patch binário tem %d bytes, e não %d"
+
+#, python-format
+msgid "unable to strip away %d dirs from %s"
+msgstr "impossível remover %d diretórios de %s"
+
+msgid "undefined source and destination files"
+msgstr "arquivos de origem e destino não definidos"
+
+#, python-format
+msgid "malformed patch %s %s"
+msgstr "patch malformado %s %s"
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr "estado do parser não suportado: %s"
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr "comando de patch falhou: %s"
+
+#, python-format
+msgid "Unsupported line endings type: %s"
+msgstr "Tipo de quebra de linha não suportado: %s"
+
+#, python-format
+msgid "no valid hunks found; trying with %r instead\n"
+msgstr "nenhum trecho válido encontrado; tentando com %r\n"
+
+#, python-format
+msgid "exited with status %d"
+msgstr "terminou com o código %d"
+
+#, python-format
+msgid "killed by signal %d"
+msgstr "morto pelo sinal %d"
+
+#, python-format
+msgid "stopped by signal %d"
+msgstr "parado pelo sinal %d"
+
+msgid "invalid exit code"
+msgstr "código de saída inválido"
+
+#, python-format
+msgid "saving bundle to %s\n"
+msgstr "salvando bundle em %s\n"
+
+msgid "adding branch\n"
+msgstr "adicionando ramo\n"
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr "impossível %s; repositório remoto não suporta a funcionalidade '%r'"
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr "tipo de compressão %r desconhecido"
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr "índice %s marcadores desconhecidos %#04x para o formato v0"
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr "índice %s marcadores desconhecidos %#04x para o revlogng"
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr "índice %s formato desconhecido %d"
+
+#, python-format
+msgid "index %s is corrupted"
+msgstr "índice %s corrompido"
+
+msgid "no node"
+msgstr "nenhum nó"
+
+msgid "ambiguous identifier"
+msgstr "identificador ambíguo"
+
+msgid "no match found"
+msgstr "nenhum casamento encontrado"
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr "marcação de revisão incompatível %x"
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr "%s não encontrado na transação"
+
+msgid "unknown base"
+msgstr "base desconhecida"
+
+msgid "consistency error adding group"
+msgstr "erro de consistência adicionando grupo"
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr "%s parece um arquivo binário."
+
+msgid "can only specify two labels."
+msgstr "só pode especificar dois rótulos."
+
+msgid "warning: conflicts during merge.\n"
+msgstr "atenção: conflitos durante a mesclagem.\n"
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr "não foi possível processar localização %s"
+
+msgid "could not create remote repo"
+msgstr "não foi possível criar repositório remoto"
+
+msgid "remote: "
+msgstr "remoto: "
+
+msgid "no suitable response from remote hg"
+msgstr "nenhuma resposta adequada do hg remoto"
+
+#, python-format
+msgid "push refused: %s"
+msgstr "envio recusado: %s"
+
+msgid "unsynced changes"
+msgstr "alterações não sincronizadas"
+
+msgid "cannot lock static-http repository"
+msgstr "não é possível travar repositório http estático"
+
+msgid "cannot create new static-http repository"
+msgstr "não é possível criar novo repositório http estático"
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr "entrada inválida na fncache, linha %s"
+
+msgid "scanning\n"
+msgstr "lendo\n"
+
+#, python-format
+msgid "%d files, %d bytes to transfer\n"
+msgstr "%d arquivos, %d bytes para transferir\n"
+
+#, python-format
+msgid "sending %s (%d bytes)\n"
+msgstr "enviando %s (%d bytes)\n"
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?"
+msgstr ""
+" origens do sub-repositório para %s diferem\n"
+"usar fonte (l)ocal (%s) ou (r)emota (%s)?"
+
+msgid "&Remote"
+msgstr "&Remoto"
+
+msgid "r"
+msgstr "r"
+
+#, python-format
+msgid ""
+" local changed subrepository %s which remote removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+" local mudou sub-repositório %s, que a remota removeu\n"
+"use (c) a versão alterada, ou (d) apague?"
+
+#, python-format
+msgid ""
+" remote changed subrepository %s which local removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+" remota mudou sub-repositório %s apagado pela local\n"
+"use (c) a versão alterada ou (d) apague?"
+
+#, python-format
+msgid "removing subrepo %s\n"
+msgstr "removendo sub-repositório %s\n"
+
+#, python-format
+msgid "pulling subrepo %s\n"
+msgstr "trazendo sub-repositório %s\n"
+
+#, python-format
+msgid "pushing subrepo %s\n"
+msgstr "enviando sub-repositório %s\n"
+
+msgid "unmatched quotes"
+msgstr "aspas não combinam"
+
+#, python-format
+msgid "error expanding '%s%%%s'"
+msgstr "erro ao expandir '%s%%%s'"
+
+#, python-format
+msgid "unknown filter '%s'"
+msgstr "filtro '%s' desconhecido"
+
+#, python-format
+msgid "style not found: %s"
+msgstr "estilo não encontrado: %s"
+
+#, python-format
+msgid "template file %s: %s"
+msgstr "arquivo de modelo %s: %s"
+
+msgid "cannot use transaction when it is already committed/aborted"
+msgstr "não é possível usar transação quando já estiver consolidada/abortada"
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr "falha ao truncar %s\n"
+
+msgid "transaction abort!\n"
+msgstr "transação abortada!\n"
+
+msgid "rollback completed\n"
+msgstr "desfazer completo\n"
+
+msgid "rollback failed - please run hg recover\n"
+msgstr "rollback falhou - por favor execute hg recover\n"
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr "Não confiando em arquivo %s de usuário não confiável %s, grupo %s\n"
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr "Ignorado: %s\n"
+
+#, python-format
+msgid "ignoring untrusted configuration option %s.%s = %s\n"
+msgstr "ignorando opção de configuração não confiável %s.%s = %s\n"
+
+#, python-format
+msgid "%s.%s not a boolean ('%s')"
+msgstr "%s.%s não é uma booleana ('%s')"
+
+msgid "enter a commit username:"
+msgstr "entre o nome do usuário para consolidação:"
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr "Nome de usuário não encontrado, usando '%s'\n"
+
+msgid "Please specify a username."
+msgstr "Por favor, especifique um nome de usuário."
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr "nome de usuário %s contém quebra de linha\n"
+
+msgid "unrecognized response\n"
+msgstr "resposta desconhecida\n"
+
+msgid "response expected"
+msgstr "resposta esperada"
+
+msgid "password: "
+msgstr "senha: "
+
+msgid "edit failed"
+msgstr "falha ao editar"
+
+msgid "http authorization required"
+msgstr "autorização http requerida"
+
+msgid "http authorization required\n"
+msgstr "autorização http requerida\n"
+
+#, python-format
+msgid "realm: %s\n"
+msgstr "domínio: %s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "usuário: %s\n"
+
+msgid "user:"
+msgstr "usuário:"
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr "autenticação http: usuário %s, senha %s\n"
+
+#, python-format
+msgid "proxying through http://%s:%s\n"
+msgstr "usando proxy através de http://%s:%s\n"
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr "falha ao executar o comando '%s' : %s"
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr "o caminho contém componente ilegais: %s"
+
+#, python-format
+msgid "path %r is inside repo %r"
+msgstr "o caminho %r está dentro do repositório %r"
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr "o caminho %r percorre o link simbólico %r"
+
+msgid "Hardlinks not supported"
+msgstr "Hardlinks não suportados"
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr "impossível criar link simbólico para %r: %s"
+
+#, python-format
+msgid "invalid date: %r "
+msgstr "data inválida: %r "
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr "data supera 32 bit: %d"
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr "fuso horário impossível: %d"
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr "especificação de dia inválida: %s"
+
+#, python-format
+msgid "%.0f GB"
+msgstr "%.0f GB"
+
+#, python-format
+msgid "%.1f GB"
+msgstr "%.1f GB"
+
+#, python-format
+msgid "%.2f GB"
+msgstr "%.2f GB"
+
+#, python-format
+msgid "%.0f MB"
+msgstr "%.0f MB"
+
+#, python-format
+msgid "%.1f MB"
+msgstr "%.1f MB"
+
+#, python-format
+msgid "%.2f MB"
+msgstr "%.2f MB"
+
+#, python-format
+msgid "%.0f KB"
+msgstr "%.0f KB"
+
+#, python-format
+msgid "%.1f KB"
+msgstr "%.1f KB"
+
+#, python-format
+msgid "%.2f KB"
+msgstr "%.2f KB"
+
+#, python-format
+msgid "%.0f bytes"
+msgstr "%.0f byte"
+
+msgid "cannot verify bundle or remote repos"
+msgstr "impossível verificar bundle ou repositório remoto"
+
+msgid "interrupted"
+msgstr "interrompido"
+
+#, python-format
+msgid "empty or missing %s"
+msgstr "%s vazio ou faltando"
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr "comprimento dos dados difere de %d bytes"
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr "índice contém %d bytes extras"
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr "aviso: `%s' usa revlog no formato 1"
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr "aviso: `%s' usa revlog no formato 0"
+
+#, python-format
+msgid "rev %d points to nonexistent changeset %d"
+msgstr "revisão %d aponta para changeset inexistente %d"
+
+#, python-format
+msgid "rev %d points to unexpected changeset %d"
+msgstr "revisão %d aponta para changeset inesperado %d"
+
+#, python-format
+msgid " (expected %s)"
+msgstr " (esperado %s)"
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr "pai 1 %s de %s desconhecido"
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr "pai 2 %s de %s desconhecido"
+
+#, python-format
+msgid "checking parents of %s"
+msgstr "checando pais de %s"
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr "revisão duplicada %d (%d)"
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr "repositório utiliza revlog no formato %d\n"
+
+msgid "checking changesets\n"
+msgstr "checando changesets\n"
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr "desempacotando changeset %s"
+
+msgid "checking manifests\n"
+msgstr "checando manifestos\n"
+
+#, python-format
+msgid "%s not in changesets"
+msgstr "%s não está em changesets"
+
+msgid "file without name in manifest"
+msgstr "arquivo sem nome no manifesto"
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr "lendo alterações no manifesto %s"
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr "checagem cruzada de arquivos no changeset e no manifesto\n"
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr "changeset se refere a manifesto desconhecido %s"
+
+msgid "in changeset but not in manifest"
+msgstr "no changeset mas não no manifesto"
+
+msgid "in manifest but not in changeset"
+msgstr "no manifesto mas não no changeset"
+
+msgid "checking files\n"
+msgstr "checando arquivos\n"
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr "impossível decodificar nome de arquivo '%s'"
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr "revlog quebrado! (%s)"
+
+msgid "missing revlog!"
+msgstr "revlog faltando!"
+
+#, python-format
+msgid "%s not in manifests"
+msgstr "%s não está no manifesto"
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr "o tamanho descompactado é %s, esperado %s"
+
+#, python-format
+msgid "unpacking %s"
+msgstr "descompactando %s"
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr "revlog de origem %s:%s vazio ou faltando"
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s\n"
+msgstr "aviso: %s@%s: revisão fonte da cópia é nullid %s:%s\n"
+
+#, python-format
+msgid "checking rename of %s"
+msgstr "checando renomeação de %s"
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr "%s não encontrado no manifesto"
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr "atenção: revlog '%s' órfão"
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr "%d arquivos, %d changesets, %d revisões ao todo\n"
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr "%d avisos encontrados!\n"
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr "%d erros de integridade encontrados!\n"
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr "(primeiro changeset danificado parece ser %d)\n"
+
+msgid "user name not available - set USERNAME environment variable"
+msgstr "nome de usuário indisponível - defina a variável de ambiente USERNAME"
+
diff --git a/sys/src/cmd/hg/i18n/zh_CN.po b/sys/src/cmd/hg/i18n/zh_CN.po
new file mode 100644
index 000000000..81437565a
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/zh_CN.po
@@ -0,0 +1,9165 @@
+#
+# Chinese (simplified) translation for Mercurial
+# This file is distributed under the same license as Mercurial
+#
+# Copyright (C) 2009 the Mercurial team
+# Dongsheng Song <dongsheng.song@gmail.com>, 2009
+#
+# $Id: zh_CN.po 1313 2009-06-24 02:08:02Z songdongsheng@live.cn $
+#
+# Update with pot file:
+# msgmerge --update zh_CN.po hg.pot
+# msgfmt --statistics -c zh_CN.po
+#
+# Please test your translation before commit:
+# python setup.py build_py -c -d . build_ext -i build_mo
+# LC_ALL=zh_CN.UTF-8 ./hg
+#
+# Please format your translation before commit:
+# msgcat --width=80 --sort-by-file -o zh_CN_new.po zh_CN.po
+# mv -f zh_CN_new.po zh_CN.po
+#
+# Please remove '#: filename:line' lines before submit to hg:
+# msgcat --width=80 --no-location -o zh_CN_new.po zh_CN.po
+# mv -f zh_CN_new.po zh_CN.po
+#
+# Dictionary:
+# blame 追溯
+# branch 分支
+# changes 修改
+# changeset 修改集
+# checkout 检出
+# remove 移除(从版本库删除)
+# delete 删除(åªä»Žæ–‡ä»¶ç³»ç»Ÿåˆ é™¤)
+# patchset è¡¥ä¸é›†
+# pushing to 推到
+# pulling from 拉自
+# rename 改å
+# repository 版本库
+# revert æ¢å¤
+# revision 版本
+# tag 标签
+# tip 顶点
+# undo 撤销
+# unversioned 未版本控制
+# versioned å—版本控制
+# working copy 工作副本
+# ...
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial 1.3\n"
+"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
+"POT-Creation-Date: 2009-06-24 10:03+0800\n"
+"PO-Revision-Date: 2009-03-31 20:38+0200\n"
+"Last-Translator: Dongsheng Song <dongsheng.song@gmail.com>\n"
+"Language-Team: Chinese translation team <i18n-zh@googlegroups.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-Country: CHINA\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (默认: %s)"
+
+msgid "OPTIONS"
+msgstr "选项"
+
+msgid "COMMANDS"
+msgstr "命令"
+
+msgid " options:\n"
+msgstr " 选项:\n"
+
+#, python-format
+msgid ""
+" aliases: %s\n"
+"\n"
+msgstr ""
+" 别å: %s\n"
+"\n"
+
+msgid ""
+"control access to a repository using simple hooks\n"
+"\n"
+"This hook makes it possible to allow or deny write access to portions\n"
+"of a repository when receiving incoming changesets.\n"
+"\n"
+"The authorization is matched based on the local user name on the\n"
+"system where the hook runs, and not the committer of the original\n"
+"changeset (since the latter is merely informative).\n"
+"\n"
+"The acl hook is best used along with a restricted shell like hgsh,\n"
+"preventing authenticating users from doing anything other than\n"
+"pushing or pulling. The hook is not safe to use if users have\n"
+"interactive shell access, as they can then disable the hook.\n"
+"Nor is it safe if remote users share an account, because then there\n"
+"is no way to distinguish them.\n"
+"\n"
+"To use this hook, configure the acl extension in your hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.acl =\n"
+"\n"
+" [hooks]\n"
+" pretxnchangegroup.acl = python:hgext.acl.hook\n"
+"\n"
+" [acl]\n"
+" # Check whether the source of incoming changes is in this list\n"
+" # (\"serve\" == ssh or http, \"push\", \"pull\", \"bundle\")\n"
+" sources = serve\n"
+"\n"
+"The allow and deny sections take a subtree pattern as key (with a\n"
+"glob syntax by default), and a comma separated list of users as\n"
+"the corresponding value. The deny list is checked before the allow\n"
+"list is.\n"
+"\n"
+" [acl.allow]\n"
+" # If acl.allow is not present, all users are allowed by default.\n"
+" # An empty acl.allow section means no users allowed.\n"
+" docs/** = doc_writer\n"
+" .hgtags = release_engineer\n"
+"\n"
+" [acl.deny]\n"
+" # If acl.deny is not present, no users are refused by default.\n"
+" # An empty acl.deny section means all users allowed.\n"
+" glob pattern = user4, user5\n"
+" ** = user6\n"
+msgstr ""
+
+#, python-format
+msgid "acl: %s not enabled\n"
+msgstr "acl: 未å¯ç”¨ %s\n"
+
+#, python-format
+msgid "acl: %s enabled, %d entries for user %s\n"
+msgstr "acl: å·²å¯ç”¨ %s, %d 项,用户 %s\n"
+
+#, python-format
+msgid "config error - hook type \"%s\" cannot stop incoming changesets"
+msgstr "é…置错误 - é’©å­ç±»åž‹ \"%s\" ä¸èƒ½ç»ˆæ­¢è¿›å…¥çš„修改集"
+
+#, python-format
+msgid "acl: changes have source \"%s\" - skipping\n"
+msgstr "acl: æ”¹å˜æº \"%s\" - 跳过\n"
+
+#, python-format
+msgid "acl: user %s denied on %s\n"
+msgstr "acl: 用户 %s 被拒ç»è®¿é—® %s\n"
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr "acl: æ‹’ç»è®¿é—®ä¿®æ”¹é›† %s"
+
+#, python-format
+msgid "acl: user %s not allowed on %s\n"
+msgstr "acl: 用户 %s 被拒ç»è®¿é—® %s\n"
+
+#, python-format
+msgid "acl: allowing changeset %s\n"
+msgstr "acl: å…许修改集 %s\n"
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+"Bookmarks are local movable markers to changesets. Every bookmark\n"
+"points to a changeset identified by its hash. If you commit a\n"
+"changeset that is based on a changeset that has a bookmark on it,\n"
+"the bookmark shifts to the new changeset.\n"
+"\n"
+"It is possible to use bookmark names in every revision lookup\n"
+"(e.g. hg merge, hg update).\n"
+"\n"
+"By default, when several bookmarks point to the same changeset, they\n"
+"will all move forward together. It is possible to obtain a more\n"
+"git-like experience by adding the following configuration option to\n"
+"your .hgrc:\n"
+"\n"
+" [bookmarks]\n"
+" track.current = True\n"
+"\n"
+"This will cause Mercurial to track the bookmark that you are currently\n"
+"using, and only update it. This is similar to git's approach to\n"
+"branching.\n"
+msgstr ""
+
+msgid ""
+"track a line of development with movable markers\n"
+"\n"
+" Bookmarks are pointers to certain commits that move when\n"
+" committing. Bookmarks are local. They can be renamed, copied and\n"
+" deleted. It is possible to use bookmark names in 'hg merge' and\n"
+" 'hg update' to merge and update respectively to a given bookmark.\n"
+"\n"
+" You can use 'hg bookmark NAME' to set a bookmark on the working\n"
+" directory's parent revision with the given name. If you specify\n"
+" a revision using -r REV (where REV may be an existing bookmark),\n"
+" the bookmark is assigned to that revision.\n"
+" "
+msgstr ""
+
+msgid "a bookmark of this name does not exist"
+msgstr ""
+
+msgid "a bookmark of the same name already exists"
+msgstr ""
+
+msgid "new bookmark name required"
+msgstr ""
+
+msgid "bookmark name required"
+msgstr ""
+
+msgid "bookmark name cannot contain newlines"
+msgstr ""
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr ""
+
+msgid "force"
+msgstr "强制"
+
+msgid "revision"
+msgstr "版本"
+
+msgid "delete a given bookmark"
+msgstr "删除指定书签"
+
+msgid "rename a given bookmark"
+msgstr "æ”¹åæŒ‡å®šä¹¦ç­¾"
+
+msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
+msgstr ""
+
+msgid ""
+"integrate Mercurial with a Bugzilla bug tracker\n"
+"\n"
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
+"bug status.\n"
+"\n"
+"The hook updates the Bugzilla database directly. Only Bugzilla\n"
+"installations using MySQL are supported.\n"
+"\n"
+"The hook relies on a Bugzilla script to send bug change notification\n"
+"emails. That script changes between Bugzilla versions; the\n"
+"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
+"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
+"be run by Mercurial as the user pushing the change; you will need to\n"
+"ensure the Bugzilla install file permissions are set appropriately.\n"
+"\n"
+"Configuring the extension:\n"
+"\n"
+" [bugzilla]\n"
+"\n"
+" host Hostname of the MySQL server holding the Bugzilla\n"
+" database.\n"
+" db Name of the Bugzilla database in MySQL. Default 'bugs'.\n"
+" user Username to use to access MySQL server. Default 'bugs'.\n"
+" password Password to use to access MySQL server.\n"
+" timeout Database connection timeout (seconds). Default 5.\n"
+" version Bugzilla version. Specify '3.0' for Bugzilla versions\n"
+" 3.0 and later, '2.18' for Bugzilla versions from 2.18\n"
+" and '2.16' for versions prior to 2.18.\n"
+" bzuser Fallback Bugzilla user name to record comments with, if\n"
+" changeset committer cannot be found as a Bugzilla user.\n"
+" bzdir Bugzilla install directory. Used by default notify.\n"
+" Default '/var/www/html/bugzilla'.\n"
+" notify The command to run to get Bugzilla to send bug change\n"
+" notification emails. Substitutes from a map with 3\n"
+" keys, 'bzdir', 'id' (bug id) and 'user' (committer\n"
+" bugzilla email). Default depends on version; from 2.18\n"
+" it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
+" %(id)s %(user)s\".\n"
+" regexp Regular expression to match bug IDs in changeset commit\n"
+" message. Must contain one \"()\" group. The default\n"
+" expression matches 'Bug 1234', 'Bug no. 1234', 'Bug\n"
+" number 1234', 'Bugs 1234,5678', 'Bug 1234 and 5678' and\n"
+" variations thereof. Matching is case insensitive.\n"
+" style The style file to use when formatting comments.\n"
+" template Template to use when formatting comments. Overrides\n"
+" style if specified. In addition to the usual Mercurial\n"
+" keywords, the extension specifies:\n"
+" {bug} The Bugzilla bug ID.\n"
+" {root} The full pathname of the Mercurial\n"
+" repository.\n"
+" {webroot} Stripped pathname of the Mercurial\n"
+" repository.\n"
+" {hgweb} Base URL for browsing Mercurial\n"
+" repositories.\n"
+" Default 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip The number of slashes to strip from the front of {root}\n"
+" to produce {webroot}. Default 0.\n"
+" usermap Path of file containing Mercurial committer ID to\n"
+" Bugzilla user ID mappings. If specified, the file\n"
+" should contain one mapping per line,\n"
+" \"committer\"=\"Bugzilla user\". See also the [usermap]\n"
+" section.\n"
+"\n"
+" [usermap]\n"
+" Any entries in this section specify mappings of Mercurial\n"
+" committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl Base URL for browsing Mercurial repositories. Reference\n"
+" from templates as {hgweb}.\n"
+"\n"
+"Activating the extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # run bugzilla hook on every change pulled or pushed in here\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Example configuration:\n"
+"\n"
+"This example configuration is for a collection of Mercurial\n"
+"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
+"installation in /opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Commits add a comment to the Bugzilla bug record of the form:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr "连接到 %s:%s as %sï¼Œå¯†ç  %s\n"
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr "查询: %s %s\n"
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr "查询失败: %s %s\n"
+
+msgid "unknown database schema"
+msgstr "未知的数æ®åº“方案"
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr ""
+
+msgid "telling bugzilla to send mail:\n"
+msgstr ""
+
+#, python-format
+msgid " bug %s\n"
+msgstr ""
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr ""
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr ""
+
+msgid "done\n"
+msgstr "完æˆ\n"
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr ""
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr ""
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr ""
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr ""
+
+#, python-format
+msgid "database error: %s"
+msgstr ""
+
+#, fuzzy
+msgid "display children changesets"
+msgstr "列出修改集"
+
+#, fuzzy
+msgid ""
+"show the children of the given or working directory revision\n"
+"\n"
+" Print the children of the working directory's revisions. If a\n"
+" revision is given via -r/--rev, the children of that revision will\n"
+" be printed. If a file argument is given, revision in which the\n"
+" file was last changed (after the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"显示工作目录或指定版本的父亲\n"
+"\n"
+" 显示工作目录的父亲版本。如果使用 '--rev' 指定版本,就显示此版本的\n"
+" 父亲。如果指定了文件,那么使用此文件最åŽä¿®æ”¹çš„版本(工作目录的起æº\n"
+" 版本,或 '--rev' 指定的版本)。\n"
+" "
+
+#, fuzzy
+msgid "show children of the specified revision"
+msgstr "从指定的版本显示父亲"
+
+msgid "hg children [-r REV] [FILE]"
+msgstr ""
+
+msgid "display statistics about repository history"
+msgstr ""
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr ""
+
+#, python-format
+msgid "generating stats: %d%%"
+msgstr ""
+
+msgid ""
+"histogram of changes to the repository\n"
+"\n"
+" This command will display a histogram representing the number\n"
+" of changed lines or revisions, grouped according to the given\n"
+" template. The default template will group changes by author.\n"
+" The --dateformat option may be used to group the results by\n"
+" date instead.\n"
+"\n"
+" Statistics are based on the number of changed lines, or\n"
+" alternatively the number of matching revisions if the\n"
+" --changesets option is specified.\n"
+"\n"
+" Examples:\n"
+"\n"
+" # display count of changed lines for every committer\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # display daily activity graph\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # display activity of developers by month\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # display count of lines changed in every year\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" It is possible to map alternate email addresses to a main address\n"
+" by providing a file using the following format:\n"
+"\n"
+" <alias email> <actual email>\n"
+"\n"
+" Such a file may be specified with the --aliases option, otherwise a\n"
+" .hgchurn file will be looked for in the working directory root.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "assuming %i character terminal\n"
+msgstr ""
+
+msgid "count rate for the specified revision or range"
+msgstr ""
+
+#, fuzzy
+msgid "count rate for revisions matching date spec"
+msgstr "æ˜¾ç¤ºåŒ¹é…æ—¥æœŸçš„版本"
+
+msgid "template to group changesets"
+msgstr ""
+
+msgid "strftime-compatible format for grouping by date"
+msgstr ""
+
+msgid "count rate by number of changesets"
+msgstr ""
+
+msgid "sort by key (default: sort by count)"
+msgstr ""
+
+msgid "file with email aliases"
+msgstr ""
+
+msgid "show progress"
+msgstr ""
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+msgstr ""
+
+msgid ""
+"colorize output from some commands\n"
+"\n"
+"This extension modifies the status command to add color to its output\n"
+"to reflect file status, the qseries command to add color to reflect\n"
+"patch status (applied, unapplied, missing), and to diff-related\n"
+"commands to highlight additions, removals, diff headers, and trailing\n"
+"whitespace.\n"
+"\n"
+"Other effects in addition to color, like bold and underlined text, are\n"
+"also available. Effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes). This module also provides the\n"
+"render_text function, which can be used to add effects to any text.\n"
+"\n"
+"Default effects may be overridden from the .hgrc file:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' turns off all effects\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+msgstr ""
+
+msgid "when to colorize (always, auto, or never)"
+msgstr ""
+
+msgid "don't colorize output"
+msgstr ""
+
+msgid "import from foreign VCS repositories into Mercurial"
+msgstr ""
+
+msgid ""
+"convert a foreign SCM repository to a Mercurial one.\n"
+"\n"
+" Accepted source formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Accepted destination formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (history on branches is not preserved)\n"
+"\n"
+" If no revision is given, all revisions will be converted.\n"
+" Otherwise, convert will only import up to the named revision\n"
+" (given in a format understood by the source).\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source with '-hg' appended. If the destination\n"
+" repository doesn't exist, it will be created.\n"
+"\n"
+" By default, all sources except Mercurial will use\n"
+" --branchsort. Mercurial uses --sourcesort to preserve original\n"
+" revision numbers order. Sort modes have the following effects:\n"
+" --branchsort: convert from parent to child revision when\n"
+" possible, which means branches are usually converted one after\n"
+" the other. It generates more compact repositories.\n"
+" --datesort: sort revisions by date. Converted repositories have\n"
+" good-looking changelogs but are often an order of magnitude\n"
+" larger than the same ones generated by --branchsort.\n"
+" --sourcesort: try to preserve source revisions order, only\n"
+" supported by Mercurial sources.\n"
+"\n"
+" If <REVMAP> isn't given, it will be put in a default location\n"
+" (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file\n"
+" that maps each source commit ID to the destination ID for that\n"
+" revision, like so:\n"
+" <source ID> <destination ID>\n"
+"\n"
+" If the file doesn't exist, it's automatically created. It's\n"
+" updated on each commit copied, so convert-repo can be interrupted\n"
+" and can be run repeatedly to copy new commits.\n"
+"\n"
+" The [username mapping] file is a simple text file that maps each\n"
+" source commit author to a destination commit author. It is handy\n"
+" for source SCMs that use unix logins to identify authors (eg:\n"
+" CVS). One line per author mapping and the line format is:\n"
+" srcauthor=whatever string you want\n"
+"\n"
+" The filemap is a file that allows filtering and remapping of files\n"
+" and directories. Comment lines start with '#'. Each line can\n"
+" contain one of the following directives:\n"
+"\n"
+" include path/to/file\n"
+"\n"
+" exclude path/to/file\n"
+"\n"
+" rename from/file to/file\n"
+"\n"
+" The 'include' directive causes a file, or all files under a\n"
+" directory, to be included in the destination repository, and the\n"
+" exclusion of all other files and directories not explicitly included.\n"
+" The 'exclude' directive causes files or directories to be omitted.\n"
+" The 'rename' directive renames a file or directory. To rename from\n"
+" a subdirectory into the root of the repository, use '.' as the\n"
+" path to rename to.\n"
+"\n"
+" The splicemap is a file that allows insertion of synthetic\n"
+" history, letting you specify the parents of a revision. This is\n"
+" useful if you want to e.g. give a Subversion merge two parents, or\n"
+" graft two disconnected series of history together. Each entry\n"
+" contains a key, followed by a space, followed by one or two\n"
+" comma-separated values. The key is the revision ID in the source\n"
+" revision control system whose parents should be modified (same\n"
+" format as a key in .hg/shamap). The values are the revision IDs\n"
+" (in either the source or destination revision control system) that\n"
+" should be used as the new parents for that node.\n"
+"\n"
+" The branchmap is a file that allows you to rename a branch when it is\n"
+" being brought in from whatever external repository. When used in\n"
+" conjunction with a splicemap, it allows for a powerful combination\n"
+" to help fix even the most badly mismanaged repositories and turn them\n"
+" into nicely structured Mercurial repositories. The branchmap contains\n"
+" lines of the form \"original_branch_name new_branch_name\".\n"
+" \"original_branch_name\" is the name of the branch in the source\n"
+" repository, and \"new_branch_name\" is the name of the branch is the\n"
+" destination repository. This can be used to (for instance) move code\n"
+" in one repository from \"default\" to a named branch.\n"
+"\n"
+" Mercurial Source\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (boolean)\n"
+" ignore integrity errors when reading. Use it to fix Mercurial\n"
+" repositories with missing revlogs, by converting from and to\n"
+" Mercurial.\n"
+" --config convert.hg.saverev=False (boolean)\n"
+" store original revision ID in changeset (forces target IDs to\n"
+" change)\n"
+" --config convert.hg.startrev=0 (hg revision identifier)\n"
+" convert start revision and its descendants\n"
+"\n"
+" CVS Source\n"
+" ----------\n"
+"\n"
+" CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+" to indicate the starting point of what will be converted. Direct\n"
+" access to the repository files is not needed, unless of course the\n"
+" repository is :local:. The conversion uses the top level directory\n"
+" in the sandbox to find the CVS repository, and then uses CVS rlog\n"
+" commands to find files to convert. This means that unless a\n"
+" filemap is given, all files under the starting directory will be\n"
+" converted, and that any directory reorganization in the CVS\n"
+" sandbox is ignored.\n"
+"\n"
+" Because CVS does not have changesets, it is necessary to collect\n"
+" individual commits to CVS and merge them into changesets. CVS\n"
+" source uses its internal changeset merging code by default but can\n"
+" be configured to call the external 'cvsps' program by setting:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" This option is deprecated and will be removed in Mercurial 1.4.\n"
+"\n"
+" The options shown are the defaults.\n"
+"\n"
+" Internal cvsps is selected by setting\n"
+" --config convert.cvsps=builtin\n"
+" and has a few more configurable options:\n"
+" --config convert.cvsps.cache=True (boolean)\n"
+" Set to False to disable remote log caching, for testing and\n"
+" debugging purposes.\n"
+" --config convert.cvsps.fuzz=60 (integer)\n"
+" Specify the maximum time (in seconds) that is allowed\n"
+" between commits with identical user and log message in a\n"
+" single changeset. When very large files were checked in as\n"
+" part of a changeset then the default may not be long\n"
+" enough.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will insert a dummy revision merging the branch on\n"
+" which this log message occurs to the branch indicated in\n"
+" the regex.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will add the most recent revision on the branch\n"
+" indicated in the regex as the second parent of the\n"
+" changeset.\n"
+"\n"
+" The hgext/convert/cvsps wrapper script allows the builtin\n"
+" changeset merging code to be run without doing a conversion. Its\n"
+" parameters and output are similar to that of cvsps 2.1.\n"
+"\n"
+" Subversion Source\n"
+" -----------------\n"
+"\n"
+" Subversion source detects classical trunk/branches/tags layouts.\n"
+" By default, the supplied \"svn://repo/path/\" source URL is\n"
+" converted as a single branch. If \"svn://repo/path/trunk\" exists it\n"
+" replaces the default branch. If \"svn://repo/path/branches\" exists,\n"
+" its subdirectories are listed as possible branches. If\n"
+" \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
+" converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
+" can be overridden with following options. Set them to paths\n"
+" relative to the source URL, or leave them blank to disable auto\n"
+" detection.\n"
+"\n"
+" --config convert.svn.branches=branches (directory name)\n"
+" specify the directory containing branches\n"
+" --config convert.svn.tags=tags (directory name)\n"
+" specify the directory containing tags\n"
+" --config convert.svn.trunk=trunk (directory name)\n"
+" specify the name of the trunk branch\n"
+"\n"
+" Source history can be retrieved starting at a specific revision,\n"
+" instead of being integrally converted. Only single branch\n"
+" conversions are supported.\n"
+"\n"
+" --config convert.svn.startrev=0 (svn revision number)\n"
+" specify start Subversion revision.\n"
+"\n"
+" Perforce Source\n"
+" ---------------\n"
+"\n"
+" The Perforce (P4) importer can be given a p4 depot path or a\n"
+" client specification as source. It will convert all files in the\n"
+" source to a flat Mercurial repository, ignoring labels, branches\n"
+" and integrations. Note that when a depot path is given you then\n"
+" usually should specify a target directory, because otherwise the\n"
+" target may be named ...-hg.\n"
+"\n"
+" It is possible to limit the amount of source history to be\n"
+" converted by specifying an initial Perforce revision.\n"
+"\n"
+" --config convert.p4.startrev=0 (perforce changelist number)\n"
+" specify initial Perforce revision.\n"
+"\n"
+"\n"
+" Mercurial Destination\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (boolean)\n"
+" dispatch source branches in separate clones.\n"
+" --config convert.hg.tagsbranch=default (branch name)\n"
+" tag revisions branch name\n"
+" --config convert.hg.usebranchnames=True (boolean)\n"
+" preserve branch names\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"create changeset information from CVS\n"
+"\n"
+" This command is intended as a debugging tool for the CVS to\n"
+" Mercurial converter, and can be used as a direct replacement for\n"
+" cvsps.\n"
+"\n"
+" Hg debugcvsps reads the CVS rlog for current directory (or any\n"
+" named directory) in the CVS repository, and converts the log to a\n"
+" series of changesets based on matching commit log entries and\n"
+" dates."
+msgstr ""
+
+msgid "username mapping filename"
+msgstr ""
+
+msgid "destination repository type"
+msgstr ""
+
+msgid "remap file names using contents of file"
+msgstr ""
+
+msgid "import up to target revision REV"
+msgstr ""
+
+msgid "source repository type"
+msgstr ""
+
+msgid "splice synthesized history into place"
+msgstr ""
+
+msgid "change branch names while converting"
+msgstr ""
+
+msgid "try to sort changesets by branches"
+msgstr ""
+
+msgid "try to sort changesets by date"
+msgstr ""
+
+msgid "preserve source changesets order"
+msgstr ""
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr ""
+
+msgid "only return changes on specified branches"
+msgstr ""
+
+msgid "prefix to remove from file names"
+msgstr ""
+
+msgid "only return changes after or between specified tags"
+msgstr ""
+
+msgid "update cvs log cache"
+msgstr ""
+
+msgid "create new cvs log cache"
+msgstr ""
+
+msgid "set commit time fuzz in seconds"
+msgstr ""
+
+msgid "specify cvsroot"
+msgstr ""
+
+msgid "show parent changesets"
+msgstr ""
+
+msgid "show current changeset in ancestor branches"
+msgstr ""
+
+msgid "ignored for compatibility"
+msgstr ""
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr ""
+
+msgid ""
+"warning: lightweight checkouts may cause conversion failures, try with a "
+"regular branch instead.\n"
+msgstr ""
+
+msgid "bzr source type could not be determined\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr ""
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr ""
+
+#, python-format
+msgid "%s.%s symlink has no target"
+msgstr ""
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr ""
+
+#, python-format
+msgid "running: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s error:\n"
+msgstr ""
+
+#, python-format
+msgid "%s %s"
+msgstr ""
+
+#, python-format
+msgid "syntax error in %s(%d): key/value pair expected"
+msgstr ""
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr ""
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr ""
+
+#, python-format
+msgid "convert: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "unknown sort mode: %s"
+msgstr "hg: 未知命令 '%s'\n"
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr ""
+
+msgid "not all revisions were sorted"
+msgstr ""
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "overriding mapping for author %s, was %s, will be %s\n"
+msgstr ""
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr ""
+
+msgid "scanning source...\n"
+msgstr ""
+
+msgid "sorting...\n"
+msgstr ""
+
+msgid "converting...\n"
+msgstr ""
+
+#, python-format
+msgid "source: %s\n"
+msgstr ""
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr ""
+
+msgid "more than one sort mode specified"
+msgstr ""
+
+msgid "--sourcesort is not supported by this data source"
+msgstr ""
+
+msgid ""
+"warning: support for external cvsps is deprecated and will be removed in "
+"Mercurial 1.4\n"
+msgstr ""
+
+#, python-format
+msgid "revision %s is not a patchset number or date"
+msgstr ""
+
+msgid "using builtin cvsps\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr ""
+
+msgid "CVS pserver authentication failed"
+msgstr ""
+
+msgid "server sucks"
+msgstr ""
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr ""
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr ""
+
+msgid "collecting CVS rlog\n"
+msgstr ""
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr ""
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr ""
+
+#, python-format
+msgid "running %s\n"
+msgstr ""
+
+#, python-format
+msgid "prefix=%r directory=%r root=%r\n"
+msgstr ""
+
+msgid "RCS file must be followed by working file"
+msgstr ""
+
+msgid "must have at least some revisions"
+msgstr ""
+
+msgid "expected revision number"
+msgstr ""
+
+msgid "revision must be followed by date line"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "found synthetic revision in %s: %r\n"
+msgstr "版本 %d 有未知路径: %s\n"
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "%d log entries\n"
+msgstr ""
+
+msgid "creating changesets\n"
+msgstr ""
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: CVS commit message references non-existent branch %r:\n"
+"%s\n"
+msgstr ""
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr ""
+
+msgid "Python ElementTree module is not available"
+msgstr ""
+
+#, python-format
+msgid "cleaning up %s\n"
+msgstr ""
+
+msgid "internal calling inconsistency"
+msgstr ""
+
+msgid "errors in filemap"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr ""
+
+msgid "source repository doesn't support --filemap"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a GNU Arch repo"
+msgstr ""
+
+msgid "cannot find a GNU Arch tool"
+msgstr ""
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr ""
+
+#, python-format
+msgid "applying revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "computing changeset between %s and %s...\n"
+msgstr ""
+
+#, python-format
+msgid "obtaining revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "analyzing revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr ""
+
+#, python-format
+msgid "%s is not a local Mercurial repo"
+msgstr "%s 䏿˜¯æœ¬åœ°çš„æ°´é“¶ç‰ˆæœ¬åº“"
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr "åˆå§‹åŒ–目标版本库 %s\n"
+
+msgid "run hg sink pre-conversion action\n"
+msgstr "执行动作 hg sink pre-conversion\n"
+
+msgid "run hg sink post-conversion action\n"
+msgstr "执行动作 hg sink post-conversion action\n"
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr "自 %s 拉到 %s\n"
+
+msgid "filtering out empty revision\n"
+msgstr ""
+
+msgid "updating tags\n"
+msgstr "正在更新标签\n"
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr "%s 䏿˜¯æœ‰æ•ˆçš„开始版本"
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr "忽略: %s\n"
+
+msgid "run hg source pre-conversion action\n"
+msgstr "执行动作 hg source pre-conversion\n"
+
+msgid "run hg source post-conversion action\n"
+msgstr "执行动作 hg source post-conversion\n"
+
+#, python-format
+msgid "%s does not look like a monotone repo"
+msgstr "%s ä¸åƒæ˜¯å•纯的 monotone 版本库"
+
+#, fuzzy, python-format
+msgid "copying file in renamed directory from '%s' to '%s'"
+msgstr "从已改å的目录 '%s' å¤åˆ¶æ–‡ä»¶åˆ° '%s'"
+
+msgid "reading p4 views\n"
+msgstr ""
+
+msgid "collecting p4 changelists\n"
+msgstr "正在æœç´¢ p4 修改集\n"
+
+msgid "Subversion python bindings could not be loaded"
+msgstr "ä¸èƒ½åŠ è½½ svn çš„ python 绑定"
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr "å‘现 svn çš„ python 绑定版本 %d.%dï¼Œéœ€è¦ 1.4 或更新的版本"
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr "svn çš„ python ç»‘å®šå¤ªæ—§ï¼Œéœ€è¦ 1.4 或更新的版本"
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr "svn: 版本 %s 䏿˜¯æ•´æ•°"
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr "svn: 开始版本 %s 䏿˜¯æ•´æ•°"
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr "æ²¡æœ‰åœ¨æ¨¡å— %s 中å‘现版本"
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr "期望 %s ä½äºŽ %r,但是没有å‘现"
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr "å‘现 %s ä½äºŽ %r\n"
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr "忽略空的分支 %s\n"
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr "å‘现分支 %s ä½äºŽ %d\n"
+
+#, fuzzy
+msgid "svn: start revision is not supported with more than one branch"
+msgstr "svn: åœ¨ç»™å‡ºå¤šäºŽä¸€ä¸ªåˆ†æ”¯æ—¶ä¸æ”¯æŒå¼€å§‹ç‰ˆæœ¬"
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr "svn: 在开始版本 %d ä¹‹åŽæ²¡æœ‰ç‰ˆæœ¬"
+
+#, python-format
+msgid "no tags found at revision %d\n"
+msgstr "在版本 %d 没有å‘现标签\n"
+
+#, python-format
+msgid "ignoring foreign branch %r\n"
+msgstr "忽略外部分支 %r\n"
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr "没有å‘现 %s,一直到版本 %d"
+
+#, python-format
+msgid "branch renamed from %s to %s at %d\n"
+msgstr "分支从 %s 改å为 %s,在 %d\n"
+
+#, python-format
+msgid "reparent to %s\n"
+msgstr ""
+
+#, python-format
+msgid "copied to %s from %s@%s\n"
+msgstr "å¤åˆ¶åˆ° %s,自 %s@%s\n"
+
+#, python-format
+msgid "gone from %s\n"
+msgstr "离开 %s\n"
+
+#, fuzzy, python-format
+msgid "entry %s\n"
+msgstr "åŸºæœ¬ï¼Œå…¥å£ %s %s\n"
+
+#, python-format
+msgid "unknown path in revision %d: %s\n"
+msgstr "版本 %d 有未知路径: %s\n"
+
+#, python-format
+msgid "mark %s came from %s:%d\n"
+msgstr "标记 %s æ¥è‡ª %s:%d\n"
+
+#, python-format
+msgid "parsing revision %d (%d changes)\n"
+msgstr "è§£æžç‰ˆæœ¬ %d (%d 个改å˜)\n"
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr "å‘现分支 %s 的父亲,在 %d: %s\n"
+
+msgid "no copyfrom path, don't know what to do.\n"
+msgstr "没有 copyfrom 路径,ä¸çŸ¥é“该怎么办。\n"
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr "为 \"%s\" 获å–版本日志,自 %d 到 %d\n"
+
+#, python-format
+msgid "revision %d has no entries\n"
+msgstr "版本 %d 没有入å£\n"
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr "svn: 分支没有版本 %s"
+
+#, python-format
+msgid "%r is not under %r, ignoring\n"
+msgstr "%r ä¸åœ¨ %r 之下,忽略之\n"
+
+#, python-format
+msgid "initializing svn repo %r\n"
+msgstr "åˆå§‹åŒ– svn 版本库 %r\n"
+
+#, python-format
+msgid "initializing svn wc %r\n"
+msgstr "åˆå§‹åŒ– svn 工作副本 %r\n"
+
+msgid "unexpected svn output:\n"
+msgstr "æ„外的 svn 输出:\n"
+
+msgid "unable to cope with svn output"
+msgstr "ä¸èƒ½å¤„ç† svn 的输出"
+
+msgid "XXX TAGS NOT IMPLEMENTED YET\n"
+msgstr ""
+
+msgid ""
+"allow external programs to compare revisions\n"
+"\n"
+"The `extdiff' Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working directory. The external diff\n"
+"programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare.\n"
+"\n"
+"The `extdiff' extension also allows to configure new diff commands, so\n"
+"you do not need to type \"hg extdiff -p kdiff3\" always.\n"
+"\n"
+" [extdiff]\n"
+" # add new command that runs GNU diff(1) in 'context diff' mode\n"
+" cdiff = gdiff -Nprc5\n"
+" ## or the old way:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # add new command called vdiff, runs kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # add new command called meld, runs meld (no need to name twice)\n"
+" meld =\n"
+"\n"
+" # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+" # (see http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Non English user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" in\n"
+" # your .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"You can use -I/-X and list of file or directory names like normal \"hg\n"
+"diff\" command. The `extdiff' extension makes snapshots of only needed\n"
+"files, so running the external diff program will actually be pretty\n"
+"fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from working directory\n"
+msgstr ""
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr "ä¸èƒ½åŒæ—¶æŒ‡å®š '--rev' å’Œ '--change'"
+
+#, python-format
+msgid "running %r in %s\n"
+msgstr ""
+
+#, python-format
+msgid "file changed while diffing. Overwriting: %s (src: %s)\n"
+msgstr ""
+
+msgid "cleaning up temp directory\n"
+msgstr ""
+
+msgid ""
+"use external program to diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files, using\n"
+" an external program. The default program used is diff, with\n"
+" default options \"-Npru\".\n"
+"\n"
+" To select a different program, use the -p/--program option. The\n"
+" program will be passed the names of two directories to compare. To\n"
+" pass additional options to the program, use -o/--option. These\n"
+" will be passed before the names of the directories to compare.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent."
+msgstr ""
+
+msgid "comparison program to run"
+msgstr ""
+
+msgid "pass option to comparison program"
+msgstr ""
+
+msgid "change made by revision"
+msgstr "此版本的修改"
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr ""
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "pull, update and merge in one command"
+msgstr ""
+
+msgid ""
+"pull changes from a remote repository, merge new changes if needed.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository.\n"
+"\n"
+" If the pulled changes add a new branch head, the head is\n"
+" automatically merged, and the result of the merge is committed.\n"
+" Otherwise, the working directory is updated to include the new\n"
+" changes.\n"
+"\n"
+" When a merge occurs, the newly pulled changes are assumed to be\n"
+" \"authoritative\". The head of the new changes is used as the first\n"
+" parent, with local changes as the second. To switch the merge\n"
+" order, use --switch-parent.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid ""
+"working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+
+msgid "outstanding uncommitted merge"
+msgstr ""
+
+msgid "outstanding uncommitted changes"
+msgstr ""
+
+msgid "working directory is missing some files"
+msgstr ""
+
+msgid ""
+"multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr "正在拉自 %s\n"
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "Automated merge with %s"
+msgstr ""
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr "新修改集 '%d:%s' 将远程修改与本地åˆå¹¶\n"
+
+msgid "a specific revision you would like to pull"
+msgstr "指定å–得的版本"
+
+msgid "edit commit message"
+msgstr "编辑æäº¤æ—¥å¿—"
+
+msgid "edit commit message (DEPRECATED)"
+msgstr "编辑æäº¤æ—¥å¿—(ä¸èµžæˆ)"
+
+msgid "switch parents when merging"
+msgstr "当åˆå¹¶æ—¶åˆ‡æ¢çˆ¶äº²"
+
+msgid "hg fetch [SOURCE]"
+msgstr ""
+
+#, fuzzy
+msgid "sign and verify changesets"
+msgstr "正在增加修改集\n"
+
+msgid "error while verifying signature"
+msgstr ""
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr ""
+
+msgid "list signed changesets"
+msgstr ""
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr ""
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr ""
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr ""
+
+msgid ""
+"add a signature for the current or given revision\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr ""
+
+msgid "Error while signing"
+msgstr ""
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+
+#, python-format
+msgid "Added signature for changeset %s"
+msgstr ""
+
+msgid "unknown signature version"
+msgstr ""
+
+msgid "make the signature local"
+msgstr ""
+
+msgid "sign even if the sigfile is modified"
+msgstr ""
+
+msgid "do not commit the sigfile after signing"
+msgstr ""
+
+msgid "the key id to sign with"
+msgstr ""
+
+msgid "commit message"
+msgstr ""
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr ""
+
+msgid "hg sigcheck REVISION"
+msgstr ""
+
+msgid "hg sigs"
+msgstr ""
+
+msgid ""
+"show revision graphs in terminals\n"
+"\n"
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ASCII representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+
+#, python-format
+msgid "--graph option is incompatible with --%s"
+msgstr ""
+
+msgid ""
+"show revision history alongside an ASCII revision graph\n"
+"\n"
+" Print a revision history alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr ""
+
+msgid "no changes found\n"
+msgstr "没有å‘现修改\n"
+
+msgid "show the revision DAG"
+msgstr "显示版本分支图"
+
+msgid "limit number of changes displayed"
+msgstr "é™åˆ¶æ˜¾ç¤ºçš„修改集数é‡"
+
+msgid "show patch"
+msgstr "显示补ä¸"
+
+msgid "show the specified revision or range"
+msgstr ""
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr ""
+
+msgid ""
+"integrate Mercurial with a CIA notification service\n"
+"\n"
+"This is meant to be run as a changegroup or incoming hook.\n"
+"To configure it, set the following options in your hgrc:\n"
+"\n"
+"[cia]\n"
+"# your registered CIA user name\n"
+"user = foo\n"
+"# the name of the project in CIA\n"
+"project = foo\n"
+"# the module (subproject) (optional)\n"
+"#module = foo\n"
+"# Append a diffstat to the log message (optional)\n"
+"#diffstat = False\n"
+"# Template to use for log messages (optional)\n"
+"#template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"# Style to use (optional)\n"
+"#style = foo\n"
+"# The URL of the CIA notification service (optional)\n"
+"# You can use mailto: URLs to send by email, eg\n"
+"# mailto:cia@cia.vc\n"
+"# Make sure to set email.from if you do this.\n"
+"#url = http://cia.vc/\n"
+"# print message instead of sending it (optional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# one of these:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# If you want hyperlinks (optional)\n"
+"baseurl = http://server/path/to/repo\n"
+msgstr ""
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr ""
+
+msgid "email.from must be defined when sending by email"
+msgstr ""
+
+msgid "cia: no user specified"
+msgstr ""
+
+msgid "cia: no project specified"
+msgstr ""
+
+msgid ""
+"browse the repository in a graphical way\n"
+"\n"
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not\n"
+"distributed with Mercurial.)\n"
+"\n"
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to Mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and the extension is shipped in the hgext\n"
+"repository, and needs to be enabled.\n"
+"\n"
+"The hg view command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can specify\n"
+"the path to hgk in your .hgrc file:\n"
+"\n"
+" [hgk]\n"
+" path=/location/of/hgk\n"
+"\n"
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions."
+msgstr ""
+
+msgid "diff trees from two commits"
+msgstr ""
+
+msgid "output common ancestor information"
+msgstr ""
+
+msgid "cat a specific revision"
+msgstr ""
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr ""
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr ""
+
+msgid "parse given revisions"
+msgstr ""
+
+msgid "print revisions"
+msgstr ""
+
+msgid "print extension options"
+msgstr ""
+
+msgid "start interactive history viewer"
+msgstr ""
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr ""
+
+msgid "generate patch"
+msgstr ""
+
+msgid "recursive"
+msgstr ""
+
+msgid "pretty"
+msgstr ""
+
+msgid "stdin"
+msgstr ""
+
+msgid "detect copies"
+msgstr ""
+
+msgid "search"
+msgstr ""
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr ""
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr ""
+
+msgid "hg debug-config"
+msgstr ""
+
+msgid "hg debug-merge-base node node"
+msgstr ""
+
+msgid "ignored"
+msgstr ""
+
+msgid "hg debug-rev-parse REV"
+msgstr ""
+
+msgid "header"
+msgstr ""
+
+msgid "topo-order"
+msgstr ""
+
+msgid "parents"
+msgstr ""
+
+msgid "max-count"
+msgstr ""
+
+msgid "hg debug-rev-list [options] revs"
+msgstr ""
+
+msgid ""
+"syntax highlighting for hgweb\n"
+"\n"
+"It depends on the Pygments syntax highlighting library:\n"
+"http://pygments.org/\n"
+"\n"
+"There is a single configuration option:\n"
+"\n"
+"[web]\n"
+"pygments_style = <style>\n"
+"\n"
+"The default is 'colorful'.\n"
+"\n"
+"-- Adam Hupp <adam@hupp.org>\n"
+msgstr ""
+
+msgid "accelerate status report using system level services"
+msgstr ""
+
+msgid "start an inotify server for this repository"
+msgstr "为此版本库å¯åЍæœåŠ¡ 'inotify'"
+
+msgid ""
+"debugging information for inotify extension\n"
+"\n"
+" Prints the list of directories being watched by the inotify server.\n"
+" "
+msgstr ""
+
+msgid "directories being watched:\n"
+msgstr ""
+
+msgid "run server in background"
+msgstr "在åŽå°è¿è¡ŒæœåŠ¡"
+
+msgid "used internally by daemon mode"
+msgstr "在åŽå°æœåŠ¡æ¨¡å¼å†…部使用"
+
+msgid "minutes to sit idle before exiting"
+msgstr "空闲几分钟åŽé€€å‡º"
+
+msgid "name of file to write process ID to"
+msgstr "写入进程标识符的文件åç§°"
+
+msgid "hg inserve [OPT]..."
+msgstr ""
+
+msgid "(found dead inotify server socket; removing it)\n"
+msgstr ""
+
+msgid "(starting inotify server)\n"
+msgstr ""
+
+#, python-format
+msgid "could not start inotify server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "could not talk to new inotify server: %s\n"
+msgstr ""
+
+msgid "(inotify server not running)\n"
+msgstr ""
+
+#, python-format
+msgid "failed to contact inotify server: %s\n"
+msgstr ""
+
+msgid "received empty answer from inotify server"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received '%s' response when expecting '%s')\n"
+msgstr ""
+
+msgid "this system does not seem to support inotify"
+msgstr ""
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr ""
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr ""
+
+msgid "*** counting directories: "
+msgstr ""
+
+#, python-format
+msgid "found %d\n"
+msgstr ""
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr ""
+
+#, python-format
+msgid "*** echo %d > %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr ""
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr ""
+
+#, python-format
+msgid "watching %r\n"
+msgstr ""
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r dir(%d) -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s dirstate reload\n"
+msgstr ""
+
+#, python-format
+msgid "%s end dirstate reload\n"
+msgstr ""
+
+msgid "rescanning due to .hgignore change\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr ""
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr ""
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr ""
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr ""
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr ""
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr ""
+
+#, python-format
+msgid "could not start server: %s"
+msgstr ""
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr ""
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr ""
+
+#, python-format
+msgid "unrecognized query type: %s\n"
+msgstr ""
+
+msgid "finished setup\n"
+msgstr ""
+
+msgid ""
+"expand expressions into changelog and summaries\n"
+"\n"
+"This extension allows the use of a special syntax in summaries,\n"
+"which will be automatically expanded into links or any other\n"
+"arbitrary expression, much like InterWiki does.\n"
+"\n"
+"A few example patterns (link to bug tracking, etc.) that may\n"
+"be used in your hgrc:\n"
+"\n"
+" [interhg]\n"
+" issues = s!issue(\\d+)!<a href=\"http://bts/issue\\1\">issue\\1</a>!\n"
+" bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2\">\\1</a>!"
+"i\n"
+" boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr ""
+
+msgid ""
+"expand keywords in tracked files\n"
+"\n"
+"This extension expands RCS/CVS-like or self-customized $Keywords$ in\n"
+"tracked text files selected by your configuration.\n"
+"\n"
+"Keywords are only expanded in local repositories and not stored in the\n"
+"change history. The mechanism can be regarded as a convenience for the\n"
+"current user or for archive distribution.\n"
+"\n"
+"Configuration is done in the [keyword] and [keywordmaps] sections of\n"
+"hgrc files.\n"
+"\n"
+"Example:\n"
+"\n"
+" [keyword]\n"
+" # expand keywords in every python file except those matching \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Note: the more specific you are in your filename patterns\n"
+" the less you lose speed in huge repositories.\n"
+"\n"
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run \"hg kwdemo\".\n"
+"\n"
+"An additional date template filter {date|utcdate} is provided.\n"
+"\n"
+"The default template mappings (view with \"hg kwdemo -d\") can be\n"
+"replaced with customized keywords and templates. Again, run \"hg\n"
+"kwdemo\" to control the results of your config changes.\n"
+"\n"
+"Before changing/disabling active keywords, run \"hg kwshrink\" to avoid\n"
+"the risk of inadvertently storing expanded keywords in the change\n"
+"history.\n"
+"\n"
+"To force expansion after enabling it, or a configuration change, run\n"
+"\"hg kwexpand\".\n"
+"\n"
+"Also, when committing with the record extension or using mq's qrecord,\n"
+"be aware that keywords cannot be updated. Again, run \"hg kwexpand\" on\n"
+"the files in question to update keyword expansions after all changes\n"
+"have been checked in.\n"
+"\n"
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map\n"
+"\"Log = {desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s expanding keywords\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s shrinking keywords\n"
+msgstr ""
+
+msgid "[keyword] patterns cannot match"
+msgstr ""
+
+msgid "no [keyword] patterns configured"
+msgstr ""
+
+msgid ""
+"print [keywordmaps] configuration and an expansion example\n"
+"\n"
+" Show current, custom, or default keyword template maps and their\n"
+" expansions.\n"
+"\n"
+" Extend current configuration by specifying maps as arguments and\n"
+" optionally by reading from an additional hgrc file.\n"
+"\n"
+" Override current keyword template maps with \"default\" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"\t%s\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "creating temporary repository at %s\n"
+msgstr ""
+"\n"
+"正在删除临时版本库 %s\n"
+
+#, python-format
+msgid ""
+"\n"
+"%s keywords written to %s:\n"
+msgstr ""
+
+msgid "unhooked all commit hooks\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid ""
+"\n"
+"removing temporary repository %s\n"
+msgstr ""
+"\n"
+"正在删除临时版本库 %s\n"
+
+msgid ""
+"expand keywords in the working directory\n"
+"\n"
+" Run after (re)enabling keyword expansion.\n"
+"\n"
+" kwexpand refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid ""
+"print files currently configured for keyword expansion\n"
+"\n"
+" Crosscheck which files in working directory are potential targets\n"
+" for keyword expansion. That is, files matched by [keyword] config\n"
+" patterns but not symlinks.\n"
+" "
+msgstr ""
+
+msgid ""
+"revert expanded keywords in the working directory\n"
+"\n"
+" Run before changing/disabling active keywords or if you experience\n"
+" problems with \"hg import\" or \"hg merge\".\n"
+"\n"
+" kwshrink refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid "show default keyword template maps"
+msgstr ""
+
+msgid "read maps from rcfile"
+msgstr ""
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr ""
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "show keyword status flags of all files"
+msgstr ""
+
+msgid "show files excluded from expansion"
+msgstr ""
+
+msgid "additionally show untracked files"
+msgstr ""
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr ""
+
+msgid ""
+"work with a stack of patches\n"
+"\n"
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches).\n"
+"\n"
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets.\n"
+"\n"
+"Common tasks (use \"hg help command\" for more details):\n"
+"\n"
+"prepare repository to work with patches qinit\n"
+"create new patch qnew\n"
+"import existing patch qimport\n"
+"\n"
+"print patch series qseries\n"
+"print applied patches qapplied\n"
+"print name of top applied patch qtop\n"
+"\n"
+"add known patch to applied stack qpush\n"
+"remove patch from applied stack qpop\n"
+"refresh contents of top applied patch qrefresh\n"
+msgstr ""
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr ""
+
+msgid "guard cannot be an empty string"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr ""
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr ""
+
+#, python-format
+msgid "active guards: %s\n"
+msgstr ""
+
+#, python-format
+msgid "guard %r too short"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr ""
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr ""
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "update returned %d"
+msgstr ""
+
+msgid "repo commit failed"
+msgstr ""
+
+#, python-format
+msgid "unable to read %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr ""
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr ""
+
+#, python-format
+msgid "applying %s\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "unable to read %s\n"
+msgstr ""
+"è§£æž '%s' 失败\n"
+"%s"
+
+#, python-format
+msgid "imported patch %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"imported patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr ""
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr ""
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr ""
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "patch %s finalized without changeset message\n"
+msgstr "åªæ˜¾ç¤ºæ— æ”¹åŠ¨æ–‡ä»¶çš„çŠ¶æ€"
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr ""
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr ""
+
+msgid "no patches applied"
+msgstr ""
+
+msgid "working directory revision is not qtip"
+msgstr ""
+
+msgid "local changes found, refresh first"
+msgstr ""
+
+msgid "local changes found"
+msgstr ""
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr ""
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr ""
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series"
+msgstr ""
+
+msgid "(working directory not at a head)\n"
+msgstr ""
+
+msgid "no patches in series\n"
+msgstr ""
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr ""
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr ""
+
+#, python-format
+msgid "guarded by %r"
+msgstr ""
+
+msgid "no matching guards"
+msgstr ""
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr ""
+
+msgid "all patches are currently applied\n"
+msgstr ""
+
+msgid "patch series already fully applied\n"
+msgstr ""
+
+msgid "cleaning up working directory..."
+msgstr ""
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr ""
+
+#, python-format
+msgid "now at: %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr ""
+
+msgid "no patches applied\n"
+msgstr ""
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr ""
+
+msgid "qpop: forcing dirstate update\n"
+msgstr ""
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr ""
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr ""
+
+msgid "deletions found between repo revs"
+msgstr ""
+
+msgid "patch queue now empty\n"
+msgstr ""
+
+msgid "cannot refresh a revision with children"
+msgstr ""
+
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to recover)\n"
+msgstr ""
+
+msgid "patch queue directory already exists"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr ""
+
+msgid "No saved patch data found\n"
+msgstr ""
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr ""
+
+msgid "save entry has children, leaving it alone\n"
+msgstr ""
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr ""
+
+msgid "queue directory updating\n"
+msgstr ""
+
+msgid "Unable to load queue repository\n"
+msgstr ""
+
+msgid "save: no patches applied, exiting\n"
+msgstr ""
+
+msgid "status is already saved\n"
+msgstr ""
+
+msgid "hg patches saved state"
+msgstr ""
+
+msgid "repo commit failed\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr ""
+
+msgid "option \"-r\" not valid when importing files"
+msgstr ""
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr ""
+
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr ""
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr ""
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr ""
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr ""
+
+msgid "-e is incompatible with import from -"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr ""
+
+msgid "need --name to import a patch from -"
+msgstr ""
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr ""
+
+msgid ""
+"remove patches from queue\n"
+"\n"
+" The patches must not be applied, and at least one patch is\n"
+" required.\n"
+"\n"
+" With -k/--keep, the patch files are preserved in the patch\n"
+" directory.\n"
+"\n"
+" To stop managing a patch and move it into permanent history,\n"
+" use the qfinish command."
+msgstr ""
+
+msgid "print the patches already applied"
+msgstr ""
+
+msgid "print the patches not yet applied"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"import a patch\n"
+"\n"
+" The patch is inserted into the series after the last applied\n"
+" patch. If no patches have been applied, qimport prepends the patch\n"
+" to the series.\n"
+"\n"
+" The patch will have the same name as its source file unless you\n"
+" give it a new one with -n/--name.\n"
+"\n"
+" You can register an existing patch inside the patch directory with\n"
+" the -e/--existing flag.\n"
+"\n"
+" With -f/--force, an existing patch of the same name will be\n"
+" overwritten.\n"
+"\n"
+" An existing changeset may be placed under mq control with -r/--rev\n"
+" (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+" With -g/--git, patches imported with --rev will use the git diff\n"
+" format. See the diffs help topic for information on why this is\n"
+" important for preserving rename/copy information and permission\n"
+" changes.\n"
+"\n"
+" To import a patch from standard input, pass - as the patch file.\n"
+" When importing from standard input, a patch name must be specified\n"
+" using the --name flag.\n"
+" "
+msgstr ""
+"导入补ä¸\n"
+"\n"
+" æ­¤è¡¥ä¸æ’入到最近一次应用的补ä¸åºåˆ—中。\n"
+" 如果尚无应用补ä¸ï¼Œqimport 会æ’入补ä¸åˆ°åºåˆ—开始。\n"
+"\n"
+" 除éžä½ ä½¿ç”¨ '--name' 给出补ä¸å称,å¦åˆ™å°±ä¸Žæºæ–‡ä»¶åŒå。\n"
+"\n"
+" ä½ å¯ä»¥ä½¿ç”¨ '--existing' 注册一个已在补ä¸ç›®å½•中的补ä¸ã€‚\n"
+"\n"
+" 使用 '--force' 会覆盖已有的补ä¸ã€‚\n"
+"\n"
+" å¯ä»¥ä½¿ç”¨ '--rev' 将已有的修改集置于 mq 控制下(例如 \n"
+" 'qimport --rev tip -n patch' 会将 tip 置于 mq 控制下)。当使用 '--git'\n"
+" 时,'--rev' 导入的补ä¸å°†ä¼šä½¿ç”¨ git 差异格å¼ã€‚å‚è§å·®å¼‚帮助主题,以了解\n"
+" 为什么这对于ä¿ç•™æ”¹å/å¤åˆ¶ä¿¡æ¯å’Œæƒé™ä¿®æ”¹å¾ˆé‡è¦ã€‚\n"
+" "
+
+#, fuzzy
+msgid ""
+"init a new queue repository\n"
+"\n"
+" The queue repository is unversioned by default. If\n"
+" -c/--create-repo is specified, qinit will create a separate nested\n"
+" repository for patches (qinit -c may also be run later to convert\n"
+" an unversioned patch repository into a versioned one). You can use\n"
+" qcommit to commit changes to this queue repository."
+msgstr ""
+"åˆå§‹åŒ–队列仓库\n"
+"\n"
+" 默认队列仓库ä¸å—版本控制。如果指定了 '-c',那么 qinit 会为补ä¸åˆ›å»ºä¸€ä¸ª\n"
+" å•独的嵌套版本库(也å¯ä»¥ç¨åŽè¿è¡Œ 'qinit -c' æ¥å°†ä¸å—版本控制的补ä¸ä»“库\n"
+" è½¬æ¢æˆå—版本控制)。你å¯ä»¥ä½¿ç”¨ 'qcommit' æäº¤æ”¹å˜åˆ°æ­¤é˜Ÿåˆ—版本库。"
+
+msgid ""
+"clone main and patch repository at same time\n"
+"\n"
+" If source is local, destination will have no patches applied. If\n"
+" source is remote, this command can not check if patches are\n"
+" applied in source, so cannot guarantee that patches are not\n"
+" applied in destination. If you clone remote repository, be sure\n"
+" before that it has no patches applied.\n"
+"\n"
+" Source patch repository is looked for in <src>/.hg/patches by\n"
+" default. Use -p <url> to change.\n"
+"\n"
+" The patch directory must be a nested Mercurial repository, as\n"
+" would be created by qinit -c.\n"
+" "
+msgstr ""
+
+msgid "versioned patch repository not found (see qinit -c)"
+msgstr ""
+
+#, fuzzy
+msgid "cloning main repository\n"
+msgstr "åˆå§‹åŒ–目标版本库 %s\n"
+
+msgid "cloning patch repository\n"
+msgstr ""
+
+#, fuzzy
+msgid "stripping applied patches from destination repository\n"
+msgstr "åˆå§‹åŒ–目标版本库 %s\n"
+
+#, fuzzy
+msgid "updating destination repository\n"
+msgstr "åˆå§‹åŒ–目标版本库 %s\n"
+
+msgid "commit changes in the queue repository"
+msgstr ""
+
+msgid "print the entire series file"
+msgstr ""
+
+msgid "print the name of the current patch"
+msgstr ""
+
+msgid "print the name of the next patch"
+msgstr ""
+
+msgid "all patches applied\n"
+msgstr ""
+
+msgid "print the name of the previous patch"
+msgstr ""
+
+msgid "only one patch applied\n"
+msgstr ""
+
+msgid ""
+"create a new patch\n"
+"\n"
+" qnew creates a new patch on top of the currently-applied patch (if\n"
+" any). It will refuse to run if there are any outstanding changes\n"
+" unless -f/--force is specified, in which case the patch will be\n"
+" initialized with them. You may also use -I/--include,\n"
+" -X/--exclude, and/or a list of files after the patch name to add\n"
+" only changes to matching files to the new patch, leaving the rest\n"
+" as uncommitted modifications.\n"
+"\n"
+" -u/--user and -d/--date can be used to set the (given) user and\n"
+" date, respectively. -U/--currentuser and -D/--currentdate set user\n"
+" to current user and date to current date.\n"
+"\n"
+" -e/--edit, -m/--message or -l/--logfile set the patch header as\n"
+" well as the commit message. If none is specified, the header is\n"
+" empty and the commit message is '[mq]: PATCH'.\n"
+"\n"
+" Use the -g/--git option to keep the patch in the git extended diff\n"
+" format. Read the diffs help topic for more information on why this\n"
+" is important for preserving permission changes and copy/rename\n"
+" information.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"update the current patch\n"
+"\n"
+" If any file patterns are provided, the refreshed patch will\n"
+" contain only the modifications that match those patterns; the\n"
+" remaining modifications will remain in the working directory.\n"
+"\n"
+" If -s/--short is specified, files currently included in the patch\n"
+" will be refreshed just like matched files and remain in the patch.\n"
+"\n"
+" hg add/remove/copy/rename work as usual, though you might want to\n"
+" use git-style patches (-g/--git or [diff] git=1) to track copies\n"
+" and renames. See the diffs help topic for more information on the\n"
+" git diff format.\n"
+" "
+msgstr ""
+"更新当å‰è¡¥ä¸\n"
+"\n"
+" 如果æä¾›äº†æ–‡ä»¶åŒ¹é…模å¼ï¼Œæ›´æ–°åŽçš„è¡¥ä¸åªåŒ…å«åŒ¹é…这些模å¼çš„修改,其它\n"
+" çš„ä¿®æ”¹ä»æ—§åœ¨å·¥ä½œç›®å½•中。\n"
+"\n"
+" 如果指定了 '--short'ï¼Œåªæ›´æ–°å·²ç»åœ¨è¡¥ä¸ä¸­çš„æ–‡ä»¶ï¼Œä¸Žæ–‡ä»¶åŒ¹é…模å¼ç±»ä¼¼ã€‚\n"
+"\n"
+" 'hg add/remove/copy/rename' 如常工作,你å¯èƒ½æƒ³ä½¿ç”¨ git æ ¼å¼è¡¥ä¸(使\n"
+" 用选项 '--git' 或在é…置文件的 [diff] 区中设置 git=1)以跟踪å¤åˆ¶å’Œæ”¹\n"
+" å。请å‚è§å·®å¼‚帮助主题,以了解关于 git 差异格å¼çš„æ›´å¤šä¿¡æ¯ã€‚\n"
+" "
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr ""
+
+#, fuzzy
+msgid ""
+"diff of the current patch and subsequent modifications\n"
+"\n"
+" Shows a diff which includes the current patch as well as any\n"
+" changes which have been made in the working directory since the\n"
+" last refresh (thus showing what the current patch would become\n"
+" after a qrefresh).\n"
+"\n"
+" Use 'hg diff' if you only want to see the changes made since the\n"
+" last qrefresh, or 'hg export qtip' if you want to see changes made\n"
+" by the current patch without including changes made since the\n"
+" qrefresh.\n"
+" "
+msgstr ""
+"显å¼å½“å‰çš„è¡¥ä¸å’ŒåŽç»­çš„修改\n"
+"\n"
+" 显示当å‰çš„è¡¥ä¸å’Œæœ€è¿‘一次刷新之åŽçš„修改(因而在执行 'qrefresh' 之åŽå°±åª\n"
+" 显示当å‰çš„è¡¥ä¸)。\n"
+"\n"
+" å¦‚æžœä½ åªæƒ³çœ‹åˆ°æœ€è¿‘一次刷新之åŽçš„修改请使用 'hg diff'ï¼Œå¦‚æžœä½ åªæƒ³çœ‹åˆ°å½“\n"
+" å‰çš„è¡¥ä¸è¯·ä½¿ç”¨ 'hg export qtip'。\n"
+" "
+
+msgid ""
+"fold the named patches into the current patch\n"
+"\n"
+" Patches must not yet be applied. Each patch will be successively\n"
+" applied to the current patch in the order given. If all the\n"
+" patches apply successfully, the current patch will be refreshed\n"
+" with the new cumulative patch, and the folded patches will be\n"
+" deleted. With -k/--keep, the folded patch files will not be\n"
+" removed afterwards.\n"
+"\n"
+" The header for each folded patch will be concatenated with the\n"
+" current patch header, separated by a line of '* * *'."
+msgstr ""
+
+msgid "qfold requires at least one patch name"
+msgstr ""
+
+msgid "No patches applied"
+msgstr ""
+
+#, python-format
+msgid "Skipping already folded patch %s"
+msgstr ""
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "Error folding patch %s"
+msgstr ""
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr ""
+
+msgid ""
+"set or print guards for a patch\n"
+"\n"
+" Guards control whether a patch can be pushed. A patch with no\n"
+" guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+" pushed only if the qselect command has activated it. A patch with\n"
+" a negative guard (\"-foo\") is never pushed if the qselect command\n"
+" has activated it.\n"
+"\n"
+" With no arguments, print the currently active guards.\n"
+" With arguments, set guards for the named patch.\n"
+" NOTE: Specifying negative guards now requires '--'.\n"
+"\n"
+" To set guards on another patch:\n"
+" hg qguard -- other.patch +2.6.17 -stable\n"
+" "
+msgstr ""
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr ""
+
+msgid "no patch to work with"
+msgstr ""
+
+#, python-format
+msgid "no patch named %s"
+msgstr ""
+
+msgid "print the header of the topmost or specified patch"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"push the next patch onto the stack\n"
+"\n"
+" When -f/--force is applied, all local changes in patched files\n"
+" will be lost.\n"
+" "
+msgstr ""
+"将下个补ä¸åŽ‹å…¥å †æ ˆ\n"
+"\n"
+" 当指定 '--force' æ—¶ï¼Œæ‰€æœ‰åœ¨è¡¥ä¸æ–‡ä»¶ä¸­çš„æœ¬åœ°ä¿®æ”¹éƒ½ä¼šä¸¢å¤±ã€‚\n"
+" "
+
+msgid "no saved queues found, please use -n\n"
+msgstr ""
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"pop the current patch off the stack\n"
+"\n"
+" By default, pops off the top of the patch stack. If given a patch\n"
+" name, keeps popping off patches until the named patch is at the\n"
+" top of the stack.\n"
+" "
+msgstr ""
+"将当å‰è¡¥ä¸å¼¹å‡ºå †æ ˆ\n"
+"\n"
+" 默认将补ä¸å †æ ˆçš„顶部弹出。如果指定了补ä¸å称,那么就会一直弹出,直到此\n"
+" è¡¥ä¸ä½äºŽå †æ ˆé¡¶éƒ¨ã€‚\n"
+" "
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr ""
+
+msgid ""
+"rename a patch\n"
+"\n"
+" With one argument, renames the current patch to PATCH1.\n"
+" With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+
+#, python-format
+msgid "%s already exists"
+msgstr ""
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr ""
+
+msgid "restore the queue state saved by a revision"
+msgstr ""
+
+msgid "save current queue state"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr ""
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"strip a revision and all its descendants from the repository\n"
+"\n"
+" If one of the working directory's parent revisions is stripped, the\n"
+" working directory will be updated to the parent of the stripped\n"
+" revision.\n"
+" "
+msgstr ""
+"从版本库删除一个版本以åŠå®ƒçš„å­å­™\n"
+"\n"
+" 如果有工作目录的父版本被删除,那么此目录会被更新到已删除版本的父版本。\n"
+" "
+
+msgid ""
+"set or print guarded patches to push\n"
+"\n"
+" Use the qguard command to set or print guards on patch, then use\n"
+" qselect to tell mq which guards to use. A patch will be pushed if\n"
+" it has no guards or any positive guards match the currently\n"
+" selected guard, but will not be pushed if any negative guards\n"
+" match the current guard. For example:\n"
+"\n"
+" qguard foo.patch -stable (negative guard)\n"
+" qguard bar.patch +stable (positive guard)\n"
+" qselect stable\n"
+"\n"
+" This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+" it has a negative match) but push bar.patch (because it has a\n"
+" positive match).\n"
+"\n"
+" With no arguments, prints the currently active guards.\n"
+" With one argument, sets the active guard.\n"
+"\n"
+" Use -n/--none to deactivate guards (no other arguments needed).\n"
+" When no guards are active, patches with positive guards are\n"
+" skipped and patches with negative guards are pushed.\n"
+"\n"
+" qselect can change the guards on applied patches. It does not pop\n"
+" guarded patches by default. Use --pop to pop back to the last\n"
+" applied patch that is not guarded. Use --reapply (which implies\n"
+" --pop) to push back to the current patch afterwards, but skip\n"
+" guarded patches.\n"
+"\n"
+" Use -s/--series to print a list of all guards in the series file\n"
+" (no other arguments needed). Use -v for more information."
+msgstr ""
+
+msgid "guards deactivated\n"
+msgstr ""
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr ""
+
+msgid "guards in series file:\n"
+msgstr ""
+
+msgid "no guards in series file\n"
+msgstr ""
+
+msgid "active guards:\n"
+msgstr ""
+
+msgid "no active guards\n"
+msgstr ""
+
+msgid "popping guarded patches\n"
+msgstr ""
+
+msgid "reapplying unguarded patches\n"
+msgstr ""
+
+msgid ""
+"move applied patches into repository history\n"
+"\n"
+" Finishes the specified revisions (corresponding to applied\n"
+" patches) by moving them out of mq control into regular repository\n"
+" history.\n"
+"\n"
+" Accepts a revision range or the -a/--applied option. If --applied\n"
+" is specified, all applied mq revisions are removed from mq\n"
+" control. Otherwise, the given revisions must be at the base of the\n"
+" stack of applied patches.\n"
+"\n"
+" This can be especially useful if your changes have been applied to\n"
+" an upstream repository, or if you are about to push your changes\n"
+" to upstream.\n"
+" "
+msgstr ""
+
+msgid "no revisions specified"
+msgstr ""
+
+msgid "cannot commit over an applied mq patch"
+msgstr ""
+
+msgid "source has mq patches applied"
+msgstr ""
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr ""
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr ""
+
+msgid "cannot import over an applied patch"
+msgstr ""
+
+msgid "print first line of patch header"
+msgstr ""
+
+msgid "hg qapplied [-s] [PATCH]"
+msgstr ""
+
+msgid "use pull protocol to copy metadata"
+msgstr "数用åè®® 'pull' æ¥å¤åˆ¶å…ƒæ•°æ®"
+
+msgid "do not update the new working directories"
+msgstr ""
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr "使用ä¸åŽ‹ç¼©çš„ä¼ è¾“(在局域网更快)"
+
+#, fuzzy
+msgid "location of source patch repository"
+msgstr "为此版本库å¯åЍæœåŠ¡ 'inotify'"
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr ""
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "keep patch file"
+msgstr ""
+
+msgid "stop managing a revision (DEPRECATED)"
+msgstr ""
+
+msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
+msgstr ""
+
+msgid "edit patch header"
+msgstr ""
+
+msgid "keep folded patch files"
+msgstr ""
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr ""
+
+msgid "overwrite any local changes"
+msgstr ""
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr ""
+
+msgid "list all patches and guards"
+msgstr ""
+
+msgid "drop all guards"
+msgstr ""
+
+msgid "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+msgstr ""
+
+msgid "hg qheader [PATCH]"
+msgstr ""
+
+#, fuzzy
+msgid "import file in patch directory"
+msgstr "从补ä¸ç›®å½•导入文件"
+
+#, fuzzy
+msgid "name of patch file"
+msgstr "è¡¥ä¸æ–‡ä»¶åç§°"
+
+msgid "overwrite existing files"
+msgstr "覆盖已有文件"
+
+msgid "place existing revisions under mq control"
+msgstr "将现有的版本置于 mq 控制下"
+
+msgid "use git extended diff format"
+msgstr "使用 git 扩展差异格å¼"
+
+msgid "qpush after importing"
+msgstr ""
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr ""
+
+msgid "create queue repository"
+msgstr "创建队列版本库"
+
+msgid "hg qinit [-c]"
+msgstr ""
+
+msgid "import uncommitted changes into patch"
+msgstr ""
+
+msgid "add \"From: <current user>\" to patch"
+msgstr ""
+
+msgid "add \"From: <given user>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <given date>\" to patch"
+msgstr ""
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+msgstr ""
+
+msgid "hg qnext [-s]"
+msgstr ""
+
+msgid "hg qprev [-s]"
+msgstr ""
+
+msgid "pop all patches"
+msgstr "弹出全部补ä¸"
+
+msgid "queue name to pop"
+msgstr "æ“作的队列åç§°"
+
+msgid "forget any local changes"
+msgstr "丢弃本地修改"
+
+msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+msgstr ""
+
+msgid "apply if the patch has rejects"
+msgstr "强制应用补ä¸"
+
+msgid "list patch name in commit text"
+msgstr "在æäº¤æ—¥å¿—中列出补ä¸åç§°"
+
+msgid "apply all patches"
+msgstr "应用所有补ä¸"
+
+msgid "merge from another queue"
+msgstr "从其它队列åˆå¹¶"
+
+msgid "merge queue name"
+msgstr "åˆå¹¶é˜Ÿåˆ—çš„åç§°"
+
+msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+msgstr ""
+
+msgid "refresh only files already in the patch and specified files"
+msgstr "仅当文件已ç»åœ¨è¡¥ä¸æˆ–æŒ‡å®šæ–‡ä»¶ä¸­æ—¶æ‰æ›´æ–°"
+
+msgid "add/update \"From: <current user>\" in patch"
+msgstr "在补ä¸ä¸­å¢žåŠ /æ›´æ–° \"From: <current user>\""
+
+msgid "add/update \"From: <given user>\" in patch"
+msgstr "在补ä¸ä¸­å¢žåŠ /æ›´æ–° \"From: <given user>\""
+
+msgid "update \"Date: <current date>\" in patch (if present)"
+msgstr "在补ä¸ä¸­æ›´æ–° \"Date: <current date>\" (如果存在)"
+
+msgid "update \"Date: <given date>\" in patch (if present)"
+msgstr "在补ä¸ä¸­æ›´æ–° \"Date: <given date>\" (如果存在)"
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr ""
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr ""
+
+msgid "delete save entry"
+msgstr ""
+
+#, fuzzy
+msgid "update queue working directory"
+msgstr "正在更新工作目录\n"
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr ""
+
+msgid "copy patch directory"
+msgstr ""
+
+msgid "copy directory name"
+msgstr ""
+
+msgid "clear queue status file"
+msgstr ""
+
+msgid "force copy"
+msgstr ""
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr ""
+
+msgid "disable all guards"
+msgstr ""
+
+msgid "list all guards in series file"
+msgstr ""
+
+msgid "pop to before first guarded applied patch"
+msgstr ""
+
+msgid "pop, then reapply patches"
+msgstr ""
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr ""
+
+msgid "print patches not in series"
+msgstr ""
+
+msgid "hg qseries [-ms]"
+msgstr ""
+
+msgid "force removal with local changes"
+msgstr "强制删除,纵然有本地修改"
+
+msgid "bundle unrelated changesets"
+msgstr "打包ä¸ç›¸å…³çš„修改集"
+
+msgid "no backups"
+msgstr "ä¸å¤‡ä»½"
+
+msgid "hg strip [-f] [-b] [-n] REV"
+msgstr ""
+
+msgid "hg qtop [-s]"
+msgstr ""
+
+msgid "hg qunapplied [-s] [PATCH]"
+msgstr ""
+
+msgid "finish all applied changesets"
+msgstr ""
+
+msgid "hg qfinish [-a] [REV...]"
+msgstr ""
+
+msgid ""
+"send e-mail notifications for commits/pushes\n"
+"\n"
+"Subscriptions can be managed through hgrc. Default mode is to print\n"
+"messages to stdout, for testing and configuring.\n"
+"\n"
+"To use, configure notify extension and enable in hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # one email for each incoming changeset\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # batch emails when many changesets incoming at one time\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # config items go in here\n"
+"\n"
+" config items:\n"
+"\n"
+" REQUIRED:\n"
+" config = /path/to/file # file containing subscriptions\n"
+"\n"
+" OPTIONAL:\n"
+" test = True # print messages to stdout for testing\n"
+" strip = 3 # number of slashes to strip for url paths\n"
+" domain = example.com # domain to use if committer missing domain\n"
+" style = ... # style file to use when formatting email\n"
+" template = ... # template to use when formatting email\n"
+" incoming = ... # template to use when run as incoming hook\n"
+" changegroup = ... # template when run as changegroup hook\n"
+" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n"
+" maxsubject = 67 # truncate subject line longer than this\n"
+" diffstat = True # add a diffstat before the diff content\n"
+" sources = serve # notify if source of incoming changes in this "
+"list\n"
+" # (serve == ssh or http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # email address to send as if none given\n"
+" [web]\n"
+" baseurl = http://hgserver/... # root of hg web site for browsing commits\n"
+"\n"
+" notify config file has same format as regular hgrc. it has two\n"
+" sections so you can express subscriptions in whatever way is handier\n"
+" for you.\n"
+"\n"
+" [usersubs]\n"
+" # key is subscriber email, value is \",\"-separated list of glob patterns\n"
+" user@host = pattern\n"
+"\n"
+" [reposubs]\n"
+" # key is glob pattern, value is \",\"-separated list of subscriber emails\n"
+" pattern = user@host\n"
+"\n"
+" glob patterns are matched against path to repository root.\n"
+"\n"
+" if you like, you can put notify config file in repository that users\n"
+" can push changes to, they can manage their own subscriptions."
+msgstr ""
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr ""
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "notify: no subscribers to repository %s\n"
+msgstr ""
+
+#, python-format
+msgid "notify: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+msgid ""
+"browse command output with an external pager\n"
+"\n"
+"To set the pager that should be used, set the application variable:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"If no pager is set, the pager extensions uses the environment variable\n"
+"$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.\n"
+"\n"
+"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
+"setting:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"You can also enable the pager only for certain commands using\n"
+"pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"If pager.attend is present, pager.ignore will be ignored.\n"
+"\n"
+"To ignore global commands like \"hg version\" or \"hg help\", you have to\n"
+"specify them in the global .hgrc\n"
+msgstr ""
+
+msgid ""
+"interpret suffixes to refer to ancestor revisions\n"
+"\n"
+"This extension allows you to use git-style suffixes to refer to the\n"
+"ancestors of a specific revision.\n"
+"\n"
+"For example, if you can refer to a revision as \"foo\", then:\n"
+"\n"
+"- foo^N = Nth parent of foo\n"
+" foo^0 = foo\n"
+" foo^1 = first parent of foo\n"
+" foo^2 = second parent of foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nth first grandparent of foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = first parent of foo\n"
+" foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
+msgstr ""
+
+msgid ""
+"send Mercurial changesets as a series of patch e-mails\n"
+"\n"
+"The series is started off with a \"[PATCH 0 of N]\" introduction, which\n"
+"describes the series as a whole.\n"
+"\n"
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using the\n"
+"first line of the changeset description as the subject text. The\n"
+"message contains two or three body parts:\n"
+"\n"
+" The changeset description.\n"
+"\n"
+" [Optional] The result of running diffstat on the patch.\n"
+"\n"
+" The patch itself, as generated by \"hg export\".\n"
+"\n"
+"Each message refers to the first in the series using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in threaded\n"
+"mail and news readers, and in mail archives.\n"
+"\n"
+"With the -d/--diffstat option, you will be prompted for each changeset\n"
+"with a diffstat summary and the changeset summary, so you can be sure\n"
+"you are sending the right changes.\n"
+"\n"
+"To configure other defaults, add a section like this to your hgrc\n"
+"file:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Then you can use the \"hg email\" command to mail a series of changesets\n"
+"as a patchbomb.\n"
+"\n"
+"To avoid sending patches prematurely, it is a good idea to first run\n"
+"the \"email\" command with the \"-n\" option (test only). You will be\n"
+"prompted for an email recipient address, a subject and an introductory\n"
+"message describing the patches of your patchbomb. Then when all is\n"
+"done, patchbomb messages are displayed. If the PAGER environment\n"
+"variable is set, your pager will be fired up once for each patchbomb\n"
+"message, so you can verify everything is alright.\n"
+"\n"
+"The -m/--mbox option is also very useful. Instead of previewing each\n"
+"patchbomb message in a pager or sending the messages directly, it will\n"
+"create a UNIX mailbox file with the patch emails. This mailbox file\n"
+"can be previewed with any mail user agent which supports UNIX mbox\n"
+"files, e.g. with mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"When you are previewing the patchbomb messages, you can use `formail'\n"
+"(a utility that is commonly installed as part of the procmail\n"
+"package), to send each message out:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"That should be all. Now your patchbomb is on its way out.\n"
+"\n"
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatible mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs\n"
+"directly from the commandline. See the [email] and [smtp] sections in\n"
+"hgrc(5) for details."
+msgstr ""
+
+msgid "Please enter a valid value.\n"
+msgstr ""
+
+msgid "does the diffstat above look okay? "
+msgstr ""
+
+msgid "diffstat rejected"
+msgstr ""
+
+msgid ""
+"send changesets by email\n"
+"\n"
+" By default, diffs are sent in the format generated by hg export,\n"
+" one per message. The series starts with a \"[PATCH 0 of N]\"\n"
+" introduction, which describes the series as a whole.\n"
+"\n"
+" Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+" the first line of the changeset description as the subject text.\n"
+" The message contains two or three parts. First, the changeset\n"
+" description. Next, (optionally) if the diffstat program is\n"
+" installed and -d/--diffstat is used, the result of running\n"
+" diffstat on the patch. Finally, the patch itself, as generated by\n"
+" \"hg export\".\n"
+"\n"
+" By default the patch is included as text in the email body for\n"
+" easy reviewing. Using the -a/--attach option will instead create\n"
+" an attachment for the patch. With -i/--inline an inline attachment\n"
+" will be created.\n"
+"\n"
+" With -o/--outgoing, emails will be generated for patches not found\n"
+" in the destination repository (or only those which are ancestors\n"
+" of the specified revisions if any are provided)\n"
+"\n"
+" With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+" single email containing a binary Mercurial bundle as an attachment\n"
+" will be sent.\n"
+"\n"
+" Examples:\n"
+"\n"
+" hg email -r 3000 # send patch 3000 only\n"
+" hg email -r 3000 -r 3001 # send patches 3000 and 3001\n"
+" hg email -r 3000:3005 # send patches 3000 through 3005\n"
+" hg email 3000 # send patch 3000 (deprecated)\n"
+"\n"
+" hg email -o # send all patches not in default\n"
+" hg email -o DEST # send all patches not in DEST\n"
+" hg email -o -r 3000 # send all ancestors of 3000 not in default\n"
+" hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST\n"
+"\n"
+" hg email -b # send bundle of all patches not in default\n"
+" hg email -b DEST # send bundle of all patches not in DEST\n"
+" hg email -b -r 3000 # bundle of all ancestors of 3000 not in "
+"default\n"
+" hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST\n"
+"\n"
+" Before using this command, you will need to enable email in your\n"
+" hgrc. See the [email] section in hgrc(5) for details.\n"
+" "
+msgstr ""
+
+msgid "specify at least one changeset with -r or -o"
+msgstr ""
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr ""
+
+msgid "too many destinations"
+msgstr ""
+
+msgid "use only one form to specify the revision"
+msgstr ""
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series.\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"This patch series consists of %d patches.\n"
+"\n"
+msgstr ""
+
+msgid "Final summary:\n"
+msgstr ""
+
+msgid "Displaying "
+msgstr ""
+
+msgid "Writing "
+msgstr ""
+
+msgid "Sending "
+msgstr ""
+
+msgid "send patches as attachments"
+msgstr ""
+
+msgid "send patches as inline attachments"
+msgstr ""
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr ""
+
+msgid "email addresses of copy recipients"
+msgstr ""
+
+msgid "add diffstat output to messages"
+msgstr ""
+
+msgid "use the given date as the sending date"
+msgstr ""
+
+msgid "use the given file as the series description"
+msgstr ""
+
+msgid "email address of sender"
+msgstr ""
+
+msgid "print messages that would be sent"
+msgstr ""
+
+msgid "write messages to mbox file instead of sending them"
+msgstr ""
+
+msgid "subject of first message (intro or single patch)"
+msgstr ""
+
+msgid "message identifier to reply to"
+msgstr ""
+
+msgid "email addresses of recipients"
+msgstr ""
+
+msgid "omit hg patch header"
+msgstr ""
+
+msgid "send changes not found in the target repository"
+msgstr ""
+
+msgid "send changes not in target as a binary bundle"
+msgstr ""
+
+msgid "name of the bundle attachment file"
+msgstr ""
+
+msgid "a revision to send"
+msgstr ""
+
+#, fuzzy
+msgid "run even when remote repository is unrelated (with -b/--bundle)"
+msgstr "çºµç„¶è¿œç¨‹ç‰ˆæœ¬åº“æ˜¯æ— å…³çš„ä¹Ÿè¦æ‰§è¡Œ"
+
+msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
+msgstr ""
+
+msgid "send an introduction email for a single patch"
+msgstr ""
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr ""
+
+msgid "delete files not tracked from the working directory"
+msgstr ""
+
+msgid ""
+"removes files not tracked by Mercurial\n"
+"\n"
+" Delete files not known to Mercurial. This is useful to test local\n"
+" and uncommitted changes in an otherwise-clean source tree.\n"
+"\n"
+" This means that purge will delete:\n"
+" - Unknown files: files marked with \"?\" by \"hg status\"\n"
+" - Empty directories: in fact Mercurial ignores directories unless\n"
+" they contain files under source control management\n"
+" But it will leave untouched:\n"
+" - Modified and unmodified tracked files\n"
+" - Ignored files (unless --all is specified)\n"
+" - New files added to the repository (with \"hg add\")\n"
+"\n"
+" If directories are given on the command line, only files in these\n"
+" directories are considered.\n"
+"\n"
+" Be careful with purge, as you could irreversibly delete some files\n"
+" you forgot to add to the repository. If you only want to print the\n"
+" list of files that this program would delete, use the --print\n"
+" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s\n"
+msgstr ""
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr "正在删除文件 %s\n"
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr "正在删除目录 %s\n"
+
+msgid "abort if an error occurs"
+msgstr ""
+
+msgid "purge ignored files too"
+msgstr ""
+
+msgid "print filenames instead of deleting them"
+msgstr ""
+
+#, fuzzy
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr "在文件å称结尾增加 NUL,用于 xargs"
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr ""
+
+msgid ""
+"move sets of revisions to a different ancestor\n"
+"\n"
+"This extension lets you rebase changesets in an existing Mercurial\n"
+"repository.\n"
+"\n"
+"For more information:\n"
+"http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject\n"
+msgstr ""
+
+msgid "first revision, do not change ancestor\n"
+msgstr ""
+
+msgid ""
+"move changeset (and descendants) to a different branch\n"
+"\n"
+" Rebase uses repeated merging to graft changesets from one part of\n"
+" history onto another. This can be useful for linearizing local\n"
+" changes relative to a master development tree.\n"
+"\n"
+" If a rebase is interrupted to manually resolve a merge, it can be\n"
+" continued with --continue/-c or aborted with --abort/-a.\n"
+" "
+msgstr ""
+
+msgid "cannot use both abort and continue"
+msgstr ""
+
+msgid "cannot use collapse with continue or abort"
+msgstr ""
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr ""
+
+msgid "cannot specify both a revision and a base"
+msgstr ""
+
+msgid "nothing to rebase\n"
+msgstr ""
+
+msgid "cannot use both keepbranches and extrafn"
+msgstr ""
+
+msgid "rebase merging completed\n"
+msgstr ""
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr ""
+
+msgid "rebase completed\n"
+msgstr ""
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr ""
+
+msgid " set parents\n"
+msgstr ""
+
+#, python-format
+msgid "rebasing %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid " future parents are %d and %d\n"
+msgstr ""
+
+#, python-format
+msgid " update to %d:%s\n"
+msgstr ""
+
+msgid " already in target\n"
+msgstr ""
+
+#, python-format
+msgid " merge against %d:%s\n"
+msgstr ""
+
+msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgstr ""
+
+msgid "resuming interrupted rebase\n"
+msgstr ""
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr ""
+
+#, python-format
+msgid "next revision set to %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr ""
+
+#, python-format
+msgid "revision %d is an mq patch (%s), finalize it.\n"
+msgstr ""
+
+#, python-format
+msgid "import mq patch %d (%s)\n"
+msgstr ""
+
+msgid "rebase status stored\n"
+msgstr ""
+
+msgid "rebase status resumed\n"
+msgstr ""
+
+msgid "no rebase in progress"
+msgstr ""
+
+msgid "warning: new changesets detected on target branch, not stripping\n"
+msgstr ""
+
+msgid "rebase aborted\n"
+msgstr ""
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr ""
+
+msgid "cannot rebase an ancestor"
+msgstr ""
+
+msgid "cannot rebase a descendant"
+msgstr ""
+
+msgid "already working on current\n"
+msgstr ""
+
+msgid "already working on the current branch\n"
+msgstr ""
+
+#, python-format
+msgid "rebase onto %d starting from %d\n"
+msgstr ""
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr ""
+
+msgid "--update and --rebase are not compatible, ignoring the update flag\n"
+msgstr ""
+
+msgid "rebase working directory to branch head"
+msgstr ""
+
+msgid "rebase from a given revision"
+msgstr ""
+
+msgid "rebase from the base of a given revision"
+msgstr ""
+
+msgid "rebase onto a given revision"
+msgstr ""
+
+msgid "collapse the rebased revisions"
+msgstr ""
+
+msgid "keep original revisions"
+msgstr ""
+
+msgid "keep original branches"
+msgstr ""
+
+msgid "continue an interrupted rebase"
+msgstr ""
+
+msgid "abort an interrupted rebase"
+msgstr ""
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] | "
+"[-c] | [-a]"
+msgstr ""
+
+msgid "interactively select which sets of changes to commit/qrefresh"
+msgstr ""
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr ""
+
+msgid "this is a binary file\n"
+msgstr ""
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr ""
+
+msgid "[Ynsfdaq?]"
+msgstr ""
+
+msgid "&Yes, record this change"
+msgstr ""
+
+msgid "&No, skip this change"
+msgstr ""
+
+msgid "&Skip remaining changes to this file"
+msgstr ""
+
+msgid "Record remaining changes to this &file"
+msgstr ""
+
+msgid "&Done, skip remaining changes and files"
+msgstr ""
+
+#, fuzzy
+msgid "Record &all changes to all remaining files"
+msgstr "将丢失的文件视为删除"
+
+#, fuzzy
+msgid "&Quit, recording no changes"
+msgstr "正在æœç´¢ä¿®æ”¹\n"
+
+msgid "&?"
+msgstr ""
+
+msgid "y"
+msgstr ""
+
+msgid "?"
+msgstr ""
+
+msgid "y - record this change"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "f"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "a"
+msgstr ""
+
+msgid "q"
+msgstr ""
+
+msgid "user quit"
+msgstr "用户退出"
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr ""
+
+msgid " and "
+msgstr ""
+
+#, python-format
+msgid "record this change to %r?"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "record change %d/%d to %r?"
+msgstr "ä¸éœ€è¦æ”¹å˜ %s\n"
+
+msgid ""
+"interactively select changes to commit\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be candidates for recording.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" You will be prompted for whether to record changes to each\n"
+" modified file, and for files with multiple changes, for each\n"
+" change to use. For each query, the following responses are\n"
+" possible:\n"
+"\n"
+" y - record this change\n"
+" n - skip this change\n"
+"\n"
+" s - skip remaining changes to this file\n"
+" f - record remaining changes to this file\n"
+"\n"
+" d - done, skip remaining changes and files\n"
+" a - record all changes to all remaining files\n"
+" q - quit, recording no changes\n"
+"\n"
+" ? - display help"
+msgstr ""
+
+msgid "'mq' extension not loaded"
+msgstr ""
+
+msgid "running non-interactively, use commit instead"
+msgstr ""
+
+msgid "no changes to record\n"
+msgstr ""
+
+#, python-format
+msgid "backup %r as %r\n"
+msgstr ""
+
+msgid "applying patch\n"
+msgstr ""
+
+msgid "patch failed to apply"
+msgstr ""
+
+#, python-format
+msgid "restoring %r to %r\n"
+msgstr ""
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr ""
+
+msgid "share a common history between several working directories"
+msgstr ""
+
+msgid ""
+"create a new shared repository (experimental)\n"
+"\n"
+" Initialize a new repository and working directory that shares its\n"
+" history with another repository.\n"
+"\n"
+" NOTE: actions that change history such as rollback or moving the\n"
+" source may confuse sharers.\n"
+" "
+msgstr ""
+
+msgid "do not create a working copy"
+msgstr ""
+
+msgid "[-U] SOURCE [DEST]"
+msgstr ""
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+"This extension allows you to transplant patches from another branch.\n"
+"\n"
+"Transplanted patches are recorded in .hg/transplant/transplants, as a\n"
+"map from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr ""
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr ""
+
+#, python-format
+msgid "filtering %s\n"
+msgstr ""
+
+msgid "filter failed"
+msgstr ""
+
+msgid "can only omit patchfile if merging"
+msgstr ""
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr ""
+
+msgid "Fix up the merge and run hg transplant --continue"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr ""
+
+msgid "transplant log file is corrupt"
+msgstr ""
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr ""
+
+msgid "commit failed"
+msgstr ""
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr ""
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+" Selected changesets will be applied on top of the current working\n"
+" directory with the log of the original changeset. If --log is\n"
+" specified, log messages will have a comment appended of the form:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" You can rewrite the changelog message with the --filter option.\n"
+" Its argument will be invoked with the current changelog message as\n"
+" $1 and the patch as $2.\n"
+"\n"
+" If --source/-s is specified, selects changesets from the named\n"
+" repository. If --branch/-b is specified, selects changesets from\n"
+" the branch holding the named revision, up to that revision. If\n"
+" --all/-a is specified, all changesets on the branch will be\n"
+" transplanted, otherwise you will be prompted to select the\n"
+" changesets you want.\n"
+"\n"
+" hg transplant --branch REVISION --all will rebase the selected\n"
+" branch (up to the named revision) onto your current working\n"
+" directory.\n"
+"\n"
+" You can optionally mark selected transplanted changesets as merge\n"
+" changesets. You will not be prompted to transplant any ancestors\n"
+" of a merged transplant, and you can merge descendants of them\n"
+" normally instead of transplanting them.\n"
+"\n"
+" If no merges or revisions are provided, hg transplant will start\n"
+" an interactive changeset browser.\n"
+"\n"
+" If a changeset application fails, you can fix the merge by hand\n"
+" and then resume where you left off by calling hg transplant\n"
+" --continue/-c.\n"
+" "
+msgstr ""
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr ""
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr ""
+
+msgid "--all requires a branch revision"
+msgstr ""
+
+msgid "--all is incompatible with a revision list"
+msgstr ""
+
+msgid "no revision checked out"
+msgstr ""
+
+msgid "outstanding uncommitted merges"
+msgstr ""
+
+msgid "outstanding local changes"
+msgstr ""
+
+msgid "pull patches from REPOSITORY"
+msgstr ""
+
+msgid "pull patches from branch BRANCH"
+msgstr ""
+
+msgid "pull all changesets up to BRANCH"
+msgstr ""
+
+msgid "skip over REV"
+msgstr ""
+
+msgid "merge at REV"
+msgstr ""
+
+msgid "append transplant info to log message"
+msgstr ""
+
+msgid "continue last transplant session after repair"
+msgstr ""
+
+msgid "filter changesets through FILTER"
+msgstr ""
+
+msgid ""
+"hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr ""
+
+msgid ""
+"allow the use of MBCS paths with problematic encoding\n"
+"\n"
+"Some MBCS encodings are not good for some path operations (i.e.\n"
+"splitting path, case conversion, etc.) with its encoded bytes. We call\n"
+"such a encoding (i.e. shift_jis and big5) as \"problematic encoding\".\n"
+"This extension can be used to fix the issue with those encodings by\n"
+"wrapping some functions to convert to Unicode string before path\n"
+"operation.\n"
+"\n"
+"This extension is useful for:\n"
+" * Japanese Windows users using shift_jis encoding.\n"
+" * Chinese Windows users using big5 encoding.\n"
+" * All users who use a repository with one of problematic encodings on\n"
+" case-insensitive file system.\n"
+"\n"
+"This extension is not needed for:\n"
+" * Any user who use only ASCII chars in path.\n"
+" * Any user who do not use any of problematic encodings.\n"
+"\n"
+"Note that there are some limitations on using this extension:\n"
+" * You should use single encoding in one repository.\n"
+" * You should set same encoding for the repository by locale or\n"
+" HGENCODING.\n"
+"\n"
+"Path encoding conversion are done between Unicode and\n"
+"encoding.encoding which is decided by Mercurial from current locale\n"
+"setting or HGENCODING.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] filename conversion fail with %s encoding\n"
+msgstr ""
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] activated with encoding: %s\n"
+msgstr ""
+
+msgid ""
+"perform automatic newline conversion\n"
+"\n"
+"To perform automatic newline conversion, use:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = cleverencode:\n"
+"# or ** = macencode:\n"
+"\n"
+"[decode]\n"
+"** = cleverdecode:\n"
+"# or ** = macdecode:\n"
+"\n"
+"If not doing conversion, to make sure you do not commit CRLF/CR by accident:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxncommit.cr = python:hgext.win32text.forbidcr\n"
+"\n"
+"To do the same check on a server to prevent CRLF/CR from being\n"
+"pushed or pulled:\n"
+"\n"
+"[hooks]\n"
+"pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf\n"
+"# or pretxnchangegroup.cr = python:hgext.win32text.forbidcr\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr ""
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"and also consider adding:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+
+msgid ""
+"discover and advertise repositories on the local network\n"
+"\n"
+"Zeroconf enabled repositories will be announced in a network without\n"
+"the need to configure a server or a service. They can be discovered\n"
+"without knowing their actual IP address.\n"
+"\n"
+"To allow other people to discover your repository using run \"hg serve\"\n"
+"in your repository.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"You can discover zeroconf enabled repositories by running \"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+msgstr ""
+
+msgid "archive prefix contains illegal components"
+msgstr ""
+
+msgid "cannot give prefix when archiving to files"
+msgstr ""
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr ""
+
+msgid "invalid changegroup"
+msgstr ""
+
+msgid "unknown parent"
+msgstr ""
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr ""
+
+#, python-format
+msgid "%s: not a Mercurial bundle file"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle version"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle compression type"
+msgstr ""
+
+msgid "cannot create new bundle repository"
+msgstr ""
+
+#, python-format
+msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgstr ""
+
+msgid "empty username"
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr ""
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr ""
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr ""
+
+msgid "limit must be a positive integer"
+msgstr ""
+
+msgid "limit must be positive"
+msgstr ""
+
+msgid "too many revisions specified"
+msgstr ""
+
+#, python-format
+msgid "invalid format spec '%%%s' in output filename"
+msgstr ""
+
+#, python-format
+msgid "adding %s\n"
+msgstr ""
+
+#, python-format
+msgid "removing %s\n"
+msgstr "正在删除 %s\n"
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr ""
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr ""
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr ""
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "copying %s to %s\n"
+msgstr "正在推到 %s\n"
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+
+msgid "no source or destination specified"
+msgstr ""
+
+msgid "no destination specified"
+msgstr ""
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr ""
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr ""
+
+msgid "no files to copy"
+msgstr ""
+
+msgid "(consider using --after)\n"
+msgstr "(考虑使用 --after)\n"
+
+#, python-format
+msgid "changeset: %d:%s\n"
+msgstr "修改集: %d:%s\n"
+
+#, python-format
+msgid "branch: %s\n"
+msgstr "分支: %s\n"
+
+#, python-format
+msgid "tag: %s\n"
+msgstr "标签: %s\n"
+
+#, python-format
+msgid "parent: %d:%s\n"
+msgstr "父亲: %d:%s\n"
+
+#, python-format
+msgid "manifest: %d:%s\n"
+msgstr "清å•: %d:%s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "用户: %s\n"
+
+#, python-format
+msgid "date: %s\n"
+msgstr "日期: %s\n"
+
+msgid "files+:"
+msgstr "文件+:"
+
+msgid "files-:"
+msgstr "文件-:"
+
+msgid "files:"
+msgstr "文件:"
+
+#, python-format
+msgid "files: %s\n"
+msgstr "文件: %s\n"
+
+#, python-format
+msgid "copies: %s\n"
+msgstr "å¤åˆ¶: %s\n"
+
+#, python-format
+msgid "extra: %s=%s\n"
+msgstr "é¢å¤–: %s=%s\n"
+
+msgid "description:\n"
+msgstr "æè¿°:\n"
+
+#, python-format
+msgid "summary: %s\n"
+msgstr "摘è¦: %s\n"
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr ""
+
+#, python-format
+msgid "%s: %s"
+msgstr ""
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr ""
+
+msgid "revision matching date not found"
+msgstr ""
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "%s:%s copy source revision cannot be found!\n"
+msgstr ""
+
+msgid "can only follow copies/renames for explicit filenames"
+msgstr ""
+
+msgid "HG: Enter commit message. Lines beginning with 'HG:' are removed."
+msgstr "HG: 请输入æäº¤æ—¥å¿—。以 'HG:' 开始的行会被删除。"
+
+msgid "HG: Leave message empty to abort commit."
+msgstr ""
+
+#, fuzzy, python-format
+msgid "HG: user: %s"
+msgstr "用户: %s\n"
+
+msgid "HG: branch merge"
+msgstr ""
+
+#, python-format
+msgid "HG: branch '%s'"
+msgstr ""
+
+#, python-format
+msgid "HG: added %s"
+msgstr ""
+
+#, python-format
+msgid "HG: changed %s"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "HG: removed %s"
+msgstr "已删除"
+
+#, fuzzy
+msgid "HG: no files changed"
+msgstr "正在增加文件改å˜\n"
+
+msgid "empty commit message"
+msgstr "空的æäº¤æ—¥å¿—"
+
+#, fuzzy
+msgid ""
+"add the specified files on the next commit\n"
+"\n"
+" Schedule files to be version controlled and added to the\n"
+" repository.\n"
+"\n"
+" The files will be added to the repository at the next commit. To\n"
+" undo an add before that, see hg forget.\n"
+"\n"
+" If no names are given, add all files to the repository.\n"
+" "
+msgstr ""
+"增加指定文件用于下次æäº¤\n"
+"\n"
+" 调度文件å—版本控制,增加到版本库。\n"
+"\n"
+" 这些文件将于下次æäº¤æ—¶å¢žåŠ åˆ°ç‰ˆæœ¬åº“ã€‚éœ€è¦åœ¨æäº¤å‰æ’¤é”€å¢žåŠ ï¼Œ\n"
+" å‚è§ 'hg revert'。\n"
+"\n"
+" 如果没有给出文件å称,就增加所有文件到版本库。\n"
+" "
+
+msgid ""
+"add all new files, delete all missing files\n"
+"\n"
+" Add all new files and remove all missing files from the\n"
+" repository.\n"
+"\n"
+" New files are ignored if they match any of the patterns in\n"
+" .hgignore. As with add, these changes take effect at the next\n"
+" commit.\n"
+"\n"
+" Use the -s/--similarity option to detect renamed files. With a\n"
+" parameter > 0, this compares every removed file with every added\n"
+" file and records those similar enough as renames. This option\n"
+" takes a percentage between 0 (disabled) and 100 (files must be\n"
+" identical) as its parameter. Detecting renamed files this way can\n"
+" be expensive.\n"
+" "
+msgstr ""
+
+msgid "similarity must be a number"
+msgstr ""
+
+msgid "similarity must be between 0 and 100"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"show changeset information by line for each file\n"
+"\n"
+" List changes in files, showing the revision id responsible for\n"
+" each line\n"
+"\n"
+" This command is useful for discovering when a change was made and\n"
+" by whom.\n"
+"\n"
+" Without the -a/--text option, annotate will avoid processing files\n"
+" it detects as binary. With -a, annotate will annotate the file\n"
+" anyway, although the results will probably be neither useful\n"
+" nor desirable.\n"
+" "
+msgstr ""
+"显示指定文件æ¯è¡Œçš„修改集信æ¯\n"
+"\n"
+" 列出文件中的修改,为æ¯è¡Œæ˜¾ç¤ºç‰ˆæœ¬æ ‡è¯†\n"
+"\n"
+" 此命令用于查找è°åšå‡ºçš„修改,或者什么时候å‘生的修改\n"
+"\n"
+" 当没有选项 '-a' 时,annotate 会é¿å…å¤„ç†æ£€æµ‹ä¸ºäºŒè¿›åˆ¶çš„æ–‡ä»¶\n"
+" 当使用选项 '-a' 时,annotate 会直接产生追溯,å¯èƒ½ä¼šæœ‰ä¸åˆéœ€è¦çš„结果\n"
+" "
+
+msgid "at least one filename or pattern is required"
+msgstr ""
+
+msgid "at least one of -n/-c is required for -l"
+msgstr ""
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr ""
+
+msgid ""
+"create an unversioned archive of a repository revision\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use -r/--rev to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use -t/--type. Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see 'hg help export' for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use -p/--prefix to specify a format string for the\n"
+" prefix. The default is the basename of the archive, with suffixes\n"
+" removed.\n"
+" "
+msgstr ""
+
+msgid "no working directory: please specify a revision"
+msgstr ""
+
+msgid "repository root cannot be destination"
+msgstr ""
+
+msgid "cannot archive plain files to stdout"
+msgstr ""
+
+msgid ""
+"reverse effect of earlier changeset\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you backout a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head.\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by hand.\n"
+" The result of this merge is not committed, as with a normal merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "please specify just one revision"
+msgstr ""
+
+msgid "please specify a revision to backout"
+msgstr ""
+
+msgid "cannot backout change on a different branch"
+msgstr ""
+
+msgid "cannot backout a change with no parents"
+msgstr ""
+
+msgid "cannot backout a merge changeset without --parent"
+msgstr ""
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr ""
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr ""
+
+#, python-format
+msgid "Backed out changeset %s"
+msgstr ""
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr ""
+
+msgid "the backout changeset is a new head - do not forget to merge\n"
+msgstr ""
+
+msgid "(use \"backout --merge\" if you want to auto-merge)\n"
+msgstr ""
+
+msgid ""
+"subdivision search of changesets\n"
+"\n"
+" This command helps to find changesets which introduce problems. To\n"
+" use, mark the earliest changeset you know exhibits the problem as\n"
+" bad, then mark the latest changeset which is free from the problem\n"
+" as good. Bisect will update your working directory to a revision\n"
+" for testing (unless the -U/--noupdate option is specified). Once\n"
+" you have performed tests, mark the working directory as good or\n"
+" bad, and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command, it will be used for automatic bisection.\n"
+" Its exit status will be used to mark revisions as good or bad:\n"
+" status 0 means good, 125 means to skip the revision, 127\n"
+" (command not found) will abort the bisection, and any other\n"
+" non-zero exit status means the revision is bad.\n"
+" "
+msgstr ""
+
+msgid "The first good revision is:\n"
+msgstr ""
+
+msgid "The first bad revision is:\n"
+msgstr ""
+
+msgid "Due to skipped revisions, the first good revision could be any of:\n"
+msgstr ""
+
+msgid "Due to skipped revisions, the first bad revision could be any of:\n"
+msgstr ""
+
+msgid "cannot bisect (no known good revisions)"
+msgstr ""
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr ""
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr ""
+
+msgid "incompatible arguments"
+msgstr ""
+
+#, python-format
+msgid "cannot find executable: %s"
+msgstr ""
+
+#, python-format
+msgid "failed to execute %s"
+msgstr ""
+
+#, python-format
+msgid "%s killed"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "Changeset %d:%s: %s\n"
+msgstr "修改集: %d:%s\n"
+
+#, python-format
+msgid "Testing changeset %s:%s (%s changesets remaining, ~%s tests)\n"
+msgstr ""
+
+msgid ""
+"set or show the current branch name\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch will not exist\n"
+" in the repository until the next commit). Standard practice\n"
+" recommends that primary development take place on the 'default'\n"
+" branch.\n"
+"\n"
+" Unless -f/--force is specified, branch will not let you set a\n"
+" branch name that already exists, even if it's inactive.\n"
+"\n"
+" Use -C/--clean to reset the working directory branch to that of\n"
+" the parent of the working directory, negating a previous branch\n"
+" change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr ""
+
+msgid "a branch of the same name already exists (use --force to override)"
+msgstr ""
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr ""
+
+msgid ""
+"list repository named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If active is specified, only show active branches.\n"
+"\n"
+" A branch is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+
+msgid ""
+"create a changegroup file\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" -a/--all (or --base null).\n"
+"\n"
+" To change the compression method applied, use the -t/--type\n"
+" option. The available compression methods are: none, bzip2, and\n"
+" gzip (by default, bundles are compressed using bzip2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means\n"
+" and applied to another repository with the unbundle or pull\n"
+" command. This is useful when direct push and pull are not\n"
+" available or when exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+msgstr ""
+
+msgid "--base is incompatible with specifying a destination"
+msgstr ""
+
+msgid "unknown bundle type specified with --type"
+msgstr ""
+
+msgid ""
+"output the current or given revision of files\n"
+"\n"
+" Print the specified files as they were at the given revision. If\n"
+" no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repository root\n"
+" %p root-relative path name of file being printed\n"
+" "
+msgstr ""
+
+msgid ""
+"make a copy of an existing repository\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" If you use the -r/--rev option to clone up to a specific revision,\n"
+" no subsequent revisions (including subsequent tags) will be\n"
+" present in the cloned repository. This option implies --pull, even\n"
+" on local repositories.\n"
+"\n"
+" By default, clone will check out the head of the 'default' branch.\n"
+" If the -U/--noupdate option is used, the new clone will contain\n"
+" only a repository (.hg) and no working copy (the working copy\n"
+" parent is the null revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Please see 'hg help urls' for important details about ssh:// URLs.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"commit the specified files or all outstanding changes\n"
+"\n"
+" Commit changes to the given files into the repository. Unlike a\n"
+" centralized RCS, this operation is a local operation. See hg push\n"
+" for a way to actively distribute your changes.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" filenames or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is\n"
+" started to prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"æäº¤æŒ‡å®šæ–‡ä»¶çš„修改或全部修改\n"
+"\n"
+" 将指定文件的修改æäº¤åˆ°ç‰ˆæœ¬åº“。\n"
+"\n"
+" 如果çœç•¥äº†æ–‡ä»¶åˆ—表,那么 \"hg status\" 报告的所有修改都被æäº¤ã€‚\n"
+"\n"
+" å¦‚æžœä½ è¦æäº¤åˆå¹¶ç»“果,请ä¸è¦æä¾›ä»»ä½•文件å称或过滤器 '-I/-X'。\n"
+"\n"
+" 如果没有指定æäº¤æ—¥å¿—,将会å¯åЍé…置的编辑器,让你输入信æ¯ã€‚\n"
+"\n"
+" å‚è§ 'hg help dates' 以获得 '-d/--date' 的有效格å¼åˆ—表。\n"
+" "
+
+msgid "created new head\n"
+msgstr "å·²ç»åˆ›å»ºæ–°é¡¶ç‚¹\n"
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr "æäº¤ä¿®æ”¹é›† %d:%s\n"
+
+msgid ""
+"mark files as copied for the next commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr ""
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr "此处没有水银版本库(没有找到 .hg)"
+
+msgid "either two or three arguments required"
+msgstr "需è¦ä¸¤ä¸ªæˆ–ä¸‰ä¸ªå‚æ•°"
+
+msgid "returns the completion list associated with the given command"
+msgstr ""
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr ""
+
+msgid "validate the correctness of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr ""
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr ""
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr ""
+
+msgid ""
+"show combined config settings from all hgrc files\n"
+"\n"
+" With no arguments, print names and values of all config items.\n"
+"\n"
+" With one argument of the form section.name, print just the value\n"
+" of that config item.\n"
+"\n"
+" With multiple arguments, print names and values of all config\n"
+" items with matching section names.\n"
+"\n"
+" With --debug, the source (filename and line number) is printed\n"
+" for each config item.\n"
+" "
+msgstr ""
+
+msgid "only one config item permitted"
+msgstr ""
+
+msgid ""
+"manually set the parents of the current working directory\n"
+"\n"
+" This is useful for writing repository conversion tools, but should\n"
+" be used with care.\n"
+" "
+msgstr ""
+
+msgid "show the contents of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr ""
+
+msgid "dump the contents of a data file revision"
+msgstr ""
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr ""
+
+msgid "parse and display a date"
+msgstr ""
+
+msgid "dump the contents of an index file"
+msgstr ""
+
+msgid "dump an index DAG as a graphviz dot file"
+msgstr ""
+
+msgid "test Mercurial installation"
+msgstr ""
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr ""
+
+msgid " (check that your locale is properly set)\n"
+msgstr ""
+
+msgid "Checking extensions...\n"
+msgstr ""
+
+msgid " One or more extensions could not be found"
+msgstr ""
+
+msgid " (check that you compiled the extensions)\n"
+msgstr ""
+
+msgid "Checking templates...\n"
+msgstr ""
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr ""
+
+msgid "Checking patch...\n"
+msgstr ""
+
+msgid " patch call failed:\n"
+msgstr ""
+
+msgid " unexpected patch output!\n"
+msgstr ""
+
+msgid " patch test failed!\n"
+msgstr ""
+
+msgid ""
+" (Current patch tool may be incompatible with patch, or misconfigured. Please "
+"check your .hgrc file)\n"
+msgstr ""
+
+msgid ""
+" Internal patcher failure, please report this error to http://www.selenic.com/"
+"mercurial/bts\n"
+msgstr ""
+
+msgid "Checking commit editor...\n"
+msgstr ""
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr ""
+
+msgid " (specify a commit editor in your .hgrc file)\n"
+msgstr ""
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr ""
+
+msgid "Checking username...\n"
+msgstr ""
+
+msgid " (specify a username in your .hgrc file)\n"
+msgstr ""
+
+msgid "No problems detected\n"
+msgstr ""
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr ""
+
+msgid "dump rename information"
+msgstr ""
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr ""
+
+msgid "show how files match on given patterns"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a/--text option, diff will avoid generating diffs of\n"
+" files it detects as binary. With -a, diff will generate a diff\n"
+" anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. For more information, read 'hg help diffs'.\n"
+" "
+msgstr ""
+"在版本库中比较(指定的文件)\n"
+"\n"
+" 显示指定文件在版本间的差异。\n"
+"\n"
+" 文件间的差异使用åŒä¸€å·®å¼‚æ ¼å¼æ˜¾ç¤ºã€‚\n"
+"\n"
+" 注æ„: 对åˆå¹¶çš„æ¯”较å¯èƒ½ä¼šäº§ç”Ÿä¸æœŸæœ›çš„结果,因为没有指定版本时,默认\n"
+" 与工作目录的直接父亲比较。\n"
+"\n"
+" å½“ç»™å‡ºä¸¤ä¸ªç‰ˆæœ¬å‚æ•°æ—¶ï¼Œä¼šæ˜¾ç¤ºåœ¨è¿™äº›ç‰ˆæœ¬é—´çš„修改。如果åªç»™å‡ºä¸€ä¸ªç‰ˆæœ¬ï¼Œ\n"
+" 那么它将与工作目录比较。当没有指定版本时,将比较工作目录中的文件与\n"
+" 它的直接父亲。\n"
+"\n"
+" 当没有选项 '-a' 时,将会é¿å…å¤„ç†æ£€æµ‹ä¸ºäºŒè¿›åˆ¶çš„æ–‡ä»¶ã€‚当使用选项 '-a'\n"
+" 时,å¯èƒ½ä¼šæœ‰ä¸åˆéœ€è¦çš„结果。\n"
+"\n"
+" 使用选项 '--git' 会使用 git 扩展差异格å¼ã€‚请阅读 'hg help diffs' 以\n"
+" 了解更多信æ¯ã€‚\n"
+" "
+
+#, fuzzy
+msgid ""
+"dump the header and diffs for one or more changesets\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a/--text option, export will avoid generating diffs\n"
+" of files it detects as binary. With -a, export will generate a\n"
+" diff anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. See 'hg help diffs' for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the\n"
+" second parent. It can be useful to review a merge.\n"
+" "
+msgstr ""
+"为一个或多个修改集输出标题和差异\n"
+"\n"
+" 为一个或多个版本输出标题和差异。\n"
+"\n"
+" åœ¨ä¿®æ”¹é›†æ ‡é¢˜ä¸­æ˜¾ç¤ºçš„ä¿¡æ¯æ˜¯: 作者,修改集哈希,父亲和æäº¤æ—¥å¿—。\n"
+"\n"
+" 注æ„: 对于åˆå¹¶ä¿®æ”¹é›†ï¼Œå¯¼å‡ºå¯èƒ½äº§ç”Ÿä¸æœŸæœ›çš„差异输出,因为它åªä¼šå°†åˆå¹¶\n"
+" 修改集与其第一个父亲比较。\n"
+"\n"
+" å¯ä»¥è¾“出到文件,这时会使用指定的格å¼åŒ–字符串构造文件å称。格å¼åŒ–规则\n"
+" 如下:\n"
+"\n"
+" %% 字符 \"%\"\n"
+" %H 修改集哈希 (40 ä½å六进制数字)\n"
+" %N 产生的补ä¸å·\n"
+" %R 修改集版本å·\n"
+" %b 待导出的版本库的基本åç§°\n"
+" %h 短修改集哈希(12 ä½å六进制数字)\n"
+" %n 从 1 开始补 0 çš„åºåˆ—å·\n"
+" %r è¡¥ 0 的修改集版本å·\n"
+"\n"
+" 当没有选项 '-a' 时,将会é¿å…å¤„ç†æ£€æµ‹ä¸ºäºŒè¿›åˆ¶çš„æ–‡ä»¶ã€‚当使用选项 '-a'\n"
+" 时,å¯èƒ½ä¼šæœ‰ä¸åˆéœ€è¦çš„结果。\n"
+"\n"
+" 使用选项 '--git' 会使用 git 扩展差异格å¼ã€‚请阅读差异帮助主题以了解\n"
+" 更多信æ¯ã€‚\n"
+"\n"
+" 使用选项 '--switch-parent',将会与第二个父亲比较。对于å¤å®¡åˆå¹¶å¾ˆæœ‰ç”¨ã€‚\n"
+" "
+
+msgid "export requires at least one changeset"
+msgstr ""
+
+msgid "exporting patches:\n"
+msgstr ""
+
+msgid "exporting patch:\n"
+msgstr ""
+
+msgid ""
+"forget the specified files on the next commit\n"
+"\n"
+" Mark the specified files so they will no longer be tracked\n"
+" after the next commit.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history, and it does not delete them from the\n"
+" working directory.\n"
+"\n"
+" To undo a forget before the next commit, see hg add.\n"
+" "
+msgstr ""
+
+msgid "no files specified"
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file is already untracked\n"
+msgstr ""
+
+msgid ""
+"search for a pattern in specified files and revisions\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which a\n"
+" match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr ""
+
+msgid ""
+"show current repository heads or show branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" If one or more REV is given, the \"branch heads\" will be shown for\n"
+" the named branch associated with that revision. The name of the\n"
+" branch is called the revision's branch tag.\n"
+"\n"
+" Branch heads are revisions on a given named branch that do not have\n"
+" any children on the same branch. A branch head could be a true head\n"
+" or it could be the last changeset on a branch before a new branch\n"
+" was created. If none of the branch heads are true heads, the branch\n"
+" is considered inactive.\n"
+"\n"
+" If STARTREV is specified only those heads (or branch heads) that\n"
+" are descendants of STARTREV will be displayed.\n"
+" "
+msgstr ""
+
+#, fuzzy, python-format
+msgid "no open branch heads on branch %s\n"
+msgstr "svn: 分支没有版本 %s"
+
+#, python-format
+msgid "no changes on branch %s containing %s are reachable from %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes on branch %s are reachable from %s\n"
+msgstr ""
+
+msgid ""
+"show help for a given topic or a help overview\n"
+"\n"
+" With no arguments, print a list of commands with short help messages.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that\n"
+" topic."
+msgstr ""
+
+msgid "global options:"
+msgstr "全局选项:"
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr "使用 \"hg help\" 获得全部命令的列表"
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr "使用 \"hg help\" 获得全部命令的列表,或 \"hg -v\" 获得详细信æ¯"
+
+#, python-format
+msgid "use \"hg -v help%s\" to show aliases and global options"
+msgstr "使用 \"hg -v help%s\" 显示别å和全局选项"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "使用 \"hg -v help %s\" 显示全局选项"
+
+msgid ""
+"list of commands:\n"
+"\n"
+msgstr ""
+"命令列表:\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"别å: %s\n"
+
+msgid "(no help text available)"
+msgstr "(没有å¯ç”¨çš„帮助信æ¯)"
+
+msgid "options:\n"
+msgstr "选项:\n"
+
+msgid "no commands defined\n"
+msgstr ""
+
+#, fuzzy
+msgid "enabled extensions:"
+msgstr ""
+"\n"
+"å¯ç”¨çš„æ‰©å±•:\n"
+"\n"
+
+msgid "no help text available"
+msgstr "没有å¯ç”¨çš„帮助信æ¯"
+
+#, python-format
+msgid "%s extension - %s\n"
+msgstr ""
+
+msgid "Mercurial Distributed SCM\n"
+msgstr "分布å¼è½¯ä»¶é…置管ç†å·¥å…· - æ°´é“¶\n"
+
+msgid ""
+"basic commands:\n"
+"\n"
+msgstr ""
+"基本命令:\n"
+"\n"
+
+msgid ""
+"\n"
+"additional help topics:\n"
+"\n"
+msgstr ""
+"\n"
+"é¢å¤–的帮助主题:\n"
+"\n"
+
+msgid ""
+"identify the working copy or specified revision\n"
+"\n"
+" With no revision, print a summary of the current state of the\n"
+" repository.\n"
+"\n"
+" Specifying a path to a repository root or Mercurial bundle will\n"
+" cause lookup to operate on that repository/bundle.\n"
+"\n"
+" This summary identifies the repository state using one or two\n"
+" parent hash identifiers, followed by a \"+\" if there are\n"
+" uncommitted changes in the working directory, a list of tags for\n"
+" this revision and a branch name for non-default branches.\n"
+" "
+msgstr ""
+
+msgid ""
+"import an ordered set of patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f/--force flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (to use the body part, it must have type\n"
+" text/plain or text/x-patch). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and\n"
+" description from patch override values from message headers and\n"
+" body. Values given on command line with -m/--message and -u/--user\n"
+" override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory to\n"
+" the parent of each patch before applying it, and will abort if the\n"
+" resulting changeset has a different ID than the one recorded in\n"
+" the patch. This may happen due to character set problems or other\n"
+" deficiencies in the text patch format.\n"
+"\n"
+" With -s/--similarity, hg will attempt to discover renames and\n"
+" copies in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use \"-\" as the patch name.\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "applying patch from stdin\n"
+msgstr ""
+
+msgid "no diffs found"
+msgstr ""
+
+#, python-format
+msgid ""
+"message:\n"
+"%s\n"
+msgstr ""
+
+#, fuzzy
+msgid "not a Mercurial patch"
+msgstr "%s 䏿˜¯æœ¬åœ°çš„æ°´é“¶ç‰ˆæœ¬åº“"
+
+msgid "patch is damaged or loses information"
+msgstr ""
+
+msgid ""
+"show new changesets found in source\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would have been pulled\n"
+" if a pull at the time you issued this command.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the\n"
+" changesets twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"create a new repository in the given directory\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it will be created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"在指定目录创建新版本库\n"
+"\n"
+" 在指定目录åˆå§‹åŒ–新版本库。如果指定的目录ä¸å­˜åœ¨ï¼Œé‚£ä¹ˆä¼šè¢«åˆ›å»ºã€‚\n"
+"\n"
+" 如果没有指定目录,就使用当å‰ç›®å½•。\n"
+"\n"
+" å¯ä»¥æŒ‡å®šä½ç½® 'ssh://' 作为目标。å‚è§å‘½ä»¤ 'hg help urls' 的帮助信æ¯ï¼Œ\n"
+" 以了解ä½ç½® 'ssh://' çš„é‡è¦è¯¦æƒ…。\n"
+" "
+
+msgid ""
+"locate files matching specific patterns\n"
+"\n"
+" Print files under Mercurial control in the working directory whose\n"
+" names match the given patterns.\n"
+"\n"
+" By default, this command searches all directories in the working\n"
+" directory. To search just the current directory and its\n"
+" subdirectories, use \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints the names\n"
+" of all files under Mercurial control in the working directory.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the -0 option to both this command and \"xargs\". This\n"
+" will avoid the problem of \"xargs\" treating single filenames that\n"
+" contain whitespace as multiple filenames.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a filename to follow history across\n"
+" renames and copies. --follow without a filename will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command prints revision number and changeset id,\n"
+" tags, non-trivial parents, user, date and time, and a summary for\n"
+" each commit. When the -v/--verbose switch is used, the list of\n"
+" changed files and full commit message are shown.\n"
+"\n"
+" NOTE: log -p/--patch may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, only files different from BOTH parents\n"
+" will appear in files:.\n"
+" "
+msgstr ""
+"显示全部版本库或指定文件的版本历å²\n"
+"\n"
+" 显示全部版本库或指定文件的版本历å²ã€‚\n"
+"\n"
+" 显示文件历å²çš„æ—¶å€™ä¸è·Ÿè¸ªæ”¹å或å¤åˆ¶ã€‚对文件å称使用 '-f/--follow'\n"
+" ä¼šè·Ÿè¸ªæ”¹åæˆ–å¤åˆ¶çš„历å²ã€‚当ä¸ç»™å‡ºæ–‡ä»¶å称时,使用 '--follow' åªæ˜¾\n"
+" 示开始版本的直系祖先。使用 '--follow-first' åªæ˜¾ç¤ºåˆå¹¶ç‰ˆæœ¬çš„第一\n"
+" 个父亲。\n"
+"\n"
+" 如果没有指定版本范围,默认是 'tip:0'。当使用 '--follow' 时,使用\n"
+" 工作目录的父亲作为开始版本。\n"
+"\n"
+" å‚è§ 'hg help dates' 以获得 '-d/--date' 的有效格å¼åˆ—表。\n"
+"\n"
+" 此命令缺çœè¾“出: 修改集标识和哈希,标签,父亲,æäº¤è€…,日期和时间,\n"
+" ä»¥åŠæ¯æ¬¡æäº¤çš„æ¦‚è¦ä¿¡æ¯ã€‚当使用选项 '-v/--verbose' 时,会显示文件\n"
+" å˜æ›´åˆ—表和完整的æäº¤ä¿¡æ¯ã€‚\n"
+"\n"
+" 注æ„: 对于åˆå¹¶ä¿®æ”¹é›†ï¼Œ'log -p' å¯èƒ½äº§ç”Ÿä¸æœŸæœ›çš„差异输出,因为它åª\n"
+" 会将åˆå¹¶ä¿®æ”¹é›†ä¸Žå…¶ç¬¬ä¸€ä¸ªçˆ¶äº²æ¯”è¾ƒã€‚è€Œä¸”ï¼Œåªæ˜¾ç¤ºå¯¹æ‰€æœ‰çˆ¶äº²éƒ½ä¸åŒçš„\n"
+" 文件列表。\n"
+"\n"
+" "
+
+msgid ""
+"output the current or given revision of the project manifest\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the first parent of the working directory\n"
+" is used, or the null revision if no revision is checked out.\n"
+"\n"
+" With -v, print file permissions, symlink and executable bits.\n"
+" With --debug, print file revision hashes.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"merge working directory with another revision\n"
+"\n"
+" The current working directory is updated with all changes made in\n"
+" the requested revision since the last common predecessor revision.\n"
+"\n"
+" Files that changed between either parent are marked as changed for\n"
+" the next commit and a commit must be performed before any further\n"
+" updates to the repository are allowed. The next commit will have\n"
+" two parents.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other\n"
+" head, the other head is merged with by default. Otherwise, an\n"
+" explicit revision with which to merge with must be provided.\n"
+" "
+msgstr ""
+"将工作目录与其它版本åˆå¹¶\n"
+"\n"
+" 将当å‰å·¥ä½œç›®å½•中的内容与指定版本åˆå¹¶ã€‚对任一父亲而言改å˜çš„æ–‡ä»¶éƒ½ä¼šå¯¹\n"
+" 下次æäº¤æ ‡è®°ä¸ºå·²ä¿®æ”¹ï¼Œåœ¨æäº¤ä¹‹å‰ä¸å…è®¸å†æ‰§è¡Œæ›´æ–°ã€‚\n"
+"\n"
+" 如果没有指定版本,那么工作目录的父亲是一个åˆå¹¶é¡¶ç‚¹ï¼Œå¦ä¸€ä¸ªåœ¨å½“å‰åˆ†æ”¯\n"
+" 中,åˆå¹¶åŽçš„内容是新的顶点。å¦åˆ™ï¼Œå¿…须明确的指定è¦åˆå¹¶çš„版本。\n"
+" "
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr ""
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr ""
+
+msgid "there is nothing to merge"
+msgstr ""
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr ""
+
+msgid ""
+"working dir not at a head rev - use \"hg update\" or merge with an explicit "
+"rev"
+msgstr ""
+
+msgid ""
+"show changesets not found in destination\n"
+"\n"
+" Show changesets not found in the specified destination repository\n"
+" or the default push location. These are the changesets that would\n"
+" be pushed if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"show the parents of the working directory or revision\n"
+"\n"
+" Print the working directory's parent revisions. If a revision is\n"
+" given via -r/--rev, the parent of that revision will be printed.\n"
+" If a file argument is given, the revision in which the file was\n"
+" last changed (before the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"显示工作目录或指定版本的父亲\n"
+"\n"
+" 显示工作目录的父亲版本。如果使用 '--rev' 指定版本,就显示此版本的\n"
+" 父亲。如果指定了文件,那么使用此文件最åŽä¿®æ”¹çš„版本(工作目录的起æº\n"
+" 版本,或 '--rev' 指定的版本)。\n"
+" "
+
+msgid "can only specify an explicit filename"
+msgstr ""
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr ""
+
+msgid ""
+"show aliases for remote repositories\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given,\n"
+" show definition of all available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+
+msgid "not found!\n"
+msgstr ""
+
+msgid "not updating, since new heads added\n"
+msgstr ""
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr ""
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"pull changes from the specified source\n"
+"\n"
+" Pull changes from a remote repository to a local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to a local repository (the current one unless\n"
+" -R is specified). By default, this does not update the copy of the\n"
+" project in the working directory.\n"
+"\n"
+" Use hg incoming if you want to see what would have been added by a\n"
+" pull at the time you issued this command. If you then decide to\n"
+" added those changes to the repository, you should use pull -r X\n"
+" where X is the last changeset listed by hg incoming.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"从指定版本库å–得修改集\n"
+"\n"
+" 从远程版本库å–得修改集到本地版本库。\n"
+"\n"
+" 查找ä½äºŽæŒ‡å®šè·¯å¾„或ä½ç½®çš„版本库的全部修改,增加到版本版本库。默认ä¸\n"
+" 更新工作目录。\n"
+"\n"
+" 如果没有指定ä½ç½®ï¼Œå°±ä½¿ç”¨è·¯å¾„ 'default'。å‚è§ 'hg help urls' 以了解\n"
+" 更多信æ¯ã€‚\n"
+" "
+
+#, fuzzy
+msgid ""
+"push changes to the specified destination\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It moves changes from\n"
+" the current repository to a different one. If the destination is\n"
+" local this is identical to a pull in that directory from the\n"
+" current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" user forgot to pull and merge before pushing.\n"
+"\n"
+" If -r/--rev is used, the named revision and all its ancestors will\n"
+" be pushed to the remote repository.\n"
+"\n"
+" Please see 'hg help urls' for important details about ssh://\n"
+" URLs. If DESTINATION is omitted, a default path will be used.\n"
+" "
+msgstr ""
+"æŽ¨é€æ”¹å˜åˆ°æŒ‡å®šä½ç½®\n"
+"\n"
+" ä»Žæœ¬åœ°ç‰ˆæœ¬åº“æŽ¨é€æ”¹å˜åˆ°æŒ‡å®šä½ç½®ã€‚\n"
+"\n"
+" 这是 'pull' 的对称æ“作。它从当å‰ç‰ˆæœ¬åº“æŽ¨é€æ”¹å˜åˆ°å…¶å®ƒç‰ˆæœ¬åº“。如果目标\n"
+" 是本地版本库,那么此æ“作与在目标版本库从当å‰ç‰ˆæœ¬åº“执行 'pull' æ“作等\n"
+" åŒã€‚\n"
+"\n"
+" 推é€é»˜è®¤æ‹’ç»å¯¼è‡´å¢žåŠ è¿œç¨‹ç‰ˆæœ¬åº“é¡¶ç‚¹æ•°ç›®çš„æ“作。这通常表明客户端在推é€\n"
+" 之å‰å¿˜è®°å–得远程版本库的修改,并且åˆå¹¶ã€‚\n"
+"\n"
+" 如果使用了选项 '-r',此命å修改集以åŠå…¶ç¥–先都会被推é€åˆ°è¿œç¨‹ç‰ˆæœ¬åº“。\n"
+" \n"
+"\n"
+" å‚è§ä¸»é¢˜ 'urls' 的帮助信æ¯ï¼Œä»¥äº†è§£ä½ç½® 'ssh://' çš„é‡è¦è¯¦æƒ…。如果没有\n"
+" 给出目标ä½ç½®ï¼Œé‚£ä¹ˆä½¿ç”¨é»˜è®¤è·¯å¾„。å‚è§ 'hg help urls' 以了解更多信æ¯ã€‚\n"
+" "
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr "正在推到 %s\n"
+
+msgid ""
+"roll back an interrupted transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an\n"
+" interrupted operation. It should only be necessary when Mercurial\n"
+" suggests it.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"remove the specified files on the next commit\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history. -A/--after can be used to remove only\n"
+" files that have already been deleted, -f/--force can be used to\n"
+" force deletion, and -Af can be used to remove files from the next\n"
+" revision without deleting them from the working directory.\n"
+"\n"
+" The following table details the behavior of remove for different\n"
+" file states (columns) and option combinations (rows). The file\n"
+" states are Added [A], Clean [C], Modified [M] and Missing [!]\n"
+" (as reported by hg status). The actions are Warn, Remove (from\n"
+" branch) and Delete (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+msgstr ""
+"在下次æäº¤æ—¶åˆ é™¤æŒ‡å®šæ–‡ä»¶\n"
+"\n"
+" 调度从版本库删除指定文件。\n"
+"\n"
+" 它åªä»Žå½“å‰åˆ†æ”¯åˆ é™¤æ–‡ä»¶ï¼Œä¸åˆ é™¤åކå²ã€‚'-A' 用于åªç§»é™¤å·²ç»åˆ é™¤çš„æ–‡\n"
+" 件,'-f' 用于强制删除,'-Af' 用于从下个版本移除文件,但是ä¸åˆ é™¤\n"
+" 它们。\n"
+"\n"
+" 下表给出了删除ä¸åŒçжæ€(列)文件的行为和å¯é€‰çš„组åˆ(行)。文件状æ€\n"
+" ('hg status' 报告的状æ€)是增加(A),干净(C),已修改(M),丢失(!)。\n"
+" 动作是警告(W),移除(R,从分支),以åŠåˆ é™¤(D,从ç£ç›˜)。\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" 此命令调度下次æäº¤æ—¶åˆ é™¤æ–‡ä»¶ã€‚\n"
+" è¦åœ¨æ­¤ä¹‹å‰æ’¤é”€åˆ é™¤ï¼Œè¯·å‚è§ 'hg revert'。\n"
+" "
+
+#, python-format
+msgid "not removing %s: file is untracked\n"
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file %s (use -f to force removal)\n"
+msgstr ""
+
+msgid "still exists"
+msgstr ""
+
+msgid "is modified"
+msgstr ""
+
+msgid "has been marked for add"
+msgstr ""
+
+msgid ""
+"rename files; equivalent of copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If dest\n"
+" is a directory, copies are put in that directory. If dest is a\n"
+" file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+
+msgid ""
+"retry file merges from a merge or update\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a/--all switch.\n"
+"\n"
+" If a conflict is resolved manually, please note that the changes\n"
+" will be overwritten if the merge is retried with resolve. The\n"
+" -m/--mark switch should be used to mark the file as resolved.\n"
+"\n"
+" This command also allows listing resolved files and manually\n"
+" indicating whether or not files are resolved. All files must be\n"
+" marked as resolved before a commit is permitted.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+msgstr ""
+
+msgid "too many options specified"
+msgstr ""
+
+msgid "can't specify --all and patterns"
+msgstr ""
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr ""
+
+msgid ""
+"restore individual files or directories to an earlier state\n"
+"\n"
+" (Use update -r to check out earlier revisions, revert does not\n"
+" change the working directory parents.)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r/--rev option, revert the given files or directories\n"
+" to their contents as of a specific revision. This can be helpful\n"
+" to \"roll back\" some or all of an earlier change. See 'hg help\n"
+" dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable mode\n"
+" of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+msgstr ""
+
+msgid "you can't specify a revision and a date"
+msgstr ""
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr ""
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr ""
+
+#, python-format
+msgid "reverting %s\n"
+msgstr "正在æ¢å¤ %s\n"
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr "正在撤销删除 %s\n"
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr "ä¿å­˜å½“å‰ç‰ˆæœ¬çš„ %s 为 %s\n"
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr "文件未被控制: %s\n"
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr "ä¸éœ€è¦æ”¹å˜ %s\n"
+
+msgid ""
+"roll back the last transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time. This command does not alter\n"
+" the working directory.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+msgstr ""
+
+msgid ""
+"print the root (top) of the current working directory\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"export the repository via HTTP\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+" files.\n"
+" "
+msgstr ""
+"通过 HTTP å‘布版本库\n"
+"\n"
+" å¯åŠ¨æœ¬åœ° HTTP 版本库æµè§ˆå™¨å’Œå‘布æœåŠ¡å™¨ã€‚\n"
+"\n"
+" 默认æœåŠ¡å™¨è®¿é—®æ—¥å¿—è¾“å‡ºåˆ° stdout,错误日志输出到 stderr。\n"
+" å¯ä»¥ä½¿ç”¨é€‰é¡¹ \"-A\" å’Œ \"-E\",将这些日志输出到文件。\n"
+" "
+
+#, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"show changed files in the working directory\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" the source of a copy/move operation, are not listed unless\n"
+" -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.\n"
+" Unless options described with \"show only ...\" are given, the\n"
+" options -mardu are used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/--ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the differences between them are\n"
+" shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = missing (deleted by non-hg command, but still tracked)\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = origin of the previous file listed as A (added)\n"
+" "
+msgstr ""
+"显示工作目录中已改å˜çš„æ–‡ä»¶\n"
+"\n"
+" 显示版本库中的文件状æ€ã€‚如果指定文件åç§°ï¼Œåªæ˜¾ç¤ºåŒ¹é…的文件。干净的\n"
+" 文件,被忽略的文件,å¤åˆ¶/ç§»åŠ¨çš„æºæ–‡ä»¶ï¼Œä¸ä¼šè¢«æ˜¾ç¤ºï¼Œé™¤éžä½¿ç”¨äº†é€‰é¡¹\n"
+" '-c' (干净的),'-i' (被忽略的),'-C' (å¤åˆ¶æº) 或者 '-A' (全部)。除\n"
+" éžä½¿ç”¨äº†é€‰é¡¹ \"åªæ˜¾ç¤º ...\",å¦åˆ™å°±ä½¿ç”¨é€‰é¡¹ '-mardu'。\n"
+"\n"
+" 选项 '-q/--quiet' éšè—未跟踪(未知或被忽略)çš„æ–‡ä»¶ï¼Œé™¤éžæ˜Žç¡®åœ°ä½¿ç”¨é€‰\n"
+" 项 '-u/--unknown' 或 ‘-i/-ignored’。\n"
+"\n"
+" 注æ„: 如果修改了æƒé™æˆ–者执行了åˆå¹¶ï¼Œ'status' 与 'diff' 的显示å¯èƒ½\n"
+" ä¸ä¸€è‡´ã€‚标准差异格å¼ä¸æŠ¥å‘Šæƒé™çš„æ”¹å˜ï¼Œ'diff' åªæŠ¥å‘Šç›¸å¯¹äºŽä¸€ä¸ªåˆå¹¶\n"
+" 父亲的改å˜ã€‚\n"
+"\n"
+" 如果给出 1 个版本,就用于基础版本。如果给出 2 个版本,就显示其差异。\n"
+"\n"
+" 显示文件状æ€çš„ä»£ç æ˜¯:\n"
+" M = 已修改\n"
+" A = 已增加\n"
+" R = 已移除\n"
+" C = 干净的\n"
+" ! = å·²åˆ é™¤ï¼Œä»æ—§è¢«è·Ÿè¸ª\n"
+" ? = 未跟踪\n"
+" I = 已忽略\n"
+" = 早先增加的文件自此å¤åˆ¶\n"
+" "
+
+msgid ""
+"add one or more tags for the current or given revision\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is\n"
+" used, or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "tag names must be unique"
+msgstr ""
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr ""
+
+msgid "--rev and --remove are incompatible"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "tag '%s' is not a global tag"
+msgstr "éžæœ¬åœ°ç‰ˆæœ¬åº“ '%s'"
+
+#, fuzzy, python-format
+msgid "tag '%s' is not a local tag"
+msgstr "éžæœ¬åœ°ç‰ˆæœ¬åº“ '%s'"
+
+#, python-format
+msgid "Removed tag %s"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr ""
+
+#, python-format
+msgid "Added tag %s for changeset %s"
+msgstr ""
+
+msgid ""
+"list repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose\n"
+" switch is used, a third column \"local\" is printed for local tags.\n"
+" "
+msgstr ""
+
+msgid ""
+"show the tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the changeset\n"
+" most recently added to the repository (and therefore the most\n"
+" recently changed head).\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+msgstr ""
+
+msgid ""
+"apply one or more changegroup files\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid ""
+"update working directory\n"
+"\n"
+" Update the repository's working directory to the specified\n"
+" revision, or the tip of the current branch if none is specified.\n"
+" Use null as the revision to remove the working copy (like 'hg\n"
+" clone -U').\n"
+"\n"
+" When the working directory contains no uncommitted changes, it\n"
+" will be replaced by the state of the requested revision from the\n"
+" repository. When the requested revision is on a different branch,\n"
+" the working directory will additionally be switched to that\n"
+" branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C/--clean to\n"
+" discard them, forcibly replacing the state of the working\n"
+" directory with the requested revision. Alternately, use -c/--check\n"
+" to abort.\n"
+"\n"
+" When there are uncommitted changes and option -C/--clean is not\n"
+" used, and the parent revision and requested revision are on the\n"
+" same branch, and one of them is an ancestor of the other, then the\n"
+" new working directory will contain the requested revision merged\n"
+" with the uncommitted changes. Otherwise, the update will fail with\n"
+" a suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use\n"
+" revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"更新工作目录\n"
+"\n"
+" 更新工作目录到指定版本,或者到当å‰åˆ†æ”¯çš„顶点。使用 'null' 作为版本å¯ä»¥\n"
+" 删除工作副本(类似于 'hg clone -U')。\n"
+"\n"
+" å½“å·¥ä½œç›®å½•åŒ…å«æœªæäº¤çš„ä¿®æ”¹æ—¶ï¼Œå®ƒä¼šè¢«ç‰ˆæœ¬åº“ä¸­æŒ‡å®šç‰ˆæœ¬çš„çŠ¶æ€æ›¿æ¢ã€‚当请求\n"
+" 的版本ä½äºŽä¸åŒåˆ†æ”¯æ—¶ï¼Œå·¥ä½œç›®å½•会被切æ¢åˆ°æ­¤åˆ†æ”¯ã€‚\n"
+"\n"
+" å¯ä»¥ä½¿ç”¨é€‰é¡¹ '-C' æ¥ä¸¢å¼ƒæœªæäº¤çš„修改,强制使用请求的版本替æ¢å·¥ä½œç›®å½•çš„\n"
+" 状æ€ã€‚\n"
+"\n"
+" 当有未æäº¤çš„修改,没有使用选项 '-C',父版本和请求版本ä½äºŽä¸åŒåˆ†æ”¯ï¼Œå¹¶ä¸”\n"
+" 其中一个是å¦ä¸€ä¸ªçš„祖先时,那么新的工作目录包å«è¯·æ±‚版本与未æäº¤çš„修改的\n"
+" åˆå¹¶ç»“果。å¦åˆ™ï¼Œæ›´æ–°ä¼šå¤±è´¥ï¼Œå»ºè®®ä½¿ç”¨ 'merge' 或 'update -C'。\n"
+"\n"
+" å¦‚æžœä½ åªæƒ³æ›´æ–°ä¸€ä¸ªæ–‡ä»¶åˆ°æ—§ç‰ˆæœ¬ï¼Œè¯·ä½¿ç”¨ 'revert'。\n"
+"\n"
+" å‚è§ 'hg help dates' 以获得 '-d/--date' 的有效格å¼åˆ—表。\n"
+" "
+
+#, fuzzy
+msgid "uncommitted local changes"
+msgstr "æäº¤ä¿®æ”¹é›† %d:%s\n"
+
+msgid ""
+"verify the integrity of the repository\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+msgstr ""
+
+msgid "output version and copyright information"
+msgstr "输出版本和版æƒä¿¡æ¯"
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr "分布å¼è½¯ä»¶é…置管ç†å·¥å…· - æ°´é“¶ (版本 %s)\n"
+
+msgid ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"\n"
+"ç‰ˆæƒæ‰€æœ‰ (C) 2005-2009 Matt Mackall <mpm@selenic.com> 和其他人。\n"
+"这是自由软件,具体å‚è§ç‰ˆæƒæ¡æ¬¾ã€‚这里没有任何担ä¿ï¼Œç”šè‡³æ²¡æœ‰é€‚åˆ\n"
+"特定目的的éšå«çš„æ‹…ä¿ã€‚\n"
+
+msgid "repository root directory or symbolic path name"
+msgstr "版本库的根目录或符å·è·¯å¾„åç§°"
+
+msgid "change working directory"
+msgstr "改å˜å·¥ä½œç›®å½•"
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr "ä¸å†è¯¢é—®ï¼Œå‡å®šæ‰€æœ‰ç­”案都是 'yes'"
+
+msgid "suppress output"
+msgstr "抑制输出"
+
+msgid "enable additional output"
+msgstr "å¯ç”¨é¢å¤–的输出"
+
+msgid "set/override config option"
+msgstr "设置/覆盖é…置选项"
+
+msgid "enable debugging output"
+msgstr "å¯ç”¨è°ƒè¯•输出"
+
+msgid "start debugger"
+msgstr "å¯åŠ¨è°ƒè¯•å™¨"
+
+msgid "set the charset encoding"
+msgstr "设置字符集编ç "
+
+msgid "set the charset encoding mode"
+msgstr "è®¾ç½®å­—ç¬¦é›†ç¼–ç æ¨¡å¼"
+
+msgid "print traceback on exception"
+msgstr "显示异常的跟踪"
+
+msgid "time how long the command takes"
+msgstr "为命令计时"
+
+msgid "print command execution profile"
+msgstr "显示命令执行的剖æž"
+
+msgid "output version information and exit"
+msgstr "显示版本信æ¯åŽé€€å‡º"
+
+msgid "display help and exit"
+msgstr "显示帮助åŽé€€å‡º"
+
+msgid "do not perform actions, just print output"
+msgstr "䏿‰§è¡Œæ“ä½œï¼Œåªæ‰“å°è¾“出"
+
+msgid "specify ssh command to use"
+msgstr "指定è¦ä½¿ç”¨çš„ 'ssh' 命令"
+
+msgid "specify hg command to run on the remote side"
+msgstr "指定è¦åœ¨è¿œç¨‹è¿è¡Œçš„ 'hg' 命令"
+
+msgid "include names matching the given patterns"
+msgstr "包å«åŒ¹é…指定模å¼çš„åç§°"
+
+msgid "exclude names matching the given patterns"
+msgstr "æ‹’ç»åŒ¹é…指定模å¼çš„åç§°"
+
+msgid "use <text> as commit message"
+msgstr "使用 <text> 作为æäº¤æ—¥å¿—"
+
+msgid "read commit message from <file>"
+msgstr "从 <file> è¯»å–æäº¤æ—¥å¿—"
+
+msgid "record datecode as commit date"
+msgstr "å°†æä¾›çš„æ—¥æœŸä½œä¸ºæäº¤æ—¥æœŸ"
+
+#, fuzzy
+msgid "record the specified user as committer"
+msgstr "å°†æä¾›çš„用户作为æäº¤è€…"
+
+msgid "display using template map file"
+msgstr "ä½¿ç”¨æŒ‡å®šçš„æ ·å¼æ˜¾ç¤º"
+
+msgid "display with template"
+msgstr "ä½¿ç”¨æŒ‡å®šçš„æ¨¡æ¿æ˜¾ç¤º"
+
+msgid "do not show merges"
+msgstr "䏿˜¾ç¤ºåˆå¹¶"
+
+msgid "treat all files as text"
+msgstr "将所有文件视为文本文件"
+
+msgid "don't include dates in diff headers"
+msgstr "ä¸è¦çš„å·®å¼‚å¤´ä¸­åŒ…å«æ—¥æœŸ"
+
+msgid "show which function each change is in"
+msgstr "为æ¯ä¸ªä¿®æ”¹æ˜¾ç¤ºåœ¨ä»€ä¹ˆå‡½æ•°ä¸­"
+
+msgid "ignore white space when comparing lines"
+msgstr "当比较行时忽略空白"
+
+msgid "ignore changes in the amount of white space"
+msgstr "忽略空白数é‡çš„æ”¹å˜"
+
+msgid "ignore changes whose lines are all blank"
+msgstr "忽略空行的改å˜"
+
+msgid "number of lines of context to show"
+msgstr "显示几行上下文"
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr ""
+
+msgid "[OPTION]... [FILE]..."
+msgstr ""
+
+msgid "annotate the specified revision"
+msgstr "追溯指定版本"
+
+msgid "follow file copies and renames"
+msgstr "å¤„ç†æ–‡ä»¶å¤åˆ¶ä¸Žæ”¹å"
+
+msgid "list the author (long with -v)"
+msgstr "列出作者 (增加 '-v' ä¼šä»¥é•¿æ ¼å¼æ˜¾ç¤º)"
+
+msgid "list the date (short with -q)"
+msgstr "列出日期 (增加 '-q' ä¼šä»¥çŸ­æ ¼å¼æ˜¾ç¤º)"
+
+msgid "list the revision number (default)"
+msgstr "åˆ—å‡ºç‰ˆæœ¬å· (默认)"
+
+msgid "list the changeset"
+msgstr "列出修改集"
+
+msgid "show line number at the first appearance"
+msgstr "列出首次出现时的行å·"
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr ""
+
+msgid "do not pass files through decoders"
+msgstr ""
+
+msgid "directory prefix for files in archive"
+msgstr ""
+
+msgid "revision to distribute"
+msgstr ""
+
+msgid "type of distribution to create"
+msgstr ""
+
+msgid "[OPTION]... DEST"
+msgstr ""
+
+msgid "merge with old dirstate parent after backout"
+msgstr ""
+
+msgid "parent to choose when backing out merge"
+msgstr ""
+
+msgid "revision to backout"
+msgstr ""
+
+msgid "[OPTION]... [-r] REV"
+msgstr ""
+
+msgid "reset bisect state"
+msgstr ""
+
+msgid "mark changeset good"
+msgstr ""
+
+msgid "mark changeset bad"
+msgstr ""
+
+msgid "skip testing changeset"
+msgstr ""
+
+msgid "use command to check changeset state"
+msgstr ""
+
+msgid "do not update to target"
+msgstr ""
+
+msgid "[-gbsr] [-c CMD] [REV]"
+msgstr ""
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr ""
+
+msgid "reset branch name to parent branch name"
+msgstr ""
+
+msgid "[-fC] [NAME]"
+msgstr ""
+
+msgid "show only branches that have unmerged heads"
+msgstr ""
+
+msgid "[-a]"
+msgstr ""
+
+msgid "run even when remote repository is unrelated"
+msgstr "çºµç„¶è¿œç¨‹ç‰ˆæœ¬åº“æ˜¯æ— å…³çš„ä¹Ÿè¦æ‰§è¡Œ"
+
+msgid "a changeset up to which you would like to bundle"
+msgstr ""
+
+msgid "a base changeset to specify instead of a destination"
+msgstr ""
+
+msgid "bundle all changesets in the repository"
+msgstr ""
+
+msgid "bundle compression type to use"
+msgstr ""
+
+msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr ""
+
+msgid "print output to file with formatted name"
+msgstr "输出到使用格å¼åŒ–å称的文件中"
+
+msgid "print the given revision"
+msgstr ""
+
+msgid "apply any matching decode filter"
+msgstr ""
+
+msgid "[OPTION]... FILE..."
+msgstr ""
+
+msgid "the clone will only contain a repository (no working copy)"
+msgstr "åªå¤åˆ¶ç‰ˆæœ¬åº“(没有工作副本)"
+
+msgid "a changeset you would like to have after cloning"
+msgstr "å¤åˆ¶åŽä½ æœŸæœ›æœ‰çš„修改集"
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr ""
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr "在æäº¤ä¹‹å‰å°†'æ–°çš„/丢失的'文件标记为'已增加/已删除'"
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr "标记一个分支已关闭,ä¸åœ¨åˆ†æ”¯åˆ—表中显示"
+
+msgid "record a copy that has already occurred"
+msgstr ""
+
+msgid "forcibly copy over an existing managed file"
+msgstr ""
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr ""
+
+msgid "[INDEX] REV1 REV2"
+msgstr ""
+
+#, fuzzy
+msgid "[COMMAND]"
+msgstr "命令"
+
+msgid "show the command options"
+msgstr ""
+
+msgid "[-o] CMD"
+msgstr ""
+
+msgid "try extended date formats"
+msgstr ""
+
+msgid "[-e] DATE [RANGE]"
+msgstr ""
+
+msgid "FILE REV"
+msgstr ""
+
+msgid "[PATH]"
+msgstr ""
+
+msgid "FILE"
+msgstr ""
+
+msgid "revision to rebuild to"
+msgstr ""
+
+msgid "[-r REV] [REV]"
+msgstr ""
+
+msgid "revision to debug"
+msgstr ""
+
+msgid "[-r REV] FILE"
+msgstr ""
+
+msgid "REV1 [REV2]"
+msgstr ""
+
+msgid "do not display the saved mtime"
+msgstr ""
+
+msgid "[OPTION]..."
+msgstr ""
+
+#, fuzzy
+msgid "revision to check"
+msgstr "è¦åˆå¹¶çš„版本"
+
+msgid "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+msgstr ""
+
+msgid "diff against the second parent"
+msgstr "与第二个父亲比较"
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr ""
+
+msgid "end fields with NUL"
+msgstr ""
+
+msgid "print all revisions that match"
+msgstr ""
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr "跟踪修改集历å²ï¼Œæˆ–者跟踪文件的å¤åˆ¶ä¸Žæ”¹åæ“作"
+
+msgid "ignore case when matching"
+msgstr ""
+
+msgid "print only filenames and revisions that match"
+msgstr ""
+
+msgid "print matching line numbers"
+msgstr ""
+
+msgid "search in given revision range"
+msgstr ""
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr ""
+
+msgid "show only heads which are descendants of REV"
+msgstr ""
+
+msgid "show only the active heads from open branches"
+msgstr ""
+
+#, fuzzy
+msgid "show normal and closed heads"
+msgstr "åªæ˜¾ç¤ºå·²å¢žåŠ æ–‡ä»¶çš„çŠ¶æ€"
+
+msgid "[-r STARTREV] [REV]..."
+msgstr ""
+
+msgid "[TOPIC]"
+msgstr ""
+
+#, fuzzy
+msgid "identify the specified revision"
+msgstr "追溯指定版本"
+
+msgid "show local revision number"
+msgstr ""
+
+msgid "show global revision id"
+msgstr ""
+
+msgid "show branch"
+msgstr ""
+
+msgid "show tags"
+msgstr ""
+
+msgid "[-nibt] [-r REV] [SOURCE]"
+msgstr ""
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr ""
+
+msgid "base path"
+msgstr ""
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr ""
+
+msgid "don't commit, just update the working directory"
+msgstr ""
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr ""
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr ""
+
+msgid "[OPTION]... PATCH..."
+msgstr ""
+
+msgid "show newest record first"
+msgstr ""
+
+msgid "file to store the bundles into"
+msgstr ""
+
+msgid "a specific revision up to which you would like to pull"
+msgstr "指定è¦å–得的最高版本"
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr ""
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr ""
+
+msgid "search the repository as it stood at REV"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr "在文件å称结尾增加 NUL,用于 xargs"
+
+msgid "print complete paths from the filesystem root"
+msgstr ""
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr ""
+
+msgid "only follow the first parent of merge changesets"
+msgstr "åªè·Ÿè¸ªä¿®æ”¹é›†çš„第一个父亲"
+
+#, fuzzy
+msgid "show revisions matching date spec"
+msgstr "æ˜¾ç¤ºåŒ¹é…æ—¥æœŸçš„版本"
+
+msgid "show copied files"
+msgstr "显示å¤åˆ¶çš„æ–‡ä»¶"
+
+msgid "do case-insensitive search for a keyword"
+msgstr "对关键字执行ä¸åŒºåˆ†å¤§å°å†™çš„æœç´¢"
+
+#, fuzzy
+msgid "include revisions where files were removed"
+msgstr "包å«åˆ é™¤æ–‡ä»¶çš„版本"
+
+msgid "show only merges"
+msgstr "åªæ˜¾ç¤ºåˆå¹¶"
+
+#, fuzzy
+msgid "revisions committed by user"
+msgstr "指定用户æäº¤çš„版本"
+
+msgid "show only changesets within the given named branch"
+msgstr "åªæ˜¾ç¤ºä½äºŽæŒ‡å®šå‘½å分支中的修改集"
+
+msgid "do not display revision or any of its ancestors"
+msgstr "䏿˜¾ç¤ºæŒ‡å®šç‰ˆæœ¬æˆ–其祖先"
+
+msgid "[OPTION]... [FILE]"
+msgstr ""
+
+msgid "revision to display"
+msgstr ""
+
+msgid "[-r REV]"
+msgstr ""
+
+msgid "force a merge with outstanding changes"
+msgstr "强制与已有修改åˆå¹¶"
+
+msgid "revision to merge"
+msgstr "è¦åˆå¹¶çš„版本"
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr ""
+
+msgid "[-f] [[-r] REV]"
+msgstr ""
+
+msgid "a specific revision up to which you would like to push"
+msgstr "æŒ‡å®šä½ è¦æŽ¨é€çš„æœ€é«˜ç‰ˆæœ¬"
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr ""
+
+#, fuzzy
+msgid "show parents from the specified revision"
+msgstr "从指定的版本显示父亲"
+
+msgid "[-r REV] [FILE]"
+msgstr ""
+
+msgid "[NAME]"
+msgstr ""
+
+msgid "update to new tip if changesets were pulled"
+msgstr "如果有新的修改集,就更新到最新版本"
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr ""
+
+msgid "force push"
+msgstr "强制推é€"
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr ""
+
+msgid "record delete for missing files"
+msgstr "将丢失的文件视为删除"
+
+msgid "remove (and delete) file even if added or modified"
+msgstr "删除文件,纵然它已被增加或修改"
+
+msgid "record a rename that has already occurred"
+msgstr "记录已ç»å‘生的改å"
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr ""
+
+msgid "remerge all unresolved files"
+msgstr ""
+
+msgid "list state of files needing merge"
+msgstr ""
+
+msgid "mark files as resolved"
+msgstr ""
+
+msgid "unmark files as resolved"
+msgstr ""
+
+msgid "revert all changes when no arguments given"
+msgstr ""
+
+msgid "tipmost revision matching date"
+msgstr "åŒ¹é…æœ€æŽ¥è¿‘顶点的日期"
+
+msgid "revision to revert to"
+msgstr ""
+
+msgid "do not save backup copies of files"
+msgstr ""
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr ""
+
+msgid "name of access log file to write to"
+msgstr "记录访问日志的文件åç§°"
+
+msgid "name of error log file to write to"
+msgstr "记录错误日志的文件åç§°"
+
+msgid "port to listen on (default: 8000)"
+msgstr "监å¬çš„端å£(默认: 8000)"
+
+msgid "address to listen on (default: all interfaces)"
+msgstr "监å¬åœ°å€(默认: 所有地å€)"
+
+msgid "prefix path to serve from (default: server root)"
+msgstr "æœåŠ¡è·¯å¾„å‰ç¼€(默认: æœåŠ¡å™¨æ ¹)"
+
+#, fuzzy
+msgid "name to show in web pages (default: working directory)"
+msgstr "在 WEB 页é¢ä¸­æ˜¾ç¤ºçš„åç§°(默认: 工作目录)"
+
+#, fuzzy
+msgid "name of the webdir config file (serve more than one repository)"
+msgstr "webdir é…置文件的åç§°(å‘布多个版本库)"
+
+msgid "for remote clients"
+msgstr "针对远程客户端"
+
+msgid "web templates to use"
+msgstr "使用的 WEB 模æ¿"
+
+msgid "template style to use"
+msgstr "使用的显示样å¼"
+
+msgid "use IPv6 in addition to IPv4"
+msgstr "åŒæ—¶ä½¿ç”¨ IPv6 å’Œ IPv4"
+
+msgid "SSL certificate file"
+msgstr "SSL è¯ä¹¦æ–‡ä»¶"
+
+msgid "show untrusted configuration options"
+msgstr "显示ä¸èƒ½ä¿¡èµ–çš„é…置选项"
+
+msgid "[-u] [NAME]..."
+msgstr ""
+
+msgid "show status of all files"
+msgstr "显示全部文件的状æ€"
+
+msgid "show only modified files"
+msgstr "åªæ˜¾ç¤ºå·²ä¿®æ”¹æ–‡ä»¶çš„状æ€"
+
+msgid "show only added files"
+msgstr "åªæ˜¾ç¤ºå·²å¢žåŠ æ–‡ä»¶çš„çŠ¶æ€"
+
+msgid "show only removed files"
+msgstr "åªæ˜¾ç¤ºå·²ç§»é™¤æ–‡ä»¶çš„状æ€"
+
+msgid "show only deleted (but tracked) files"
+msgstr "åªæ˜¾ç¤ºå·²åˆ é™¤(但被跟踪)文件的状æ€"
+
+msgid "show only files without changes"
+msgstr "åªæ˜¾ç¤ºæ— æ”¹åŠ¨æ–‡ä»¶çš„çŠ¶æ€"
+
+msgid "show only unknown (not tracked) files"
+msgstr "åªæ˜¾ç¤ºæœªçŸ¥(未被跟踪)文件的状æ€"
+
+msgid "show only ignored files"
+msgstr "åªæ˜¾ç¤ºè¢«å¿½ç•¥æ–‡ä»¶çš„状æ€"
+
+msgid "hide status prefix"
+msgstr "éšè—状æ€å‰ç¼€"
+
+msgid "show source of copied files"
+msgstr "显示文件的å¤åˆ¶æº"
+
+msgid "show difference from revision"
+msgstr "显示版本差异"
+
+msgid "replace existing tag"
+msgstr "替æ¢å·²æœ‰çš„æ ‡ç­¾"
+
+msgid "make the tag local"
+msgstr "标记标签为本地"
+
+msgid "revision to tag"
+msgstr "标签对应的版本"
+
+msgid "remove a tag"
+msgstr "删除标签"
+
+msgid "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr ""
+
+msgid "[-p]"
+msgstr ""
+
+msgid "update to new tip if changesets were unbundled"
+msgstr ""
+
+msgid "[-u] FILE..."
+msgstr ""
+
+msgid "overwrite locally modified files (no backup)"
+msgstr "覆盖本地修改的文件(ä¸å¤‡ä»½)"
+
+#, fuzzy
+msgid "check for uncommitted changes"
+msgstr "æäº¤ä¿®æ”¹é›† %d:%s\n"
+
+msgid "[-C] [-d DATE] [[-r] REV]"
+msgstr ""
+
+#, python-format
+msgid "config error at %s:%d: '%s'"
+msgstr ""
+
+msgid "not found in manifest"
+msgstr ""
+
+msgid "branch name not in UTF-8!"
+msgstr ""
+
+#, python-format
+msgid " searching for copies back to rev %d\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" unmatched files in local:\n"
+" %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" unmatched files in other:\n"
+" %s\n"
+msgstr ""
+
+msgid " all copies found (* = to merge, ! = divergent):\n"
+msgstr ""
+
+msgid " checking for directory renames\n"
+msgstr ""
+
+#, python-format
+msgid " dir %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid " file %s -> %s\n"
+msgstr ""
+
+msgid "working directory state appears damaged!"
+msgstr ""
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr ""
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr ""
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr ""
+
+#, python-format
+msgid "not in dirstate: %s\n"
+msgstr ""
+
+msgid "unknown"
+msgstr ""
+
+msgid "character device"
+msgstr ""
+
+msgid "block device"
+msgstr ""
+
+msgid "fifo"
+msgstr ""
+
+msgid "socket"
+msgstr ""
+
+msgid "directory"
+msgstr ""
+
+#, python-format
+msgid "unsupported file type (type is %s)"
+msgstr ""
+
+#, python-format
+msgid "abort: %s\n"
+msgstr "中止: %s\n"
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+" %s\n"
+msgstr ""
+
+#, python-format
+msgid "hg: %s\n"
+msgstr ""
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr ""
+
+#, python-format
+msgid "lock held by %s"
+msgstr ""
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr "中止: %s: %s\n"
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr "中止: ä¸èƒ½é”定 %s: %s\n"
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr "中止: %s!\n"
+
+#, python-format
+msgid "abort: %s"
+msgstr "中止: %s"
+
+msgid " empty string\n"
+msgstr ""
+
+msgid "killed!\n"
+msgstr ""
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr "hg: 未知命令 '%s'\n"
+
+#, python-format
+msgid "abort: could not import module %s!\n"
+msgstr "中止: ä¸èƒ½å¯¼å…¥æ¨¡å— %s!\n"
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr "(你是å¦å¿˜è®°äº†ç¼–译扩展?)\n"
+
+msgid "(is your Python install correct?)\n"
+msgstr "(你的 Python 安装正确�)\n"
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr "中止: 失败: %s\n"
+
+msgid "broken pipe\n"
+msgstr "åæŽ‰çš„管é“\n"
+
+msgid "interrupted!\n"
+msgstr "中断!\n"
+
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+"\n"
+"åæŽ‰çš„管é“\n"
+
+msgid "abort: out of memory\n"
+msgstr "中止: 内存ä¸è¶³\n"
+
+msgid "** unknown exception encountered, details follow\n"
+msgstr "** é‡åˆ°äº†æœªçŸ¥å¼‚常,详细信æ¯å¦‚下\n"
+
+msgid "** report bug details to http://www.selenic.com/mercurial/bts\n"
+msgstr "** 报告问题详情到 http://www.selenic.com/mercurial/bts\n"
+
+msgid "** or mercurial@selenic.com\n"
+msgstr "** 或 mercurial@selenic.com\n"
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr "** 分布å¼è½¯ä»¶é…置管ç†å·¥å…· - æ°´é“¶ (版本 %s)\n"
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr "** 已加载的扩展: %s\n"
+
+#, python-format
+msgid "no definition for alias '%s'\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "alias '%s' resolves to unknown command '%s'\n"
+msgstr "hg: 未知命令 '%s'\n"
+
+#, python-format
+msgid "alias '%s' resolves to ambiguous command '%s'\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "alias '%s' shadows command\n"
+msgstr ""
+"命令列表:\n"
+"\n"
+
+#, python-format
+msgid "malformed --config option: %s"
+msgstr "éžæ³• '--config' 选项: %s"
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr "扩展 '%s' 覆盖了命令: %s\n"
+
+msgid "Option --config may not be abbreviated!"
+msgstr "选项 '--config' ä¸èƒ½ç®€çŸ­!"
+
+msgid "Option --cwd may not be abbreviated!"
+msgstr "选项 '--cwd' ä¸èƒ½ç®€çŸ­!"
+
+#, fuzzy
+msgid ""
+"Option -R has to be separated from other options (e.g. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr ""
+"选项 -R 必须隔离使用(也就是ä¸èƒ½ -qR),并且 --repository åªèƒ½ç®€çŸ­ä¸º --repo!"
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr "时间: 实际 %.3f 秒(用户 %.3f+%.3f 系统 %.3f+%.3f)\n"
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr "éžæœ¬åœ°ç‰ˆæœ¬åº“ '%s'"
+
+msgid "invalid arguments"
+msgstr "éžæ³•傿•°"
+
+#, python-format
+msgid "unrecognized profiling format '%s' - Ignored\n"
+msgstr ""
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+"lsprof ä¸å¯ç”¨ - 从 http://codespeak.net/svn/user/arigo/hack/misc/lsprof/ 安装"
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr "*** 加载扩展 '%s',自 '%s': %s\n"
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr "*** 加载扩展 '%s' 失败: %s\n"
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr "ä¸èƒ½æ‰¾åˆ°åˆå¹¶å·¥å…· '%s'\n"
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr "工具 '%s' ä¸èƒ½å¤„ç†ç¬¦å·é“¾æŽ¥\n"
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr "工具 '%s' ä¸èƒ½å¤„ç†äºŒè¿›åˆ¶\n"
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr "工具 '%s' éœ€è¦ GUI\n"
+
+#, python-format
+msgid "picked tool '%s' for %s (binary %s symlink %s)\n"
+msgstr "选择工具 '%s',用于 %s(二进制 %s 符å·é“¾æŽ¥ %s)\n"
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+" 没有找到工具åˆå¹¶ %s\n"
+"使用本地(l)或者他人(o)的内容?"
+
+msgid "&Local"
+msgstr ""
+
+msgid "&Other"
+msgstr ""
+
+msgid "l"
+msgstr ""
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "my %s other %s ancestor %s\n"
+msgstr ""
+
+msgid " premerge successful\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+
+msgid "&No"
+msgstr ""
+
+msgid "&Yes"
+msgstr ""
+
+msgid "n"
+msgstr ""
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr ""
+
+#, python-format
+msgid "Inconsistent state, %s:%s is good and bad"
+msgstr ""
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial has the ability to add new features through the use of\n"
+" extensions. Extensions may add new commands, add options to\n"
+" existing commands, change the default behavior of commands, or\n"
+" implement hooks.\n"
+"\n"
+" Extensions are not loaded by default for a variety of reasons:\n"
+" they can increase startup overhead; they may be meant for\n"
+" advanced usage only; they may provide potentially dangerous\n"
+" abilities (such as letting you destroy or modify history); they\n"
+" might not be ready for prime time; or they may alter some\n"
+" usual behaviors of stock Mercurial. It is thus up to the user to\n"
+" activate extensions as needed.\n"
+"\n"
+" To enable the \"foo\" extension, either shipped with Mercurial\n"
+" or in the Python search path, create an entry for it in your\n"
+" hgrc, like this:\n"
+"\n"
+" [extensions]\n"
+" foo =\n"
+"\n"
+" You may also specify the full path to an extension:\n"
+"\n"
+" [extensions]\n"
+" myfeature = ~/.hgext/myfeature.py\n"
+"\n"
+" To explicitly disable an extension enabled in an hgrc of broader\n"
+" scope, prepend its path with !:\n"
+"\n"
+" [extensions]\n"
+" # disabling extension bar residing in /path/to/extension/bar.py\n"
+" hgext.bar = !/path/to/extension/bar.py\n"
+" # ditto, but no path was supplied for extension baz\n"
+" hgext.baz = !\n"
+" "
+msgstr ""
+
+#, fuzzy
+msgid "disabled extensions:"
+msgstr ""
+"\n"
+"å¯ç”¨çš„æ‰©å±•:\n"
+"\n"
+
+msgid "Date Formats"
+msgstr ""
+
+msgid ""
+"\n"
+" Some commands allow the user to specify a date, e.g.:\n"
+" * backout, commit, import, tag: Specify the commit date.\n"
+" * log, revert, update: Select revision(s) by date.\n"
+"\n"
+" Many date formats are valid. Here are some examples:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n"
+" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n"
+" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n"
+" \"Dec 6\" (midnight)\n"
+" \"13:18\" (today assumed)\n"
+" \"3:39\" (3:39AM assumed)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Lastly, there is Mercurial's internal format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" This is the internal representation format for dates. unixtime is\n"
+" the number of seconds since the epoch (1970-01-01 00:00 UTC).\n"
+" offset is the offset of the local timezone, in seconds west of UTC\n"
+" (negative if the timezone is east of UTC).\n"
+"\n"
+" The log command also accepts date ranges:\n"
+"\n"
+" \"<{datetime}\" - at or before a given date/time\n"
+" \">{datetime}\" - on or after a given date/time\n"
+" \"{datetime} to {datetime}\" - a date range, inclusive\n"
+" \"-{days}\" - within a given number of days of today\n"
+" "
+msgstr ""
+
+msgid "File Name Patterns"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial accepts several notations for identifying one or more\n"
+" files at a time.\n"
+"\n"
+" By default, Mercurial treats filenames as shell-style extended\n"
+" glob patterns.\n"
+"\n"
+" Alternate pattern notations must be specified explicitly.\n"
+"\n"
+" To use a plain path name without any pattern matching, start it\n"
+" with \"path:\". These path names must completely match starting at\n"
+" the current repository root.\n"
+"\n"
+" To use an extended glob, start a name with \"glob:\". Globs are\n"
+" rooted at the current directory; a glob such as \"*.c\" will only\n"
+" match files in the current directory ending with \".c\".\n"
+"\n"
+" The supported glob syntax extensions are \"**\" to match any string\n"
+" across path separators and \"{a,b}\" to mean \"a or b\".\n"
+"\n"
+" To use a Perl/Python regular expression, start a name with \"re:\".\n"
+" Regexp pattern matching is anchored at the root of the repository.\n"
+"\n"
+" Plain examples:\n"
+"\n"
+" path:foo/bar a name bar in a directory named foo in the root of\n"
+" the repository\n"
+" path:path:name a file or directory named \"path:name\"\n"
+"\n"
+" Glob examples:\n"
+"\n"
+" glob:*.c any name ending in \".c\" in the current directory\n"
+" *.c any name ending in \".c\" in the current directory\n"
+" **.c any name ending in \".c\" in any subdirectory of the\n"
+" current directory including itself.\n"
+" foo/*.c any name ending in \".c\" in the directory foo\n"
+" foo/**.c any name ending in \".c\" in any subdirectory of foo\n"
+" including itself.\n"
+"\n"
+" Regexp examples:\n"
+"\n"
+" re:.*\\.c$ any name ending in \".c\", anywhere in the repository\n"
+"\n"
+" "
+msgstr ""
+
+msgid "Environment Variables"
+msgstr ""
+
+msgid ""
+"\n"
+"HG::\n"
+" Path to the 'hg' executable, automatically passed when running\n"
+" hooks, extensions or external tools. If unset or empty, this is\n"
+" the hg executable's name if it's frozen, or an executable named\n"
+" 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+" Windows) is searched.\n"
+"\n"
+"HGEDITOR::\n"
+" This is the name of the editor to run when committing. See EDITOR.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" This overrides the default locale setting detected by Mercurial.\n"
+" This setting is used to convert data including usernames,\n"
+" changeset descriptions, tag names, and branches. This setting can\n"
+" be overridden with the --encoding command-line option.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" This sets Mercurial's behavior for handling unknown characters\n"
+" while transcoding user input. The default is \"strict\", which\n"
+" causes Mercurial to abort if it can't map a character. Other\n"
+" settings include \"replace\", which replaces unknown characters, and\n"
+" \"ignore\", which drops them. This setting can be overridden with\n"
+" the --encodingmode command-line option.\n"
+"\n"
+"HGMERGE::\n"
+" An executable to use for resolving merge conflicts. The program\n"
+" will be executed with three arguments: local file, remote file,\n"
+" ancestor file.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" A list of files or directories to search for hgrc files. Item\n"
+" separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
+" platform default search path is used. If empty, only the .hg/hgrc\n"
+" from the current repository is read.\n"
+"\n"
+" For each element in HGRCPATH:\n"
+" * if it's a directory, all files ending with .rc are added\n"
+" * otherwise, the file itself will be added\n"
+"\n"
+"HGUSER::\n"
+" This is the string used as the author of a commit. If not set,\n"
+" available values will be considered in this order:\n"
+"\n"
+" * HGUSER (deprecated)\n"
+" * hgrc files from the HGRCPATH\n"
+" * EMAIL\n"
+" * interactive prompt\n"
+" * LOGNAME (with '@hostname' appended)\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"LOGNAME::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"VISUAL::\n"
+" This is the name of the editor to use when committing. See EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Sometimes Mercurial needs to open a text file in an editor for a\n"
+" user to modify, for example when writing commit messages. The\n"
+" editor it uses is determined by looking at the environment\n"
+" variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+" non-empty one is chosen. If all of them are empty, the editor\n"
+" defaults to 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" This is used by Python to find imported modules and may need to be\n"
+" set appropriately if this Mercurial is not installed system-wide.\n"
+" "
+msgstr ""
+
+msgid "Specifying Single Revisions"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial supports several ways to specify individual revisions.\n"
+"\n"
+" A plain integer is treated as a revision number. Negative integers\n"
+" are treated as topological offsets from the tip, with -1 denoting\n"
+" the tip. As such, negative numbers are only useful if you've\n"
+" memorized your local tree numbers and want to save typing a single\n"
+" digit. This editor suggests copy and paste.\n"
+"\n"
+" A 40-digit hexadecimal string is treated as a unique revision\n"
+" identifier.\n"
+"\n"
+" A hexadecimal string less than 40 characters long is treated as a\n"
+" unique revision identifier, and referred to as a short-form\n"
+" identifier. A short-form identifier is only valid if it is the\n"
+" prefix of exactly one full-length identifier.\n"
+"\n"
+" Any other string is treated as a tag name, which is a symbolic\n"
+" name associated with a revision identifier. Tag names may not\n"
+" contain the \":\" character.\n"
+"\n"
+" The reserved name \"tip\" is a special tag that always identifies\n"
+" the most recent revision.\n"
+"\n"
+" The reserved name \"null\" indicates the null revision. This is the\n"
+" revision of an empty repository, and the parent of revision 0.\n"
+"\n"
+" The reserved name \".\" indicates the working directory parent. If\n"
+" no working directory is checked out, it is equivalent to null. If\n"
+" an uncommitted merge is in progress, \".\" is the revision of the\n"
+" first parent.\n"
+" "
+msgstr ""
+
+msgid "Specifying Multiple Revisions"
+msgstr "指定多个版本"
+
+#, fuzzy
+msgid ""
+"\n"
+" When Mercurial accepts more than one revision, they may be\n"
+" specified individually, or provided as a topologically continuous\n"
+" range, separated by the \":\" character.\n"
+"\n"
+" The syntax of range notation is [BEGIN]:[END], where BEGIN and END\n"
+" are revision identifiers. Both BEGIN and END are optional. If\n"
+" BEGIN is not specified, it defaults to revision number 0. If END\n"
+" is not specified, it defaults to the tip. The range \":\" thus means\n"
+" \"all revisions\".\n"
+"\n"
+" If BEGIN is greater than END, revisions are treated in reverse\n"
+" order.\n"
+"\n"
+" A range acts as a closed interval. This means that a range of 3:5\n"
+" gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+" "
+msgstr ""
+"\n"
+" 当水银接å—多个版本时,它们å¯ä»¥å•独给出,或者以字符 \":\" 分割的拓扑连续\n"
+" èŒƒå›´æ ¼å¼æä¾›ã€‚\n"
+"\n"
+" 范围的语法是 '[BEGIN]:[END]',其中 'BEGIN' 和 'END' 是版本标识。'BEGIN'\n"
+" å’Œ 'END' 都是å¯é€‰çš„。'BEGIN' 默认是 0,'END' 默认是 'tip'。因此范围 \":"
+"\"\n"
+" æ„味ç€å…¨éƒ¨ç‰ˆæœ¬ã€‚\n"
+"\n"
+" 如果 'BEGIN' 大于 'END',版本视为ååºã€‚\n"
+"\n"
+" 范围是闭区间。å³èŒƒå›´ '3:5' 是 '3','4','5'ã€‚åŒæ ·ï¼ŒèŒƒå›´ '9:6' 是 '9',\n"
+" '8','7' 和 '6'。\n"
+" "
+
+msgid "Diff Formats"
+msgstr "差异格å¼"
+
+#, fuzzy
+msgid ""
+"\n"
+" Mercurial's default format for showing changes between two\n"
+" versions of a file is compatible with the unified format of GNU\n"
+" diff, which can be used by GNU patch and many other standard\n"
+" tools.\n"
+"\n"
+" While this standard format is often enough, it does not encode the\n"
+" following information:\n"
+"\n"
+" - executable status and other permission bits\n"
+" - copy or rename information\n"
+" - changes in binary files\n"
+" - creation or deletion of empty files\n"
+"\n"
+" Mercurial also supports the extended diff format from the git VCS\n"
+" which addresses these limitations. The git diff format is not\n"
+" produced by default because a few widespread tools still do not\n"
+" understand this format.\n"
+"\n"
+" This means that when generating diffs from a Mercurial repository\n"
+" (e.g. with \"hg export\"), you should be careful about things like\n"
+" file copies and renames or other things mentioned above, because\n"
+" when applying a standard diff to a different repository, this\n"
+" extra information is lost. Mercurial's internal operations (like\n"
+" push and pull) are not affected by this, because they use an\n"
+" internal binary format for communicating changes.\n"
+"\n"
+" To make Mercurial produce the git extended diff format, use the\n"
+" --git option available for many commands, or set 'git = True' in\n"
+" the [diff] section of your hgrc. You do not need to set this\n"
+" option when importing diffs in this format or using them in the mq\n"
+" extension.\n"
+" "
+msgstr ""
+"\n"
+" 水银显示文件ä¸åŒç‰ˆæœ¬ä¹‹é—´å·®å¼‚的格å¼ä¸Ž GNU diff 标准格å¼å…¼å®¹ï¼Œå¯ç”¨äºŽ\n"
+" GNU patch 和许多标准工具。\n"
+"\n"
+" 虽然标准格å¼åœ¨å¤§å¤šæ•°æƒ…å†µä¸‹éƒ½èƒ½æ»¡è¶³è¦æ±‚,但是它ä¸åŒ…å«ä¸‹è¿°ä¿¡æ¯:\n"
+"\n"
+" - 坿‰§è¡Œçжæ€å’Œå…¶å®ƒæƒé™ä½\n"
+" - å¤åˆ¶æˆ–改åä¿¡æ¯\n"
+" - 二进制文件的修改\n"
+" - 创建或删除空文件\n"
+"\n"
+" 水银也支æŒè§£å†³è¿™äº›é™åˆ¶çš„ git 扩展差异格å¼ã€‚ç”±äºŽä¸€äº›å¸¸ç”¨çš„å·¥å…·è¿˜ä¸æ”¯æŒ\n"
+" 此格å¼ï¼Œæ‰€ä»¥å®ƒä¸æ˜¯é»˜è®¤æ ¼å¼ã€‚\n"
+"\n"
+" è¿™æ„味ç€å½“从水银版本库(例如 \"hg export\")产生差异时,在其它版本库应用标\n"
+" 准差异时,会丢失文件å¤åˆ¶æˆ–改åç­‰é¢å¤–ä¿¡æ¯ï¼Œæ‰€ä»¥ä½ è¦å°å¿ƒå¤„ç†ã€‚水银的内部\n"
+" æ“作(例如 push å’Œ pull)åœ¨ä¼ è¾¾æ”¹å˜æ—¶ï¼Œä½¿ç”¨å†…部的二进制格å¼ï¼Œæ‰€ä»¥ä¸å—å½±\n"
+" å“。\n"
+"\n"
+" è¦è®©æ°´é“¶äº§ç”Ÿ git 扩展差异格å¼ï¼Œå¯ä»¥å¯¹è®¸å¤šå‘½ä»¤ä½¿ç”¨é€‰é¡¹ '--git',或者在\n"
+" ä½ çš„ hgrc 文件中的节 '[diff]' 中增加 'git = True'。当你从此格å¼å¯¼å…¥æ—¶ï¼Œ\n"
+" 或在 mq 扩展中使用时,ä¸éœ€è¦è®¾ç½®æ­¤é€‰é¡¹ã€‚\n"
+" "
+
+msgid "Template Usage"
+msgstr "模版用法"
+
+#, fuzzy
+msgid ""
+"\n"
+" Mercurial allows you to customize output of commands through\n"
+" templates. You can either pass in a template from the command\n"
+" line, via the --template option, or select an existing\n"
+" template-style (--style).\n"
+"\n"
+" You can customize output for any \"log-like\" command: log,\n"
+" outgoing, incoming, tip, parents, heads and glog.\n"
+"\n"
+" Three styles are packaged with Mercurial: default (the style used\n"
+" when no explicit preference is passed), compact and changelog.\n"
+" Usage:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" A template is a piece of text, with markup to invoke variable\n"
+" expansion:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings in curly braces are called keywords. The availability of\n"
+" keywords depends on the exact context of the templater. These\n"
+" keywords are usually available for templating a log-like command:\n"
+"\n"
+" - author: String. The unmodified author of the changeset.\n"
+" - branches: String. The name of the branch on which the changeset\n"
+" was committed. Will be empty if the branch name was default.\n"
+" - date: Date information. The date when the changeset was committed.\n"
+" - desc: String. The text of the changeset description.\n"
+" - diffstat: String. Statistics of changes with the following\n"
+" format: \"modified files: +added/-removed lines\"\n"
+" - files: List of strings. All files modified, added, or removed by\n"
+" this changeset.\n"
+" - file_adds: List of strings. Files added by this changeset.\n"
+" - file_mods: List of strings. Files modified by this changeset.\n"
+" - file_dels: List of strings. Files removed by this changeset.\n"
+" - node: String. The changeset identification hash, as a\n"
+" 40-character hexadecimal string.\n"
+" - parents: List of strings. The parents of the changeset.\n"
+" - rev: Integer. The repository-local changeset revision number.\n"
+" - tags: List of strings. Any tags associated with the changeset.\n"
+"\n"
+" The \"date\" keyword does not produce human-readable output. If you\n"
+" want to use a date in your output, you can use a filter to process\n"
+" it. Filters are functions which return a string based on the input\n"
+" variable. You can also use a chain of filters to get the desired\n"
+" output:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" List of filters:\n"
+"\n"
+" - addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
+" every line except the last.\n"
+" - age: Date. Returns a human-readable date/time difference between\n"
+" the given date/time and the current date/time.\n"
+" - basename: Any text. Treats the text as a path, and returns the\n"
+" last component of the path after splitting by the path\n"
+" separator (ignoring trailing separators). For example,\n"
+" \"foo/bar/baz\" becomes \"baz\" and \"foo/bar//\" becomes \"bar\".\n"
+" - stripdir: Treat the text as path and strip a directory level, if\n"
+" possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\".\n"
+" - date: Date. Returns a date in a Unix date format, including\n"
+" the timezone: \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - domain: Any text. Finds the first string that looks like an\n"
+" email address, and extracts just the domain component.\n"
+" Example: 'User <user@example.com>' becomes 'example.com'.\n"
+" - email: Any text. Extracts the first string that looks like an\n"
+" email address. Example: 'User <user@example.com>' becomes\n"
+" 'user@example.com'.\n"
+" - escape: Any text. Replaces the special XML/XHTML characters \"&\",\n"
+" \"<\" and \">\" with XML entities.\n"
+" - fill68: Any text. Wraps the text to fit in 68 columns.\n"
+" - fill76: Any text. Wraps the text to fit in 76 columns.\n"
+" - firstline: Any text. Returns the first line of text.\n"
+" - nonempty: Any text. Returns '(none)' if the string is empty.\n"
+" - hgdate: Date. Returns the date as a pair of numbers:\n"
+" \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
+" - isodate: Date. Returns the date in ISO 8601 format.\n"
+" - localdate: Date. Converts a date to local date.\n"
+" - obfuscate: Any text. Returns the input text rendered as a\n"
+" sequence of XML entities.\n"
+" - person: Any text. Returns the text before an email address.\n"
+" - rfc822date: Date. Returns a date using the same format used\n"
+" in email headers.\n"
+" - short: Changeset hash. Returns the short form of a changeset\n"
+" hash, i.e. a 12-byte hexadecimal string.\n"
+" - shortdate: Date. Returns a date like \"2006-09-18\".\n"
+" - strip: Any text. Strips all leading and trailing whitespace.\n"
+" - tabindent: Any text. Returns the text, with every line except\n"
+" the first starting with a tab character.\n"
+" - urlescape: Any text. Escapes all \"special\" characters. For\n"
+" example, \"foo bar\" becomes \"foo%20bar\".\n"
+" - user: Any text. Returns the user portion of an email address.\n"
+" "
+msgstr ""
+"\n"
+" æ°´é“¶å…许你通过模版定制命令的输出。你å¯ä»¥é€šè¿‡å‘½ä»¤è¡Œé€‰é¡¹ '--template'\n"
+" æ¥ä½¿ç”¨æ¨¡ç‰ˆï¼Œæˆ–者选择已有的模版样å¼(--style)。\n"
+"\n"
+" ä½ å¯ä»¥å®šåˆ¶ä»»æ„输出与日志信æ¯ç±»ä¼¼çš„命令,å³: log,outgoing,incoming,\n"
+" tip,parents,heads 和 glog。\n"
+"\n"
+" 水银中内置了 3 ç§æ ·å¼: default (默认), compact å’Œ changelog。用法:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" 模版是文本片断,其中的标记用于å˜é‡æ‰©å±•:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" 花括å·ä¸­çš„字符串称为关键字。å¯ç”¨çš„关键字ä¾èµ–于模版的上下文。下述关键字\n"
+" å¯ç”¨äºŽè¾“出与日志信æ¯ç±»ä¼¼çš„命令:\n"
+"\n"
+" - author: 字符串。修改集的作者。\n"
+" - branches: 字符串。修改集的分支。如果分支å称为 'default' 则为空。\n"
+" - date: 日期信æ¯ã€‚修改集的日期。\n"
+" - desc: 字符串。修改集的æè¿°ã€‚\n"
+" - files: 字符串列表。修改集中被修改ã€å¢žåŠ å’Œåˆ é™¤çš„å…¨éƒ¨æ–‡ä»¶ã€‚\n"
+" - file_adds: 字符串列表。修改集中被增加的文件。\n"
+" - file_mods: 字符串列表。修改集中被修改的文件\n"
+" - file_dels: 字符串列表。修改集中被删除的文件\n"
+" - node: 字符串。修改集的哈系标识,40 个字符的 16 进制字符串。\n"
+" - parents: 字符串列表。修改集的父亲。\n"
+" - rev: 整数。本地版本库的修改集的版本å·ã€‚\n"
+" - tags: 字符串列表。修改集的标签。\n"
+"\n"
+" 关键字 \"date\" ä¸äº§ç”Ÿäººå·¥å¯è¯»çš„输出。如果你想在输出中使用日期,å¯ä»¥ä½¿ç”¨\n"
+" 过滤器æ¥å¤„ç†å®ƒã€‚过滤器是根æ®è¾“å…¥å˜é‡è¿”回字符串的函数。你还å¯ä»¥ä½¿ç”¨è¿‡æ»¤\n"
+" 链æ¥äº§ç”Ÿç†æƒ³çš„输出:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" 过滤器列表:\n"
+"\n"
+" - addbreaks: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚除了最åŽä¸€è¡Œï¼Œåœ¨æ¯è¡Œçš„结尾增加 XHTML 标签\n"
+" \"<br />\"。\n"
+" - age: è¾“å…¥æ—¥æœŸã€‚è¿”å›žæŒ‡å®šæ—¥æœŸä¸Žå½“å‰æ—¥æœŸå·®å¼‚的人工å¯è¯»çš„字符串。\n"
+" - basename: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚将输入视为路径,返回被路径分隔符隔开的最åŽ\n"
+" 一个组件的åç§°(忽略结尾的分隔符)。例如 \"foo/bar/baz\" æˆä¸º \"baz"
+"\",\n"
+" \"foo/bar//\" æˆä¸º \"bar\"。\n"
+" - date: 输入日期。返回指定日期的 Unix 日期格å¼å­—ç¬¦ä¸²ï¼ŒåŒ…å«æ—¶åŒºï¼Œä¾‹å¦‚: \n"
+" \"Mon Sep 04 15:13:13 2006 0700\"。\n"
+" - domain: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚找到第一个 email 地å€ï¼Œè¿”回其域å。例如: \n"
+" 'User <user@example.com>' æˆä¸º 'example.com'。\n"
+" - email: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚返回第一个 email 地å€ã€‚例如: \n"
+" 'User <user@example.com>' æˆä¸º 'user@example.com'。\n"
+" - escape: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚用 XML 实体æ¥å°è£… XML/XHTML 的特殊字符 \"&\",\n"
+" \"<\" 和 \">\"。\n"
+" - fill68: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚æ ¼å¼åŒ–为 68 列文本。\n"
+" - fill76: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚æ ¼å¼åŒ–为 76 列文本。\n"
+" - firstline: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚返回首行。\n"
+" - hgdate: 输入日期。返回一对数字:\n"
+" \"1157407993 25200\" (Unix 时戳,时区åç§»)。\n"
+" - isodate: 输入日期。返回 ISO 8601 æ ¼å¼çš„æ—¥æœŸã€‚\n"
+" - obfuscate: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚返回其 XML 实体åºåˆ—。\n"
+" - person: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚返回 email 地å€å‰çš„æ–‡æœ¬ã€‚\n"
+" - rfc822date: 输入日期。返回 email 头部使用的日期格å¼ã€‚\n"
+" - short: 修改集哈系。返回修改集哈系的短格å¼ã€‚例如 12 字符的 16 进制\n"
+" 字符串。\n"
+" - shortdate: 输入日期。返回格å¼ç±»ä¼¼äºŽ \"2006-09-18\"。\n"
+" - strip: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚删除全部行首与行尾空白。\n"
+" - tabindent: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚除了首行,在æ¯è¡Œçš„开始增加制表符å·ã€‚\n"
+" - urlescape: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚å°è£…全部特殊字符。例如\n"
+" \"foo bar\" æˆä¸º \"foo%20bar\"。\n"
+" - user: è¾“å…¥ä»»æ„æ–‡æœ¬ã€‚返回 email 地å€ä¸­çš„用户å称部分。\n"
+" "
+
+#, fuzzy
+msgid "URL Paths"
+msgstr "统一资æºå®šä½è·¯å¾„"
+
+#, fuzzy
+msgid ""
+"\n"
+" Valid URLs are of the form:\n"
+"\n"
+" local/filesystem/path (or file://local/filesystem/path)\n"
+" http://[user[:pass]@]host[:port]/[path]\n"
+" https://[user[:pass]@]host[:port]/[path]\n"
+" ssh://[user[:pass]@]host[:port]/[path]\n"
+"\n"
+" Paths in the local filesystem can either point to Mercurial\n"
+" repositories or to bundle files (as created by 'hg bundle' or\n"
+" 'hg incoming --bundle').\n"
+"\n"
+" An optional identifier after # indicates a particular branch, tag,\n"
+" or changeset to use from the remote repository.\n"
+"\n"
+" Some features, such as pushing to http:// and https:// URLs are\n"
+" only possible if the feature is explicitly enabled on the remote\n"
+" Mercurial server.\n"
+"\n"
+" Some notes about using SSH with Mercurial:\n"
+" - SSH requires an accessible shell account on the destination\n"
+" machine and a copy of hg in the remote path or specified with as\n"
+" remotecmd.\n"
+" - path is relative to the remote user's home directory by default.\n"
+" Use an extra slash at the start of a path to specify an absolute path:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial doesn't use its own compression via SSH; the right\n"
+" thing to do is to configure it in your ~/.ssh/config, e.g.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternatively specify \"ssh -C\" as your ssh command in your hgrc\n"
+" or with the --ssh command line option.\n"
+"\n"
+" These URLs can all be stored in your hgrc with path aliases under\n"
+" the [paths] section like so:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" You can then use the alias for any command that uses a URL (for\n"
+" example 'hg pull alias1' would pull from the 'alias1' path).\n"
+"\n"
+" Two path aliases are special because they are used as defaults\n"
+" when you do not provide the URL to a command:\n"
+"\n"
+" default:\n"
+" When you create a repository with hg clone, the clone command\n"
+" saves the location of the source repository as the new\n"
+" repository's 'default' path. This is then used when you omit\n"
+" path from push- and pull-like commands (including incoming and\n"
+" outgoing).\n"
+"\n"
+" default-push:\n"
+" The push command will look for a path named 'default-push', and\n"
+" prefer it over 'default' if both are defined.\n"
+" "
+msgstr ""
+"\n"
+" 有效的ä½ç½®æ ¼å¼:\n"
+"\n"
+" local/filesystem/path (or file://local/filesystem/path)\n"
+" http://[user[:pass]@]host[:port]/[path]\n"
+" https://[user[:pass]@]host[:port]/[path]\n"
+" ssh://[user[:pass]@]host[:port]/[path]\n"
+"\n"
+" ä½äºŽæœ¬åœ°æ–‡ä»¶ç³»ç»Ÿä¸­çš„路径å¯ä»¥æŒ‡å‘版本库,也å¯ä»¥æŒ‡å‘打包的文件(被\n"
+" 'hg bundle' 或 'hg incoming --bundle' 创建)。\n"
+"\n"
+" 在 '#' åŽé¢å¯é€‰çš„æ ‡è¯†ç¬¦ç”¨äºŽæŒ‡å®šè¦å–得的远程版本库的分支,标签或\n"
+" 修改集。\n"
+"\n"
+" 仅当远程水银æœåŠ¡å™¨æ˜¾å¼å¯ç”¨æ—¶ï¼Œæ‰èƒ½æŽ¨åˆ° 'http://' å’Œ 'https://'。\n"
+"\n"
+" 在水银中使用 SSH 的一些æç¤º:\n"
+" - 使用 SSH 时,需è¦åœ¨è¿œç¨‹ä¸»æœºä¸Šæœ‰å¯ç™»å½•å¸å·ï¼Œè¿œç¨‹è·¯å¾„ä¸­è¿˜éœ€è¦æœ‰\n"
+" hg,或者有指定的远程命令。\n"
+" - 默认 'path' 是相对于远程主机上的用户家目录。\n"
+" å¯ä»¥åœ¨è·¯å¾„å‰å¢žåŠ ä¸€ä¸ªæ–œçº¿æŒ‡å®šç»å¯¹è·¯å¾„:\n"
+" ssh://example.com//tmp/repository\n"
+" - 水银使用 SSH æ—¶ä¸ä½¿ç”¨åŽ‹ç¼©ï¼Œæ‰€ä»¥ä½ å¯ä»¥åœ¨ ~/.ssh/config 中é…ç½®\n"
+" SSH 执行压缩,例如:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" å¦ä¸€ä¸ªæ–¹æ³•是在你的 hgrc 中将 \"ssh -C\" 作为你的 ssh 命令,或\n"
+" ç”¨äºŽå‘½ä»¤è¡Œå‚æ•° '--ssh' 中。\n"
+"\n"
+" 这些路径å¯ä»¥åœ¨ä½ çš„ 'hgrc' 中的节 '[paths]' 中定义别å:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" ç„¶åŽä½ å°±å¯ä»¥åœ¨ä»»æ„命令中使用这些别å作为路径(例如 'hg pull alias1'\n"
+" 会从 'alias1' 定义的路径å–得指定版本)。\n"
+"\n"
+" 因为用于默认路径,所以这 2 ä¸ªè·¯å¾„åˆ«åæ¯”较特殊:\n"
+"\n"
+" default:\n"
+" 当你使用 'hg clone' 创建版本库时,此命令会将æºç‰ˆæœ¬åº“çš„ä½ç½®ä¿å­˜\n"
+" 为新版本库的 'default' 路径,然åŽä½ å¯ä»¥å¯¹ç±»ä¼¼ 'push' å’Œ 'pull'\n"
+" 的命令çœç•¥è·¯å¾„(包å«è¿›å’Œå‡º)。\n"
+"\n"
+" default-push:\n"
+" 命令 'push' ä¼šæŸ¥æ‰¾åˆ«åæ˜¯ 'default-push' 的路径,它覆盖定义 'default'。\n"
+" "
+
+#, fuzzy
+msgid "Using additional features"
+msgstr "å¯ç”¨é¢å¤–的输出"
+
+#, fuzzy
+msgid "can only share local repositories"
+msgstr "为此版本库å¯åЍæœåŠ¡ 'inotify'"
+
+#, fuzzy
+msgid "destination already exists"
+msgstr "版本库 %s 已存在"
+
+msgid "updating working directory\n"
+msgstr "正在更新工作目录\n"
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr "目标目录: %s\n"
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "destination '%s' is not empty"
+msgstr "éžæœ¬åœ°ç‰ˆæœ¬åº“ '%s'"
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr ""
+
+msgid "clone from remote to remote not supported"
+msgstr ""
+
+msgid "updated"
+msgstr "已更新"
+
+msgid "merged"
+msgstr "å·²åˆå¹¶"
+
+msgid "removed"
+msgstr "已删除"
+
+msgid "unresolved"
+msgstr "未解决"
+
+#, python-format
+msgid "%d files %s"
+msgstr "%d 个文件%s"
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr ""
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to "
+"abandon\n"
+msgstr ""
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr ""
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr ""
+
+msgid "SSL support is unavailable"
+msgstr ""
+
+msgid "IPv6 is not available on this system"
+msgstr ""
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr ""
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook failed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr ""
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook %s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr ""
+
+msgid "connection ended unexpectedly"
+msgstr ""
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "using %s\n"
+msgstr "使用 %s\n"
+
+#, python-format
+msgid "capabilities: %s\n"
+msgstr ""
+
+msgid "operation not supported over http"
+msgstr ""
+
+#, python-format
+msgid "sending %s command\n"
+msgstr "å‘é€å‘½ä»¤ '%s'\n"
+
+#, python-format
+msgid "sending %s bytes\n"
+msgstr "å‘é€ %s 字节\n"
+
+msgid "authorization failed"
+msgstr "授æƒå¤±è´¥"
+
+#, python-format
+msgid "http error while sending %s command\n"
+msgstr ""
+
+msgid "http error, possibly caused by proxy setting"
+msgstr ""
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr "实际 URL 是 '%s'\n"
+
+#, fuzzy, python-format
+msgid "requested URL: '%s'\n"
+msgstr "请求的 URL: '%s'\n"
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr "'%s' ä¼¼ä¹Žä¸æ˜¯æ°´é“¶ç‰ˆæœ¬åº“"
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr ""
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr ""
+
+msgid "look up remote revision"
+msgstr ""
+
+msgid "unexpected response:"
+msgstr ""
+
+msgid "look up remote changes"
+msgstr ""
+
+msgid "push failed (unexpected response):"
+msgstr ""
+
+#, python-format
+msgid "push failed: %s"
+msgstr ""
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr ""
+
+msgid "cannot create new http repository"
+msgstr ""
+
+#, python-format
+msgid "%s: ignoring invalid syntax '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s not found"
+msgstr ""
+
+#, python-format
+msgid "repository %s already exists"
+msgstr "版本库 %s 已存在"
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr ""
+
+#, python-format
+msgid ".hg/sharedpath points to nonexistent directory %s"
+msgstr ""
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr ""
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr ""
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr ""
+
+msgid "cannot parse entry"
+msgstr ""
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr ""
+
+#, python-format
+msgid "working directory has unknown parent '%s'!"
+msgstr ""
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr ""
+
+#, python-format
+msgid "filtering %s through %s\n"
+msgstr ""
+
+msgid "journal already exists - run hg recover"
+msgstr ""
+
+msgid "rolling back interrupted transaction\n"
+msgstr "回滚中断的事务\n"
+
+msgid "no interrupted transaction available\n"
+msgstr ""
+
+msgid "rolling back last transaction\n"
+msgstr "回滚最近的事务\n"
+
+#, python-format
+msgid "Named branch could not be reset, current branch still is: %s\n"
+msgstr ""
+
+msgid "no rollback information available\n"
+msgstr "没有回滚信æ¯å¯ç”¨\n"
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s"
+msgstr ""
+
+#, python-format
+msgid "working directory of %s"
+msgstr ""
+
+#, python-format
+msgid " %s: searching for copy revision for %s\n"
+msgstr ""
+
+#, python-format
+msgid " %s: copy %s:%s\n"
+msgstr ""
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr ""
+
+#, fuzzy
+msgid "file not found!"
+msgstr "没有找到样å¼: %s"
+
+#, fuzzy
+msgid "no match under directory!"
+msgstr "改å˜å·¥ä½œç›®å½•"
+
+#, fuzzy
+msgid "file not tracked!"
+msgstr "%s 没有被跟踪!\n"
+
+msgid "nothing changed\n"
+msgstr "没有改å˜\n"
+
+msgid "unresolved merge conflicts (see hg resolve)"
+msgstr "未解决的åˆå¹¶å†²çª(å‚è§ 'hg resolve')"
+
+#, fuzzy, python-format
+msgid "committing subrepository %s\n"
+msgstr "åˆå§‹åŒ–目标版本库 %s\n"
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr "æäº¤ '%s' 出错!\n"
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr "%s ä¸å­˜åœ¨!\n"
+
+#, python-format
+msgid ""
+"%s: files over 10MB may cause memory and performance problems\n"
+"(use 'hg revert %s' to unadd the file)\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr ""
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added!\n"
+msgstr ""
+
+#, python-format
+msgid "%s still exists!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr "%s 没有被跟踪!\n"
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr ""
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr ""
+
+msgid "searching for changes\n"
+msgstr "正在æœç´¢ä¿®æ”¹\n"
+
+#, python-format
+msgid "examining %s:%s\n"
+msgstr ""
+
+msgid "branch already found\n"
+msgstr ""
+
+#, python-format
+msgid "found incomplete branch %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "found new changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "request %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "received %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowing %d:%d %s\n"
+msgstr ""
+
+#, python-format
+msgid "found new branch changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowed branch search to %s:%s\n"
+msgstr ""
+
+msgid "already have changeset "
+msgstr ""
+
+msgid "warning: repository is unrelated\n"
+msgstr ""
+
+msgid "repository is unrelated"
+msgstr ""
+
+msgid "found new changesets starting at "
+msgstr ""
+
+#, python-format
+msgid "%d total queries\n"
+msgstr ""
+
+msgid "common changesets up to "
+msgstr ""
+
+msgid "requesting all changes\n"
+msgstr "正在请求全部修改\n"
+
+msgid ""
+"Partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr ""
+
+#, python-format
+msgid "abort: push creates new remote branch '%s'!\n"
+msgstr ""
+
+msgid "abort: push creates new remote heads!\n"
+msgstr ""
+
+msgid "(did you forget to merge? use push -f to force)\n"
+msgstr ""
+
+msgid "note: unsynced remote changes!\n"
+msgstr ""
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr "å·²å‘现 %d 个修改集\n"
+
+msgid "list of changesets:\n"
+msgstr ""
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr ""
+
+#, python-format
+msgid "add changeset %s\n"
+msgstr ""
+
+msgid "adding changesets\n"
+msgstr "正在增加修改集\n"
+
+msgid "received changelog group is empty"
+msgstr ""
+
+msgid "adding manifests\n"
+msgstr "正在增加清å•\n"
+
+msgid "adding file changes\n"
+msgstr "正在增加文件改å˜\n"
+
+#, python-format
+msgid "adding %s revisions\n"
+msgstr ""
+
+msgid "received file revlog group is empty"
+msgstr ""
+
+#, python-format
+msgid " (%+d heads)"
+msgstr ""
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr "已增加 %d ä¸ªä¿®æ”¹é›†ï¼ŒåŒ…å« %d 个改å˜ï¼Œä¿®æ”¹äº† %d 个文件%s\n"
+
+msgid "updating the branch cache\n"
+msgstr ""
+
+msgid "Unexpected response from remote server:"
+msgstr ""
+
+msgid "operation forbidden by server"
+msgstr ""
+
+msgid "locking the remote repository failed"
+msgstr ""
+
+msgid "the server sent an unknown error code"
+msgstr ""
+
+msgid "streaming all changes\n"
+msgstr ""
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr ""
+
+#, python-format
+msgid "adding %s (%s)\n"
+msgstr ""
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr ""
+
+msgid "no [smtp]host in hgrc - cannot send mail"
+msgstr ""
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr ""
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr ""
+
+msgid "(using tls)\n"
+msgstr ""
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr ""
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr ""
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr ""
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr ""
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr ""
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr ""
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr ""
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr ""
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr ""
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+
+#, fuzzy
+msgid "&None"
+msgstr "完æˆ\n"
+
+msgid "E&xec"
+msgstr ""
+
+msgid "Sym&link"
+msgstr ""
+
+msgid "resolving manifests\n"
+msgstr "æ­£åœ¨è§£æžæ¸…å•\n"
+
+#, python-format
+msgid " overwrite %s partial %s\n"
+msgstr ""
+
+#, python-format
+msgid " ancestor %s local %s remote %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+msgid "&Changed"
+msgstr ""
+
+msgid "&Delete"
+msgstr ""
+
+msgid "c"
+msgstr ""
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+
+msgid "&Deleted"
+msgstr ""
+
+#, python-format
+msgid "preserving %s for resolve of %s\n"
+msgstr ""
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s\n"
+msgstr "正在检出 %s\n"
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "warning: detected divergent renames of %s to:\n"
+msgstr ""
+
+#, python-format
+msgid "branch %s not found"
+msgstr ""
+
+msgid "can't merge with ancestor"
+msgstr ""
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr ""
+
+msgid "outstanding uncommitted changes (use 'hg status' to list changes)"
+msgstr ""
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C' to discard changes)"
+msgstr ""
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C')"
+msgstr ""
+
+msgid "crosses named branches (use 'hg update -C' to discard changes)"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr ""
+
+#, python-format
+msgid "found patch at byte %d\n"
+msgstr ""
+
+msgid "patch generated by hg export\n"
+msgstr ""
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr ""
+
+#, python-format
+msgid "patching file %s\n"
+msgstr ""
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr ""
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d line).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d lines).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr ""
+
+msgid "could not extract binary patch"
+msgstr ""
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr ""
+
+#, python-format
+msgid "unable to strip away %d dirs from %s"
+msgstr ""
+
+msgid "undefined source and destination files"
+msgstr ""
+
+#, python-format
+msgid "malformed patch %s %s"
+msgstr ""
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr ""
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr ""
+
+#, python-format
+msgid "Unsupported line endings type: %s"
+msgstr ""
+
+#, python-format
+msgid "no valid hunks found; trying with %r instead\n"
+msgstr ""
+
+#, python-format
+msgid "exited with status %d"
+msgstr ""
+
+#, python-format
+msgid "killed by signal %d"
+msgstr ""
+
+#, python-format
+msgid "stopped by signal %d"
+msgstr ""
+
+msgid "invalid exit code"
+msgstr ""
+
+#, python-format
+msgid "saving bundle to %s\n"
+msgstr ""
+
+msgid "adding branch\n"
+msgstr ""
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr ""
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr ""
+
+#, python-format
+msgid "index %s is corrupted"
+msgstr ""
+
+msgid "no node"
+msgstr ""
+
+msgid "ambiguous identifier"
+msgstr ""
+
+msgid "no match found"
+msgstr ""
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr ""
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr ""
+
+msgid "unknown base"
+msgstr ""
+
+msgid "consistency error adding group"
+msgstr ""
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr ""
+
+msgid "can only specify two labels."
+msgstr ""
+
+msgid "warning: conflicts during merge.\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr ""
+
+msgid "could not create remote repo"
+msgstr ""
+
+msgid "remote: "
+msgstr ""
+
+msgid "no suitable response from remote hg"
+msgstr ""
+
+#, python-format
+msgid "push refused: %s"
+msgstr ""
+
+msgid "unsynced changes"
+msgstr ""
+
+msgid "cannot lock static-http repository"
+msgstr ""
+
+msgid "cannot create new static-http repository"
+msgstr ""
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr ""
+
+msgid "scanning\n"
+msgstr "正在扫æ\n"
+
+#, python-format
+msgid "%d files, %d bytes to transfer\n"
+msgstr "需è¦ä¼ è¾“ %d 个文件,%d 字节\n"
+
+#, python-format
+msgid "sending %s (%d bytes)\n"
+msgstr "正在å‘é€ %s (%d 字节)\n"
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?"
+msgstr ""
+
+msgid "&Remote"
+msgstr ""
+
+msgid "r"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed subrepository %s which remote removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid ""
+" remote changed subrepository %s which local removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "removing subrepo %s\n"
+msgstr "正在删除 %s\n"
+
+#, fuzzy, python-format
+msgid "pulling subrepo %s\n"
+msgstr "正在拉自 %s\n"
+
+#, fuzzy, python-format
+msgid "pushing subrepo %s\n"
+msgstr "正在推到 %s\n"
+
+msgid "unmatched quotes"
+msgstr "ä¸åŒ¹é…的引å·"
+
+#, python-format
+msgid "error expanding '%s%%%s'"
+msgstr ""
+
+#, python-format
+msgid "unknown filter '%s'"
+msgstr ""
+
+#, python-format
+msgid "style not found: %s"
+msgstr "没有找到样å¼: %s"
+
+#, python-format
+msgid "template file %s: %s"
+msgstr "模版文件 %s: %s"
+
+msgid "cannot use transaction when it is already committed/aborted"
+msgstr ""
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr "截断 '%s' 失败\n"
+
+msgid "transaction abort!\n"
+msgstr "事务中止!\n"
+
+msgid "rollback completed\n"
+msgstr "完æˆå›žæ»š\n"
+
+msgid "rollback failed - please run hg recover\n"
+msgstr ""
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "ignoring untrusted configuration option %s.%s = %s\n"
+msgstr "显示ä¸èƒ½ä¿¡èµ–çš„é…置选项"
+
+#, python-format
+msgid "%s.%s not a boolean ('%s')"
+msgstr ""
+
+msgid "enter a commit username:"
+msgstr ""
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr ""
+
+msgid "Please specify a username."
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr ""
+
+msgid "unrecognized response\n"
+msgstr ""
+
+msgid "response expected"
+msgstr ""
+
+msgid "password: "
+msgstr "密ç : "
+
+msgid "edit failed"
+msgstr ""
+
+msgid "http authorization required"
+msgstr "éœ€è¦ http 授æƒ"
+
+msgid "http authorization required\n"
+msgstr "éœ€è¦ http 授æƒ\n"
+
+#, python-format
+msgid "realm: %s\n"
+msgstr "领域: %s\n"
+
+#, python-format
+msgid "user: %s\n"
+msgstr "用户: %s\n"
+
+msgid "user:"
+msgstr "用户:"
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr ""
+
+#, python-format
+msgid "proxying through http://%s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr ""
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr ""
+
+#, python-format
+msgid "path %r is inside repo %r"
+msgstr ""
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr ""
+
+msgid "Hardlinks not supported"
+msgstr ""
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid date: %r "
+msgstr ""
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr ""
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr ""
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr ""
+
+#, python-format
+msgid "%.0f GB"
+msgstr ""
+
+#, python-format
+msgid "%.1f GB"
+msgstr ""
+
+#, python-format
+msgid "%.2f GB"
+msgstr ""
+
+#, python-format
+msgid "%.0f MB"
+msgstr ""
+
+#, python-format
+msgid "%.1f MB"
+msgstr ""
+
+#, python-format
+msgid "%.2f MB"
+msgstr ""
+
+#, python-format
+msgid "%.0f KB"
+msgstr ""
+
+#, python-format
+msgid "%.1f KB"
+msgstr ""
+
+#, python-format
+msgid "%.2f KB"
+msgstr ""
+
+#, python-format
+msgid "%.0f bytes"
+msgstr ""
+
+msgid "cannot verify bundle or remote repos"
+msgstr ""
+
+msgid "interrupted"
+msgstr ""
+
+#, python-format
+msgid "empty or missing %s"
+msgstr ""
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr ""
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to nonexistent changeset %d"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to unexpected changeset %d"
+msgstr ""
+
+#, python-format
+msgid " (expected %s)"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "checking parents of %s"
+msgstr ""
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr ""
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr ""
+
+msgid "checking changesets\n"
+msgstr ""
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr ""
+
+msgid "checking manifests\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "%s not in changesets"
+msgstr "列出修改集"
+
+msgid "file without name in manifest"
+msgstr ""
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr ""
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr ""
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr ""
+
+msgid "in changeset but not in manifest"
+msgstr ""
+
+msgid "in manifest but not in changeset"
+msgstr ""
+
+msgid "checking files\n"
+msgstr ""
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr ""
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr ""
+
+msgid "missing revlog!"
+msgstr ""
+
+#, python-format
+msgid "%s not in manifests"
+msgstr ""
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr ""
+
+#, python-format
+msgid "unpacking %s"
+msgstr ""
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s"
+msgstr ""
+
+#, python-format
+msgid "checking rename of %s"
+msgstr ""
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr ""
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr ""
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr ""
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr ""
+
+msgid "user name not available - set USERNAME environment variable"
+msgstr ""
diff --git a/sys/src/cmd/hg/i18n/zh_TW.po b/sys/src/cmd/hg/i18n/zh_TW.po
new file mode 100644
index 000000000..2aef5dff7
--- /dev/null
+++ b/sys/src/cmd/hg/i18n/zh_TW.po
@@ -0,0 +1,9255 @@
+# Traditional Chinese translation for Mercurial
+# Copyright (C) 2009 Matt Mackall <mpm@selenic.com> and others
+# This file is distributed under the same license as the Mercurial package.
+# Chia-Huan Wu <willie.tw@gmail.com>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial\n"
+"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
+"POT-Creation-Date: 2009-06-10 22:09+0800\n"
+"PO-Revision-Date: 2009-06-18 21:12+0200\n"
+"Last-Translator: Chia-Huan Wu <willie.tw@gmail.com>\n"
+"Language-Team: Traditional Chinese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (é è¨­: %s)"
+
+msgid "OPTIONS"
+msgstr "é¸é …"
+
+msgid "COMMANDS"
+msgstr "命令"
+
+msgid " options:\n"
+msgstr " é¸é …: \n"
+
+#, python-format
+msgid ""
+" aliases: %s\n"
+"\n"
+msgstr ""
+" 別å: %s\n"
+"\n"
+
+#, python-format
+msgid "acl: %s not enabled\n"
+msgstr "acl: %s 尚未啟用\n"
+
+#, python-format
+msgid "acl: %s enabled, %d entries for user %s\n"
+msgstr ""
+
+#, python-format
+msgid "config error - hook type \"%s\" cannot stop incoming changesets"
+msgstr ""
+
+#, python-format
+msgid "acl: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+#, python-format
+msgid "acl: user %s denied on %s\n"
+msgstr ""
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr ""
+
+#, python-format
+msgid "acl: user %s not allowed on %s\n"
+msgstr ""
+
+#, python-format
+msgid "acl: allowing changeset %s\n"
+msgstr ""
+
+msgid ""
+"Mercurial bookmarks\n"
+"\n"
+"Mercurial bookmarks are local moveable pointers to changesets. Every\n"
+"bookmark points to a changeset identified by its hash. If you commit a\n"
+"changeset that is based on a changeset that has a bookmark on it, the\n"
+"bookmark is forwarded to the new changeset.\n"
+"\n"
+"It is possible to use bookmark names in every revision lookup (e.g. hg\n"
+"merge, hg update).\n"
+"\n"
+"The bookmark extension offers the possiblity to have a more git-like\n"
+"experience by adding the following configuration option to your .hgrc:\n"
+"\n"
+"[bookmarks]\n"
+"track.current = True\n"
+"\n"
+"This will cause bookmarks to track the bookmark that you are currently\n"
+"on, and just updates it. This is similar to git's approach to\n"
+"branching.\n"
+msgstr ""
+
+msgid ""
+"Mercurial bookmarks\n"
+"\n"
+" Bookmarks are pointers to certain commits that move when\n"
+" commiting. Bookmarks are local. They can be renamed, copied and\n"
+" deleted. It is possible to use bookmark names in 'hg merge' and\n"
+" 'hg update' to merge and update respectively to a given bookmark.\n"
+"\n"
+" You can use 'hg bookmark NAME' to set a bookmark on the working\n"
+" directory's parent revision with the given name. If you specify\n"
+" a revision using -r REV (where REV may be an existing bookmark),\n"
+" the bookmark is assigned to that revision.\n"
+" "
+msgstr ""
+
+msgid "a bookmark of this name does not exist"
+msgstr ""
+
+msgid "a bookmark of the same name already exists"
+msgstr ""
+
+msgid "new bookmark name required"
+msgstr ""
+
+msgid "bookmark name required"
+msgstr ""
+
+msgid "bookmark name cannot contain newlines"
+msgstr ""
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr ""
+
+msgid "force"
+msgstr ""
+
+msgid "revision"
+msgstr ""
+
+msgid "delete a given bookmark"
+msgstr ""
+
+msgid "rename a given bookmark"
+msgstr ""
+
+msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
+msgstr ""
+
+msgid ""
+"Bugzilla integration\n"
+"\n"
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
+"bug status.\n"
+"\n"
+"The hook updates the Bugzilla database directly. Only Bugzilla\n"
+"installations using MySQL are supported.\n"
+"\n"
+"The hook relies on a Bugzilla script to send bug change notification\n"
+"emails. That script changes between Bugzilla versions; the\n"
+"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
+"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
+"be run by Mercurial as the user pushing the change; you will need to\n"
+"ensure the Bugzilla install file permissions are set appropriately.\n"
+"\n"
+"Configuring the extension:\n"
+"\n"
+" [bugzilla]\n"
+"\n"
+" host Hostname of the MySQL server holding the Bugzilla\n"
+" database.\n"
+" db Name of the Bugzilla database in MySQL. Default 'bugs'.\n"
+" user Username to use to access MySQL server. Default 'bugs'.\n"
+" password Password to use to access MySQL server.\n"
+" timeout Database connection timeout (seconds). Default 5.\n"
+" version Bugzilla version. Specify '3.0' for Bugzilla versions\n"
+" 3.0 and later, '2.18' for Bugzilla versions from 2.18\n"
+" and '2.16' for versions prior to 2.18.\n"
+" bzuser Fallback Bugzilla user name to record comments with, if\n"
+" changeset committer cannot be found as a Bugzilla user.\n"
+" bzdir Bugzilla install directory. Used by default notify.\n"
+" Default '/var/www/html/bugzilla'.\n"
+" notify The command to run to get Bugzilla to send bug change\n"
+" notification emails. Substitutes from a map with 3\n"
+" keys, 'bzdir', 'id' (bug id) and 'user' (committer\n"
+" bugzilla email). Default depends on version; from 2.18\n"
+" it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
+" %(id)s %(user)s\".\n"
+" regexp Regular expression to match bug IDs in changeset commit\n"
+" message. Must contain one \"()\" group. The default\n"
+" expression matches 'Bug 1234', 'Bug no. 1234', 'Bug\n"
+" number 1234', 'Bugs 1234,5678', 'Bug 1234 and 5678' and\n"
+" variations thereof. Matching is case insensitive.\n"
+" style The style file to use when formatting comments.\n"
+" template Template to use when formatting comments. Overrides\n"
+" style if specified. In addition to the usual Mercurial\n"
+" keywords, the extension specifies:\n"
+" {bug} The Bugzilla bug ID.\n"
+" {root} The full pathname of the Mercurial\n"
+" repository.\n"
+" {webroot} Stripped pathname of the Mercurial\n"
+" repository.\n"
+" {hgweb} Base URL for browsing Mercurial\n"
+" repositories.\n"
+" Default 'changeset {node|short} in repo {root} refers '\n"
+" 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'\n"
+" strip The number of slashes to strip from the front of {root}\n"
+" to produce {webroot}. Default 0.\n"
+" usermap Path of file containing Mercurial committer ID to\n"
+" Bugzilla user ID mappings. If specified, the file\n"
+" should contain one mapping per line,\n"
+" \"committer\"=\"Bugzilla user\". See also the [usermap]\n"
+" section.\n"
+"\n"
+" [usermap]\n"
+" Any entries in this section specify mappings of Mercurial\n"
+" committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
+" \"committer\"=\"Bugzilla user\"\n"
+"\n"
+" [web]\n"
+" baseurl Base URL for browsing Mercurial repositories. Reference\n"
+" from templates as {hgweb}.\n"
+"\n"
+"Activating the extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.bugzilla =\n"
+"\n"
+" [hooks]\n"
+" # run bugzilla hook on every change pulled or pushed in here\n"
+" incoming.bugzilla = python:hgext.bugzilla.hook\n"
+"\n"
+"Example configuration:\n"
+"\n"
+"This example configuration is for a collection of Mercurial\n"
+"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
+"installation in /opt/bugzilla-3.2.\n"
+"\n"
+" [bugzilla]\n"
+" host=localhost\n"
+" password=XYZZY\n"
+" version=3.0\n"
+" bzuser=unknown@domain.com\n"
+" bzdir=/opt/bugzilla-3.2\n"
+" template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/"
+"rev/{node|short}\\n\\n{desc}\\n\n"
+" strip=5\n"
+"\n"
+" [web]\n"
+" baseurl=http://dev.domain.com/hg\n"
+"\n"
+" [usermap]\n"
+" user@emaildomain.com=user.name@bugzilladomain.com\n"
+"\n"
+"Commits add a comment to the Bugzilla bug record of the form:\n"
+"\n"
+" Changeset 3b16791d6642 in repository-name.\n"
+" http://dev.domain.com/hg/repository-name/rev/3b16791d6642\n"
+"\n"
+" Changeset commit comment. Bug 1234.\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr ""
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr ""
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr ""
+
+msgid "unknown database schema"
+msgstr ""
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr ""
+
+msgid "telling bugzilla to send mail:\n"
+msgstr ""
+
+#, python-format
+msgid " bug %s\n"
+msgstr ""
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr ""
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr ""
+
+msgid "done\n"
+msgstr ""
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr ""
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr ""
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr ""
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr ""
+
+#, python-format
+msgid "database error: %s"
+msgstr ""
+
+msgid ""
+"show the children of the given or working directory revision\n"
+"\n"
+" Print the children of the working directory's revisions. If a\n"
+" revision is given via -r/--rev, the children of that revision will\n"
+" be printed. If a file argument is given, revision in which the\n"
+" file was last changed (after the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+
+msgid "show children of the specified revision"
+msgstr ""
+
+msgid "hg children [-r REV] [FILE]"
+msgstr ""
+
+msgid "command to show certain statistics about revision history"
+msgstr ""
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr ""
+
+#, python-format
+msgid "generating stats: %d%%"
+msgstr ""
+
+msgid ""
+"graph count of revisions grouped by template\n"
+"\n"
+" Will graph count of changed lines or revisions grouped by template\n"
+" or alternatively by date, if dateformat is used. In this case it\n"
+" will override template.\n"
+"\n"
+" By default statistics are counted for number of changed lines.\n"
+"\n"
+" Examples:\n"
+"\n"
+" # display count of changed lines for every committer\n"
+" hg churn -t '{author|email}'\n"
+"\n"
+" # display daily activity graph\n"
+" hg churn -f '%H' -s -c\n"
+"\n"
+" # display activity of developers by month\n"
+" hg churn -f '%Y-%m' -s -c\n"
+"\n"
+" # display count of lines changed in every year\n"
+" hg churn -f '%Y' -s\n"
+"\n"
+" The map file format used to specify aliases is fairly simple:\n"
+"\n"
+" <alias email> <actual email>\n"
+"\n"
+" By default .hgchurn in the working directory root will be used, if\n"
+" it exists. Use the --aliases option to override this.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "assuming %i character terminal\n"
+msgstr ""
+
+msgid "count rate for the specified revision or range"
+msgstr ""
+
+msgid "count rate for revisions matching date spec"
+msgstr ""
+
+msgid "template to group changesets"
+msgstr ""
+
+msgid "strftime-compatible format for grouping by date"
+msgstr ""
+
+msgid "count rate by number of changesets"
+msgstr ""
+
+msgid "sort by key (default: sort by count)"
+msgstr ""
+
+msgid "file with email aliases"
+msgstr ""
+
+msgid "show progress"
+msgstr ""
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]"
+msgstr ""
+
+msgid ""
+"add color output to status, qseries, and diff-related commands\n"
+"\n"
+"This extension modifies the status command to add color to its output\n"
+"to reflect file status, the qseries command to add color to reflect\n"
+"patch status (applied, unapplied, missing), and to diff-related\n"
+"commands to highlight additions, removals, diff headers, and trailing\n"
+"whitespace.\n"
+"\n"
+"Other effects in addition to color, like bold and underlined text, are\n"
+"also available. Effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes). This module also provides the\n"
+"render_text function, which can be used to add effects to any text.\n"
+"\n"
+"To enable this extension, add this to your .hgrc file:\n"
+"[extensions]\n"
+"color =\n"
+"\n"
+"Default effects may be overridden from the .hgrc file:\n"
+"\n"
+"[color]\n"
+"status.modified = blue bold underline red_background\n"
+"status.added = green bold\n"
+"status.removed = red bold blue_background\n"
+"status.deleted = cyan bold underline\n"
+"status.unknown = magenta bold underline\n"
+"status.ignored = black bold\n"
+"\n"
+"# 'none' turns off all effects\n"
+"status.clean = none\n"
+"status.copied = none\n"
+"\n"
+"qseries.applied = blue bold underline\n"
+"qseries.unapplied = black bold\n"
+"qseries.missing = red bold\n"
+"\n"
+"diff.diffline = bold\n"
+"diff.extended = cyan bold\n"
+"diff.file_a = red bold\n"
+"diff.file_b = green bold\n"
+"diff.hunk = magenta\n"
+"diff.deleted = red\n"
+"diff.inserted = green\n"
+"diff.changed = white\n"
+"diff.trailingwhitespace = bold red_background\n"
+msgstr ""
+
+msgid "when to colorize (always, auto, or never)"
+msgstr ""
+
+msgid "don't colorize output"
+msgstr ""
+
+msgid "converting foreign VCS repositories to Mercurial"
+msgstr ""
+
+msgid ""
+"convert a foreign SCM repository to a Mercurial one.\n"
+"\n"
+" Accepted source formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - CVS [cvs]\n"
+" - Darcs [darcs]\n"
+" - git [git]\n"
+" - Subversion [svn]\n"
+" - Monotone [mtn]\n"
+" - GNU Arch [gnuarch]\n"
+" - Bazaar [bzr]\n"
+" - Perforce [p4]\n"
+"\n"
+" Accepted destination formats [identifiers]:\n"
+" - Mercurial [hg]\n"
+" - Subversion [svn] (history on branches is not preserved)\n"
+"\n"
+" If no revision is given, all revisions will be converted.\n"
+" Otherwise, convert will only import up to the named revision\n"
+" (given in a format understood by the source).\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source with '-hg' appended. If the destination\n"
+" repository doesn't exist, it will be created.\n"
+"\n"
+" By default, all sources except Mercurial will use\n"
+" --branchsort. Mercurial uses --sourcesort to preserve original\n"
+" revision numbers order. Sort modes have the following effects:\n"
+" --branchsort: convert from parent to child revision when\n"
+" possible, which means branches are usually converted one after\n"
+" the other. It generates more compact repositories.\n"
+" --datesort: sort revisions by date. Converted repositories have\n"
+" good-looking changelogs but are often an order of magnitude\n"
+" larger than the same ones generated by --branchsort.\n"
+" --sourcesort: try to preserve source revisions order, only\n"
+" supported by Mercurial sources.\n"
+"\n"
+" If <REVMAP> isn't given, it will be put in a default location\n"
+" (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file\n"
+" that maps each source commit ID to the destination ID for that\n"
+" revision, like so:\n"
+" <source ID> <destination ID>\n"
+"\n"
+" If the file doesn't exist, it's automatically created. It's\n"
+" updated on each commit copied, so convert-repo can be interrupted\n"
+" and can be run repeatedly to copy new commits.\n"
+"\n"
+" The [username mapping] file is a simple text file that maps each\n"
+" source commit author to a destination commit author. It is handy\n"
+" for source SCMs that use unix logins to identify authors (eg:\n"
+" CVS). One line per author mapping and the line format is:\n"
+" srcauthor=whatever string you want\n"
+"\n"
+" The filemap is a file that allows filtering and remapping of files\n"
+" and directories. Comment lines start with '#'. Each line can\n"
+" contain one of the following directives:\n"
+"\n"
+" include path/to/file\n"
+"\n"
+" exclude path/to/file\n"
+"\n"
+" rename from/file to/file\n"
+"\n"
+" The 'include' directive causes a file, or all files under a\n"
+" directory, to be included in the destination repository, and the\n"
+" exclusion of all other files and directories not explicitly included.\n"
+" The 'exclude' directive causes files or directories to be omitted.\n"
+" The 'rename' directive renames a file or directory. To rename from\n"
+" a subdirectory into the root of the repository, use '.' as the\n"
+" path to rename to.\n"
+"\n"
+" The splicemap is a file that allows insertion of synthetic\n"
+" history, letting you specify the parents of a revision. This is\n"
+" useful if you want to e.g. give a Subversion merge two parents, or\n"
+" graft two disconnected series of history together. Each entry\n"
+" contains a key, followed by a space, followed by one or two\n"
+" comma-separated values. The key is the revision ID in the source\n"
+" revision control system whose parents should be modified (same\n"
+" format as a key in .hg/shamap). The values are the revision IDs\n"
+" (in either the source or destination revision control system) that\n"
+" should be used as the new parents for that node.\n"
+"\n"
+" The branchmap is a file that allows you to rename a branch when it is\n"
+" being brought in from whatever external repository. When used in\n"
+" conjunction with a splicemap, it allows for a powerful combination\n"
+" to help fix even the most badly mismanaged repositories and turn them\n"
+" into nicely structured Mercurial repositories. The branchmap contains\n"
+" lines of the form \"original_branch_name new_branch_name\".\n"
+" \"original_branch_name\" is the name of the branch in the source\n"
+" repository, and \"new_branch_name\" is the name of the branch is the\n"
+" destination repository. This can be used to (for instance) move code\n"
+" in one repository from \"default\" to a named branch.\n"
+"\n"
+" Mercurial Source\n"
+" -----------------\n"
+"\n"
+" --config convert.hg.ignoreerrors=False (boolean)\n"
+" ignore integrity errors when reading. Use it to fix Mercurial\n"
+" repositories with missing revlogs, by converting from and to\n"
+" Mercurial.\n"
+" --config convert.hg.saverev=False (boolean)\n"
+" store original revision ID in changeset (forces target IDs to\n"
+" change)\n"
+" --config convert.hg.startrev=0 (hg revision identifier)\n"
+" convert start revision and its descendants\n"
+"\n"
+" CVS Source\n"
+" ----------\n"
+"\n"
+" CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+" to indicate the starting point of what will be converted. Direct\n"
+" access to the repository files is not needed, unless of course the\n"
+" repository is :local:. The conversion uses the top level directory\n"
+" in the sandbox to find the CVS repository, and then uses CVS rlog\n"
+" commands to find files to convert. This means that unless a\n"
+" filemap is given, all files under the starting directory will be\n"
+" converted, and that any directory reorganization in the CVS\n"
+" sandbox is ignored.\n"
+"\n"
+" Because CVS does not have changesets, it is necessary to collect\n"
+" individual commits to CVS and merge them into changesets. CVS\n"
+" source uses its internal changeset merging code by default but can\n"
+" be configured to call the external 'cvsps' program by setting:\n"
+" --config convert.cvsps='cvsps -A -u --cvs-direct -q'\n"
+" This option is deprecated and will be removed in Mercurial 1.4.\n"
+"\n"
+" The options shown are the defaults.\n"
+"\n"
+" Internal cvsps is selected by setting\n"
+" --config convert.cvsps=builtin\n"
+" and has a few more configurable options:\n"
+" --config convert.cvsps.cache=True (boolean)\n"
+" Set to False to disable remote log caching, for testing and\n"
+" debugging purposes.\n"
+" --config convert.cvsps.fuzz=60 (integer)\n"
+" Specify the maximum time (in seconds) that is allowed\n"
+" between commits with identical user and log message in a\n"
+" single changeset. When very large files were checked in as\n"
+" part of a changeset then the default may not be long\n"
+" enough.\n"
+" --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will insert a dummy revision merging the branch on\n"
+" which this log message occurs to the branch indicated in\n"
+" the regex.\n"
+" --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
+" Specify a regular expression to which commit log messages\n"
+" are matched. If a match occurs, then the conversion\n"
+" process will add the most recent revision on the branch\n"
+" indicated in the regex as the second parent of the\n"
+" changeset.\n"
+"\n"
+" The hgext/convert/cvsps wrapper script allows the builtin\n"
+" changeset merging code to be run without doing a conversion. Its\n"
+" parameters and output are similar to that of cvsps 2.1.\n"
+"\n"
+" Subversion Source\n"
+" -----------------\n"
+"\n"
+" Subversion source detects classical trunk/branches/tags layouts.\n"
+" By default, the supplied \"svn://repo/path/\" source URL is\n"
+" converted as a single branch. If \"svn://repo/path/trunk\" exists it\n"
+" replaces the default branch. If \"svn://repo/path/branches\" exists,\n"
+" its subdirectories are listed as possible branches. If\n"
+" \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
+" converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
+" can be overridden with following options. Set them to paths\n"
+" relative to the source URL, or leave them blank to disable auto\n"
+" detection.\n"
+"\n"
+" --config convert.svn.branches=branches (directory name)\n"
+" specify the directory containing branches\n"
+" --config convert.svn.tags=tags (directory name)\n"
+" specify the directory containing tags\n"
+" --config convert.svn.trunk=trunk (directory name)\n"
+" specify the name of the trunk branch\n"
+"\n"
+" Source history can be retrieved starting at a specific revision,\n"
+" instead of being integrally converted. Only single branch\n"
+" conversions are supported.\n"
+"\n"
+" --config convert.svn.startrev=0 (svn revision number)\n"
+" specify start Subversion revision.\n"
+"\n"
+" Perforce Source\n"
+" ---------------\n"
+"\n"
+" The Perforce (P4) importer can be given a p4 depot path or a\n"
+" client specification as source. It will convert all files in the\n"
+" source to a flat Mercurial repository, ignoring labels, branches\n"
+" and integrations. Note that when a depot path is given you then\n"
+" usually should specify a target directory, because otherwise the\n"
+" target may be named ...-hg.\n"
+"\n"
+" It is possible to limit the amount of source history to be\n"
+" converted by specifying an initial Perforce revision.\n"
+"\n"
+" --config convert.p4.startrev=0 (perforce changelist number)\n"
+" specify initial Perforce revision.\n"
+"\n"
+"\n"
+" Mercurial Destination\n"
+" ---------------------\n"
+"\n"
+" --config convert.hg.clonebranches=False (boolean)\n"
+" dispatch source branches in separate clones.\n"
+" --config convert.hg.tagsbranch=default (branch name)\n"
+" tag revisions branch name\n"
+" --config convert.hg.usebranchnames=True (boolean)\n"
+" preserve branch names\n"
+"\n"
+" "
+msgstr ""
+
+msgid ""
+"create changeset information from CVS\n"
+"\n"
+" This command is intended as a debugging tool for the CVS to\n"
+" Mercurial converter, and can be used as a direct replacement for\n"
+" cvsps.\n"
+"\n"
+" Hg debugcvsps reads the CVS rlog for current directory (or any\n"
+" named directory) in the CVS repository, and converts the log to a\n"
+" series of changesets based on matching commit log entries and\n"
+" dates."
+msgstr ""
+
+msgid "username mapping filename"
+msgstr ""
+
+msgid "destination repository type"
+msgstr ""
+
+msgid "remap file names using contents of file"
+msgstr ""
+
+msgid "import up to target revision REV"
+msgstr ""
+
+msgid "source repository type"
+msgstr ""
+
+msgid "splice synthesized history into place"
+msgstr ""
+
+msgid "change branch names while converting"
+msgstr ""
+
+msgid "try to sort changesets by branches"
+msgstr ""
+
+msgid "try to sort changesets by date"
+msgstr ""
+
+msgid "preserve source changesets order"
+msgstr ""
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr ""
+
+msgid "only return changes on specified branches"
+msgstr ""
+
+msgid "prefix to remove from file names"
+msgstr ""
+
+msgid "only return changes after or between specified tags"
+msgstr ""
+
+msgid "update cvs log cache"
+msgstr ""
+
+msgid "create new cvs log cache"
+msgstr ""
+
+msgid "set commit time fuzz in seconds"
+msgstr ""
+
+msgid "specify cvsroot"
+msgstr ""
+
+msgid "show parent changesets"
+msgstr ""
+
+msgid "show current changeset in ancestor branches"
+msgstr ""
+
+msgid "ignored for compatibility"
+msgstr ""
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr ""
+
+msgid ""
+"warning: lightweight checkouts may cause conversion failures, try with a "
+"regular branch instead.\n"
+msgstr ""
+
+msgid "bzr source type could not be determined\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr ""
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr ""
+
+#, python-format
+msgid "%s.%s symlink has no target"
+msgstr ""
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr ""
+
+#, python-format
+msgid "running: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s error:\n"
+msgstr ""
+
+#, python-format
+msgid "%s %s"
+msgstr ""
+
+#, python-format
+msgid "syntax error in %s(%d): key/value pair expected"
+msgstr ""
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr ""
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr ""
+
+#, python-format
+msgid "convert: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr ""
+
+#, python-format
+msgid "unknown sort mode: %s"
+msgstr ""
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr ""
+
+msgid "not all revisions were sorted"
+msgstr ""
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "overriding mapping for author %s, was %s, will be %s\n"
+msgstr ""
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr ""
+
+msgid "scanning source...\n"
+msgstr ""
+
+msgid "sorting...\n"
+msgstr ""
+
+msgid "converting...\n"
+msgstr ""
+
+#, python-format
+msgid "source: %s\n"
+msgstr ""
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr ""
+
+msgid "more than one sort mode specified"
+msgstr ""
+
+msgid "--sourcesort is not supported by this data source"
+msgstr ""
+
+msgid ""
+"warning: support for external cvsps is deprecated and will be removed in "
+"Mercurial 1.4\n"
+msgstr ""
+
+#, python-format
+msgid "revision %s is not a patchset number or date"
+msgstr ""
+
+msgid "using builtin cvsps\n"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr ""
+
+msgid "CVS pserver authentication failed"
+msgstr ""
+
+msgid "server sucks"
+msgstr ""
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr ""
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr ""
+
+msgid "collecting CVS rlog\n"
+msgstr ""
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr ""
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr ""
+
+#, python-format
+msgid "running %s\n"
+msgstr ""
+
+#, python-format
+msgid "prefix=%r directory=%r root=%r\n"
+msgstr ""
+
+msgid "RCS file must be followed by working file"
+msgstr ""
+
+msgid "must have at least some revisions"
+msgstr ""
+
+msgid "expected revision number"
+msgstr ""
+
+msgid "revision must be followed by date line"
+msgstr ""
+
+#, python-format
+msgid "found synthetic revision in %s: %r\n"
+msgstr ""
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "%d log entries\n"
+msgstr ""
+
+msgid "creating changesets\n"
+msgstr ""
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: CVS commit message references non-existent branch %r:\n"
+"%s\n"
+msgstr ""
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr ""
+
+msgid "Python ElementTree module is not available"
+msgstr ""
+
+#, python-format
+msgid "cleaning up %s\n"
+msgstr ""
+
+msgid "internal calling inconsistency"
+msgstr ""
+
+msgid "errors in filemap"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr ""
+
+msgid "source repository doesn't support --filemap"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a GNU Arch repo"
+msgstr ""
+
+msgid "cannot find a GNU Arch tool"
+msgstr ""
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr ""
+
+#, python-format
+msgid "applying revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "computing changeset between %s and %s...\n"
+msgstr ""
+
+#, python-format
+msgid "obtaining revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "analyzing revision %s...\n"
+msgstr ""
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr ""
+
+#, python-format
+msgid "%s is not a local Mercurial repo"
+msgstr ""
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr ""
+
+msgid "run hg sink pre-conversion action\n"
+msgstr ""
+
+msgid "run hg sink post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr ""
+
+msgid "filtering out empty revision\n"
+msgstr ""
+
+msgid "updating tags\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr ""
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr ""
+
+msgid "run hg source pre-conversion action\n"
+msgstr ""
+
+msgid "run hg source post-conversion action\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a monotone repo"
+msgstr ""
+
+#, python-format
+msgid "copying file in renamed directory from '%s' to '%s'"
+msgstr ""
+
+msgid "reading p4 views\n"
+msgstr ""
+
+msgid "collecting p4 changelists\n"
+msgstr ""
+
+msgid "Subversion python bindings could not be loaded"
+msgstr ""
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr ""
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr ""
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr ""
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr ""
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr ""
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr ""
+
+msgid "svn: start revision is not supported with more than one branch"
+msgstr ""
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr ""
+
+#, python-format
+msgid "no tags found at revision %d\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring foreign branch %r\n"
+msgstr ""
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr ""
+
+#, python-format
+msgid "branch renamed from %s to %s at %d\n"
+msgstr ""
+
+#, python-format
+msgid "reparent to %s\n"
+msgstr ""
+
+#, python-format
+msgid "copied to %s from %s@%s\n"
+msgstr ""
+
+#, python-format
+msgid "gone from %s\n"
+msgstr ""
+
+#, python-format
+msgid "found parent directory %s\n"
+msgstr ""
+
+#, python-format
+msgid "base, entry %s %s\n"
+msgstr ""
+
+msgid "munge-o-matic\n"
+msgstr ""
+
+#, python-format
+msgid "info: %s %s %s %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown path in revision %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mark %s came from %s:%d\n"
+msgstr ""
+
+#, python-format
+msgid "parsing revision %d (%d changes)\n"
+msgstr ""
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr ""
+
+msgid "no copyfrom path, don't know what to do.\n"
+msgstr ""
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "skipping blacklisted revision %d\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d has no entries\n"
+msgstr ""
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr ""
+
+#, python-format
+msgid "%r is not under %r, ignoring\n"
+msgstr ""
+
+#, python-format
+msgid "initializing svn repo %r\n"
+msgstr ""
+
+#, python-format
+msgid "initializing svn wc %r\n"
+msgstr ""
+
+msgid "unexpected svn output:\n"
+msgstr ""
+
+msgid "unable to cope with svn output"
+msgstr ""
+
+msgid "XXX TAGS NOT IMPLEMENTED YET\n"
+msgstr ""
+
+msgid ""
+"\n"
+"The `extdiff' Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working directory. The external diff\n"
+"programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare.\n"
+"\n"
+"To enable this extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.extdiff =\n"
+"\n"
+"The `extdiff' extension also allows to configure new diff commands, so\n"
+"you do not need to type \"hg extdiff -p kdiff3\" always.\n"
+"\n"
+" [extdiff]\n"
+" # add new command that runs GNU diff(1) in 'context diff' mode\n"
+" cdiff = gdiff -Nprc5\n"
+" ## or the old way:\n"
+" #cmd.cdiff = gdiff\n"
+" #opts.cdiff = -Nprc5\n"
+"\n"
+" # add new command called vdiff, runs kdiff3\n"
+" vdiff = kdiff3\n"
+"\n"
+" # add new command called meld, runs meld (no need to name twice)\n"
+" meld =\n"
+"\n"
+" # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+" # (see http://www.vim.org/scripts/script.php?script_id=102)\n"
+" # Non English user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" "
+"in\n"
+" # your .vimrc\n"
+" vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'\n"
+"\n"
+"You can use -I/-X and list of file or directory names like normal \"hg\n"
+"diff\" command. The `extdiff' extension makes snapshots of only needed\n"
+"files, so running the external diff program will actually be pretty\n"
+"fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from working directory\n"
+msgstr ""
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr ""
+
+#, python-format
+msgid "running %r in %s\n"
+msgstr ""
+
+#, python-format
+msgid "file changed while diffing. Overwriting: %s (src: %s)\n"
+msgstr ""
+
+msgid "cleaning up temp directory\n"
+msgstr ""
+
+msgid ""
+"use external program to diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files, using\n"
+" an external program. The default program used is diff, with\n"
+" default options \"-Npru\".\n"
+"\n"
+" To select a different program, use the -p/--program option. The\n"
+" program will be passed the names of two directories to compare. To\n"
+" pass additional options to the program, use -o/--option. These\n"
+" will be passed before the names of the directories to compare.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent."
+msgstr ""
+
+msgid "comparison program to run"
+msgstr ""
+
+msgid "pass option to comparison program"
+msgstr ""
+
+msgid "change made by revision"
+msgstr ""
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr ""
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "pulling, updating and merging in one command"
+msgstr ""
+
+msgid ""
+"pull changes from a remote repository, merge new changes if needed.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to the local repository.\n"
+"\n"
+" If the pulled changes add a new branch head, the head is\n"
+" automatically merged, and the result of the merge is committed.\n"
+" Otherwise, the working directory is updated to include the new\n"
+" changes.\n"
+"\n"
+" When a merge occurs, the newly pulled changes are assumed to be\n"
+" \"authoritative\". The head of the new changes is used as the first\n"
+" parent, with local changes as the second. To switch the merge\n"
+" order, use --switch-parent.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid ""
+"working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+
+msgid "outstanding uncommitted merge"
+msgstr ""
+
+msgid "outstanding uncommitted changes"
+msgstr ""
+
+msgid "working directory is missing some files"
+msgstr ""
+
+msgid ""
+"multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr ""
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "Automated merge with %s"
+msgstr ""
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr ""
+
+msgid "a specific revision you would like to pull"
+msgstr ""
+
+msgid "edit commit message"
+msgstr ""
+
+msgid "edit commit message (DEPRECATED)"
+msgstr ""
+
+msgid "switch parents when merging"
+msgstr ""
+
+msgid "hg fetch [SOURCE]"
+msgstr ""
+
+msgid "error while verifying signature"
+msgstr ""
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr ""
+
+msgid "list signed changesets"
+msgstr ""
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr ""
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr ""
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr ""
+
+msgid ""
+"add a signature for the current or given revision\n"
+"\n"
+" If no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr ""
+
+msgid "Error while signing"
+msgstr ""
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+
+#, python-format
+msgid "Added signature for changeset %s"
+msgstr ""
+
+msgid "unknown signature version"
+msgstr ""
+
+msgid "make the signature local"
+msgstr ""
+
+msgid "sign even if the sigfile is modified"
+msgstr ""
+
+msgid "do not commit the sigfile after signing"
+msgstr ""
+
+msgid "the key id to sign with"
+msgstr ""
+
+msgid "commit message"
+msgstr ""
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr ""
+
+msgid "hg sigcheck REVISION"
+msgstr ""
+
+msgid "hg sigs"
+msgstr ""
+
+msgid ""
+"show revision graphs in terminal windows\n"
+"\n"
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ASCII representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+
+#, python-format
+msgid "--graph option is incompatible with --%s"
+msgstr ""
+
+msgid ""
+"show revision history alongside an ASCII revision graph\n"
+"\n"
+" Print a revision history alongside a revision graph drawn with\n"
+" ASCII characters.\n"
+"\n"
+" Nodes printed as an @ character are parents of the working\n"
+" directory.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr ""
+
+msgid "no changes found\n"
+msgstr ""
+
+msgid "show the revision DAG"
+msgstr ""
+
+msgid "limit number of changes displayed"
+msgstr ""
+
+msgid "show patch"
+msgstr ""
+
+msgid "show the specified revision or range"
+msgstr ""
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr ""
+
+msgid ""
+"CIA notification\n"
+"\n"
+"This is meant to be run as a changegroup or incoming hook.\n"
+"To configure it, set the following options in your hgrc:\n"
+"\n"
+"[cia]\n"
+"# your registered CIA user name\n"
+"user = foo\n"
+"# the name of the project in CIA\n"
+"project = foo\n"
+"# the module (subproject) (optional)\n"
+"#module = foo\n"
+"# Append a diffstat to the log message (optional)\n"
+"#diffstat = False\n"
+"# Template to use for log messages (optional)\n"
+"#template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"# Style to use (optional)\n"
+"#style = foo\n"
+"# The URL of the CIA notification service (optional)\n"
+"# You can use mailto: URLs to send by email, eg\n"
+"# mailto:cia@cia.vc\n"
+"# Make sure to set email.from if you do this.\n"
+"#url = http://cia.vc/\n"
+"# print message instead of sending it (optional)\n"
+"#test = False\n"
+"\n"
+"[hooks]\n"
+"# one of these:\n"
+"changegroup.cia = python:hgcia.hook\n"
+"#incoming.cia = python:hgcia.hook\n"
+"\n"
+"[web]\n"
+"# If you want hyperlinks (optional)\n"
+"baseurl = http://server/path/to/repo\n"
+msgstr ""
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr ""
+
+msgid "email.from must be defined when sending by email"
+msgstr ""
+
+msgid "cia: no user specified"
+msgstr ""
+
+msgid "cia: no project specified"
+msgstr ""
+
+msgid ""
+"browsing the repository in a graphical way\n"
+"\n"
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not\n"
+"distributed with Mercurial.)\n"
+"\n"
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to Mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and hgk.py can be found in the hgext directory.\n"
+"\n"
+"To load the hgext.py extension, add it to your .hgrc file (you have to\n"
+"use your global $HOME/.hgrc file, not one in a repository). You can\n"
+"specify an absolute path:\n"
+"\n"
+" [extensions]\n"
+" hgk=/usr/local/lib/hgk.py\n"
+"\n"
+"Mercurial can also scan the default python library path for a file\n"
+"named 'hgk.py' if you set hgk empty:\n"
+"\n"
+" [extensions]\n"
+" hgk=\n"
+"\n"
+"The hg view command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can specify\n"
+"the path to hgk in your .hgrc file:\n"
+"\n"
+" [hgk]\n"
+" path=/location/of/hgk\n"
+"\n"
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add:\n"
+"\n"
+" [hgk]\n"
+" vdiff=vdiff\n"
+"\n"
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions."
+msgstr ""
+
+msgid "diff trees from two commits"
+msgstr ""
+
+msgid "output common ancestor information"
+msgstr ""
+
+msgid "cat a specific revision"
+msgstr ""
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr ""
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr ""
+
+msgid "parse given revisions"
+msgstr ""
+
+msgid "print revisions"
+msgstr ""
+
+msgid "print extension options"
+msgstr ""
+
+msgid "start interactive history viewer"
+msgstr ""
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr ""
+
+msgid "generate patch"
+msgstr ""
+
+msgid "recursive"
+msgstr ""
+
+msgid "pretty"
+msgstr ""
+
+msgid "stdin"
+msgstr ""
+
+msgid "detect copies"
+msgstr ""
+
+msgid "search"
+msgstr ""
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr ""
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr ""
+
+msgid "hg debug-config"
+msgstr ""
+
+msgid "hg debug-merge-base node node"
+msgstr ""
+
+msgid "ignored"
+msgstr ""
+
+msgid "hg debug-rev-parse REV"
+msgstr ""
+
+msgid "header"
+msgstr ""
+
+msgid "topo-order"
+msgstr ""
+
+msgid "parents"
+msgstr ""
+
+msgid "max-count"
+msgstr ""
+
+msgid "hg debug-rev-list [options] revs"
+msgstr ""
+
+msgid ""
+"syntax highlighting in hgweb, based on Pygments\n"
+"\n"
+"It depends on the Pygments syntax highlighting library:\n"
+"http://pygments.org/\n"
+"\n"
+"To enable the extension add this to hgrc:\n"
+"\n"
+"[extensions]\n"
+"hgext.highlight =\n"
+"\n"
+"There is a single configuration option:\n"
+"\n"
+"[web]\n"
+"pygments_style = <style>\n"
+"\n"
+"The default is 'colorful'.\n"
+"\n"
+"-- Adam Hupp <adam@hupp.org>\n"
+msgstr ""
+
+msgid "inotify-based status acceleration for Linux systems\n"
+msgstr ""
+
+msgid "start an inotify server for this repository"
+msgstr ""
+
+msgid ""
+"debugging information for inotify extension\n"
+"\n"
+" Prints the list of directories being watched by the inotify server.\n"
+" "
+msgstr ""
+
+msgid "directories being watched:\n"
+msgstr ""
+
+msgid "run server in background"
+msgstr ""
+
+msgid "used internally by daemon mode"
+msgstr ""
+
+msgid "minutes to sit idle before exiting"
+msgstr ""
+
+msgid "name of file to write process ID to"
+msgstr ""
+
+msgid "hg inserve [OPT]..."
+msgstr ""
+
+msgid "(found dead inotify server socket; removing it)\n"
+msgstr ""
+
+msgid "(starting inotify server)\n"
+msgstr ""
+
+#, python-format
+msgid "could not start inotify server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "could not talk to new inotify server: %s\n"
+msgstr ""
+
+msgid "(inotify server not running)\n"
+msgstr ""
+
+#, python-format
+msgid "failed to contact inotify server: %s\n"
+msgstr ""
+
+msgid "received empty answer from inotify server"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received '%s' response when expecting '%s')\n"
+msgstr ""
+
+msgid "this system does not seem to support inotify"
+msgstr ""
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr ""
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr ""
+
+msgid "*** counting directories: "
+msgstr ""
+
+#, python-format
+msgid "found %d\n"
+msgstr ""
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr ""
+
+#, python-format
+msgid "*** echo %d > %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr ""
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr ""
+
+#, python-format
+msgid "watching %r\n"
+msgstr ""
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r dir(%d) -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s dirstate reload\n"
+msgstr ""
+
+#, python-format
+msgid "%s end dirstate reload\n"
+msgstr ""
+
+msgid "rescanning due to .hgignore change\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr ""
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr ""
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr ""
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr ""
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr ""
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr ""
+
+#, python-format
+msgid "could not start server: %s"
+msgstr ""
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr ""
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr ""
+
+#, python-format
+msgid "unrecognized query type: %s\n"
+msgstr ""
+
+msgid "finished setup\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr ""
+
+msgid ""
+"keyword expansion in local repositories\n"
+"\n"
+"This extension expands RCS/CVS-like or self-customized $Keywords$ in\n"
+"tracked text files selected by your configuration.\n"
+"\n"
+"Keywords are only expanded in local repositories and not stored in the\n"
+"change history. The mechanism can be regarded as a convenience for the\n"
+"current user or for archive distribution.\n"
+"\n"
+"Configuration is done in the [keyword] and [keywordmaps] sections of\n"
+"hgrc files.\n"
+"\n"
+"Example:\n"
+"\n"
+" [keyword]\n"
+" # expand keywords in every python file except those matching \"x*\"\n"
+" **.py =\n"
+" x* = ignore\n"
+"\n"
+"Note: the more specific you are in your filename patterns\n"
+" the less you lose speed in huge repositories.\n"
+"\n"
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run \"hg kwdemo\".\n"
+"\n"
+"An additional date template filter {date|utcdate} is provided.\n"
+"\n"
+"The default template mappings (view with \"hg kwdemo -d\") can be\n"
+"replaced with customized keywords and templates. Again, run \"hg\n"
+"kwdemo\" to control the results of your config changes.\n"
+"\n"
+"Before changing/disabling active keywords, run \"hg kwshrink\" to avoid\n"
+"the risk of inadvertently storing expanded keywords in the change\n"
+"history.\n"
+"\n"
+"To force expansion after enabling it, or a configuration change, run\n"
+"\"hg kwexpand\".\n"
+"\n"
+"Also, when committing with the record extension or using mq's qrecord,\n"
+"be aware that keywords cannot be updated. Again, run \"hg kwexpand\" on\n"
+"the files in question to update keyword expansions after all changes\n"
+"have been checked in.\n"
+"\n"
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map\n"
+"\"Log = {desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s expanding keywords\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s shrinking keywords\n"
+msgstr ""
+
+msgid "[keyword] patterns cannot match"
+msgstr ""
+
+msgid "no [keyword] patterns configured"
+msgstr ""
+
+msgid ""
+"print [keywordmaps] configuration and an expansion example\n"
+"\n"
+" Show current, custom, or default keyword template maps and their\n"
+" expansions.\n"
+"\n"
+" Extend current configuration by specifying maps as arguments and\n"
+" optionally by reading from an additional hgrc file.\n"
+"\n"
+" Override current keyword template maps with \"default\" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"\t%s\n"
+msgstr ""
+
+#, python-format
+msgid "creating temporary repository at %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"%s keywords written to %s:\n"
+msgstr ""
+
+msgid "unhooked all commit hooks\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"removing temporary repository %s\n"
+msgstr ""
+
+msgid ""
+"expand keywords in the working directory\n"
+"\n"
+" Run after (re)enabling keyword expansion.\n"
+"\n"
+" kwexpand refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid ""
+"print files currently configured for keyword expansion\n"
+"\n"
+" Crosscheck which files in working directory are potential targets\n"
+" for keyword expansion. That is, files matched by [keyword] config\n"
+" patterns but not symlinks.\n"
+" "
+msgstr ""
+
+msgid ""
+"revert expanded keywords in the working directory\n"
+"\n"
+" Run before changing/disabling active keywords or if you experience\n"
+" problems with \"hg import\" or \"hg merge\".\n"
+"\n"
+" kwshrink refuses to run if given files contain local changes.\n"
+" "
+msgstr ""
+
+msgid "show default keyword template maps"
+msgstr ""
+
+msgid "read maps from rcfile"
+msgstr ""
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr ""
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "show keyword status flags of all files"
+msgstr ""
+
+msgid "show files excluded from expansion"
+msgstr ""
+
+msgid "additionally show untracked files"
+msgstr ""
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr ""
+
+msgid ""
+"patch management and development\n"
+"\n"
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches).\n"
+"\n"
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets.\n"
+"\n"
+"Common tasks (use \"hg help command\" for more details):\n"
+"\n"
+"prepare repository to work with patches qinit\n"
+"create new patch qnew\n"
+"import existing patch qimport\n"
+"\n"
+"print patch series qseries\n"
+"print applied patches qapplied\n"
+"print name of top applied patch qtop\n"
+"\n"
+"add known patch to applied stack qpush\n"
+"remove patch from applied stack qpop\n"
+"refresh contents of top applied patch qrefresh\n"
+msgstr ""
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr ""
+
+msgid "guard cannot be an empty string"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr ""
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr ""
+
+#, python-format
+msgid "active guards: %s\n"
+msgstr ""
+
+#, python-format
+msgid "guard %r too short"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr ""
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr ""
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "update returned %d"
+msgstr ""
+
+msgid "repo commit failed"
+msgstr ""
+
+#, python-format
+msgid "unable to read %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr ""
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr ""
+
+#, python-format
+msgid "applying %s\n"
+msgstr ""
+
+#, python-format
+msgid "Unable to read %s\n"
+msgstr ""
+
+#, python-format
+msgid "imported patch %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"imported patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr ""
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr ""
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr ""
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr ""
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr ""
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr ""
+
+msgid "no patches applied"
+msgstr ""
+
+msgid "working directory revision is not qtip"
+msgstr ""
+
+msgid "local changes found, refresh first"
+msgstr ""
+
+msgid "local changes found"
+msgstr ""
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr ""
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr ""
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series"
+msgstr ""
+
+msgid "(working directory not at a head)\n"
+msgstr ""
+
+msgid "no patches in series\n"
+msgstr ""
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr ""
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr ""
+
+#, python-format
+msgid "guarded by %r"
+msgstr ""
+
+msgid "no matching guards"
+msgstr ""
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr ""
+
+msgid "all patches are currently applied\n"
+msgstr ""
+
+msgid "patch series already fully applied\n"
+msgstr ""
+
+msgid "cleaning up working directory..."
+msgstr ""
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr ""
+
+#, python-format
+msgid "now at: %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr ""
+
+msgid "no patches applied\n"
+msgstr ""
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr ""
+
+msgid "qpop: forcing dirstate update\n"
+msgstr ""
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr ""
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr ""
+
+msgid "deletions found between repo revs"
+msgstr ""
+
+msgid "patch queue now empty\n"
+msgstr ""
+
+msgid "cannot refresh a revision with children"
+msgstr ""
+
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to "
+"recover)\n"
+msgstr ""
+
+msgid "patch queue directory already exists"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr ""
+
+msgid "No saved patch data found\n"
+msgstr ""
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr ""
+
+msgid "save entry has children, leaving it alone\n"
+msgstr ""
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr ""
+
+msgid "queue directory updating\n"
+msgstr ""
+
+msgid "Unable to load queue repository\n"
+msgstr ""
+
+msgid "save: no patches applied, exiting\n"
+msgstr ""
+
+msgid "status is already saved\n"
+msgstr ""
+
+msgid "hg patches saved state"
+msgstr ""
+
+msgid "repo commit failed\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr ""
+
+msgid "option \"-r\" not valid when importing files"
+msgstr ""
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr ""
+
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr ""
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr ""
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr ""
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr ""
+
+msgid "-e is incompatible with import from -"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr ""
+
+msgid "need --name to import a patch from -"
+msgstr ""
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr ""
+
+msgid ""
+"remove patches from queue\n"
+"\n"
+" The patches must not be applied, unless they are arguments to the\n"
+" -r/--rev parameter. At least one patch or revision is required.\n"
+"\n"
+" With --rev, mq will stop managing the named revisions (converting\n"
+" them to regular Mercurial changesets). The qfinish command should\n"
+" be used as an alternative for qdelete -r, as the latter option is\n"
+" deprecated.\n"
+"\n"
+" With -k/--keep, the patch files are preserved in the patch\n"
+" directory."
+msgstr ""
+
+msgid "print the patches already applied"
+msgstr ""
+
+msgid "print the patches not yet applied"
+msgstr ""
+
+msgid ""
+"import a patch\n"
+"\n"
+" The patch is inserted into the series after the last applied\n"
+" patch. If no patches have been applied, qimport prepends the patch\n"
+" to the series.\n"
+"\n"
+" The patch will have the same name as its source file unless you\n"
+" give it a new one with -n/--name.\n"
+"\n"
+" You can register an existing patch inside the patch directory with\n"
+" the -e/--existing flag.\n"
+"\n"
+" With -f/--force, an existing patch of the same name will be\n"
+" overwritten.\n"
+"\n"
+" An existing changeset may be placed under mq control with -r/--rev\n"
+" (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+" With -g/--git, patches imported with --rev will use the git diff\n"
+" format. See the diffs help topic for information on why this is\n"
+" important for preserving rename/copy information and permission\n"
+" changes.\n"
+"\n"
+" To import a patch from standard input, pass - as the patch file.\n"
+" When importing from standard input, a patch name must be specified\n"
+" using the --name flag.\n"
+" "
+msgstr ""
+
+msgid ""
+"init a new queue repository\n"
+"\n"
+" The queue repository is unversioned by default. If\n"
+" -c/--create-repo is specified, qinit will create a separate nested\n"
+" repository for patches (qinit -c may also be run later to convert\n"
+" an unversioned patch repository into a versioned one). You can use\n"
+" qcommit to commit changes to this queue repository."
+msgstr ""
+
+msgid ""
+"clone main and patch repository at same time\n"
+"\n"
+" If source is local, destination will have no patches applied. If\n"
+" source is remote, this command can not check if patches are\n"
+" applied in source, so cannot guarantee that patches are not\n"
+" applied in destination. If you clone remote repository, be sure\n"
+" before that it has no patches applied.\n"
+"\n"
+" Source patch repository is looked for in <src>/.hg/patches by\n"
+" default. Use -p <url> to change.\n"
+"\n"
+" The patch directory must be a nested Mercurial repository, as\n"
+" would be created by qinit -c.\n"
+" "
+msgstr ""
+
+msgid "versioned patch repository not found (see qinit -c)"
+msgstr ""
+
+msgid "cloning main repository\n"
+msgstr ""
+
+msgid "cloning patch repository\n"
+msgstr ""
+
+msgid "stripping applied patches from destination repository\n"
+msgstr ""
+
+msgid "updating destination repository\n"
+msgstr ""
+
+msgid "commit changes in the queue repository"
+msgstr ""
+
+msgid "print the entire series file"
+msgstr ""
+
+msgid "print the name of the current patch"
+msgstr ""
+
+msgid "print the name of the next patch"
+msgstr ""
+
+msgid "all patches applied\n"
+msgstr ""
+
+msgid "print the name of the previous patch"
+msgstr ""
+
+msgid "only one patch applied\n"
+msgstr ""
+
+msgid ""
+"create a new patch\n"
+"\n"
+" qnew creates a new patch on top of the currently-applied patch (if\n"
+" any). It will refuse to run if there are any outstanding changes\n"
+" unless -f/--force is specified, in which case the patch will be\n"
+" initialized with them. You may also use -I/--include,\n"
+" -X/--exclude, and/or a list of files after the patch name to add\n"
+" only changes to matching files to the new patch, leaving the rest\n"
+" as uncommitted modifications.\n"
+"\n"
+" -u/--user and -d/--date can be used to set the (given) user and\n"
+" date, respectively. -U/--currentuser and -D/--currentdate set user\n"
+" to current user and date to current date.\n"
+"\n"
+" -e/--edit, -m/--message or -l/--logfile set the patch header as\n"
+" well as the commit message. If none is specified, the header is\n"
+" empty and the commit message is '[mq]: PATCH'.\n"
+"\n"
+" Use the -g/--git option to keep the patch in the git extended diff\n"
+" format. Read the diffs help topic for more information on why this\n"
+" is important for preserving permission changes and copy/rename\n"
+" information.\n"
+" "
+msgstr ""
+
+msgid ""
+"update the current patch\n"
+"\n"
+" If any file patterns are provided, the refreshed patch will\n"
+" contain only the modifications that match those patterns; the\n"
+" remaining modifications will remain in the working directory.\n"
+"\n"
+" If -s/--short is specified, files currently included in the patch\n"
+" will be refreshed just like matched files and remain in the patch.\n"
+"\n"
+" hg add/remove/copy/rename work as usual, though you might want to\n"
+" use git-style patches (-g/--git or [diff] git=1) to track copies\n"
+" and renames. See the diffs help topic for more information on the\n"
+" git diff format.\n"
+" "
+msgstr ""
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr ""
+
+msgid ""
+"diff of the current patch and subsequent modifications\n"
+"\n"
+" Shows a diff which includes the current patch as well as any\n"
+" changes which have been made in the working directory since the\n"
+" last refresh (thus showing what the current patch would become\n"
+" after a qrefresh).\n"
+"\n"
+" Use 'hg diff' if you only want to see the changes made since the\n"
+" last qrefresh, or 'hg export qtip' if you want to see changes made\n"
+" by the current patch without including changes made since the\n"
+" qrefresh.\n"
+" "
+msgstr ""
+
+msgid ""
+"fold the named patches into the current patch\n"
+"\n"
+" Patches must not yet be applied. Each patch will be successively\n"
+" applied to the current patch in the order given. If all the\n"
+" patches apply successfully, the current patch will be refreshed\n"
+" with the new cumulative patch, and the folded patches will be\n"
+" deleted. With -k/--keep, the folded patch files will not be\n"
+" removed afterwards.\n"
+"\n"
+" The header for each folded patch will be concatenated with the\n"
+" current patch header, separated by a line of '* * *'."
+msgstr ""
+
+msgid "qfold requires at least one patch name"
+msgstr ""
+
+msgid "No patches applied"
+msgstr ""
+
+#, python-format
+msgid "Skipping already folded patch %s"
+msgstr ""
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "Error folding patch %s"
+msgstr ""
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr ""
+
+msgid ""
+"set or print guards for a patch\n"
+"\n"
+" Guards control whether a patch can be pushed. A patch with no\n"
+" guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+" pushed only if the qselect command has activated it. A patch with\n"
+" a negative guard (\"-foo\") is never pushed if the qselect command\n"
+" has activated it.\n"
+"\n"
+" With no arguments, print the currently active guards.\n"
+" With arguments, set guards for the named patch.\n"
+" NOTE: Specifying negative guards now requires '--'.\n"
+"\n"
+" To set guards on another patch:\n"
+" hg qguard -- other.patch +2.6.17 -stable\n"
+" "
+msgstr ""
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr ""
+
+msgid "no patch to work with"
+msgstr ""
+
+#, python-format
+msgid "no patch named %s"
+msgstr ""
+
+msgid "print the header of the topmost or specified patch"
+msgstr ""
+
+msgid ""
+"push the next patch onto the stack\n"
+"\n"
+" When -f/--force is applied, all local changes in patched files\n"
+" will be lost.\n"
+" "
+msgstr ""
+
+msgid "no saved queues found, please use -n\n"
+msgstr ""
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr ""
+
+msgid ""
+"pop the current patch off the stack\n"
+"\n"
+" By default, pops off the top of the patch stack. If given a patch\n"
+" name, keeps popping off patches until the named patch is at the\n"
+" top of the stack.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr ""
+
+msgid ""
+"rename a patch\n"
+"\n"
+" With one argument, renames the current patch to PATCH1.\n"
+" With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+
+#, python-format
+msgid "%s already exists"
+msgstr ""
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr ""
+
+msgid "restore the queue state saved by a revision"
+msgstr ""
+
+msgid "save current queue state"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr ""
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr ""
+
+msgid ""
+"strip a revision and all its descendants from the repository\n"
+"\n"
+" If one of the working directory's parent revisions is stripped, the\n"
+" working directory will be updated to the parent of the stripped\n"
+" revision.\n"
+" "
+msgstr ""
+
+msgid ""
+"set or print guarded patches to push\n"
+"\n"
+" Use the qguard command to set or print guards on patch, then use\n"
+" qselect to tell mq which guards to use. A patch will be pushed if\n"
+" it has no guards or any positive guards match the currently\n"
+" selected guard, but will not be pushed if any negative guards\n"
+" match the current guard. For example:\n"
+"\n"
+" qguard foo.patch -stable (negative guard)\n"
+" qguard bar.patch +stable (positive guard)\n"
+" qselect stable\n"
+"\n"
+" This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+" it has a negative match) but push bar.patch (because it has a\n"
+" positive match).\n"
+"\n"
+" With no arguments, prints the currently active guards.\n"
+" With one argument, sets the active guard.\n"
+"\n"
+" Use -n/--none to deactivate guards (no other arguments needed).\n"
+" When no guards are active, patches with positive guards are\n"
+" skipped and patches with negative guards are pushed.\n"
+"\n"
+" qselect can change the guards on applied patches. It does not pop\n"
+" guarded patches by default. Use --pop to pop back to the last\n"
+" applied patch that is not guarded. Use --reapply (which implies\n"
+" --pop) to push back to the current patch afterwards, but skip\n"
+" guarded patches.\n"
+"\n"
+" Use -s/--series to print a list of all guards in the series file\n"
+" (no other arguments needed). Use -v for more information."
+msgstr ""
+
+msgid "guards deactivated\n"
+msgstr ""
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr ""
+
+msgid "guards in series file:\n"
+msgstr ""
+
+msgid "no guards in series file\n"
+msgstr ""
+
+msgid "active guards:\n"
+msgstr ""
+
+msgid "no active guards\n"
+msgstr ""
+
+msgid "popping guarded patches\n"
+msgstr ""
+
+msgid "reapplying unguarded patches\n"
+msgstr ""
+
+msgid ""
+"move applied patches into repository history\n"
+"\n"
+" Finishes the specified revisions (corresponding to applied\n"
+" patches) by moving them out of mq control into regular repository\n"
+" history.\n"
+"\n"
+" Accepts a revision range or the -a/--applied option. If --applied\n"
+" is specified, all applied mq revisions are removed from mq\n"
+" control. Otherwise, the given revisions must be at the base of the\n"
+" stack of applied patches.\n"
+"\n"
+" This can be especially useful if your changes have been applied to\n"
+" an upstream repository, or if you are about to push your changes\n"
+" to upstream.\n"
+" "
+msgstr ""
+
+msgid "no revisions specified"
+msgstr ""
+
+msgid "cannot commit over an applied mq patch"
+msgstr ""
+
+msgid "source has mq patches applied"
+msgstr ""
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr ""
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr ""
+
+msgid "cannot import over an applied patch"
+msgstr ""
+
+msgid "print first line of patch header"
+msgstr ""
+
+msgid "hg qapplied [-s] [PATCH]"
+msgstr ""
+
+msgid "use pull protocol to copy metadata"
+msgstr ""
+
+msgid "do not update the new working directories"
+msgstr ""
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr ""
+
+msgid "location of source patch repository"
+msgstr ""
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr ""
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "keep patch file"
+msgstr ""
+
+msgid "stop managing a revision"
+msgstr ""
+
+msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
+msgstr ""
+
+msgid "edit patch header"
+msgstr ""
+
+msgid "keep folded patch files"
+msgstr ""
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr ""
+
+msgid "overwrite any local changes"
+msgstr ""
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr ""
+
+msgid "list all patches and guards"
+msgstr ""
+
+msgid "drop all guards"
+msgstr ""
+
+msgid "hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]..."
+msgstr ""
+
+msgid "hg qheader [PATCH]"
+msgstr ""
+
+msgid "import file in patch directory"
+msgstr ""
+
+msgid "name of patch file"
+msgstr ""
+
+msgid "overwrite existing files"
+msgstr ""
+
+msgid "place existing revisions under mq control"
+msgstr ""
+
+msgid "use git extended diff format"
+msgstr ""
+
+msgid "qpush after importing"
+msgstr ""
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr ""
+
+msgid "create queue repository"
+msgstr ""
+
+msgid "hg qinit [-c]"
+msgstr ""
+
+msgid "import uncommitted changes into patch"
+msgstr ""
+
+msgid "add \"From: <current user>\" to patch"
+msgstr ""
+
+msgid "add \"From: <given user>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <given date>\" to patch"
+msgstr ""
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]..."
+msgstr ""
+
+msgid "hg qnext [-s]"
+msgstr ""
+
+msgid "hg qprev [-s]"
+msgstr ""
+
+msgid "pop all patches"
+msgstr ""
+
+msgid "queue name to pop"
+msgstr ""
+
+msgid "forget any local changes"
+msgstr ""
+
+msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
+msgstr ""
+
+msgid "apply if the patch has rejects"
+msgstr ""
+
+msgid "list patch name in commit text"
+msgstr ""
+
+msgid "apply all patches"
+msgstr ""
+
+msgid "merge from another queue"
+msgstr ""
+
+msgid "merge queue name"
+msgstr ""
+
+msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]"
+msgstr ""
+
+msgid "refresh only files already in the patch and specified files"
+msgstr ""
+
+msgid "add/update \"From: <current user>\" in patch"
+msgstr ""
+
+msgid "add/update \"From: <given user>\" in patch"
+msgstr ""
+
+msgid "update \"Date: <current date>\" in patch (if present)"
+msgstr ""
+
+msgid "update \"Date: <given date>\" in patch (if present)"
+msgstr ""
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr ""
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr ""
+
+msgid "delete save entry"
+msgstr ""
+
+msgid "update queue working directory"
+msgstr ""
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr ""
+
+msgid "copy patch directory"
+msgstr ""
+
+msgid "copy directory name"
+msgstr ""
+
+msgid "clear queue status file"
+msgstr ""
+
+msgid "force copy"
+msgstr ""
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr ""
+
+msgid "disable all guards"
+msgstr ""
+
+msgid "list all guards in series file"
+msgstr ""
+
+msgid "pop to before first guarded applied patch"
+msgstr ""
+
+msgid "pop, then reapply patches"
+msgstr ""
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr ""
+
+msgid "print patches not in series"
+msgstr ""
+
+msgid "hg qseries [-ms]"
+msgstr ""
+
+msgid "force removal with local changes"
+msgstr ""
+
+msgid "bundle unrelated changesets"
+msgstr ""
+
+msgid "no backups"
+msgstr ""
+
+msgid "hg strip [-f] [-b] [-n] REV"
+msgstr ""
+
+msgid "hg qtop [-s]"
+msgstr ""
+
+msgid "hg qunapplied [-s] [PATCH]"
+msgstr ""
+
+msgid "finish all applied changesets"
+msgstr ""
+
+msgid "hg qfinish [-a] [REV...]"
+msgstr ""
+
+msgid ""
+"hook extension to email notifications on commits/pushes\n"
+"\n"
+"Subscriptions can be managed through hgrc. Default mode is to print\n"
+"messages to stdout, for testing and configuring.\n"
+"\n"
+"To use, configure notify extension and enable in hgrc like this:\n"
+"\n"
+" [extensions]\n"
+" hgext.notify =\n"
+"\n"
+" [hooks]\n"
+" # one email for each incoming changeset\n"
+" incoming.notify = python:hgext.notify.hook\n"
+" # batch emails when many changesets incoming at one time\n"
+" changegroup.notify = python:hgext.notify.hook\n"
+"\n"
+" [notify]\n"
+" # config items go in here\n"
+"\n"
+" config items:\n"
+"\n"
+" REQUIRED:\n"
+" config = /path/to/file # file containing subscriptions\n"
+"\n"
+" OPTIONAL:\n"
+" test = True # print messages to stdout for testing\n"
+" strip = 3 # number of slashes to strip for url paths\n"
+" domain = example.com # domain to use if committer missing domain\n"
+" style = ... # style file to use when formatting email\n"
+" template = ... # template to use when formatting email\n"
+" incoming = ... # template to use when run as incoming hook\n"
+" changegroup = ... # template when run as changegroup hook\n"
+" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n"
+" maxsubject = 67 # truncate subject line longer than this\n"
+" diffstat = True # add a diffstat before the diff content\n"
+" sources = serve # notify if source of incoming changes in this "
+"list\n"
+" # (serve == ssh or http, push, pull, bundle)\n"
+" [email]\n"
+" from = user@host.com # email address to send as if none given\n"
+" [web]\n"
+" baseurl = http://hgserver/... # root of hg web site for browsing commits\n"
+"\n"
+" notify config file has same format as regular hgrc. it has two\n"
+" sections so you can express subscriptions in whatever way is handier\n"
+" for you.\n"
+"\n"
+" [usersubs]\n"
+" # key is subscriber email, value is \",\"-separated list of glob "
+"patterns\n"
+" user@host = pattern\n"
+"\n"
+" [reposubs]\n"
+" # key is glob pattern, value is \",\"-separated list of subscriber "
+"emails\n"
+" pattern = user@host\n"
+"\n"
+" glob patterns are matched against path to repository root.\n"
+"\n"
+" if you like, you can put notify config file in repository that users\n"
+" can push changes to, they can manage their own subscriptions."
+msgstr ""
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr ""
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "notify: no subscribers to repository %s\n"
+msgstr ""
+
+#, python-format
+msgid "notify: changes have source \"%s\" - skipping\n"
+msgstr ""
+
+msgid ""
+"browse command output with external pager\n"
+"\n"
+"To set the pager that should be used, set the application variable:\n"
+"\n"
+" [pager]\n"
+" pager = LESS='FSRX' less\n"
+"\n"
+"If no pager is set, the pager extensions uses the environment variable\n"
+"$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.\n"
+"\n"
+"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
+"setting:\n"
+"\n"
+" [pager]\n"
+" quiet = True\n"
+"\n"
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list:\n"
+"\n"
+" [pager]\n"
+" ignore = version, help, update\n"
+"\n"
+"You can also enable the pager only for certain commands using\n"
+"pager.attend:\n"
+"\n"
+" [pager]\n"
+" attend = log\n"
+"\n"
+"If pager.attend is present, pager.ignore will be ignored.\n"
+"\n"
+"To ignore global commands like \"hg version\" or \"hg help\", you have to\n"
+"specify them in the global .hgrc\n"
+msgstr ""
+
+msgid ""
+"use suffixes to refer to ancestor revisions\n"
+"\n"
+"This extension allows you to use git-style suffixes to refer to the\n"
+"ancestors of a specific revision.\n"
+"\n"
+"For example, if you can refer to a revision as \"foo\", then:\n"
+"\n"
+"- foo^N = Nth parent of foo\n"
+" foo^0 = foo\n"
+" foo^1 = first parent of foo\n"
+" foo^2 = second parent of foo\n"
+" foo^ = foo^1\n"
+"\n"
+"- foo~N = Nth first grandparent of foo\n"
+" foo~0 = foo\n"
+" foo~1 = foo^1 = foo^ = first parent of foo\n"
+" foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
+msgstr ""
+
+msgid ""
+"sending Mercurial changesets as a series of patch emails\n"
+"\n"
+"The series is started off with a \"[PATCH 0 of N]\" introduction, which\n"
+"describes the series as a whole.\n"
+"\n"
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using the\n"
+"first line of the changeset description as the subject text. The\n"
+"message contains two or three body parts:\n"
+"\n"
+" The changeset description.\n"
+"\n"
+" [Optional] The result of running diffstat on the patch.\n"
+"\n"
+" The patch itself, as generated by \"hg export\".\n"
+"\n"
+"Each message refers to the first in the series using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in threaded\n"
+"mail and news readers, and in mail archives.\n"
+"\n"
+"With the -d/--diffstat option, you will be prompted for each changeset\n"
+"with a diffstat summary and the changeset summary, so you can be sure\n"
+"you are sending the right changes.\n"
+"\n"
+"To enable this extension:\n"
+"\n"
+" [extensions]\n"
+" hgext.patchbomb =\n"
+"\n"
+"To configure other defaults, add a section like this to your hgrc\n"
+"file:\n"
+"\n"
+" [email]\n"
+" from = My Name <my@email>\n"
+" to = recipient1, recipient2, ...\n"
+" cc = cc1, cc2, ...\n"
+" bcc = bcc1, bcc2, ...\n"
+"\n"
+"Then you can use the \"hg email\" command to mail a series of changesets\n"
+"as a patchbomb.\n"
+"\n"
+"To avoid sending patches prematurely, it is a good idea to first run\n"
+"the \"email\" command with the \"-n\" option (test only). You will be\n"
+"prompted for an email recipient address, a subject and an introductory\n"
+"message describing the patches of your patchbomb. Then when all is\n"
+"done, patchbomb messages are displayed. If the PAGER environment\n"
+"variable is set, your pager will be fired up once for each patchbomb\n"
+"message, so you can verify everything is alright.\n"
+"\n"
+"The -m/--mbox option is also very useful. Instead of previewing each\n"
+"patchbomb message in a pager or sending the messages directly, it will\n"
+"create a UNIX mailbox file with the patch emails. This mailbox file\n"
+"can be previewed with any mail user agent which supports UNIX mbox\n"
+"files, e.g. with mutt:\n"
+"\n"
+" % mutt -R -f mbox\n"
+"\n"
+"When you are previewing the patchbomb messages, you can use `formail'\n"
+"(a utility that is commonly installed as part of the procmail\n"
+"package), to send each message out:\n"
+"\n"
+" % formail -s sendmail -bm -t < mbox\n"
+"\n"
+"That should be all. Now your patchbomb is on its way out.\n"
+"\n"
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatible mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs\n"
+"directly from the commandline. See the [email] and [smtp] sections in\n"
+"hgrc(5) for details."
+msgstr ""
+
+msgid "Please enter a valid value.\n"
+msgstr ""
+
+msgid "does the diffstat above look okay? "
+msgstr ""
+
+msgid "diffstat rejected"
+msgstr ""
+
+msgid ""
+"send changesets by email\n"
+"\n"
+" By default, diffs are sent in the format generated by hg export,\n"
+" one per message. The series starts with a \"[PATCH 0 of N]\"\n"
+" introduction, which describes the series as a whole.\n"
+"\n"
+" Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+" the first line of the changeset description as the subject text.\n"
+" The message contains two or three parts. First, the changeset\n"
+" description. Next, (optionally) if the diffstat program is\n"
+" installed and -d/--diffstat is used, the result of running\n"
+" diffstat on the patch. Finally, the patch itself, as generated by\n"
+" \"hg export\".\n"
+"\n"
+" By default the patch is included as text in the email body for\n"
+" easy reviewing. Using the -a/--attach option will instead create\n"
+" an attachment for the patch. With -i/--inline an inline attachment\n"
+" will be created.\n"
+"\n"
+" With -o/--outgoing, emails will be generated for patches not found\n"
+" in the destination repository (or only those which are ancestors\n"
+" of the specified revisions if any are provided)\n"
+"\n"
+" With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+" single email containing a binary Mercurial bundle as an attachment\n"
+" will be sent.\n"
+"\n"
+" Examples:\n"
+"\n"
+" hg email -r 3000 # send patch 3000 only\n"
+" hg email -r 3000 -r 3001 # send patches 3000 and 3001\n"
+" hg email -r 3000:3005 # send patches 3000 through 3005\n"
+" hg email 3000 # send patch 3000 (deprecated)\n"
+"\n"
+" hg email -o # send all patches not in default\n"
+" hg email -o DEST # send all patches not in DEST\n"
+" hg email -o -r 3000 # send all ancestors of 3000 not in default\n"
+" hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST\n"
+"\n"
+" hg email -b # send bundle of all patches not in default\n"
+" hg email -b DEST # send bundle of all patches not in DEST\n"
+" hg email -b -r 3000 # bundle of all ancestors of 3000 not in "
+"default\n"
+" hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST\n"
+"\n"
+" Before using this command, you will need to enable email in your\n"
+" hgrc. See the [email] section in hgrc(5) for details.\n"
+" "
+msgstr ""
+
+msgid "specify at least one changeset with -r or -o"
+msgstr ""
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr ""
+
+msgid "too many destinations"
+msgstr ""
+
+msgid "use only one form to specify the revision"
+msgstr ""
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series.\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"This patch series consists of %d patches.\n"
+"\n"
+msgstr ""
+
+msgid "Final summary:\n"
+msgstr ""
+
+msgid "Displaying "
+msgstr ""
+
+msgid "Writing "
+msgstr ""
+
+msgid "Sending "
+msgstr ""
+
+msgid "send patches as attachments"
+msgstr ""
+
+msgid "send patches as inline attachments"
+msgstr ""
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr ""
+
+msgid "email addresses of copy recipients"
+msgstr ""
+
+msgid "add diffstat output to messages"
+msgstr ""
+
+msgid "use the given date as the sending date"
+msgstr ""
+
+msgid "use the given file as the series description"
+msgstr ""
+
+msgid "email address of sender"
+msgstr ""
+
+msgid "print messages that would be sent"
+msgstr ""
+
+msgid "write messages to mbox file instead of sending them"
+msgstr ""
+
+msgid "subject of first message (intro or single patch)"
+msgstr ""
+
+msgid "message identifier to reply to"
+msgstr ""
+
+msgid "email addresses of recipients"
+msgstr ""
+
+msgid "omit hg patch header"
+msgstr ""
+
+msgid "send changes not found in the target repository"
+msgstr ""
+
+msgid "send changes not in target as a binary bundle"
+msgstr ""
+
+msgid "name of the bundle attachment file"
+msgstr ""
+
+msgid "a revision to send"
+msgstr ""
+
+msgid "run even when remote repository is unrelated (with -b/--bundle)"
+msgstr ""
+
+msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
+msgstr ""
+
+msgid "send an introduction email for a single patch"
+msgstr ""
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr ""
+
+msgid ""
+"removes files not tracked by Mercurial\n"
+"\n"
+" Delete files not known to Mercurial. This is useful to test local\n"
+" and uncommitted changes in an otherwise-clean source tree.\n"
+"\n"
+" This means that purge will delete:\n"
+" - Unknown files: files marked with \"?\" by \"hg status\"\n"
+" - Empty directories: in fact Mercurial ignores directories unless\n"
+" they contain files under source control management\n"
+" But it will leave untouched:\n"
+" - Modified and unmodified tracked files\n"
+" - Ignored files (unless --all is specified)\n"
+" - New files added to the repository (with \"hg add\")\n"
+"\n"
+" If directories are given on the command line, only files in these\n"
+" directories are considered.\n"
+"\n"
+" Be careful with purge, as you could irreversibly delete some files\n"
+" you forgot to add to the repository. If you only want to print the\n"
+" list of files that this program would delete, use the --print\n"
+" option.\n"
+" "
+msgstr ""
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s\n"
+msgstr ""
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr ""
+
+msgid "abort if an error occurs"
+msgstr ""
+
+msgid "purge ignored files too"
+msgstr ""
+
+msgid "print filenames instead of deleting them"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr ""
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr ""
+
+msgid ""
+"move sets of revisions to a different ancestor\n"
+"\n"
+"This extension lets you rebase changesets in an existing Mercurial\n"
+"repository.\n"
+"\n"
+"For more information:\n"
+"http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject\n"
+msgstr ""
+
+msgid "first revision, do not change ancestor\n"
+msgstr ""
+
+msgid ""
+"move changeset (and descendants) to a different branch\n"
+"\n"
+" Rebase uses repeated merging to graft changesets from one part of\n"
+" history onto another. This can be useful for linearizing local\n"
+" changes relative to a master development tree.\n"
+"\n"
+" If a rebase is interrupted to manually resolve a merge, it can be\n"
+" continued with --continue/-c or aborted with --abort/-a.\n"
+" "
+msgstr ""
+
+msgid "cannot use both abort and continue"
+msgstr ""
+
+msgid "cannot use collapse with continue or abort"
+msgstr ""
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr ""
+
+msgid "cannot specify both a revision and a base"
+msgstr ""
+
+msgid "nothing to rebase\n"
+msgstr ""
+
+msgid "cannot use both keepbranches and extrafn"
+msgstr ""
+
+msgid "rebase merging completed\n"
+msgstr ""
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr ""
+
+msgid "rebase completed\n"
+msgstr ""
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr ""
+
+msgid " set parents\n"
+msgstr ""
+
+#, python-format
+msgid "rebasing %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid " future parents are %d and %d\n"
+msgstr ""
+
+#, python-format
+msgid " update to %d:%s\n"
+msgstr ""
+
+msgid " already in target\n"
+msgstr ""
+
+#, python-format
+msgid " merge against %d:%s\n"
+msgstr ""
+
+msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgstr ""
+
+msgid "resuming interrupted rebase\n"
+msgstr ""
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr ""
+
+#, python-format
+msgid "next revision set to %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr ""
+
+#, python-format
+msgid "revision %d is an mq patch (%s), finalize it.\n"
+msgstr ""
+
+#, python-format
+msgid "import mq patch %d (%s)\n"
+msgstr ""
+
+msgid "rebase status stored\n"
+msgstr ""
+
+msgid "rebase status resumed\n"
+msgstr ""
+
+msgid "no rebase in progress"
+msgstr ""
+
+msgid "warning: new changesets detected on target branch, not stripping\n"
+msgstr ""
+
+msgid "rebase aborted\n"
+msgstr ""
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr ""
+
+msgid "cannot rebase an ancestor"
+msgstr ""
+
+msgid "cannot rebase a descendant"
+msgstr ""
+
+msgid "already working on current\n"
+msgstr ""
+
+msgid "already working on the current branch\n"
+msgstr ""
+
+#, python-format
+msgid "rebase onto %d starting from %d\n"
+msgstr ""
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr ""
+
+msgid "--update and --rebase are not compatible, ignoring the update flag\n"
+msgstr ""
+
+msgid "rebase working directory to branch head"
+msgstr ""
+
+msgid "rebase from a given revision"
+msgstr ""
+
+msgid "rebase from the base of a given revision"
+msgstr ""
+
+msgid "rebase onto a given revision"
+msgstr ""
+
+msgid "collapse the rebased revisions"
+msgstr ""
+
+msgid "keep original revisions"
+msgstr ""
+
+msgid "keep original branches"
+msgstr ""
+
+msgid "continue an interrupted rebase"
+msgstr ""
+
+msgid "abort an interrupted rebase"
+msgstr ""
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] [--keepbranches] "
+"| [-c] | [-a]"
+msgstr ""
+
+msgid "interactive change selection during commit or qrefresh"
+msgstr ""
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr ""
+
+msgid "this is a binary file\n"
+msgstr ""
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr ""
+
+msgid "[Ynsfdaq?]"
+msgstr ""
+
+msgid "&Yes, record this change"
+msgstr ""
+
+msgid "&No, skip this change"
+msgstr ""
+
+msgid "&Skip remaining changes to this file"
+msgstr ""
+
+msgid "Record remaining changes to this &file"
+msgstr ""
+
+msgid "&Done, skip remaining changes and files"
+msgstr ""
+
+msgid "Record &all changes to all remaining files"
+msgstr ""
+
+msgid "&Quit, recording no changes"
+msgstr ""
+
+msgid "&?"
+msgstr ""
+
+msgid "y"
+msgstr ""
+
+msgid "?"
+msgstr ""
+
+msgid "y - record this change"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "f"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "a"
+msgstr ""
+
+msgid "q"
+msgstr ""
+
+msgid "user quit"
+msgstr ""
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr ""
+
+msgid " and "
+msgstr ""
+
+#, python-format
+msgid "record this change to %r?"
+msgstr ""
+
+#, python-format
+msgid "record change %d/%d to %r?"
+msgstr ""
+
+msgid ""
+"interactively select changes to commit\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be candidates for recording.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" You will be prompted for whether to record changes to each\n"
+" modified file, and for files with multiple changes, for each\n"
+" change to use. For each query, the following responses are\n"
+" possible:\n"
+"\n"
+" y - record this change\n"
+" n - skip this change\n"
+"\n"
+" s - skip remaining changes to this file\n"
+" f - record remaining changes to this file\n"
+"\n"
+" d - done, skip remaining changes and files\n"
+" a - record all changes to all remaining files\n"
+" q - quit, recording no changes\n"
+"\n"
+" ? - display help"
+msgstr ""
+
+msgid "'mq' extension not loaded"
+msgstr ""
+
+msgid "running non-interactively, use commit instead"
+msgstr ""
+
+msgid "no changes to record\n"
+msgstr ""
+
+#, python-format
+msgid "backup %r as %r\n"
+msgstr ""
+
+msgid "applying patch\n"
+msgstr ""
+
+msgid "patch failed to apply"
+msgstr ""
+
+#, python-format
+msgid "restoring %r to %r\n"
+msgstr ""
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr ""
+
+msgid ""
+"create a new shared repository (experimental)\n"
+"\n"
+" Initialize a new repository and working directory that shares its\n"
+" history with another repository.\n"
+"\n"
+" NOTE: actions that change history such as rollback or moving the\n"
+" source may confuse sharers.\n"
+" "
+msgstr ""
+
+msgid "do not create a working copy"
+msgstr ""
+
+msgid "[-U] SOURCE [DEST]"
+msgstr ""
+
+msgid ""
+"patch transplanting tool\n"
+"\n"
+"This extension allows you to transplant patches from another branch.\n"
+"\n"
+"Transplanted patches are recorded in .hg/transplant/transplants, as a\n"
+"map from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr ""
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr ""
+
+#, python-format
+msgid "filtering %s\n"
+msgstr ""
+
+msgid "filter failed"
+msgstr ""
+
+msgid "can only omit patchfile if merging"
+msgstr ""
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr ""
+
+msgid "Fix up the merge and run hg transplant --continue"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr ""
+
+msgid "transplant log file is corrupt"
+msgstr ""
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr ""
+
+msgid "commit failed"
+msgstr ""
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr ""
+
+msgid ""
+"transplant changesets from another branch\n"
+"\n"
+" Selected changesets will be applied on top of the current working\n"
+" directory with the log of the original changeset. If --log is\n"
+" specified, log messages will have a comment appended of the form:\n"
+"\n"
+" (transplanted from CHANGESETHASH)\n"
+"\n"
+" You can rewrite the changelog message with the --filter option.\n"
+" Its argument will be invoked with the current changelog message as\n"
+" $1 and the patch as $2.\n"
+"\n"
+" If --source/-s is specified, selects changesets from the named\n"
+" repository. If --branch/-b is specified, selects changesets from\n"
+" the branch holding the named revision, up to that revision. If\n"
+" --all/-a is specified, all changesets on the branch will be\n"
+" transplanted, otherwise you will be prompted to select the\n"
+" changesets you want.\n"
+"\n"
+" hg transplant --branch REVISION --all will rebase the selected\n"
+" branch (up to the named revision) onto your current working\n"
+" directory.\n"
+"\n"
+" You can optionally mark selected transplanted changesets as merge\n"
+" changesets. You will not be prompted to transplant any ancestors\n"
+" of a merged transplant, and you can merge descendants of them\n"
+" normally instead of transplanting them.\n"
+"\n"
+" If no merges or revisions are provided, hg transplant will start\n"
+" an interactive changeset browser.\n"
+"\n"
+" If a changeset application fails, you can fix the merge by hand\n"
+" and then resume where you left off by calling hg transplant\n"
+" --continue/-c.\n"
+" "
+msgstr ""
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr ""
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr ""
+
+msgid "--all requires a branch revision"
+msgstr ""
+
+msgid "--all is incompatible with a revision list"
+msgstr ""
+
+msgid "no revision checked out"
+msgstr ""
+
+msgid "outstanding uncommitted merges"
+msgstr ""
+
+msgid "outstanding local changes"
+msgstr ""
+
+msgid "pull patches from REPOSITORY"
+msgstr ""
+
+msgid "pull patches from branch BRANCH"
+msgstr ""
+
+msgid "pull all changesets up to BRANCH"
+msgstr ""
+
+msgid "skip over REV"
+msgstr ""
+
+msgid "merge at REV"
+msgstr ""
+
+msgid "append transplant info to log message"
+msgstr ""
+
+msgid "continue last transplant session after repair"
+msgstr ""
+
+msgid "filter changesets through FILTER"
+msgstr ""
+
+msgid ""
+"hg transplant [-s REPOSITORY] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr ""
+
+msgid ""
+"allow to use MBCS path with problematic encoding.\n"
+"\n"
+"Some MBCS encodings are not good for some path operations (i.e.\n"
+"splitting path, case conversion, etc.) with its encoded bytes. We call\n"
+"such a encoding (i.e. shift_jis and big5) as \"problematic encoding\".\n"
+"This extension can be used to fix the issue with those encodings by\n"
+"wrapping some functions to convert to Unicode string before path\n"
+"operation.\n"
+"\n"
+"This extension is useful for:\n"
+" * Japanese Windows users using shift_jis encoding.\n"
+" * Chinese Windows users using big5 encoding.\n"
+" * All users who use a repository with one of problematic encodings on\n"
+" case-insensitive file system.\n"
+"\n"
+"This extension is not needed for:\n"
+" * Any user who use only ASCII chars in path.\n"
+" * Any user who do not use any of problematic encodings.\n"
+"\n"
+"Note that there are some limitations on using this extension:\n"
+" * You should use single encoding in one repository.\n"
+" * You should set same encoding for the repository by locale or\n"
+" HGENCODING.\n"
+"\n"
+"To use this extension, enable the extension in .hg/hgrc or ~/.hgrc:\n"
+"\n"
+" [extensions]\n"
+" hgext.win32mbcs =\n"
+"\n"
+"Path encoding conversion are done between Unicode and\n"
+"encoding.encoding which is decided by Mercurial from current locale\n"
+"setting or HGENCODING.\n"
+"\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] filename conversion fail with %s encoding\n"
+msgstr ""
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] activated with encoding: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr ""
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:\n"
+"\n"
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s\n"
+"\n"
+"and also consider adding:\n"
+"\n"
+"[extensions]\n"
+"hgext.win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+
+msgid ""
+"zeroconf support for Mercurial repositories\n"
+"\n"
+"Zeroconf enabled repositories will be announced in a network without\n"
+"the need to configure a server or a service. They can be discovered\n"
+"without knowing their actual IP address.\n"
+"\n"
+"To use the zeroconf extension add the following entry to your hgrc\n"
+"file:\n"
+"\n"
+"[extensions]\n"
+"hgext.zeroconf =\n"
+"\n"
+"To allow other people to discover your repository using run \"hg serve\"\n"
+"in your repository.\n"
+"\n"
+" $ cd test\n"
+" $ hg serve\n"
+"\n"
+"You can discover zeroconf enabled repositories by running \"hg paths\".\n"
+"\n"
+" $ hg paths\n"
+" zc-test = http://example.com:8000/test\n"
+msgstr ""
+
+msgid "archive prefix contains illegal components"
+msgstr ""
+
+msgid "cannot give prefix when archiving to files"
+msgstr ""
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr ""
+
+msgid "invalid changegroup"
+msgstr ""
+
+msgid "unknown parent"
+msgstr ""
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr ""
+
+#, python-format
+msgid "%s: not a Mercurial bundle file"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle version"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle compression type"
+msgstr ""
+
+msgid "cannot create new bundle repository"
+msgstr ""
+
+#, python-format
+msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgstr ""
+
+msgid "empty username"
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr ""
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr ""
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr ""
+
+msgid "limit must be a positive integer"
+msgstr ""
+
+msgid "limit must be positive"
+msgstr ""
+
+msgid "too many revisions specified"
+msgstr ""
+
+#, python-format
+msgid "invalid format spec '%%%s' in output filename"
+msgstr ""
+
+#, python-format
+msgid "adding %s\n"
+msgstr ""
+
+#, python-format
+msgid "removing %s\n"
+msgstr ""
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr ""
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr ""
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr ""
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "copying %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+
+msgid "no source or destination specified"
+msgstr ""
+
+msgid "no destination specified"
+msgstr ""
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr ""
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr ""
+
+msgid "no files to copy"
+msgstr ""
+
+msgid "(consider using --after)\n"
+msgstr ""
+
+#, python-format
+msgid "changeset: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "branch: %s\n"
+msgstr ""
+
+#, python-format
+msgid "tag: %s\n"
+msgstr ""
+
+#, python-format
+msgid "parent: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "manifest: %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "user: %s\n"
+msgstr ""
+
+#, python-format
+msgid "date: %s\n"
+msgstr ""
+
+msgid "files+:"
+msgstr ""
+
+msgid "files-:"
+msgstr ""
+
+msgid "files:"
+msgstr ""
+
+#, python-format
+msgid "files: %s\n"
+msgstr ""
+
+#, python-format
+msgid "copies: %s\n"
+msgstr ""
+
+#, python-format
+msgid "extra: %s=%s\n"
+msgstr ""
+
+msgid "description:\n"
+msgstr ""
+
+#, python-format
+msgid "summary: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr ""
+
+#, python-format
+msgid "%s: %s"
+msgstr ""
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr ""
+
+msgid "revision matching date not found"
+msgstr ""
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "%s:%s copy source revision cannot be found!\n"
+msgstr ""
+
+msgid "can only follow copies/renames for explicit filenames"
+msgstr ""
+
+msgid "HG: Enter commit message. Lines beginning with 'HG:' are removed."
+msgstr ""
+
+msgid "HG: Leave message empty to abort commit."
+msgstr ""
+
+#, python-format
+msgid "HG: user: %s"
+msgstr ""
+
+msgid "HG: branch merge"
+msgstr ""
+
+#, python-format
+msgid "HG: branch '%s'"
+msgstr ""
+
+#, python-format
+msgid "HG: added %s"
+msgstr ""
+
+#, python-format
+msgid "HG: changed %s"
+msgstr ""
+
+#, python-format
+msgid "HG: removed %s"
+msgstr ""
+
+msgid "HG: no files changed"
+msgstr ""
+
+msgid "empty commit message"
+msgstr ""
+
+msgid ""
+"add the specified files on the next commit\n"
+"\n"
+" Schedule files to be version controlled and added to the\n"
+" repository.\n"
+"\n"
+" The files will be added to the repository at the next commit. To\n"
+" undo an add before that, see hg revert.\n"
+"\n"
+" If no names are given, add all files to the repository.\n"
+" "
+msgstr ""
+"æ–°å¢žä¸‹æ¬¡è¦ commit 的檔案\n"
+"\n"
+" 新增è¦ç´å…¥ç‰ˆæœ¬æŽ§åˆ¶ä¸¦åŠ åˆ° repository 的檔案。\n"
+"\n"
+" 這些檔案將於下次 commit 時被加到 repository。\n"
+" 若想è¦å›žåˆ°æ–°å¢žæª”案å‰çš„狀態,請åƒé–± hg revert 命令。\n"
+"\n"
+" 如果沒有指定檔案,則會將所有的檔案都標示為加到 repository。\n"
+" "
+
+msgid ""
+"add all new files, delete all missing files\n"
+"\n"
+" Add all new files and remove all missing files from the\n"
+" repository.\n"
+"\n"
+" New files are ignored if they match any of the patterns in\n"
+" .hgignore. As with add, these changes take effect at the next\n"
+" commit.\n"
+"\n"
+" Use the -s/--similarity option to detect renamed files. With a\n"
+" parameter > 0, this compares every removed file with every added\n"
+" file and records those similar enough as renames. This option\n"
+" takes a percentage between 0 (disabled) and 100 (files must be\n"
+" identical) as its parameter. Detecting renamed files this way can\n"
+" be expensive.\n"
+" "
+msgstr ""
+"新增所有未å—版本控制的檔案,並刪除所有消失的檔案。\n"
+"\n"
+" 新增所有未加到 repository 的檔案,並移除已加到 repository\n"
+" 廿¶ˆå¤±çš„æª”案。\n"
+"\n"
+" å¦‚æžœæ–°çš„æª”æ¡ˆä¸­æª”åæœ‰ç¬¦åˆä»»ä¸€å­˜åœ¨æ–¼ .hgignore 的樣å¼ï¼Œ\n"
+" å‰‡è©²æª”å°‡è¢«å¿½ç•¥ã€‚å¦‚åŒ add 命令,這些變更將於下次æäº¤æ™‚發生效用。\n"
+"\n"
+" å¯ä½¿ç”¨ -s/--similarity é¸é …åŽ»åµæ¸¬æ›´åçš„æª”æ¡ˆã€‚å¾Œé¢æŽ¥è‘—çš„æ˜¯ä¸€å€‹\n"
+" 大於 0 çš„åƒæ•¸ï¼Œå¯ç”¨ä¾†æ¯”å°æ¯å€‹è¢«æ–°å¢žæˆ–移除的檔案,並試圖找出其\n"
+" æ›´åçš„å¯èƒ½æ€§ã€‚æ­¤é¸é …éœ€è¦æŒ‡å®šä¸€å€‹ä»‹æ–¼ 0 (ä¸ä½¿ç”¨) 至\n"
+" 100 (檔案必須是åŒä¸€å€‹) çš„åƒæ•¸ã€‚嵿¸¬æ›´å檔案的動作將需è¦\n"
+" 一點時間。\n"
+" "
+
+msgid "similarity must be a number"
+msgstr "similarity åƒæ•¸å¿…須是數字"
+
+msgid "similarity must be between 0 and 100"
+msgstr "similarity åƒæ•¸å¿…須介於 0 至 100"
+
+msgid ""
+"show changeset information by line for each file\n"
+"\n"
+" List changes in files, showing the revision id responsible for\n"
+" each line\n"
+"\n"
+" This command is useful for discovering when a change was made and\n"
+" by whom.\n"
+"\n"
+" Without the -a/--text option, annotate will avoid processing files\n"
+" it detects as binary. With -a, annotate will annotate the file\n"
+" anyway, although the results will probably be neither useful\n"
+" nor desirable.\n"
+" "
+msgstr ""
+"顯示æ¯å€‹æª”案中æ¯ä¸€è¡Œ changeset 的資訊\n"
+"\n"
+" List changes in files, showing the revision id responsible for\n"
+" each line\n"
+"\n"
+" This command is useful for discovering when a change was made and\n"
+" by whom.\n"
+"\n"
+" Without the -a/--text option, annotate will avoid processing files\n"
+" it detects as binary. With -a, annotate will annotate the file\n"
+" anyway, although the results will probably be neither useful\n"
+" nor desirable.\n"
+" "
+
+msgid "at least one filename or pattern is required"
+msgstr ""
+
+msgid "at least one of -n/-c is required for -l"
+msgstr ""
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr ""
+
+msgid ""
+"create an unversioned archive of a repository revision\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use -r/--rev to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use -t/--type. Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see 'hg help export' for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use -p/--prefix to specify a format string for the\n"
+" prefix. The default is the basename of the archive, with suffixes\n"
+" removed.\n"
+" "
+msgstr ""
+"建立一個沒有版本控制的版本å°å­˜\n"
+"\n"
+" By default, the revision used is the parent of the working\n"
+" directory; use -r/--rev to specify a different revision.\n"
+"\n"
+" To specify the type of archive to create, use -t/--type. Valid\n"
+" types are:\n"
+"\n"
+" \"files\" (default): a directory full of files\n"
+" \"tar\": tar archive, uncompressed\n"
+" \"tbz2\": tar archive, compressed using bzip2\n"
+" \"tgz\": tar archive, compressed using gzip\n"
+" \"uzip\": zip archive, uncompressed\n"
+" \"zip\": zip archive, compressed using deflate\n"
+"\n"
+" The exact name of the destination archive or directory is given\n"
+" using a format string; see 'hg help export' for details.\n"
+"\n"
+" Each member added to an archive file has a directory prefix\n"
+" prepended. Use -p/--prefix to specify a format string for the\n"
+" prefix. The default is the basename of the archive, with suffixes\n"
+" removed.\n"
+" "
+
+msgid "no working directory: please specify a revision"
+msgstr ""
+
+msgid "repository root cannot be destination"
+msgstr ""
+
+msgid "cannot archive plain files to stdout"
+msgstr ""
+
+msgid ""
+"reverse effect of earlier changeset\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you backout a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head.\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by hand.\n"
+" The result of this merge is not committed, as with a normal merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"å›žå¾©å…ˆå‰ changeset 所作的變更\n"
+"\n"
+" Commit the backed out changes as a new changeset. The new\n"
+" changeset is a child of the backed out changeset.\n"
+"\n"
+" If you backout a changeset other than the tip, a new head is\n"
+" created. This head will be the new tip and you should merge this\n"
+" backout changeset with another head.\n"
+"\n"
+" The --merge option remembers the parent of the working directory\n"
+" before starting the backout, then merges the new head with that\n"
+" changeset afterwards. This saves you from doing the merge by hand.\n"
+" The result of this merge is not committed, as with a normal merge.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+
+msgid "please specify just one revision"
+msgstr ""
+
+msgid "please specify a revision to backout"
+msgstr ""
+
+msgid "cannot backout change on a different branch"
+msgstr ""
+
+msgid "cannot backout a change with no parents"
+msgstr ""
+
+msgid "cannot backout a merge changeset without --parent"
+msgstr ""
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr ""
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr ""
+
+#, python-format
+msgid "Backed out changeset %s"
+msgstr ""
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr ""
+
+msgid "the backout changeset is a new head - do not forget to merge\n"
+msgstr ""
+
+msgid "(use \"backout --merge\" if you want to auto-merge)\n"
+msgstr ""
+
+msgid ""
+"subdivision search of changesets\n"
+"\n"
+" This command helps to find changesets which introduce problems. To\n"
+" use, mark the earliest changeset you know exhibits the problem as\n"
+" bad, then mark the latest changeset which is free from the problem\n"
+" as good. Bisect will update your working directory to a revision\n"
+" for testing (unless the -U/--noupdate option is specified). Once\n"
+" you have performed tests, mark the working directory as good or\n"
+" bad, and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command, it will be used for automatic bisection.\n"
+" Its exit status will be used to mark revisions as good or bad:\n"
+" status 0 means good, 125 means to skip the revision, 127\n"
+" (command not found) will abort the bisection, and any other\n"
+" non-zero exit status means the revision is bad.\n"
+" "
+msgstr ""
+"å° changesets 作二分法æœå°‹\n"
+"\n"
+" This command helps to find changesets which introduce problems. To\n"
+" use, mark the earliest changeset you know exhibits the problem as\n"
+" bad, then mark the latest changeset which is free from the problem\n"
+" as good. Bisect will update your working directory to a revision\n"
+" for testing (unless the -U/--noupdate option is specified). Once\n"
+" you have performed tests, mark the working directory as good or\n"
+" bad, and bisect will either update to another candidate changeset\n"
+" or announce that it has found the bad revision.\n"
+"\n"
+" As a shortcut, you can also use the revision argument to mark a\n"
+" revision as good or bad without checking it out first.\n"
+"\n"
+" If you supply a command, it will be used for automatic bisection.\n"
+" Its exit status will be used to mark revisions as good or bad:\n"
+" status 0 means good, 125 means to skip the revision, 127\n"
+" (command not found) will abort the bisection, and any other\n"
+" non-zero exit status means the revision is bad.\n"
+" "
+
+msgid "The first good revision is:\n"
+msgstr ""
+
+msgid "The first bad revision is:\n"
+msgstr ""
+
+msgid "Due to skipped revisions, the first good revision could be any of:\n"
+msgstr ""
+
+msgid "Due to skipped revisions, the first bad revision could be any of:\n"
+msgstr ""
+
+msgid "cannot bisect (no known good revisions)"
+msgstr ""
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr ""
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr ""
+
+msgid "incompatible arguments"
+msgstr ""
+
+#, python-format
+msgid "cannot find executable: %s"
+msgstr ""
+
+#, python-format
+msgid "failed to execute %s"
+msgstr ""
+
+#, python-format
+msgid "%s killed"
+msgstr ""
+
+#, python-format
+msgid "Changeset %d:%s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "Testing changeset %s:%s (%s changesets remaining, ~%s tests)\n"
+msgstr ""
+
+msgid ""
+"set or show the current branch name\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch will not exist\n"
+" in the repository until the next commit). Standard practice\n"
+" recommends that primary development take place on the 'default'\n"
+" branch.\n"
+"\n"
+" Unless -f/--force is specified, branch will not let you set a\n"
+" branch name that already exists, even if it's inactive.\n"
+"\n"
+" Use -C/--clean to reset the working directory branch to that of\n"
+" the parent of the working directory, negating a previous branch\n"
+" change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+"設定或顯示目å‰çš„ branch å稱\n"
+"\n"
+" With no argument, show the current branch name. With one argument,\n"
+" set the working directory branch name (the branch will not exist\n"
+" in the repository until the next commit). Standard practice\n"
+" recommends that primary development take place on the 'default'\n"
+" branch.\n"
+"\n"
+" Unless -f/--force is specified, branch will not let you set a\n"
+" branch name that already exists, even if it's inactive.\n"
+"\n"
+" Use -C/--clean to reset the working directory branch to that of\n"
+" the parent of the working directory, negating a previous branch\n"
+" change.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr ""
+
+msgid "a branch of the same name already exists (use --force to override)"
+msgstr ""
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr ""
+
+msgid ""
+"list repository named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If active is specified, only show active branches.\n"
+"\n"
+" A branch is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+msgstr ""
+"顯示 repository 的 named branches\n"
+"\n"
+" List the repository's named branches, indicating which ones are\n"
+" inactive. If active is specified, only show active branches.\n"
+"\n"
+" A branch is considered active if it contains repository heads.\n"
+"\n"
+" Use the command 'hg update' to switch to an existing branch.\n"
+" "
+
+msgid ""
+"create a changegroup file\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" -a/--all (or --base null). To change the compression method\n"
+" applied, use the -t/--type option (by default, bundles are\n"
+" compressed using bz2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means\n"
+" and applied to another repository with the unbundle or pull\n"
+" command. This is useful when direct push and pull are not\n"
+" available or when exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+msgstr ""
+"建立一個 changegroup 檔案\n"
+"\n"
+" Generate a compressed changegroup file collecting changesets not\n"
+" known to be in another repository.\n"
+"\n"
+" If no destination repository is specified the destination is\n"
+" assumed to have all the nodes specified by one or more --base\n"
+" parameters. To create a bundle containing all changesets, use\n"
+" -a/--all (or --base null). To change the compression method\n"
+" applied, use the -t/--type option (by default, bundles are\n"
+" compressed using bz2).\n"
+"\n"
+" The bundle file can then be transferred using conventional means\n"
+" and applied to another repository with the unbundle or pull\n"
+" command. This is useful when direct push and pull are not\n"
+" available or when exporting an entire repository is undesirable.\n"
+"\n"
+" Applying bundles preserves all changeset contents including\n"
+" permissions, copy/rename information, and revision history.\n"
+" "
+
+msgid "--base is incompatible with specifying a destination"
+msgstr ""
+
+msgid "unknown bundle type specified with --type"
+msgstr ""
+
+msgid ""
+"output the current or given revision of files\n"
+"\n"
+" Print the specified files as they were at the given revision. If\n"
+" no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repository root\n"
+" %p root-relative path name of file being printed\n"
+" "
+msgstr ""
+"è¼¸å‡ºç›®å‰æˆ–是特定 revision 的檔案內容\n"
+"\n"
+" Print the specified files as they were at the given revision. If\n"
+" no revision is given, the parent of the working directory is used,\n"
+" or tip if no revision is checked out.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are the same as\n"
+" for the export command, with the following additions:\n"
+"\n"
+" %s basename of file being printed\n"
+" %d dirname of file being printed, or '.' if in repository root\n"
+" %p root-relative path name of file being printed\n"
+" "
+
+msgid ""
+"make a copy of an existing repository\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" If you use the -r/--rev option to clone up to a specific revision,\n"
+" no subsequent revisions (including subsequent tags) will be\n"
+" present in the cloned repository. This option implies --pull, even\n"
+" on local repositories.\n"
+"\n"
+" By default, clone will check out the head of the 'default' branch.\n"
+" If the -U/--noupdate option is used, the new clone will contain\n"
+" only a repository (.hg) and no working copy (the working copy\n"
+" parent is the null revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Please see 'hg help urls' for important details about ssh:// URLs.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" "
+msgstr ""
+"å°å·²å­˜åœ¨çš„ repository 複製一份\n"
+"\n"
+" Create a copy of an existing repository in a new directory.\n"
+"\n"
+" If no destination directory name is specified, it defaults to the\n"
+" basename of the source.\n"
+"\n"
+" The location of the source is added to the new repository's\n"
+" .hg/hgrc file, as the default to be used for future pulls.\n"
+"\n"
+" If you use the -r/--rev option to clone up to a specific revision,\n"
+" no subsequent revisions (including subsequent tags) will be\n"
+" present in the cloned repository. This option implies --pull, even\n"
+" on local repositories.\n"
+"\n"
+" By default, clone will check out the head of the 'default' branch.\n"
+" If the -U/--noupdate option is used, the new clone will contain\n"
+" only a repository (.hg) and no working copy (the working copy\n"
+" parent is the null revision).\n"
+"\n"
+" See 'hg help urls' for valid source format details.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination, but no\n"
+" .hg/hgrc and working directory will be created on the remote side.\n"
+" Please see 'hg help urls' for important details about ssh:// URLs.\n"
+"\n"
+" For efficiency, hardlinks are used for cloning whenever the source\n"
+" and destination are on the same filesystem (note this applies only\n"
+" to the repository data, not to the checked out files). Some\n"
+" filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+" do not report errors. In these cases, use the --pull option to\n"
+" avoid hardlinking.\n"
+"\n"
+" In some cases, you can clone repositories and checked out files\n"
+" using full hardlinks with\n"
+"\n"
+" $ cp -al REPO REPOCLONE\n"
+"\n"
+" This is the fastest way to clone, but it is not always safe. The\n"
+" operation is not atomic (making sure REPO is not modified during\n"
+" the operation is up to you) and you have to make sure your editor\n"
+" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+" this is not compatible with certain extensions that place their\n"
+" metadata under the .hg directory, such as mq.\n"
+"\n"
+" "
+
+msgid ""
+"commit the specified files or all outstanding changes\n"
+"\n"
+" Commit changes to the given files into the repository. Unlike a\n"
+" centralized RCS, this operation is a local operation. See hg push\n"
+" for a way to actively distribute your changes.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" filenames or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is\n"
+" started to prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"將指定的檔案或是目å‰çš„變更 commit\n"
+"\n"
+" Commit changes to the given files into the repository. Unlike a\n"
+" centralized RCS, this operation is a local operation. See hg push\n"
+" for a way to actively distribute your changes.\n"
+"\n"
+" If a list of files is omitted, all changes reported by \"hg status\"\n"
+" will be committed.\n"
+"\n"
+" If you are committing the result of a merge, do not provide any\n"
+" filenames or -I/-X filters.\n"
+"\n"
+" If no commit message is specified, the configured editor is\n"
+" started to prompt you for a message.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+
+msgid "created new head\n"
+msgstr ""
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr ""
+
+msgid ""
+"mark files as copied for the next commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+"將檔案標示為 copied 並於下次 commit\n"
+"\n"
+" Mark dest as having copies of source files. If dest is a\n"
+" directory, copies are put in that directory. If dest is a file,\n"
+" the source must be a single file.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect with the next commit. To undo a copy\n"
+" before that, see hg revert.\n"
+" "
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr ""
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr ""
+
+msgid "either two or three arguments required"
+msgstr ""
+
+msgid "returns the completion list associated with the given command"
+msgstr ""
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr ""
+
+msgid "validate the correctness of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr ""
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr ""
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr ""
+
+msgid ""
+"show combined config settings from all hgrc files\n"
+"\n"
+" With no arguments, print names and values of all config items.\n"
+"\n"
+" With one argument of the form section.name, print just the value\n"
+" of that config item.\n"
+"\n"
+" With multiple arguments, print names and values of all config\n"
+" items with matching section names.\n"
+"\n"
+" With --debug, the source (filename and line number) is printed\n"
+" for each config item.\n"
+" "
+msgstr ""
+"顯示åˆä½µè‡ªæ‰€æœ‰ hgrc 檔案內容的設定值\n"
+"\n"
+" With no arguments, print names and values of all config items.\n"
+"\n"
+" With one argument of the form section.name, print just the value\n"
+" of that config item.\n"
+"\n"
+" With multiple arguments, print names and values of all config\n"
+" items with matching section names.\n"
+"\n"
+" With --debug, the source (filename and line number) is printed\n"
+" for each config item.\n"
+" "
+
+msgid "only one config item permitted"
+msgstr ""
+
+msgid ""
+"manually set the parents of the current working directory\n"
+"\n"
+" This is useful for writing repository conversion tools, but should\n"
+" be used with care.\n"
+" "
+msgstr ""
+
+msgid "show the contents of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr ""
+
+msgid "dump the contents of a data file revision"
+msgstr ""
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr ""
+
+msgid "parse and display a date"
+msgstr ""
+
+msgid "dump the contents of an index file"
+msgstr ""
+
+msgid "dump an index DAG as a graphviz dot file"
+msgstr ""
+
+msgid "test Mercurial installation"
+msgstr ""
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr ""
+
+msgid " (check that your locale is properly set)\n"
+msgstr ""
+
+msgid "Checking extensions...\n"
+msgstr ""
+
+msgid " One or more extensions could not be found"
+msgstr ""
+
+msgid " (check that you compiled the extensions)\n"
+msgstr ""
+
+msgid "Checking templates...\n"
+msgstr ""
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr ""
+
+msgid "Checking patch...\n"
+msgstr ""
+
+msgid " patch call failed:\n"
+msgstr ""
+
+msgid " unexpected patch output!\n"
+msgstr ""
+
+msgid " patch test failed!\n"
+msgstr ""
+
+msgid ""
+" (Current patch tool may be incompatible with patch, or misconfigured. "
+"Please check your .hgrc file)\n"
+msgstr ""
+
+msgid ""
+" Internal patcher failure, please report this error to http://www.selenic."
+"com/mercurial/bts\n"
+msgstr ""
+
+msgid "Checking commit editor...\n"
+msgstr ""
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr ""
+
+msgid " (specify a commit editor in your .hgrc file)\n"
+msgstr ""
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr ""
+
+msgid "Checking username...\n"
+msgstr ""
+
+msgid " (specify a username in your .hgrc file)\n"
+msgstr ""
+
+msgid "No problems detected\n"
+msgstr ""
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr ""
+
+msgid "dump rename information"
+msgstr ""
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr ""
+
+msgid "show how files match on given patterns"
+msgstr ""
+
+msgid ""
+"diff repository (or selected files)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a/--text option, diff will avoid generating diffs of\n"
+" files it detects as binary. With -a, diff will generate a diff\n"
+" anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. For more information, read 'hg help diffs'.\n"
+" "
+msgstr ""
+"diff repository (æˆ–æ˜¯æ‰€é¸æ“‡çš„æª”案)\n"
+"\n"
+" Show differences between revisions for the specified files.\n"
+"\n"
+" Differences between files are shown using the unified diff format.\n"
+"\n"
+" NOTE: diff may generate unexpected results for merges, as it will\n"
+" default to comparing against the working directory's first parent\n"
+" changeset if no revisions are specified.\n"
+"\n"
+" When two revision arguments are given, then changes are shown\n"
+" between those revisions. If only one revision is specified then\n"
+" that revision is compared to the working directory, and, when no\n"
+" revisions are specified, the working directory files are compared\n"
+" to its parent.\n"
+"\n"
+" Without the -a/--text option, diff will avoid generating diffs of\n"
+" files it detects as binary. With -a, diff will generate a diff\n"
+" anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. For more information, read 'hg help diffs'.\n"
+" "
+
+msgid ""
+"dump the header and diffs for one or more changesets\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a/--text option, export will avoid generating diffs\n"
+" of files it detects as binary. With -a, export will generate a\n"
+" diff anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. See 'hg help diffs' for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the\n"
+" second parent. It can be useful to review a merge.\n"
+" "
+msgstr ""
+"將一或多個 changesets çš„ header ä»¥åŠ diffs dump 出來\n"
+"\n"
+" Print the changeset header and diffs for one or more revisions.\n"
+"\n"
+" The information shown in the changeset header is: author,\n"
+" changeset hash, parent(s) and commit comment.\n"
+"\n"
+" NOTE: export may generate unexpected diff output for merge\n"
+" changesets, as it will compare the merge changeset against its\n"
+" first parent only.\n"
+"\n"
+" Output may be to a file, in which case the name of the file is\n"
+" given using a format string. The formatting rules are as follows:\n"
+"\n"
+" %% literal \"%\" character\n"
+" %H changeset hash (40 bytes of hexadecimal)\n"
+" %N number of patches being generated\n"
+" %R changeset revision number\n"
+" %b basename of the exporting repository\n"
+" %h short-form changeset hash (12 bytes of hexadecimal)\n"
+" %n zero-padded sequence number, starting at 1\n"
+" %r zero-padded changeset revision number\n"
+"\n"
+" Without the -a/--text option, export will avoid generating diffs\n"
+" of files it detects as binary. With -a, export will generate a\n"
+" diff anyway, probably with undesirable results.\n"
+"\n"
+" Use the -g/--git option to generate diffs in the git extended diff\n"
+" format. See 'hg help diffs' for more information.\n"
+"\n"
+" With the --switch-parent option, the diff will be against the\n"
+" second parent. It can be useful to review a merge.\n"
+" "
+
+msgid "export requires at least one changeset"
+msgstr ""
+
+msgid "exporting patches:\n"
+msgstr ""
+
+msgid "exporting patch:\n"
+msgstr ""
+
+msgid ""
+"search for a pattern in specified files and revisions\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which a\n"
+" match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+msgstr ""
+"從指定的檔案或 revisions æœå°‹æ¨£å¼\n"
+"\n"
+" Search revisions of files for a regular expression.\n"
+"\n"
+" This command behaves differently than Unix grep. It only accepts\n"
+" Python/Perl regexps. It searches repository history, not the\n"
+" working directory. It always prints the revision number in which a\n"
+" match appears.\n"
+"\n"
+" By default, grep only prints output for the first revision of a\n"
+" file in which it finds a match. To get it to print every revision\n"
+" that contains a change in match status (\"-\" for a match that\n"
+" becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+" use the --all flag.\n"
+" "
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr ""
+
+msgid ""
+"show current repository heads or show branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" If one or more REV is given, the \"branch heads\" will be shown for\n"
+" the named branch associated with that revision. The name of the\n"
+" branch is called the revision's branch tag.\n"
+"\n"
+" Branch heads are revisions on a given named branch that do not have\n"
+" any children on the same branch. A branch head could be a true head\n"
+" or it could be the last changeset on a branch before a new branch\n"
+" was created. If none of the branch heads are true heads, the branch\n"
+" is considered inactive.\n"
+"\n"
+" If STARTREV is specified only those heads (or branch heads) that\n"
+" are descendants of STARTREV will be displayed.\n"
+" "
+msgstr ""
+"顯示目å‰çš„ repository heads 或是 branch heads\n"
+"\n"
+" With no arguments, show all repository head changesets.\n"
+"\n"
+" Repository \"heads\" are changesets that don't have child\n"
+" changesets. They are where development generally takes place and\n"
+" are the usual targets for update and merge operations.\n"
+"\n"
+" If one or more REV is given, the \"branch heads\" will be shown for\n"
+" the named branch associated with that revision. The name of the\n"
+" branch is called the revision's branch tag.\n"
+"\n"
+" Branch heads are revisions on a given named branch that do not have\n"
+" any children on the same branch. A branch head could be a true head\n"
+" or it could be the last changeset on a branch before a new branch\n"
+" was created. If none of the branch heads are true heads, the branch\n"
+" is considered inactive.\n"
+"\n"
+" If STARTREV is specified only those heads (or branch heads) that\n"
+" are descendants of STARTREV will be displayed.\n"
+" "
+
+#, python-format
+msgid "no open branch heads on branch %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes on branch %s containing %s are reachable from %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes on branch %s are reachable from %s\n"
+msgstr ""
+
+msgid ""
+"show help for a given topic or a help overview\n"
+"\n"
+" With no arguments, print a list of commands with short help messages.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that\n"
+" topic."
+msgstr ""
+"顯示特定主題的 help 說明或是 help overview\n"
+"\n"
+" With no arguments, print a list of commands with short help messages.\n"
+"\n"
+" Given a topic, extension, or command name, print help for that\n"
+" topic."
+
+msgid "global options:"
+msgstr "全域é¸é …:"
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr ""
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr ""
+
+#, python-format
+msgid "use \"hg -v help%s\" to show aliases and global options"
+msgstr "使用 \"hg -v help%s\" 以顯示別å以åŠå…¨åŸŸé¸é …"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "使用 \"hg -v help %s\" 以顯示全域é¸é …"
+
+msgid ""
+"list of commands:\n"
+"\n"
+msgstr ""
+"命令列表:\n"
+"\n"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"別å: %s\n"
+
+msgid "(no help text available)"
+msgstr "(沒有å¯ç”¨çš„說明文字)"
+
+msgid "options:\n"
+msgstr "é¸é …:\n"
+
+msgid "no commands defined\n"
+msgstr "沒有定義的命令\n"
+
+msgid ""
+"\n"
+"enabled extensions:\n"
+"\n"
+msgstr ""
+"\n"
+"已啟用的擴充套件:\n"
+"\n"
+
+#, python-format
+msgid " %s %s\n"
+msgstr ""
+
+msgid "no help text available"
+msgstr "沒有å¯ç”¨çš„說明文字"
+
+#, python-format
+msgid "%s extension - %s\n"
+msgstr "%s 擴充套件 - %s\n"
+
+msgid "Mercurial Distributed SCM\n"
+msgstr "Mercurial 分散å¼ç‰ˆæœ¬æŽ§åˆ¶ç³»çµ±\n"
+
+msgid ""
+"basic commands:\n"
+"\n"
+msgstr ""
+"基本命令:\n"
+"\n"
+
+msgid ""
+"\n"
+"additional help topics:\n"
+"\n"
+msgstr ""
+"\n"
+"é¡å¤–的說明主題:\n"
+"\n"
+
+msgid ""
+"identify the working copy or specified revision\n"
+"\n"
+" With no revision, print a summary of the current state of the\n"
+" repository.\n"
+"\n"
+" Specifying a path to a repository root or Mercurial bundle will\n"
+" cause lookup to operate on that repository/bundle.\n"
+"\n"
+" This summary identifies the repository state using one or two\n"
+" parent hash identifiers, followed by a \"+\" if there are\n"
+" uncommitted changes in the working directory, a list of tags for\n"
+" this revision and a branch name for non-default branches.\n"
+" "
+msgstr ""
+"識別 working copy 或指定的 revision 完整性\n"
+"\n"
+" With no revision, print a summary of the current state of the\n"
+" repository.\n"
+"\n"
+" Specifying a path to a repository root or Mercurial bundle will\n"
+" cause lookup to operate on that repository/bundle.\n"
+"\n"
+" This summary identifies the repository state using one or two\n"
+" parent hash identifiers, followed by a \"+\" if there are\n"
+" uncommitted changes in the working directory, a list of tags for\n"
+" this revision and a branch name for non-default branches.\n"
+" "
+
+msgid ""
+"import an ordered set of patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f/--force flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (to use the body part, it must have type\n"
+" text/plain or text/x-patch). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and\n"
+" description from patch override values from message headers and\n"
+" body. Values given on command line with -m/--message and -u/--user\n"
+" override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory to\n"
+" the parent of each patch before applying it, and will abort if the\n"
+" resulting changeset has a different ID than the one recorded in\n"
+" the patch. This may happen due to character set problems or other\n"
+" deficiencies in the text patch format.\n"
+"\n"
+" With -s/--similarity, hg will attempt to discover renames and\n"
+" copies in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use \"-\" as the patch name.\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"import 一組有順åºçš„ patches\n"
+"\n"
+" Import a list of patches and commit them individually.\n"
+"\n"
+" If there are outstanding changes in the working directory, import\n"
+" will abort unless given the -f/--force flag.\n"
+"\n"
+" You can import a patch straight from a mail message. Even patches\n"
+" as attachments work (to use the body part, it must have type\n"
+" text/plain or text/x-patch). From and Subject headers of email\n"
+" message are used as default committer and commit message. All\n"
+" text/plain body parts before first diff are added to commit\n"
+" message.\n"
+"\n"
+" If the imported patch was generated by hg export, user and\n"
+" description from patch override values from message headers and\n"
+" body. Values given on command line with -m/--message and -u/--user\n"
+" override these.\n"
+"\n"
+" If --exact is specified, import will set the working directory to\n"
+" the parent of each patch before applying it, and will abort if the\n"
+" resulting changeset has a different ID than the one recorded in\n"
+" the patch. This may happen due to character set problems or other\n"
+" deficiencies in the text patch format.\n"
+"\n"
+" With -s/--similarity, hg will attempt to discover renames and\n"
+" copies in the patch in the same way as 'addremove'.\n"
+"\n"
+" To read a patch from standard input, use \"-\" as the patch name.\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+
+msgid "applying patch from stdin\n"
+msgstr ""
+
+msgid "no diffs found"
+msgstr ""
+
+#, python-format
+msgid ""
+"message:\n"
+"%s\n"
+msgstr ""
+
+msgid "not a Mercurial patch"
+msgstr ""
+
+msgid "patch is damaged or loses information"
+msgstr ""
+
+msgid ""
+"show new changesets found in source\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would have been pulled\n"
+" if a pull at the time you issued this command.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the\n"
+" changesets twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+msgstr ""
+"顯示來æºç«¯æ–°çš„ changesets\n"
+"\n"
+" Show new changesets found in the specified path/URL or the default\n"
+" pull location. These are the changesets that would have been pulled\n"
+" if a pull at the time you issued this command.\n"
+"\n"
+" For remote repository, using --bundle avoids downloading the\n"
+" changesets twice if the incoming is followed by a pull.\n"
+"\n"
+" See pull for valid source format details.\n"
+" "
+
+msgid ""
+"create a new repository in the given directory\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it will be created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"於指定的目錄建立新的 repository\n"
+"\n"
+" Initialize a new repository in the given directory. If the given\n"
+" directory does not exist, it will be created.\n"
+"\n"
+" If no directory is given, the current directory is used.\n"
+"\n"
+" It is possible to specify an ssh:// URL as the destination.\n"
+" See 'hg help urls' for more information.\n"
+" "
+
+msgid ""
+"locate files matching specific patterns\n"
+"\n"
+" Print files under Mercurial control in the working directory whose\n"
+" names match the given patterns.\n"
+"\n"
+" By default, this command searches all directories in the working\n"
+" directory. To search just the current directory and its\n"
+" subdirectories, use \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints the names\n"
+" of all files under Mercurial control in the working directory.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the -0 option to both this command and \"xargs\". This\n"
+" will avoid the problem of \"xargs\" treating single filenames that\n"
+" contain whitespace as multiple filenames.\n"
+" "
+msgstr ""
+"æ‰¾å‡ºç¬¦åˆæŒ‡å®šæ¨£å¼çš„æª”案\n"
+"\n"
+" Print files under Mercurial control in the working directory whose\n"
+" names match the given patterns.\n"
+"\n"
+" By default, this command searches all directories in the working\n"
+" directory. To search just the current directory and its\n"
+" subdirectories, use \"--include .\".\n"
+"\n"
+" If no patterns are given to match, this command prints the names\n"
+" of all files under Mercurial control in the working directory.\n"
+"\n"
+" If you want to feed the output of this command into the \"xargs\"\n"
+" command, use the -0 option to both this command and \"xargs\". This\n"
+" will avoid the problem of \"xargs\" treating single filenames that\n"
+" contain whitespace as multiple filenames.\n"
+" "
+
+msgid ""
+"show revision history of entire repository or files\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a filename to follow history across\n"
+" renames and copies. --follow without a filename will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command prints revision number and changeset id,\n"
+" tags, non-trivial parents, user, date and time, and a summary for\n"
+" each commit. When the -v/--verbose switch is used, the list of\n"
+" changed files and full commit message are shown.\n"
+"\n"
+" NOTE: log -p/--patch may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, only files different from BOTH parents\n"
+" will appear in files:.\n"
+" "
+msgstr ""
+"顯示整個 repository 或特定檔案的 revision history\n"
+"\n"
+" Print the revision history of the specified files or the entire\n"
+" project.\n"
+"\n"
+" File history is shown without following rename or copy history of\n"
+" files. Use -f/--follow with a filename to follow history across\n"
+" renames and copies. --follow without a filename will only show\n"
+" ancestors or descendants of the starting revision. --follow-first\n"
+" only follows the first parent of merge revisions.\n"
+"\n"
+" If no revision range is specified, the default is tip:0 unless\n"
+" --follow is set, in which case the working directory parent is\n"
+" used as the starting revision.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" By default this command prints revision number and changeset id,\n"
+" tags, non-trivial parents, user, date and time, and a summary for\n"
+" each commit. When the -v/--verbose switch is used, the list of\n"
+" changed files and full commit message are shown.\n"
+"\n"
+" NOTE: log -p/--patch may generate unexpected diff output for merge\n"
+" changesets, as it will only compare the merge changeset against\n"
+" its first parent. Also, only files different from BOTH parents\n"
+" will appear in files:.\n"
+" "
+
+msgid ""
+"output the current or given revision of the project manifest\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the first parent of the working directory\n"
+" is used, or the null revision if no revision is checked out.\n"
+"\n"
+" With -v, print file permissions, symlink and executable bits.\n"
+" With --debug, print file revision hashes.\n"
+" "
+msgstr ""
+"輸出 project manifest ç›®å‰æˆ–指定的 revision\n"
+"\n"
+" Print a list of version controlled files for the given revision.\n"
+" If no revision is given, the first parent of the working directory\n"
+" is used, or the null revision if no revision is checked out.\n"
+"\n"
+" With -v, print file permissions, symlink and executable bits.\n"
+" With --debug, print file revision hashes.\n"
+" "
+
+msgid ""
+"merge working directory with another revision\n"
+"\n"
+" The current working directory is updated with all changes made in\n"
+" the requested revision since the last common predecessor revision.\n"
+"\n"
+" Files that changed between either parent are marked as changed for\n"
+" the next commit and a commit must be performed before any further\n"
+" updates to the repository are allowed. The next commit will have\n"
+" two parents.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other\n"
+" head, the other head is merged with by default. Otherwise, an\n"
+" explicit revision with which to merge with must be provided.\n"
+" "
+msgstr ""
+"å°‡ working directory 與其他的 revision åˆä½µ\n"
+"\n"
+" The current working directory is updated with all changes made in\n"
+" the requested revision since the last common predecessor revision.\n"
+"\n"
+" Files that changed between either parent are marked as changed for\n"
+" the next commit and a commit must be performed before any further\n"
+" updates to the repository are allowed. The next commit will have\n"
+" two parents.\n"
+"\n"
+" If no revision is specified, the working directory's parent is a\n"
+" head revision, and the current branch contains exactly one other\n"
+" head, the other head is merged with by default. Otherwise, an\n"
+" explicit revision with which to merge with must be provided.\n"
+" "
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr ""
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr ""
+
+msgid "there is nothing to merge"
+msgstr ""
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr ""
+
+msgid ""
+"working dir not at a head rev - use \"hg update\" or merge with an explicit "
+"rev"
+msgstr ""
+
+msgid ""
+"show changesets not found in destination\n"
+"\n"
+" Show changesets not found in the specified destination repository\n"
+" or the default push location. These are the changesets that would\n"
+" be pushed if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+msgstr ""
+"顯示目的端沒有的 changesets\n"
+"\n"
+" Show changesets not found in the specified destination repository\n"
+" or the default push location. These are the changesets that would\n"
+" be pushed if a push was requested.\n"
+"\n"
+" See pull for valid destination format details.\n"
+" "
+
+msgid ""
+"show the parents of the working directory or revision\n"
+"\n"
+" Print the working directory's parent revisions. If a revision is\n"
+" given via -r/--rev, the parent of that revision will be printed.\n"
+" If a file argument is given, the revision in which the file was\n"
+" last changed (before the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+msgstr ""
+"顯示 working directory 或特定 revision 的 parents\n"
+"\n"
+" Print the working directory's parent revisions. If a revision is\n"
+" given via -r/--rev, the parent of that revision will be printed.\n"
+" If a file argument is given, the revision in which the file was\n"
+" last changed (before the working directory revision or the\n"
+" argument to --rev if given) is printed.\n"
+" "
+
+msgid "can only specify an explicit filename"
+msgstr ""
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr ""
+
+msgid ""
+"show aliases for remote repositories\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given,\n"
+" show definition of all available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"顯示 remote repositories 的別å\n"
+"\n"
+" Show definition of symbolic path name NAME. If no name is given,\n"
+" show definition of all available names.\n"
+"\n"
+" Path names are defined in the [paths] section of /etc/mercurial/hgrc\n"
+" and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.\n"
+"\n"
+" See 'hg help urls' for more information.\n"
+" "
+
+msgid "not found!\n"
+msgstr "沒有找到ï¼\n"
+
+msgid "not updating, since new heads added\n"
+msgstr "沒有更新,因為新的 heads 已加入\n"
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr "(執行 'hg heads' 以顯示 heads,'hg merge' 以執行åˆä½µ)\n"
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr "(執行 'hg update' 來å–å¾— working copy)\n"
+
+msgid ""
+"pull changes from the specified source\n"
+"\n"
+" Pull changes from a remote repository to a local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to a local repository (the current one unless\n"
+" -R is specified). By default, this does not update the copy of the\n"
+" project in the working directory.\n"
+"\n"
+" Use hg incoming if you want to see what would have been added by a\n"
+" pull at the time you issued this command. If you then decide to\n"
+" added those changes to the repository, you should use pull -r X\n"
+" where X is the last changeset listed by hg incoming.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"pull 指定來æºç«¯çš„ changes\n"
+"\n"
+" Pull changes from a remote repository to a local one.\n"
+"\n"
+" This finds all changes from the repository at the specified path\n"
+" or URL and adds them to a local repository (the current one unless\n"
+" -R is specified). By default, this does not update the copy of the\n"
+" project in the working directory.\n"
+"\n"
+" Use hg incoming if you want to see what would have been added by a\n"
+" pull at the time you issued this command. If you then decide to\n"
+" added those changes to the repository, you should use pull -r X\n"
+" where X is the last changeset listed by hg incoming.\n"
+"\n"
+" If SOURCE is omitted, the 'default' path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+
+msgid ""
+"push changes to the specified destination\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It moves changes from\n"
+" the current repository to a different one. If the destination is\n"
+" local this is identical to a pull in that directory from the\n"
+" current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" user forgot to pull and merge before pushing.\n"
+"\n"
+" If -r/--rev is used, the named revision and all its ancestors will\n"
+" be pushed to the remote repository.\n"
+"\n"
+" Please see 'hg help urls' for important details about ssh://\n"
+" URLs. If DESTINATION is omitted, a default path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+msgstr ""
+"將 changes push 至指定的目的端\n"
+"\n"
+" Push changes from the local repository to the given destination.\n"
+"\n"
+" This is the symmetrical operation for pull. It moves changes from\n"
+" the current repository to a different one. If the destination is\n"
+" local this is identical to a pull in that directory from the\n"
+" current one.\n"
+"\n"
+" By default, push will refuse to run if it detects the result would\n"
+" increase the number of remote heads. This generally indicates the\n"
+" user forgot to pull and merge before pushing.\n"
+"\n"
+" If -r/--rev is used, the named revision and all its ancestors will\n"
+" be pushed to the remote repository.\n"
+"\n"
+" Please see 'hg help urls' for important details about ssh://\n"
+" URLs. If DESTINATION is omitted, a default path will be used.\n"
+" See 'hg help urls' for more information.\n"
+" "
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr ""
+
+msgid ""
+"roll back an interrupted transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an\n"
+" interrupted operation. It should only be necessary when Mercurial\n"
+" suggests it.\n"
+" "
+msgstr ""
+"roll back 一個被中斷的 transaction\n"
+"\n"
+" Recover from an interrupted commit or pull.\n"
+"\n"
+" This command tries to fix the repository status after an\n"
+" interrupted operation. It should only be necessary when Mercurial\n"
+" suggests it.\n"
+" "
+
+msgid ""
+"remove the specified files on the next commit\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history. -A/--after can be used to remove only\n"
+" files that have already been deleted, -f/--force can be used to\n"
+" force deletion, and -Af can be used to remove files from the next\n"
+" revision without deleting them from the working directory.\n"
+"\n"
+" The following table details the behavior of remove for different\n"
+" file states (columns) and option combinations (rows). The file\n"
+" states are Added [A], Clean [C], Modified [M] and Missing [!]\n"
+" (as reported by hg status). The actions are Warn, Remove (from\n"
+" branch) and Delete (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+msgstr ""
+"ç§»é™¤ä¸‹æ¬¡è¦ commit 的檔案\n"
+"\n"
+" Schedule the indicated files for removal from the repository.\n"
+"\n"
+" This only removes files from the current branch, not from the\n"
+" entire project history. -A/--after can be used to remove only\n"
+" files that have already been deleted, -f/--force can be used to\n"
+" force deletion, and -Af can be used to remove files from the next\n"
+" revision without deleting them from the working directory.\n"
+"\n"
+" The following table details the behavior of remove for different\n"
+" file states (columns) and option combinations (rows). The file\n"
+" states are Added [A], Clean [C], Modified [M] and Missing [!]\n"
+" (as reported by hg status). The actions are Warn, Remove (from\n"
+" branch) and Delete (from disk).\n"
+"\n"
+" A C M !\n"
+" none W RD W R\n"
+" -f R RD RD R\n"
+" -A W W W R\n"
+" -Af R R R R\n"
+"\n"
+" This command schedules the files to be removed at the next commit.\n"
+" To undo a remove before that, see hg revert.\n"
+" "
+
+msgid "no files specified"
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file is untracked\n"
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file %s (use -f to force removal)\n"
+msgstr ""
+
+msgid "still exists"
+msgstr ""
+
+msgid "is modified"
+msgstr ""
+
+msgid "has been marked for add"
+msgstr ""
+
+msgid ""
+"rename files; equivalent of copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If dest\n"
+" is a directory, copies are put in that directory. If dest is a\n"
+" file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+msgstr ""
+"釿–°å‘½åæª”æ¡ˆï¼›ç­‰åŒæ–¼ copy + remove\n"
+"\n"
+" Mark dest as copies of sources; mark sources for deletion. If dest\n"
+" is a directory, copies are put in that directory. If dest is a\n"
+" file, there can only be one source.\n"
+"\n"
+" By default, this command copies the contents of files as they\n"
+" exist in the working directory. If invoked with -A/--after, the\n"
+" operation is recorded, but no copying is performed.\n"
+"\n"
+" This command takes effect at the next commit. To undo a rename\n"
+" before that, see hg revert.\n"
+" "
+
+msgid ""
+"retry file merges from a merge or update\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a/--all switch.\n"
+"\n"
+" If a conflict is resolved manually, please note that the changes\n"
+" will be overwritten if the merge is retried with resolve. The\n"
+" -m/--mark switch should be used to mark the file as resolved.\n"
+"\n"
+" This command also allows listing resolved files and manually\n"
+" indicating whether or not files are resolved. All files must be\n"
+" marked as resolved before a commit is permitted.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+msgstr ""
+"é‡è©¦ç¶“ç”± merge 或 update 命令所造æˆã€å»æœªå®Œæˆçš„åˆä½µ\n"
+"\n"
+" This command will cleanly retry unresolved file merges using file\n"
+" revisions preserved from the last update or merge. To attempt to\n"
+" resolve all unresolved files, use the -a/--all switch.\n"
+"\n"
+" If a conflict is resolved manually, please note that the changes\n"
+" will be overwritten if the merge is retried with resolve. The\n"
+" -m/--mark switch should be used to mark the file as resolved.\n"
+"\n"
+" This command also allows listing resolved files and manually\n"
+" indicating whether or not files are resolved. All files must be\n"
+" marked as resolved before a commit is permitted.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" U = unresolved\n"
+" R = resolved\n"
+" "
+
+msgid "too many options specified"
+msgstr ""
+
+msgid "can't specify --all and patterns"
+msgstr ""
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr ""
+
+msgid ""
+"restore individual files or directories to an earlier state\n"
+"\n"
+" (Use update -r to check out earlier revisions, revert does not\n"
+" change the working directory parents.)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r/--rev option, revert the given files or directories\n"
+" to their contents as of a specific revision. This can be helpful\n"
+" to \"roll back\" some or all of an earlier change. See 'hg help\n"
+" dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable mode\n"
+" of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+msgstr ""
+"將特定的檔案或目錄回復æˆè¼ƒæ—©çš„狀態\n"
+"\n"
+" (Use update -r to check out earlier revisions, revert does not\n"
+" change the working directory parents.)\n"
+"\n"
+" With no revision specified, revert the named files or directories\n"
+" to the contents they had in the parent of the working directory.\n"
+" This restores the contents of the affected files to an unmodified\n"
+" state and unschedules adds, removes, copies, and renames. If the\n"
+" working directory has two parents, you must explicitly specify the\n"
+" revision to revert to.\n"
+"\n"
+" Using the -r/--rev option, revert the given files or directories\n"
+" to their contents as of a specific revision. This can be helpful\n"
+" to \"roll back\" some or all of an earlier change. See 'hg help\n"
+" dates' for a list of formats valid for -d/--date.\n"
+"\n"
+" Revert modifies the working directory. It does not commit any\n"
+" changes, or change the parent of the working directory. If you\n"
+" revert to a revision other than the parent of the working\n"
+" directory, the reverted files will thus appear modified\n"
+" afterwards.\n"
+"\n"
+" If a file has been deleted, it is restored. If the executable mode\n"
+" of a file was changed, it is reset.\n"
+"\n"
+" If names are given, all files matching the names are reverted.\n"
+" If no arguments are given, no files are reverted.\n"
+"\n"
+" Modified files are saved with a .orig suffix before reverting.\n"
+" To disable these backups, use --no-backup.\n"
+" "
+
+msgid "you can't specify a revision and a date"
+msgstr ""
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr ""
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr ""
+
+#, python-format
+msgid "reverting %s\n"
+msgstr ""
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr ""
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr ""
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr ""
+
+msgid ""
+"roll back the last transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+msgstr ""
+"roll back 最後一次的 transaction\n"
+"\n"
+" This command should be used with care. There is only one level of\n"
+" rollback, and there is no way to undo a rollback. It will also\n"
+" restore the dirstate at the time of the last transaction, losing\n"
+" any dirstate changes since that time.\n"
+"\n"
+" Transactions are used to encapsulate the effects of all commands\n"
+" that create new changesets or propagate existing changesets into a\n"
+" repository. For example, the following commands are transactional,\n"
+" and their effects can be rolled back:\n"
+"\n"
+" commit\n"
+" import\n"
+" pull\n"
+" push (with this repository as destination)\n"
+" unbundle\n"
+"\n"
+" This command is not intended for use on public repositories. Once\n"
+" changes are visible for pull by other users, rolling a transaction\n"
+" back locally is ineffective (someone else may already have pulled\n"
+" the changes). Furthermore, a race is possible with readers of the\n"
+" repository; for example an in-progress pull from the repository\n"
+" may fail if a rollback is performed.\n"
+" "
+
+msgid ""
+"print the root (top) of the current working directory\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+msgstr ""
+"é¡¯ç¤ºç›®å‰ working directory çš„ root 目錄\n"
+"\n"
+" Print the root directory of the current repository.\n"
+" "
+
+msgid ""
+"export the repository via HTTP\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+" files.\n"
+" "
+msgstr ""
+"將 repository 經由 HTTP 發佈\n"
+"\n"
+" Start a local HTTP repository browser and pull server.\n"
+"\n"
+" By default, the server logs accesses to stdout and errors to\n"
+" stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+" files.\n"
+" "
+
+#, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr ""
+
+msgid ""
+"show changed files in the working directory\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" the source of a copy/move operation, are not listed unless\n"
+" -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.\n"
+" Unless options described with \"show only ...\" are given, the\n"
+" options -mardu are used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/--ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the differences between them are\n"
+" shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = missing (deleted by non-hg command, but still tracked)\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = origin of the previous file listed as A (added)\n"
+" "
+msgstr ""
+"顯示 working directory 中已變更的檔案\n"
+"\n"
+" Show status of files in the repository. If names are given, only\n"
+" files that match are shown. Files that are clean or ignored or\n"
+" the source of a copy/move operation, are not listed unless\n"
+" -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.\n"
+" Unless options described with \"show only ...\" are given, the\n"
+" options -mardu are used.\n"
+"\n"
+" Option -q/--quiet hides untracked (unknown and ignored) files\n"
+" unless explicitly requested with -u/--unknown or -i/--ignored.\n"
+"\n"
+" NOTE: status may appear to disagree with diff if permissions have\n"
+" changed or a merge has occurred. The standard diff format does not\n"
+" report permission changes and diff only reports changes relative\n"
+" to one merge parent.\n"
+"\n"
+" If one revision is given, it is used as the base revision.\n"
+" If two revisions are given, the differences between them are\n"
+" shown.\n"
+"\n"
+" The codes used to show the status of files are:\n"
+" M = modified\n"
+" A = added\n"
+" R = removed\n"
+" C = clean\n"
+" ! = missing (deleted by non-hg command, but still tracked)\n"
+" ? = not tracked\n"
+" I = ignored\n"
+" = origin of the previous file listed as A (added)\n"
+" "
+
+msgid ""
+"add one or more tags for the current or given revision\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is\n"
+" used, or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"å°ç›®å‰æˆ–是指定的 revision 新增一或多個 tags\n"
+"\n"
+" Name a particular revision using <name>.\n"
+"\n"
+" 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.\n"
+"\n"
+" If no revision is given, the parent of the working directory is\n"
+" used, or tip if no revision is checked out.\n"
+"\n"
+" 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).\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+
+msgid "tag names must be unique"
+msgstr ""
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr ""
+
+msgid "--rev and --remove are incompatible"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' is not a global tag"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' is not a local tag"
+msgstr ""
+
+#, python-format
+msgid "Removed tag %s"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr ""
+
+#, python-format
+msgid "Added tag %s for changeset %s"
+msgstr ""
+
+msgid ""
+"list repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose\n"
+" switch is used, a third column \"local\" is printed for local tags.\n"
+" "
+msgstr ""
+"列出 repository tags\n"
+"\n"
+" This lists both regular and local tags. When the -v/--verbose\n"
+" switch is used, a third column \"local\" is printed for local tags.\n"
+" "
+
+msgid ""
+"show the tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the changeset\n"
+" most recently added to the repository (and therefore the most\n"
+" recently changed head).\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+msgstr ""
+"顯示 tip revision\n"
+"\n"
+" The tip revision (usually just called the tip) is the changeset\n"
+" most recently added to the repository (and therefore the most\n"
+" recently changed head).\n"
+"\n"
+" If you have just made a commit, that commit will be the tip. If\n"
+" you have just pulled changes from another repository, the tip of\n"
+" that repository becomes the current tip. The \"tip\" tag is special\n"
+" and cannot be renamed or assigned to a different changeset.\n"
+" "
+
+msgid ""
+"apply one or more changegroup files\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+msgstr ""
+"套用一或多個 changegroup 檔案\n"
+"\n"
+" Apply one or more compressed changegroup files generated by the\n"
+" bundle command.\n"
+" "
+
+msgid ""
+"update working directory\n"
+"\n"
+" Update the repository's working directory to the specified\n"
+" revision, or the tip of the current branch if none is specified.\n"
+" Use null as the revision to remove the working copy (like 'hg\n"
+" clone -U').\n"
+"\n"
+" When the working directory contains no uncommitted changes, it\n"
+" will be replaced by the state of the requested revision from the\n"
+" repository. When the requested revision is on a different branch,\n"
+" the working directory will additionally be switched to that\n"
+" branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C/--clean to\n"
+" discard them, forcibly replacing the state of the working\n"
+" directory with the requested revision.\n"
+"\n"
+" When there are uncommitted changes and option -C/--clean is not\n"
+" used, and the parent revision and requested revision are on the\n"
+" same branch, and one of them is an ancestor of the other, then the\n"
+" new working directory will contain the requested revision merged\n"
+" with the uncommitted changes. Otherwise, the update will fail with\n"
+" a suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use\n"
+" revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+msgstr ""
+"æ›´æ–° working directory\n"
+"\n"
+" Update the repository's working directory to the specified\n"
+" revision, or the tip of the current branch if none is specified.\n"
+" Use null as the revision to remove the working copy (like 'hg\n"
+" clone -U').\n"
+"\n"
+" When the working directory contains no uncommitted changes, it\n"
+" will be replaced by the state of the requested revision from the\n"
+" repository. When the requested revision is on a different branch,\n"
+" the working directory will additionally be switched to that\n"
+" branch.\n"
+"\n"
+" When there are uncommitted changes, use option -C/--clean to\n"
+" discard them, forcibly replacing the state of the working\n"
+" directory with the requested revision.\n"
+"\n"
+" When there are uncommitted changes and option -C/--clean is not\n"
+" used, and the parent revision and requested revision are on the\n"
+" same branch, and one of them is an ancestor of the other, then the\n"
+" new working directory will contain the requested revision merged\n"
+" with the uncommitted changes. Otherwise, the update will fail with\n"
+" a suggestion to use 'merge' or 'update -C' instead.\n"
+"\n"
+" If you want to update just one file to an older revision, use\n"
+" revert.\n"
+"\n"
+" See 'hg help dates' for a list of formats valid for -d/--date.\n"
+" "
+
+msgid ""
+"verify the integrity of the repository\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+msgstr ""
+"驗證 repository 的完整性\n"
+"\n"
+" Verify the integrity of the current repository.\n"
+"\n"
+" This will perform an extensive check of the repository's\n"
+" integrity, validating the hashes and checksums of each entry in\n"
+" the changelog, manifest, and tracked files, as well as the\n"
+" integrity of their crosslinks and indices.\n"
+" "
+
+msgid "output version and copyright information"
+msgstr "輸出版本以åŠç‰ˆæ¬Šè³‡è¨Š"
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr "mercurial 分散å¼ç‰ˆæœ¬æŽ§åˆ¶ç³»çµ± (版本 %s)\n"
+
+msgid ""
+"\n"
+"Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+
+msgid "repository root directory or symbolic path name"
+msgstr ""
+
+msgid "change working directory"
+msgstr ""
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr ""
+
+msgid "suppress output"
+msgstr ""
+
+msgid "enable additional output"
+msgstr ""
+
+msgid "set/override config option"
+msgstr ""
+
+msgid "enable debugging output"
+msgstr ""
+
+msgid "start debugger"
+msgstr ""
+
+msgid "set the charset encoding"
+msgstr ""
+
+msgid "set the charset encoding mode"
+msgstr ""
+
+msgid "print traceback on exception"
+msgstr ""
+
+msgid "time how long the command takes"
+msgstr ""
+
+msgid "print command execution profile"
+msgstr ""
+
+msgid "output version information and exit"
+msgstr ""
+
+msgid "display help and exit"
+msgstr ""
+
+msgid "do not perform actions, just print output"
+msgstr ""
+
+msgid "specify ssh command to use"
+msgstr ""
+
+msgid "specify hg command to run on the remote side"
+msgstr ""
+
+msgid "include names matching the given patterns"
+msgstr ""
+
+msgid "exclude names matching the given patterns"
+msgstr ""
+
+msgid "use <text> as commit message"
+msgstr ""
+
+msgid "read commit message from <file>"
+msgstr ""
+
+msgid "record datecode as commit date"
+msgstr ""
+
+msgid "record the specified user as committer"
+msgstr ""
+
+msgid "display using template map file"
+msgstr ""
+
+msgid "display with template"
+msgstr ""
+
+msgid "do not show merges"
+msgstr ""
+
+msgid "treat all files as text"
+msgstr ""
+
+msgid "don't include dates in diff headers"
+msgstr ""
+
+msgid "show which function each change is in"
+msgstr ""
+
+msgid "ignore white space when comparing lines"
+msgstr ""
+
+msgid "ignore changes in the amount of white space"
+msgstr ""
+
+msgid "ignore changes whose lines are all blank"
+msgstr ""
+
+msgid "number of lines of context to show"
+msgstr ""
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr ""
+
+msgid "[OPTION]... [FILE]..."
+msgstr ""
+
+msgid "annotate the specified revision"
+msgstr ""
+
+msgid "follow file copies and renames"
+msgstr ""
+
+msgid "list the author (long with -v)"
+msgstr ""
+
+msgid "list the date (short with -q)"
+msgstr ""
+
+msgid "list the revision number (default)"
+msgstr ""
+
+msgid "list the changeset"
+msgstr ""
+
+msgid "show line number at the first appearance"
+msgstr ""
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr ""
+
+msgid "do not pass files through decoders"
+msgstr ""
+
+msgid "directory prefix for files in archive"
+msgstr ""
+
+msgid "revision to distribute"
+msgstr ""
+
+msgid "type of distribution to create"
+msgstr ""
+
+msgid "[OPTION]... DEST"
+msgstr ""
+
+msgid "merge with old dirstate parent after backout"
+msgstr ""
+
+msgid "parent to choose when backing out merge"
+msgstr ""
+
+msgid "revision to backout"
+msgstr ""
+
+msgid "[OPTION]... [-r] REV"
+msgstr ""
+
+msgid "reset bisect state"
+msgstr ""
+
+msgid "mark changeset good"
+msgstr ""
+
+msgid "mark changeset bad"
+msgstr ""
+
+msgid "skip testing changeset"
+msgstr ""
+
+msgid "use command to check changeset state"
+msgstr ""
+
+msgid "do not update to target"
+msgstr ""
+
+msgid "[-gbsr] [-c CMD] [REV]"
+msgstr ""
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr ""
+
+msgid "reset branch name to parent branch name"
+msgstr ""
+
+msgid "[-fC] [NAME]"
+msgstr ""
+
+msgid "show only branches that have unmerged heads"
+msgstr ""
+
+msgid "[-a]"
+msgstr ""
+
+msgid "run even when remote repository is unrelated"
+msgstr ""
+
+msgid "a changeset up to which you would like to bundle"
+msgstr ""
+
+msgid "a base changeset to specify instead of a destination"
+msgstr ""
+
+msgid "bundle all changesets in the repository"
+msgstr ""
+
+msgid "bundle compression type to use"
+msgstr ""
+
+msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr ""
+
+msgid "print output to file with formatted name"
+msgstr ""
+
+msgid "print the given revision"
+msgstr ""
+
+msgid "apply any matching decode filter"
+msgstr ""
+
+msgid "[OPTION]... FILE..."
+msgstr ""
+
+msgid "the clone will only contain a repository (no working copy)"
+msgstr ""
+
+msgid "a changeset you would like to have after cloning"
+msgstr ""
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr ""
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr ""
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr ""
+
+msgid "record a copy that has already occurred"
+msgstr ""
+
+msgid "forcibly copy over an existing managed file"
+msgstr ""
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr ""
+
+msgid "[INDEX] REV1 REV2"
+msgstr ""
+
+msgid "[COMMAND]"
+msgstr ""
+
+msgid "show the command options"
+msgstr ""
+
+msgid "[-o] CMD"
+msgstr ""
+
+msgid "try extended date formats"
+msgstr ""
+
+msgid "[-e] DATE [RANGE]"
+msgstr ""
+
+msgid "FILE REV"
+msgstr ""
+
+msgid "[PATH]"
+msgstr ""
+
+msgid "FILE"
+msgstr ""
+
+msgid "revision to rebuild to"
+msgstr ""
+
+msgid "[-r REV] [REV]"
+msgstr ""
+
+msgid "revision to debug"
+msgstr ""
+
+msgid "[-r REV] FILE"
+msgstr ""
+
+msgid "REV1 [REV2]"
+msgstr ""
+
+msgid "do not display the saved mtime"
+msgstr ""
+
+msgid "[OPTION]..."
+msgstr ""
+
+msgid "revision to check"
+msgstr ""
+
+msgid "[OPTION]... [-r REV1 [-r REV2]] [FILE]..."
+msgstr ""
+
+msgid "diff against the second parent"
+msgstr ""
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr ""
+
+msgid "end fields with NUL"
+msgstr ""
+
+msgid "print all revisions that match"
+msgstr ""
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr ""
+
+msgid "ignore case when matching"
+msgstr ""
+
+msgid "print only filenames and revisions that match"
+msgstr ""
+
+msgid "print matching line numbers"
+msgstr ""
+
+msgid "search in given revision range"
+msgstr ""
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr ""
+
+msgid "show only heads which are descendants of REV"
+msgstr ""
+
+msgid "show only the active heads from open branches"
+msgstr ""
+
+msgid "show normal and closed heads"
+msgstr ""
+
+msgid "[-r STARTREV] [REV]..."
+msgstr ""
+
+msgid "[TOPIC]"
+msgstr ""
+
+msgid "identify the specified revision"
+msgstr ""
+
+msgid "show local revision number"
+msgstr ""
+
+msgid "show global revision id"
+msgstr ""
+
+msgid "show branch"
+msgstr ""
+
+msgid "show tags"
+msgstr ""
+
+msgid "[-nibt] [-r REV] [SOURCE]"
+msgstr ""
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr ""
+
+msgid "base path"
+msgstr ""
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr ""
+
+msgid "don't commit, just update the working directory"
+msgstr ""
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr ""
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr ""
+
+msgid "[OPTION]... PATCH..."
+msgstr ""
+
+msgid "show newest record first"
+msgstr ""
+
+msgid "file to store the bundles into"
+msgstr ""
+
+msgid "a specific revision up to which you would like to pull"
+msgstr ""
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr ""
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr ""
+
+msgid "search the repository as it stood at REV"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr ""
+
+msgid "print complete paths from the filesystem root"
+msgstr ""
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr ""
+
+msgid "only follow the first parent of merge changesets"
+msgstr ""
+
+msgid "show revisions matching date spec"
+msgstr ""
+
+msgid "show copied files"
+msgstr ""
+
+msgid "do case-insensitive search for a keyword"
+msgstr ""
+
+msgid "include revisions where files were removed"
+msgstr ""
+
+msgid "show only merges"
+msgstr ""
+
+msgid "revisions committed by user"
+msgstr ""
+
+msgid "show only changesets within the given named branch"
+msgstr ""
+
+msgid "do not display revision or any of its ancestors"
+msgstr ""
+
+msgid "[OPTION]... [FILE]"
+msgstr ""
+
+msgid "revision to display"
+msgstr ""
+
+msgid "[-r REV]"
+msgstr ""
+
+msgid "force a merge with outstanding changes"
+msgstr ""
+
+msgid "revision to merge"
+msgstr ""
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr ""
+
+msgid "[-f] [[-r] REV]"
+msgstr ""
+
+msgid "a specific revision up to which you would like to push"
+msgstr ""
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr ""
+
+msgid "show parents from the specified revision"
+msgstr ""
+
+msgid "[-r REV] [FILE]"
+msgstr ""
+
+msgid "[NAME]"
+msgstr ""
+
+msgid "update to new tip if changesets were pulled"
+msgstr ""
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr ""
+
+msgid "force push"
+msgstr ""
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr ""
+
+msgid "record delete for missing files"
+msgstr ""
+
+msgid "remove (and delete) file even if added or modified"
+msgstr ""
+
+msgid "record a rename that has already occurred"
+msgstr ""
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr ""
+
+msgid "remerge all unresolved files"
+msgstr ""
+
+msgid "list state of files needing merge"
+msgstr ""
+
+msgid "mark files as resolved"
+msgstr ""
+
+msgid "unmark files as resolved"
+msgstr ""
+
+msgid "revert all changes when no arguments given"
+msgstr ""
+
+msgid "tipmost revision matching date"
+msgstr ""
+
+msgid "revision to revert to"
+msgstr ""
+
+msgid "do not save backup copies of files"
+msgstr ""
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr ""
+
+msgid "name of access log file to write to"
+msgstr ""
+
+msgid "name of error log file to write to"
+msgstr ""
+
+msgid "port to listen on (default: 8000)"
+msgstr ""
+
+msgid "address to listen on (default: all interfaces)"
+msgstr ""
+
+msgid "prefix path to serve from (default: server root)"
+msgstr ""
+
+msgid "name to show in web pages (default: working directory)"
+msgstr ""
+
+msgid "name of the webdir config file (serve more than one repository)"
+msgstr ""
+
+msgid "for remote clients"
+msgstr ""
+
+msgid "web templates to use"
+msgstr ""
+
+msgid "template style to use"
+msgstr ""
+
+msgid "use IPv6 in addition to IPv4"
+msgstr ""
+
+msgid "SSL certificate file"
+msgstr ""
+
+msgid "show untrusted configuration options"
+msgstr ""
+
+msgid "[-u] [NAME]..."
+msgstr ""
+
+msgid "show status of all files"
+msgstr ""
+
+msgid "show only modified files"
+msgstr ""
+
+msgid "show only added files"
+msgstr ""
+
+msgid "show only removed files"
+msgstr ""
+
+msgid "show only deleted (but tracked) files"
+msgstr ""
+
+msgid "show only files without changes"
+msgstr ""
+
+msgid "show only unknown (not tracked) files"
+msgstr ""
+
+msgid "show only ignored files"
+msgstr ""
+
+msgid "hide status prefix"
+msgstr ""
+
+msgid "show source of copied files"
+msgstr ""
+
+msgid "show difference from revision"
+msgstr ""
+
+msgid "replace existing tag"
+msgstr ""
+
+msgid "make the tag local"
+msgstr ""
+
+msgid "revision to tag"
+msgstr ""
+
+msgid "remove a tag"
+msgstr ""
+
+msgid "[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr ""
+
+msgid "[-p]"
+msgstr ""
+
+msgid "update to new tip if changesets were unbundled"
+msgstr ""
+
+msgid "[-u] FILE..."
+msgstr ""
+
+msgid "overwrite locally modified files (no backup)"
+msgstr ""
+
+msgid "[-C] [-d DATE] [[-r] REV]"
+msgstr ""
+
+#, python-format
+msgid "config error at %s:%d: '%s'"
+msgstr ""
+
+msgid "not found in manifest"
+msgstr ""
+
+msgid "branch name not in UTF-8!"
+msgstr ""
+
+#, python-format
+msgid " searching for copies back to rev %d\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" unmatched files in local:\n"
+" %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" unmatched files in other:\n"
+" %s\n"
+msgstr ""
+
+msgid " all copies found (* = to merge, ! = divergent):\n"
+msgstr ""
+
+msgid " checking for directory renames\n"
+msgstr ""
+
+#, python-format
+msgid " dir %s -> %s\n"
+msgstr ""
+
+#, python-format
+msgid " file %s -> %s\n"
+msgstr ""
+
+msgid "working directory state appears damaged!"
+msgstr ""
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr ""
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr ""
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr ""
+
+#, python-format
+msgid "not in dirstate: %s\n"
+msgstr ""
+
+msgid "unknown"
+msgstr ""
+
+msgid "character device"
+msgstr ""
+
+msgid "block device"
+msgstr ""
+
+msgid "fifo"
+msgstr ""
+
+msgid "socket"
+msgstr ""
+
+msgid "directory"
+msgstr ""
+
+#, python-format
+msgid "unsupported file type (type is %s)"
+msgstr ""
+
+#, python-format
+msgid "abort: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+" %s\n"
+msgstr ""
+
+#, python-format
+msgid "hg: %s\n"
+msgstr ""
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr ""
+
+#, python-format
+msgid "lock held by %s"
+msgstr ""
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr ""
+
+#, python-format
+msgid "abort: %s"
+msgstr ""
+
+msgid " empty string\n"
+msgstr ""
+
+msgid "killed!\n"
+msgstr ""
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "abort: could not import module %s!\n"
+msgstr ""
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr ""
+
+msgid "(is your Python install correct?)\n"
+msgstr ""
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr ""
+
+msgid "broken pipe\n"
+msgstr ""
+
+msgid "interrupted!\n"
+msgstr ""
+
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+
+msgid "abort: out of memory\n"
+msgstr ""
+
+msgid "** unknown exception encountered, details follow\n"
+msgstr ""
+
+msgid "** report bug details to http://www.selenic.com/mercurial/bts\n"
+msgstr ""
+
+msgid "** or mercurial@selenic.com\n"
+msgstr ""
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr ""
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr ""
+
+#, python-format
+msgid "no definition for alias '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' resolves to unknown command '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' resolves to ambiguous command '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' shadows command\n"
+msgstr ""
+
+#, python-format
+msgid "malformed --config option: %s"
+msgstr ""
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr ""
+
+msgid "Option --config may not be abbreviated!"
+msgstr ""
+
+msgid "Option --cwd may not be abbreviated!"
+msgstr ""
+
+msgid ""
+"Option -R has to be separated from other options (i.e. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr ""
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr ""
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr ""
+
+msgid "invalid arguments"
+msgstr ""
+
+#, python-format
+msgid "unrecognized profiling format '%s' - Ignored\n"
+msgstr ""
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr "*** 匯入擴充套件 %s 失敗,路徑為 %s: %s\n"
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr "找ä¸åˆ°åˆä½µå·¥å…· %s\n"
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr "%s å·¥å…·ç„¡æ³•è™•ç† symlinks\n"
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr "%s å·¥å…·ç„¡æ³•è™•ç† binary\n"
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr "%s å·¥å…·éœ€è¦ GUI 環境\n"
+
+#, python-format
+msgid "picked tool '%s' for %s (binary %s symlink %s)\n"
+msgstr "é¸ç”¨ '%s' å·¥å…·ä¾†è™•ç† %s (binary %s symlink %s)\n"
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+" 找ä¸åˆ°å·¥å…·å¯ç”¨ä¾†åˆä½µ %s\n"
+"ç¶­æŒ (l)ocal 還是é¸ç”¨ (o)ther?"
+
+msgid "&Local"
+msgstr ""
+
+msgid "&Other"
+msgstr ""
+
+msgid "l"
+msgstr ""
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr "åˆä½µ %s å’Œ %s 至 %s\n"
+
+#, python-format
+msgid "merging %s\n"
+msgstr "åˆä½µ %s 中\n"
+
+#, python-format
+msgid "my %s other %s ancestor %s\n"
+msgstr ""
+
+msgid " premerge successful\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+
+msgid "&No"
+msgstr ""
+
+msgid "&Yes"
+msgstr ""
+
+msgid "n"
+msgstr ""
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr "åˆä½µ %s 失敗ï¼\n"
+
+#, python-format
+msgid "Inconsistent state, %s:%s is good and bad"
+msgstr ""
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr ""
+
+msgid "Date Formats"
+msgstr "日期格å¼"
+
+msgid ""
+"\n"
+" Some commands allow the user to specify a date, e.g.:\n"
+" * backout, commit, import, tag: Specify the commit date.\n"
+" * log, revert, update: Select revision(s) by date.\n"
+"\n"
+" Many date formats are valid. Here are some examples:\n"
+"\n"
+" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n"
+" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n"
+" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n"
+" \"Dec 6\" (midnight)\n"
+" \"13:18\" (today assumed)\n"
+" \"3:39\" (3:39AM assumed)\n"
+" \"3:39pm\" (15:39)\n"
+" \"2006-12-06 13:18:29\" (ISO 8601 format)\n"
+" \"2006-12-6 13:18\"\n"
+" \"2006-12-6\"\n"
+" \"12-6\"\n"
+" \"12/6\"\n"
+" \"12/6/6\" (Dec 6 2006)\n"
+"\n"
+" Lastly, there is Mercurial's internal format:\n"
+"\n"
+" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n"
+"\n"
+" This is the internal representation format for dates. unixtime is\n"
+" the number of seconds since the epoch (1970-01-01 00:00 UTC).\n"
+" offset is the offset of the local timezone, in seconds west of UTC\n"
+" (negative if the timezone is east of UTC).\n"
+"\n"
+" The log command also accepts date ranges:\n"
+"\n"
+" \"<{datetime}\" - at or before a given date/time\n"
+" \">{datetime}\" - on or after a given date/time\n"
+" \"{datetime} to {datetime}\" - a date range, inclusive\n"
+" \"-{days}\" - within a given number of days of today\n"
+" "
+msgstr ""
+
+msgid "File Name Patterns"
+msgstr "檔案å稱樣å¼"
+
+msgid ""
+"\n"
+" Mercurial accepts several notations for identifying one or more\n"
+" files at a time.\n"
+"\n"
+" By default, Mercurial treats filenames as shell-style extended\n"
+" glob patterns.\n"
+"\n"
+" Alternate pattern notations must be specified explicitly.\n"
+"\n"
+" To use a plain path name without any pattern matching, start it\n"
+" with \"path:\". These path names must completely match starting at\n"
+" the current repository root.\n"
+"\n"
+" To use an extended glob, start a name with \"glob:\". Globs are\n"
+" rooted at the current directory; a glob such as \"*.c\" will only\n"
+" match files in the current directory ending with \".c\".\n"
+"\n"
+" The supported glob syntax extensions are \"**\" to match any string\n"
+" across path separators and \"{a,b}\" to mean \"a or b\".\n"
+"\n"
+" To use a Perl/Python regular expression, start a name with \"re:\".\n"
+" Regexp pattern matching is anchored at the root of the repository.\n"
+"\n"
+" Plain examples:\n"
+"\n"
+" path:foo/bar a name bar in a directory named foo in the root of\n"
+" the repository\n"
+" path:path:name a file or directory named \"path:name\"\n"
+"\n"
+" Glob examples:\n"
+"\n"
+" glob:*.c any name ending in \".c\" in the current directory\n"
+" *.c any name ending in \".c\" in the current directory\n"
+" **.c any name ending in \".c\" in any subdirectory of the\n"
+" current directory including itself.\n"
+" foo/*.c any name ending in \".c\" in the directory foo\n"
+" foo/**.c any name ending in \".c\" in any subdirectory of foo\n"
+" including itself.\n"
+"\n"
+" Regexp examples:\n"
+"\n"
+" re:.*\\.c$ any name ending in \".c\", anywhere in the repository\n"
+"\n"
+" "
+msgstr ""
+
+msgid "Environment Variables"
+msgstr "環境變數"
+
+msgid ""
+"\n"
+"HG::\n"
+" Path to the 'hg' executable, automatically passed when running\n"
+" hooks, extensions or external tools. If unset or empty, this is\n"
+" the hg executable's name if it's frozen, or an executable named\n"
+" 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+" Windows) is searched.\n"
+"\n"
+"HGEDITOR::\n"
+" This is the name of the editor to run when committing. See EDITOR.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGENCODING::\n"
+" This overrides the default locale setting detected by Mercurial.\n"
+" This setting is used to convert data including usernames,\n"
+" changeset descriptions, tag names, and branches. This setting can\n"
+" be overridden with the --encoding command-line option.\n"
+"\n"
+"HGENCODINGMODE::\n"
+" This sets Mercurial's behavior for handling unknown characters\n"
+" while transcoding user input. The default is \"strict\", which\n"
+" causes Mercurial to abort if it can't map a character. Other\n"
+" settings include \"replace\", which replaces unknown characters, and\n"
+" \"ignore\", which drops them. This setting can be overridden with\n"
+" the --encodingmode command-line option.\n"
+"\n"
+"HGMERGE::\n"
+" An executable to use for resolving merge conflicts. The program\n"
+" will be executed with three arguments: local file, remote file,\n"
+" ancestor file.\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"HGRCPATH::\n"
+" A list of files or directories to search for hgrc files. Item\n"
+" separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
+" platform default search path is used. If empty, only the .hg/hgrc\n"
+" from the current repository is read.\n"
+"\n"
+" For each element in HGRCPATH:\n"
+" * if it's a directory, all files ending with .rc are added\n"
+" * otherwise, the file itself will be added\n"
+"\n"
+"HGUSER::\n"
+" This is the string used as the author of a commit. If not set,\n"
+" available values will be considered in this order:\n"
+"\n"
+" * HGUSER (deprecated)\n"
+" * hgrc files from the HGRCPATH\n"
+" * EMAIL\n"
+" * interactive prompt\n"
+" * LOGNAME (with '@hostname' appended)\n"
+"\n"
+" (deprecated, use .hgrc)\n"
+"\n"
+"EMAIL::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"LOGNAME::\n"
+" May be used as the author of a commit; see HGUSER.\n"
+"\n"
+"VISUAL::\n"
+" This is the name of the editor to use when committing. See EDITOR.\n"
+"\n"
+"EDITOR::\n"
+" Sometimes Mercurial needs to open a text file in an editor for a\n"
+" user to modify, for example when writing commit messages. The\n"
+" editor it uses is determined by looking at the environment\n"
+" variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+" non-empty one is chosen. If all of them are empty, the editor\n"
+" defaults to 'vi'.\n"
+"\n"
+"PYTHONPATH::\n"
+" This is used by Python to find imported modules and may need to be\n"
+" set appropriately if this Mercurial is not installed system-wide.\n"
+" "
+msgstr ""
+
+msgid "Specifying Single Revisions"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial supports several ways to specify individual revisions.\n"
+"\n"
+" A plain integer is treated as a revision number. Negative integers\n"
+" are treated as topological offsets from the tip, with -1 denoting\n"
+" the tip. As such, negative numbers are only useful if you've\n"
+" memorized your local tree numbers and want to save typing a single\n"
+" digit. This editor suggests copy and paste.\n"
+"\n"
+" A 40-digit hexadecimal string is treated as a unique revision\n"
+" identifier.\n"
+"\n"
+" A hexadecimal string less than 40 characters long is treated as a\n"
+" unique revision identifier, and referred to as a short-form\n"
+" identifier. A short-form identifier is only valid if it is the\n"
+" prefix of exactly one full-length identifier.\n"
+"\n"
+" Any other string is treated as a tag name, which is a symbolic\n"
+" name associated with a revision identifier. Tag names may not\n"
+" contain the \":\" character.\n"
+"\n"
+" The reserved name \"tip\" is a special tag that always identifies\n"
+" the most recent revision.\n"
+"\n"
+" The reserved name \"null\" indicates the null revision. This is the\n"
+" revision of an empty repository, and the parent of revision 0.\n"
+"\n"
+" The reserved name \".\" indicates the working directory parent. If\n"
+" no working directory is checked out, it is equivalent to null. If\n"
+" an uncommitted merge is in progress, \".\" is the revision of the\n"
+" first parent.\n"
+" "
+msgstr ""
+
+msgid "Specifying Multiple Revisions"
+msgstr ""
+
+msgid ""
+"\n"
+" When Mercurial accepts more than one revision, they may be\n"
+" specified individually, or provided as a topologically continuous\n"
+" range, separated by the \":\" character.\n"
+"\n"
+" The syntax of range notation is [BEGIN]:[END], where BEGIN and END\n"
+" are revision identifiers. Both BEGIN and END are optional. If\n"
+" BEGIN is not specified, it defaults to revision number 0. If END\n"
+" is not specified, it defaults to the tip. The range \":\" thus means\n"
+" \"all revisions\".\n"
+"\n"
+" If BEGIN is greater than END, revisions are treated in reverse\n"
+" order.\n"
+"\n"
+" A range acts as a closed interval. This means that a range of 3:5\n"
+" gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+" "
+msgstr ""
+
+msgid "Diff Formats"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial's default format for showing changes between two\n"
+" versions of a file is compatible with the unified format of GNU\n"
+" diff, which can be used by GNU patch and many other standard\n"
+" tools.\n"
+"\n"
+" While this standard format is often enough, it does not encode the\n"
+" following information:\n"
+"\n"
+" - executable status and other permission bits\n"
+" - copy or rename information\n"
+" - changes in binary files\n"
+" - creation or deletion of empty files\n"
+"\n"
+" Mercurial also supports the extended diff format from the git VCS\n"
+" which addresses these limitations. The git diff format is not\n"
+" produced by default because a few widespread tools still do not\n"
+" understand this format.\n"
+"\n"
+" This means that when generating diffs from a Mercurial repository\n"
+" (e.g. with \"hg export\"), you should be careful about things like\n"
+" file copies and renames or other things mentioned above, because\n"
+" when applying a standard diff to a different repository, this\n"
+" extra information is lost. Mercurial's internal operations (like\n"
+" push and pull) are not affected by this, because they use an\n"
+" internal binary format for communicating changes.\n"
+"\n"
+" To make Mercurial produce the git extended diff format, use the\n"
+" --git option available for many commands, or set 'git = True' in\n"
+" the [diff] section of your hgrc. You do not need to set this\n"
+" option when importing diffs in this format or using them in the mq\n"
+" extension.\n"
+" "
+msgstr ""
+
+msgid "Template Usage"
+msgstr ""
+
+msgid ""
+"\n"
+" Mercurial allows you to customize output of commands through\n"
+" templates. You can either pass in a template from the command\n"
+" line, via the --template option, or select an existing\n"
+" template-style (--style).\n"
+"\n"
+" You can customize output for any \"log-like\" command: log,\n"
+" outgoing, incoming, tip, parents, heads and glog.\n"
+"\n"
+" Three styles are packaged with Mercurial: default (the style used\n"
+" when no explicit preference is passed), compact and changelog.\n"
+" Usage:\n"
+"\n"
+" $ hg log -r1 --style changelog\n"
+"\n"
+" A template is a piece of text, with markup to invoke variable\n"
+" expansion:\n"
+"\n"
+" $ hg log -r1 --template \"{node}\\n\"\n"
+" b56ce7b07c52de7d5fd79fb89701ea538af65746\n"
+"\n"
+" Strings in curly braces are called keywords. The availability of\n"
+" keywords depends on the exact context of the templater. These\n"
+" keywords are usually available for templating a log-like command:\n"
+"\n"
+" - author: String. The unmodified author of the changeset.\n"
+" - branches: String. The name of the branch on which the changeset\n"
+" was committed. Will be empty if the branch name was default.\n"
+" - date: Date information. The date when the changeset was committed.\n"
+" - desc: String. The text of the changeset description.\n"
+" - diffstat: String. Statistics of changes with the following\n"
+" format: \"modified files: +added/-removed lines\"\n"
+" - files: List of strings. All files modified, added, or removed by\n"
+" this changeset.\n"
+" - file_adds: List of strings. Files added by this changeset.\n"
+" - file_mods: List of strings. Files modified by this changeset.\n"
+" - file_dels: List of strings. Files removed by this changeset.\n"
+" - node: String. The changeset identification hash, as a\n"
+" 40-character hexadecimal string.\n"
+" - parents: List of strings. The parents of the changeset.\n"
+" - rev: Integer. The repository-local changeset revision number.\n"
+" - tags: List of strings. Any tags associated with the changeset.\n"
+"\n"
+" The \"date\" keyword does not produce human-readable output. If you\n"
+" want to use a date in your output, you can use a filter to process\n"
+" it. Filters are functions which return a string based on the input\n"
+" variable. You can also use a chain of filters to get the desired\n"
+" output:\n"
+"\n"
+" $ hg tip --template \"{date|isodate}\\n\"\n"
+" 2008-08-21 18:22 +0000\n"
+"\n"
+" List of filters:\n"
+"\n"
+" - addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
+" every line except the last.\n"
+" - age: Date. Returns a human-readable date/time difference between\n"
+" the given date/time and the current date/time.\n"
+" - basename: Any text. Treats the text as a path, and returns the\n"
+" last component of the path after splitting by the path\n"
+" separator (ignoring trailing separators). For example,\n"
+" \"foo/bar/baz\" becomes \"baz\" and \"foo/bar//\" becomes \"bar"
+"\".\n"
+" - stripdir: Treat the text as path and strip a directory level, if\n"
+" possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\".\n"
+" - date: Date. Returns a date in a Unix date format, including\n"
+" the timezone: \"Mon Sep 04 15:13:13 2006 0700\".\n"
+" - domain: Any text. Finds the first string that looks like an\n"
+" email address, and extracts just the domain component.\n"
+" Example: 'User <user@example.com>' becomes 'example.com'.\n"
+" - email: Any text. Extracts the first string that looks like an\n"
+" email address. Example: 'User <user@example.com>' becomes\n"
+" 'user@example.com'.\n"
+" - escape: Any text. Replaces the special XML/XHTML characters \"&\",\n"
+" \"<\" and \">\" with XML entities.\n"
+" - fill68: Any text. Wraps the text to fit in 68 columns.\n"
+" - fill76: Any text. Wraps the text to fit in 76 columns.\n"
+" - firstline: Any text. Returns the first line of text.\n"
+" - nonempty: Any text. Returns '(none)' if the string is empty.\n"
+" - hgdate: Date. Returns the date as a pair of numbers:\n"
+" \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
+" - isodate: Date. Returns the date in ISO 8601 format.\n"
+" - localdate: Date. Converts a date to local date.\n"
+" - obfuscate: Any text. Returns the input text rendered as a\n"
+" sequence of XML entities.\n"
+" - person: Any text. Returns the text before an email address.\n"
+" - rfc822date: Date. Returns a date using the same format used\n"
+" in email headers.\n"
+" - short: Changeset hash. Returns the short form of a changeset\n"
+" hash, i.e. a 12-byte hexadecimal string.\n"
+" - shortdate: Date. Returns a date like \"2006-09-18\".\n"
+" - strip: Any text. Strips all leading and trailing whitespace.\n"
+" - tabindent: Any text. Returns the text, with every line except\n"
+" the first starting with a tab character.\n"
+" - urlescape: Any text. Escapes all \"special\" characters. For\n"
+" example, \"foo bar\" becomes \"foo%20bar\".\n"
+" - user: Any text. Returns the user portion of an email address.\n"
+" "
+msgstr ""
+
+msgid "URL Paths"
+msgstr ""
+
+msgid ""
+"\n"
+" Valid URLs are of the form:\n"
+"\n"
+" local/filesystem/path (or file://local/filesystem/path)\n"
+" http://[user[:pass]@]host[:port]/[path]\n"
+" https://[user[:pass]@]host[:port]/[path]\n"
+" ssh://[user[:pass]@]host[:port]/[path]\n"
+"\n"
+" Paths in the local filesystem can either point to Mercurial\n"
+" repositories or to bundle files (as created by 'hg bundle' or\n"
+" 'hg incoming --bundle').\n"
+"\n"
+" An optional identifier after # indicates a particular branch, tag,\n"
+" or changeset to use from the remote repository.\n"
+"\n"
+" Some features, such as pushing to http:// and https:// URLs are\n"
+" only possible if the feature is explicitly enabled on the remote\n"
+" Mercurial server.\n"
+"\n"
+" Some notes about using SSH with Mercurial:\n"
+" - SSH requires an accessible shell account on the destination\n"
+" machine and a copy of hg in the remote path or specified with as\n"
+" remotecmd.\n"
+" - path is relative to the remote user's home directory by default.\n"
+" Use an extra slash at the start of a path to specify an absolute "
+"path:\n"
+" ssh://example.com//tmp/repository\n"
+" - Mercurial doesn't use its own compression via SSH; the right\n"
+" thing to do is to configure it in your ~/.ssh/config, e.g.:\n"
+" Host *.mylocalnetwork.example.com\n"
+" Compression no\n"
+" Host *\n"
+" Compression yes\n"
+" Alternatively specify \"ssh -C\" as your ssh command in your hgrc\n"
+" or with the --ssh command line option.\n"
+"\n"
+" These URLs can all be stored in your hgrc with path aliases under\n"
+" the [paths] section like so:\n"
+" [paths]\n"
+" alias1 = URL1\n"
+" alias2 = URL2\n"
+" ...\n"
+"\n"
+" You can then use the alias for any command that uses a URL (for\n"
+" example 'hg pull alias1' would pull from the 'alias1' path).\n"
+"\n"
+" Two path aliases are special because they are used as defaults\n"
+" when you do not provide the URL to a command:\n"
+"\n"
+" default:\n"
+" When you create a repository with hg clone, the clone command\n"
+" saves the location of the source repository as the new\n"
+" repository's 'default' path. This is then used when you omit\n"
+" path from push- and pull-like commands (including incoming and\n"
+" outgoing).\n"
+"\n"
+" default-push:\n"
+" The push command will look for a path named 'default-push', and\n"
+" prefer it over 'default' if both are defined.\n"
+" "
+msgstr ""
+
+msgid "can only share local repositories"
+msgstr ""
+
+msgid "destination already exists"
+msgstr "目的端已存在"
+
+msgid "updating working directory\n"
+msgstr "更新 working directory 中\n"
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr "目的端目錄: %s\n"
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr "目的端 '%s' 已存在"
+
+#, python-format
+msgid "destination '%s' is not empty"
+msgstr "目的端 '%s' 䏿˜¯ç©ºçš„"
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr ""
+
+msgid "clone from remote to remote not supported"
+msgstr ""
+
+msgid "updated"
+msgstr "已更新"
+
+msgid "merged"
+msgstr "å·²åˆä½µ"
+
+msgid "removed"
+msgstr "已移除"
+
+msgid "unresolved"
+msgstr ""
+
+#, python-format
+msgid "%d files %s"
+msgstr ""
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr ""
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to "
+"abandon\n"
+msgstr ""
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr ""
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr ""
+
+msgid "SSL support is unavailable"
+msgstr ""
+
+msgid "IPv6 is not available on this system"
+msgstr "æ­¤ä½œæ¥­ç³»çµ±ä¸æ”¯æ´ IPv6"
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr "無法於 '%s:%d' 啟動伺æœå™¨: %s"
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook failed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr ""
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook %s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr ""
+
+msgid "connection ended unexpectedly"
+msgstr ""
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr ""
+
+#, python-format
+msgid "using %s\n"
+msgstr ""
+
+#, python-format
+msgid "capabilities: %s\n"
+msgstr ""
+
+msgid "operation not supported over http"
+msgstr ""
+
+#, python-format
+msgid "sending %s command\n"
+msgstr ""
+
+#, python-format
+msgid "sending %s bytes\n"
+msgstr ""
+
+msgid "authorization failed"
+msgstr ""
+
+#, python-format
+msgid "http error while sending %s command\n"
+msgstr ""
+
+msgid "http error, possibly caused by proxy setting"
+msgstr ""
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr ""
+
+#, python-format
+msgid "requested URL: '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr ""
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr ""
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr ""
+
+msgid "look up remote revision"
+msgstr ""
+
+msgid "unexpected response:"
+msgstr ""
+
+msgid "look up remote changes"
+msgstr ""
+
+msgid "push failed (unexpected response):"
+msgstr ""
+
+#, python-format
+msgid "push failed: %s"
+msgstr ""
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr ""
+
+msgid "cannot create new http repository"
+msgstr ""
+
+#, python-format
+msgid "%s: ignoring invalid syntax '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s not found"
+msgstr ""
+
+#, python-format
+msgid "repository %s already exists"
+msgstr ""
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr ""
+
+#, python-format
+msgid ".hg/sharedpath points to nonexistent directory %s"
+msgstr ""
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr ""
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr ""
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr ""
+
+msgid "cannot parse entry"
+msgstr ""
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr ""
+
+#, python-format
+msgid "tag '%s' refers to unknown node"
+msgstr ""
+
+#, python-format
+msgid "working directory has unknown parent '%s'!"
+msgstr ""
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr ""
+
+#, python-format
+msgid "filtering %s through %s\n"
+msgstr ""
+
+msgid "journal already exists - run hg recover"
+msgstr ""
+
+msgid "rolling back interrupted transaction\n"
+msgstr ""
+
+msgid "no interrupted transaction available\n"
+msgstr ""
+
+msgid "rolling back last transaction\n"
+msgstr ""
+
+#, python-format
+msgid "Named branch could not be reset, current branch still is: %s\n"
+msgstr ""
+
+msgid "no rollback information available\n"
+msgstr ""
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s"
+msgstr ""
+
+#, python-format
+msgid "working directory of %s"
+msgstr ""
+
+#, python-format
+msgid " %s: searching for copy revision for %s\n"
+msgstr ""
+
+#, python-format
+msgid " %s: copy %s:%s\n"
+msgstr ""
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr ""
+
+msgid "file not found!"
+msgstr ""
+
+msgid "no match under directory!"
+msgstr ""
+
+msgid "file not tracked!"
+msgstr ""
+
+msgid "nothing changed\n"
+msgstr ""
+
+msgid "unresolved merge conflicts (see hg resolve)"
+msgstr ""
+
+#, python-format
+msgid "committing subrepository %s\n"
+msgstr ""
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"%s: files over 10MB may cause memory and performance problems\n"
+"(use 'hg revert %s' to unadd the file)\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr ""
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added!\n"
+msgstr ""
+
+#, python-format
+msgid "%s still exists!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr ""
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr ""
+
+msgid "searching for changes\n"
+msgstr ""
+
+#, python-format
+msgid "examining %s:%s\n"
+msgstr ""
+
+msgid "branch already found\n"
+msgstr ""
+
+#, python-format
+msgid "found incomplete branch %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "found new changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "request %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "received %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowing %d:%d %s\n"
+msgstr ""
+
+#, python-format
+msgid "found new branch changeset %s\n"
+msgstr ""
+
+#, python-format
+msgid "narrowed branch search to %s:%s\n"
+msgstr ""
+
+msgid "already have changeset "
+msgstr ""
+
+msgid "warning: repository is unrelated\n"
+msgstr ""
+
+msgid "repository is unrelated"
+msgstr ""
+
+msgid "found new changesets starting at "
+msgstr ""
+
+#, python-format
+msgid "%d total queries\n"
+msgstr ""
+
+msgid "common changesets up to "
+msgstr ""
+
+msgid "requesting all changes\n"
+msgstr ""
+
+msgid ""
+"Partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr ""
+
+#, python-format
+msgid "abort: push creates new remote branch '%s'!\n"
+msgstr ""
+
+msgid "abort: push creates new remote heads!\n"
+msgstr ""
+
+msgid "(did you forget to merge? use push -f to force)\n"
+msgstr ""
+
+msgid "note: unsynced remote changes!\n"
+msgstr ""
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr ""
+
+msgid "list of changesets:\n"
+msgstr ""
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr ""
+
+#, python-format
+msgid "add changeset %s\n"
+msgstr ""
+
+msgid "adding changesets\n"
+msgstr ""
+
+msgid "received changelog group is empty"
+msgstr ""
+
+msgid "adding manifests\n"
+msgstr ""
+
+msgid "adding file changes\n"
+msgstr ""
+
+#, python-format
+msgid "adding %s revisions\n"
+msgstr ""
+
+msgid "received file revlog group is empty"
+msgstr ""
+
+#, python-format
+msgid " (%+d heads)"
+msgstr ""
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr ""
+
+msgid "updating the branch cache\n"
+msgstr ""
+
+msgid "Unexpected response from remote server:"
+msgstr ""
+
+msgid "operation forbidden by server"
+msgstr ""
+
+msgid "locking the remote repository failed"
+msgstr ""
+
+msgid "the server sent an unknown error code"
+msgstr ""
+
+msgid "streaming all changes\n"
+msgstr ""
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr ""
+
+#, python-format
+msgid "adding %s (%s)\n"
+msgstr ""
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr ""
+
+msgid "no [smtp]host in hgrc - cannot send mail"
+msgstr ""
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr ""
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr ""
+
+msgid "(using tls)\n"
+msgstr ""
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr ""
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr ""
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr ""
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr ""
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr ""
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr ""
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr ""
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr ""
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr ""
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+
+msgid "&None"
+msgstr ""
+
+msgid "E&xec"
+msgstr ""
+
+msgid "Sym&link"
+msgstr ""
+
+msgid "resolving manifests\n"
+msgstr ""
+
+#, python-format
+msgid " overwrite %s partial %s\n"
+msgstr ""
+
+#, python-format
+msgid " ancestor %s local %s remote %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+msgid "&Changed"
+msgstr ""
+
+msgid "&Delete"
+msgstr ""
+
+msgid "c"
+msgstr ""
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+
+msgid "&Deleted"
+msgstr ""
+
+#, python-format
+msgid "preserving %s for resolve of %s\n"
+msgstr ""
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "warning: detected divergent renames of %s to:\n"
+msgstr ""
+
+#, python-format
+msgid "branch %s not found"
+msgstr "找ä¸åˆ° branch %s"
+
+msgid "can't merge with ancestor"
+msgstr "ä¸èƒ½å’Œ ancestor åˆä½µ"
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr "沒有å¯åˆä½µçš„變更 (請使用 'hg update' 或 'hg heads' 檢查)"
+
+msgid "outstanding uncommitted changes (use 'hg status' to list changes)"
+msgstr "還有未 commit 的變更 (請使用 'hg status' 來列出變更)"
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C' to discard changes)"
+msgstr ""
+
+msgid "crosses branches (use 'hg merge' or 'hg update -C')"
+msgstr ""
+
+msgid "crosses named branches (use 'hg update -C' to discard changes)"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr "無法建立 %s: 目的端已存在"
+
+#, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr "無法建立 %s: 無法建立目的端目錄"
+
+#, python-format
+msgid "found patch at byte %d\n"
+msgstr "於 byte %d 找到 patch\n"
+
+msgid "patch generated by hg export\n"
+msgstr "經由 hg export 產生的 patch\n"
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr "找ä¸åˆ°å¯ patch çš„ '%s'\n"
+
+#, python-format
+msgid "patching file %s\n"
+msgstr "檔案 %s patching 中\n"
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr ""
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr "檔案 %s 已存在\n"
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d line).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d succeeded at %d %s(offset %d lines).\n"
+msgstr ""
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr ""
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr ""
+
+msgid "could not extract binary patch"
+msgstr "無法解開 binary patch"
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr "binary patch 是 %d bytesï¼Œè€Œä¸æ˜¯ %d"
+
+#, python-format
+msgid "unable to strip away %d dirs from %s"
+msgstr ""
+
+msgid "undefined source and destination files"
+msgstr ""
+
+#, python-format
+msgid "malformed patch %s %s"
+msgstr ""
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr ""
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr "patch 命令失敗: %s"
+
+#, python-format
+msgid "Unsupported line endings type: %s"
+msgstr "䏿”¯æ´çš„è¡Œå°¾çµæŸé¡žåž‹: %s"
+
+#, python-format
+msgid "no valid hunks found; trying with %r instead\n"
+msgstr ""
+
+#, python-format
+msgid "exited with status %d"
+msgstr "以狀態 %d 離開"
+
+#, python-format
+msgid "killed by signal %d"
+msgstr "已被信號 %d 終止"
+
+#, python-format
+msgid "stopped by signal %d"
+msgstr "已被信號 %d åœæ­¢"
+
+msgid "invalid exit code"
+msgstr "ä¸åˆæ³•çš„ exit code"
+
+#, python-format
+msgid "saving bundle to %s\n"
+msgstr "正在儲存 bundle 至 %s\n"
+
+msgid "adding branch\n"
+msgstr "正在新增 branch\n"
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr ""
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr "未知的壓縮類型 %r"
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr "index %s æœªçŸ¥çš„æ ¼å¼ %d"
+
+#, python-format
+msgid "index %s is corrupted"
+msgstr "index %s 已被竄改"
+
+msgid "no node"
+msgstr "沒有 node"
+
+msgid "ambiguous identifier"
+msgstr "䏿˜Žç¢ºçš„ identifier"
+
+msgid "no match found"
+msgstr ""
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr ""
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr "æ–¼ transaction 中找ä¸åˆ° %s"
+
+msgid "unknown base"
+msgstr "未知的 base"
+
+msgid "consistency error adding group"
+msgstr ""
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr "%s çœ‹èµ·ä¾†åƒæ˜¯äºŒé€²ä½æª”案。"
+
+msgid "can only specify two labels."
+msgstr "åªèƒ½æŒ‡å®šå…©å€‹ labels。"
+
+msgid "warning: conflicts during merge.\n"
+msgstr "警告: åˆä½µä¸­ç™¼ç”Ÿè¡çªã€‚\n"
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr "無法解æžä½å€ %s"
+
+msgid "could not create remote repo"
+msgstr "無法建立é ç«¯ repo"
+
+msgid "remote: "
+msgstr "é ç«¯: "
+
+msgid "no suitable response from remote hg"
+msgstr ""
+
+#, python-format
+msgid "push refused: %s"
+msgstr "push 被拒絕: %s"
+
+msgid "unsynced changes"
+msgstr "æœªåŒæ­¥çš„變更"
+
+msgid "cannot lock static-http repository"
+msgstr "無法鎖定 static-http repository"
+
+msgid "cannot create new static-http repository"
+msgstr "無法建立新的 static-http repository"
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr ""
+
+msgid "scanning\n"
+msgstr "掃æä¸­\n"
+
+#, python-format
+msgid "%d files, %d bytes to transfer\n"
+msgstr "å‚³é€ %d 檔案,%d bytes\n"
+
+#, python-format
+msgid "sending %s (%d bytes)\n"
+msgstr "å‚³é€ %s (%d bytes)\n"
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?"
+msgstr ""
+
+msgid "&Remote"
+msgstr ""
+
+msgid "r"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed subrepository %s which remote removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid ""
+" remote changed subrepository %s which local removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid "removing subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid "pulling subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid "pushing subrepo %s\n"
+msgstr ""
+
+msgid "unmatched quotes"
+msgstr ""
+
+#, python-format
+msgid "error expanding '%s%%%s'"
+msgstr ""
+
+#, python-format
+msgid "unknown filter '%s'"
+msgstr ""
+
+#, python-format
+msgid "style not found: %s"
+msgstr ""
+
+#, python-format
+msgid "template file %s: %s"
+msgstr ""
+
+msgid "cannot use transaction when it is already committed/aborted"
+msgstr ""
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr ""
+
+msgid "transaction abort!\n"
+msgstr ""
+
+msgid "rollback completed\n"
+msgstr ""
+
+msgid "rollback failed - please run hg recover\n"
+msgstr ""
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring untrusted configuration option %s.%s = %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s.%s not a boolean ('%s')"
+msgstr ""
+
+msgid "enter a commit username:"
+msgstr ""
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr ""
+
+msgid "Please specify a username."
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr ""
+
+msgid "unrecognized response\n"
+msgstr ""
+
+msgid "response expected"
+msgstr ""
+
+msgid "password: "
+msgstr ""
+
+msgid "edit failed"
+msgstr ""
+
+msgid "http authorization required"
+msgstr ""
+
+msgid "http authorization required\n"
+msgstr ""
+
+#, python-format
+msgid "realm: %s\n"
+msgstr ""
+
+#, python-format
+msgid "user: %s\n"
+msgstr ""
+
+msgid "user:"
+msgstr ""
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr ""
+
+#, python-format
+msgid "proxying through http://%s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr ""
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr ""
+
+#, python-format
+msgid "path %r is inside repo %r"
+msgstr ""
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr ""
+
+msgid "Hardlinks not supported"
+msgstr ""
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid date: %r "
+msgstr ""
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr ""
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr ""
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr ""
+
+#, python-format
+msgid "%.0f GB"
+msgstr ""
+
+#, python-format
+msgid "%.1f GB"
+msgstr ""
+
+#, python-format
+msgid "%.2f GB"
+msgstr ""
+
+#, python-format
+msgid "%.0f MB"
+msgstr ""
+
+#, python-format
+msgid "%.1f MB"
+msgstr ""
+
+#, python-format
+msgid "%.2f MB"
+msgstr ""
+
+#, python-format
+msgid "%.0f KB"
+msgstr ""
+
+#, python-format
+msgid "%.1f KB"
+msgstr ""
+
+#, python-format
+msgid "%.2f KB"
+msgstr ""
+
+#, python-format
+msgid "%.0f bytes"
+msgstr ""
+
+msgid "cannot verify bundle or remote repos"
+msgstr ""
+
+msgid "interrupted"
+msgstr ""
+
+#, python-format
+msgid "empty or missing %s"
+msgstr ""
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr ""
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to nonexistent changeset %d"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to unexpected changeset %d"
+msgstr ""
+
+#, python-format
+msgid " (expected %s)"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "checking parents of %s"
+msgstr ""
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr ""
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr ""
+
+msgid "checking changesets\n"
+msgstr ""
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr ""
+
+msgid "checking manifests\n"
+msgstr ""
+
+#, python-format
+msgid "%s not in changesets"
+msgstr ""
+
+msgid "file without name in manifest"
+msgstr ""
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr ""
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr ""
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr ""
+
+msgid "in changeset but not in manifest"
+msgstr ""
+
+msgid "in manifest but not in changeset"
+msgstr ""
+
+msgid "checking files\n"
+msgstr ""
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr ""
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr ""
+
+msgid "missing revlog!"
+msgstr ""
+
+#, python-format
+msgid "%s not in manifests"
+msgstr ""
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr ""
+
+#, python-format
+msgid "unpacking %s"
+msgstr ""
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s"
+msgstr ""
+
+#, python-format
+msgid "checking rename of %s"
+msgstr ""
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr ""
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr ""
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr ""
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr ""
+
+msgid "user name not available - set USERNAME environment variable"
+msgstr ""
diff --git a/sys/src/cmd/hg/mercurial/__init__.py b/sys/src/cmd/hg/mercurial/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/__init__.py
diff --git a/sys/src/cmd/hg/mercurial/__init__.pyc b/sys/src/cmd/hg/mercurial/__init__.pyc
new file mode 100644
index 000000000..e03123097
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/__init__.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/ancestor.py b/sys/src/cmd/hg/mercurial/ancestor.py
new file mode 100644
index 000000000..56464283b
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/ancestor.py
@@ -0,0 +1,85 @@
+# ancestor.py - generic DAG ancestor algorithm for mercurial
+#
+# Copyright 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import heapq
+
+def ancestor(a, b, pfunc):
+ """
+ return the least common ancestor of nodes a and b or None if there
+ is no such ancestor.
+
+ pfunc must return a list of parent vertices
+ """
+
+ if a == b:
+ return a
+
+ # find depth from root of all ancestors
+ parentcache = {}
+ visit = [a, b]
+ depth = {}
+ while visit:
+ vertex = visit[-1]
+ pl = pfunc(vertex)
+ parentcache[vertex] = pl
+ if not pl:
+ depth[vertex] = 0
+ visit.pop()
+ else:
+ for p in pl:
+ if p == a or p == b: # did we find a or b as a parent?
+ return p # we're done
+ if p not in depth:
+ visit.append(p)
+ if visit[-1] == vertex:
+ depth[vertex] = min([depth[p] for p in pl]) - 1
+ visit.pop()
+
+ # traverse ancestors in order of decreasing distance from root
+ def ancestors(vertex):
+ h = [(depth[vertex], vertex)]
+ seen = set()
+ while h:
+ d, n = heapq.heappop(h)
+ if n not in seen:
+ seen.add(n)
+ yield (d, n)
+ for p in parentcache[n]:
+ heapq.heappush(h, (depth[p], p))
+
+ def generations(vertex):
+ sg, s = None, set()
+ for g, v in ancestors(vertex):
+ if g != sg:
+ if sg:
+ yield sg, s
+ sg, s = g, set((v,))
+ else:
+ s.add(v)
+ yield sg, s
+
+ x = generations(a)
+ y = generations(b)
+ gx = x.next()
+ gy = y.next()
+
+ # increment each ancestor list until it is closer to root than
+ # the other, or they match
+ try:
+ while 1:
+ if gx[0] == gy[0]:
+ for v in gx[1]:
+ if v in gy[1]:
+ return v
+ gy = y.next()
+ gx = x.next()
+ elif gx[0] > gy[0]:
+ gy = y.next()
+ else:
+ gx = x.next()
+ except StopIteration:
+ return None
diff --git a/sys/src/cmd/hg/mercurial/archival.py b/sys/src/cmd/hg/mercurial/archival.py
new file mode 100644
index 000000000..17093ce0f
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/archival.py
@@ -0,0 +1,226 @@
+# archival.py - revision archival for mercurial
+#
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+from node import hex
+import util
+import cStringIO, os, stat, tarfile, time, zipfile
+import zlib, gzip
+
+def tidyprefix(dest, prefix, suffixes):
+ '''choose prefix to use for names in archive. make sure prefix is
+ safe for consumers.'''
+
+ if prefix:
+ prefix = util.normpath(prefix)
+ else:
+ if not isinstance(dest, str):
+ raise ValueError('dest must be string if no prefix')
+ prefix = os.path.basename(dest)
+ lower = prefix.lower()
+ for sfx in suffixes:
+ if lower.endswith(sfx):
+ prefix = prefix[:-len(sfx)]
+ break
+ lpfx = os.path.normpath(util.localpath(prefix))
+ prefix = util.pconvert(lpfx)
+ if not prefix.endswith('/'):
+ prefix += '/'
+ if prefix.startswith('../') or os.path.isabs(lpfx) or '/../' in prefix:
+ raise util.Abort(_('archive prefix contains illegal components'))
+ return prefix
+
+class tarit(object):
+ '''write archive to tar file or stream. can write uncompressed,
+ or compress with gzip or bzip2.'''
+
+ class GzipFileWithTime(gzip.GzipFile):
+
+ def __init__(self, *args, **kw):
+ timestamp = None
+ if 'timestamp' in kw:
+ timestamp = kw.pop('timestamp')
+ if timestamp is None:
+ self.timestamp = time.time()
+ else:
+ self.timestamp = timestamp
+ gzip.GzipFile.__init__(self, *args, **kw)
+
+ def _write_gzip_header(self):
+ self.fileobj.write('\037\213') # magic header
+ self.fileobj.write('\010') # compression method
+ # Python 2.6 deprecates self.filename
+ fname = getattr(self, 'name', None) or self.filename
+ flags = 0
+ if fname:
+ flags = gzip.FNAME
+ self.fileobj.write(chr(flags))
+ gzip.write32u(self.fileobj, long(self.timestamp))
+ self.fileobj.write('\002')
+ self.fileobj.write('\377')
+ if fname:
+ self.fileobj.write(fname + '\000')
+
+ def __init__(self, dest, prefix, mtime, kind=''):
+ self.prefix = tidyprefix(dest, prefix, ['.tar', '.tar.bz2', '.tar.gz',
+ '.tgz', '.tbz2'])
+ self.mtime = mtime
+
+ def taropen(name, mode, fileobj=None):
+ if kind == 'gz':
+ mode = mode[0]
+ if not fileobj:
+ fileobj = open(name, mode + 'b')
+ gzfileobj = self.GzipFileWithTime(name, mode + 'b',
+ zlib.Z_BEST_COMPRESSION,
+ fileobj, timestamp=mtime)
+ return tarfile.TarFile.taropen(name, mode, gzfileobj)
+ else:
+ return tarfile.open(name, mode + kind, fileobj)
+
+ if isinstance(dest, str):
+ self.z = taropen(dest, mode='w:')
+ else:
+ # Python 2.5-2.5.1 have a regression that requires a name arg
+ self.z = taropen(name='', mode='w|', fileobj=dest)
+
+ def addfile(self, name, mode, islink, data):
+ i = tarfile.TarInfo(self.prefix + name)
+ i.mtime = self.mtime
+ i.size = len(data)
+ if islink:
+ i.type = tarfile.SYMTYPE
+ i.mode = 0777
+ i.linkname = data
+ data = None
+ i.size = 0
+ else:
+ i.mode = mode
+ data = cStringIO.StringIO(data)
+ self.z.addfile(i, data)
+
+ def done(self):
+ self.z.close()
+
+class tellable(object):
+ '''provide tell method for zipfile.ZipFile when writing to http
+ response file object.'''
+
+ def __init__(self, fp):
+ self.fp = fp
+ self.offset = 0
+
+ def __getattr__(self, key):
+ return getattr(self.fp, key)
+
+ def write(self, s):
+ self.fp.write(s)
+ self.offset += len(s)
+
+ def tell(self):
+ return self.offset
+
+class zipit(object):
+ '''write archive to zip file or stream. can write uncompressed,
+ or compressed with deflate.'''
+
+ def __init__(self, dest, prefix, mtime, compress=True):
+ self.prefix = tidyprefix(dest, prefix, ('.zip',))
+ if not isinstance(dest, str):
+ try:
+ dest.tell()
+ except (AttributeError, IOError):
+ dest = tellable(dest)
+ self.z = zipfile.ZipFile(dest, 'w',
+ compress and zipfile.ZIP_DEFLATED or
+ zipfile.ZIP_STORED)
+ self.date_time = time.gmtime(mtime)[:6]
+
+ def addfile(self, name, mode, islink, data):
+ i = zipfile.ZipInfo(self.prefix + name, self.date_time)
+ i.compress_type = self.z.compression
+ # unzip will not honor unix file modes unless file creator is
+ # set to unix (id 3).
+ i.create_system = 3
+ ftype = stat.S_IFREG
+ if islink:
+ mode = 0777
+ ftype = stat.S_IFLNK
+ i.external_attr = (mode | ftype) << 16L
+ self.z.writestr(i, data)
+
+ def done(self):
+ self.z.close()
+
+class fileit(object):
+ '''write archive as files in directory.'''
+
+ def __init__(self, name, prefix, mtime):
+ if prefix:
+ raise util.Abort(_('cannot give prefix when archiving to files'))
+ self.basedir = name
+ self.opener = util.opener(self.basedir)
+
+ def addfile(self, name, mode, islink, data):
+ if islink:
+ self.opener.symlink(data, name)
+ return
+ f = self.opener(name, "w", atomictemp=True)
+ f.write(data)
+ f.rename()
+ destfile = os.path.join(self.basedir, name)
+ os.chmod(destfile, mode)
+
+ def done(self):
+ pass
+
+archivers = {
+ 'files': fileit,
+ 'tar': tarit,
+ 'tbz2': lambda name, prefix, mtime: tarit(name, prefix, mtime, 'bz2'),
+ 'tgz': lambda name, prefix, mtime: tarit(name, prefix, mtime, 'gz'),
+ 'uzip': lambda name, prefix, mtime: zipit(name, prefix, mtime, False),
+ 'zip': zipit,
+ }
+
+def archive(repo, dest, node, kind, decode=True, matchfn=None,
+ prefix=None, mtime=None):
+ '''create archive of repo as it was at node.
+
+ dest can be name of directory, name of archive file, or file
+ object to write archive to.
+
+ kind is type of archive to create.
+
+ decode tells whether to put files through decode filters from
+ hgrc.
+
+ matchfn is function to filter names of files to write to archive.
+
+ prefix is name of path to put before every archive member.'''
+
+ def write(name, mode, islink, getdata):
+ if matchfn and not matchfn(name): return
+ data = getdata()
+ if decode:
+ data = repo.wwritedata(name, data)
+ archiver.addfile(name, mode, islink, data)
+
+ if kind not in archivers:
+ raise util.Abort(_("unknown archive type '%s'") % kind)
+
+ ctx = repo[node]
+ archiver = archivers[kind](dest, prefix, mtime or ctx.date()[0])
+
+ if repo.ui.configbool("ui", "archivemeta", True):
+ write('.hg_archival.txt', 0644, False,
+ lambda: 'repo: %s\nnode: %s\n' % (
+ hex(repo.changelog.node(0)), hex(node)))
+ for f in ctx:
+ ff = ctx.flags(f)
+ write(f, 'x' in ff and 0755 or 0644, 'l' in ff, ctx[f].data)
+ archiver.done()
diff --git a/sys/src/cmd/hg/mercurial/base85.c b/sys/src/cmd/hg/mercurial/base85.c
new file mode 100644
index 000000000..3e6c0614c
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/base85.c
@@ -0,0 +1,155 @@
+/*
+ base85 codec
+
+ Copyright 2006 Brendan Cully <brendan@kublai.com>
+
+ This software may be used and distributed according to the terms of
+ the GNU General Public License, incorporated herein by reference.
+
+ Largely based on git's implementation
+*/
+
+#include <Python.h>
+
+static const char b85chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
+static char b85dec[256];
+
+static void
+b85prep(void)
+{
+ int i;
+
+ memset(b85dec, 0, sizeof(b85dec));
+ for (i = 0; i < sizeof(b85chars); i++)
+ b85dec[(int)(b85chars[i])] = i + 1;
+}
+
+static PyObject *
+b85encode(PyObject *self, PyObject *args)
+{
+ const unsigned char *text;
+ PyObject *out;
+ char *dst;
+ int len, olen, i;
+ unsigned int acc, val, ch;
+ int pad = 0;
+
+ if (!PyArg_ParseTuple(args, "s#|i", &text, &len, &pad))
+ return NULL;
+
+ if (pad)
+ olen = ((len + 3) / 4 * 5) - 3;
+ else {
+ olen = len % 4;
+ if (olen)
+ olen++;
+ olen += len / 4 * 5;
+ }
+ if (!(out = PyString_FromStringAndSize(NULL, olen + 3)))
+ return NULL;
+
+ dst = PyString_AS_STRING(out);
+
+ while (len) {
+ acc = 0;
+ for (i = 24; i >= 0; i -= 8) {
+ ch = *text++;
+ acc |= ch << i;
+ if (--len == 0)
+ break;
+ }
+ for (i = 4; i >= 0; i--) {
+ val = acc % 85;
+ acc /= 85;
+ dst[i] = b85chars[val];
+ }
+ dst += 5;
+ }
+
+ if (!pad)
+ _PyString_Resize(&out, olen);
+
+ return out;
+}
+
+static PyObject *
+b85decode(PyObject *self, PyObject *args)
+{
+ PyObject *out;
+ const char *text;
+ char *dst;
+ int len, i, j, olen, c, cap;
+ unsigned int acc;
+
+ if (!PyArg_ParseTuple(args, "s#", &text, &len))
+ return NULL;
+
+ olen = len / 5 * 4;
+ i = len % 5;
+ if (i)
+ olen += i - 1;
+ if (!(out = PyString_FromStringAndSize(NULL, olen)))
+ return NULL;
+
+ dst = PyString_AS_STRING(out);
+
+ i = 0;
+ while (i < len)
+ {
+ acc = 0;
+ cap = len - i - 1;
+ if (cap > 4)
+ cap = 4;
+ for (j = 0; j < cap; i++, j++)
+ {
+ c = b85dec[(int)*text++] - 1;
+ if (c < 0)
+ return PyErr_Format(PyExc_ValueError, "Bad base85 character at position %d", i);
+ acc = acc * 85 + c;
+ }
+ if (i++ < len)
+ {
+ c = b85dec[(int)*text++] - 1;
+ if (c < 0)
+ return PyErr_Format(PyExc_ValueError, "Bad base85 character at position %d", i);
+ /* overflow detection: 0xffffffff == "|NsC0",
+ * "|NsC" == 0x03030303 */
+ if (acc > 0x03030303 || (acc *= 85) > 0xffffffff - c)
+ return PyErr_Format(PyExc_ValueError, "Bad base85 sequence at position %d", i);
+ acc += c;
+ }
+
+ cap = olen < 4 ? olen : 4;
+ olen -= cap;
+ for (j = 0; j < 4 - cap; j++)
+ acc *= 85;
+ if (cap && cap < 4)
+ acc += 0xffffff >> (cap - 1) * 8;
+ for (j = 0; j < cap; j++)
+ {
+ acc = (acc << 8) | (acc >> 24);
+ *dst++ = acc;
+ }
+ }
+
+ return out;
+}
+
+static char base85_doc[] = "Base85 Data Encoding";
+
+static PyMethodDef methods[] = {
+ {"b85encode", b85encode, METH_VARARGS,
+ "Encode text in base85.\n\n"
+ "If the second parameter is true, pad the result to a multiple of "
+ "five characters.\n"},
+ {"b85decode", b85decode, METH_VARARGS, "Decode base85 text.\n"},
+ {NULL, NULL}
+};
+
+PyMODINIT_FUNC initbase85(void)
+{
+ Py_InitModule3("base85", methods, base85_doc);
+
+ b85prep();
+}
diff --git a/sys/src/cmd/hg/mercurial/bdiff.c b/sys/src/cmd/hg/mercurial/bdiff.c
new file mode 100644
index 000000000..60d3c633b
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/bdiff.c
@@ -0,0 +1,401 @@
+/*
+ bdiff.c - efficient binary diff extension for Mercurial
+
+ Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+
+ This software may be used and distributed according to the terms of
+ the GNU General Public License, incorporated herein by reference.
+
+ Based roughly on Python difflib
+*/
+
+#include <Python.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#if defined __hpux || defined __SUNPRO_C || defined _AIX
+# define inline
+#endif
+
+#ifdef __linux
+# define inline __inline
+#endif
+
+#ifdef _WIN32
+#ifdef _MSC_VER
+#define inline __inline
+typedef unsigned long uint32_t;
+#else
+#include <stdint.h>
+#endif
+static uint32_t htonl(uint32_t x)
+{
+ return ((x & 0x000000ffUL) << 24) |
+ ((x & 0x0000ff00UL) << 8) |
+ ((x & 0x00ff0000UL) >> 8) |
+ ((x & 0xff000000UL) >> 24);
+}
+#else
+#include <sys/types.h>
+#if defined __BEOS__ && !defined __HAIKU__
+#include <ByteOrder.h>
+#else
+#include <arpa/inet.h>
+#endif
+#include <inttypes.h>
+#endif
+
+struct line {
+ int h, len, n, e;
+ const char *l;
+};
+
+struct pos {
+ int pos, len;
+};
+
+struct hunk {
+ int a1, a2, b1, b2;
+};
+
+struct hunklist {
+ struct hunk *base, *head;
+};
+
+int splitlines(const char *a, int len, struct line **lr)
+{
+ int h, i;
+ const char *p, *b = a;
+ const char * const plast = a + len - 1;
+ struct line *l;
+
+ /* count the lines */
+ i = 1; /* extra line for sentinel */
+ for (p = a; p < a + len; p++)
+ if (*p == '\n' || p == plast)
+ i++;
+
+ *lr = l = (struct line *)malloc(sizeof(struct line) * i);
+ if (!l)
+ return -1;
+
+ /* build the line array and calculate hashes */
+ h = 0;
+ for (p = a; p < a + len; p++) {
+ /* Leonid Yuriev's hash */
+ h = (h * 1664525) + *p + 1013904223;
+
+ if (*p == '\n' || p == plast) {
+ l->h = h;
+ h = 0;
+ l->len = p - b + 1;
+ l->l = b;
+ l->n = INT_MAX;
+ l++;
+ b = p + 1;
+ }
+ }
+
+ /* set up a sentinel */
+ l->h = l->len = 0;
+ l->l = a + len;
+ return i - 1;
+}
+
+int inline cmp(struct line *a, struct line *b)
+{
+ return a->h != b->h || a->len != b->len || memcmp(a->l, b->l, a->len);
+}
+
+static int equatelines(struct line *a, int an, struct line *b, int bn)
+{
+ int i, j, buckets = 1, t, scale;
+ struct pos *h = NULL;
+
+ /* build a hash table of the next highest power of 2 */
+ while (buckets < bn + 1)
+ buckets *= 2;
+
+ /* try to allocate a large hash table to avoid collisions */
+ for (scale = 4; scale; scale /= 2) {
+ h = (struct pos *)malloc(scale * buckets * sizeof(struct pos));
+ if (h)
+ break;
+ }
+
+ if (!h)
+ return 0;
+
+ buckets = buckets * scale - 1;
+
+ /* clear the hash table */
+ for (i = 0; i <= buckets; i++) {
+ h[i].pos = INT_MAX;
+ h[i].len = 0;
+ }
+
+ /* add lines to the hash table chains */
+ for (i = bn - 1; i >= 0; i--) {
+ /* find the equivalence class */
+ for (j = b[i].h & buckets; h[j].pos != INT_MAX;
+ j = (j + 1) & buckets)
+ if (!cmp(b + i, b + h[j].pos))
+ break;
+
+ /* add to the head of the equivalence class */
+ b[i].n = h[j].pos;
+ b[i].e = j;
+ h[j].pos = i;
+ h[j].len++; /* keep track of popularity */
+ }
+
+ /* compute popularity threshold */
+ t = (bn >= 4000) ? bn / 1000 : bn + 1;
+
+ /* match items in a to their equivalence class in b */
+ for (i = 0; i < an; i++) {
+ /* find the equivalence class */
+ for (j = a[i].h & buckets; h[j].pos != INT_MAX;
+ j = (j + 1) & buckets)
+ if (!cmp(a + i, b + h[j].pos))
+ break;
+
+ a[i].e = j; /* use equivalence class for quick compare */
+ if (h[j].len <= t)
+ a[i].n = h[j].pos; /* point to head of match list */
+ else
+ a[i].n = INT_MAX; /* too popular */
+ }
+
+ /* discard hash tables */
+ free(h);
+ return 1;
+}
+
+static int longest_match(struct line *a, struct line *b, struct pos *pos,
+ int a1, int a2, int b1, int b2, int *omi, int *omj)
+{
+ int mi = a1, mj = b1, mk = 0, mb = 0, i, j, k;
+
+ for (i = a1; i < a2; i++) {
+ /* skip things before the current block */
+ for (j = a[i].n; j < b1; j = b[j].n)
+ ;
+
+ /* loop through all lines match a[i] in b */
+ for (; j < b2; j = b[j].n) {
+ /* does this extend an earlier match? */
+ if (i > a1 && j > b1 && pos[j - 1].pos == i - 1)
+ k = pos[j - 1].len + 1;
+ else
+ k = 1;
+ pos[j].pos = i;
+ pos[j].len = k;
+
+ /* best match so far? */
+ if (k > mk) {
+ mi = i;
+ mj = j;
+ mk = k;
+ }
+ }
+ }
+
+ if (mk) {
+ mi = mi - mk + 1;
+ mj = mj - mk + 1;
+ }
+
+ /* expand match to include neighboring popular lines */
+ while (mi - mb > a1 && mj - mb > b1 &&
+ a[mi - mb - 1].e == b[mj - mb - 1].e)
+ mb++;
+ while (mi + mk < a2 && mj + mk < b2 &&
+ a[mi + mk].e == b[mj + mk].e)
+ mk++;
+
+ *omi = mi - mb;
+ *omj = mj - mb;
+
+ return mk + mb;
+}
+
+static void recurse(struct line *a, struct line *b, struct pos *pos,
+ int a1, int a2, int b1, int b2, struct hunklist *l)
+{
+ int i, j, k;
+
+ /* find the longest match in this chunk */
+ k = longest_match(a, b, pos, a1, a2, b1, b2, &i, &j);
+ if (!k)
+ return;
+
+ /* and recurse on the remaining chunks on either side */
+ recurse(a, b, pos, a1, i, b1, j, l);
+ l->head->a1 = i;
+ l->head->a2 = i + k;
+ l->head->b1 = j;
+ l->head->b2 = j + k;
+ l->head++;
+ recurse(a, b, pos, i + k, a2, j + k, b2, l);
+}
+
+static struct hunklist diff(struct line *a, int an, struct line *b, int bn)
+{
+ struct hunklist l;
+ struct hunk *curr;
+ struct pos *pos;
+ int t;
+
+ /* allocate and fill arrays */
+ t = equatelines(a, an, b, bn);
+ pos = (struct pos *)calloc(bn ? bn : 1, sizeof(struct pos));
+ /* we can't have more matches than lines in the shorter file */
+ l.head = l.base = (struct hunk *)malloc(sizeof(struct hunk) *
+ ((an<bn ? an:bn) + 1));
+
+ if (pos && l.base && t) {
+ /* generate the matching block list */
+ recurse(a, b, pos, 0, an, 0, bn, &l);
+ l.head->a1 = l.head->a2 = an;
+ l.head->b1 = l.head->b2 = bn;
+ l.head++;
+ }
+
+ free(pos);
+
+ /* normalize the hunk list, try to push each hunk towards the end */
+ for (curr = l.base; curr != l.head; curr++) {
+ struct hunk *next = curr+1;
+ int shift = 0;
+
+ if (next == l.head)
+ break;
+
+ if (curr->a2 == next->a1)
+ while (curr->a2+shift < an && curr->b2+shift < bn
+ && !cmp(a+curr->a2+shift, b+curr->b2+shift))
+ shift++;
+ else if (curr->b2 == next->b1)
+ while (curr->b2+shift < bn && curr->a2+shift < an
+ && !cmp(b+curr->b2+shift, a+curr->a2+shift))
+ shift++;
+ if (!shift)
+ continue;
+ curr->b2 += shift;
+ next->b1 += shift;
+ curr->a2 += shift;
+ next->a1 += shift;
+ }
+
+ return l;
+}
+
+static PyObject *blocks(PyObject *self, PyObject *args)
+{
+ PyObject *sa, *sb, *rl = NULL, *m;
+ struct line *a, *b;
+ struct hunklist l = {NULL, NULL};
+ struct hunk *h;
+ int an, bn, pos = 0;
+
+ if (!PyArg_ParseTuple(args, "SS:bdiff", &sa, &sb))
+ return NULL;
+
+ an = splitlines(PyString_AsString(sa), PyString_Size(sa), &a);
+ bn = splitlines(PyString_AsString(sb), PyString_Size(sb), &b);
+ if (!a || !b)
+ goto nomem;
+
+ l = diff(a, an, b, bn);
+ rl = PyList_New(l.head - l.base);
+ if (!l.head || !rl)
+ goto nomem;
+
+ for (h = l.base; h != l.head; h++) {
+ m = Py_BuildValue("iiii", h->a1, h->a2, h->b1, h->b2);
+ PyList_SetItem(rl, pos, m);
+ pos++;
+ }
+
+nomem:
+ free(a);
+ free(b);
+ free(l.base);
+ return rl ? rl : PyErr_NoMemory();
+}
+
+static PyObject *bdiff(PyObject *self, PyObject *args)
+{
+ char *sa, *sb;
+ PyObject *result = NULL;
+ struct line *al, *bl;
+ struct hunklist l = {NULL, NULL};
+ struct hunk *h;
+ char encode[12], *rb;
+ int an, bn, len = 0, la, lb;
+
+ if (!PyArg_ParseTuple(args, "s#s#:bdiff", &sa, &la, &sb, &lb))
+ return NULL;
+
+ an = splitlines(sa, la, &al);
+ bn = splitlines(sb, lb, &bl);
+ if (!al || !bl)
+ goto nomem;
+
+ l = diff(al, an, bl, bn);
+ if (!l.head)
+ goto nomem;
+
+ /* calculate length of output */
+ la = lb = 0;
+ for (h = l.base; h != l.head; h++) {
+ if (h->a1 != la || h->b1 != lb)
+ len += 12 + bl[h->b1].l - bl[lb].l;
+ la = h->a2;
+ lb = h->b2;
+ }
+
+ result = PyString_FromStringAndSize(NULL, len);
+ if (!result)
+ goto nomem;
+
+ /* build binary patch */
+ rb = PyString_AsString(result);
+ la = lb = 0;
+
+ for (h = l.base; h != l.head; h++) {
+ if (h->a1 != la || h->b1 != lb) {
+ len = bl[h->b1].l - bl[lb].l;
+ *(uint32_t *)(encode) = htonl(al[la].l - al->l);
+ *(uint32_t *)(encode + 4) = htonl(al[h->a1].l - al->l);
+ *(uint32_t *)(encode + 8) = htonl(len);
+ memcpy(rb, encode, 12);
+ memcpy(rb + 12, bl[lb].l, len);
+ rb += 12 + len;
+ }
+ la = h->a2;
+ lb = h->b2;
+ }
+
+nomem:
+ free(al);
+ free(bl);
+ free(l.base);
+ return result ? result : PyErr_NoMemory();
+}
+
+static char mdiff_doc[] = "Efficient binary diff.";
+
+static PyMethodDef methods[] = {
+ {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"},
+ {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"},
+ {NULL, NULL}
+};
+
+PyMODINIT_FUNC initbdiff(void)
+{
+ Py_InitModule3("bdiff", methods, mdiff_doc);
+}
+
diff --git a/sys/src/cmd/hg/mercurial/bundlerepo.py b/sys/src/cmd/hg/mercurial/bundlerepo.py
new file mode 100644
index 000000000..14d74e1e5
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/bundlerepo.py
@@ -0,0 +1,303 @@
+# bundlerepo.py - repository class for viewing uncompressed bundles
+#
+# Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+"""Repository class for viewing uncompressed bundles.
+
+This provides a read-only repository interface to bundles as if they
+were part of the actual repository.
+"""
+
+from node import nullid
+from i18n import _
+import os, struct, bz2, zlib, tempfile, shutil
+import changegroup, util, mdiff
+import localrepo, changelog, manifest, filelog, revlog, error
+
+class bundlerevlog(revlog.revlog):
+ def __init__(self, opener, indexfile, bundlefile,
+ linkmapper=None):
+ # How it works:
+ # to retrieve a revision, we need to know the offset of
+ # the revision in the bundlefile (an opened file).
+ #
+ # We store this offset in the index (start), to differentiate a
+ # rev in the bundle and from a rev in the revlog, we check
+ # len(index[r]). If the tuple is bigger than 7, it is a bundle
+ # (it is bigger since we store the node to which the delta is)
+ #
+ revlog.revlog.__init__(self, opener, indexfile)
+ self.bundlefile = bundlefile
+ self.basemap = {}
+ def chunkpositer():
+ for chunk in changegroup.chunkiter(bundlefile):
+ pos = bundlefile.tell()
+ yield chunk, pos - len(chunk)
+ n = len(self)
+ prev = None
+ for chunk, start in chunkpositer():
+ size = len(chunk)
+ if size < 80:
+ raise util.Abort(_("invalid changegroup"))
+ start += 80
+ size -= 80
+ node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
+ if node in self.nodemap:
+ prev = node
+ continue
+ for p in (p1, p2):
+ if not p in self.nodemap:
+ raise error.LookupError(p1, self.indexfile,
+ _("unknown parent"))
+ if linkmapper is None:
+ link = n
+ else:
+ link = linkmapper(cs)
+
+ if not prev:
+ prev = p1
+ # start, size, full unc. size, base (unused), link, p1, p2, node
+ e = (revlog.offset_type(start, 0), size, -1, -1, link,
+ self.rev(p1), self.rev(p2), node)
+ self.basemap[n] = prev
+ self.index.insert(-1, e)
+ self.nodemap[node] = n
+ prev = node
+ n += 1
+
+ def bundle(self, rev):
+ """is rev from the bundle"""
+ if rev < 0:
+ return False
+ return rev in self.basemap
+ def bundlebase(self, rev): return self.basemap[rev]
+ def chunk(self, rev, df=None, cachelen=4096):
+ # Warning: in case of bundle, the diff is against bundlebase,
+ # not against rev - 1
+ # XXX: could use some caching
+ if not self.bundle(rev):
+ return revlog.revlog.chunk(self, rev, df)
+ self.bundlefile.seek(self.start(rev))
+ return self.bundlefile.read(self.length(rev))
+
+ def revdiff(self, rev1, rev2):
+ """return or calculate a delta between two revisions"""
+ if self.bundle(rev1) and self.bundle(rev2):
+ # hot path for bundle
+ revb = self.rev(self.bundlebase(rev2))
+ if revb == rev1:
+ return self.chunk(rev2)
+ elif not self.bundle(rev1) and not self.bundle(rev2):
+ return revlog.revlog.revdiff(self, rev1, rev2)
+
+ return mdiff.textdiff(self.revision(self.node(rev1)),
+ self.revision(self.node(rev2)))
+
+ def revision(self, node):
+ """return an uncompressed revision of a given"""
+ if node == nullid: return ""
+
+ text = None
+ chain = []
+ iter_node = node
+ rev = self.rev(iter_node)
+ # reconstruct the revision if it is from a changegroup
+ while self.bundle(rev):
+ if self._cache and self._cache[0] == iter_node:
+ text = self._cache[2]
+ break
+ chain.append(rev)
+ iter_node = self.bundlebase(rev)
+ rev = self.rev(iter_node)
+ if text is None:
+ text = revlog.revlog.revision(self, iter_node)
+
+ while chain:
+ delta = self.chunk(chain.pop())
+ text = mdiff.patches(text, [delta])
+
+ p1, p2 = self.parents(node)
+ if node != revlog.hash(text, p1, p2):
+ raise error.RevlogError(_("integrity check failed on %s:%d")
+ % (self.datafile, self.rev(node)))
+
+ self._cache = (node, self.rev(node), text)
+ return text
+
+ def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
+ raise NotImplementedError
+ def addgroup(self, revs, linkmapper, transaction):
+ raise NotImplementedError
+ def strip(self, rev, minlink):
+ raise NotImplementedError
+ def checksize(self):
+ raise NotImplementedError
+
+class bundlechangelog(bundlerevlog, changelog.changelog):
+ def __init__(self, opener, bundlefile):
+ changelog.changelog.__init__(self, opener)
+ bundlerevlog.__init__(self, opener, self.indexfile, bundlefile)
+
+class bundlemanifest(bundlerevlog, manifest.manifest):
+ def __init__(self, opener, bundlefile, linkmapper):
+ manifest.manifest.__init__(self, opener)
+ bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
+ linkmapper)
+
+class bundlefilelog(bundlerevlog, filelog.filelog):
+ def __init__(self, opener, path, bundlefile, linkmapper):
+ filelog.filelog.__init__(self, opener, path)
+ bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
+ linkmapper)
+
+class bundlerepository(localrepo.localrepository):
+ def __init__(self, ui, path, bundlename):
+ self._tempparent = None
+ try:
+ localrepo.localrepository.__init__(self, ui, path)
+ except error.RepoError:
+ self._tempparent = tempfile.mkdtemp()
+ localrepo.instance(ui, self._tempparent, 1)
+ localrepo.localrepository.__init__(self, ui, self._tempparent)
+
+ if path:
+ self._url = 'bundle:' + path + '+' + bundlename
+ else:
+ self._url = 'bundle:' + bundlename
+
+ self.tempfile = None
+ self.bundlefile = open(bundlename, "rb")
+ header = self.bundlefile.read(6)
+ if not header.startswith("HG"):
+ raise util.Abort(_("%s: not a Mercurial bundle file") % bundlename)
+ elif not header.startswith("HG10"):
+ raise util.Abort(_("%s: unknown bundle version") % bundlename)
+ elif (header == "HG10BZ") or (header == "HG10GZ"):
+ fdtemp, temp = tempfile.mkstemp(prefix="hg-bundle-",
+ suffix=".hg10un", dir=self.path)
+ self.tempfile = temp
+ fptemp = os.fdopen(fdtemp, 'wb')
+ def generator(f):
+ if header == "HG10BZ":
+ zd = bz2.BZ2Decompressor()
+ zd.decompress("BZ")
+ elif header == "HG10GZ":
+ zd = zlib.decompressobj()
+ for chunk in f:
+ yield zd.decompress(chunk)
+ gen = generator(util.filechunkiter(self.bundlefile, 4096))
+
+ try:
+ fptemp.write("HG10UN")
+ for chunk in gen:
+ fptemp.write(chunk)
+ finally:
+ fptemp.close()
+ self.bundlefile.close()
+
+ self.bundlefile = open(self.tempfile, "rb")
+ # seek right after the header
+ self.bundlefile.seek(6)
+ elif header == "HG10UN":
+ # nothing to do
+ pass
+ else:
+ raise util.Abort(_("%s: unknown bundle compression type")
+ % bundlename)
+ # dict with the mapping 'filename' -> position in the bundle
+ self.bundlefilespos = {}
+
+ @util.propertycache
+ def changelog(self):
+ c = bundlechangelog(self.sopener, self.bundlefile)
+ self.manstart = self.bundlefile.tell()
+ return c
+
+ @util.propertycache
+ def manifest(self):
+ self.bundlefile.seek(self.manstart)
+ m = bundlemanifest(self.sopener, self.bundlefile, self.changelog.rev)
+ self.filestart = self.bundlefile.tell()
+ return m
+
+ @util.propertycache
+ def manstart(self):
+ self.changelog
+ return self.manstart
+
+ @util.propertycache
+ def filestart(self):
+ self.manifest
+ return self.filestart
+
+ def url(self):
+ return self._url
+
+ def file(self, f):
+ if not self.bundlefilespos:
+ self.bundlefile.seek(self.filestart)
+ while 1:
+ chunk = changegroup.getchunk(self.bundlefile)
+ if not chunk:
+ break
+ self.bundlefilespos[chunk] = self.bundlefile.tell()
+ for c in changegroup.chunkiter(self.bundlefile):
+ pass
+
+ if f[0] == '/':
+ f = f[1:]
+ if f in self.bundlefilespos:
+ self.bundlefile.seek(self.bundlefilespos[f])
+ return bundlefilelog(self.sopener, f, self.bundlefile,
+ self.changelog.rev)
+ else:
+ return filelog.filelog(self.sopener, f)
+
+ def close(self):
+ """Close assigned bundle file immediately."""
+ self.bundlefile.close()
+
+ def __del__(self):
+ bundlefile = getattr(self, 'bundlefile', None)
+ if bundlefile and not bundlefile.closed:
+ bundlefile.close()
+ tempfile = getattr(self, 'tempfile', None)
+ if tempfile is not None:
+ os.unlink(tempfile)
+ if self._tempparent:
+ shutil.rmtree(self._tempparent, True)
+
+ def cancopy(self):
+ return False
+
+ def getcwd(self):
+ return os.getcwd() # always outside the repo
+
+def instance(ui, path, create):
+ if create:
+ raise util.Abort(_('cannot create new bundle repository'))
+ parentpath = ui.config("bundle", "mainreporoot", "")
+ if parentpath:
+ # Try to make the full path relative so we get a nice, short URL.
+ # In particular, we don't want temp dir names in test outputs.
+ cwd = os.getcwd()
+ if parentpath == cwd:
+ parentpath = ''
+ else:
+ cwd = os.path.join(cwd,'')
+ if parentpath.startswith(cwd):
+ parentpath = parentpath[len(cwd):]
+ path = util.drop_scheme('file', path)
+ if path.startswith('bundle:'):
+ path = util.drop_scheme('bundle', path)
+ s = path.split("+", 1)
+ if len(s) == 1:
+ repopath, bundlename = parentpath, s[0]
+ else:
+ repopath, bundlename = s
+ else:
+ repopath, bundlename = parentpath, path
+ return bundlerepository(ui, repopath, bundlename)
diff --git a/sys/src/cmd/hg/mercurial/byterange.py b/sys/src/cmd/hg/mercurial/byterange.py
new file mode 100644
index 000000000..f833e8270
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/byterange.py
@@ -0,0 +1,468 @@
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330,
+# Boston, MA 02111-1307 USA
+
+# This file is part of urlgrabber, a high-level cross-protocol url-grabber
+# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
+
+# $Id: byterange.py,v 1.9 2005/02/14 21:55:07 mstenner Exp $
+
+import os
+import stat
+import urllib
+import urllib2
+import email.Utils
+
+try:
+ from cStringIO import StringIO
+except ImportError, msg:
+ from StringIO import StringIO
+
+class RangeError(IOError):
+ """Error raised when an unsatisfiable range is requested."""
+ pass
+
+class HTTPRangeHandler(urllib2.BaseHandler):
+ """Handler that enables HTTP Range headers.
+
+ This was extremely simple. The Range header is a HTTP feature to
+ begin with so all this class does is tell urllib2 that the
+ "206 Partial Content" reponse from the HTTP server is what we
+ expected.
+
+ Example:
+ import urllib2
+ import byterange
+
+ range_handler = range.HTTPRangeHandler()
+ opener = urllib2.build_opener(range_handler)
+
+ # install it
+ urllib2.install_opener(opener)
+
+ # create Request and set Range header
+ req = urllib2.Request('http://www.python.org/')
+ req.header['Range'] = 'bytes=30-50'
+ f = urllib2.urlopen(req)
+ """
+
+ def http_error_206(self, req, fp, code, msg, hdrs):
+ # 206 Partial Content Response
+ r = urllib.addinfourl(fp, hdrs, req.get_full_url())
+ r.code = code
+ r.msg = msg
+ return r
+
+ def http_error_416(self, req, fp, code, msg, hdrs):
+ # HTTP's Range Not Satisfiable error
+ raise RangeError('Requested Range Not Satisfiable')
+
+class RangeableFileObject:
+ """File object wrapper to enable raw range handling.
+ This was implemented primarilary for handling range
+ specifications for file:// urls. This object effectively makes
+ a file object look like it consists only of a range of bytes in
+ the stream.
+
+ Examples:
+ # expose 10 bytes, starting at byte position 20, from
+ # /etc/aliases.
+ >>> fo = RangeableFileObject(file('/etc/passwd', 'r'), (20,30))
+ # seek seeks within the range (to position 23 in this case)
+ >>> fo.seek(3)
+ # tell tells where your at _within the range_ (position 3 in
+ # this case)
+ >>> fo.tell()
+ # read EOFs if an attempt is made to read past the last
+ # byte in the range. the following will return only 7 bytes.
+ >>> fo.read(30)
+ """
+
+ def __init__(self, fo, rangetup):
+ """Create a RangeableFileObject.
+ fo -- a file like object. only the read() method need be
+ supported but supporting an optimized seek() is
+ preferable.
+ rangetup -- a (firstbyte,lastbyte) tuple specifying the range
+ to work over.
+ The file object provided is assumed to be at byte offset 0.
+ """
+ self.fo = fo
+ (self.firstbyte, self.lastbyte) = range_tuple_normalize(rangetup)
+ self.realpos = 0
+ self._do_seek(self.firstbyte)
+
+ def __getattr__(self, name):
+ """This effectively allows us to wrap at the instance level.
+ Any attribute not found in _this_ object will be searched for
+ in self.fo. This includes methods."""
+ if hasattr(self.fo, name):
+ return getattr(self.fo, name)
+ raise AttributeError(name)
+
+ def tell(self):
+ """Return the position within the range.
+ This is different from fo.seek in that position 0 is the
+ first byte position of the range tuple. For example, if
+ this object was created with a range tuple of (500,899),
+ tell() will return 0 when at byte position 500 of the file.
+ """
+ return (self.realpos - self.firstbyte)
+
+ def seek(self, offset, whence=0):
+ """Seek within the byte range.
+ Positioning is identical to that described under tell().
+ """
+ assert whence in (0, 1, 2)
+ if whence == 0: # absolute seek
+ realoffset = self.firstbyte + offset
+ elif whence == 1: # relative seek
+ realoffset = self.realpos + offset
+ elif whence == 2: # absolute from end of file
+ # XXX: are we raising the right Error here?
+ raise IOError('seek from end of file not supported.')
+
+ # do not allow seek past lastbyte in range
+ if self.lastbyte and (realoffset >= self.lastbyte):
+ realoffset = self.lastbyte
+
+ self._do_seek(realoffset - self.realpos)
+
+ def read(self, size=-1):
+ """Read within the range.
+ This method will limit the size read based on the range.
+ """
+ size = self._calc_read_size(size)
+ rslt = self.fo.read(size)
+ self.realpos += len(rslt)
+ return rslt
+
+ def readline(self, size=-1):
+ """Read lines within the range.
+ This method will limit the size read based on the range.
+ """
+ size = self._calc_read_size(size)
+ rslt = self.fo.readline(size)
+ self.realpos += len(rslt)
+ return rslt
+
+ def _calc_read_size(self, size):
+ """Handles calculating the amount of data to read based on
+ the range.
+ """
+ if self.lastbyte:
+ if size > -1:
+ if ((self.realpos + size) >= self.lastbyte):
+ size = (self.lastbyte - self.realpos)
+ else:
+ size = (self.lastbyte - self.realpos)
+ return size
+
+ def _do_seek(self, offset):
+ """Seek based on whether wrapped object supports seek().
+ offset is relative to the current position (self.realpos).
+ """
+ assert offset >= 0
+ if not hasattr(self.fo, 'seek'):
+ self._poor_mans_seek(offset)
+ else:
+ self.fo.seek(self.realpos + offset)
+ self.realpos += offset
+
+ def _poor_mans_seek(self, offset):
+ """Seek by calling the wrapped file objects read() method.
+ This is used for file like objects that do not have native
+ seek support. The wrapped objects read() method is called
+ to manually seek to the desired position.
+ offset -- read this number of bytes from the wrapped
+ file object.
+ raise RangeError if we encounter EOF before reaching the
+ specified offset.
+ """
+ pos = 0
+ bufsize = 1024
+ while pos < offset:
+ if (pos + bufsize) > offset:
+ bufsize = offset - pos
+ buf = self.fo.read(bufsize)
+ if len(buf) != bufsize:
+ raise RangeError('Requested Range Not Satisfiable')
+ pos += bufsize
+
+class FileRangeHandler(urllib2.FileHandler):
+ """FileHandler subclass that adds Range support.
+ This class handles Range headers exactly like an HTTP
+ server would.
+ """
+ def open_local_file(self, req):
+ import mimetypes
+ import email
+ host = req.get_host()
+ file = req.get_selector()
+ localfile = urllib.url2pathname(file)
+ stats = os.stat(localfile)
+ size = stats[stat.ST_SIZE]
+ modified = email.Utils.formatdate(stats[stat.ST_MTIME])
+ mtype = mimetypes.guess_type(file)[0]
+ if host:
+ host, port = urllib.splitport(host)
+ if port or socket.gethostbyname(host) not in self.get_names():
+ raise urllib2.URLError('file not on local host')
+ fo = open(localfile,'rb')
+ brange = req.headers.get('Range', None)
+ brange = range_header_to_tuple(brange)
+ assert brange != ()
+ if brange:
+ (fb, lb) = brange
+ if lb == '':
+ lb = size
+ if fb < 0 or fb > size or lb > size:
+ raise RangeError('Requested Range Not Satisfiable')
+ size = (lb - fb)
+ fo = RangeableFileObject(fo, (fb, lb))
+ headers = email.message_from_string(
+ 'Content-Type: %s\nContent-Length: %d\nLast-Modified: %s\n' %
+ (mtype or 'text/plain', size, modified))
+ return urllib.addinfourl(fo, headers, 'file:'+file)
+
+
+# FTP Range Support
+# Unfortunately, a large amount of base FTP code had to be copied
+# from urllib and urllib2 in order to insert the FTP REST command.
+# Code modifications for range support have been commented as
+# follows:
+# -- range support modifications start/end here
+
+from urllib import splitport, splituser, splitpasswd, splitattr, \
+ unquote, addclosehook, addinfourl
+import ftplib
+import socket
+import sys
+import mimetypes
+import email
+
+class FTPRangeHandler(urllib2.FTPHandler):
+ def ftp_open(self, req):
+ host = req.get_host()
+ if not host:
+ raise IOError('ftp error', 'no host given')
+ host, port = splitport(host)
+ if port is None:
+ port = ftplib.FTP_PORT
+
+ # username/password handling
+ user, host = splituser(host)
+ if user:
+ user, passwd = splitpasswd(user)
+ else:
+ passwd = None
+ host = unquote(host)
+ user = unquote(user or '')
+ passwd = unquote(passwd or '')
+
+ try:
+ host = socket.gethostbyname(host)
+ except socket.error, msg:
+ raise urllib2.URLError(msg)
+ path, attrs = splitattr(req.get_selector())
+ dirs = path.split('/')
+ dirs = map(unquote, dirs)
+ dirs, file = dirs[:-1], dirs[-1]
+ if dirs and not dirs[0]:
+ dirs = dirs[1:]
+ try:
+ fw = self.connect_ftp(user, passwd, host, port, dirs)
+ type = file and 'I' or 'D'
+ for attr in attrs:
+ attr, value = splitattr(attr)
+ if attr.lower() == 'type' and \
+ value in ('a', 'A', 'i', 'I', 'd', 'D'):
+ type = value.upper()
+
+ # -- range support modifications start here
+ rest = None
+ range_tup = range_header_to_tuple(req.headers.get('Range', None))
+ assert range_tup != ()
+ if range_tup:
+ (fb, lb) = range_tup
+ if fb > 0:
+ rest = fb
+ # -- range support modifications end here
+
+ fp, retrlen = fw.retrfile(file, type, rest)
+
+ # -- range support modifications start here
+ if range_tup:
+ (fb, lb) = range_tup
+ if lb == '':
+ if retrlen is None or retrlen == 0:
+ raise RangeError('Requested Range Not Satisfiable due to unobtainable file length.')
+ lb = retrlen
+ retrlen = lb - fb
+ if retrlen < 0:
+ # beginning of range is larger than file
+ raise RangeError('Requested Range Not Satisfiable')
+ else:
+ retrlen = lb - fb
+ fp = RangeableFileObject(fp, (0, retrlen))
+ # -- range support modifications end here
+
+ headers = ""
+ mtype = mimetypes.guess_type(req.get_full_url())[0]
+ if mtype:
+ headers += "Content-Type: %s\n" % mtype
+ if retrlen is not None and retrlen >= 0:
+ headers += "Content-Length: %d\n" % retrlen
+ headers = email.message_from_string(headers)
+ return addinfourl(fp, headers, req.get_full_url())
+ except ftplib.all_errors, msg:
+ raise IOError('ftp error', msg), sys.exc_info()[2]
+
+ def connect_ftp(self, user, passwd, host, port, dirs):
+ fw = ftpwrapper(user, passwd, host, port, dirs)
+ return fw
+
+class ftpwrapper(urllib.ftpwrapper):
+ # range support note:
+ # this ftpwrapper code is copied directly from
+ # urllib. The only enhancement is to add the rest
+ # argument and pass it on to ftp.ntransfercmd
+ def retrfile(self, file, type, rest=None):
+ self.endtransfer()
+ if type in ('d', 'D'):
+ cmd = 'TYPE A'
+ isdir = 1
+ else:
+ cmd = 'TYPE ' + type
+ isdir = 0
+ try:
+ self.ftp.voidcmd(cmd)
+ except ftplib.all_errors:
+ self.init()
+ self.ftp.voidcmd(cmd)
+ conn = None
+ if file and not isdir:
+ # Use nlst to see if the file exists at all
+ try:
+ self.ftp.nlst(file)
+ except ftplib.error_perm, reason:
+ raise IOError('ftp error', reason), sys.exc_info()[2]
+ # Restore the transfer mode!
+ self.ftp.voidcmd(cmd)
+ # Try to retrieve as a file
+ try:
+ cmd = 'RETR ' + file
+ conn = self.ftp.ntransfercmd(cmd, rest)
+ except ftplib.error_perm, reason:
+ if str(reason).startswith('501'):
+ # workaround for REST not supported error
+ fp, retrlen = self.retrfile(file, type)
+ fp = RangeableFileObject(fp, (rest,''))
+ return (fp, retrlen)
+ elif not str(reason).startswith('550'):
+ raise IOError('ftp error', reason), sys.exc_info()[2]
+ if not conn:
+ # Set transfer mode to ASCII!
+ self.ftp.voidcmd('TYPE A')
+ # Try a directory listing
+ if file:
+ cmd = 'LIST ' + file
+ else:
+ cmd = 'LIST'
+ conn = self.ftp.ntransfercmd(cmd)
+ self.busy = 1
+ # Pass back both a suitably decorated object and a retrieval length
+ return (addclosehook(conn[0].makefile('rb'),
+ self.endtransfer), conn[1])
+
+
+####################################################################
+# Range Tuple Functions
+# XXX: These range tuple functions might go better in a class.
+
+_rangere = None
+def range_header_to_tuple(range_header):
+ """Get a (firstbyte,lastbyte) tuple from a Range header value.
+
+ Range headers have the form "bytes=<firstbyte>-<lastbyte>". This
+ function pulls the firstbyte and lastbyte values and returns
+ a (firstbyte,lastbyte) tuple. If lastbyte is not specified in
+ the header value, it is returned as an empty string in the
+ tuple.
+
+ Return None if range_header is None
+ Return () if range_header does not conform to the range spec
+ pattern.
+
+ """
+ global _rangere
+ if range_header is None:
+ return None
+ if _rangere is None:
+ import re
+ _rangere = re.compile(r'^bytes=(\d{1,})-(\d*)')
+ match = _rangere.match(range_header)
+ if match:
+ tup = range_tuple_normalize(match.group(1, 2))
+ if tup and tup[1]:
+ tup = (tup[0], tup[1]+1)
+ return tup
+ return ()
+
+def range_tuple_to_header(range_tup):
+ """Convert a range tuple to a Range header value.
+ Return a string of the form "bytes=<firstbyte>-<lastbyte>" or None
+ if no range is needed.
+ """
+ if range_tup is None:
+ return None
+ range_tup = range_tuple_normalize(range_tup)
+ if range_tup:
+ if range_tup[1]:
+ range_tup = (range_tup[0], range_tup[1] - 1)
+ return 'bytes=%s-%s' % range_tup
+
+def range_tuple_normalize(range_tup):
+ """Normalize a (first_byte,last_byte) range tuple.
+ Return a tuple whose first element is guaranteed to be an int
+ and whose second element will be '' (meaning: the last byte) or
+ an int. Finally, return None if the normalized tuple == (0,'')
+ as that is equivelant to retrieving the entire file.
+ """
+ if range_tup is None:
+ return None
+ # handle first byte
+ fb = range_tup[0]
+ if fb in (None, ''):
+ fb = 0
+ else:
+ fb = int(fb)
+ # handle last byte
+ try:
+ lb = range_tup[1]
+ except IndexError:
+ lb = ''
+ else:
+ if lb is None:
+ lb = ''
+ elif lb != '':
+ lb = int(lb)
+ # check if range is over the entire file
+ if (fb, lb) == (0, ''):
+ return None
+ # check that the range is valid
+ if lb < fb:
+ raise RangeError('Invalid byte range: %s-%s' % (fb, lb))
+ return (fb, lb)
diff --git a/sys/src/cmd/hg/mercurial/changegroup.py b/sys/src/cmd/hg/mercurial/changegroup.py
new file mode 100644
index 000000000..a4ada4eb6
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/changegroup.py
@@ -0,0 +1,140 @@
+# changegroup.py - Mercurial changegroup manipulation functions
+#
+# Copyright 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import util
+import struct, os, bz2, zlib, tempfile
+
+def getchunk(source):
+ """get a chunk from a changegroup"""
+ d = source.read(4)
+ if not d:
+ return ""
+ l = struct.unpack(">l", d)[0]
+ if l <= 4:
+ return ""
+ d = source.read(l - 4)
+ if len(d) < l - 4:
+ raise util.Abort(_("premature EOF reading chunk"
+ " (got %d bytes, expected %d)")
+ % (len(d), l - 4))
+ return d
+
+def chunkiter(source):
+ """iterate through the chunks in source"""
+ while 1:
+ c = getchunk(source)
+ if not c:
+ break
+ yield c
+
+def chunkheader(length):
+ """build a changegroup chunk header"""
+ return struct.pack(">l", length + 4)
+
+def closechunk():
+ return struct.pack(">l", 0)
+
+class nocompress(object):
+ def compress(self, x):
+ return x
+ def flush(self):
+ return ""
+
+bundletypes = {
+ "": ("", nocompress),
+ "HG10UN": ("HG10UN", nocompress),
+ "HG10BZ": ("HG10", lambda: bz2.BZ2Compressor()),
+ "HG10GZ": ("HG10GZ", lambda: zlib.compressobj()),
+}
+
+# hgweb uses this list to communicate its preferred type
+bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
+
+def writebundle(cg, filename, bundletype):
+ """Write a bundle file and return its filename.
+
+ Existing files will not be overwritten.
+ If no filename is specified, a temporary file is created.
+ bz2 compression can be turned off.
+ The bundle file will be deleted in case of errors.
+ """
+
+ fh = None
+ cleanup = None
+ try:
+ if filename:
+ fh = open(filename, "wb")
+ else:
+ fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
+ fh = os.fdopen(fd, "wb")
+ cleanup = filename
+
+ header, compressor = bundletypes[bundletype]
+ fh.write(header)
+ z = compressor()
+
+ # parse the changegroup data, otherwise we will block
+ # in case of sshrepo because we don't know the end of the stream
+
+ # an empty chunkiter is the end of the changegroup
+ # a changegroup has at least 2 chunkiters (changelog and manifest).
+ # after that, an empty chunkiter is the end of the changegroup
+ empty = False
+ count = 0
+ while not empty or count <= 2:
+ empty = True
+ count += 1
+ for chunk in chunkiter(cg):
+ empty = False
+ fh.write(z.compress(chunkheader(len(chunk))))
+ pos = 0
+ while pos < len(chunk):
+ next = pos + 2**20
+ fh.write(z.compress(chunk[pos:next]))
+ pos = next
+ fh.write(z.compress(closechunk()))
+ fh.write(z.flush())
+ cleanup = None
+ return filename
+ finally:
+ if fh is not None:
+ fh.close()
+ if cleanup is not None:
+ os.unlink(cleanup)
+
+def unbundle(header, fh):
+ if header == 'HG10UN':
+ return fh
+ elif not header.startswith('HG'):
+ # old client with uncompressed bundle
+ def generator(f):
+ yield header
+ for chunk in f:
+ yield chunk
+ elif header == 'HG10GZ':
+ def generator(f):
+ zd = zlib.decompressobj()
+ for chunk in f:
+ yield zd.decompress(chunk)
+ elif header == 'HG10BZ':
+ def generator(f):
+ zd = bz2.BZ2Decompressor()
+ zd.decompress("BZ")
+ for chunk in util.filechunkiter(f, 4096):
+ yield zd.decompress(chunk)
+ return util.chunkbuffer(generator(fh))
+
+def readbundle(fh, fname):
+ header = fh.read(6)
+ if not header.startswith('HG'):
+ raise util.Abort(_('%s: not a Mercurial bundle file') % fname)
+ if not header.startswith('HG10'):
+ raise util.Abort(_('%s: unknown bundle version') % fname)
+ elif header not in bundletypes:
+ raise util.Abort(_('%s: unknown bundle compression type') % fname)
+ return unbundle(header, fh)
diff --git a/sys/src/cmd/hg/mercurial/changelog.py b/sys/src/cmd/hg/mercurial/changelog.py
new file mode 100644
index 000000000..f99479022
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/changelog.py
@@ -0,0 +1,228 @@
+# changelog.py - changelog class for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import bin, hex, nullid
+from i18n import _
+import util, error, revlog, encoding
+
+def _string_escape(text):
+ """
+ >>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)}
+ >>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
+ >>> s
+ 'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
+ >>> res = _string_escape(s)
+ >>> s == res.decode('string_escape')
+ True
+ """
+ # subset of the string_escape codec
+ text = text.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r')
+ return text.replace('\0', '\\0')
+
+def decodeextra(text):
+ extra = {}
+ for l in text.split('\0'):
+ if l:
+ k, v = l.decode('string_escape').split(':', 1)
+ extra[k] = v
+ return extra
+
+def encodeextra(d):
+ # keys must be sorted to produce a deterministic changelog entry
+ items = [_string_escape('%s:%s' % (k, d[k])) for k in sorted(d)]
+ return "\0".join(items)
+
+class appender(object):
+ '''the changelog index must be updated last on disk, so we use this class
+ to delay writes to it'''
+ def __init__(self, fp, buf):
+ self.data = buf
+ self.fp = fp
+ self.offset = fp.tell()
+ self.size = util.fstat(fp).st_size
+
+ def end(self):
+ return self.size + len("".join(self.data))
+ def tell(self):
+ return self.offset
+ def flush(self):
+ pass
+ def close(self):
+ self.fp.close()
+
+ def seek(self, offset, whence=0):
+ '''virtual file offset spans real file and data'''
+ if whence == 0:
+ self.offset = offset
+ elif whence == 1:
+ self.offset += offset
+ elif whence == 2:
+ self.offset = self.end() + offset
+ if self.offset < self.size:
+ self.fp.seek(self.offset)
+
+ def read(self, count=-1):
+ '''only trick here is reads that span real file and data'''
+ ret = ""
+ if self.offset < self.size:
+ s = self.fp.read(count)
+ ret = s
+ self.offset += len(s)
+ if count > 0:
+ count -= len(s)
+ if count != 0:
+ doff = self.offset - self.size
+ self.data.insert(0, "".join(self.data))
+ del self.data[1:]
+ s = self.data[0][doff:doff+count]
+ self.offset += len(s)
+ ret += s
+ return ret
+
+ def write(self, s):
+ self.data.append(str(s))
+ self.offset += len(s)
+
+def delayopener(opener, target, divert, buf):
+ def o(name, mode='r'):
+ if name != target:
+ return opener(name, mode)
+ if divert:
+ return opener(name + ".a", mode.replace('a', 'w'))
+ # otherwise, divert to memory
+ return appender(opener(name, mode), buf)
+ return o
+
+class changelog(revlog.revlog):
+ def __init__(self, opener):
+ revlog.revlog.__init__(self, opener, "00changelog.i")
+ self._realopener = opener
+ self._delayed = False
+ self._divert = False
+
+ def delayupdate(self):
+ "delay visibility of index updates to other readers"
+ self._delayed = True
+ self._divert = (len(self) == 0)
+ self._delaybuf = []
+ self.opener = delayopener(self._realopener, self.indexfile,
+ self._divert, self._delaybuf)
+
+ def finalize(self, tr):
+ "finalize index updates"
+ self._delayed = False
+ self.opener = self._realopener
+ # move redirected index data back into place
+ if self._divert:
+ n = self.opener(self.indexfile + ".a").name
+ util.rename(n, n[:-2])
+ elif self._delaybuf:
+ fp = self.opener(self.indexfile, 'a')
+ fp.write("".join(self._delaybuf))
+ fp.close()
+ self._delaybuf = []
+ # split when we're done
+ self.checkinlinesize(tr)
+
+ def readpending(self, file):
+ r = revlog.revlog(self.opener, file)
+ self.index = r.index
+ self.nodemap = r.nodemap
+ self._chunkcache = r._chunkcache
+
+ def writepending(self):
+ "create a file containing the unfinalized state for pretxnchangegroup"
+ if self._delaybuf:
+ # make a temporary copy of the index
+ fp1 = self._realopener(self.indexfile)
+ fp2 = self._realopener(self.indexfile + ".a", "w")
+ fp2.write(fp1.read())
+ # add pending data
+ fp2.write("".join(self._delaybuf))
+ fp2.close()
+ # switch modes so finalize can simply rename
+ self._delaybuf = []
+ self._divert = True
+
+ if self._divert:
+ return True
+
+ return False
+
+ def checkinlinesize(self, tr, fp=None):
+ if not self._delayed:
+ revlog.revlog.checkinlinesize(self, tr, fp)
+
+ def read(self, node):
+ """
+ format used:
+ nodeid\n : manifest node in ascii
+ user\n : user, no \n or \r allowed
+ time tz extra\n : date (time is int or float, timezone is int)
+ : extra is metadatas, encoded and separated by '\0'
+ : older versions ignore it
+ files\n\n : files modified by the cset, no \n or \r allowed
+ (.*) : comment (free text, ideally utf-8)
+
+ changelog v0 doesn't use extra
+ """
+ text = self.revision(node)
+ if not text:
+ return (nullid, "", (0, 0), [], "", {'branch': 'default'})
+ last = text.index("\n\n")
+ desc = encoding.tolocal(text[last + 2:])
+ l = text[:last].split('\n')
+ manifest = bin(l[0])
+ user = encoding.tolocal(l[1])
+
+ extra_data = l[2].split(' ', 2)
+ if len(extra_data) != 3:
+ time = float(extra_data.pop(0))
+ try:
+ # various tools did silly things with the time zone field.
+ timezone = int(extra_data[0])
+ except:
+ timezone = 0
+ extra = {}
+ else:
+ time, timezone, extra = extra_data
+ time, timezone = float(time), int(timezone)
+ extra = decodeextra(extra)
+ if not extra.get('branch'):
+ extra['branch'] = 'default'
+ files = l[3:]
+ return (manifest, user, (time, timezone), files, desc, extra)
+
+ def add(self, manifest, files, desc, transaction, p1, p2,
+ user, date=None, extra={}):
+ user = user.strip()
+ # An empty username or a username with a "\n" will make the
+ # revision text contain two "\n\n" sequences -> corrupt
+ # repository since read cannot unpack the revision.
+ if not user:
+ raise error.RevlogError(_("empty username"))
+ if "\n" in user:
+ raise error.RevlogError(_("username %s contains a newline")
+ % repr(user))
+
+ # strip trailing whitespace and leading and trailing empty lines
+ desc = '\n'.join([l.rstrip() for l in desc.splitlines()]).strip('\n')
+
+ user, desc = encoding.fromlocal(user), encoding.fromlocal(desc)
+
+ if date:
+ parseddate = "%d %d" % util.parsedate(date)
+ else:
+ parseddate = "%d %d" % util.makedate()
+ if extra and extra.get("branch") in ("default", ""):
+ del extra["branch"]
+ if extra:
+ extra = encodeextra(extra)
+ parseddate = "%s %s" % (parseddate, extra)
+ l = [hex(manifest), user, parseddate] + sorted(files) + ["", desc]
+ text = "\n".join(l)
+ return self.addrevision(text, transaction, len(self), p1, p2)
diff --git a/sys/src/cmd/hg/mercurial/cmdutil.py b/sys/src/cmd/hg/mercurial/cmdutil.py
new file mode 100644
index 000000000..1c58d6bdc
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/cmdutil.py
@@ -0,0 +1,1254 @@
+# cmdutil.py - help for command processing in mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import hex, nullid, nullrev, short
+from i18n import _
+import os, sys, errno, re, glob
+import mdiff, bdiff, util, templater, patch, error, encoding
+import match as _match
+
+revrangesep = ':'
+
+def findpossible(cmd, table, strict=False):
+ """
+ Return cmd -> (aliases, command table entry)
+ for each matching command.
+ Return debug commands (or their aliases) only if no normal command matches.
+ """
+ choice = {}
+ debugchoice = {}
+ for e in table.keys():
+ aliases = e.lstrip("^").split("|")
+ found = None
+ if cmd in aliases:
+ found = cmd
+ elif not strict:
+ for a in aliases:
+ if a.startswith(cmd):
+ found = a
+ break
+ if found is not None:
+ if aliases[0].startswith("debug") or found.startswith("debug"):
+ debugchoice[found] = (aliases, table[e])
+ else:
+ choice[found] = (aliases, table[e])
+
+ if not choice and debugchoice:
+ choice = debugchoice
+
+ return choice
+
+def findcmd(cmd, table, strict=True):
+ """Return (aliases, command table entry) for command string."""
+ choice = findpossible(cmd, table, strict)
+
+ if cmd in choice:
+ return choice[cmd]
+
+ if len(choice) > 1:
+ clist = choice.keys()
+ clist.sort()
+ raise error.AmbiguousCommand(cmd, clist)
+
+ if choice:
+ return choice.values()[0]
+
+ raise error.UnknownCommand(cmd)
+
+def bail_if_changed(repo):
+ if repo.dirstate.parents()[1] != nullid:
+ raise util.Abort(_('outstanding uncommitted merge'))
+ modified, added, removed, deleted = repo.status()[:4]
+ if modified or added or removed or deleted:
+ raise util.Abort(_("outstanding uncommitted changes"))
+
+def logmessage(opts):
+ """ get the log message according to -m and -l option """
+ message = opts.get('message')
+ logfile = opts.get('logfile')
+
+ if message and logfile:
+ raise util.Abort(_('options --message and --logfile are mutually '
+ 'exclusive'))
+ if not message and logfile:
+ try:
+ if logfile == '-':
+ message = sys.stdin.read()
+ else:
+ message = open(logfile).read()
+ except IOError, inst:
+ raise util.Abort(_("can't read commit message '%s': %s") %
+ (logfile, inst.strerror))
+ return message
+
+def loglimit(opts):
+ """get the log limit according to option -l/--limit"""
+ limit = opts.get('limit')
+ if limit:
+ try:
+ limit = int(limit)
+ except ValueError:
+ raise util.Abort(_('limit must be a positive integer'))
+ if limit <= 0: raise util.Abort(_('limit must be positive'))
+ else:
+ limit = sys.maxint
+ return limit
+
+def remoteui(src, opts):
+ 'build a remote ui from ui or repo and opts'
+ if hasattr(src, 'baseui'): # looks like a repository
+ dst = src.baseui.copy() # drop repo-specific config
+ src = src.ui # copy target options from repo
+ else: # assume it's a global ui object
+ dst = src.copy() # keep all global options
+
+ # copy ssh-specific options
+ for o in 'ssh', 'remotecmd':
+ v = opts.get(o) or src.config('ui', o)
+ if v:
+ dst.setconfig("ui", o, v)
+ # copy bundle-specific options
+ r = src.config('bundle', 'mainreporoot')
+ if r:
+ dst.setconfig('bundle', 'mainreporoot', r)
+
+ return dst
+
+def revpair(repo, revs):
+ '''return pair of nodes, given list of revisions. second item can
+ be None, meaning use working dir.'''
+
+ def revfix(repo, val, defval):
+ if not val and val != 0 and defval is not None:
+ val = defval
+ return repo.lookup(val)
+
+ if not revs:
+ return repo.dirstate.parents()[0], None
+ end = None
+ if len(revs) == 1:
+ if revrangesep in revs[0]:
+ start, end = revs[0].split(revrangesep, 1)
+ start = revfix(repo, start, 0)
+ end = revfix(repo, end, len(repo) - 1)
+ else:
+ start = revfix(repo, revs[0], None)
+ elif len(revs) == 2:
+ if revrangesep in revs[0] or revrangesep in revs[1]:
+ raise util.Abort(_('too many revisions specified'))
+ start = revfix(repo, revs[0], None)
+ end = revfix(repo, revs[1], None)
+ else:
+ raise util.Abort(_('too many revisions specified'))
+ return start, end
+
+def revrange(repo, revs):
+ """Yield revision as strings from a list of revision specifications."""
+
+ def revfix(repo, val, defval):
+ if not val and val != 0 and defval is not None:
+ return defval
+ return repo.changelog.rev(repo.lookup(val))
+
+ seen, l = set(), []
+ for spec in revs:
+ if revrangesep in spec:
+ start, end = spec.split(revrangesep, 1)
+ start = revfix(repo, start, 0)
+ end = revfix(repo, end, len(repo) - 1)
+ step = start > end and -1 or 1
+ for rev in xrange(start, end+step, step):
+ if rev in seen:
+ continue
+ seen.add(rev)
+ l.append(rev)
+ else:
+ rev = revfix(repo, spec, None)
+ if rev in seen:
+ continue
+ seen.add(rev)
+ l.append(rev)
+
+ return l
+
+def make_filename(repo, pat, node,
+ total=None, seqno=None, revwidth=None, pathname=None):
+ node_expander = {
+ 'H': lambda: hex(node),
+ 'R': lambda: str(repo.changelog.rev(node)),
+ 'h': lambda: short(node),
+ }
+ expander = {
+ '%': lambda: '%',
+ 'b': lambda: os.path.basename(repo.root),
+ }
+
+ try:
+ if node:
+ expander.update(node_expander)
+ if node:
+ expander['r'] = (lambda:
+ str(repo.changelog.rev(node)).zfill(revwidth or 0))
+ if total is not None:
+ expander['N'] = lambda: str(total)
+ if seqno is not None:
+ expander['n'] = lambda: str(seqno)
+ if total is not None and seqno is not None:
+ expander['n'] = lambda: str(seqno).zfill(len(str(total)))
+ if pathname is not None:
+ expander['s'] = lambda: os.path.basename(pathname)
+ expander['d'] = lambda: os.path.dirname(pathname) or '.'
+ expander['p'] = lambda: pathname
+
+ newname = []
+ patlen = len(pat)
+ i = 0
+ while i < patlen:
+ c = pat[i]
+ if c == '%':
+ i += 1
+ c = pat[i]
+ c = expander[c]()
+ newname.append(c)
+ i += 1
+ return ''.join(newname)
+ except KeyError, inst:
+ raise util.Abort(_("invalid format spec '%%%s' in output filename") %
+ inst.args[0])
+
+def make_file(repo, pat, node=None,
+ total=None, seqno=None, revwidth=None, mode='wb', pathname=None):
+
+ writable = 'w' in mode or 'a' in mode
+
+ if not pat or pat == '-':
+ return writable and sys.stdout or sys.stdin
+ if hasattr(pat, 'write') and writable:
+ return pat
+ if hasattr(pat, 'read') and 'r' in mode:
+ return pat
+ return open(make_filename(repo, pat, node, total, seqno, revwidth,
+ pathname),
+ mode)
+
+def expandpats(pats):
+ if not util.expandglobs:
+ return list(pats)
+ ret = []
+ for p in pats:
+ kind, name = _match._patsplit(p, None)
+ if kind is None:
+ try:
+ globbed = glob.glob(name)
+ except re.error:
+ globbed = [name]
+ if globbed:
+ ret.extend(globbed)
+ continue
+ ret.append(p)
+ return ret
+
+def match(repo, pats=[], opts={}, globbed=False, default='relpath'):
+ if not globbed and default == 'relpath':
+ pats = expandpats(pats or [])
+ m = _match.match(repo.root, repo.getcwd(), pats,
+ opts.get('include'), opts.get('exclude'), default)
+ def badfn(f, msg):
+ repo.ui.warn("%s: %s\n" % (m.rel(f), msg))
+ m.bad = badfn
+ return m
+
+def matchall(repo):
+ return _match.always(repo.root, repo.getcwd())
+
+def matchfiles(repo, files):
+ return _match.exact(repo.root, repo.getcwd(), files)
+
+def findrenames(repo, added, removed, threshold):
+ '''find renamed files -- yields (before, after, score) tuples'''
+ ctx = repo['.']
+ for a in added:
+ aa = repo.wread(a)
+ bestname, bestscore = None, threshold
+ for r in removed:
+ if r not in ctx:
+ continue
+ rr = ctx.filectx(r).data()
+
+ # bdiff.blocks() returns blocks of matching lines
+ # count the number of bytes in each
+ equal = 0
+ alines = mdiff.splitnewlines(aa)
+ matches = bdiff.blocks(aa, rr)
+ for x1,x2,y1,y2 in matches:
+ for line in alines[x1:x2]:
+ equal += len(line)
+
+ lengths = len(aa) + len(rr)
+ if lengths:
+ myscore = equal*2.0 / lengths
+ if myscore >= bestscore:
+ bestname, bestscore = r, myscore
+ if bestname:
+ yield bestname, a, bestscore
+
+def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
+ if dry_run is None:
+ dry_run = opts.get('dry_run')
+ if similarity is None:
+ similarity = float(opts.get('similarity') or 0)
+ # we'd use status here, except handling of symlinks and ignore is tricky
+ added, unknown, deleted, removed = [], [], [], []
+ audit_path = util.path_auditor(repo.root)
+ m = match(repo, pats, opts)
+ for abs in repo.walk(m):
+ target = repo.wjoin(abs)
+ good = True
+ try:
+ audit_path(abs)
+ except:
+ good = False
+ rel = m.rel(abs)
+ exact = m.exact(abs)
+ if good and abs not in repo.dirstate:
+ unknown.append(abs)
+ if repo.ui.verbose or not exact:
+ repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
+ elif repo.dirstate[abs] != 'r' and (not good or not util.lexists(target)
+ or (os.path.isdir(target) and not os.path.islink(target))):
+ deleted.append(abs)
+ if repo.ui.verbose or not exact:
+ repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
+ # for finding renames
+ elif repo.dirstate[abs] == 'r':
+ removed.append(abs)
+ elif repo.dirstate[abs] == 'a':
+ added.append(abs)
+ if not dry_run:
+ repo.remove(deleted)
+ repo.add(unknown)
+ if similarity > 0:
+ for old, new, score in findrenames(repo, added + unknown,
+ removed + deleted, similarity):
+ if repo.ui.verbose or not m.exact(old) or not m.exact(new):
+ repo.ui.status(_('recording removal of %s as rename to %s '
+ '(%d%% similar)\n') %
+ (m.rel(old), m.rel(new), score * 100))
+ if not dry_run:
+ repo.copy(old, new)
+
+def copy(ui, repo, pats, opts, rename=False):
+ # called with the repo lock held
+ #
+ # hgsep => pathname that uses "/" to separate directories
+ # ossep => pathname that uses os.sep to separate directories
+ cwd = repo.getcwd()
+ targets = {}
+ after = opts.get("after")
+ dryrun = opts.get("dry_run")
+
+ def walkpat(pat):
+ srcs = []
+ m = match(repo, [pat], opts, globbed=True)
+ for abs in repo.walk(m):
+ state = repo.dirstate[abs]
+ rel = m.rel(abs)
+ exact = m.exact(abs)
+ if state in '?r':
+ if exact and state == '?':
+ ui.warn(_('%s: not copying - file is not managed\n') % rel)
+ if exact and state == 'r':
+ ui.warn(_('%s: not copying - file has been marked for'
+ ' remove\n') % rel)
+ continue
+ # abs: hgsep
+ # rel: ossep
+ srcs.append((abs, rel, exact))
+ return srcs
+
+ # abssrc: hgsep
+ # relsrc: ossep
+ # otarget: ossep
+ def copyfile(abssrc, relsrc, otarget, exact):
+ abstarget = util.canonpath(repo.root, cwd, otarget)
+ reltarget = repo.pathto(abstarget, cwd)
+ target = repo.wjoin(abstarget)
+ src = repo.wjoin(abssrc)
+ state = repo.dirstate[abstarget]
+
+ # check for collisions
+ prevsrc = targets.get(abstarget)
+ if prevsrc is not None:
+ ui.warn(_('%s: not overwriting - %s collides with %s\n') %
+ (reltarget, repo.pathto(abssrc, cwd),
+ repo.pathto(prevsrc, cwd)))
+ return
+
+ # check for overwrites
+ exists = os.path.exists(target)
+ if not after and exists or after and state in 'mn':
+ if not opts['force']:
+ ui.warn(_('%s: not overwriting - file exists\n') %
+ reltarget)
+ return
+
+ if after:
+ if not exists:
+ return
+ elif not dryrun:
+ try:
+ if exists:
+ os.unlink(target)
+ targetdir = os.path.dirname(target) or '.'
+ if not os.path.isdir(targetdir):
+ os.makedirs(targetdir)
+ util.copyfile(src, target)
+ except IOError, inst:
+ if inst.errno == errno.ENOENT:
+ ui.warn(_('%s: deleted in working copy\n') % relsrc)
+ else:
+ ui.warn(_('%s: cannot copy - %s\n') %
+ (relsrc, inst.strerror))
+ return True # report a failure
+
+ if ui.verbose or not exact:
+ if rename:
+ ui.status(_('moving %s to %s\n') % (relsrc, reltarget))
+ else:
+ ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
+
+ targets[abstarget] = abssrc
+
+ # fix up dirstate
+ origsrc = repo.dirstate.copied(abssrc) or abssrc
+ if abstarget == origsrc: # copying back a copy?
+ if state not in 'mn' and not dryrun:
+ repo.dirstate.normallookup(abstarget)
+ else:
+ if repo.dirstate[origsrc] == 'a' and origsrc == abssrc:
+ if not ui.quiet:
+ ui.warn(_("%s has not been committed yet, so no copy "
+ "data will be stored for %s.\n")
+ % (repo.pathto(origsrc, cwd), reltarget))
+ if repo.dirstate[abstarget] in '?r' and not dryrun:
+ repo.add([abstarget])
+ elif not dryrun:
+ repo.copy(origsrc, abstarget)
+
+ if rename and not dryrun:
+ repo.remove([abssrc], not after)
+
+ # pat: ossep
+ # dest ossep
+ # srcs: list of (hgsep, hgsep, ossep, bool)
+ # return: function that takes hgsep and returns ossep
+ def targetpathfn(pat, dest, srcs):
+ if os.path.isdir(pat):
+ abspfx = util.canonpath(repo.root, cwd, pat)
+ abspfx = util.localpath(abspfx)
+ if destdirexists:
+ striplen = len(os.path.split(abspfx)[0])
+ else:
+ striplen = len(abspfx)
+ if striplen:
+ striplen += len(os.sep)
+ res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
+ elif destdirexists:
+ res = lambda p: os.path.join(dest,
+ os.path.basename(util.localpath(p)))
+ else:
+ res = lambda p: dest
+ return res
+
+ # pat: ossep
+ # dest ossep
+ # srcs: list of (hgsep, hgsep, ossep, bool)
+ # return: function that takes hgsep and returns ossep
+ def targetpathafterfn(pat, dest, srcs):
+ if _match.patkind(pat):
+ # a mercurial pattern
+ res = lambda p: os.path.join(dest,
+ os.path.basename(util.localpath(p)))
+ else:
+ abspfx = util.canonpath(repo.root, cwd, pat)
+ if len(abspfx) < len(srcs[0][0]):
+ # A directory. Either the target path contains the last
+ # component of the source path or it does not.
+ def evalpath(striplen):
+ score = 0
+ for s in srcs:
+ t = os.path.join(dest, util.localpath(s[0])[striplen:])
+ if os.path.exists(t):
+ score += 1
+ return score
+
+ abspfx = util.localpath(abspfx)
+ striplen = len(abspfx)
+ if striplen:
+ striplen += len(os.sep)
+ if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
+ score = evalpath(striplen)
+ striplen1 = len(os.path.split(abspfx)[0])
+ if striplen1:
+ striplen1 += len(os.sep)
+ if evalpath(striplen1) > score:
+ striplen = striplen1
+ res = lambda p: os.path.join(dest,
+ util.localpath(p)[striplen:])
+ else:
+ # a file
+ if destdirexists:
+ res = lambda p: os.path.join(dest,
+ os.path.basename(util.localpath(p)))
+ else:
+ res = lambda p: dest
+ return res
+
+
+ pats = expandpats(pats)
+ if not pats:
+ raise util.Abort(_('no source or destination specified'))
+ if len(pats) == 1:
+ raise util.Abort(_('no destination specified'))
+ dest = pats.pop()
+ destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
+ if not destdirexists:
+ if len(pats) > 1 or _match.patkind(pats[0]):
+ raise util.Abort(_('with multiple sources, destination must be an '
+ 'existing directory'))
+ if util.endswithsep(dest):
+ raise util.Abort(_('destination %s is not a directory') % dest)
+
+ tfn = targetpathfn
+ if after:
+ tfn = targetpathafterfn
+ copylist = []
+ for pat in pats:
+ srcs = walkpat(pat)
+ if not srcs:
+ continue
+ copylist.append((tfn(pat, dest, srcs), srcs))
+ if not copylist:
+ raise util.Abort(_('no files to copy'))
+
+ errors = 0
+ for targetpath, srcs in copylist:
+ for abssrc, relsrc, exact in srcs:
+ if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
+ errors += 1
+
+ if errors:
+ ui.warn(_('(consider using --after)\n'))
+
+ return errors
+
+def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None):
+ '''Run a command as a service.'''
+
+ if opts['daemon'] and not opts['daemon_pipefds']:
+ rfd, wfd = os.pipe()
+ args = sys.argv[:]
+ args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
+ # Don't pass --cwd to the child process, because we've already
+ # changed directory.
+ for i in xrange(1,len(args)):
+ if args[i].startswith('--cwd='):
+ del args[i]
+ break
+ elif args[i].startswith('--cwd'):
+ del args[i:i+2]
+ break
+ pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
+ args[0], args)
+ os.close(wfd)
+ os.read(rfd, 1)
+ if parentfn:
+ return parentfn(pid)
+ else:
+ os._exit(0)
+
+ if initfn:
+ initfn()
+
+ if opts['pid_file']:
+ fp = open(opts['pid_file'], 'w')
+ fp.write(str(os.getpid()) + '\n')
+ fp.close()
+
+ if opts['daemon_pipefds']:
+ rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
+ os.close(rfd)
+ try:
+ os.setsid()
+ except AttributeError:
+ pass
+ os.write(wfd, 'y')
+ os.close(wfd)
+ sys.stdout.flush()
+ sys.stderr.flush()
+
+ nullfd = os.open(util.nulldev, os.O_RDWR)
+ logfilefd = nullfd
+ if logfile:
+ logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
+ os.dup2(nullfd, 0)
+ os.dup2(logfilefd, 1)
+ os.dup2(logfilefd, 2)
+ if nullfd not in (0, 1, 2):
+ os.close(nullfd)
+ if logfile and logfilefd not in (0, 1, 2):
+ os.close(logfilefd)
+
+ if runfn:
+ return runfn()
+
+class changeset_printer(object):
+ '''show changeset information when templating not requested.'''
+
+ def __init__(self, ui, repo, patch, diffopts, buffered):
+ self.ui = ui
+ self.repo = repo
+ self.buffered = buffered
+ self.patch = patch
+ self.diffopts = diffopts
+ self.header = {}
+ self.hunk = {}
+ self.lastheader = None
+
+ def flush(self, rev):
+ if rev in self.header:
+ h = self.header[rev]
+ if h != self.lastheader:
+ self.lastheader = h
+ self.ui.write(h)
+ del self.header[rev]
+ if rev in self.hunk:
+ self.ui.write(self.hunk[rev])
+ del self.hunk[rev]
+ return 1
+ return 0
+
+ def show(self, ctx, copies=(), **props):
+ if self.buffered:
+ self.ui.pushbuffer()
+ self._show(ctx, copies, props)
+ self.hunk[ctx.rev()] = self.ui.popbuffer()
+ else:
+ self._show(ctx, copies, props)
+
+ def _show(self, ctx, copies, props):
+ '''show a single changeset or file revision'''
+ changenode = ctx.node()
+ rev = ctx.rev()
+
+ if self.ui.quiet:
+ self.ui.write("%d:%s\n" % (rev, short(changenode)))
+ return
+
+ log = self.repo.changelog
+ changes = log.read(changenode)
+ date = util.datestr(changes[2])
+ extra = changes[5]
+ branch = extra.get("branch")
+
+ hexfunc = self.ui.debugflag and hex or short
+
+ parents = [(p, hexfunc(log.node(p)))
+ for p in self._meaningful_parentrevs(log, rev)]
+
+ self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode)))
+
+ # don't show the default branch name
+ if branch != 'default':
+ branch = encoding.tolocal(branch)
+ self.ui.write(_("branch: %s\n") % branch)
+ for tag in self.repo.nodetags(changenode):
+ self.ui.write(_("tag: %s\n") % tag)
+ for parent in parents:
+ self.ui.write(_("parent: %d:%s\n") % parent)
+
+ if self.ui.debugflag:
+ self.ui.write(_("manifest: %d:%s\n") %
+ (self.repo.manifest.rev(changes[0]), hex(changes[0])))
+ self.ui.write(_("user: %s\n") % changes[1])
+ self.ui.write(_("date: %s\n") % date)
+
+ if self.ui.debugflag:
+ files = self.repo.status(log.parents(changenode)[0], changenode)[:3]
+ for key, value in zip([_("files:"), _("files+:"), _("files-:")],
+ files):
+ if value:
+ self.ui.write("%-12s %s\n" % (key, " ".join(value)))
+ elif changes[3] and self.ui.verbose:
+ self.ui.write(_("files: %s\n") % " ".join(changes[3]))
+ if copies and self.ui.verbose:
+ copies = ['%s (%s)' % c for c in copies]
+ self.ui.write(_("copies: %s\n") % ' '.join(copies))
+
+ if extra and self.ui.debugflag:
+ for key, value in sorted(extra.items()):
+ self.ui.write(_("extra: %s=%s\n")
+ % (key, value.encode('string_escape')))
+
+ description = changes[4].strip()
+ if description:
+ if self.ui.verbose:
+ self.ui.write(_("description:\n"))
+ self.ui.write(description)
+ self.ui.write("\n\n")
+ else:
+ self.ui.write(_("summary: %s\n") %
+ description.splitlines()[0])
+ self.ui.write("\n")
+
+ self.showpatch(changenode)
+
+ def showpatch(self, node):
+ if self.patch:
+ prev = self.repo.changelog.parents(node)[0]
+ chunks = patch.diff(self.repo, prev, node, match=self.patch,
+ opts=patch.diffopts(self.ui, self.diffopts))
+ for chunk in chunks:
+ self.ui.write(chunk)
+ self.ui.write("\n")
+
+ def _meaningful_parentrevs(self, log, rev):
+ """Return list of meaningful (or all if debug) parentrevs for rev.
+
+ For merges (two non-nullrev revisions) both parents are meaningful.
+ Otherwise the first parent revision is considered meaningful if it
+ is not the preceding revision.
+ """
+ parents = log.parentrevs(rev)
+ if not self.ui.debugflag and parents[1] == nullrev:
+ if parents[0] >= rev - 1:
+ parents = []
+ else:
+ parents = [parents[0]]
+ return parents
+
+
+class changeset_templater(changeset_printer):
+ '''format changeset information.'''
+
+ def __init__(self, ui, repo, patch, diffopts, mapfile, buffered):
+ changeset_printer.__init__(self, ui, repo, patch, diffopts, buffered)
+ formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
+ self.t = templater.templater(mapfile, {'formatnode': formatnode},
+ cache={
+ 'parent': '{rev}:{node|formatnode} ',
+ 'manifest': '{rev}:{node|formatnode}',
+ 'filecopy': '{name} ({source})'})
+
+ def use_template(self, t):
+ '''set template string to use'''
+ self.t.cache['changeset'] = t
+
+ def _meaningful_parentrevs(self, ctx):
+ """Return list of meaningful (or all if debug) parentrevs for rev.
+ """
+ parents = ctx.parents()
+ if len(parents) > 1:
+ return parents
+ if self.ui.debugflag:
+ return [parents[0], self.repo['null']]
+ if parents[0].rev() >= ctx.rev() - 1:
+ return []
+ return parents
+
+ def _show(self, ctx, copies, props):
+ '''show a single changeset or file revision'''
+
+ def showlist(name, values, plural=None, **args):
+ '''expand set of values.
+ name is name of key in template map.
+ values is list of strings or dicts.
+ plural is plural of name, if not simply name + 's'.
+
+ expansion works like this, given name 'foo'.
+
+ if values is empty, expand 'no_foos'.
+
+ if 'foo' not in template map, return values as a string,
+ joined by space.
+
+ expand 'start_foos'.
+
+ for each value, expand 'foo'. if 'last_foo' in template
+ map, expand it instead of 'foo' for last key.
+
+ expand 'end_foos'.
+ '''
+ if plural: names = plural
+ else: names = name + 's'
+ if not values:
+ noname = 'no_' + names
+ if noname in self.t:
+ yield self.t(noname, **args)
+ return
+ if name not in self.t:
+ if isinstance(values[0], str):
+ yield ' '.join(values)
+ else:
+ for v in values:
+ yield dict(v, **args)
+ return
+ startname = 'start_' + names
+ if startname in self.t:
+ yield self.t(startname, **args)
+ vargs = args.copy()
+ def one(v, tag=name):
+ try:
+ vargs.update(v)
+ except (AttributeError, ValueError):
+ try:
+ for a, b in v:
+ vargs[a] = b
+ except ValueError:
+ vargs[name] = v
+ return self.t(tag, **vargs)
+ lastname = 'last_' + name
+ if lastname in self.t:
+ last = values.pop()
+ else:
+ last = None
+ for v in values:
+ yield one(v)
+ if last is not None:
+ yield one(last, tag=lastname)
+ endname = 'end_' + names
+ if endname in self.t:
+ yield self.t(endname, **args)
+
+ def showbranches(**args):
+ branch = ctx.branch()
+ if branch != 'default':
+ branch = encoding.tolocal(branch)
+ return showlist('branch', [branch], plural='branches', **args)
+
+ def showparents(**args):
+ parents = [[('rev', p.rev()), ('node', p.hex())]
+ for p in self._meaningful_parentrevs(ctx)]
+ return showlist('parent', parents, **args)
+
+ def showtags(**args):
+ return showlist('tag', ctx.tags(), **args)
+
+ def showextras(**args):
+ for key, value in sorted(ctx.extra().items()):
+ args = args.copy()
+ args.update(dict(key=key, value=value))
+ yield self.t('extra', **args)
+
+ def showcopies(**args):
+ c = [{'name': x[0], 'source': x[1]} for x in copies]
+ return showlist('file_copy', c, plural='file_copies', **args)
+
+ files = []
+ def getfiles():
+ if not files:
+ files[:] = self.repo.status(ctx.parents()[0].node(),
+ ctx.node())[:3]
+ return files
+ def showfiles(**args):
+ return showlist('file', ctx.files(), **args)
+ def showmods(**args):
+ return showlist('file_mod', getfiles()[0], **args)
+ def showadds(**args):
+ return showlist('file_add', getfiles()[1], **args)
+ def showdels(**args):
+ return showlist('file_del', getfiles()[2], **args)
+ def showmanifest(**args):
+ args = args.copy()
+ args.update(dict(rev=self.repo.manifest.rev(ctx.changeset()[0]),
+ node=hex(ctx.changeset()[0])))
+ return self.t('manifest', **args)
+
+ def showdiffstat(**args):
+ diff = patch.diff(self.repo, ctx.parents()[0].node(), ctx.node())
+ files, adds, removes = 0, 0, 0
+ for i in patch.diffstatdata(util.iterlines(diff)):
+ files += 1
+ adds += i[1]
+ removes += i[2]
+ return '%s: +%s/-%s' % (files, adds, removes)
+
+ defprops = {
+ 'author': ctx.user(),
+ 'branches': showbranches,
+ 'date': ctx.date(),
+ 'desc': ctx.description().strip(),
+ 'file_adds': showadds,
+ 'file_dels': showdels,
+ 'file_mods': showmods,
+ 'files': showfiles,
+ 'file_copies': showcopies,
+ 'manifest': showmanifest,
+ 'node': ctx.hex(),
+ 'parents': showparents,
+ 'rev': ctx.rev(),
+ 'tags': showtags,
+ 'extras': showextras,
+ 'diffstat': showdiffstat,
+ }
+ props = props.copy()
+ props.update(defprops)
+
+ # find correct templates for current mode
+
+ tmplmodes = [
+ (True, None),
+ (self.ui.verbose, 'verbose'),
+ (self.ui.quiet, 'quiet'),
+ (self.ui.debugflag, 'debug'),
+ ]
+
+ types = {'header': '', 'changeset': 'changeset'}
+ for mode, postfix in tmplmodes:
+ for type in types:
+ cur = postfix and ('%s_%s' % (type, postfix)) or type
+ if mode and cur in self.t:
+ types[type] = cur
+
+ try:
+
+ # write header
+ if types['header']:
+ h = templater.stringify(self.t(types['header'], **props))
+ if self.buffered:
+ self.header[ctx.rev()] = h
+ else:
+ self.ui.write(h)
+
+ # write changeset metadata, then patch if requested
+ key = types['changeset']
+ self.ui.write(templater.stringify(self.t(key, **props)))
+ self.showpatch(ctx.node())
+
+ except KeyError, inst:
+ msg = _("%s: no key named '%s'")
+ raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
+ except SyntaxError, inst:
+ raise util.Abort(_('%s: %s') % (self.t.mapfile, inst.args[0]))
+
+def show_changeset(ui, repo, opts, buffered=False, matchfn=False):
+ """show one changeset using template or regular display.
+
+ Display format will be the first non-empty hit of:
+ 1. option 'template'
+ 2. option 'style'
+ 3. [ui] setting 'logtemplate'
+ 4. [ui] setting 'style'
+ If all of these values are either the unset or the empty string,
+ regular display via changeset_printer() is done.
+ """
+ # options
+ patch = False
+ if opts.get('patch'):
+ patch = matchfn or matchall(repo)
+
+ tmpl = opts.get('template')
+ style = None
+ if tmpl:
+ tmpl = templater.parsestring(tmpl, quoted=False)
+ else:
+ style = opts.get('style')
+
+ # ui settings
+ if not (tmpl or style):
+ tmpl = ui.config('ui', 'logtemplate')
+ if tmpl:
+ tmpl = templater.parsestring(tmpl)
+ else:
+ style = ui.config('ui', 'style')
+
+ if not (tmpl or style):
+ return changeset_printer(ui, repo, patch, opts, buffered)
+
+ mapfile = None
+ if style and not tmpl:
+ mapfile = style
+ if not os.path.split(mapfile)[0]:
+ mapname = (templater.templatepath('map-cmdline.' + mapfile)
+ or templater.templatepath(mapfile))
+ if mapname: mapfile = mapname
+
+ try:
+ t = changeset_templater(ui, repo, patch, opts, mapfile, buffered)
+ except SyntaxError, inst:
+ raise util.Abort(inst.args[0])
+ if tmpl: t.use_template(tmpl)
+ return t
+
+def finddate(ui, repo, date):
+ """Find the tipmost changeset that matches the given date spec"""
+ df = util.matchdate(date)
+ get = util.cachefunc(lambda r: repo[r].changeset())
+ changeiter, matchfn = walkchangerevs(ui, repo, [], get, {'rev':None})
+ results = {}
+ for st, rev, fns in changeiter:
+ if st == 'add':
+ d = get(rev)[2]
+ if df(d[0]):
+ results[rev] = d
+ elif st == 'iter':
+ if rev in results:
+ ui.status(_("Found revision %s from %s\n") %
+ (rev, util.datestr(results[rev])))
+ return str(rev)
+
+ raise util.Abort(_("revision matching date not found"))
+
+def walkchangerevs(ui, repo, pats, change, opts):
+ '''Iterate over files and the revs in which they changed.
+
+ Callers most commonly need to iterate backwards over the history
+ in which they are interested. Doing so has awful (quadratic-looking)
+ performance, so we use iterators in a "windowed" way.
+
+ We walk a window of revisions in the desired order. Within the
+ window, we first walk forwards to gather data, then in the desired
+ order (usually backwards) to display it.
+
+ This function returns an (iterator, matchfn) tuple. The iterator
+ yields 3-tuples. They will be of one of the following forms:
+
+ "window", incrementing, lastrev: stepping through a window,
+ positive if walking forwards through revs, last rev in the
+ sequence iterated over - use to reset state for the current window
+
+ "add", rev, fns: out-of-order traversal of the given filenames
+ fns, which changed during revision rev - use to gather data for
+ possible display
+
+ "iter", rev, None: in-order traversal of the revs earlier iterated
+ over with "add" - use to display data'''
+
+ def increasing_windows(start, end, windowsize=8, sizelimit=512):
+ if start < end:
+ while start < end:
+ yield start, min(windowsize, end-start)
+ start += windowsize
+ if windowsize < sizelimit:
+ windowsize *= 2
+ else:
+ while start > end:
+ yield start, min(windowsize, start-end-1)
+ start -= windowsize
+ if windowsize < sizelimit:
+ windowsize *= 2
+
+ m = match(repo, pats, opts)
+ follow = opts.get('follow') or opts.get('follow_first')
+
+ if not len(repo):
+ return [], m
+
+ if follow:
+ defrange = '%s:0' % repo['.'].rev()
+ else:
+ defrange = '-1:0'
+ revs = revrange(repo, opts['rev'] or [defrange])
+ wanted = set()
+ slowpath = m.anypats() or (m.files() and opts.get('removed'))
+ fncache = {}
+
+ if not slowpath and not m.files():
+ # No files, no patterns. Display all revs.
+ wanted = set(revs)
+ copies = []
+ if not slowpath:
+ # Only files, no patterns. Check the history of each file.
+ def filerevgen(filelog, node):
+ cl_count = len(repo)
+ if node is None:
+ last = len(filelog) - 1
+ else:
+ last = filelog.rev(node)
+ for i, window in increasing_windows(last, nullrev):
+ revs = []
+ for j in xrange(i - window, i + 1):
+ n = filelog.node(j)
+ revs.append((filelog.linkrev(j),
+ follow and filelog.renamed(n)))
+ for rev in reversed(revs):
+ # only yield rev for which we have the changelog, it can
+ # happen while doing "hg log" during a pull or commit
+ if rev[0] < cl_count:
+ yield rev
+ def iterfiles():
+ for filename in m.files():
+ yield filename, None
+ for filename_node in copies:
+ yield filename_node
+ minrev, maxrev = min(revs), max(revs)
+ for file_, node in iterfiles():
+ filelog = repo.file(file_)
+ if not len(filelog):
+ if node is None:
+ # A zero count may be a directory or deleted file, so
+ # try to find matching entries on the slow path.
+ if follow:
+ raise util.Abort(_('cannot follow nonexistent file: "%s"') % file_)
+ slowpath = True
+ break
+ else:
+ ui.warn(_('%s:%s copy source revision cannot be found!\n')
+ % (file_, short(node)))
+ continue
+ for rev, copied in filerevgen(filelog, node):
+ if rev <= maxrev:
+ if rev < minrev:
+ break
+ fncache.setdefault(rev, [])
+ fncache[rev].append(file_)
+ wanted.add(rev)
+ if follow and copied:
+ copies.append(copied)
+ if slowpath:
+ if follow:
+ raise util.Abort(_('can only follow copies/renames for explicit '
+ 'filenames'))
+
+ # The slow path checks files modified in every changeset.
+ def changerevgen():
+ for i, window in increasing_windows(len(repo) - 1, nullrev):
+ for j in xrange(i - window, i + 1):
+ yield j, change(j)[3]
+
+ for rev, changefiles in changerevgen():
+ matches = filter(m, changefiles)
+ if matches:
+ fncache[rev] = matches
+ wanted.add(rev)
+
+ class followfilter(object):
+ def __init__(self, onlyfirst=False):
+ self.startrev = nullrev
+ self.roots = []
+ self.onlyfirst = onlyfirst
+
+ def match(self, rev):
+ def realparents(rev):
+ if self.onlyfirst:
+ return repo.changelog.parentrevs(rev)[0:1]
+ else:
+ return filter(lambda x: x != nullrev,
+ repo.changelog.parentrevs(rev))
+
+ if self.startrev == nullrev:
+ self.startrev = rev
+ return True
+
+ if rev > self.startrev:
+ # forward: all descendants
+ if not self.roots:
+ self.roots.append(self.startrev)
+ for parent in realparents(rev):
+ if parent in self.roots:
+ self.roots.append(rev)
+ return True
+ else:
+ # backwards: all parents
+ if not self.roots:
+ self.roots.extend(realparents(self.startrev))
+ if rev in self.roots:
+ self.roots.remove(rev)
+ self.roots.extend(realparents(rev))
+ return True
+
+ return False
+
+ # it might be worthwhile to do this in the iterator if the rev range
+ # is descending and the prune args are all within that range
+ for rev in opts.get('prune', ()):
+ rev = repo.changelog.rev(repo.lookup(rev))
+ ff = followfilter()
+ stop = min(revs[0], revs[-1])
+ for x in xrange(rev, stop-1, -1):
+ if ff.match(x):
+ wanted.discard(x)
+
+ def iterate():
+ if follow and not m.files():
+ ff = followfilter(onlyfirst=opts.get('follow_first'))
+ def want(rev):
+ return ff.match(rev) and rev in wanted
+ else:
+ def want(rev):
+ return rev in wanted
+
+ for i, window in increasing_windows(0, len(revs)):
+ yield 'window', revs[0] < revs[-1], revs[-1]
+ nrevs = [rev for rev in revs[i:i+window] if want(rev)]
+ for rev in sorted(nrevs):
+ fns = fncache.get(rev)
+ if not fns:
+ def fns_generator():
+ for f in change(rev)[3]:
+ if m(f):
+ yield f
+ fns = fns_generator()
+ yield 'add', rev, fns
+ for rev in nrevs:
+ yield 'iter', rev, None
+ return iterate(), m
+
+def commit(ui, repo, commitfunc, pats, opts):
+ '''commit the specified files or all outstanding changes'''
+ date = opts.get('date')
+ if date:
+ opts['date'] = util.parsedate(date)
+ message = logmessage(opts)
+
+ # extract addremove carefully -- this function can be called from a command
+ # that doesn't support addremove
+ if opts.get('addremove'):
+ addremove(repo, pats, opts)
+
+ return commitfunc(ui, repo, message, match(repo, pats, opts), opts)
+
+def commiteditor(repo, ctx, subs):
+ if ctx.description():
+ return ctx.description()
+ return commitforceeditor(repo, ctx, subs)
+
+def commitforceeditor(repo, ctx, subs):
+ edittext = []
+ modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
+ if ctx.description():
+ edittext.append(ctx.description())
+ edittext.append("")
+ edittext.append("") # Empty line between message and comments.
+ edittext.append(_("HG: Enter commit message."
+ " Lines beginning with 'HG:' are removed."))
+ edittext.append(_("HG: Leave message empty to abort commit."))
+ edittext.append("HG: --")
+ edittext.append(_("HG: user: %s") % ctx.user())
+ if ctx.p2():
+ edittext.append(_("HG: branch merge"))
+ if ctx.branch():
+ edittext.append(_("HG: branch '%s'")
+ % encoding.tolocal(ctx.branch()))
+ edittext.extend([_("HG: subrepo %s") % s for s in subs])
+ edittext.extend([_("HG: added %s") % f for f in added])
+ edittext.extend([_("HG: changed %s") % f for f in modified])
+ edittext.extend([_("HG: removed %s") % f for f in removed])
+ if not added and not modified and not removed:
+ edittext.append(_("HG: no files changed"))
+ edittext.append("")
+ # run editor in the repository root
+ olddir = os.getcwd()
+ os.chdir(repo.root)
+ text = repo.ui.edit("\n".join(edittext), ctx.user())
+ text = re.sub("(?m)^HG:.*\n", "", text)
+ os.chdir(olddir)
+
+ if not text.strip():
+ raise util.Abort(_("empty commit message"))
+
+ return text
diff --git a/sys/src/cmd/hg/mercurial/commands.py b/sys/src/cmd/hg/mercurial/commands.py
new file mode 100644
index 000000000..2dfd3def0
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/commands.py
@@ -0,0 +1,3565 @@
+# commands.py - command processing for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import hex, nullid, nullrev, short
+from lock import release
+from i18n import _, gettext
+import os, re, sys, subprocess, difflib, time, tempfile
+import hg, util, revlog, bundlerepo, extensions, copies, context, error
+import patch, help, mdiff, url, encoding
+import archival, changegroup, cmdutil, sshserver, hbisect
+from hgweb import server
+import merge as merge_
+import minirst
+
+# Commands start here, listed alphabetically
+
+def add(ui, repo, *pats, **opts):
+ """add the specified files on the next commit
+
+ Schedule files to be version controlled and added to the
+ repository.
+
+ The files will be added to the repository at the next commit. To
+ undo an add before that, see hg forget.
+
+ If no names are given, add all files to the repository.
+ """
+
+ bad = []
+ exacts = {}
+ names = []
+ m = cmdutil.match(repo, pats, opts)
+ oldbad = m.bad
+ m.bad = lambda x,y: bad.append(x) or oldbad(x,y)
+
+ for f in repo.walk(m):
+ exact = m.exact(f)
+ if exact or f not in repo.dirstate:
+ names.append(f)
+ if ui.verbose or not exact:
+ ui.status(_('adding %s\n') % m.rel(f))
+ if not opts.get('dry_run'):
+ bad += [f for f in repo.add(names) if f in m.files()]
+ return bad and 1 or 0
+
+def addremove(ui, repo, *pats, **opts):
+ """add all new files, delete all missing files
+
+ Add all new files and remove all missing files from the
+ repository.
+
+ New files are ignored if they match any of the patterns in
+ .hgignore. As with add, these changes take effect at the next
+ commit.
+
+ Use the -s/--similarity option to detect renamed files. With a
+ parameter greater than 0, this compares every removed file with
+ every added file and records those similar enough as renames. This
+ option takes a percentage between 0 (disabled) and 100 (files must
+ be identical) as its parameter. Detecting renamed files this way
+ can be expensive.
+ """
+ try:
+ sim = float(opts.get('similarity') or 0)
+ except ValueError:
+ raise util.Abort(_('similarity must be a number'))
+ if sim < 0 or sim > 100:
+ raise util.Abort(_('similarity must be between 0 and 100'))
+ return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
+
+def annotate(ui, repo, *pats, **opts):
+ """show changeset information by line for each file
+
+ List changes in files, showing the revision id responsible for
+ each line
+
+ This command is useful for discovering when a change was made and
+ by whom.
+
+ Without the -a/--text option, annotate will avoid processing files
+ it detects as binary. With -a, annotate will annotate the file
+ anyway, although the results will probably be neither useful
+ nor desirable.
+ """
+ datefunc = ui.quiet and util.shortdate or util.datestr
+ getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
+
+ if not pats:
+ raise util.Abort(_('at least one filename or pattern is required'))
+
+ opmap = [('user', lambda x: ui.shortuser(x[0].user())),
+ ('number', lambda x: str(x[0].rev())),
+ ('changeset', lambda x: short(x[0].node())),
+ ('date', getdate),
+ ('follow', lambda x: x[0].path()),
+ ]
+
+ if (not opts.get('user') and not opts.get('changeset') and not opts.get('date')
+ and not opts.get('follow')):
+ opts['number'] = 1
+
+ linenumber = opts.get('line_number') is not None
+ if (linenumber and (not opts.get('changeset')) and (not opts.get('number'))):
+ raise util.Abort(_('at least one of -n/-c is required for -l'))
+
+ funcmap = [func for op, func in opmap if opts.get(op)]
+ if linenumber:
+ lastfunc = funcmap[-1]
+ funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
+
+ ctx = repo[opts.get('rev')]
+
+ m = cmdutil.match(repo, pats, opts)
+ for abs in ctx.walk(m):
+ fctx = ctx[abs]
+ if not opts.get('text') and util.binary(fctx.data()):
+ ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
+ continue
+
+ lines = fctx.annotate(follow=opts.get('follow'),
+ linenumber=linenumber)
+ pieces = []
+
+ for f in funcmap:
+ l = [f(n) for n, dummy in lines]
+ if l:
+ ml = max(map(len, l))
+ pieces.append(["%*s" % (ml, x) for x in l])
+
+ if pieces:
+ for p, l in zip(zip(*pieces), lines):
+ ui.write("%s: %s" % (" ".join(p), l[1]))
+
+def archive(ui, repo, dest, **opts):
+ '''create an unversioned archive of a repository revision
+
+ By default, the revision used is the parent of the working
+ directory; use -r/--rev to specify a different revision.
+
+ To specify the type of archive to create, use -t/--type. Valid
+ types are::
+
+ "files" (default): a directory full of files
+ "tar": tar archive, uncompressed
+ "tbz2": tar archive, compressed using bzip2
+ "tgz": tar archive, compressed using gzip
+ "uzip": zip archive, uncompressed
+ "zip": zip archive, compressed using deflate
+
+ The exact name of the destination archive or directory is given
+ using a format string; see 'hg help export' for details.
+
+ Each member added to an archive file has a directory prefix
+ prepended. Use -p/--prefix to specify a format string for the
+ prefix. The default is the basename of the archive, with suffixes
+ removed.
+ '''
+
+ ctx = repo[opts.get('rev')]
+ if not ctx:
+ raise util.Abort(_('no working directory: please specify a revision'))
+ node = ctx.node()
+ dest = cmdutil.make_filename(repo, dest, node)
+ if os.path.realpath(dest) == repo.root:
+ raise util.Abort(_('repository root cannot be destination'))
+ matchfn = cmdutil.match(repo, [], opts)
+ kind = opts.get('type') or 'files'
+ prefix = opts.get('prefix')
+ if dest == '-':
+ if kind == 'files':
+ raise util.Abort(_('cannot archive plain files to stdout'))
+ dest = sys.stdout
+ if not prefix: prefix = os.path.basename(repo.root) + '-%h'
+ prefix = cmdutil.make_filename(repo, prefix, node)
+ archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
+ matchfn, prefix)
+
+def backout(ui, repo, node=None, rev=None, **opts):
+ '''reverse effect of earlier changeset
+
+ Commit the backed out changes as a new changeset. The new
+ changeset is a child of the backed out changeset.
+
+ If you backout a changeset other than the tip, a new head is
+ created. This head will be the new tip and you should merge this
+ backout changeset with another head.
+
+ The --merge option remembers the parent of the working directory
+ before starting the backout, then merges the new head with that
+ changeset afterwards. This saves you from doing the merge by hand.
+ The result of this merge is not committed, as with a normal merge.
+
+ See 'hg help dates' for a list of formats valid for -d/--date.
+ '''
+ if rev and node:
+ raise util.Abort(_("please specify just one revision"))
+
+ if not rev:
+ rev = node
+
+ if not rev:
+ raise util.Abort(_("please specify a revision to backout"))
+
+ date = opts.get('date')
+ if date:
+ opts['date'] = util.parsedate(date)
+
+ cmdutil.bail_if_changed(repo)
+ node = repo.lookup(rev)
+
+ op1, op2 = repo.dirstate.parents()
+ a = repo.changelog.ancestor(op1, node)
+ if a != node:
+ raise util.Abort(_('cannot backout change on a different branch'))
+
+ p1, p2 = repo.changelog.parents(node)
+ if p1 == nullid:
+ raise util.Abort(_('cannot backout a change with no parents'))
+ if p2 != nullid:
+ if not opts.get('parent'):
+ raise util.Abort(_('cannot backout a merge changeset without '
+ '--parent'))
+ p = repo.lookup(opts['parent'])
+ if p not in (p1, p2):
+ raise util.Abort(_('%s is not a parent of %s') %
+ (short(p), short(node)))
+ parent = p
+ else:
+ if opts.get('parent'):
+ raise util.Abort(_('cannot use --parent on non-merge changeset'))
+ parent = p1
+
+ # the backout should appear on the same branch
+ branch = repo.dirstate.branch()
+ hg.clean(repo, node, show_stats=False)
+ repo.dirstate.setbranch(branch)
+ revert_opts = opts.copy()
+ revert_opts['date'] = None
+ revert_opts['all'] = True
+ revert_opts['rev'] = hex(parent)
+ revert_opts['no_backup'] = None
+ revert(ui, repo, **revert_opts)
+ commit_opts = opts.copy()
+ commit_opts['addremove'] = False
+ if not commit_opts['message'] and not commit_opts['logfile']:
+ # we don't translate commit messages
+ commit_opts['message'] = "Backed out changeset %s" % short(node)
+ commit_opts['force_editor'] = True
+ commit(ui, repo, **commit_opts)
+ def nice(node):
+ return '%d:%s' % (repo.changelog.rev(node), short(node))
+ ui.status(_('changeset %s backs out changeset %s\n') %
+ (nice(repo.changelog.tip()), nice(node)))
+ if op1 != node:
+ hg.clean(repo, op1, show_stats=False)
+ if opts.get('merge'):
+ ui.status(_('merging with changeset %s\n') % nice(repo.changelog.tip()))
+ hg.merge(repo, hex(repo.changelog.tip()))
+ else:
+ ui.status(_('the backout changeset is a new head - '
+ 'do not forget to merge\n'))
+ ui.status(_('(use "backout --merge" '
+ 'if you want to auto-merge)\n'))
+
+def bisect(ui, repo, rev=None, extra=None, command=None,
+ reset=None, good=None, bad=None, skip=None, noupdate=None):
+ """subdivision search of changesets
+
+ This command helps to find changesets which introduce problems. To
+ use, mark the earliest changeset you know exhibits the problem as
+ bad, then mark the latest changeset which is free from the problem
+ as good. Bisect will update your working directory to a revision
+ for testing (unless the -U/--noupdate option is specified). Once
+ you have performed tests, mark the working directory as good or
+ bad, and bisect will either update to another candidate changeset
+ or announce that it has found the bad revision.
+
+ As a shortcut, you can also use the revision argument to mark a
+ revision as good or bad without checking it out first.
+
+ If you supply a command, it will be used for automatic bisection.
+ Its exit status will be used to mark revisions as good or bad:
+ status 0 means good, 125 means to skip the revision, 127
+ (command not found) will abort the bisection, and any other
+ non-zero exit status means the revision is bad.
+ """
+ def print_result(nodes, good):
+ displayer = cmdutil.show_changeset(ui, repo, {})
+ if len(nodes) == 1:
+ # narrowed it down to a single revision
+ if good:
+ ui.write(_("The first good revision is:\n"))
+ else:
+ ui.write(_("The first bad revision is:\n"))
+ displayer.show(repo[nodes[0]])
+ else:
+ # multiple possible revisions
+ if good:
+ ui.write(_("Due to skipped revisions, the first "
+ "good revision could be any of:\n"))
+ else:
+ ui.write(_("Due to skipped revisions, the first "
+ "bad revision could be any of:\n"))
+ for n in nodes:
+ displayer.show(repo[n])
+
+ def check_state(state, interactive=True):
+ if not state['good'] or not state['bad']:
+ if (good or bad or skip or reset) and interactive:
+ return
+ if not state['good']:
+ raise util.Abort(_('cannot bisect (no known good revisions)'))
+ else:
+ raise util.Abort(_('cannot bisect (no known bad revisions)'))
+ return True
+
+ # backward compatibility
+ if rev in "good bad reset init".split():
+ ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
+ cmd, rev, extra = rev, extra, None
+ if cmd == "good":
+ good = True
+ elif cmd == "bad":
+ bad = True
+ else:
+ reset = True
+ elif extra or good + bad + skip + reset + bool(command) > 1:
+ raise util.Abort(_('incompatible arguments'))
+
+ if reset:
+ p = repo.join("bisect.state")
+ if os.path.exists(p):
+ os.unlink(p)
+ return
+
+ state = hbisect.load_state(repo)
+
+ if command:
+ commandpath = util.find_exe(command)
+ if commandpath is None:
+ raise util.Abort(_("cannot find executable: %s") % command)
+ changesets = 1
+ try:
+ while changesets:
+ # update state
+ status = subprocess.call([commandpath])
+ if status == 125:
+ transition = "skip"
+ elif status == 0:
+ transition = "good"
+ # status < 0 means process was killed
+ elif status == 127:
+ raise util.Abort(_("failed to execute %s") % command)
+ elif status < 0:
+ raise util.Abort(_("%s killed") % command)
+ else:
+ transition = "bad"
+ ctx = repo[rev or '.']
+ state[transition].append(ctx.node())
+ ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
+ check_state(state, interactive=False)
+ # bisect
+ nodes, changesets, good = hbisect.bisect(repo.changelog, state)
+ # update to next check
+ cmdutil.bail_if_changed(repo)
+ hg.clean(repo, nodes[0], show_stats=False)
+ finally:
+ hbisect.save_state(repo, state)
+ return print_result(nodes, not status)
+
+ # update state
+ node = repo.lookup(rev or '.')
+ if good:
+ state['good'].append(node)
+ elif bad:
+ state['bad'].append(node)
+ elif skip:
+ state['skip'].append(node)
+
+ hbisect.save_state(repo, state)
+
+ if not check_state(state):
+ return
+
+ # actually bisect
+ nodes, changesets, good = hbisect.bisect(repo.changelog, state)
+ if changesets == 0:
+ print_result(nodes, good)
+ else:
+ assert len(nodes) == 1 # only a single node can be tested next
+ node = nodes[0]
+ # compute the approximate number of remaining tests
+ tests, size = 0, 2
+ while size <= changesets:
+ tests, size = tests + 1, size * 2
+ rev = repo.changelog.rev(node)
+ ui.write(_("Testing changeset %d:%s "
+ "(%d changesets remaining, ~%d tests)\n")
+ % (rev, short(node), changesets, tests))
+ if not noupdate:
+ cmdutil.bail_if_changed(repo)
+ return hg.clean(repo, node)
+
+def branch(ui, repo, label=None, **opts):
+ """set or show the current branch name
+
+ With no argument, show the current branch name. With one argument,
+ set the working directory branch name (the branch will not exist
+ in the repository until the next commit). Standard practice
+ recommends that primary development take place on the 'default'
+ branch.
+
+ Unless -f/--force is specified, branch will not let you set a
+ branch name that already exists, even if it's inactive.
+
+ Use -C/--clean to reset the working directory branch to that of
+ the parent of the working directory, negating a previous branch
+ change.
+
+ Use the command 'hg update' to switch to an existing branch. Use
+ 'hg commit --close-branch' to mark this branch as closed.
+ """
+
+ if opts.get('clean'):
+ label = repo[None].parents()[0].branch()
+ repo.dirstate.setbranch(label)
+ ui.status(_('reset working directory to branch %s\n') % label)
+ elif label:
+ if not opts.get('force') and label in repo.branchtags():
+ if label not in [p.branch() for p in repo.parents()]:
+ raise util.Abort(_('a branch of the same name already exists'
+ ' (use --force to override)'))
+ repo.dirstate.setbranch(encoding.fromlocal(label))
+ ui.status(_('marked working directory as branch %s\n') % label)
+ else:
+ ui.write("%s\n" % encoding.tolocal(repo.dirstate.branch()))
+
+def branches(ui, repo, active=False, closed=False):
+ """list repository named branches
+
+ List the repository's named branches, indicating which ones are
+ inactive. If -c/--closed is specified, also list branches which have
+ been marked closed (see hg commit --close-branch).
+
+ If -a/--active is specified, only show active branches. A branch
+ is considered active if it contains repository heads.
+
+ Use the command 'hg update' to switch to an existing branch.
+ """
+
+ hexfunc = ui.debugflag and hex or short
+ activebranches = [encoding.tolocal(repo[n].branch())
+ for n in repo.heads()]
+ def testactive(tag, node):
+ realhead = tag in activebranches
+ open = node in repo.branchheads(tag, closed=False)
+ return realhead and open
+ branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
+ for tag, node in repo.branchtags().items()],
+ reverse=True)
+
+ for isactive, node, tag in branches:
+ if (not active) or isactive:
+ if ui.quiet:
+ ui.write("%s\n" % tag)
+ else:
+ hn = repo.lookup(node)
+ if isactive:
+ notice = ''
+ elif hn not in repo.branchheads(tag, closed=False):
+ if not closed:
+ continue
+ notice = ' (closed)'
+ else:
+ notice = ' (inactive)'
+ rev = str(node).rjust(31 - encoding.colwidth(tag))
+ data = tag, rev, hexfunc(hn), notice
+ ui.write("%s %s:%s%s\n" % data)
+
+def bundle(ui, repo, fname, dest=None, **opts):
+ """create a changegroup file
+
+ Generate a compressed changegroup file collecting changesets not
+ known to be in another repository.
+
+ If no destination repository is specified the destination is
+ assumed to have all the nodes specified by one or more --base
+ parameters. To create a bundle containing all changesets, use
+ -a/--all (or --base null).
+
+ You can change compression method with the -t/--type option.
+ The available compression methods are: none, bzip2, and
+ gzip (by default, bundles are compressed using bzip2).
+
+ The bundle file can then be transferred using conventional means
+ and applied to another repository with the unbundle or pull
+ command. This is useful when direct push and pull are not
+ available or when exporting an entire repository is undesirable.
+
+ Applying bundles preserves all changeset contents including
+ permissions, copy/rename information, and revision history.
+ """
+ revs = opts.get('rev') or None
+ if revs:
+ revs = [repo.lookup(rev) for rev in revs]
+ if opts.get('all'):
+ base = ['null']
+ else:
+ base = opts.get('base')
+ if base:
+ if dest:
+ raise util.Abort(_("--base is incompatible with specifying "
+ "a destination"))
+ base = [repo.lookup(rev) for rev in base]
+ # create the right base
+ # XXX: nodesbetween / changegroup* should be "fixed" instead
+ o = []
+ has = set((nullid,))
+ for n in base:
+ has.update(repo.changelog.reachable(n))
+ if revs:
+ visit = list(revs)
+ else:
+ visit = repo.changelog.heads()
+ seen = {}
+ while visit:
+ n = visit.pop(0)
+ parents = [p for p in repo.changelog.parents(n) if p not in has]
+ if len(parents) == 0:
+ o.insert(0, n)
+ else:
+ for p in parents:
+ if p not in seen:
+ seen[p] = 1
+ visit.append(p)
+ else:
+ dest, revs, checkout = hg.parseurl(
+ ui.expandpath(dest or 'default-push', dest or 'default'), revs)
+ other = hg.repository(cmdutil.remoteui(repo, opts), dest)
+ o = repo.findoutgoing(other, force=opts.get('force'))
+
+ if revs:
+ cg = repo.changegroupsubset(o, revs, 'bundle')
+ else:
+ cg = repo.changegroup(o, 'bundle')
+
+ bundletype = opts.get('type', 'bzip2').lower()
+ btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
+ bundletype = btypes.get(bundletype)
+ if bundletype not in changegroup.bundletypes:
+ raise util.Abort(_('unknown bundle type specified with --type'))
+
+ changegroup.writebundle(cg, fname, bundletype)
+
+def cat(ui, repo, file1, *pats, **opts):
+ """output the current or given revision of files
+
+ Print the specified files as they were at the given revision. If
+ no revision is given, the parent of the working directory is used,
+ or tip if no revision is checked out.
+
+ Output may be to a file, in which case the name of the file is
+ given using a format string. The formatting rules are the same as
+ for the export command, with the following additions::
+
+ %s basename of file being printed
+ %d dirname of file being printed, or '.' if in repository root
+ %p root-relative path name of file being printed
+ """
+ ctx = repo[opts.get('rev')]
+ err = 1
+ m = cmdutil.match(repo, (file1,) + pats, opts)
+ for abs in ctx.walk(m):
+ fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
+ data = ctx[abs].data()
+ if opts.get('decode'):
+ data = repo.wwritedata(abs, data)
+ fp.write(data)
+ err = 0
+ return err
+
+def clone(ui, source, dest=None, **opts):
+ """make a copy of an existing repository
+
+ Create a copy of an existing repository in a new directory.
+
+ If no destination directory name is specified, it defaults to the
+ basename of the source.
+
+ The location of the source is added to the new repository's
+ .hg/hgrc file, as the default to be used for future pulls.
+
+ If you use the -r/--rev option to clone up to a specific revision,
+ no subsequent revisions (including subsequent tags) will be
+ present in the cloned repository. This option implies --pull, even
+ on local repositories.
+
+ By default, clone will check out the head of the 'default' branch.
+ If the -U/--noupdate option is used, the new clone will contain
+ only a repository (.hg) and no working copy (the working copy
+ parent is the null revision).
+
+ See 'hg help urls' for valid source format details.
+
+ It is possible to specify an ssh:// URL as the destination, but no
+ .hg/hgrc and working directory will be created on the remote side.
+ Please see 'hg help urls' for important details about ssh:// URLs.
+
+ For efficiency, hardlinks are used for cloning whenever the source
+ and destination are on the same filesystem (note this applies only
+ to the repository data, not to the checked out files). Some
+ filesystems, such as AFS, implement hardlinking incorrectly, but
+ do not report errors. In these cases, use the --pull option to
+ avoid hardlinking.
+
+ In some cases, you can clone repositories and checked out files
+ using full hardlinks with ::
+
+ $ cp -al REPO REPOCLONE
+
+ This is the fastest way to clone, but it is not always safe. The
+ operation is not atomic (making sure REPO is not modified during
+ the operation is up to you) and you have to make sure your editor
+ breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
+ this is not compatible with certain extensions that place their
+ metadata under the .hg directory, such as mq.
+ """
+ hg.clone(cmdutil.remoteui(ui, opts), source, dest,
+ pull=opts.get('pull'),
+ stream=opts.get('uncompressed'),
+ rev=opts.get('rev'),
+ update=not opts.get('noupdate'))
+
+def commit(ui, repo, *pats, **opts):
+ """commit the specified files or all outstanding changes
+
+ Commit changes to the given files into the repository. Unlike a
+ centralized RCS, this operation is a local operation. See hg push
+ for a way to actively distribute your changes.
+
+ If a list of files is omitted, all changes reported by "hg status"
+ will be committed.
+
+ If you are committing the result of a merge, do not provide any
+ filenames or -I/-X filters.
+
+ If no commit message is specified, the configured editor is
+ started to prompt you for a message.
+
+ See 'hg help dates' for a list of formats valid for -d/--date.
+ """
+ extra = {}
+ if opts.get('close_branch'):
+ extra['close'] = 1
+ e = cmdutil.commiteditor
+ if opts.get('force_editor'):
+ e = cmdutil.commitforceeditor
+
+ def commitfunc(ui, repo, message, match, opts):
+ return repo.commit(message, opts.get('user'), opts.get('date'), match,
+ editor=e, extra=extra)
+
+ node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
+ if not node:
+ ui.status(_("nothing changed\n"))
+ return
+ cl = repo.changelog
+ rev = cl.rev(node)
+ parents = cl.parentrevs(rev)
+ if rev - 1 in parents:
+ # one of the parents was the old tip
+ pass
+ elif (parents == (nullrev, nullrev) or
+ len(cl.heads(cl.node(parents[0]))) > 1 and
+ (parents[1] == nullrev or len(cl.heads(cl.node(parents[1]))) > 1)):
+ ui.status(_('created new head\n'))
+
+ if ui.debugflag:
+ ui.write(_('committed changeset %d:%s\n') % (rev, hex(node)))
+ elif ui.verbose:
+ ui.write(_('committed changeset %d:%s\n') % (rev, short(node)))
+
+def copy(ui, repo, *pats, **opts):
+ """mark files as copied for the next commit
+
+ Mark dest as having copies of source files. If dest is a
+ directory, copies are put in that directory. If dest is a file,
+ the source must be a single file.
+
+ By default, this command copies the contents of files as they
+ exist in the working directory. If invoked with -A/--after, the
+ operation is recorded, but no copying is performed.
+
+ This command takes effect with the next commit. To undo a copy
+ before that, see hg revert.
+ """
+ wlock = repo.wlock(False)
+ try:
+ return cmdutil.copy(ui, repo, pats, opts)
+ finally:
+ wlock.release()
+
+def debugancestor(ui, repo, *args):
+ """find the ancestor revision of two revisions in a given index"""
+ if len(args) == 3:
+ index, rev1, rev2 = args
+ r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
+ lookup = r.lookup
+ elif len(args) == 2:
+ if not repo:
+ raise util.Abort(_("There is no Mercurial repository here "
+ "(.hg not found)"))
+ rev1, rev2 = args
+ r = repo.changelog
+ lookup = repo.lookup
+ else:
+ raise util.Abort(_('either two or three arguments required'))
+ a = r.ancestor(lookup(rev1), lookup(rev2))
+ ui.write("%d:%s\n" % (r.rev(a), hex(a)))
+
+def debugcommands(ui, cmd='', *args):
+ for cmd, vals in sorted(table.iteritems()):
+ cmd = cmd.split('|')[0].strip('^')
+ opts = ', '.join([i[1] for i in vals[1]])
+ ui.write('%s: %s\n' % (cmd, opts))
+
+def debugcomplete(ui, cmd='', **opts):
+ """returns the completion list associated with the given command"""
+
+ if opts.get('options'):
+ options = []
+ otables = [globalopts]
+ if cmd:
+ aliases, entry = cmdutil.findcmd(cmd, table, False)
+ otables.append(entry[1])
+ for t in otables:
+ for o in t:
+ if o[0]:
+ options.append('-%s' % o[0])
+ options.append('--%s' % o[1])
+ ui.write("%s\n" % "\n".join(options))
+ return
+
+ cmdlist = cmdutil.findpossible(cmd, table)
+ if ui.verbose:
+ cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
+ ui.write("%s\n" % "\n".join(sorted(cmdlist)))
+
+def debugfsinfo(ui, path = "."):
+ open('.debugfsinfo', 'w').write('')
+ ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
+ ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
+ ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
+ and 'yes' or 'no'))
+ os.unlink('.debugfsinfo')
+
+def debugrebuildstate(ui, repo, rev="tip"):
+ """rebuild the dirstate as it would look like for the given revision"""
+ ctx = repo[rev]
+ wlock = repo.wlock()
+ try:
+ repo.dirstate.rebuild(ctx.node(), ctx.manifest())
+ finally:
+ wlock.release()
+
+def debugcheckstate(ui, repo):
+ """validate the correctness of the current dirstate"""
+ parent1, parent2 = repo.dirstate.parents()
+ m1 = repo[parent1].manifest()
+ m2 = repo[parent2].manifest()
+ errors = 0
+ for f in repo.dirstate:
+ state = repo.dirstate[f]
+ if state in "nr" and f not in m1:
+ ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
+ errors += 1
+ if state in "a" and f in m1:
+ ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
+ errors += 1
+ if state in "m" and f not in m1 and f not in m2:
+ ui.warn(_("%s in state %s, but not in either manifest\n") %
+ (f, state))
+ errors += 1
+ for f in m1:
+ state = repo.dirstate[f]
+ if state not in "nrm":
+ ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
+ errors += 1
+ if errors:
+ error = _(".hg/dirstate inconsistent with current parent's manifest")
+ raise util.Abort(error)
+
+def showconfig(ui, repo, *values, **opts):
+ """show combined config settings from all hgrc files
+
+ With no arguments, print names and values of all config items.
+
+ With one argument of the form section.name, print just the value
+ of that config item.
+
+ With multiple arguments, print names and values of all config
+ items with matching section names.
+
+ With --debug, the source (filename and line number) is printed
+ for each config item.
+ """
+
+ untrusted = bool(opts.get('untrusted'))
+ if values:
+ if len([v for v in values if '.' in v]) > 1:
+ raise util.Abort(_('only one config item permitted'))
+ for section, name, value in ui.walkconfig(untrusted=untrusted):
+ sectname = section + '.' + name
+ if values:
+ for v in values:
+ if v == section:
+ ui.debug('%s: ' %
+ ui.configsource(section, name, untrusted))
+ ui.write('%s=%s\n' % (sectname, value))
+ elif v == sectname:
+ ui.debug('%s: ' %
+ ui.configsource(section, name, untrusted))
+ ui.write(value, '\n')
+ else:
+ ui.debug('%s: ' %
+ ui.configsource(section, name, untrusted))
+ ui.write('%s=%s\n' % (sectname, value))
+
+def debugsetparents(ui, repo, rev1, rev2=None):
+ """manually set the parents of the current working directory
+
+ This is useful for writing repository conversion tools, but should
+ be used with care.
+ """
+
+ if not rev2:
+ rev2 = hex(nullid)
+
+ wlock = repo.wlock()
+ try:
+ repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
+ finally:
+ wlock.release()
+
+def debugstate(ui, repo, nodates=None):
+ """show the contents of the current dirstate"""
+ timestr = ""
+ showdate = not nodates
+ for file_, ent in sorted(repo.dirstate._map.iteritems()):
+ if showdate:
+ if ent[3] == -1:
+ # Pad or slice to locale representation
+ locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ", time.localtime(0)))
+ timestr = 'unset'
+ timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
+ else:
+ timestr = time.strftime("%Y-%m-%d %H:%M:%S ", time.localtime(ent[3]))
+ if ent[1] & 020000:
+ mode = 'lnk'
+ else:
+ mode = '%3o' % (ent[1] & 0777)
+ ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
+ for f in repo.dirstate.copies():
+ ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
+
+def debugsub(ui, repo, rev=None):
+ if rev == '':
+ rev = None
+ for k,v in sorted(repo[rev].substate.items()):
+ ui.write('path %s\n' % k)
+ ui.write(' source %s\n' % v[0])
+ ui.write(' revision %s\n' % v[1])
+
+def debugdata(ui, file_, rev):
+ """dump the contents of a data file revision"""
+ r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
+ try:
+ ui.write(r.revision(r.lookup(rev)))
+ except KeyError:
+ raise util.Abort(_('invalid revision identifier %s') % rev)
+
+def debugdate(ui, date, range=None, **opts):
+ """parse and display a date"""
+ if opts["extended"]:
+ d = util.parsedate(date, util.extendeddateformats)
+ else:
+ d = util.parsedate(date)
+ ui.write("internal: %s %s\n" % d)
+ ui.write("standard: %s\n" % util.datestr(d))
+ if range:
+ m = util.matchdate(range)
+ ui.write("match: %s\n" % m(d[0]))
+
+def debugindex(ui, file_):
+ """dump the contents of an index file"""
+ r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
+ ui.write(" rev offset length base linkrev"
+ " nodeid p1 p2\n")
+ for i in r:
+ node = r.node(i)
+ try:
+ pp = r.parents(node)
+ except:
+ pp = [nullid, nullid]
+ ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
+ i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
+ short(node), short(pp[0]), short(pp[1])))
+
+def debugindexdot(ui, file_):
+ """dump an index DAG as a graphviz dot file"""
+ r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
+ ui.write("digraph G {\n")
+ for i in r:
+ node = r.node(i)
+ pp = r.parents(node)
+ ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
+ if pp[1] != nullid:
+ ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
+ ui.write("}\n")
+
+def debuginstall(ui):
+ '''test Mercurial installation'''
+
+ def writetemp(contents):
+ (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
+ f = os.fdopen(fd, "wb")
+ f.write(contents)
+ f.close()
+ return name
+
+ problems = 0
+
+ # encoding
+ ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
+ try:
+ encoding.fromlocal("test")
+ except util.Abort, inst:
+ ui.write(" %s\n" % inst)
+ ui.write(_(" (check that your locale is properly set)\n"))
+ problems += 1
+
+ # compiled modules
+ ui.status(_("Checking extensions...\n"))
+ try:
+ import bdiff, mpatch, base85
+ except Exception, inst:
+ ui.write(" %s\n" % inst)
+ ui.write(_(" One or more extensions could not be found"))
+ ui.write(_(" (check that you compiled the extensions)\n"))
+ problems += 1
+
+ # templates
+ ui.status(_("Checking templates...\n"))
+ try:
+ import templater
+ templater.templater(templater.templatepath("map-cmdline.default"))
+ except Exception, inst:
+ ui.write(" %s\n" % inst)
+ ui.write(_(" (templates seem to have been installed incorrectly)\n"))
+ problems += 1
+
+ # patch
+ ui.status(_("Checking patch...\n"))
+ patchproblems = 0
+ a = "1\n2\n3\n4\n"
+ b = "1\n2\n3\ninsert\n4\n"
+ fa = writetemp(a)
+ d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
+ os.path.basename(fa))
+ fd = writetemp(d)
+
+ files = {}
+ try:
+ patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
+ except util.Abort, e:
+ ui.write(_(" patch call failed:\n"))
+ ui.write(" " + str(e) + "\n")
+ patchproblems += 1
+ else:
+ if list(files) != [os.path.basename(fa)]:
+ ui.write(_(" unexpected patch output!\n"))
+ patchproblems += 1
+ a = open(fa).read()
+ if a != b:
+ ui.write(_(" patch test failed!\n"))
+ patchproblems += 1
+
+ if patchproblems:
+ if ui.config('ui', 'patch'):
+ ui.write(_(" (Current patch tool may be incompatible with patch,"
+ " or misconfigured. Please check your .hgrc file)\n"))
+ else:
+ ui.write(_(" Internal patcher failure, please report this error"
+ " to http://mercurial.selenic.com/bts/\n"))
+ problems += patchproblems
+
+ os.unlink(fa)
+ os.unlink(fd)
+
+ # editor
+ ui.status(_("Checking commit editor...\n"))
+ editor = ui.geteditor()
+ cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
+ if not cmdpath:
+ if editor == 'vi':
+ ui.write(_(" No commit editor set and can't find vi in PATH\n"))
+ ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
+ else:
+ ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
+ ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
+ problems += 1
+
+ # check username
+ ui.status(_("Checking username...\n"))
+ user = os.environ.get("HGUSER")
+ if user is None:
+ user = ui.config("ui", "username")
+ if user is None:
+ user = os.environ.get("EMAIL")
+ if not user:
+ ui.warn(" ")
+ ui.username()
+ ui.write(_(" (specify a username in your .hgrc file)\n"))
+
+ if not problems:
+ ui.status(_("No problems detected\n"))
+ else:
+ ui.write(_("%s problems detected,"
+ " please check your install!\n") % problems)
+
+ return problems
+
+def debugrename(ui, repo, file1, *pats, **opts):
+ """dump rename information"""
+
+ ctx = repo[opts.get('rev')]
+ m = cmdutil.match(repo, (file1,) + pats, opts)
+ for abs in ctx.walk(m):
+ fctx = ctx[abs]
+ o = fctx.filelog().renamed(fctx.filenode())
+ rel = m.rel(abs)
+ if o:
+ ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
+ else:
+ ui.write(_("%s not renamed\n") % rel)
+
+def debugwalk(ui, repo, *pats, **opts):
+ """show how files match on given patterns"""
+ m = cmdutil.match(repo, pats, opts)
+ items = list(repo.walk(m))
+ if not items:
+ return
+ fmt = 'f %%-%ds %%-%ds %%s' % (
+ max([len(abs) for abs in items]),
+ max([len(m.rel(abs)) for abs in items]))
+ for abs in items:
+ line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
+ ui.write("%s\n" % line.rstrip())
+
+def diff(ui, repo, *pats, **opts):
+ """diff repository (or selected files)
+
+ Show differences between revisions for the specified files.
+
+ Differences between files are shown using the unified diff format.
+
+ NOTE: diff may generate unexpected results for merges, as it will
+ default to comparing against the working directory's first parent
+ changeset if no revisions are specified.
+
+ When two revision arguments are given, then changes are shown
+ between those revisions. If only one revision is specified then
+ that revision is compared to the working directory, and, when no
+ revisions are specified, the working directory files are compared
+ to its parent.
+
+ Without the -a/--text option, diff will avoid generating diffs of
+ files it detects as binary. With -a, diff will generate a diff
+ anyway, probably with undesirable results.
+
+ Use the -g/--git option to generate diffs in the git extended diff
+ format. For more information, read 'hg help diffs'.
+ """
+
+ revs = opts.get('rev')
+ change = opts.get('change')
+
+ if revs and change:
+ msg = _('cannot specify --rev and --change at the same time')
+ raise util.Abort(msg)
+ elif change:
+ node2 = repo.lookup(change)
+ node1 = repo[node2].parents()[0].node()
+ else:
+ node1, node2 = cmdutil.revpair(repo, revs)
+
+ m = cmdutil.match(repo, pats, opts)
+ it = patch.diff(repo, node1, node2, match=m, opts=patch.diffopts(ui, opts))
+ for chunk in it:
+ ui.write(chunk)
+
+def export(ui, repo, *changesets, **opts):
+ """dump the header and diffs for one or more changesets
+
+ Print the changeset header and diffs for one or more revisions.
+
+ The information shown in the changeset header is: author,
+ changeset hash, parent(s) and commit comment.
+
+ NOTE: export may generate unexpected diff output for merge
+ changesets, as it will compare the merge changeset against its
+ first parent only.
+
+ Output may be to a file, in which case the name of the file is
+ given using a format string. The formatting rules are as follows::
+
+ %% literal "%" character
+ %H changeset hash (40 bytes of hexadecimal)
+ %N number of patches being generated
+ %R changeset revision number
+ %b basename of the exporting repository
+ %h short-form changeset hash (12 bytes of hexadecimal)
+ %n zero-padded sequence number, starting at 1
+ %r zero-padded changeset revision number
+
+ Without the -a/--text option, export will avoid generating diffs
+ of files it detects as binary. With -a, export will generate a
+ diff anyway, probably with undesirable results.
+
+ Use the -g/--git option to generate diffs in the git extended diff
+ format. See 'hg help diffs' for more information.
+
+ With the --switch-parent option, the diff will be against the
+ second parent. It can be useful to review a merge.
+ """
+ if not changesets:
+ raise util.Abort(_("export requires at least one changeset"))
+ revs = cmdutil.revrange(repo, changesets)
+ if len(revs) > 1:
+ ui.note(_('exporting patches:\n'))
+ else:
+ ui.note(_('exporting patch:\n'))
+ patch.export(repo, revs, template=opts.get('output'),
+ switch_parent=opts.get('switch_parent'),
+ opts=patch.diffopts(ui, opts))
+
+def forget(ui, repo, *pats, **opts):
+ """forget the specified files on the next commit
+
+ Mark the specified files so they will no longer be tracked
+ after the next commit.
+
+ This only removes files from the current branch, not from the
+ entire project history, and it does not delete them from the
+ working directory.
+
+ To undo a forget before the next commit, see hg add.
+ """
+
+ if not pats:
+ raise util.Abort(_('no files specified'))
+
+ m = cmdutil.match(repo, pats, opts)
+ s = repo.status(match=m, clean=True)
+ forget = sorted(s[0] + s[1] + s[3] + s[6])
+
+ for f in m.files():
+ if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
+ ui.warn(_('not removing %s: file is already untracked\n')
+ % m.rel(f))
+
+ for f in forget:
+ if ui.verbose or not m.exact(f):
+ ui.status(_('removing %s\n') % m.rel(f))
+
+ repo.remove(forget, unlink=False)
+
+def grep(ui, repo, pattern, *pats, **opts):
+ """search for a pattern in specified files and revisions
+
+ Search revisions of files for a regular expression.
+
+ This command behaves differently than Unix grep. It only accepts
+ Python/Perl regexps. It searches repository history, not the
+ working directory. It always prints the revision number in which a
+ match appears.
+
+ By default, grep only prints output for the first revision of a
+ file in which it finds a match. To get it to print every revision
+ that contains a change in match status ("-" for a match that
+ becomes a non-match, or "+" for a non-match that becomes a match),
+ use the --all flag.
+ """
+ reflags = 0
+ if opts.get('ignore_case'):
+ reflags |= re.I
+ try:
+ regexp = re.compile(pattern, reflags)
+ except Exception, inst:
+ ui.warn(_("grep: invalid match pattern: %s\n") % inst)
+ return None
+ sep, eol = ':', '\n'
+ if opts.get('print0'):
+ sep = eol = '\0'
+
+ getfile = util.lrucachefunc(repo.file)
+
+ def matchlines(body):
+ begin = 0
+ linenum = 0
+ while True:
+ match = regexp.search(body, begin)
+ if not match:
+ break
+ mstart, mend = match.span()
+ linenum += body.count('\n', begin, mstart) + 1
+ lstart = body.rfind('\n', begin, mstart) + 1 or begin
+ begin = body.find('\n', mend) + 1 or len(body)
+ lend = begin - 1
+ yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
+
+ class linestate(object):
+ def __init__(self, line, linenum, colstart, colend):
+ self.line = line
+ self.linenum = linenum
+ self.colstart = colstart
+ self.colend = colend
+
+ def __hash__(self):
+ return hash((self.linenum, self.line))
+
+ def __eq__(self, other):
+ return self.line == other.line
+
+ matches = {}
+ copies = {}
+ def grepbody(fn, rev, body):
+ matches[rev].setdefault(fn, [])
+ m = matches[rev][fn]
+ for lnum, cstart, cend, line in matchlines(body):
+ s = linestate(line, lnum, cstart, cend)
+ m.append(s)
+
+ def difflinestates(a, b):
+ sm = difflib.SequenceMatcher(None, a, b)
+ for tag, alo, ahi, blo, bhi in sm.get_opcodes():
+ if tag == 'insert':
+ for i in xrange(blo, bhi):
+ yield ('+', b[i])
+ elif tag == 'delete':
+ for i in xrange(alo, ahi):
+ yield ('-', a[i])
+ elif tag == 'replace':
+ for i in xrange(alo, ahi):
+ yield ('-', a[i])
+ for i in xrange(blo, bhi):
+ yield ('+', b[i])
+
+ def display(fn, r, pstates, states):
+ datefunc = ui.quiet and util.shortdate or util.datestr
+ found = False
+ filerevmatches = {}
+ if opts.get('all'):
+ iter = difflinestates(pstates, states)
+ else:
+ iter = [('', l) for l in states]
+ for change, l in iter:
+ cols = [fn, str(r)]
+ if opts.get('line_number'):
+ cols.append(str(l.linenum))
+ if opts.get('all'):
+ cols.append(change)
+ if opts.get('user'):
+ cols.append(ui.shortuser(get(r)[1]))
+ if opts.get('date'):
+ cols.append(datefunc(get(r)[2]))
+ if opts.get('files_with_matches'):
+ c = (fn, r)
+ if c in filerevmatches:
+ continue
+ filerevmatches[c] = 1
+ else:
+ cols.append(l.line)
+ ui.write(sep.join(cols), eol)
+ found = True
+ return found
+
+ skip = {}
+ revfiles = {}
+ get = util.cachefunc(lambda r: repo[r].changeset())
+ changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
+ found = False
+ follow = opts.get('follow')
+ for st, rev, fns in changeiter:
+ if st == 'window':
+ matches.clear()
+ revfiles.clear()
+ elif st == 'add':
+ ctx = repo[rev]
+ pctx = ctx.parents()[0]
+ parent = pctx.rev()
+ matches.setdefault(rev, {})
+ matches.setdefault(parent, {})
+ files = revfiles.setdefault(rev, [])
+ for fn in fns:
+ flog = getfile(fn)
+ try:
+ fnode = ctx.filenode(fn)
+ except error.LookupError:
+ continue
+
+ copied = flog.renamed(fnode)
+ copy = follow and copied and copied[0]
+ if copy:
+ copies.setdefault(rev, {})[fn] = copy
+ if fn in skip:
+ if copy:
+ skip[copy] = True
+ continue
+ files.append(fn)
+
+ if not matches[rev].has_key(fn):
+ grepbody(fn, rev, flog.read(fnode))
+
+ pfn = copy or fn
+ if not matches[parent].has_key(pfn):
+ try:
+ fnode = pctx.filenode(pfn)
+ grepbody(pfn, parent, flog.read(fnode))
+ except error.LookupError:
+ pass
+ elif st == 'iter':
+ parent = repo[rev].parents()[0].rev()
+ for fn in sorted(revfiles.get(rev, [])):
+ states = matches[rev][fn]
+ copy = copies.get(rev, {}).get(fn)
+ if fn in skip:
+ if copy:
+ skip[copy] = True
+ continue
+ pstates = matches.get(parent, {}).get(copy or fn, [])
+ if pstates or states:
+ r = display(fn, rev, pstates, states)
+ found = found or r
+ if r and not opts.get('all'):
+ skip[fn] = True
+ if copy:
+ skip[copy] = True
+
+def heads(ui, repo, *branchrevs, **opts):
+ """show current repository heads or show branch heads
+
+ With no arguments, show all repository head changesets.
+
+ Repository "heads" are changesets that don't have child
+ changesets. They are where development generally takes place and
+ are the usual targets for update and merge operations.
+
+ If one or more REV is given, the "branch heads" will be shown for
+ the named branch associated with that revision. The name of the
+ branch is called the revision's branch tag.
+
+ Branch heads are revisions on a given named branch that do not have
+ any descendants on the same branch. A branch head could be a true head
+ or it could be the last changeset on a branch before a new branch
+ was created. If none of the branch heads are true heads, the branch
+ is considered inactive. If -c/--closed is specified, also show branch
+ heads marked closed (see hg commit --close-branch).
+
+ If STARTREV is specified only those heads (or branch heads) that
+ are descendants of STARTREV will be displayed.
+ """
+ if opts.get('rev'):
+ start = repo.lookup(opts['rev'])
+ else:
+ start = None
+ closed = opts.get('closed')
+ hideinactive, _heads = opts.get('active'), None
+ if not branchrevs:
+ if closed:
+ raise error.Abort(_('you must specify a branch to use --closed'))
+ # Assume we're looking repo-wide heads if no revs were specified.
+ heads = repo.heads(start)
+ else:
+ if hideinactive:
+ _heads = repo.heads(start)
+ heads = []
+ visitedset = set()
+ for branchrev in branchrevs:
+ branch = repo[branchrev].branch()
+ if branch in visitedset:
+ continue
+ visitedset.add(branch)
+ bheads = repo.branchheads(branch, start, closed=closed)
+ if not bheads:
+ if not opts.get('rev'):
+ ui.warn(_("no open branch heads on branch %s\n") % branch)
+ elif branch != branchrev:
+ ui.warn(_("no changes on branch %s containing %s are "
+ "reachable from %s\n")
+ % (branch, branchrev, opts.get('rev')))
+ else:
+ ui.warn(_("no changes on branch %s are reachable from %s\n")
+ % (branch, opts.get('rev')))
+ if hideinactive:
+ bheads = [bhead for bhead in bheads if bhead in _heads]
+ heads.extend(bheads)
+ if not heads:
+ return 1
+ displayer = cmdutil.show_changeset(ui, repo, opts)
+ for n in heads:
+ displayer.show(repo[n])
+
+def help_(ui, name=None, with_version=False):
+ """show help for a given topic or a help overview
+
+ With no arguments, print a list of commands with short help messages.
+
+ Given a topic, extension, or command name, print help for that
+ topic."""
+ option_lists = []
+ textwidth = util.termwidth() - 2
+
+ def addglobalopts(aliases):
+ if ui.verbose:
+ option_lists.append((_("global options:"), globalopts))
+ if name == 'shortlist':
+ option_lists.append((_('use "hg help" for the full list '
+ 'of commands'), ()))
+ else:
+ if name == 'shortlist':
+ msg = _('use "hg help" for the full list of commands '
+ 'or "hg -v" for details')
+ elif aliases:
+ msg = _('use "hg -v help%s" to show aliases and '
+ 'global options') % (name and " " + name or "")
+ else:
+ msg = _('use "hg -v help %s" to show global options') % name
+ option_lists.append((msg, ()))
+
+ def helpcmd(name):
+ if with_version:
+ version_(ui)
+ ui.write('\n')
+
+ try:
+ aliases, i = cmdutil.findcmd(name, table, False)
+ except error.AmbiguousCommand, inst:
+ # py3k fix: except vars can't be used outside the scope of the
+ # except block, nor can be used inside a lambda. python issue4617
+ prefix = inst.args[0]
+ select = lambda c: c.lstrip('^').startswith(prefix)
+ helplist(_('list of commands:\n\n'), select)
+ return
+
+ # synopsis
+ if len(i) > 2:
+ if i[2].startswith('hg'):
+ ui.write("%s\n" % i[2])
+ else:
+ ui.write('hg %s %s\n' % (aliases[0], i[2]))
+ else:
+ ui.write('hg %s\n' % aliases[0])
+
+ # aliases
+ if not ui.quiet and len(aliases) > 1:
+ ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
+
+ # description
+ doc = gettext(i[0].__doc__)
+ if not doc:
+ doc = _("(no help text available)")
+ if ui.quiet:
+ doc = doc.splitlines()[0]
+ ui.write("\n%s\n" % minirst.format(doc, textwidth))
+
+ if not ui.quiet:
+ # options
+ if i[1]:
+ option_lists.append((_("options:\n"), i[1]))
+
+ addglobalopts(False)
+
+ def helplist(header, select=None):
+ h = {}
+ cmds = {}
+ for c, e in table.iteritems():
+ f = c.split("|", 1)[0]
+ if select and not select(f):
+ continue
+ if (not select and name != 'shortlist' and
+ e[0].__module__ != __name__):
+ continue
+ if name == "shortlist" and not f.startswith("^"):
+ continue
+ f = f.lstrip("^")
+ if not ui.debugflag and f.startswith("debug"):
+ continue
+ doc = e[0].__doc__
+ if doc and 'DEPRECATED' in doc and not ui.verbose:
+ continue
+ doc = gettext(doc)
+ if not doc:
+ doc = _("(no help text available)")
+ h[f] = doc.splitlines()[0].rstrip()
+ cmds[f] = c.lstrip("^")
+
+ if not h:
+ ui.status(_('no commands defined\n'))
+ return
+
+ ui.status(header)
+ fns = sorted(h)
+ m = max(map(len, fns))
+ for f in fns:
+ if ui.verbose:
+ commands = cmds[f].replace("|",", ")
+ ui.write(" %s:\n %s\n"%(commands, h[f]))
+ else:
+ ui.write(' %-*s %s\n' % (m, f, util.wrap(h[f], m + 4)))
+
+ if name != 'shortlist':
+ exts, maxlength = extensions.enabled()
+ text = help.listexts(_('enabled extensions:'), exts, maxlength)
+ if text:
+ ui.write("\n%s\n" % minirst.format(text, textwidth))
+
+ if not ui.quiet:
+ addglobalopts(True)
+
+ def helptopic(name):
+ for names, header, doc in help.helptable:
+ if name in names:
+ break
+ else:
+ raise error.UnknownCommand(name)
+
+ # description
+ if not doc:
+ doc = _("(no help text available)")
+ if hasattr(doc, '__call__'):
+ doc = doc()
+
+ ui.write("%s\n\n" % header)
+ ui.write("%s\n" % minirst.format(doc, textwidth))
+
+ def helpext(name):
+ try:
+ mod = extensions.find(name)
+ except KeyError:
+ raise error.UnknownCommand(name)
+
+ doc = gettext(mod.__doc__) or _('no help text available')
+ if '\n' not in doc:
+ head, tail = doc, ""
+ else:
+ head, tail = doc.split('\n', 1)
+ ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
+ if tail:
+ ui.write(minirst.format(tail, textwidth))
+ ui.status('\n\n')
+
+ try:
+ ct = mod.cmdtable
+ except AttributeError:
+ ct = {}
+
+ modcmds = set([c.split('|', 1)[0] for c in ct])
+ helplist(_('list of commands:\n\n'), modcmds.__contains__)
+
+ if name and name != 'shortlist':
+ i = None
+ for f in (helptopic, helpcmd, helpext):
+ try:
+ f(name)
+ i = None
+ break
+ except error.UnknownCommand, inst:
+ i = inst
+ if i:
+ raise i
+
+ else:
+ # program name
+ if ui.verbose or with_version:
+ version_(ui)
+ else:
+ ui.status(_("Mercurial Distributed SCM\n"))
+ ui.status('\n')
+
+ # list of commands
+ if name == "shortlist":
+ header = _('basic commands:\n\n')
+ else:
+ header = _('list of commands:\n\n')
+
+ helplist(header)
+
+ # list all option lists
+ opt_output = []
+ for title, options in option_lists:
+ opt_output.append(("\n%s" % title, None))
+ for shortopt, longopt, default, desc in options:
+ if "DEPRECATED" in desc and not ui.verbose: continue
+ opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
+ longopt and " --%s" % longopt),
+ "%s%s" % (desc,
+ default
+ and _(" (default: %s)") % default
+ or "")))
+
+ if not name:
+ ui.write(_("\nadditional help topics:\n\n"))
+ topics = []
+ for names, header, doc in help.helptable:
+ names = [(-len(name), name) for name in names]
+ names.sort()
+ topics.append((names[0][1], header))
+ topics_len = max([len(s[0]) for s in topics])
+ for t, desc in topics:
+ ui.write(" %-*s %s\n" % (topics_len, t, desc))
+
+ if opt_output:
+ opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
+ for first, second in opt_output:
+ if second:
+ second = util.wrap(second, opts_len + 3)
+ ui.write(" %-*s %s\n" % (opts_len, first, second))
+ else:
+ ui.write("%s\n" % first)
+
+def identify(ui, repo, source=None,
+ rev=None, num=None, id=None, branch=None, tags=None):
+ """identify the working copy or specified revision
+
+ With no revision, print a summary of the current state of the
+ repository.
+
+ Specifying a path to a repository root or Mercurial bundle will
+ cause lookup to operate on that repository/bundle.
+
+ This summary identifies the repository state using one or two
+ parent hash identifiers, followed by a "+" if there are
+ uncommitted changes in the working directory, a list of tags for
+ this revision and a branch name for non-default branches.
+ """
+
+ if not repo and not source:
+ raise util.Abort(_("There is no Mercurial repository here "
+ "(.hg not found)"))
+
+ hexfunc = ui.debugflag and hex or short
+ default = not (num or id or branch or tags)
+ output = []
+
+ revs = []
+ if source:
+ source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
+ repo = hg.repository(ui, source)
+
+ if not repo.local():
+ if not rev and revs:
+ rev = revs[0]
+ if not rev:
+ rev = "tip"
+ if num or branch or tags:
+ raise util.Abort(
+ "can't query remote revision number, branch, or tags")
+ output = [hexfunc(repo.lookup(rev))]
+ elif not rev:
+ ctx = repo[None]
+ parents = ctx.parents()
+ changed = False
+ if default or id or num:
+ changed = ctx.files() + ctx.deleted()
+ if default or id:
+ output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
+ (changed) and "+" or "")]
+ if num:
+ output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
+ (changed) and "+" or ""))
+ else:
+ ctx = repo[rev]
+ if default or id:
+ output = [hexfunc(ctx.node())]
+ if num:
+ output.append(str(ctx.rev()))
+
+ if repo.local() and default and not ui.quiet:
+ b = encoding.tolocal(ctx.branch())
+ if b != 'default':
+ output.append("(%s)" % b)
+
+ # multiple tags for a single parent separated by '/'
+ t = "/".join(ctx.tags())
+ if t:
+ output.append(t)
+
+ if branch:
+ output.append(encoding.tolocal(ctx.branch()))
+
+ if tags:
+ output.extend(ctx.tags())
+
+ ui.write("%s\n" % ' '.join(output))
+
+def import_(ui, repo, patch1, *patches, **opts):
+ """import an ordered set of patches
+
+ Import a list of patches and commit them individually.
+
+ If there are outstanding changes in the working directory, import
+ will abort unless given the -f/--force flag.
+
+ You can import a patch straight from a mail message. Even patches
+ as attachments work (to use the body part, it must have type
+ text/plain or text/x-patch). From and Subject headers of email
+ message are used as default committer and commit message. All
+ text/plain body parts before first diff are added to commit
+ message.
+
+ If the imported patch was generated by hg export, user and
+ description from patch override values from message headers and
+ body. Values given on command line with -m/--message and -u/--user
+ override these.
+
+ If --exact is specified, import will set the working directory to
+ the parent of each patch before applying it, and will abort if the
+ resulting changeset has a different ID than the one recorded in
+ the patch. This may happen due to character set problems or other
+ deficiencies in the text patch format.
+
+ With -s/--similarity, hg will attempt to discover renames and
+ copies in the patch in the same way as 'addremove'.
+
+ To read a patch from standard input, use "-" as the patch name. If
+ a URL is specified, the patch will be downloaded from it.
+ See 'hg help dates' for a list of formats valid for -d/--date.
+ """
+ patches = (patch1,) + patches
+
+ date = opts.get('date')
+ if date:
+ opts['date'] = util.parsedate(date)
+
+ try:
+ sim = float(opts.get('similarity') or 0)
+ except ValueError:
+ raise util.Abort(_('similarity must be a number'))
+ if sim < 0 or sim > 100:
+ raise util.Abort(_('similarity must be between 0 and 100'))
+
+ if opts.get('exact') or not opts.get('force'):
+ cmdutil.bail_if_changed(repo)
+
+ d = opts["base"]
+ strip = opts["strip"]
+ wlock = lock = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ for p in patches:
+ pf = os.path.join(d, p)
+
+ if pf == '-':
+ ui.status(_("applying patch from stdin\n"))
+ pf = sys.stdin
+ else:
+ ui.status(_("applying %s\n") % p)
+ pf = url.open(ui, pf)
+ data = patch.extract(ui, pf)
+ tmpname, message, user, date, branch, nodeid, p1, p2 = data
+
+ if tmpname is None:
+ raise util.Abort(_('no diffs found'))
+
+ try:
+ cmdline_message = cmdutil.logmessage(opts)
+ if cmdline_message:
+ # pickup the cmdline msg
+ message = cmdline_message
+ elif message:
+ # pickup the patch msg
+ message = message.strip()
+ else:
+ # launch the editor
+ message = None
+ ui.debug(_('message:\n%s\n') % message)
+
+ wp = repo.parents()
+ if opts.get('exact'):
+ if not nodeid or not p1:
+ raise util.Abort(_('not a Mercurial patch'))
+ p1 = repo.lookup(p1)
+ p2 = repo.lookup(p2 or hex(nullid))
+
+ if p1 != wp[0].node():
+ hg.clean(repo, p1)
+ repo.dirstate.setparents(p1, p2)
+ elif p2:
+ try:
+ p1 = repo.lookup(p1)
+ p2 = repo.lookup(p2)
+ if p1 == wp[0].node():
+ repo.dirstate.setparents(p1, p2)
+ except error.RepoError:
+ pass
+ if opts.get('exact') or opts.get('import_branch'):
+ repo.dirstate.setbranch(branch or 'default')
+
+ files = {}
+ try:
+ patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
+ files=files, eolmode=None)
+ finally:
+ files = patch.updatedir(ui, repo, files, similarity=sim/100.)
+ if not opts.get('no_commit'):
+ m = cmdutil.matchfiles(repo, files or [])
+ n = repo.commit(message, opts.get('user') or user,
+ opts.get('date') or date, match=m,
+ editor=cmdutil.commiteditor)
+ if opts.get('exact'):
+ if hex(n) != nodeid:
+ repo.rollback()
+ raise util.Abort(_('patch is damaged'
+ ' or loses information'))
+ # Force a dirstate write so that the next transaction
+ # backups an up-do-date file.
+ repo.dirstate.write()
+ finally:
+ os.unlink(tmpname)
+ finally:
+ release(lock, wlock)
+
+def incoming(ui, repo, source="default", **opts):
+ """show new changesets found in source
+
+ Show new changesets found in the specified path/URL or the default
+ pull location. These are the changesets that would have been pulled
+ if a pull at the time you issued this command.
+
+ For remote repository, using --bundle avoids downloading the
+ changesets twice if the incoming is followed by a pull.
+
+ See pull for valid source format details.
+ """
+ limit = cmdutil.loglimit(opts)
+ source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
+ other = hg.repository(cmdutil.remoteui(repo, opts), source)
+ ui.status(_('comparing with %s\n') % url.hidepassword(source))
+ if revs:
+ revs = [other.lookup(rev) for rev in revs]
+ common, incoming, rheads = repo.findcommonincoming(other, heads=revs,
+ force=opts["force"])
+ if not incoming:
+ try:
+ os.unlink(opts["bundle"])
+ except:
+ pass
+ ui.status(_("no changes found\n"))
+ return 1
+
+ cleanup = None
+ try:
+ fname = opts["bundle"]
+ if fname or not other.local():
+ # create a bundle (uncompressed if other repo is not local)
+
+ if revs is None and other.capable('changegroupsubset'):
+ revs = rheads
+
+ if revs is None:
+ cg = other.changegroup(incoming, "incoming")
+ else:
+ cg = other.changegroupsubset(incoming, revs, 'incoming')
+ bundletype = other.local() and "HG10BZ" or "HG10UN"
+ fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
+ # keep written bundle?
+ if opts["bundle"]:
+ cleanup = None
+ if not other.local():
+ # use the created uncompressed bundlerepo
+ other = bundlerepo.bundlerepository(ui, repo.root, fname)
+
+ o = other.changelog.nodesbetween(incoming, revs)[0]
+ if opts.get('newest_first'):
+ o.reverse()
+ displayer = cmdutil.show_changeset(ui, other, opts)
+ count = 0
+ for n in o:
+ if count >= limit:
+ break
+ parents = [p for p in other.changelog.parents(n) if p != nullid]
+ if opts.get('no_merges') and len(parents) == 2:
+ continue
+ count += 1
+ displayer.show(other[n])
+ finally:
+ if hasattr(other, 'close'):
+ other.close()
+ if cleanup:
+ os.unlink(cleanup)
+
+def init(ui, dest=".", **opts):
+ """create a new repository in the given directory
+
+ Initialize a new repository in the given directory. If the given
+ directory does not exist, it will be created.
+
+ If no directory is given, the current directory is used.
+
+ It is possible to specify an ssh:// URL as the destination.
+ See 'hg help urls' for more information.
+ """
+ hg.repository(cmdutil.remoteui(ui, opts), dest, create=1)
+
+def locate(ui, repo, *pats, **opts):
+ """locate files matching specific patterns
+
+ Print files under Mercurial control in the working directory whose
+ names match the given patterns.
+
+ By default, this command searches all directories in the working
+ directory. To search just the current directory and its
+ subdirectories, use "--include .".
+
+ If no patterns are given to match, this command prints the names
+ of all files under Mercurial control in the working directory.
+
+ If you want to feed the output of this command into the "xargs"
+ command, use the -0 option to both this command and "xargs". This
+ will avoid the problem of "xargs" treating single filenames that
+ contain whitespace as multiple filenames.
+ """
+ end = opts.get('print0') and '\0' or '\n'
+ rev = opts.get('rev') or None
+
+ ret = 1
+ m = cmdutil.match(repo, pats, opts, default='relglob')
+ m.bad = lambda x,y: False
+ for abs in repo[rev].walk(m):
+ if not rev and abs not in repo.dirstate:
+ continue
+ if opts.get('fullpath'):
+ ui.write(repo.wjoin(abs), end)
+ else:
+ ui.write(((pats and m.rel(abs)) or abs), end)
+ ret = 0
+
+ return ret
+
+def log(ui, repo, *pats, **opts):
+ """show revision history of entire repository or files
+
+ Print the revision history of the specified files or the entire
+ project.
+
+ File history is shown without following rename or copy history of
+ files. Use -f/--follow with a filename to follow history across
+ renames and copies. --follow without a filename will only show
+ ancestors or descendants of the starting revision. --follow-first
+ only follows the first parent of merge revisions.
+
+ If no revision range is specified, the default is tip:0 unless
+ --follow is set, in which case the working directory parent is
+ used as the starting revision.
+
+ See 'hg help dates' for a list of formats valid for -d/--date.
+
+ By default this command prints revision number and changeset id,
+ tags, non-trivial parents, user, date and time, and a summary for
+ each commit. When the -v/--verbose switch is used, the list of
+ changed files and full commit message are shown.
+
+ NOTE: log -p/--patch may generate unexpected diff output for merge
+ changesets, as it will only compare the merge changeset against
+ its first parent. Also, only files different from BOTH parents
+ will appear in files:.
+ """
+
+ get = util.cachefunc(lambda r: repo[r].changeset())
+ changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
+
+ limit = cmdutil.loglimit(opts)
+ count = 0
+
+ if opts.get('copies') and opts.get('rev'):
+ endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
+ else:
+ endrev = len(repo)
+ rcache = {}
+ ncache = {}
+ def getrenamed(fn, rev):
+ '''looks up all renames for a file (up to endrev) the first
+ time the file is given. It indexes on the changerev and only
+ parses the manifest if linkrev != changerev.
+ Returns rename info for fn at changerev rev.'''
+ if fn not in rcache:
+ rcache[fn] = {}
+ ncache[fn] = {}
+ fl = repo.file(fn)
+ for i in fl:
+ node = fl.node(i)
+ lr = fl.linkrev(i)
+ renamed = fl.renamed(node)
+ rcache[fn][lr] = renamed
+ if renamed:
+ ncache[fn][node] = renamed
+ if lr >= endrev:
+ break
+ if rev in rcache[fn]:
+ return rcache[fn][rev]
+
+ # If linkrev != rev (i.e. rev not found in rcache) fallback to
+ # filectx logic.
+
+ try:
+ return repo[rev][fn].renamed()
+ except error.LookupError:
+ pass
+ return None
+
+ df = False
+ if opts["date"]:
+ df = util.matchdate(opts["date"])
+
+ only_branches = opts.get('only_branch')
+
+ displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
+ for st, rev, fns in changeiter:
+ if st == 'add':
+ parents = [p for p in repo.changelog.parentrevs(rev)
+ if p != nullrev]
+ if opts.get('no_merges') and len(parents) == 2:
+ continue
+ if opts.get('only_merges') and len(parents) != 2:
+ continue
+
+ if only_branches:
+ revbranch = get(rev)[5]['branch']
+ if revbranch not in only_branches:
+ continue
+
+ if df:
+ changes = get(rev)
+ if not df(changes[2][0]):
+ continue
+
+ if opts.get('keyword'):
+ changes = get(rev)
+ miss = 0
+ for k in [kw.lower() for kw in opts['keyword']]:
+ if not (k in changes[1].lower() or
+ k in changes[4].lower() or
+ k in " ".join(changes[3]).lower()):
+ miss = 1
+ break
+ if miss:
+ continue
+
+ if opts['user']:
+ changes = get(rev)
+ if not [k for k in opts['user'] if k in changes[1]]:
+ continue
+
+ copies = []
+ if opts.get('copies') and rev:
+ for fn in get(rev)[3]:
+ rename = getrenamed(fn, rev)
+ if rename:
+ copies.append((fn, rename[0]))
+ displayer.show(context.changectx(repo, rev), copies=copies)
+ elif st == 'iter':
+ if count == limit: break
+ if displayer.flush(rev):
+ count += 1
+
+def manifest(ui, repo, node=None, rev=None):
+ """output the current or given revision of the project manifest
+
+ Print a list of version controlled files for the given revision.
+ If no revision is given, the first parent of the working directory
+ is used, or the null revision if no revision is checked out.
+
+ With -v, print file permissions, symlink and executable bits.
+ With --debug, print file revision hashes.
+ """
+
+ if rev and node:
+ raise util.Abort(_("please specify just one revision"))
+
+ if not node:
+ node = rev
+
+ decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
+ ctx = repo[node]
+ for f in ctx:
+ if ui.debugflag:
+ ui.write("%40s " % hex(ctx.manifest()[f]))
+ if ui.verbose:
+ ui.write(decor[ctx.flags(f)])
+ ui.write("%s\n" % f)
+
+def merge(ui, repo, node=None, **opts):
+ """merge working directory with another revision
+
+ The current working directory is updated with all changes made in
+ the requested revision since the last common predecessor revision.
+
+ Files that changed between either parent are marked as changed for
+ the next commit and a commit must be performed before any further
+ updates to the repository are allowed. The next commit will have
+ two parents.
+
+ If no revision is specified, the working directory's parent is a
+ head revision, and the current branch contains exactly one other
+ head, the other head is merged with by default. Otherwise, an
+ explicit revision with which to merge with must be provided.
+ """
+
+ if opts.get('rev') and node:
+ raise util.Abort(_("please specify just one revision"))
+ if not node:
+ node = opts.get('rev')
+
+ if not node:
+ branch = repo.changectx(None).branch()
+ bheads = repo.branchheads(branch)
+ if len(bheads) > 2:
+ raise util.Abort(_("branch '%s' has %d heads - "
+ "please merge with an explicit rev") %
+ (branch, len(bheads)))
+
+ parent = repo.dirstate.parents()[0]
+ if len(bheads) == 1:
+ if len(repo.heads()) > 1:
+ raise util.Abort(_("branch '%s' has one head - "
+ "please merge with an explicit rev") %
+ branch)
+ msg = _('there is nothing to merge')
+ if parent != repo.lookup(repo[None].branch()):
+ msg = _('%s - use "hg update" instead') % msg
+ raise util.Abort(msg)
+
+ if parent not in bheads:
+ raise util.Abort(_('working dir not at a head rev - '
+ 'use "hg update" or merge with an explicit rev'))
+ node = parent == bheads[0] and bheads[-1] or bheads[0]
+
+ if opts.get('preview'):
+ p1 = repo['.']
+ p2 = repo[node]
+ common = p1.ancestor(p2)
+ roots, heads = [common.node()], [p2.node()]
+ displayer = cmdutil.show_changeset(ui, repo, opts)
+ for node in repo.changelog.nodesbetween(roots=roots, heads=heads)[0]:
+ displayer.show(repo[node])
+ return 0
+
+ return hg.merge(repo, node, force=opts.get('force'))
+
+def outgoing(ui, repo, dest=None, **opts):
+ """show changesets not found in destination
+
+ Show changesets not found in the specified destination repository
+ or the default push location. These are the changesets that would
+ be pushed if a push was requested.
+
+ See pull for valid destination format details.
+ """
+ limit = cmdutil.loglimit(opts)
+ dest, revs, checkout = hg.parseurl(
+ ui.expandpath(dest or 'default-push', dest or 'default'), opts.get('rev'))
+ if revs:
+ revs = [repo.lookup(rev) for rev in revs]
+
+ other = hg.repository(cmdutil.remoteui(repo, opts), dest)
+ ui.status(_('comparing with %s\n') % url.hidepassword(dest))
+ o = repo.findoutgoing(other, force=opts.get('force'))
+ if not o:
+ ui.status(_("no changes found\n"))
+ return 1
+ o = repo.changelog.nodesbetween(o, revs)[0]
+ if opts.get('newest_first'):
+ o.reverse()
+ displayer = cmdutil.show_changeset(ui, repo, opts)
+ count = 0
+ for n in o:
+ if count >= limit:
+ break
+ parents = [p for p in repo.changelog.parents(n) if p != nullid]
+ if opts.get('no_merges') and len(parents) == 2:
+ continue
+ count += 1
+ displayer.show(repo[n])
+
+def parents(ui, repo, file_=None, **opts):
+ """show the parents of the working directory or revision
+
+ Print the working directory's parent revisions. If a revision is
+ given via -r/--rev, the parent of that revision will be printed.
+ If a file argument is given, the revision in which the file was
+ last changed (before the working directory revision or the
+ argument to --rev if given) is printed.
+ """
+ rev = opts.get('rev')
+ if rev:
+ ctx = repo[rev]
+ else:
+ ctx = repo[None]
+
+ if file_:
+ m = cmdutil.match(repo, (file_,), opts)
+ if m.anypats() or len(m.files()) != 1:
+ raise util.Abort(_('can only specify an explicit filename'))
+ file_ = m.files()[0]
+ filenodes = []
+ for cp in ctx.parents():
+ if not cp:
+ continue
+ try:
+ filenodes.append(cp.filenode(file_))
+ except error.LookupError:
+ pass
+ if not filenodes:
+ raise util.Abort(_("'%s' not found in manifest!") % file_)
+ fl = repo.file(file_)
+ p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
+ else:
+ p = [cp.node() for cp in ctx.parents()]
+
+ displayer = cmdutil.show_changeset(ui, repo, opts)
+ for n in p:
+ if n != nullid:
+ displayer.show(repo[n])
+
+def paths(ui, repo, search=None):
+ """show aliases for remote repositories
+
+ Show definition of symbolic path name NAME. If no name is given,
+ show definition of all available names.
+
+ Path names are defined in the [paths] section of /etc/mercurial/hgrc
+ and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
+
+ See 'hg help urls' for more information.
+ """
+ if search:
+ for name, path in ui.configitems("paths"):
+ if name == search:
+ ui.write("%s\n" % url.hidepassword(path))
+ return
+ ui.warn(_("not found!\n"))
+ return 1
+ else:
+ for name, path in ui.configitems("paths"):
+ ui.write("%s = %s\n" % (name, url.hidepassword(path)))
+
+def postincoming(ui, repo, modheads, optupdate, checkout):
+ if modheads == 0:
+ return
+ if optupdate:
+ if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
+ return hg.update(repo, checkout)
+ else:
+ ui.status(_("not updating, since new heads added\n"))
+ if modheads > 1:
+ ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
+ else:
+ ui.status(_("(run 'hg update' to get a working copy)\n"))
+
+def pull(ui, repo, source="default", **opts):
+ """pull changes from the specified source
+
+ Pull changes from a remote repository to a local one.
+
+ This finds all changes from the repository at the specified path
+ or URL and adds them to a local repository (the current one unless
+ -R is specified). By default, this does not update the copy of the
+ project in the working directory.
+
+ Use hg incoming if you want to see what would have been added by a
+ pull at the time you issued this command. If you then decide to
+ added those changes to the repository, you should use pull -r X
+ where X is the last changeset listed by hg incoming.
+
+ If SOURCE is omitted, the 'default' path will be used.
+ See 'hg help urls' for more information.
+ """
+ source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
+ other = hg.repository(cmdutil.remoteui(repo, opts), source)
+ ui.status(_('pulling from %s\n') % url.hidepassword(source))
+ if revs:
+ try:
+ revs = [other.lookup(rev) for rev in revs]
+ except error.CapabilityError:
+ err = _("Other repository doesn't support revision lookup, "
+ "so a rev cannot be specified.")
+ raise util.Abort(err)
+
+ modheads = repo.pull(other, heads=revs, force=opts.get('force'))
+ return postincoming(ui, repo, modheads, opts.get('update'), checkout)
+
+def push(ui, repo, dest=None, **opts):
+ """push changes to the specified destination
+
+ Push changes from the local repository to the given destination.
+
+ This is the symmetrical operation for pull. It moves changes from
+ the current repository to a different one. If the destination is
+ local this is identical to a pull in that directory from the
+ current one.
+
+ By default, push will refuse to run if it detects the result would
+ increase the number of remote heads. This generally indicates the
+ user forgot to pull and merge before pushing.
+
+ If -r/--rev is used, the named revision and all its ancestors will
+ be pushed to the remote repository.
+
+ Please see 'hg help urls' for important details about ssh://
+ URLs. If DESTINATION is omitted, a default path will be used.
+ """
+ dest, revs, checkout = hg.parseurl(
+ ui.expandpath(dest or 'default-push', dest or 'default'), opts.get('rev'))
+ other = hg.repository(cmdutil.remoteui(repo, opts), dest)
+ ui.status(_('pushing to %s\n') % url.hidepassword(dest))
+ if revs:
+ revs = [repo.lookup(rev) for rev in revs]
+
+ # push subrepos depth-first for coherent ordering
+ c = repo['']
+ subs = c.substate # only repos that are committed
+ for s in sorted(subs):
+ c.sub(s).push(opts.get('force'))
+
+ r = repo.push(other, opts.get('force'), revs=revs)
+ return r == 0
+
+def recover(ui, repo):
+ """roll back an interrupted transaction
+
+ Recover from an interrupted commit or pull.
+
+ This command tries to fix the repository status after an
+ interrupted operation. It should only be necessary when Mercurial
+ suggests it.
+ """
+ if repo.recover():
+ return hg.verify(repo)
+ return 1
+
+def remove(ui, repo, *pats, **opts):
+ """remove the specified files on the next commit
+
+ Schedule the indicated files for removal from the repository.
+
+ This only removes files from the current branch, not from the
+ entire project history. -A/--after can be used to remove only
+ files that have already been deleted, -f/--force can be used to
+ force deletion, and -Af can be used to remove files from the next
+ revision without deleting them from the working directory.
+
+ The following table details the behavior of remove for different
+ file states (columns) and option combinations (rows). The file
+ states are Added [A], Clean [C], Modified [M] and Missing [!] (as
+ reported by hg status). The actions are Warn, Remove (from branch)
+ and Delete (from disk)::
+
+ A C M !
+ none W RD W R
+ -f R RD RD R
+ -A W W W R
+ -Af R R R R
+
+ This command schedules the files to be removed at the next commit.
+ To undo a remove before that, see hg revert.
+ """
+
+ after, force = opts.get('after'), opts.get('force')
+ if not pats and not after:
+ raise util.Abort(_('no files specified'))
+
+ m = cmdutil.match(repo, pats, opts)
+ s = repo.status(match=m, clean=True)
+ modified, added, deleted, clean = s[0], s[1], s[3], s[6]
+
+ for f in m.files():
+ if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
+ ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
+
+ def warn(files, reason):
+ for f in files:
+ ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
+ % (m.rel(f), reason))
+
+ if force:
+ remove, forget = modified + deleted + clean, added
+ elif after:
+ remove, forget = deleted, []
+ warn(modified + added + clean, _('still exists'))
+ else:
+ remove, forget = deleted + clean, []
+ warn(modified, _('is modified'))
+ warn(added, _('has been marked for add'))
+
+ for f in sorted(remove + forget):
+ if ui.verbose or not m.exact(f):
+ ui.status(_('removing %s\n') % m.rel(f))
+
+ repo.forget(forget)
+ repo.remove(remove, unlink=not after)
+
+def rename(ui, repo, *pats, **opts):
+ """rename files; equivalent of copy + remove
+
+ Mark dest as copies of sources; mark sources for deletion. If dest
+ is a directory, copies are put in that directory. If dest is a
+ file, there can only be one source.
+
+ By default, this command copies the contents of files as they
+ exist in the working directory. If invoked with -A/--after, the
+ operation is recorded, but no copying is performed.
+
+ This command takes effect at the next commit. To undo a rename
+ before that, see hg revert.
+ """
+ wlock = repo.wlock(False)
+ try:
+ return cmdutil.copy(ui, repo, pats, opts, rename=True)
+ finally:
+ wlock.release()
+
+def resolve(ui, repo, *pats, **opts):
+ """retry file merges from a merge or update
+
+ This command will cleanly retry unresolved file merges using file
+ revisions preserved from the last update or merge. To attempt to
+ resolve all unresolved files, use the -a/--all switch.
+
+ If a conflict is resolved manually, please note that the changes
+ will be overwritten if the merge is retried with resolve. The
+ -m/--mark switch should be used to mark the file as resolved.
+
+ This command also allows listing resolved files and manually
+ indicating whether or not files are resolved. All files must be
+ marked as resolved before a commit is permitted.
+
+ The codes used to show the status of files are::
+
+ U = unresolved
+ R = resolved
+ """
+
+ all, mark, unmark, show = [opts.get(o) for o in 'all mark unmark list'.split()]
+
+ if (show and (mark or unmark)) or (mark and unmark):
+ raise util.Abort(_("too many options specified"))
+ if pats and all:
+ raise util.Abort(_("can't specify --all and patterns"))
+ if not (all or pats or show or mark or unmark):
+ raise util.Abort(_('no files or directories specified; '
+ 'use --all to remerge all files'))
+
+ ms = merge_.mergestate(repo)
+ m = cmdutil.match(repo, pats, opts)
+
+ for f in ms:
+ if m(f):
+ if show:
+ ui.write("%s %s\n" % (ms[f].upper(), f))
+ elif mark:
+ ms.mark(f, "r")
+ elif unmark:
+ ms.mark(f, "u")
+ else:
+ wctx = repo[None]
+ mctx = wctx.parents()[-1]
+
+ # backup pre-resolve (merge uses .orig for its own purposes)
+ a = repo.wjoin(f)
+ util.copyfile(a, a + ".resolve")
+
+ # resolve file
+ ms.resolve(f, wctx, mctx)
+
+ # replace filemerge's .orig file with our resolve file
+ util.rename(a + ".resolve", a + ".orig")
+
+def revert(ui, repo, *pats, **opts):
+ """restore individual files or directories to an earlier state
+
+ (Use update -r to check out earlier revisions, revert does not
+ change the working directory parents.)
+
+ With no revision specified, revert the named files or directories
+ to the contents they had in the parent of the working directory.
+ This restores the contents of the affected files to an unmodified
+ state and unschedules adds, removes, copies, and renames. If the
+ working directory has two parents, you must explicitly specify the
+ revision to revert to.
+
+ Using the -r/--rev option, revert the given files or directories
+ to their contents as of a specific revision. This can be helpful
+ to "roll back" some or all of an earlier change. See 'hg help
+ dates' for a list of formats valid for -d/--date.
+
+ Revert modifies the working directory. It does not commit any
+ changes, or change the parent of the working directory. If you
+ revert to a revision other than the parent of the working
+ directory, the reverted files will thus appear modified
+ afterwards.
+
+ If a file has been deleted, it is restored. If the executable mode
+ of a file was changed, it is reset.
+
+ If names are given, all files matching the names are reverted.
+ If no arguments are given, no files are reverted.
+
+ Modified files are saved with a .orig suffix before reverting.
+ To disable these backups, use --no-backup.
+ """
+
+ if opts["date"]:
+ if opts["rev"]:
+ raise util.Abort(_("you can't specify a revision and a date"))
+ opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
+
+ if not pats and not opts.get('all'):
+ raise util.Abort(_('no files or directories specified; '
+ 'use --all to revert the whole repo'))
+
+ parent, p2 = repo.dirstate.parents()
+ if not opts.get('rev') and p2 != nullid:
+ raise util.Abort(_('uncommitted merge - please provide a '
+ 'specific revision'))
+ ctx = repo[opts.get('rev')]
+ node = ctx.node()
+ mf = ctx.manifest()
+ if node == parent:
+ pmf = mf
+ else:
+ pmf = None
+
+ # need all matching names in dirstate and manifest of target rev,
+ # so have to walk both. do not print errors if files exist in one
+ # but not other.
+
+ names = {}
+
+ wlock = repo.wlock()
+ try:
+ # walk dirstate.
+
+ m = cmdutil.match(repo, pats, opts)
+ m.bad = lambda x,y: False
+ for abs in repo.walk(m):
+ names[abs] = m.rel(abs), m.exact(abs)
+
+ # walk target manifest.
+
+ def badfn(path, msg):
+ if path in names:
+ return
+ path_ = path + '/'
+ for f in names:
+ if f.startswith(path_):
+ return
+ ui.warn("%s: %s\n" % (m.rel(path), msg))
+
+ m = cmdutil.match(repo, pats, opts)
+ m.bad = badfn
+ for abs in repo[node].walk(m):
+ if abs not in names:
+ names[abs] = m.rel(abs), m.exact(abs)
+
+ m = cmdutil.matchfiles(repo, names)
+ changes = repo.status(match=m)[:4]
+ modified, added, removed, deleted = map(set, changes)
+
+ # if f is a rename, also revert the source
+ cwd = repo.getcwd()
+ for f in added:
+ src = repo.dirstate.copied(f)
+ if src and src not in names and repo.dirstate[src] == 'r':
+ removed.add(src)
+ names[src] = (repo.pathto(src, cwd), True)
+
+ def removeforget(abs):
+ if repo.dirstate[abs] == 'a':
+ return _('forgetting %s\n')
+ return _('removing %s\n')
+
+ revert = ([], _('reverting %s\n'))
+ add = ([], _('adding %s\n'))
+ remove = ([], removeforget)
+ undelete = ([], _('undeleting %s\n'))
+
+ disptable = (
+ # dispatch table:
+ # file state
+ # action if in target manifest
+ # action if not in target manifest
+ # make backup if in target manifest
+ # make backup if not in target manifest
+ (modified, revert, remove, True, True),
+ (added, revert, remove, True, False),
+ (removed, undelete, None, False, False),
+ (deleted, revert, remove, False, False),
+ )
+
+ for abs, (rel, exact) in sorted(names.items()):
+ mfentry = mf.get(abs)
+ target = repo.wjoin(abs)
+ def handle(xlist, dobackup):
+ xlist[0].append(abs)
+ if dobackup and not opts.get('no_backup') and util.lexists(target):
+ bakname = "%s.orig" % rel
+ ui.note(_('saving current version of %s as %s\n') %
+ (rel, bakname))
+ if not opts.get('dry_run'):
+ util.copyfile(target, bakname)
+ if ui.verbose or not exact:
+ msg = xlist[1]
+ if not isinstance(msg, basestring):
+ msg = msg(abs)
+ ui.status(msg % rel)
+ for table, hitlist, misslist, backuphit, backupmiss in disptable:
+ if abs not in table: continue
+ # file has changed in dirstate
+ if mfentry:
+ handle(hitlist, backuphit)
+ elif misslist is not None:
+ handle(misslist, backupmiss)
+ break
+ else:
+ if abs not in repo.dirstate:
+ if mfentry:
+ handle(add, True)
+ elif exact:
+ ui.warn(_('file not managed: %s\n') % rel)
+ continue
+ # file has not changed in dirstate
+ if node == parent:
+ if exact: ui.warn(_('no changes needed to %s\n') % rel)
+ continue
+ if pmf is None:
+ # only need parent manifest in this unlikely case,
+ # so do not read by default
+ pmf = repo[parent].manifest()
+ if abs in pmf:
+ if mfentry:
+ # if version of file is same in parent and target
+ # manifests, do nothing
+ if (pmf[abs] != mfentry or
+ pmf.flags(abs) != mf.flags(abs)):
+ handle(revert, False)
+ else:
+ handle(remove, False)
+
+ if not opts.get('dry_run'):
+ def checkout(f):
+ fc = ctx[f]
+ repo.wwrite(f, fc.data(), fc.flags())
+
+ audit_path = util.path_auditor(repo.root)
+ for f in remove[0]:
+ if repo.dirstate[f] == 'a':
+ repo.dirstate.forget(f)
+ continue
+ audit_path(f)
+ try:
+ util.unlink(repo.wjoin(f))
+ except OSError:
+ pass
+ repo.dirstate.remove(f)
+
+ normal = None
+ if node == parent:
+ # We're reverting to our parent. If possible, we'd like status
+ # to report the file as clean. We have to use normallookup for
+ # merges to avoid losing information about merged/dirty files.
+ if p2 != nullid:
+ normal = repo.dirstate.normallookup
+ else:
+ normal = repo.dirstate.normal
+ for f in revert[0]:
+ checkout(f)
+ if normal:
+ normal(f)
+
+ for f in add[0]:
+ checkout(f)
+ repo.dirstate.add(f)
+
+ normal = repo.dirstate.normallookup
+ if node == parent and p2 == nullid:
+ normal = repo.dirstate.normal
+ for f in undelete[0]:
+ checkout(f)
+ normal(f)
+
+ finally:
+ wlock.release()
+
+def rollback(ui, repo):
+ """roll back the last transaction
+
+ This command should be used with care. There is only one level of
+ rollback, and there is no way to undo a rollback. It will also
+ restore the dirstate at the time of the last transaction, losing
+ any dirstate changes since that time. This command does not alter
+ the working directory.
+
+ Transactions are used to encapsulate the effects of all commands
+ that create new changesets or propagate existing changesets into a
+ repository. For example, the following commands are transactional,
+ and their effects can be rolled back::
+
+ commit
+ import
+ pull
+ push (with this repository as destination)
+ unbundle
+
+ This command is not intended for use on public repositories. Once
+ changes are visible for pull by other users, rolling a transaction
+ back locally is ineffective (someone else may already have pulled
+ the changes). Furthermore, a race is possible with readers of the
+ repository; for example an in-progress pull from the repository
+ may fail if a rollback is performed.
+ """
+ repo.rollback()
+
+def root(ui, repo):
+ """print the root (top) of the current working directory
+
+ Print the root directory of the current repository.
+ """
+ ui.write(repo.root + "\n")
+
+def serve(ui, repo, **opts):
+ """export the repository via HTTP
+
+ Start a local HTTP repository browser and pull server.
+
+ By default, the server logs accesses to stdout and errors to
+ stderr. Use the -A/--accesslog and -E/--errorlog options to log to
+ files.
+ """
+
+ if opts["stdio"]:
+ if repo is None:
+ raise error.RepoError(_("There is no Mercurial repository here"
+ " (.hg not found)"))
+ s = sshserver.sshserver(ui, repo)
+ s.serve_forever()
+
+ baseui = repo and repo.baseui or ui
+ optlist = ("name templates style address port prefix ipv6"
+ " accesslog errorlog webdir_conf certificate encoding")
+ for o in optlist.split():
+ if opts.get(o, None):
+ baseui.setconfig("web", o, str(opts[o]))
+ if (repo is not None) and (repo.ui != baseui):
+ repo.ui.setconfig("web", o, str(opts[o]))
+
+ if repo is None and not ui.config("web", "webdir_conf"):
+ raise error.RepoError(_("There is no Mercurial repository here"
+ " (.hg not found)"))
+
+ class service(object):
+ def init(self):
+ util.set_signal_handler()
+ self.httpd = server.create_server(baseui, repo)
+
+ if not ui.verbose: return
+
+ if self.httpd.prefix:
+ prefix = self.httpd.prefix.strip('/') + '/'
+ else:
+ prefix = ''
+
+ port = ':%d' % self.httpd.port
+ if port == ':80':
+ port = ''
+
+ bindaddr = self.httpd.addr
+ if bindaddr == '0.0.0.0':
+ bindaddr = '*'
+ elif ':' in bindaddr: # IPv6
+ bindaddr = '[%s]' % bindaddr
+
+ fqaddr = self.httpd.fqaddr
+ if ':' in fqaddr:
+ fqaddr = '[%s]' % fqaddr
+ ui.status(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
+ (fqaddr, port, prefix, bindaddr, self.httpd.port))
+
+ def run(self):
+ self.httpd.serve_forever()
+
+ service = service()
+
+ cmdutil.service(opts, initfn=service.init, runfn=service.run)
+
+def status(ui, repo, *pats, **opts):
+ """show changed files in the working directory
+
+ Show status of files in the repository. If names are given, only
+ files that match are shown. Files that are clean or ignored or
+ the source of a copy/move operation, are not listed unless
+ -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
+ Unless options described with "show only ..." are given, the
+ options -mardu are used.
+
+ Option -q/--quiet hides untracked (unknown and ignored) files
+ unless explicitly requested with -u/--unknown or -i/--ignored.
+
+ NOTE: status may appear to disagree with diff if permissions have
+ changed or a merge has occurred. The standard diff format does not
+ report permission changes and diff only reports changes relative
+ to one merge parent.
+
+ If one revision is given, it is used as the base revision.
+ If two revisions are given, the differences between them are
+ shown.
+
+ The codes used to show the status of files are::
+
+ M = modified
+ A = added
+ R = removed
+ C = clean
+ ! = missing (deleted by non-hg command, but still tracked)
+ ? = not tracked
+ I = ignored
+ = origin of the previous file listed as A (added)
+ """
+
+ node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
+ cwd = (pats and repo.getcwd()) or ''
+ end = opts.get('print0') and '\0' or '\n'
+ copy = {}
+ states = 'modified added removed deleted unknown ignored clean'.split()
+ show = [k for k in states if opts.get(k)]
+ if opts.get('all'):
+ show += ui.quiet and (states[:4] + ['clean']) or states
+ if not show:
+ show = ui.quiet and states[:4] or states[:5]
+
+ stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
+ 'ignored' in show, 'clean' in show, 'unknown' in show)
+ changestates = zip(states, 'MAR!?IC', stat)
+
+ if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
+ ctxn = repo[nullid]
+ ctx1 = repo[node1]
+ ctx2 = repo[node2]
+ added = stat[1]
+ if node2 is None:
+ added = stat[0] + stat[1] # merged?
+
+ for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
+ if k in added:
+ copy[k] = v
+ elif v in added:
+ copy[v] = k
+
+ for state, char, files in changestates:
+ if state in show:
+ format = "%s %%s%s" % (char, end)
+ if opts.get('no_status'):
+ format = "%%s%s" % end
+
+ for f in files:
+ ui.write(format % repo.pathto(f, cwd))
+ if f in copy:
+ ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end))
+
+def tag(ui, repo, name1, *names, **opts):
+ """add one or more tags for the current or given revision
+
+ Name a particular revision using <name>.
+
+ Tags are used to name particular revisions of the repository and are
+ very useful to compare different revisions, to go back to significant
+ earlier versions or to mark branch points as releases, etc.
+
+ If no revision is given, the parent of the working directory is
+ used, or tip if no revision is checked out.
+
+ To facilitate version control, distribution, and merging of tags,
+ they are stored as a file named ".hgtags" which is managed
+ similarly to other project files and can be hand-edited if
+ necessary. The file '.hg/localtags' is used for local tags (not
+ shared among repositories).
+
+ See 'hg help dates' for a list of formats valid for -d/--date.
+ """
+
+ rev_ = "."
+ names = (name1,) + names
+ if len(names) != len(set(names)):
+ raise util.Abort(_('tag names must be unique'))
+ for n in names:
+ if n in ['tip', '.', 'null']:
+ raise util.Abort(_('the name \'%s\' is reserved') % n)
+ if opts.get('rev') and opts.get('remove'):
+ raise util.Abort(_("--rev and --remove are incompatible"))
+ if opts.get('rev'):
+ rev_ = opts['rev']
+ message = opts.get('message')
+ if opts.get('remove'):
+ expectedtype = opts.get('local') and 'local' or 'global'
+ for n in names:
+ if not repo.tagtype(n):
+ raise util.Abort(_('tag \'%s\' does not exist') % n)
+ if repo.tagtype(n) != expectedtype:
+ if expectedtype == 'global':
+ raise util.Abort(_('tag \'%s\' is not a global tag') % n)
+ else:
+ raise util.Abort(_('tag \'%s\' is not a local tag') % n)
+ rev_ = nullid
+ if not message:
+ # we don't translate commit messages
+ message = 'Removed tag %s' % ', '.join(names)
+ elif not opts.get('force'):
+ for n in names:
+ if n in repo.tags():
+ raise util.Abort(_('tag \'%s\' already exists '
+ '(use -f to force)') % n)
+ if not rev_ and repo.dirstate.parents()[1] != nullid:
+ raise util.Abort(_('uncommitted merge - please provide a '
+ 'specific revision'))
+ r = repo[rev_].node()
+
+ if not message:
+ # we don't translate commit messages
+ message = ('Added tag %s for changeset %s' %
+ (', '.join(names), short(r)))
+
+ date = opts.get('date')
+ if date:
+ date = util.parsedate(date)
+
+ repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
+
+def tags(ui, repo):
+ """list repository tags
+
+ This lists both regular and local tags. When the -v/--verbose
+ switch is used, a third column "local" is printed for local tags.
+ """
+
+ hexfunc = ui.debugflag and hex or short
+ tagtype = ""
+
+ for t, n in reversed(repo.tagslist()):
+ if ui.quiet:
+ ui.write("%s\n" % t)
+ continue
+
+ try:
+ hn = hexfunc(n)
+ r = "%5d:%s" % (repo.changelog.rev(n), hn)
+ except error.LookupError:
+ r = " ?:%s" % hn
+ else:
+ spaces = " " * (30 - encoding.colwidth(t))
+ if ui.verbose:
+ if repo.tagtype(t) == 'local':
+ tagtype = " local"
+ else:
+ tagtype = ""
+ ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
+
+def tip(ui, repo, **opts):
+ """show the tip revision
+
+ The tip revision (usually just called the tip) is the changeset
+ most recently added to the repository (and therefore the most
+ recently changed head).
+
+ If you have just made a commit, that commit will be the tip. If
+ you have just pulled changes from another repository, the tip of
+ that repository becomes the current tip. The "tip" tag is special
+ and cannot be renamed or assigned to a different changeset.
+ """
+ cmdutil.show_changeset(ui, repo, opts).show(repo[len(repo) - 1])
+
+def unbundle(ui, repo, fname1, *fnames, **opts):
+ """apply one or more changegroup files
+
+ Apply one or more compressed changegroup files generated by the
+ bundle command.
+ """
+ fnames = (fname1,) + fnames
+
+ lock = repo.lock()
+ try:
+ for fname in fnames:
+ f = url.open(ui, fname)
+ gen = changegroup.readbundle(f, fname)
+ modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
+ finally:
+ lock.release()
+
+ return postincoming(ui, repo, modheads, opts.get('update'), None)
+
+def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
+ """update working directory
+
+ Update the repository's working directory to the specified
+ revision, or the tip of the current branch if none is specified.
+ Use null as the revision to remove the working copy (like 'hg
+ clone -U').
+
+ When the working directory contains no uncommitted changes, it
+ will be replaced by the state of the requested revision from the
+ repository. When the requested revision is on a different branch,
+ the working directory will additionally be switched to that
+ branch.
+
+ When there are uncommitted changes, use option -C/--clean to
+ discard them, forcibly replacing the state of the working
+ directory with the requested revision. Alternately, use -c/--check
+ to abort.
+
+ When there are uncommitted changes and option -C/--clean is not
+ used, and the parent revision and requested revision are on the
+ same branch, and one of them is an ancestor of the other, then the
+ new working directory will contain the requested revision merged
+ with the uncommitted changes. Otherwise, the update will fail with
+ a suggestion to use 'merge' or 'update -C' instead.
+
+ If you want to update just one file to an older revision, use
+ revert.
+
+ See 'hg help dates' for a list of formats valid for -d/--date.
+ """
+ if rev and node:
+ raise util.Abort(_("please specify just one revision"))
+
+ if not rev:
+ rev = node
+
+ if not clean and check:
+ # we could use dirty() but we can ignore merge and branch trivia
+ c = repo[None]
+ if c.modified() or c.added() or c.removed():
+ raise util.Abort(_("uncommitted local changes"))
+
+ if date:
+ if rev:
+ raise util.Abort(_("you can't specify a revision and a date"))
+ rev = cmdutil.finddate(ui, repo, date)
+
+ if clean or check:
+ return hg.clean(repo, rev)
+ else:
+ return hg.update(repo, rev)
+
+def verify(ui, repo):
+ """verify the integrity of the repository
+
+ Verify the integrity of the current repository.
+
+ This will perform an extensive check of the repository's
+ integrity, validating the hashes and checksums of each entry in
+ the changelog, manifest, and tracked files, as well as the
+ integrity of their crosslinks and indices.
+ """
+ return hg.verify(repo)
+
+def version_(ui):
+ """output version and copyright information"""
+ ui.write(_("Mercurial Distributed SCM (version %s)\n")
+ % util.version())
+ ui.status(_(
+ "\nCopyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others\n"
+ "This is free software; see the source for copying conditions. "
+ "There is NO\nwarranty; "
+ "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+ ))
+
+# Command options and aliases are listed here, alphabetically
+
+globalopts = [
+ ('R', 'repository', '',
+ _('repository root directory or symbolic path name')),
+ ('', 'cwd', '', _('change working directory')),
+ ('y', 'noninteractive', None,
+ _('do not prompt, assume \'yes\' for any required answers')),
+ ('q', 'quiet', None, _('suppress output')),
+ ('v', 'verbose', None, _('enable additional output')),
+ ('', 'config', [], _('set/override config option')),
+ ('', 'debug', None, _('enable debugging output')),
+ ('', 'debugger', None, _('start debugger')),
+ ('', 'encoding', encoding.encoding, _('set the charset encoding')),
+ ('', 'encodingmode', encoding.encodingmode,
+ _('set the charset encoding mode')),
+ ('', 'traceback', None, _('print traceback on exception')),
+ ('', 'time', None, _('time how long the command takes')),
+ ('', 'profile', None, _('print command execution profile')),
+ ('', 'version', None, _('output version information and exit')),
+ ('h', 'help', None, _('display help and exit')),
+]
+
+dryrunopts = [('n', 'dry-run', None,
+ _('do not perform actions, just print output'))]
+
+remoteopts = [
+ ('e', 'ssh', '', _('specify ssh command to use')),
+ ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
+]
+
+walkopts = [
+ ('I', 'include', [], _('include names matching the given patterns')),
+ ('X', 'exclude', [], _('exclude names matching the given patterns')),
+]
+
+commitopts = [
+ ('m', 'message', '', _('use <text> as commit message')),
+ ('l', 'logfile', '', _('read commit message from <file>')),
+]
+
+commitopts2 = [
+ ('d', 'date', '', _('record datecode as commit date')),
+ ('u', 'user', '', _('record the specified user as committer')),
+]
+
+templateopts = [
+ ('', 'style', '', _('display using template map file')),
+ ('', 'template', '', _('display with template')),
+]
+
+logopts = [
+ ('p', 'patch', None, _('show patch')),
+ ('g', 'git', None, _('use git extended diff format')),
+ ('l', 'limit', '', _('limit number of changes displayed')),
+ ('M', 'no-merges', None, _('do not show merges')),
+] + templateopts
+
+diffopts = [
+ ('a', 'text', None, _('treat all files as text')),
+ ('g', 'git', None, _('use git extended diff format')),
+ ('', 'nodates', None, _("don't include dates in diff headers"))
+]
+
+diffopts2 = [
+ ('p', 'show-function', None, _('show which function each change is in')),
+ ('w', 'ignore-all-space', None,
+ _('ignore white space when comparing lines')),
+ ('b', 'ignore-space-change', None,
+ _('ignore changes in the amount of white space')),
+ ('B', 'ignore-blank-lines', None,
+ _('ignore changes whose lines are all blank')),
+ ('U', 'unified', '', _('number of lines of context to show'))
+]
+
+similarityopts = [
+ ('s', 'similarity', '',
+ _('guess renamed files by similarity (0<=s<=100)'))
+]
+
+table = {
+ "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')),
+ "addremove":
+ (addremove, similarityopts + walkopts + dryrunopts,
+ _('[OPTION]... [FILE]...')),
+ "^annotate|blame":
+ (annotate,
+ [('r', 'rev', '', _('annotate the specified revision')),
+ ('f', 'follow', None, _('follow file copies and renames')),
+ ('a', 'text', None, _('treat all files as text')),
+ ('u', 'user', None, _('list the author (long with -v)')),
+ ('d', 'date', None, _('list the date (short with -q)')),
+ ('n', 'number', None, _('list the revision number (default)')),
+ ('c', 'changeset', None, _('list the changeset')),
+ ('l', 'line-number', None,
+ _('show line number at the first appearance'))
+ ] + walkopts,
+ _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
+ "archive":
+ (archive,
+ [('', 'no-decode', None, _('do not pass files through decoders')),
+ ('p', 'prefix', '', _('directory prefix for files in archive')),
+ ('r', 'rev', '', _('revision to distribute')),
+ ('t', 'type', '', _('type of distribution to create')),
+ ] + walkopts,
+ _('[OPTION]... DEST')),
+ "backout":
+ (backout,
+ [('', 'merge', None,
+ _('merge with old dirstate parent after backout')),
+ ('', 'parent', '', _('parent to choose when backing out merge')),
+ ('r', 'rev', '', _('revision to backout')),
+ ] + walkopts + commitopts + commitopts2,
+ _('[OPTION]... [-r] REV')),
+ "bisect":
+ (bisect,
+ [('r', 'reset', False, _('reset bisect state')),
+ ('g', 'good', False, _('mark changeset good')),
+ ('b', 'bad', False, _('mark changeset bad')),
+ ('s', 'skip', False, _('skip testing changeset')),
+ ('c', 'command', '', _('use command to check changeset state')),
+ ('U', 'noupdate', False, _('do not update to target'))],
+ _("[-gbsr] [-c CMD] [REV]")),
+ "branch":
+ (branch,
+ [('f', 'force', None,
+ _('set branch name even if it shadows an existing branch')),
+ ('C', 'clean', None, _('reset branch name to parent branch name'))],
+ _('[-fC] [NAME]')),
+ "branches":
+ (branches,
+ [('a', 'active', False,
+ _('show only branches that have unmerged heads')),
+ ('c', 'closed', False,
+ _('show normal and closed branches'))],
+ _('[-a]')),
+ "bundle":
+ (bundle,
+ [('f', 'force', None,
+ _('run even when remote repository is unrelated')),
+ ('r', 'rev', [],
+ _('a changeset up to which you would like to bundle')),
+ ('', 'base', [],
+ _('a base changeset to specify instead of a destination')),
+ ('a', 'all', None, _('bundle all changesets in the repository')),
+ ('t', 'type', 'bzip2', _('bundle compression type to use')),
+ ] + remoteopts,
+ _('[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
+ "cat":
+ (cat,
+ [('o', 'output', '', _('print output to file with formatted name')),
+ ('r', 'rev', '', _('print the given revision')),
+ ('', 'decode', None, _('apply any matching decode filter')),
+ ] + walkopts,
+ _('[OPTION]... FILE...')),
+ "^clone":
+ (clone,
+ [('U', 'noupdate', None,
+ _('the clone will only contain a repository (no working copy)')),
+ ('r', 'rev', [],
+ _('a changeset you would like to have after cloning')),
+ ('', 'pull', None, _('use pull protocol to copy metadata')),
+ ('', 'uncompressed', None,
+ _('use uncompressed transfer (fast over LAN)')),
+ ] + remoteopts,
+ _('[OPTION]... SOURCE [DEST]')),
+ "^commit|ci":
+ (commit,
+ [('A', 'addremove', None,
+ _('mark new/missing files as added/removed before committing')),
+ ('', 'close-branch', None,
+ _('mark a branch as closed, hiding it from the branch list')),
+ ] + walkopts + commitopts + commitopts2,
+ _('[OPTION]... [FILE]...')),
+ "copy|cp":
+ (copy,
+ [('A', 'after', None, _('record a copy that has already occurred')),
+ ('f', 'force', None,
+ _('forcibly copy over an existing managed file')),
+ ] + walkopts + dryrunopts,
+ _('[OPTION]... [SOURCE]... DEST')),
+ "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
+ "debugcheckstate": (debugcheckstate, []),
+ "debugcommands": (debugcommands, [], _('[COMMAND]')),
+ "debugcomplete":
+ (debugcomplete,
+ [('o', 'options', None, _('show the command options'))],
+ _('[-o] CMD')),
+ "debugdate":
+ (debugdate,
+ [('e', 'extended', None, _('try extended date formats'))],
+ _('[-e] DATE [RANGE]')),
+ "debugdata": (debugdata, [], _('FILE REV')),
+ "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
+ "debugindex": (debugindex, [], _('FILE')),
+ "debugindexdot": (debugindexdot, [], _('FILE')),
+ "debuginstall": (debuginstall, []),
+ "debugrebuildstate":
+ (debugrebuildstate,
+ [('r', 'rev', '', _('revision to rebuild to'))],
+ _('[-r REV] [REV]')),
+ "debugrename":
+ (debugrename,
+ [('r', 'rev', '', _('revision to debug'))],
+ _('[-r REV] FILE')),
+ "debugsetparents":
+ (debugsetparents, [], _('REV1 [REV2]')),
+ "debugstate":
+ (debugstate,
+ [('', 'nodates', None, _('do not display the saved mtime'))],
+ _('[OPTION]...')),
+ "debugsub":
+ (debugsub,
+ [('r', 'rev', '', _('revision to check'))],
+ _('[-r REV] [REV]')),
+ "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
+ "^diff":
+ (diff,
+ [('r', 'rev', [], _('revision')),
+ ('c', 'change', '', _('change made by revision'))
+ ] + diffopts + diffopts2 + walkopts,
+ _('[OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
+ "^export":
+ (export,
+ [('o', 'output', '', _('print output to file with formatted name')),
+ ('', 'switch-parent', None, _('diff against the second parent'))
+ ] + diffopts,
+ _('[OPTION]... [-o OUTFILESPEC] REV...')),
+ "^forget":
+ (forget,
+ [] + walkopts,
+ _('[OPTION]... FILE...')),
+ "grep":
+ (grep,
+ [('0', 'print0', None, _('end fields with NUL')),
+ ('', 'all', None, _('print all revisions that match')),
+ ('f', 'follow', None,
+ _('follow changeset history, or file history across copies and renames')),
+ ('i', 'ignore-case', None, _('ignore case when matching')),
+ ('l', 'files-with-matches', None,
+ _('print only filenames and revisions that match')),
+ ('n', 'line-number', None, _('print matching line numbers')),
+ ('r', 'rev', [], _('search in given revision range')),
+ ('u', 'user', None, _('list the author (long with -v)')),
+ ('d', 'date', None, _('list the date (short with -q)')),
+ ] + walkopts,
+ _('[OPTION]... PATTERN [FILE]...')),
+ "heads":
+ (heads,
+ [('r', 'rev', '', _('show only heads which are descendants of REV')),
+ ('a', 'active', False,
+ _('show only the active branch heads from open branches')),
+ ('c', 'closed', False,
+ _('show normal and closed branch heads')),
+ ] + templateopts,
+ _('[-r STARTREV] [REV]...')),
+ "help": (help_, [], _('[TOPIC]')),
+ "identify|id":
+ (identify,
+ [('r', 'rev', '', _('identify the specified revision')),
+ ('n', 'num', None, _('show local revision number')),
+ ('i', 'id', None, _('show global revision id')),
+ ('b', 'branch', None, _('show branch')),
+ ('t', 'tags', None, _('show tags'))],
+ _('[-nibt] [-r REV] [SOURCE]')),
+ "import|patch":
+ (import_,
+ [('p', 'strip', 1,
+ _('directory strip option for patch. This has the same '
+ 'meaning as the corresponding patch option')),
+ ('b', 'base', '', _('base path')),
+ ('f', 'force', None,
+ _('skip check for outstanding uncommitted changes')),
+ ('', 'no-commit', None, _("don't commit, just update the working directory")),
+ ('', 'exact', None,
+ _('apply patch to the nodes from which it was generated')),
+ ('', 'import-branch', None,
+ _('use any branch information in patch (implied by --exact)'))] +
+ commitopts + commitopts2 + similarityopts,
+ _('[OPTION]... PATCH...')),
+ "incoming|in":
+ (incoming,
+ [('f', 'force', None,
+ _('run even when remote repository is unrelated')),
+ ('n', 'newest-first', None, _('show newest record first')),
+ ('', 'bundle', '', _('file to store the bundles into')),
+ ('r', 'rev', [],
+ _('a specific revision up to which you would like to pull')),
+ ] + logopts + remoteopts,
+ _('[-p] [-n] [-M] [-f] [-r REV]...'
+ ' [--bundle FILENAME] [SOURCE]')),
+ "^init":
+ (init,
+ remoteopts,
+ _('[-e CMD] [--remotecmd CMD] [DEST]')),
+ "locate":
+ (locate,
+ [('r', 'rev', '', _('search the repository as it stood at REV')),
+ ('0', 'print0', None,
+ _('end filenames with NUL, for use with xargs')),
+ ('f', 'fullpath', None,
+ _('print complete paths from the filesystem root')),
+ ] + walkopts,
+ _('[OPTION]... [PATTERN]...')),
+ "^log|history":
+ (log,
+ [('f', 'follow', None,
+ _('follow changeset history, or file history across copies and renames')),
+ ('', 'follow-first', None,
+ _('only follow the first parent of merge changesets')),
+ ('d', 'date', '', _('show revisions matching date spec')),
+ ('C', 'copies', None, _('show copied files')),
+ ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
+ ('r', 'rev', [], _('show the specified revision or range')),
+ ('', 'removed', None, _('include revisions where files were removed')),
+ ('m', 'only-merges', None, _('show only merges')),
+ ('u', 'user', [], _('revisions committed by user')),
+ ('b', 'only-branch', [],
+ _('show only changesets within the given named branch')),
+ ('P', 'prune', [], _('do not display revision or any of its ancestors')),
+ ] + logopts + walkopts,
+ _('[OPTION]... [FILE]')),
+ "manifest":
+ (manifest,
+ [('r', 'rev', '', _('revision to display'))],
+ _('[-r REV]')),
+ "^merge":
+ (merge,
+ [('f', 'force', None, _('force a merge with outstanding changes')),
+ ('r', 'rev', '', _('revision to merge')),
+ ('P', 'preview', None,
+ _('review revisions to merge (no merge is performed)'))],
+ _('[-f] [[-r] REV]')),
+ "outgoing|out":
+ (outgoing,
+ [('f', 'force', None,
+ _('run even when remote repository is unrelated')),
+ ('r', 'rev', [],
+ _('a specific revision up to which you would like to push')),
+ ('n', 'newest-first', None, _('show newest record first')),
+ ] + logopts + remoteopts,
+ _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
+ "^parents":
+ (parents,
+ [('r', 'rev', '', _('show parents from the specified revision')),
+ ] + templateopts,
+ _('[-r REV] [FILE]')),
+ "paths": (paths, [], _('[NAME]')),
+ "^pull":
+ (pull,
+ [('u', 'update', None,
+ _('update to new tip if changesets were pulled')),
+ ('f', 'force', None,
+ _('run even when remote repository is unrelated')),
+ ('r', 'rev', [],
+ _('a specific revision up to which you would like to pull')),
+ ] + remoteopts,
+ _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
+ "^push":
+ (push,
+ [('f', 'force', None, _('force push')),
+ ('r', 'rev', [],
+ _('a specific revision up to which you would like to push')),
+ ] + remoteopts,
+ _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
+ "recover": (recover, []),
+ "^remove|rm":
+ (remove,
+ [('A', 'after', None, _('record delete for missing files')),
+ ('f', 'force', None,
+ _('remove (and delete) file even if added or modified')),
+ ] + walkopts,
+ _('[OPTION]... FILE...')),
+ "rename|mv":
+ (rename,
+ [('A', 'after', None, _('record a rename that has already occurred')),
+ ('f', 'force', None,
+ _('forcibly copy over an existing managed file')),
+ ] + walkopts + dryrunopts,
+ _('[OPTION]... SOURCE... DEST')),
+ "resolve":
+ (resolve,
+ [('a', 'all', None, _('remerge all unresolved files')),
+ ('l', 'list', None, _('list state of files needing merge')),
+ ('m', 'mark', None, _('mark files as resolved')),
+ ('u', 'unmark', None, _('unmark files as resolved'))]
+ + walkopts,
+ _('[OPTION]... [FILE]...')),
+ "revert":
+ (revert,
+ [('a', 'all', None, _('revert all changes when no arguments given')),
+ ('d', 'date', '', _('tipmost revision matching date')),
+ ('r', 'rev', '', _('revision to revert to')),
+ ('', 'no-backup', None, _('do not save backup copies of files')),
+ ] + walkopts + dryrunopts,
+ _('[OPTION]... [-r REV] [NAME]...')),
+ "rollback": (rollback, []),
+ "root": (root, []),
+ "^serve":
+ (serve,
+ [('A', 'accesslog', '', _('name of access log file to write to')),
+ ('d', 'daemon', None, _('run server in background')),
+ ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
+ ('E', 'errorlog', '', _('name of error log file to write to')),
+ ('p', 'port', 0, _('port to listen on (default: 8000)')),
+ ('a', 'address', '', _('address to listen on (default: all interfaces)')),
+ ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
+ ('n', 'name', '',
+ _('name to show in web pages (default: working directory)')),
+ ('', 'webdir-conf', '', _('name of the webdir config file'
+ ' (serve more than one repository)')),
+ ('', 'pid-file', '', _('name of file to write process ID to')),
+ ('', 'stdio', None, _('for remote clients')),
+ ('t', 'templates', '', _('web templates to use')),
+ ('', 'style', '', _('template style to use')),
+ ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
+ ('', 'certificate', '', _('SSL certificate file'))],
+ _('[OPTION]...')),
+ "showconfig|debugconfig":
+ (showconfig,
+ [('u', 'untrusted', None, _('show untrusted configuration options'))],
+ _('[-u] [NAME]...')),
+ "^status|st":
+ (status,
+ [('A', 'all', None, _('show status of all files')),
+ ('m', 'modified', None, _('show only modified files')),
+ ('a', 'added', None, _('show only added files')),
+ ('r', 'removed', None, _('show only removed files')),
+ ('d', 'deleted', None, _('show only deleted (but tracked) files')),
+ ('c', 'clean', None, _('show only files without changes')),
+ ('u', 'unknown', None, _('show only unknown (not tracked) files')),
+ ('i', 'ignored', None, _('show only ignored files')),
+ ('n', 'no-status', None, _('hide status prefix')),
+ ('C', 'copies', None, _('show source of copied files')),
+ ('0', 'print0', None,
+ _('end filenames with NUL, for use with xargs')),
+ ('', 'rev', [], _('show difference from revision')),
+ ] + walkopts,
+ _('[OPTION]... [FILE]...')),
+ "tag":
+ (tag,
+ [('f', 'force', None, _('replace existing tag')),
+ ('l', 'local', None, _('make the tag local')),
+ ('r', 'rev', '', _('revision to tag')),
+ ('', 'remove', None, _('remove a tag')),
+ # -l/--local is already there, commitopts cannot be used
+ ('m', 'message', '', _('use <text> as commit message')),
+ ] + commitopts2,
+ _('[-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
+ "tags": (tags, []),
+ "tip":
+ (tip,
+ [('p', 'patch', None, _('show patch')),
+ ('g', 'git', None, _('use git extended diff format')),
+ ] + templateopts,
+ _('[-p]')),
+ "unbundle":
+ (unbundle,
+ [('u', 'update', None,
+ _('update to new tip if changesets were unbundled'))],
+ _('[-u] FILE...')),
+ "^update|up|checkout|co":
+ (update,
+ [('C', 'clean', None, _('overwrite locally modified files (no backup)')),
+ ('c', 'check', None, _('check for uncommitted changes')),
+ ('d', 'date', '', _('tipmost revision matching date')),
+ ('r', 'rev', '', _('revision'))],
+ _('[-C] [-d DATE] [[-r] REV]')),
+ "verify": (verify, []),
+ "version": (version_, []),
+}
+
+norepo = ("clone init version help debugcommands debugcomplete debugdata"
+ " debugindex debugindexdot debugdate debuginstall debugfsinfo")
+optionalrepo = ("identify paths serve showconfig debugancestor")
diff --git a/sys/src/cmd/hg/mercurial/commands.pyc b/sys/src/cmd/hg/mercurial/commands.pyc
new file mode 100644
index 000000000..80374c601
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/commands.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/config.py b/sys/src/cmd/hg/mercurial/config.py
new file mode 100644
index 000000000..08a8c071b
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/config.py
@@ -0,0 +1,137 @@
+# config.py - configuration parsing for Mercurial
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import error
+import re, os
+
+class sortdict(dict):
+ 'a simple sorted dictionary'
+ def __init__(self, data=None):
+ self._list = []
+ if data:
+ self.update(data)
+ def copy(self):
+ return sortdict(self)
+ def __setitem__(self, key, val):
+ if key in self:
+ self._list.remove(key)
+ self._list.append(key)
+ dict.__setitem__(self, key, val)
+ def __iter__(self):
+ return self._list.__iter__()
+ def update(self, src):
+ for k in src:
+ self[k] = src[k]
+ def items(self):
+ return [(k, self[k]) for k in self._list]
+ def __delitem__(self, key):
+ dict.__delitem__(self, key)
+ self._list.remove(key)
+
+class config(object):
+ def __init__(self, data=None):
+ self._data = {}
+ self._source = {}
+ if data:
+ for k in data._data:
+ self._data[k] = data[k].copy()
+ self._source = data._source.copy()
+ def copy(self):
+ return config(self)
+ def __contains__(self, section):
+ return section in self._data
+ def __getitem__(self, section):
+ return self._data.get(section, {})
+ def __iter__(self):
+ for d in self.sections():
+ yield d
+ def update(self, src):
+ for s in src:
+ if s not in self:
+ self._data[s] = sortdict()
+ self._data[s].update(src._data[s])
+ self._source.update(src._source)
+ def get(self, section, item, default=None):
+ return self._data.get(section, {}).get(item, default)
+ def source(self, section, item):
+ return self._source.get((section, item), "")
+ def sections(self):
+ return sorted(self._data.keys())
+ def items(self, section):
+ return self._data.get(section, {}).items()
+ def set(self, section, item, value, source=""):
+ if section not in self:
+ self._data[section] = sortdict()
+ self._data[section][item] = value
+ self._source[(section, item)] = source
+
+ def parse(self, src, data, sections=None, remap=None, include=None):
+ sectionre = re.compile(r'\[([^\[]+)\]')
+ itemre = re.compile(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
+ contre = re.compile(r'\s+(\S.*\S)')
+ emptyre = re.compile(r'(;|#|\s*$)')
+ unsetre = re.compile(r'%unset\s+(\S+)')
+ includere = re.compile(r'%include\s+(\S.*\S)')
+ section = ""
+ item = None
+ line = 0
+ cont = False
+
+ for l in data.splitlines(True):
+ line += 1
+ if cont:
+ m = contre.match(l)
+ if m:
+ if sections and section not in sections:
+ continue
+ v = self.get(section, item) + "\n" + m.group(1)
+ self.set(section, item, v, "%s:%d" % (src, line))
+ continue
+ item = None
+ m = includere.match(l)
+ if m:
+ inc = m.group(1)
+ base = os.path.dirname(src)
+ inc = os.path.normpath(os.path.join(base, inc))
+ if include:
+ include(inc, remap=remap, sections=sections)
+ continue
+ if emptyre.match(l):
+ continue
+ m = sectionre.match(l)
+ if m:
+ section = m.group(1)
+ if remap:
+ section = remap.get(section, section)
+ if section not in self:
+ self._data[section] = sortdict()
+ continue
+ m = itemre.match(l)
+ if m:
+ item = m.group(1)
+ cont = True
+ if sections and section not in sections:
+ continue
+ self.set(section, item, m.group(2), "%s:%d" % (src, line))
+ continue
+ m = unsetre.match(l)
+ if m:
+ name = m.group(1)
+ if sections and section not in sections:
+ continue
+ if self.get(section, name) != None:
+ del self._data[section][name]
+ continue
+
+ raise error.ConfigError(_("config error at %s:%d: '%s'")
+ % (src, line, l.rstrip()))
+
+ def read(self, path, fp=None, sections=None, remap=None):
+ if not fp:
+ fp = open(path)
+ self.parse(path, fp.read(), sections, remap, self.read)
diff --git a/sys/src/cmd/hg/mercurial/config.pyc b/sys/src/cmd/hg/mercurial/config.pyc
new file mode 100644
index 000000000..dfe3fd50b
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/config.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/context.py b/sys/src/cmd/hg/mercurial/context.py
new file mode 100644
index 000000000..8ba3aee10
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/context.py
@@ -0,0 +1,818 @@
+# context.py - changeset and file context objects for mercurial
+#
+# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import nullid, nullrev, short, hex
+from i18n import _
+import ancestor, bdiff, error, util, subrepo
+import os, errno
+
+propertycache = util.propertycache
+
+class changectx(object):
+ """A changecontext object makes access to data related to a particular
+ changeset convenient."""
+ def __init__(self, repo, changeid=''):
+ """changeid is a revision number, node, or tag"""
+ if changeid == '':
+ changeid = '.'
+ self._repo = repo
+ if isinstance(changeid, (long, int)):
+ self._rev = changeid
+ self._node = self._repo.changelog.node(changeid)
+ else:
+ self._node = self._repo.lookup(changeid)
+ self._rev = self._repo.changelog.rev(self._node)
+
+ def __str__(self):
+ return short(self.node())
+
+ def __int__(self):
+ return self.rev()
+
+ def __repr__(self):
+ return "<changectx %s>" % str(self)
+
+ def __hash__(self):
+ try:
+ return hash(self._rev)
+ except AttributeError:
+ return id(self)
+
+ def __eq__(self, other):
+ try:
+ return self._rev == other._rev
+ except AttributeError:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __nonzero__(self):
+ return self._rev != nullrev
+
+ @propertycache
+ def _changeset(self):
+ return self._repo.changelog.read(self.node())
+
+ @propertycache
+ def _manifest(self):
+ return self._repo.manifest.read(self._changeset[0])
+
+ @propertycache
+ def _manifestdelta(self):
+ return self._repo.manifest.readdelta(self._changeset[0])
+
+ @propertycache
+ def _parents(self):
+ p = self._repo.changelog.parentrevs(self._rev)
+ if p[1] == nullrev:
+ p = p[:-1]
+ return [changectx(self._repo, x) for x in p]
+
+ @propertycache
+ def substate(self):
+ return subrepo.state(self)
+
+ def __contains__(self, key):
+ return key in self._manifest
+
+ def __getitem__(self, key):
+ return self.filectx(key)
+
+ def __iter__(self):
+ for f in sorted(self._manifest):
+ yield f
+
+ def changeset(self): return self._changeset
+ def manifest(self): return self._manifest
+ def manifestnode(self): return self._changeset[0]
+
+ def rev(self): return self._rev
+ def node(self): return self._node
+ def hex(self): return hex(self._node)
+ def user(self): return self._changeset[1]
+ def date(self): return self._changeset[2]
+ def files(self): return self._changeset[3]
+ def description(self): return self._changeset[4]
+ def branch(self): return self._changeset[5].get("branch")
+ def extra(self): return self._changeset[5]
+ def tags(self): return self._repo.nodetags(self._node)
+
+ def parents(self):
+ """return contexts for each parent changeset"""
+ return self._parents
+
+ def p1(self):
+ return self._parents[0]
+
+ def p2(self):
+ if len(self._parents) == 2:
+ return self._parents[1]
+ return changectx(self._repo, -1)
+
+ def children(self):
+ """return contexts for each child changeset"""
+ c = self._repo.changelog.children(self._node)
+ return [changectx(self._repo, x) for x in c]
+
+ def ancestors(self):
+ for a in self._repo.changelog.ancestors(self._rev):
+ yield changectx(self._repo, a)
+
+ def descendants(self):
+ for d in self._repo.changelog.descendants(self._rev):
+ yield changectx(self._repo, d)
+
+ def _fileinfo(self, path):
+ if '_manifest' in self.__dict__:
+ try:
+ return self._manifest[path], self._manifest.flags(path)
+ except KeyError:
+ raise error.LookupError(self._node, path,
+ _('not found in manifest'))
+ if '_manifestdelta' in self.__dict__ or path in self.files():
+ if path in self._manifestdelta:
+ return self._manifestdelta[path], self._manifestdelta.flags(path)
+ node, flag = self._repo.manifest.find(self._changeset[0], path)
+ if not node:
+ raise error.LookupError(self._node, path,
+ _('not found in manifest'))
+
+ return node, flag
+
+ def filenode(self, path):
+ return self._fileinfo(path)[0]
+
+ def flags(self, path):
+ try:
+ return self._fileinfo(path)[1]
+ except error.LookupError:
+ return ''
+
+ def filectx(self, path, fileid=None, filelog=None):
+ """get a file context from this changeset"""
+ if fileid is None:
+ fileid = self.filenode(path)
+ return filectx(self._repo, path, fileid=fileid,
+ changectx=self, filelog=filelog)
+
+ def ancestor(self, c2):
+ """
+ return the ancestor context of self and c2
+ """
+ n = self._repo.changelog.ancestor(self._node, c2._node)
+ return changectx(self._repo, n)
+
+ def walk(self, match):
+ fset = set(match.files())
+ # for dirstate.walk, files=['.'] means "walk the whole tree".
+ # follow that here, too
+ fset.discard('.')
+ for fn in self:
+ for ffn in fset:
+ # match if the file is the exact name or a directory
+ if ffn == fn or fn.startswith("%s/" % ffn):
+ fset.remove(ffn)
+ break
+ if match(fn):
+ yield fn
+ for fn in sorted(fset):
+ if match.bad(fn, 'No such file in rev ' + str(self)) and match(fn):
+ yield fn
+
+ def sub(self, path):
+ return subrepo.subrepo(self, path)
+
+class filectx(object):
+ """A filecontext object makes access to data related to a particular
+ filerevision convenient."""
+ def __init__(self, repo, path, changeid=None, fileid=None,
+ filelog=None, changectx=None):
+ """changeid can be a changeset revision, node, or tag.
+ fileid can be a file revision or node."""
+ self._repo = repo
+ self._path = path
+
+ assert (changeid is not None
+ or fileid is not None
+ or changectx is not None), \
+ ("bad args: changeid=%r, fileid=%r, changectx=%r"
+ % (changeid, fileid, changectx))
+
+ if filelog:
+ self._filelog = filelog
+
+ if changeid is not None:
+ self._changeid = changeid
+ if changectx is not None:
+ self._changectx = changectx
+ if fileid is not None:
+ self._fileid = fileid
+
+ @propertycache
+ def _changectx(self):
+ return changectx(self._repo, self._changeid)
+
+ @propertycache
+ def _filelog(self):
+ return self._repo.file(self._path)
+
+ @propertycache
+ def _changeid(self):
+ if '_changectx' in self.__dict__:
+ return self._changectx.rev()
+ else:
+ return self._filelog.linkrev(self._filerev)
+
+ @propertycache
+ def _filenode(self):
+ if '_fileid' in self.__dict__:
+ return self._filelog.lookup(self._fileid)
+ else:
+ return self._changectx.filenode(self._path)
+
+ @propertycache
+ def _filerev(self):
+ return self._filelog.rev(self._filenode)
+
+ @propertycache
+ def _repopath(self):
+ return self._path
+
+ def __nonzero__(self):
+ try:
+ self._filenode
+ return True
+ except error.LookupError:
+ # file is missing
+ return False
+
+ def __str__(self):
+ return "%s@%s" % (self.path(), short(self.node()))
+
+ def __repr__(self):
+ return "<filectx %s>" % str(self)
+
+ def __hash__(self):
+ try:
+ return hash((self._path, self._fileid))
+ except AttributeError:
+ return id(self)
+
+ def __eq__(self, other):
+ try:
+ return (self._path == other._path
+ and self._fileid == other._fileid)
+ except AttributeError:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def filectx(self, fileid):
+ '''opens an arbitrary revision of the file without
+ opening a new filelog'''
+ return filectx(self._repo, self._path, fileid=fileid,
+ filelog=self._filelog)
+
+ def filerev(self): return self._filerev
+ def filenode(self): return self._filenode
+ def flags(self): return self._changectx.flags(self._path)
+ def filelog(self): return self._filelog
+
+ def rev(self):
+ if '_changectx' in self.__dict__:
+ return self._changectx.rev()
+ if '_changeid' in self.__dict__:
+ return self._changectx.rev()
+ return self._filelog.linkrev(self._filerev)
+
+ def linkrev(self): return self._filelog.linkrev(self._filerev)
+ def node(self): return self._changectx.node()
+ def hex(self): return hex(self.node())
+ def user(self): return self._changectx.user()
+ def date(self): return self._changectx.date()
+ def files(self): return self._changectx.files()
+ def description(self): return self._changectx.description()
+ def branch(self): return self._changectx.branch()
+ def manifest(self): return self._changectx.manifest()
+ def changectx(self): return self._changectx
+
+ def data(self): return self._filelog.read(self._filenode)
+ def path(self): return self._path
+ def size(self): return self._filelog.size(self._filerev)
+
+ def cmp(self, text): return self._filelog.cmp(self._filenode, text)
+
+ def renamed(self):
+ """check if file was actually renamed in this changeset revision
+
+ If rename logged in file revision, we report copy for changeset only
+ if file revisions linkrev points back to the changeset in question
+ or both changeset parents contain different file revisions.
+ """
+
+ renamed = self._filelog.renamed(self._filenode)
+ if not renamed:
+ return renamed
+
+ if self.rev() == self.linkrev():
+ return renamed
+
+ name = self.path()
+ fnode = self._filenode
+ for p in self._changectx.parents():
+ try:
+ if fnode == p.filenode(name):
+ return None
+ except error.LookupError:
+ pass
+ return renamed
+
+ def parents(self):
+ p = self._path
+ fl = self._filelog
+ pl = [(p, n, fl) for n in self._filelog.parents(self._filenode)]
+
+ r = self._filelog.renamed(self._filenode)
+ if r:
+ pl[0] = (r[0], r[1], None)
+
+ return [filectx(self._repo, p, fileid=n, filelog=l)
+ for p,n,l in pl if n != nullid]
+
+ def children(self):
+ # hard for renames
+ c = self._filelog.children(self._filenode)
+ return [filectx(self._repo, self._path, fileid=x,
+ filelog=self._filelog) for x in c]
+
+ def annotate(self, follow=False, linenumber=None):
+ '''returns a list of tuples of (ctx, line) for each line
+ in the file, where ctx is the filectx of the node where
+ that line was last changed.
+ This returns tuples of ((ctx, linenumber), line) for each line,
+ if "linenumber" parameter is NOT "None".
+ In such tuples, linenumber means one at the first appearance
+ in the managed file.
+ To reduce annotation cost,
+ this returns fixed value(False is used) as linenumber,
+ if "linenumber" parameter is "False".'''
+
+ def decorate_compat(text, rev):
+ return ([rev] * len(text.splitlines()), text)
+
+ def without_linenumber(text, rev):
+ return ([(rev, False)] * len(text.splitlines()), text)
+
+ def with_linenumber(text, rev):
+ size = len(text.splitlines())
+ return ([(rev, i) for i in xrange(1, size + 1)], text)
+
+ decorate = (((linenumber is None) and decorate_compat) or
+ (linenumber and with_linenumber) or
+ without_linenumber)
+
+ def pair(parent, child):
+ for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]):
+ child[0][b1:b2] = parent[0][a1:a2]
+ return child
+
+ getlog = util.lrucachefunc(lambda x: self._repo.file(x))
+ def getctx(path, fileid):
+ log = path == self._path and self._filelog or getlog(path)
+ return filectx(self._repo, path, fileid=fileid, filelog=log)
+ getctx = util.lrucachefunc(getctx)
+
+ def parents(f):
+ # we want to reuse filectx objects as much as possible
+ p = f._path
+ if f._filerev is None: # working dir
+ pl = [(n.path(), n.filerev()) for n in f.parents()]
+ else:
+ pl = [(p, n) for n in f._filelog.parentrevs(f._filerev)]
+
+ if follow:
+ r = f.renamed()
+ if r:
+ pl[0] = (r[0], getlog(r[0]).rev(r[1]))
+
+ return [getctx(p, n) for p, n in pl if n != nullrev]
+
+ # use linkrev to find the first changeset where self appeared
+ if self.rev() != self.linkrev():
+ base = self.filectx(self.filerev())
+ else:
+ base = self
+
+ # find all ancestors
+ needed = {base: 1}
+ visit = [base]
+ files = [base._path]
+ while visit:
+ f = visit.pop(0)
+ for p in parents(f):
+ if p not in needed:
+ needed[p] = 1
+ visit.append(p)
+ if p._path not in files:
+ files.append(p._path)
+ else:
+ # count how many times we'll use this
+ needed[p] += 1
+
+ # sort by revision (per file) which is a topological order
+ visit = []
+ for f in files:
+ fn = [(n.rev(), n) for n in needed if n._path == f]
+ visit.extend(fn)
+
+ hist = {}
+ for r, f in sorted(visit):
+ curr = decorate(f.data(), f)
+ for p in parents(f):
+ if p != nullid:
+ curr = pair(hist[p], curr)
+ # trim the history of unneeded revs
+ needed[p] -= 1
+ if not needed[p]:
+ del hist[p]
+ hist[f] = curr
+
+ return zip(hist[f][0], hist[f][1].splitlines(True))
+
+ def ancestor(self, fc2):
+ """
+ find the common ancestor file context, if any, of self, and fc2
+ """
+
+ acache = {}
+
+ # prime the ancestor cache for the working directory
+ for c in (self, fc2):
+ if c._filerev is None:
+ pl = [(n.path(), n.filenode()) for n in c.parents()]
+ acache[(c._path, None)] = pl
+
+ flcache = {self._repopath:self._filelog, fc2._repopath:fc2._filelog}
+ def parents(vertex):
+ if vertex in acache:
+ return acache[vertex]
+ f, n = vertex
+ if f not in flcache:
+ flcache[f] = self._repo.file(f)
+ fl = flcache[f]
+ pl = [(f, p) for p in fl.parents(n) if p != nullid]
+ re = fl.renamed(n)
+ if re:
+ pl.append(re)
+ acache[vertex] = pl
+ return pl
+
+ a, b = (self._path, self._filenode), (fc2._path, fc2._filenode)
+ v = ancestor.ancestor(a, b, parents)
+ if v:
+ f, n = v
+ return filectx(self._repo, f, fileid=n, filelog=flcache[f])
+
+ return None
+
+class workingctx(changectx):
+ """A workingctx object makes access to data related to
+ the current working directory convenient.
+ parents - a pair of parent nodeids, or None to use the dirstate.
+ date - any valid date string or (unixtime, offset), or None.
+ user - username string, or None.
+ extra - a dictionary of extra values, or None.
+ changes - a list of file lists as returned by localrepo.status()
+ or None to use the repository status.
+ """
+ def __init__(self, repo, parents=None, text="", user=None, date=None,
+ extra=None, changes=None):
+ self._repo = repo
+ self._rev = None
+ self._node = None
+ self._text = text
+ if date:
+ self._date = util.parsedate(date)
+ if user:
+ self._user = user
+ if parents:
+ self._parents = [changectx(self._repo, p) for p in parents]
+ if changes:
+ self._status = list(changes)
+
+ self._extra = {}
+ if extra:
+ self._extra = extra.copy()
+ if 'branch' not in self._extra:
+ branch = self._repo.dirstate.branch()
+ try:
+ branch = branch.decode('UTF-8').encode('UTF-8')
+ except UnicodeDecodeError:
+ raise util.Abort(_('branch name not in UTF-8!'))
+ self._extra['branch'] = branch
+ if self._extra['branch'] == '':
+ self._extra['branch'] = 'default'
+
+ def __str__(self):
+ return str(self._parents[0]) + "+"
+
+ def __nonzero__(self):
+ return True
+
+ def __contains__(self, key):
+ return self._repo.dirstate[key] not in "?r"
+
+ @propertycache
+ def _manifest(self):
+ """generate a manifest corresponding to the working directory"""
+
+ man = self._parents[0].manifest().copy()
+ copied = self._repo.dirstate.copies()
+ cf = lambda x: man.flags(copied.get(x, x))
+ ff = self._repo.dirstate.flagfunc(cf)
+ modified, added, removed, deleted, unknown = self._status[:5]
+ for i, l in (("a", added), ("m", modified), ("u", unknown)):
+ for f in l:
+ man[f] = man.get(copied.get(f, f), nullid) + i
+ try:
+ man.set(f, ff(f))
+ except OSError:
+ pass
+
+ for f in deleted + removed:
+ if f in man:
+ del man[f]
+
+ return man
+
+ @propertycache
+ def _status(self):
+ return self._repo.status(unknown=True)
+
+ @propertycache
+ def _user(self):
+ return self._repo.ui.username()
+
+ @propertycache
+ def _date(self):
+ return util.makedate()
+
+ @propertycache
+ def _parents(self):
+ p = self._repo.dirstate.parents()
+ if p[1] == nullid:
+ p = p[:-1]
+ self._parents = [changectx(self._repo, x) for x in p]
+ return self._parents
+
+ def manifest(self): return self._manifest
+
+ def user(self): return self._user or self._repo.ui.username()
+ def date(self): return self._date
+ def description(self): return self._text
+ def files(self):
+ return sorted(self._status[0] + self._status[1] + self._status[2])
+
+ def modified(self): return self._status[0]
+ def added(self): return self._status[1]
+ def removed(self): return self._status[2]
+ def deleted(self): return self._status[3]
+ def unknown(self): return self._status[4]
+ def clean(self): return self._status[5]
+ def branch(self): return self._extra['branch']
+ def extra(self): return self._extra
+
+ def tags(self):
+ t = []
+ [t.extend(p.tags()) for p in self.parents()]
+ return t
+
+ def children(self):
+ return []
+
+ def flags(self, path):
+ if '_manifest' in self.__dict__:
+ try:
+ return self._manifest.flags(path)
+ except KeyError:
+ return ''
+
+ pnode = self._parents[0].changeset()[0]
+ orig = self._repo.dirstate.copies().get(path, path)
+ node, flag = self._repo.manifest.find(pnode, orig)
+ try:
+ ff = self._repo.dirstate.flagfunc(lambda x: flag or '')
+ return ff(path)
+ except OSError:
+ pass
+
+ if not node or path in self.deleted() or path in self.removed():
+ return ''
+ return flag
+
+ def filectx(self, path, filelog=None):
+ """get a file context from the working directory"""
+ return workingfilectx(self._repo, path, workingctx=self,
+ filelog=filelog)
+
+ def ancestor(self, c2):
+ """return the ancestor context of self and c2"""
+ return self._parents[0].ancestor(c2) # punt on two parents for now
+
+ def walk(self, match):
+ return sorted(self._repo.dirstate.walk(match, True, False))
+
+ def dirty(self, missing=False):
+ "check whether a working directory is modified"
+
+ return (self.p2() or self.branch() != self.p1().branch() or
+ self.modified() or self.added() or self.removed() or
+ (missing and self.deleted()))
+
+class workingfilectx(filectx):
+ """A workingfilectx object makes access to data related to a particular
+ file in the working directory convenient."""
+ def __init__(self, repo, path, filelog=None, workingctx=None):
+ """changeid can be a changeset revision, node, or tag.
+ fileid can be a file revision or node."""
+ self._repo = repo
+ self._path = path
+ self._changeid = None
+ self._filerev = self._filenode = None
+
+ if filelog:
+ self._filelog = filelog
+ if workingctx:
+ self._changectx = workingctx
+
+ @propertycache
+ def _changectx(self):
+ return workingctx(self._repo)
+
+ def __nonzero__(self):
+ return True
+
+ def __str__(self):
+ return "%s@%s" % (self.path(), self._changectx)
+
+ def data(self): return self._repo.wread(self._path)
+ def renamed(self):
+ rp = self._repo.dirstate.copied(self._path)
+ if not rp:
+ return None
+ return rp, self._changectx._parents[0]._manifest.get(rp, nullid)
+
+ def parents(self):
+ '''return parent filectxs, following copies if necessary'''
+ def filenode(ctx, path):
+ return ctx._manifest.get(path, nullid)
+
+ path = self._path
+ fl = self._filelog
+ pcl = self._changectx._parents
+ renamed = self.renamed()
+
+ if renamed:
+ pl = [renamed + (None,)]
+ else:
+ pl = [(path, filenode(pcl[0], path), fl)]
+
+ for pc in pcl[1:]:
+ pl.append((path, filenode(pc, path), fl))
+
+ return [filectx(self._repo, p, fileid=n, filelog=l)
+ for p,n,l in pl if n != nullid]
+
+ def children(self):
+ return []
+
+ def size(self): return os.stat(self._repo.wjoin(self._path)).st_size
+ def date(self):
+ t, tz = self._changectx.date()
+ try:
+ return (int(os.lstat(self._repo.wjoin(self._path)).st_mtime), tz)
+ except OSError, err:
+ if err.errno != errno.ENOENT: raise
+ return (t, tz)
+
+ def cmp(self, text): return self._repo.wread(self._path) == text
+
+class memctx(object):
+ """Use memctx to perform in-memory commits via localrepo.commitctx().
+
+ Revision information is supplied at initialization time while
+ related files data and is made available through a callback
+ mechanism. 'repo' is the current localrepo, 'parents' is a
+ sequence of two parent revisions identifiers (pass None for every
+ missing parent), 'text' is the commit message and 'files' lists
+ names of files touched by the revision (normalized and relative to
+ repository root).
+
+ filectxfn(repo, memctx, path) is a callable receiving the
+ repository, the current memctx object and the normalized path of
+ requested file, relative to repository root. It is fired by the
+ commit function for every file in 'files', but calls order is
+ undefined. If the file is available in the revision being
+ committed (updated or added), filectxfn returns a memfilectx
+ object. If the file was removed, filectxfn raises an
+ IOError. Moved files are represented by marking the source file
+ removed and the new file added with copy information (see
+ memfilectx).
+
+ user receives the committer name and defaults to current
+ repository username, date is the commit date in any format
+ supported by util.parsedate() and defaults to current date, extra
+ is a dictionary of metadata or is left empty.
+ """
+ def __init__(self, repo, parents, text, files, filectxfn, user=None,
+ date=None, extra=None):
+ self._repo = repo
+ self._rev = None
+ self._node = None
+ self._text = text
+ self._date = date and util.parsedate(date) or util.makedate()
+ self._user = user
+ parents = [(p or nullid) for p in parents]
+ p1, p2 = parents
+ self._parents = [changectx(self._repo, p) for p in (p1, p2)]
+ files = sorted(set(files))
+ self._status = [files, [], [], [], []]
+ self._filectxfn = filectxfn
+
+ self._extra = extra and extra.copy() or {}
+ if 'branch' not in self._extra:
+ self._extra['branch'] = 'default'
+ elif self._extra.get('branch') == '':
+ self._extra['branch'] = 'default'
+
+ def __str__(self):
+ return str(self._parents[0]) + "+"
+
+ def __int__(self):
+ return self._rev
+
+ def __nonzero__(self):
+ return True
+
+ def __getitem__(self, key):
+ return self.filectx(key)
+
+ def p1(self): return self._parents[0]
+ def p2(self): return self._parents[1]
+
+ def user(self): return self._user or self._repo.ui.username()
+ def date(self): return self._date
+ def description(self): return self._text
+ def files(self): return self.modified()
+ def modified(self): return self._status[0]
+ def added(self): return self._status[1]
+ def removed(self): return self._status[2]
+ def deleted(self): return self._status[3]
+ def unknown(self): return self._status[4]
+ def clean(self): return self._status[5]
+ def branch(self): return self._extra['branch']
+ def extra(self): return self._extra
+ def flags(self, f): return self[f].flags()
+
+ def parents(self):
+ """return contexts for each parent changeset"""
+ return self._parents
+
+ def filectx(self, path, filelog=None):
+ """get a file context from the working directory"""
+ return self._filectxfn(self._repo, self, path)
+
+class memfilectx(object):
+ """memfilectx represents an in-memory file to commit.
+
+ See memctx for more details.
+ """
+ def __init__(self, path, data, islink, isexec, copied):
+ """
+ path is the normalized file path relative to repository root.
+ data is the file content as a string.
+ islink is True if the file is a symbolic link.
+ isexec is True if the file is executable.
+ copied is the source file path if current file was copied in the
+ revision being committed, or None."""
+ self._path = path
+ self._data = data
+ self._flags = (islink and 'l' or '') + (isexec and 'x' or '')
+ self._copied = None
+ if copied:
+ self._copied = (copied, nullid)
+
+ def __nonzero__(self): return True
+ def __str__(self): return "%s@%s" % (self.path(), self._changectx)
+ def path(self): return self._path
+ def data(self): return self._data
+ def flags(self): return self._flags
+ def isexec(self): return 'x' in self._flags
+ def islink(self): return 'l' in self._flags
+ def renamed(self): return self._copied
diff --git a/sys/src/cmd/hg/mercurial/copies.py b/sys/src/cmd/hg/mercurial/copies.py
new file mode 100644
index 000000000..63c80a3f6
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/copies.py
@@ -0,0 +1,233 @@
+# copies.py - copy detection for Mercurial
+#
+# Copyright 2008 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import util
+import heapq
+
+def _nonoverlap(d1, d2, d3):
+ "Return list of elements in d1 not in d2 or d3"
+ return sorted([d for d in d1 if d not in d3 and d not in d2])
+
+def _dirname(f):
+ s = f.rfind("/")
+ if s == -1:
+ return ""
+ return f[:s]
+
+def _dirs(files):
+ d = set()
+ for f in files:
+ f = _dirname(f)
+ while f not in d:
+ d.add(f)
+ f = _dirname(f)
+ return d
+
+def _findoldnames(fctx, limit):
+ "find files that path was copied from, back to linkrev limit"
+ old = {}
+ seen = set()
+ orig = fctx.path()
+ visit = [(fctx, 0)]
+ while visit:
+ fc, depth = visit.pop()
+ s = str(fc)
+ if s in seen:
+ continue
+ seen.add(s)
+ if fc.path() != orig and fc.path() not in old:
+ old[fc.path()] = (depth, fc.path()) # remember depth
+ if fc.rev() is not None and fc.rev() < limit:
+ continue
+ visit += [(p, depth - 1) for p in fc.parents()]
+
+ # return old names sorted by depth
+ return [o[1] for o in sorted(old.values())]
+
+def _findlimit(repo, a, b):
+ "find the earliest revision that's an ancestor of a or b but not both"
+ # basic idea:
+ # - mark a and b with different sides
+ # - if a parent's children are all on the same side, the parent is
+ # on that side, otherwise it is on no side
+ # - walk the graph in topological order with the help of a heap;
+ # - add unseen parents to side map
+ # - clear side of any parent that has children on different sides
+ # - track number of interesting revs that might still be on a side
+ # - track the lowest interesting rev seen
+ # - quit when interesting revs is zero
+
+ cl = repo.changelog
+ working = len(cl) # pseudo rev for the working directory
+ if a is None:
+ a = working
+ if b is None:
+ b = working
+
+ side = {a: -1, b: 1}
+ visit = [-a, -b]
+ heapq.heapify(visit)
+ interesting = len(visit)
+ limit = working
+
+ while interesting:
+ r = -heapq.heappop(visit)
+ if r == working:
+ parents = [cl.rev(p) for p in repo.dirstate.parents()]
+ else:
+ parents = cl.parentrevs(r)
+ for p in parents:
+ if p not in side:
+ # first time we see p; add it to visit
+ side[p] = side[r]
+ if side[p]:
+ interesting += 1
+ heapq.heappush(visit, -p)
+ elif side[p] and side[p] != side[r]:
+ # p was interesting but now we know better
+ side[p] = 0
+ interesting -= 1
+ if side[r]:
+ limit = r # lowest rev visited
+ interesting -= 1
+ return limit
+
+def copies(repo, c1, c2, ca, checkdirs=False):
+ """
+ Find moves and copies between context c1 and c2
+ """
+ # avoid silly behavior for update from empty dir
+ if not c1 or not c2 or c1 == c2:
+ return {}, {}
+
+ # avoid silly behavior for parent -> working dir
+ if c2.node() is None and c1.node() == repo.dirstate.parents()[0]:
+ return repo.dirstate.copies(), {}
+
+ limit = _findlimit(repo, c1.rev(), c2.rev())
+ m1 = c1.manifest()
+ m2 = c2.manifest()
+ ma = ca.manifest()
+
+ def makectx(f, n):
+ if len(n) != 20: # in a working context?
+ if c1.rev() is None:
+ return c1.filectx(f)
+ return c2.filectx(f)
+ return repo.filectx(f, fileid=n)
+
+ ctx = util.lrucachefunc(makectx)
+ copy = {}
+ fullcopy = {}
+ diverge = {}
+
+ def checkcopies(f, m1, m2):
+ '''check possible copies of f from m1 to m2'''
+ c1 = ctx(f, m1[f])
+ for of in _findoldnames(c1, limit):
+ fullcopy[f] = of # remember for dir rename detection
+ if of in m2: # original file not in other manifest?
+ # if the original file is unchanged on the other branch,
+ # no merge needed
+ if m2[of] != ma.get(of):
+ c2 = ctx(of, m2[of])
+ ca = c1.ancestor(c2)
+ # related and named changed on only one side?
+ if ca and (ca.path() == f or ca.path() == c2.path()):
+ if c1 != ca or c2 != ca: # merge needed?
+ copy[f] = of
+ elif of in ma:
+ diverge.setdefault(of, []).append(f)
+
+ repo.ui.debug(_(" searching for copies back to rev %d\n") % limit)
+
+ u1 = _nonoverlap(m1, m2, ma)
+ u2 = _nonoverlap(m2, m1, ma)
+
+ if u1:
+ repo.ui.debug(_(" unmatched files in local:\n %s\n")
+ % "\n ".join(u1))
+ if u2:
+ repo.ui.debug(_(" unmatched files in other:\n %s\n")
+ % "\n ".join(u2))
+
+ for f in u1:
+ checkcopies(f, m1, m2)
+ for f in u2:
+ checkcopies(f, m2, m1)
+
+ diverge2 = set()
+ for of, fl in diverge.items():
+ if len(fl) == 1:
+ del diverge[of] # not actually divergent
+ else:
+ diverge2.update(fl) # reverse map for below
+
+ if fullcopy:
+ repo.ui.debug(_(" all copies found (* = to merge, ! = divergent):\n"))
+ for f in fullcopy:
+ note = ""
+ if f in copy: note += "*"
+ if f in diverge2: note += "!"
+ repo.ui.debug(" %s -> %s %s\n" % (f, fullcopy[f], note))
+ del diverge2
+
+ if not fullcopy or not checkdirs:
+ return copy, diverge
+
+ repo.ui.debug(_(" checking for directory renames\n"))
+
+ # generate a directory move map
+ d1, d2 = _dirs(m1), _dirs(m2)
+ invalid = set()
+ dirmove = {}
+
+ # examine each file copy for a potential directory move, which is
+ # when all the files in a directory are moved to a new directory
+ for dst, src in fullcopy.iteritems():
+ dsrc, ddst = _dirname(src), _dirname(dst)
+ if dsrc in invalid:
+ # already seen to be uninteresting
+ continue
+ elif dsrc in d1 and ddst in d1:
+ # directory wasn't entirely moved locally
+ invalid.add(dsrc)
+ elif dsrc in d2 and ddst in d2:
+ # directory wasn't entirely moved remotely
+ invalid.add(dsrc)
+ elif dsrc in dirmove and dirmove[dsrc] != ddst:
+ # files from the same directory moved to two different places
+ invalid.add(dsrc)
+ else:
+ # looks good so far
+ dirmove[dsrc + "/"] = ddst + "/"
+
+ for i in invalid:
+ if i in dirmove:
+ del dirmove[i]
+ del d1, d2, invalid
+
+ if not dirmove:
+ return copy, diverge
+
+ for d in dirmove:
+ repo.ui.debug(_(" dir %s -> %s\n") % (d, dirmove[d]))
+
+ # check unaccounted nonoverlapping files against directory moves
+ for f in u1 + u2:
+ if f not in fullcopy:
+ for d in dirmove:
+ if f.startswith(d):
+ # new file added in a directory that was moved, move it
+ df = dirmove[d] + f[len(d):]
+ if df not in copy:
+ copy[f] = df
+ repo.ui.debug(_(" file %s -> %s\n") % (f, copy[f]))
+ break
+
+ return copy, diverge
diff --git a/sys/src/cmd/hg/mercurial/demandimport.py b/sys/src/cmd/hg/mercurial/demandimport.py
new file mode 100644
index 000000000..a620bb243
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/demandimport.py
@@ -0,0 +1,139 @@
+# demandimport.py - global demand-loading of modules for Mercurial
+#
+# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+'''
+demandimport - automatic demandloading of modules
+
+To enable this module, do:
+
+ import demandimport; demandimport.enable()
+
+Imports of the following forms will be demand-loaded:
+
+ import a, b.c
+ import a.b as c
+ from a import b,c # a will be loaded immediately
+
+These imports will not be delayed:
+
+ from a import *
+ b = __import__(a)
+'''
+
+import __builtin__
+_origimport = __import__
+
+class _demandmod(object):
+ """module demand-loader and proxy"""
+ def __init__(self, name, globals, locals):
+ if '.' in name:
+ head, rest = name.split('.', 1)
+ after = [rest]
+ else:
+ head = name
+ after = []
+ object.__setattr__(self, "_data", (head, globals, locals, after))
+ object.__setattr__(self, "_module", None)
+ def _extend(self, name):
+ """add to the list of submodules to load"""
+ self._data[3].append(name)
+ def _load(self):
+ if not self._module:
+ head, globals, locals, after = self._data
+ mod = _origimport(head, globals, locals)
+ # load submodules
+ def subload(mod, p):
+ h, t = p, None
+ if '.' in p:
+ h, t = p.split('.', 1)
+ if not hasattr(mod, h):
+ setattr(mod, h, _demandmod(p, mod.__dict__, mod.__dict__))
+ elif t:
+ subload(getattr(mod, h), t)
+
+ for x in after:
+ subload(mod, x)
+
+ # are we in the locals dictionary still?
+ if locals and locals.get(head) == self:
+ locals[head] = mod
+ object.__setattr__(self, "_module", mod)
+
+ def __repr__(self):
+ if self._module:
+ return "<proxied module '%s'>" % self._data[0]
+ return "<unloaded module '%s'>" % self._data[0]
+ def __call__(self, *args, **kwargs):
+ raise TypeError("%s object is not callable" % repr(self))
+ def __getattribute__(self, attr):
+ if attr in ('_data', '_extend', '_load', '_module'):
+ return object.__getattribute__(self, attr)
+ self._load()
+ return getattr(self._module, attr)
+ def __setattr__(self, attr, val):
+ self._load()
+ setattr(self._module, attr, val)
+
+def _demandimport(name, globals=None, locals=None, fromlist=None, level=None):
+ if not locals or name in ignore or fromlist == ('*',):
+ # these cases we can't really delay
+ if level is None:
+ return _origimport(name, globals, locals, fromlist)
+ else:
+ return _origimport(name, globals, locals, fromlist, level)
+ elif not fromlist:
+ # import a [as b]
+ if '.' in name: # a.b
+ base, rest = name.split('.', 1)
+ # email.__init__ loading email.mime
+ if globals and globals.get('__name__', None) == base:
+ return _origimport(name, globals, locals, fromlist)
+ # if a is already demand-loaded, add b to its submodule list
+ if base in locals:
+ if isinstance(locals[base], _demandmod):
+ locals[base]._extend(rest)
+ return locals[base]
+ return _demandmod(name, globals, locals)
+ else:
+ if level is not None:
+ # from . import b,c,d or from .a import b,c,d
+ return _origimport(name, globals, locals, fromlist, level)
+ # from a import b,c,d
+ mod = _origimport(name, globals, locals)
+ # recurse down the module chain
+ for comp in name.split('.')[1:]:
+ if not hasattr(mod, comp):
+ setattr(mod, comp, _demandmod(comp, mod.__dict__, mod.__dict__))
+ mod = getattr(mod, comp)
+ for x in fromlist:
+ # set requested submodules for demand load
+ if not(hasattr(mod, x)):
+ setattr(mod, x, _demandmod(x, mod.__dict__, locals))
+ return mod
+
+ignore = [
+ '_hashlib',
+ '_xmlplus',
+ 'fcntl',
+ 'win32com.gen_py',
+ 'pythoncom',
+ # imported by tarfile, not available under Windows
+ 'pwd',
+ 'grp',
+ # imported by profile, itself imported by hotshot.stats,
+ # not available under Windows
+ 'resource',
+ ]
+
+def enable():
+ "enable global demand-loading of modules"
+ __builtin__.__import__ = _demandimport
+
+def disable():
+ "disable global demand-loading of modules"
+ __builtin__.__import__ = _origimport
+
diff --git a/sys/src/cmd/hg/mercurial/demandimport.pyc b/sys/src/cmd/hg/mercurial/demandimport.pyc
new file mode 100644
index 000000000..a523cb46a
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/demandimport.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/diffhelpers.c b/sys/src/cmd/hg/mercurial/diffhelpers.c
new file mode 100644
index 000000000..d9316ea4b
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/diffhelpers.c
@@ -0,0 +1,156 @@
+/*
+ * diffhelpers.c - helper routines for mpatch
+ *
+ * Copyright 2007 Chris Mason <chris.mason@oracle.com>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License v2, incorporated herein by reference.
+ */
+
+#include <Python.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char diffhelpers_doc[] = "Efficient diff parsing";
+static PyObject *diffhelpers_Error;
+
+
+/* fixup the last lines of a and b when the patch has no newline at eof */
+static void _fix_newline(PyObject *hunk, PyObject *a, PyObject *b)
+{
+ int hunksz = PyList_Size(hunk);
+ PyObject *s = PyList_GET_ITEM(hunk, hunksz-1);
+ char *l = PyString_AS_STRING(s);
+ int sz = PyString_GET_SIZE(s);
+ int alen = PyList_Size(a);
+ int blen = PyList_Size(b);
+ char c = l[0];
+
+ PyObject *hline = PyString_FromStringAndSize(l, sz-1);
+ if (c == ' ' || c == '+') {
+ PyObject *rline = PyString_FromStringAndSize(l+1, sz-2);
+ PyList_SetItem(b, blen-1, rline);
+ }
+ if (c == ' ' || c == '-') {
+ Py_INCREF(hline);
+ PyList_SetItem(a, alen-1, hline);
+ }
+ PyList_SetItem(hunk, hunksz-1, hline);
+}
+
+/* python callable form of _fix_newline */
+static PyObject *
+fix_newline(PyObject *self, PyObject *args)
+{
+ PyObject *hunk, *a, *b;
+ if (!PyArg_ParseTuple(args, "OOO", &hunk, &a, &b))
+ return NULL;
+ _fix_newline(hunk, a, b);
+ return Py_BuildValue("l", 0);
+}
+
+/*
+ * read lines from fp into the hunk. The hunk is parsed into two arrays
+ * a and b. a gets the old state of the text, b gets the new state
+ * The control char from the hunk is saved when inserting into a, but not b
+ * (for performance while deleting files)
+ */
+static PyObject *
+addlines(PyObject *self, PyObject *args)
+{
+
+ PyObject *fp, *hunk, *a, *b, *x;
+ int i;
+ int lena, lenb;
+ int num;
+ int todoa, todob;
+ char *s, c;
+ PyObject *l;
+ if (!PyArg_ParseTuple(args, "OOiiOO", &fp, &hunk, &lena, &lenb, &a, &b))
+ return NULL;
+
+ while(1) {
+ todoa = lena - PyList_Size(a);
+ todob = lenb - PyList_Size(b);
+ num = todoa > todob ? todoa : todob;
+ if (num == 0)
+ break;
+ for (i = 0 ; i < num ; i++) {
+ x = PyFile_GetLine(fp, 0);
+ s = PyString_AS_STRING(x);
+ c = *s;
+ if (strcmp(s, "\\ No newline at end of file\n") == 0) {
+ _fix_newline(hunk, a, b);
+ continue;
+ }
+ if (c == '\n') {
+ /* Some patches may be missing the control char
+ * on empty lines. Supply a leading space. */
+ Py_DECREF(x);
+ x = PyString_FromString(" \n");
+ }
+ PyList_Append(hunk, x);
+ if (c == '+') {
+ l = PyString_FromString(s + 1);
+ PyList_Append(b, l);
+ Py_DECREF(l);
+ } else if (c == '-') {
+ PyList_Append(a, x);
+ } else {
+ l = PyString_FromString(s + 1);
+ PyList_Append(b, l);
+ Py_DECREF(l);
+ PyList_Append(a, x);
+ }
+ Py_DECREF(x);
+ }
+ }
+ return Py_BuildValue("l", 0);
+}
+
+/*
+ * compare the lines in a with the lines in b. a is assumed to have
+ * a control char at the start of each line, this char is ignored in the
+ * compare
+ */
+static PyObject *
+testhunk(PyObject *self, PyObject *args)
+{
+
+ PyObject *a, *b;
+ long bstart;
+ int alen, blen;
+ int i;
+ char *sa, *sb;
+
+ if (!PyArg_ParseTuple(args, "OOl", &a, &b, &bstart))
+ return NULL;
+ alen = PyList_Size(a);
+ blen = PyList_Size(b);
+ if (alen > blen - bstart) {
+ return Py_BuildValue("l", -1);
+ }
+ for (i = 0 ; i < alen ; i++) {
+ sa = PyString_AS_STRING(PyList_GET_ITEM(a, i));
+ sb = PyString_AS_STRING(PyList_GET_ITEM(b, i + bstart));
+ if (strcmp(sa+1, sb) != 0)
+ return Py_BuildValue("l", -1);
+ }
+ return Py_BuildValue("l", 0);
+}
+
+static PyMethodDef methods[] = {
+ {"addlines", addlines, METH_VARARGS, "add lines to a hunk\n"},
+ {"fix_newline", fix_newline, METH_VARARGS, "fixup newline counters\n"},
+ {"testhunk", testhunk, METH_VARARGS, "test lines in a hunk\n"},
+ {NULL, NULL}
+};
+
+PyMODINIT_FUNC
+initdiffhelpers(void)
+{
+ Py_InitModule3("diffhelpers", methods, diffhelpers_doc);
+ diffhelpers_Error = PyErr_NewException("diffhelpers.diffhelpersError",
+ NULL, NULL);
+}
+
diff --git a/sys/src/cmd/hg/mercurial/dirstate.py b/sys/src/cmd/hg/mercurial/dirstate.py
new file mode 100644
index 000000000..c10e3a6c7
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/dirstate.py
@@ -0,0 +1,601 @@
+# dirstate.py - working directory tracking for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import nullid
+from i18n import _
+import util, ignore, osutil, parsers
+import struct, os, stat, errno
+import cStringIO, sys
+
+_unknown = ('?', 0, 0, 0)
+_format = ">cllll"
+propertycache = util.propertycache
+
+def _finddirs(path):
+ pos = path.rfind('/')
+ while pos != -1:
+ yield path[:pos]
+ pos = path.rfind('/', 0, pos)
+
+def _incdirs(dirs, path):
+ for base in _finddirs(path):
+ if base in dirs:
+ dirs[base] += 1
+ return
+ dirs[base] = 1
+
+def _decdirs(dirs, path):
+ for base in _finddirs(path):
+ if dirs[base] > 1:
+ dirs[base] -= 1
+ return
+ del dirs[base]
+
+class dirstate(object):
+
+ def __init__(self, opener, ui, root):
+ self._opener = opener
+ self._root = root
+ self._rootdir = os.path.join(root, '')
+ self._dirty = False
+ self._dirtypl = False
+ self._ui = ui
+
+ @propertycache
+ def _map(self):
+ self._read()
+ return self._map
+
+ @propertycache
+ def _copymap(self):
+ self._read()
+ return self._copymap
+
+ @propertycache
+ def _foldmap(self):
+ f = {}
+ for name in self._map:
+ f[os.path.normcase(name)] = name
+ return f
+
+ @propertycache
+ def _branch(self):
+ try:
+ return self._opener("branch").read().strip() or "default"
+ except IOError:
+ return "default"
+
+ @propertycache
+ def _pl(self):
+ try:
+ st = self._opener("dirstate").read(40)
+ l = len(st)
+ if l == 40:
+ return st[:20], st[20:40]
+ elif l > 0 and l < 40:
+ raise util.Abort(_('working directory state appears damaged!'))
+ except IOError, err:
+ if err.errno != errno.ENOENT: raise
+ return [nullid, nullid]
+
+ @propertycache
+ def _dirs(self):
+ dirs = {}
+ for f,s in self._map.iteritems():
+ if s[0] != 'r':
+ _incdirs(dirs, f)
+ return dirs
+
+ @propertycache
+ def _ignore(self):
+ files = [self._join('.hgignore')]
+ for name, path in self._ui.configitems("ui"):
+ if name == 'ignore' or name.startswith('ignore.'):
+ files.append(os.path.expanduser(path))
+ return ignore.ignore(self._root, files, self._ui.warn)
+
+ @propertycache
+ def _slash(self):
+ return self._ui.configbool('ui', 'slash') and os.sep != '/'
+
+ @propertycache
+ def _checklink(self):
+ return util.checklink(self._root)
+
+ @propertycache
+ def _checkexec(self):
+ return util.checkexec(self._root)
+
+ @propertycache
+ def _checkcase(self):
+ return not util.checkcase(self._join('.hg'))
+
+ def _join(self, f):
+ # much faster than os.path.join()
+ # it's safe because f is always a relative path
+ return self._rootdir + f
+
+ def flagfunc(self, fallback):
+ if self._checklink:
+ if self._checkexec:
+ def f(x):
+ p = self._join(x)
+ if os.path.islink(p):
+ return 'l'
+ if util.is_exec(p):
+ return 'x'
+ return ''
+ return f
+ def f(x):
+ if os.path.islink(self._join(x)):
+ return 'l'
+ if 'x' in fallback(x):
+ return 'x'
+ return ''
+ return f
+ if self._checkexec:
+ def f(x):
+ if 'l' in fallback(x):
+ return 'l'
+ if util.is_exec(self._join(x)):
+ return 'x'
+ return ''
+ return f
+ return fallback
+
+ def getcwd(self):
+ cwd = os.getcwd()
+ if cwd == self._root: return ''
+ # self._root ends with a path separator if self._root is '/' or 'C:\'
+ rootsep = self._root
+ if not util.endswithsep(rootsep):
+ rootsep += os.sep
+ if cwd.startswith(rootsep):
+ return cwd[len(rootsep):]
+ else:
+ # we're outside the repo. return an absolute path.
+ return cwd
+
+ def pathto(self, f, cwd=None):
+ if cwd is None:
+ cwd = self.getcwd()
+ path = util.pathto(self._root, cwd, f)
+ if self._slash:
+ return util.normpath(path)
+ return path
+
+ def __getitem__(self, key):
+ ''' current states:
+ n normal
+ m needs merging
+ r marked for removal
+ a marked for addition
+ ? not tracked'''
+ return self._map.get(key, ("?",))[0]
+
+ def __contains__(self, key):
+ return key in self._map
+
+ def __iter__(self):
+ for x in sorted(self._map):
+ yield x
+
+ def parents(self):
+ return self._pl
+
+ def branch(self):
+ return self._branch
+
+ def setparents(self, p1, p2=nullid):
+ self._dirty = self._dirtypl = True
+ self._pl = p1, p2
+
+ def setbranch(self, branch):
+ self._branch = branch
+ self._opener("branch", "w").write(branch + '\n')
+
+ def _read(self):
+ self._map = {}
+ self._copymap = {}
+ try:
+ st = self._opener("dirstate").read()
+ except IOError, err:
+ if err.errno != errno.ENOENT: raise
+ return
+ if not st:
+ return
+
+ p = parsers.parse_dirstate(self._map, self._copymap, st)
+ if not self._dirtypl:
+ self._pl = p
+
+ def invalidate(self):
+ for a in "_map _copymap _foldmap _branch _pl _dirs _ignore".split():
+ if a in self.__dict__:
+ delattr(self, a)
+ self._dirty = False
+
+ def copy(self, source, dest):
+ """Mark dest as a copy of source. Unmark dest if source is None.
+ """
+ if source == dest:
+ return
+ self._dirty = True
+ if source is not None:
+ self._copymap[dest] = source
+ elif dest in self._copymap:
+ del self._copymap[dest]
+
+ def copied(self, file):
+ return self._copymap.get(file, None)
+
+ def copies(self):
+ return self._copymap
+
+ def _droppath(self, f):
+ if self[f] not in "?r" and "_dirs" in self.__dict__:
+ _decdirs(self._dirs, f)
+
+ def _addpath(self, f, check=False):
+ oldstate = self[f]
+ if check or oldstate == "r":
+ if '\r' in f or '\n' in f:
+ raise util.Abort(
+ _("'\\n' and '\\r' disallowed in filenames: %r") % f)
+ if f in self._dirs:
+ raise util.Abort(_('directory %r already in dirstate') % f)
+ # shadows
+ for d in _finddirs(f):
+ if d in self._dirs:
+ break
+ if d in self._map and self[d] != 'r':
+ raise util.Abort(
+ _('file %r in dirstate clashes with %r') % (d, f))
+ if oldstate in "?r" and "_dirs" in self.__dict__:
+ _incdirs(self._dirs, f)
+
+ def normal(self, f):
+ 'mark a file normal and clean'
+ self._dirty = True
+ self._addpath(f)
+ s = os.lstat(self._join(f))
+ self._map[f] = ('n', s.st_mode, s.st_size, int(s.st_mtime))
+ if f in self._copymap:
+ del self._copymap[f]
+
+ def normallookup(self, f):
+ 'mark a file normal, but possibly dirty'
+ if self._pl[1] != nullid and f in self._map:
+ # if there is a merge going on and the file was either
+ # in state 'm' or dirty before being removed, restore that state.
+ entry = self._map[f]
+ if entry[0] == 'r' and entry[2] in (-1, -2):
+ source = self._copymap.get(f)
+ if entry[2] == -1:
+ self.merge(f)
+ elif entry[2] == -2:
+ self.normaldirty(f)
+ if source:
+ self.copy(source, f)
+ return
+ if entry[0] == 'm' or entry[0] == 'n' and entry[2] == -2:
+ return
+ self._dirty = True
+ self._addpath(f)
+ self._map[f] = ('n', 0, -1, -1)
+ if f in self._copymap:
+ del self._copymap[f]
+
+ def normaldirty(self, f):
+ 'mark a file normal, but dirty'
+ self._dirty = True
+ self._addpath(f)
+ self._map[f] = ('n', 0, -2, -1)
+ if f in self._copymap:
+ del self._copymap[f]
+
+ def add(self, f):
+ 'mark a file added'
+ self._dirty = True
+ self._addpath(f, True)
+ self._map[f] = ('a', 0, -1, -1)
+ if f in self._copymap:
+ del self._copymap[f]
+
+ def remove(self, f):
+ 'mark a file removed'
+ self._dirty = True
+ self._droppath(f)
+ size = 0
+ if self._pl[1] != nullid and f in self._map:
+ entry = self._map[f]
+ if entry[0] == 'm':
+ size = -1
+ elif entry[0] == 'n' and entry[2] == -2:
+ size = -2
+ self._map[f] = ('r', 0, size, 0)
+ if size == 0 and f in self._copymap:
+ del self._copymap[f]
+
+ def merge(self, f):
+ 'mark a file merged'
+ self._dirty = True
+ s = os.lstat(self._join(f))
+ self._addpath(f)
+ self._map[f] = ('m', s.st_mode, s.st_size, int(s.st_mtime))
+ if f in self._copymap:
+ del self._copymap[f]
+
+ def forget(self, f):
+ 'forget a file'
+ self._dirty = True
+ try:
+ self._droppath(f)
+ del self._map[f]
+ except KeyError:
+ self._ui.warn(_("not in dirstate: %s\n") % f)
+
+ def _normalize(self, path, knownpath):
+ norm_path = os.path.normcase(path)
+ fold_path = self._foldmap.get(norm_path, None)
+ if fold_path is None:
+ if knownpath or not os.path.exists(os.path.join(self._root, path)):
+ fold_path = path
+ else:
+ fold_path = self._foldmap.setdefault(norm_path,
+ util.fspath(path, self._root))
+ return fold_path
+
+ def clear(self):
+ self._map = {}
+ if "_dirs" in self.__dict__:
+ delattr(self, "_dirs");
+ self._copymap = {}
+ self._pl = [nullid, nullid]
+ self._dirty = True
+
+ def rebuild(self, parent, files):
+ self.clear()
+ for f in files:
+ if 'x' in files.flags(f):
+ self._map[f] = ('n', 0777, -1, 0)
+ else:
+ self._map[f] = ('n', 0666, -1, 0)
+ self._pl = (parent, nullid)
+ self._dirty = True
+
+ def write(self):
+ if not self._dirty:
+ return
+ st = self._opener("dirstate", "w", atomictemp=True)
+
+ try:
+ gran = int(self._ui.config('dirstate', 'granularity', 1))
+ except ValueError:
+ gran = 1
+ limit = sys.maxint
+ if gran > 0:
+ limit = util.fstat(st).st_mtime - gran
+
+ cs = cStringIO.StringIO()
+ copymap = self._copymap
+ pack = struct.pack
+ write = cs.write
+ write("".join(self._pl))
+ for f, e in self._map.iteritems():
+ if f in copymap:
+ f = "%s\0%s" % (f, copymap[f])
+ if e[3] > limit and e[0] == 'n':
+ e = (e[0], 0, -1, -1)
+ e = pack(_format, e[0], e[1], e[2], e[3], len(f))
+ write(e)
+ write(f)
+ st.write(cs.getvalue())
+ st.rename()
+ self._dirty = self._dirtypl = False
+
+ def _dirignore(self, f):
+ if f == '.':
+ return False
+ if self._ignore(f):
+ return True
+ for p in _finddirs(f):
+ if self._ignore(p):
+ return True
+ return False
+
+ def walk(self, match, unknown, ignored):
+ '''
+ walk recursively through the directory tree, finding all files
+ matched by the match function
+
+ results are yielded in a tuple (filename, stat), where stat
+ and st is the stat result if the file was found in the directory.
+ '''
+
+ def fwarn(f, msg):
+ self._ui.warn('%s: %s\n' % (self.pathto(f), msg))
+ return False
+
+ def badtype(mode):
+ kind = _('unknown')
+ if stat.S_ISCHR(mode): kind = _('character device')
+ elif stat.S_ISBLK(mode): kind = _('block device')
+ elif stat.S_ISFIFO(mode): kind = _('fifo')
+ elif stat.S_ISSOCK(mode): kind = _('socket')
+ elif stat.S_ISDIR(mode): kind = _('directory')
+ return _('unsupported file type (type is %s)') % kind
+
+ ignore = self._ignore
+ dirignore = self._dirignore
+ if ignored:
+ ignore = util.never
+ dirignore = util.never
+ elif not unknown:
+ # if unknown and ignored are False, skip step 2
+ ignore = util.always
+ dirignore = util.always
+
+ matchfn = match.matchfn
+ badfn = match.bad
+ dmap = self._map
+ normpath = util.normpath
+ listdir = osutil.listdir
+ lstat = os.lstat
+ getkind = stat.S_IFMT
+ dirkind = stat.S_IFDIR
+ regkind = stat.S_IFREG
+ lnkkind = stat.S_IFLNK
+ join = self._join
+ work = []
+ wadd = work.append
+
+ if self._checkcase:
+ normalize = self._normalize
+ else:
+ normalize = lambda x, y: x
+
+ exact = skipstep3 = False
+ if matchfn == match.exact: # match.exact
+ exact = True
+ dirignore = util.always # skip step 2
+ elif match.files() and not match.anypats(): # match.match, no patterns
+ skipstep3 = True
+
+ files = set(match.files())
+ if not files or '.' in files:
+ files = ['']
+ results = {'.hg': None}
+
+ # step 1: find all explicit files
+ for ff in sorted(files):
+ nf = normalize(normpath(ff), False)
+ if nf in results:
+ continue
+
+ try:
+ st = lstat(join(nf))
+ kind = getkind(st.st_mode)
+ if kind == dirkind:
+ skipstep3 = False
+ if nf in dmap:
+ #file deleted on disk but still in dirstate
+ results[nf] = None
+ match.dir(nf)
+ if not dirignore(nf):
+ wadd(nf)
+ elif kind == regkind or kind == lnkkind:
+ results[nf] = st
+ else:
+ badfn(ff, badtype(kind))
+ if nf in dmap:
+ results[nf] = None
+ except OSError, inst:
+ if nf in dmap: # does it exactly match a file?
+ results[nf] = None
+ else: # does it match a directory?
+ prefix = nf + "/"
+ for fn in dmap:
+ if fn.startswith(prefix):
+ match.dir(nf)
+ skipstep3 = False
+ break
+ else:
+ badfn(ff, inst.strerror)
+
+ # step 2: visit subdirectories
+ while work:
+ nd = work.pop()
+ skip = None
+ if nd == '.':
+ nd = ''
+ else:
+ skip = '.hg'
+ try:
+ entries = listdir(join(nd), stat=True, skip=skip)
+ except OSError, inst:
+ if inst.errno == errno.EACCES:
+ fwarn(nd, inst.strerror)
+ continue
+ raise
+ for f, kind, st in entries:
+ nf = normalize(nd and (nd + "/" + f) or f, True)
+ if nf not in results:
+ if kind == dirkind:
+ if not ignore(nf):
+ match.dir(nf)
+ wadd(nf)
+ if nf in dmap and matchfn(nf):
+ results[nf] = None
+ elif kind == regkind or kind == lnkkind:
+ if nf in dmap:
+ if matchfn(nf):
+ results[nf] = st
+ elif matchfn(nf) and not ignore(nf):
+ results[nf] = st
+ elif nf in dmap and matchfn(nf):
+ results[nf] = None
+
+ # step 3: report unseen items in the dmap hash
+ if not skipstep3 and not exact:
+ visit = sorted([f for f in dmap if f not in results and matchfn(f)])
+ for nf, st in zip(visit, util.statfiles([join(i) for i in visit])):
+ if not st is None and not getkind(st.st_mode) in (regkind, lnkkind):
+ st = None
+ results[nf] = st
+
+ del results['.hg']
+ return results
+
+ def status(self, match, ignored, clean, unknown):
+ listignored, listclean, listunknown = ignored, clean, unknown
+ lookup, modified, added, unknown, ignored = [], [], [], [], []
+ removed, deleted, clean = [], [], []
+
+ dmap = self._map
+ ladd = lookup.append
+ madd = modified.append
+ aadd = added.append
+ uadd = unknown.append
+ iadd = ignored.append
+ radd = removed.append
+ dadd = deleted.append
+ cadd = clean.append
+
+ for fn, st in self.walk(match, listunknown, listignored).iteritems():
+ if fn not in dmap:
+ if (listignored or match.exact(fn)) and self._dirignore(fn):
+ if listignored:
+ iadd(fn)
+ elif listunknown:
+ uadd(fn)
+ continue
+
+ state, mode, size, time = dmap[fn]
+
+ if not st and state in "nma":
+ dadd(fn)
+ elif state == 'n':
+ if (size >= 0 and
+ (size != st.st_size
+ or ((mode ^ st.st_mode) & 0100 and self._checkexec))
+ or size == -2
+ or fn in self._copymap):
+ madd(fn)
+ elif time != int(st.st_mtime):
+ ladd(fn)
+ elif listclean:
+ cadd(fn)
+ elif state == 'm':
+ madd(fn)
+ elif state == 'a':
+ aadd(fn)
+ elif state == 'r':
+ radd(fn)
+
+ return (lookup, modified, added, removed, deleted, unknown, ignored,
+ clean)
diff --git a/sys/src/cmd/hg/mercurial/dispatch.py b/sys/src/cmd/hg/mercurial/dispatch.py
new file mode 100644
index 000000000..a01cf8204
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/dispatch.py
@@ -0,0 +1,501 @@
+# dispatch.py - command dispatching for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import os, sys, atexit, signal, pdb, socket, errno, shlex, time
+import util, commands, hg, fancyopts, extensions, hook, error
+import cmdutil, encoding
+import ui as _ui
+
+def run():
+ "run the command in sys.argv"
+ sys.exit(dispatch(sys.argv[1:]))
+
+def dispatch(args):
+ "run the command specified in args"
+ try:
+ u = _ui.ui()
+ if '--traceback' in args:
+ u.setconfig('ui', 'traceback', 'on')
+ except util.Abort, inst:
+ sys.stderr.write(_("abort: %s\n") % inst)
+ return -1
+ return _runcatch(u, args)
+
+def _runcatch(ui, args):
+ def catchterm(*args):
+ raise error.SignalInterrupt
+
+ for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
+ num = getattr(signal, name, None)
+ if num: signal.signal(num, catchterm)
+
+ try:
+ try:
+ # enter the debugger before command execution
+ if '--debugger' in args:
+ pdb.set_trace()
+ try:
+ return _dispatch(ui, args)
+ finally:
+ ui.flush()
+ except:
+ # enter the debugger when we hit an exception
+ if '--debugger' in args:
+ pdb.post_mortem(sys.exc_info()[2])
+ ui.traceback()
+ raise
+
+ # Global exception handling, alphabetically
+ # Mercurial-specific first, followed by built-in and library exceptions
+ except error.AmbiguousCommand, inst:
+ ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
+ (inst.args[0], " ".join(inst.args[1])))
+ except error.ConfigError, inst:
+ ui.warn(_("hg: %s\n") % inst.args[0])
+ except error.LockHeld, inst:
+ if inst.errno == errno.ETIMEDOUT:
+ reason = _('timed out waiting for lock held by %s') % inst.locker
+ else:
+ reason = _('lock held by %s') % inst.locker
+ ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
+ except error.LockUnavailable, inst:
+ ui.warn(_("abort: could not lock %s: %s\n") %
+ (inst.desc or inst.filename, inst.strerror))
+ except error.ParseError, inst:
+ if inst.args[0]:
+ ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
+ commands.help_(ui, inst.args[0])
+ else:
+ ui.warn(_("hg: %s\n") % inst.args[1])
+ commands.help_(ui, 'shortlist')
+ except error.RepoError, inst:
+ ui.warn(_("abort: %s!\n") % inst)
+ except error.ResponseError, inst:
+ ui.warn(_("abort: %s") % inst.args[0])
+ if not isinstance(inst.args[1], basestring):
+ ui.warn(" %r\n" % (inst.args[1],))
+ elif not inst.args[1]:
+ ui.warn(_(" empty string\n"))
+ else:
+ ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
+ except error.RevlogError, inst:
+ ui.warn(_("abort: %s!\n") % inst)
+ except error.SignalInterrupt:
+ ui.warn(_("killed!\n"))
+ except error.UnknownCommand, inst:
+ ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
+ commands.help_(ui, 'shortlist')
+ except util.Abort, inst:
+ ui.warn(_("abort: %s\n") % inst)
+ except ImportError, inst:
+ m = str(inst).split()[-1]
+ ui.warn(_("abort: could not import module %s!\n") % m)
+ if m in "mpatch bdiff".split():
+ ui.warn(_("(did you forget to compile extensions?)\n"))
+ elif m in "zlib".split():
+ ui.warn(_("(is your Python install correct?)\n"))
+ except IOError, inst:
+ if hasattr(inst, "code"):
+ ui.warn(_("abort: %s\n") % inst)
+ elif hasattr(inst, "reason"):
+ try: # usually it is in the form (errno, strerror)
+ reason = inst.reason.args[1]
+ except: # it might be anything, for example a string
+ reason = inst.reason
+ ui.warn(_("abort: error: %s\n") % reason)
+ elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
+ if ui.debugflag:
+ ui.warn(_("broken pipe\n"))
+ elif getattr(inst, "strerror", None):
+ if getattr(inst, "filename", None):
+ ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
+ else:
+ ui.warn(_("abort: %s\n") % inst.strerror)
+ else:
+ raise
+ except OSError, inst:
+ if getattr(inst, "filename", None):
+ ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
+ else:
+ ui.warn(_("abort: %s\n") % inst.strerror)
+ except KeyboardInterrupt:
+ try:
+ ui.warn(_("interrupted!\n"))
+ except IOError, inst:
+ if inst.errno == errno.EPIPE:
+ if ui.debugflag:
+ ui.warn(_("\nbroken pipe\n"))
+ else:
+ raise
+ except MemoryError:
+ ui.warn(_("abort: out of memory\n"))
+ except SystemExit, inst:
+ # Commands shouldn't sys.exit directly, but give a return code.
+ # Just in case catch this and and pass exit code to caller.
+ return inst.code
+ except socket.error, inst:
+ ui.warn(_("abort: %s\n") % inst.args[-1])
+ except:
+ ui.warn(_("** unknown exception encountered, details follow\n"))
+ ui.warn(_("** report bug details to "
+ "http://mercurial.selenic.com/bts/\n"))
+ ui.warn(_("** or mercurial@selenic.com\n"))
+ ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
+ % util.version())
+ ui.warn(_("** Extensions loaded: %s\n")
+ % ", ".join([x[0] for x in extensions.extensions()]))
+ raise
+
+ return -1
+
+def _findrepo(p):
+ while not os.path.isdir(os.path.join(p, ".hg")):
+ oldp, p = p, os.path.dirname(p)
+ if p == oldp:
+ return None
+
+ return p
+
+def aliasargs(fn):
+ if hasattr(fn, 'args'):
+ return fn.args
+ return []
+
+class cmdalias(object):
+ def __init__(self, name, definition, cmdtable):
+ self.name = name
+ self.definition = definition
+ self.args = []
+ self.opts = []
+ self.help = ''
+ self.norepo = True
+
+ try:
+ cmdutil.findcmd(self.name, cmdtable, True)
+ self.shadows = True
+ except error.UnknownCommand:
+ self.shadows = False
+
+ if not self.definition:
+ def fn(ui, *args):
+ ui.warn(_("no definition for alias '%s'\n") % self.name)
+ return 1
+ self.fn = fn
+
+ return
+
+ args = shlex.split(self.definition)
+ cmd = args.pop(0)
+ opts = []
+ help = ''
+
+ try:
+ self.fn, self.opts, self.help = cmdutil.findcmd(cmd, cmdtable, False)[1]
+ self.args = aliasargs(self.fn) + args
+ if cmd not in commands.norepo.split(' '):
+ self.norepo = False
+ except error.UnknownCommand:
+ def fn(ui, *args):
+ ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
+ % (self.name, cmd))
+ return 1
+ self.fn = fn
+ except error.AmbiguousCommand:
+ def fn(ui, *args):
+ ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
+ % (self.name, cmd))
+ return 1
+ self.fn = fn
+
+ def __call__(self, ui, *args, **opts):
+ if self.shadows:
+ ui.debug(_("alias '%s' shadows command\n") % self.name)
+
+ return self.fn(ui, *args, **opts)
+
+def addaliases(ui, cmdtable):
+ # aliases are processed after extensions have been loaded, so they
+ # may use extension commands. Aliases can also use other alias definitions,
+ # but only if they have been defined prior to the current definition.
+ for alias, definition in ui.configitems('alias'):
+ aliasdef = cmdalias(alias, definition, cmdtable)
+ cmdtable[alias] = (aliasdef, aliasdef.opts, aliasdef.help)
+ if aliasdef.norepo:
+ commands.norepo += ' %s' % alias
+
+def _parse(ui, args):
+ options = {}
+ cmdoptions = {}
+
+ try:
+ args = fancyopts.fancyopts(args, commands.globalopts, options)
+ except fancyopts.getopt.GetoptError, inst:
+ raise error.ParseError(None, inst)
+
+ if args:
+ cmd, args = args[0], args[1:]
+ aliases, i = cmdutil.findcmd(cmd, commands.table,
+ ui.config("ui", "strict"))
+ cmd = aliases[0]
+ args = aliasargs(i[0]) + args
+ defaults = ui.config("defaults", cmd)
+ if defaults:
+ args = shlex.split(defaults) + args
+ c = list(i[1])
+ else:
+ cmd = None
+ c = []
+
+ # combine global options into local
+ for o in commands.globalopts:
+ c.append((o[0], o[1], options[o[1]], o[3]))
+
+ try:
+ args = fancyopts.fancyopts(args, c, cmdoptions, True)
+ except fancyopts.getopt.GetoptError, inst:
+ raise error.ParseError(cmd, inst)
+
+ # separate global options back out
+ for o in commands.globalopts:
+ n = o[1]
+ options[n] = cmdoptions[n]
+ del cmdoptions[n]
+
+ return (cmd, cmd and i[0] or None, args, options, cmdoptions)
+
+def _parseconfig(ui, config):
+ """parse the --config options from the command line"""
+ for cfg in config:
+ try:
+ name, value = cfg.split('=', 1)
+ section, name = name.split('.', 1)
+ if not section or not name:
+ raise IndexError
+ ui.setconfig(section, name, value)
+ except (IndexError, ValueError):
+ raise util.Abort(_('malformed --config option: %s') % cfg)
+
+def _earlygetopt(aliases, args):
+ """Return list of values for an option (or aliases).
+
+ The values are listed in the order they appear in args.
+ The options and values are removed from args.
+ """
+ try:
+ argcount = args.index("--")
+ except ValueError:
+ argcount = len(args)
+ shortopts = [opt for opt in aliases if len(opt) == 2]
+ values = []
+ pos = 0
+ while pos < argcount:
+ if args[pos] in aliases:
+ if pos + 1 >= argcount:
+ # ignore and let getopt report an error if there is no value
+ break
+ del args[pos]
+ values.append(args.pop(pos))
+ argcount -= 2
+ elif args[pos][:2] in shortopts:
+ # short option can have no following space, e.g. hg log -Rfoo
+ values.append(args.pop(pos)[2:])
+ argcount -= 1
+ else:
+ pos += 1
+ return values
+
+def runcommand(lui, repo, cmd, fullargs, ui, options, d):
+ # run pre-hook, and abort if it fails
+ ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
+ if ret:
+ return ret
+ ret = _runcommand(ui, options, cmd, d)
+ # run post-hook, passing command result
+ hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
+ result = ret)
+ return ret
+
+_loaded = set()
+def _dispatch(ui, args):
+ # read --config before doing anything else
+ # (e.g. to change trust settings for reading .hg/hgrc)
+ _parseconfig(ui, _earlygetopt(['--config'], args))
+
+ # check for cwd
+ cwd = _earlygetopt(['--cwd'], args)
+ if cwd:
+ os.chdir(cwd[-1])
+
+ # read the local repository .hgrc into a local ui object
+ path = _findrepo(os.getcwd()) or ""
+ if not path:
+ lui = ui
+ if path:
+ try:
+ lui = ui.copy()
+ lui.readconfig(os.path.join(path, ".hg", "hgrc"))
+ except IOError:
+ pass
+
+ # now we can expand paths, even ones in .hg/hgrc
+ rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
+ if rpath:
+ path = lui.expandpath(rpath[-1])
+ lui = ui.copy()
+ lui.readconfig(os.path.join(path, ".hg", "hgrc"))
+
+ extensions.loadall(lui)
+ for name, module in extensions.extensions():
+ if name in _loaded:
+ continue
+
+ # setup extensions
+ # TODO this should be generalized to scheme, where extensions can
+ # redepend on other extensions. then we should toposort them, and
+ # do initialization in correct order
+ extsetup = getattr(module, 'extsetup', None)
+ if extsetup:
+ extsetup()
+
+ cmdtable = getattr(module, 'cmdtable', {})
+ overrides = [cmd for cmd in cmdtable if cmd in commands.table]
+ if overrides:
+ ui.warn(_("extension '%s' overrides commands: %s\n")
+ % (name, " ".join(overrides)))
+ commands.table.update(cmdtable)
+ _loaded.add(name)
+
+ addaliases(lui, commands.table)
+
+ # check for fallback encoding
+ fallback = lui.config('ui', 'fallbackencoding')
+ if fallback:
+ encoding.fallbackencoding = fallback
+
+ fullargs = args
+ cmd, func, args, options, cmdoptions = _parse(lui, args)
+
+ if options["config"]:
+ raise util.Abort(_("Option --config may not be abbreviated!"))
+ if options["cwd"]:
+ raise util.Abort(_("Option --cwd may not be abbreviated!"))
+ if options["repository"]:
+ raise util.Abort(_(
+ "Option -R has to be separated from other options (e.g. not -qR) "
+ "and --repository may only be abbreviated as --repo!"))
+
+ if options["encoding"]:
+ encoding.encoding = options["encoding"]
+ if options["encodingmode"]:
+ encoding.encodingmode = options["encodingmode"]
+ if options["time"]:
+ def get_times():
+ t = os.times()
+ if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
+ t = (t[0], t[1], t[2], t[3], time.clock())
+ return t
+ s = get_times()
+ def print_time():
+ t = get_times()
+ ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
+ (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
+ atexit.register(print_time)
+
+ if options['verbose'] or options['debug'] or options['quiet']:
+ ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
+ ui.setconfig('ui', 'debug', str(bool(options['debug'])))
+ ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
+ if options['traceback']:
+ ui.setconfig('ui', 'traceback', 'on')
+ if options['noninteractive']:
+ ui.setconfig('ui', 'interactive', 'off')
+
+ if options['help']:
+ return commands.help_(ui, cmd, options['version'])
+ elif options['version']:
+ return commands.version_(ui)
+ elif not cmd:
+ return commands.help_(ui, 'shortlist')
+
+ repo = None
+ if cmd not in commands.norepo.split():
+ try:
+ repo = hg.repository(ui, path=path)
+ ui = repo.ui
+ if not repo.local():
+ raise util.Abort(_("repository '%s' is not local") % path)
+ ui.setconfig("bundle", "mainreporoot", repo.root)
+ except error.RepoError:
+ if cmd not in commands.optionalrepo.split():
+ if args and not path: # try to infer -R from command args
+ repos = map(_findrepo, args)
+ guess = repos[0]
+ if guess and repos.count(guess) == len(repos):
+ return _dispatch(ui, ['--repository', guess] + fullargs)
+ if not path:
+ raise error.RepoError(_("There is no Mercurial repository"
+ " here (.hg not found)"))
+ raise
+ args.insert(0, repo)
+ elif rpath:
+ ui.warn("warning: --repository ignored\n")
+
+ d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
+ return runcommand(lui, repo, cmd, fullargs, ui, options, d)
+
+def _runcommand(ui, options, cmd, cmdfunc):
+ def checkargs():
+ try:
+ return cmdfunc()
+ except error.SignatureError:
+ raise error.ParseError(cmd, _("invalid arguments"))
+
+ if options['profile']:
+ format = ui.config('profiling', 'format', default='text')
+
+ if not format in ['text', 'kcachegrind']:
+ ui.warn(_("unrecognized profiling format '%s'"
+ " - Ignored\n") % format)
+ format = 'text'
+
+ output = ui.config('profiling', 'output')
+
+ if output:
+ path = os.path.expanduser(output)
+ path = ui.expandpath(path)
+ ostream = open(path, 'wb')
+ else:
+ ostream = sys.stderr
+
+ try:
+ from mercurial import lsprof
+ except ImportError:
+ raise util.Abort(_(
+ 'lsprof not available - install from '
+ 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
+ p = lsprof.Profiler()
+ p.enable(subcalls=True)
+ try:
+ return checkargs()
+ finally:
+ p.disable()
+
+ if format == 'kcachegrind':
+ import lsprofcalltree
+ calltree = lsprofcalltree.KCacheGrind(p)
+ calltree.output(ostream)
+ else:
+ # format == 'text'
+ stats = lsprof.Stats(p.getstats())
+ stats.sort()
+ stats.pprint(top=10, file=ostream, climit=5)
+
+ if output:
+ ostream.close()
+ else:
+ return checkargs()
diff --git a/sys/src/cmd/hg/mercurial/dispatch.pyc b/sys/src/cmd/hg/mercurial/dispatch.pyc
new file mode 100644
index 000000000..65dffb803
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/dispatch.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/encoding.py b/sys/src/cmd/hg/mercurial/encoding.py
new file mode 100644
index 000000000..b286cc865
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/encoding.py
@@ -0,0 +1,75 @@
+# encoding.py - character transcoding support for Mercurial
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import error
+import sys, unicodedata, locale, os
+
+_encodingfixup = {'646': 'ascii', 'ANSI_X3.4-1968': 'ascii'}
+
+try:
+ encoding = os.environ.get("HGENCODING")
+ if sys.platform == 'darwin' and not encoding:
+ # On darwin, getpreferredencoding ignores the locale environment and
+ # always returns mac-roman. We override this if the environment is
+ # not C (has been customized by the user).
+ locale.setlocale(locale.LC_CTYPE, '')
+ encoding = locale.getlocale()[1]
+ if not encoding:
+ encoding = locale.getpreferredencoding() or 'ascii'
+ encoding = _encodingfixup.get(encoding, encoding)
+except locale.Error:
+ encoding = 'ascii'
+encodingmode = os.environ.get("HGENCODINGMODE", "strict")
+fallbackencoding = 'ISO-8859-1'
+
+def tolocal(s):
+ """
+ Convert a string from internal UTF-8 to local encoding
+
+ All internal strings should be UTF-8 but some repos before the
+ implementation of locale support may contain latin1 or possibly
+ other character sets. We attempt to decode everything strictly
+ using UTF-8, then Latin-1, and failing that, we use UTF-8 and
+ replace unknown characters.
+ """
+ for e in ('UTF-8', fallbackencoding):
+ try:
+ u = s.decode(e) # attempt strict decoding
+ return u.encode(encoding, "replace")
+ except LookupError, k:
+ raise error.Abort("%s, please check your locale settings" % k)
+ except UnicodeDecodeError:
+ pass
+ u = s.decode("utf-8", "replace") # last ditch
+ return u.encode(encoding, "replace")
+
+def fromlocal(s):
+ """
+ Convert a string from the local character encoding to UTF-8
+
+ We attempt to decode strings using the encoding mode set by
+ HGENCODINGMODE, which defaults to 'strict'. In this mode, unknown
+ characters will cause an error message. Other modes include
+ 'replace', which replaces unknown characters with a special
+ Unicode character, and 'ignore', which drops the character.
+ """
+ try:
+ return s.decode(encoding, encodingmode).encode("utf-8")
+ except UnicodeDecodeError, inst:
+ sub = s[max(0, inst.start-10):inst.start+10]
+ raise error.Abort("decoding near '%s': %s!" % (sub, inst))
+ except LookupError, k:
+ raise error.Abort("%s, please check your locale settings" % k)
+
+def colwidth(s):
+ "Find the column width of a UTF-8 string for display"
+ d = s.decode(encoding, 'replace')
+ if hasattr(unicodedata, 'east_asian_width'):
+ w = unicodedata.east_asian_width
+ return sum([w(c) in 'WF' and 2 or 1 for c in d])
+ return len(d)
+
diff --git a/sys/src/cmd/hg/mercurial/encoding.pyc b/sys/src/cmd/hg/mercurial/encoding.pyc
new file mode 100644
index 000000000..2a3b87c44
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/encoding.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/error.py b/sys/src/cmd/hg/mercurial/error.py
new file mode 100644
index 000000000..f4ed42e33
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/error.py
@@ -0,0 +1,72 @@
+# error.py - Mercurial exceptions
+#
+# Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+"""Mercurial exceptions.
+
+This allows us to catch exceptions at higher levels without forcing
+imports.
+"""
+
+# Do not import anything here, please
+
+class RevlogError(Exception):
+ pass
+
+class LookupError(RevlogError, KeyError):
+ def __init__(self, name, index, message):
+ self.name = name
+ if isinstance(name, str) and len(name) == 20:
+ from node import short
+ name = short(name)
+ RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
+
+ def __str__(self):
+ return RevlogError.__str__(self)
+
+class ParseError(Exception):
+ """Exception raised on errors in parsing the command line."""
+
+class ConfigError(Exception):
+ 'Exception raised when parsing config files'
+
+class RepoError(Exception):
+ pass
+
+class CapabilityError(RepoError):
+ pass
+
+class LockError(IOError):
+ def __init__(self, errno, strerror, filename, desc):
+ IOError.__init__(self, errno, strerror, filename)
+ self.desc = desc
+
+class LockHeld(LockError):
+ def __init__(self, errno, filename, desc, locker):
+ LockError.__init__(self, errno, 'Lock held', filename, desc)
+ self.locker = locker
+
+class LockUnavailable(LockError):
+ pass
+
+class ResponseError(Exception):
+ """Raised to print an error with part of output and exit."""
+
+class UnknownCommand(Exception):
+ """Exception raised if command is not in the command table."""
+
+class AmbiguousCommand(Exception):
+ """Exception raised if command shortcut matches more than one command."""
+
+# derived from KeyboardInterrupt to simplify some breakout code
+class SignalInterrupt(KeyboardInterrupt):
+ """Exception raised on SIGTERM and SIGHUP."""
+
+class SignatureError(Exception):
+ pass
+
+class Abort(Exception):
+ """Raised if a command needs to print an error and exit."""
diff --git a/sys/src/cmd/hg/mercurial/error.pyc b/sys/src/cmd/hg/mercurial/error.pyc
new file mode 100644
index 000000000..f52728623
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/error.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/extensions.py b/sys/src/cmd/hg/mercurial/extensions.py
new file mode 100644
index 000000000..30da1ebd1
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/extensions.py
@@ -0,0 +1,178 @@
+# extensions.py - extension handling for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import imp, os
+import util, cmdutil, help
+from i18n import _, gettext
+
+_extensions = {}
+_order = []
+
+def extensions():
+ for name in _order:
+ module = _extensions[name]
+ if module:
+ yield name, module
+
+def find(name):
+ '''return module with given extension name'''
+ try:
+ return _extensions[name]
+ except KeyError:
+ for k, v in _extensions.iteritems():
+ if k.endswith('.' + name) or k.endswith('/' + name):
+ return v
+ raise KeyError(name)
+
+def loadpath(path, module_name):
+ module_name = module_name.replace('.', '_')
+ path = os.path.expanduser(path)
+ if os.path.isdir(path):
+ # module/__init__.py style
+ d, f = os.path.split(path.rstrip('/'))
+ fd, fpath, desc = imp.find_module(f, [d])
+ return imp.load_module(module_name, fd, fpath, desc)
+ else:
+ return imp.load_source(module_name, path)
+
+def load(ui, name, path):
+ if name.startswith('hgext.') or name.startswith('hgext/'):
+ shortname = name[6:]
+ else:
+ shortname = name
+ if shortname in _extensions:
+ return
+ _extensions[shortname] = None
+ if path:
+ # the module will be loaded in sys.modules
+ # choose an unique name so that it doesn't
+ # conflicts with other modules
+ mod = loadpath(path, 'hgext.%s' % name)
+ else:
+ def importh(name):
+ mod = __import__(name)
+ components = name.split('.')
+ for comp in components[1:]:
+ mod = getattr(mod, comp)
+ return mod
+ try:
+ mod = importh("hgext.%s" % name)
+ except ImportError:
+ mod = importh(name)
+ _extensions[shortname] = mod
+ _order.append(shortname)
+
+ uisetup = getattr(mod, 'uisetup', None)
+ if uisetup:
+ uisetup(ui)
+
+def loadall(ui):
+ result = ui.configitems("extensions")
+ for (name, path) in result:
+ if path:
+ if path[0] == '!':
+ continue
+ try:
+ load(ui, name, path)
+ except KeyboardInterrupt:
+ raise
+ except Exception, inst:
+ if path:
+ ui.warn(_("*** failed to import extension %s from %s: %s\n")
+ % (name, path, inst))
+ else:
+ ui.warn(_("*** failed to import extension %s: %s\n")
+ % (name, inst))
+ if ui.traceback():
+ return 1
+
+def wrapcommand(table, command, wrapper):
+ aliases, entry = cmdutil.findcmd(command, table)
+ for alias, e in table.iteritems():
+ if e is entry:
+ key = alias
+ break
+
+ origfn = entry[0]
+ def wrap(*args, **kwargs):
+ return util.checksignature(wrapper)(
+ util.checksignature(origfn), *args, **kwargs)
+
+ wrap.__doc__ = getattr(origfn, '__doc__')
+ wrap.__module__ = getattr(origfn, '__module__')
+
+ newentry = list(entry)
+ newentry[0] = wrap
+ table[key] = tuple(newentry)
+ return entry
+
+def wrapfunction(container, funcname, wrapper):
+ def wrap(*args, **kwargs):
+ return wrapper(origfn, *args, **kwargs)
+
+ origfn = getattr(container, funcname)
+ setattr(container, funcname, wrap)
+ return origfn
+
+def disabled():
+ '''find disabled extensions from hgext
+ returns a dict of {name: desc}, and the max name length'''
+
+ import hgext
+ extpath = os.path.dirname(os.path.abspath(hgext.__file__))
+
+ try: # might not be a filesystem path
+ files = os.listdir(extpath)
+ except OSError:
+ return None, 0
+
+ exts = {}
+ maxlength = 0
+ for e in files:
+
+ if e.endswith('.py'):
+ name = e.rsplit('.', 1)[0]
+ path = os.path.join(extpath, e)
+ else:
+ name = e
+ path = os.path.join(extpath, e, '__init__.py')
+ if not os.path.exists(path):
+ continue
+
+ if name in exts or name in _order or name == '__init__':
+ continue
+
+ try:
+ file = open(path)
+ except IOError:
+ continue
+ else:
+ doc = help.moduledoc(file)
+ file.close()
+
+ if doc: # extracting localized synopsis
+ exts[name] = gettext(doc).splitlines()[0]
+ else:
+ exts[name] = _('(no help text available)')
+
+ if len(name) > maxlength:
+ maxlength = len(name)
+
+ return exts, maxlength
+
+def enabled():
+ '''return a dict of {name: desc} of extensions, and the max name length'''
+ exts = {}
+ maxlength = 0
+ exthelps = []
+ for ename, ext in extensions():
+ doc = (gettext(ext.__doc__) or _('(no help text available)'))
+ ename = ename.split('.')[-1]
+ maxlength = max(len(ename), maxlength)
+ exts[ename] = doc.splitlines()[0].strip()
+
+ return exts, maxlength
diff --git a/sys/src/cmd/hg/mercurial/extensions.pyc b/sys/src/cmd/hg/mercurial/extensions.pyc
new file mode 100644
index 000000000..03e075dd8
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/extensions.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/fancyopts.py b/sys/src/cmd/hg/mercurial/fancyopts.py
new file mode 100644
index 000000000..5acf0143d
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/fancyopts.py
@@ -0,0 +1,110 @@
+# fancyopts.py - better command line parsing
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import getopt
+
+def gnugetopt(args, options, longoptions):
+ """Parse options mostly like getopt.gnu_getopt.
+
+ This is different from getopt.gnu_getopt in that an argument of - will
+ become an argument of - instead of vanishing completely.
+ """
+ extraargs = []
+ if '--' in args:
+ stopindex = args.index('--')
+ extraargs = args[stopindex+1:]
+ args = args[:stopindex]
+ opts, parseargs = getopt.getopt(args, options, longoptions)
+ args = []
+ while parseargs:
+ arg = parseargs.pop(0)
+ if arg and arg[0] == '-' and len(arg) > 1:
+ parseargs.insert(0, arg)
+ topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
+ opts = opts + topts
+ parseargs = newparseargs
+ else:
+ args.append(arg)
+ args.extend(extraargs)
+ return opts, args
+
+
+def fancyopts(args, options, state, gnu=False):
+ """
+ read args, parse options, and store options in state
+
+ each option is a tuple of:
+
+ short option or ''
+ long option
+ default value
+ description
+
+ option types include:
+
+ boolean or none - option sets variable in state to true
+ string - parameter string is stored in state
+ list - parameter string is added to a list
+ integer - parameter strings is stored as int
+ function - call function with parameter
+
+ non-option args are returned
+ """
+ namelist = []
+ shortlist = ''
+ argmap = {}
+ defmap = {}
+
+ for short, name, default, comment in options:
+ # convert opts to getopt format
+ oname = name
+ name = name.replace('-', '_')
+
+ argmap['-' + short] = argmap['--' + oname] = name
+ defmap[name] = default
+
+ # copy defaults to state
+ if isinstance(default, list):
+ state[name] = default[:]
+ elif hasattr(default, '__call__'):
+ state[name] = None
+ else:
+ state[name] = default
+
+ # does it take a parameter?
+ if not (default is None or default is True or default is False):
+ if short: short += ':'
+ if oname: oname += '='
+ if short:
+ shortlist += short
+ if name:
+ namelist.append(oname)
+
+ # parse arguments
+ if gnu:
+ parse = gnugetopt
+ else:
+ parse = getopt.getopt
+ opts, args = parse(args, shortlist, namelist)
+
+ # transfer result to state
+ for opt, val in opts:
+ name = argmap[opt]
+ t = type(defmap[name])
+ if t is type(fancyopts):
+ state[name] = defmap[name](val)
+ elif t is type(1):
+ state[name] = int(val)
+ elif t is type(''):
+ state[name] = val
+ elif t is type([]):
+ state[name].append(val)
+ elif t is type(None) or t is type(False):
+ state[name] = True
+
+ # return unparsed args
+ return args
diff --git a/sys/src/cmd/hg/mercurial/fancyopts.pyc b/sys/src/cmd/hg/mercurial/fancyopts.pyc
new file mode 100644
index 000000000..d3a9abf22
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/fancyopts.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/filelog.py b/sys/src/cmd/hg/mercurial/filelog.py
new file mode 100644
index 000000000..01ca4f1b4
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/filelog.py
@@ -0,0 +1,68 @@
+# filelog.py - file history class for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import revlog
+
+class filelog(revlog.revlog):
+ def __init__(self, opener, path):
+ revlog.revlog.__init__(self, opener,
+ "/".join(("data", path + ".i")))
+
+ def read(self, node):
+ t = self.revision(node)
+ if not t.startswith('\1\n'):
+ return t
+ s = t.index('\1\n', 2)
+ return t[s+2:]
+
+ def _readmeta(self, node):
+ t = self.revision(node)
+ if not t.startswith('\1\n'):
+ return {}
+ s = t.index('\1\n', 2)
+ mt = t[2:s]
+ m = {}
+ for l in mt.splitlines():
+ k, v = l.split(": ", 1)
+ m[k] = v
+ return m
+
+ def add(self, text, meta, transaction, link, p1=None, p2=None):
+ if meta or text.startswith('\1\n'):
+ mt = ""
+ if meta:
+ mt = ["%s: %s\n" % (k, v) for k, v in meta.iteritems()]
+ text = "\1\n%s\1\n%s" % ("".join(mt), text)
+ return self.addrevision(text, transaction, link, p1, p2)
+
+ def renamed(self, node):
+ if self.parents(node)[0] != revlog.nullid:
+ return False
+ m = self._readmeta(node)
+ if m and "copy" in m:
+ return (m["copy"], revlog.bin(m["copyrev"]))
+ return False
+
+ def size(self, rev):
+ """return the size of a given revision"""
+
+ # for revisions with renames, we have to go the slow way
+ node = self.node(rev)
+ if self.renamed(node):
+ return len(self.read(node))
+
+ return revlog.revlog.size(self, rev)
+
+ def cmp(self, node, text):
+ """compare text with a given file revision"""
+
+ # for renames, we have to go the slow way
+ if self.renamed(node):
+ t2 = self.read(node)
+ return t2 != text
+
+ return revlog.revlog.cmp(self, node, text)
diff --git a/sys/src/cmd/hg/mercurial/filemerge.py b/sys/src/cmd/hg/mercurial/filemerge.py
new file mode 100644
index 000000000..5431f8a96
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/filemerge.py
@@ -0,0 +1,231 @@
+# filemerge.py - file-level merge handling for Mercurial
+#
+# Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import short
+from i18n import _
+import util, simplemerge, match
+import os, tempfile, re, filecmp
+
+def _toolstr(ui, tool, part, default=""):
+ return ui.config("merge-tools", tool + "." + part, default)
+
+def _toolbool(ui, tool, part, default=False):
+ return ui.configbool("merge-tools", tool + "." + part, default)
+
+_internal = ['internal:' + s
+ for s in 'fail local other merge prompt dump'.split()]
+
+def _findtool(ui, tool):
+ if tool in _internal:
+ return tool
+ k = _toolstr(ui, tool, "regkey")
+ if k:
+ p = util.lookup_reg(k, _toolstr(ui, tool, "regname"))
+ if p:
+ p = util.find_exe(p + _toolstr(ui, tool, "regappend"))
+ if p:
+ return p
+ return util.find_exe(_toolstr(ui, tool, "executable", tool))
+
+def _picktool(repo, ui, path, binary, symlink):
+ def check(tool, pat, symlink, binary):
+ tmsg = tool
+ if pat:
+ tmsg += " specified for " + pat
+ if not _findtool(ui, tool):
+ if pat: # explicitly requested tool deserves a warning
+ ui.warn(_("couldn't find merge tool %s\n") % tmsg)
+ else: # configured but non-existing tools are more silent
+ ui.note(_("couldn't find merge tool %s\n") % tmsg)
+ elif symlink and not _toolbool(ui, tool, "symlink"):
+ ui.warn(_("tool %s can't handle symlinks\n") % tmsg)
+ elif binary and not _toolbool(ui, tool, "binary"):
+ ui.warn(_("tool %s can't handle binary\n") % tmsg)
+ elif not util.gui() and _toolbool(ui, tool, "gui"):
+ ui.warn(_("tool %s requires a GUI\n") % tmsg)
+ else:
+ return True
+ return False
+
+ # HGMERGE takes precedence
+ hgmerge = os.environ.get("HGMERGE")
+ if hgmerge:
+ return (hgmerge, hgmerge)
+
+ # then patterns
+ for pat, tool in ui.configitems("merge-patterns"):
+ mf = match.match(repo.root, '', [pat])
+ if mf(path) and check(tool, pat, symlink, False):
+ toolpath = _findtool(ui, tool)
+ return (tool, '"' + toolpath + '"')
+
+ # then merge tools
+ tools = {}
+ for k,v in ui.configitems("merge-tools"):
+ t = k.split('.')[0]
+ if t not in tools:
+ tools[t] = int(_toolstr(ui, t, "priority", "0"))
+ names = tools.keys()
+ tools = sorted([(-p,t) for t,p in tools.items()])
+ uimerge = ui.config("ui", "merge")
+ if uimerge:
+ if uimerge not in names:
+ return (uimerge, uimerge)
+ tools.insert(0, (None, uimerge)) # highest priority
+ tools.append((None, "hgmerge")) # the old default, if found
+ for p,t in tools:
+ if check(t, None, symlink, binary):
+ toolpath = _findtool(ui, t)
+ return (t, '"' + toolpath + '"')
+ # internal merge as last resort
+ return (not (symlink or binary) and "internal:merge" or None, None)
+
+def _eoltype(data):
+ "Guess the EOL type of a file"
+ if '\0' in data: # binary
+ return None
+ if '\r\n' in data: # Windows
+ return '\r\n'
+ if '\r' in data: # Old Mac
+ return '\r'
+ if '\n' in data: # UNIX
+ return '\n'
+ return None # unknown
+
+def _matcheol(file, origfile):
+ "Convert EOL markers in a file to match origfile"
+ tostyle = _eoltype(open(origfile, "rb").read())
+ if tostyle:
+ data = open(file, "rb").read()
+ style = _eoltype(data)
+ if style:
+ newdata = data.replace(style, tostyle)
+ if newdata != data:
+ open(file, "wb").write(newdata)
+
+def filemerge(repo, mynode, orig, fcd, fco, fca):
+ """perform a 3-way merge in the working directory
+
+ mynode = parent node before merge
+ orig = original local filename before merge
+ fco = other file context
+ fca = ancestor file context
+ fcd = local file context for current/destination file
+ """
+
+ def temp(prefix, ctx):
+ pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
+ (fd, name) = tempfile.mkstemp(prefix=pre)
+ data = repo.wwritedata(ctx.path(), ctx.data())
+ f = os.fdopen(fd, "wb")
+ f.write(data)
+ f.close()
+ return name
+
+ def isbin(ctx):
+ try:
+ return util.binary(ctx.data())
+ except IOError:
+ return False
+
+ if not fco.cmp(fcd.data()): # files identical?
+ return None
+
+ ui = repo.ui
+ fd = fcd.path()
+ binary = isbin(fcd) or isbin(fco) or isbin(fca)
+ symlink = 'l' in fcd.flags() + fco.flags()
+ tool, toolpath = _picktool(repo, ui, fd, binary, symlink)
+ ui.debug(_("picked tool '%s' for %s (binary %s symlink %s)\n") %
+ (tool, fd, binary, symlink))
+
+ if not tool or tool == 'internal:prompt':
+ tool = "internal:local"
+ if ui.promptchoice(_(" no tool found to merge %s\n"
+ "keep (l)ocal or take (o)ther?") % fd,
+ (_("&Local"), _("&Other")), 0):
+ tool = "internal:other"
+ if tool == "internal:local":
+ return 0
+ if tool == "internal:other":
+ repo.wwrite(fd, fco.data(), fco.flags())
+ return 0
+ if tool == "internal:fail":
+ return 1
+
+ # do the actual merge
+ a = repo.wjoin(fd)
+ b = temp("base", fca)
+ c = temp("other", fco)
+ out = ""
+ back = a + ".orig"
+ util.copyfile(a, back)
+
+ if orig != fco.path():
+ ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd))
+ else:
+ ui.status(_("merging %s\n") % fd)
+
+ ui.debug(_("my %s other %s ancestor %s\n") % (fcd, fco, fca))
+
+ # do we attempt to simplemerge first?
+ if _toolbool(ui, tool, "premerge", not (binary or symlink)):
+ r = simplemerge.simplemerge(ui, a, b, c, quiet=True)
+ if not r:
+ ui.debug(_(" premerge successful\n"))
+ os.unlink(back)
+ os.unlink(b)
+ os.unlink(c)
+ return 0
+ util.copyfile(back, a) # restore from backup and try again
+
+ env = dict(HG_FILE=fd,
+ HG_MY_NODE=short(mynode),
+ HG_OTHER_NODE=str(fco.changectx()),
+ HG_MY_ISLINK='l' in fcd.flags(),
+ HG_OTHER_ISLINK='l' in fco.flags(),
+ HG_BASE_ISLINK='l' in fca.flags())
+
+ if tool == "internal:merge":
+ r = simplemerge.simplemerge(ui, a, b, c, label=['local', 'other'])
+ elif tool == 'internal:dump':
+ a = repo.wjoin(fd)
+ util.copyfile(a, a + ".local")
+ repo.wwrite(fd + ".other", fco.data(), fco.flags())
+ repo.wwrite(fd + ".base", fca.data(), fca.flags())
+ return 1 # unresolved
+ else:
+ args = _toolstr(ui, tool, "args", '$local $base $other')
+ if "$output" in args:
+ out, a = a, back # read input from backup, write to original
+ replace = dict(local=a, base=b, other=c, output=out)
+ args = re.sub("\$(local|base|other|output)",
+ lambda x: '"%s"' % replace[x.group()[1:]], args)
+ r = util.system(toolpath + ' ' + args, cwd=repo.root, environ=env)
+
+ if not r and _toolbool(ui, tool, "checkconflicts"):
+ if re.match("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data()):
+ r = 1
+
+ if not r and _toolbool(ui, tool, "checkchanged"):
+ if filecmp.cmp(repo.wjoin(fd), back):
+ if ui.promptchoice(_(" output file %s appears unchanged\n"
+ "was merge successful (yn)?") % fd,
+ (_("&Yes"), _("&No")), 1):
+ r = 1
+
+ if _toolbool(ui, tool, "fixeol"):
+ _matcheol(repo.wjoin(fd), back)
+
+ if r:
+ ui.warn(_("merging %s failed!\n") % fd)
+ else:
+ os.unlink(back)
+
+ os.unlink(b)
+ os.unlink(c)
+ return r
diff --git a/sys/src/cmd/hg/mercurial/graphmod.py b/sys/src/cmd/hg/mercurial/graphmod.py
new file mode 100644
index 000000000..e8f9573c0
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/graphmod.py
@@ -0,0 +1,119 @@
+# Revision graph generator for Mercurial
+#
+# Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
+# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+"""supports walking the history as DAGs suitable for graphical output
+
+The most basic format we use is that of::
+
+ (id, type, data, [parentids])
+
+The node and parent ids are arbitrary integers which identify a node in the
+context of the graph returned. Type is a constant specifying the node type.
+Data depends on type.
+"""
+
+from mercurial.node import nullrev
+
+CHANGESET = 'C'
+
+def revisions(repo, start, stop):
+ """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
+
+ This generator function walks through the revision history from revision
+ start to revision stop (which must be less than or equal to start). It
+ returns a tuple for each node. The node and parent ids are arbitrary
+ integers which identify a node in the context of the graph returned.
+ """
+ cur = start
+ while cur >= stop:
+ ctx = repo[cur]
+ parents = [p.rev() for p in ctx.parents() if p.rev() != nullrev]
+ yield (cur, CHANGESET, ctx, sorted(parents))
+ cur -= 1
+
+def filerevs(repo, path, start, stop):
+ """file cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
+
+ This generator function walks through the revision history of a single
+ file from revision start down to revision stop.
+ """
+ filerev = len(repo.file(path)) - 1
+ while filerev >= 0:
+ fctx = repo.filectx(path, fileid=filerev)
+ parents = [f.linkrev() for f in fctx.parents() if f.path() == path]
+ rev = fctx.rev()
+ if rev <= start:
+ yield (rev, CHANGESET, fctx, sorted(parents))
+ if rev <= stop:
+ break
+ filerev -= 1
+
+def nodes(repo, nodes):
+ """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
+
+ This generator function walks the given nodes. It only returns parents
+ that are in nodes, too.
+ """
+ include = set(nodes)
+ for node in nodes:
+ ctx = repo[node]
+ parents = [p.rev() for p in ctx.parents() if p.node() in include]
+ yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
+
+def colored(dag):
+ """annotates a DAG with colored edge information
+
+ For each DAG node this function emits tuples::
+
+ (id, type, data, (col, color), [(col, nextcol, color)])
+
+ with the following new elements:
+
+ - Tuple (col, color) with column and color index for the current node
+ - A list of tuples indicating the edges between the current node and its
+ parents.
+ """
+ seen = []
+ colors = {}
+ newcolor = 1
+ for (cur, type, data, parents) in dag:
+
+ # Compute seen and next
+ if cur not in seen:
+ seen.append(cur) # new head
+ colors[cur] = newcolor
+ newcolor += 1
+
+ col = seen.index(cur)
+ color = colors.pop(cur)
+ next = seen[:]
+
+ # Add parents to next
+ addparents = [p for p in parents if p not in next]
+ next[col:col + 1] = addparents
+
+ # Set colors for the parents
+ for i, p in enumerate(addparents):
+ if not i:
+ colors[p] = color
+ else:
+ colors[p] = newcolor
+ newcolor += 1
+
+ # Add edges to the graph
+ edges = []
+ for ecol, eid in enumerate(seen):
+ if eid in next:
+ edges.append((ecol, next.index(eid), colors[eid]))
+ elif eid == cur:
+ for p in parents:
+ edges.append((ecol, next.index(p), colors[p]))
+
+ # Yield and move on
+ yield (cur, type, data, (col, color), edges)
+ seen = next
diff --git a/sys/src/cmd/hg/mercurial/hbisect.py b/sys/src/cmd/hg/mercurial/hbisect.py
new file mode 100644
index 000000000..5f6389a20
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hbisect.py
@@ -0,0 +1,145 @@
+# changelog bisection for mercurial
+#
+# Copyright 2007 Matt Mackall
+# Copyright 2005, 2006 Benoit Boissinot <benoit.boissinot@ens-lyon.org>
+#
+# Inspired by git bisect, extension skeleton taken from mq.py.
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os
+from i18n import _
+from node import short, hex
+import util
+
+def bisect(changelog, state):
+ """find the next node (if any) for testing during a bisect search.
+ returns a (nodes, number, good) tuple.
+
+ 'nodes' is the final result of the bisect if 'number' is 0.
+ Otherwise 'number' indicates the remaining possible candidates for
+ the search and 'nodes' contains the next bisect target.
+ 'good' is True if bisect is searching for a first good changeset, False
+ if searching for a first bad one.
+ """
+
+ clparents = changelog.parentrevs
+ skip = set([changelog.rev(n) for n in state['skip']])
+
+ def buildancestors(bad, good):
+ # only the earliest bad revision matters
+ badrev = min([changelog.rev(n) for n in bad])
+ goodrevs = [changelog.rev(n) for n in good]
+ # build ancestors array
+ ancestors = [[]] * (len(changelog) + 1) # an extra for [-1]
+
+ # clear good revs from array
+ for node in goodrevs:
+ ancestors[node] = None
+ for rev in xrange(len(changelog), -1, -1):
+ if ancestors[rev] is None:
+ for prev in clparents(rev):
+ ancestors[prev] = None
+
+ if ancestors[badrev] is None:
+ return badrev, None
+ return badrev, ancestors
+
+ good = 0
+ badrev, ancestors = buildancestors(state['bad'], state['good'])
+ if not ancestors: # looking for bad to good transition?
+ good = 1
+ badrev, ancestors = buildancestors(state['good'], state['bad'])
+ bad = changelog.node(badrev)
+ if not ancestors: # now we're confused
+ raise util.Abort(_("Inconsistent state, %s:%s is good and bad")
+ % (badrev, short(bad)))
+
+ # build children dict
+ children = {}
+ visit = [badrev]
+ candidates = []
+ while visit:
+ rev = visit.pop(0)
+ if ancestors[rev] == []:
+ candidates.append(rev)
+ for prev in clparents(rev):
+ if prev != -1:
+ if prev in children:
+ children[prev].append(rev)
+ else:
+ children[prev] = [rev]
+ visit.append(prev)
+
+ candidates.sort()
+ # have we narrowed it down to one entry?
+ # or have all other possible candidates besides 'bad' have been skipped?
+ tot = len(candidates)
+ unskipped = [c for c in candidates if (c not in skip) and (c != badrev)]
+ if tot == 1 or not unskipped:
+ return ([changelog.node(rev) for rev in candidates], 0, good)
+ perfect = tot // 2
+
+ # find the best node to test
+ best_rev = None
+ best_len = -1
+ poison = set()
+ for rev in candidates:
+ if rev in poison:
+ # poison children
+ poison.update(children.get(rev, []))
+ continue
+
+ a = ancestors[rev] or [rev]
+ ancestors[rev] = None
+
+ x = len(a) # number of ancestors
+ y = tot - x # number of non-ancestors
+ value = min(x, y) # how good is this test?
+ if value > best_len and rev not in skip:
+ best_len = value
+ best_rev = rev
+ if value == perfect: # found a perfect candidate? quit early
+ break
+
+ if y < perfect and rev not in skip: # all downhill from here?
+ # poison children
+ poison.update(children.get(rev, []))
+ continue
+
+ for c in children.get(rev, []):
+ if ancestors[c]:
+ ancestors[c] = list(set(ancestors[c] + a))
+ else:
+ ancestors[c] = a + [c]
+
+ assert best_rev is not None
+ best_node = changelog.node(best_rev)
+
+ return ([best_node], tot, good)
+
+
+def load_state(repo):
+ state = {'good': [], 'bad': [], 'skip': []}
+ if os.path.exists(repo.join("bisect.state")):
+ for l in repo.opener("bisect.state"):
+ kind, node = l[:-1].split()
+ node = repo.lookup(node)
+ if kind not in state:
+ raise util.Abort(_("unknown bisect kind %s") % kind)
+ state[kind].append(node)
+ return state
+
+
+def save_state(repo, state):
+ f = repo.opener("bisect.state", "w", atomictemp=True)
+ wlock = repo.wlock()
+ try:
+ for kind in state:
+ for node in state[kind]:
+ f.write("%s %s\n" % (kind, hex(node)))
+ f.rename()
+ finally:
+ wlock.release()
+
diff --git a/sys/src/cmd/hg/mercurial/help.py b/sys/src/cmd/hg/mercurial/help.py
new file mode 100644
index 000000000..a553ac15e
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/help.py
@@ -0,0 +1,527 @@
+# help.py - help data for mercurial
+#
+# Copyright 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import extensions, util
+
+
+def moduledoc(file):
+ '''return the top-level python documentation for the given file
+
+ Loosely inspired by pydoc.source_synopsis(), but rewritten to handle \'''
+ as well as """ and to return the whole text instead of just the synopsis'''
+ result = []
+
+ line = file.readline()
+ while line[:1] == '#' or not line.strip():
+ line = file.readline()
+ if not line: break
+
+ start = line[:3]
+ if start == '"""' or start == "'''":
+ line = line[3:]
+ while line:
+ if line.rstrip().endswith(start):
+ line = line.split(start)[0]
+ if line:
+ result.append(line)
+ break
+ elif not line:
+ return None # unmatched delimiter
+ result.append(line)
+ line = file.readline()
+ else:
+ return None
+
+ return ''.join(result)
+
+def listexts(header, exts, maxlength):
+ '''return a text listing of the given extensions'''
+ if not exts:
+ return ''
+ result = '\n%s\n\n' % header
+ for name, desc in sorted(exts.iteritems()):
+ result += ' %-*s %s\n' % (maxlength + 2, ':%s:' % name, desc)
+ return result
+
+def extshelp():
+ doc = _(r'''
+ Mercurial has the ability to add new features through the use of
+ extensions. Extensions may add new commands, add options to
+ existing commands, change the default behavior of commands, or
+ implement hooks.
+
+ Extensions are not loaded by default for a variety of reasons:
+ they can increase startup overhead; they may be meant for advanced
+ usage only; they may provide potentially dangerous abilities (such
+ as letting you destroy or modify history); they might not be ready
+ for prime time; or they may alter some usual behaviors of stock
+ Mercurial. It is thus up to the user to activate extensions as
+ needed.
+
+ To enable the "foo" extension, either shipped with Mercurial or in
+ the Python search path, create an entry for it in your hgrc, like
+ this::
+
+ [extensions]
+ foo =
+
+ You may also specify the full path to an extension::
+
+ [extensions]
+ myfeature = ~/.hgext/myfeature.py
+
+ To explicitly disable an extension enabled in an hgrc of broader
+ scope, prepend its path with !::
+
+ [extensions]
+ # disabling extension bar residing in /path/to/extension/bar.py
+ hgext.bar = !/path/to/extension/bar.py
+ # ditto, but no path was supplied for extension baz
+ hgext.baz = !
+ ''')
+
+ exts, maxlength = extensions.enabled()
+ doc += listexts(_('enabled extensions:'), exts, maxlength)
+
+ exts, maxlength = extensions.disabled()
+ doc += listexts(_('disabled extensions:'), exts, maxlength)
+
+ return doc
+
+helptable = (
+ (["dates"], _("Date Formats"),
+ _(r'''
+ Some commands allow the user to specify a date, e.g.:
+
+ - backout, commit, import, tag: Specify the commit date.
+ - log, revert, update: Select revision(s) by date.
+
+ Many date formats are valid. Here are some examples::
+
+ "Wed Dec 6 13:18:29 2006" (local timezone assumed)
+ "Dec 6 13:18 -0600" (year assumed, time offset provided)
+ "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
+ "Dec 6" (midnight)
+ "13:18" (today assumed)
+ "3:39" (3:39AM assumed)
+ "3:39pm" (15:39)
+ "2006-12-06 13:18:29" (ISO 8601 format)
+ "2006-12-6 13:18"
+ "2006-12-6"
+ "12-6"
+ "12/6"
+ "12/6/6" (Dec 6 2006)
+
+ Lastly, there is Mercurial's internal format::
+
+ "1165432709 0" (Wed Dec 6 13:18:29 2006 UTC)
+
+ This is the internal representation format for dates. unixtime is
+ the number of seconds since the epoch (1970-01-01 00:00 UTC).
+ offset is the offset of the local timezone, in seconds west of UTC
+ (negative if the timezone is east of UTC).
+
+ The log command also accepts date ranges::
+
+ "<{datetime}" - at or before a given date/time
+ ">{datetime}" - on or after a given date/time
+ "{datetime} to {datetime}" - a date range, inclusive
+ "-{days}" - within a given number of days of today
+ ''')),
+
+ (["patterns"], _("File Name Patterns"),
+ _(r'''
+ Mercurial accepts several notations for identifying one or more
+ files at a time.
+
+ By default, Mercurial treats filenames as shell-style extended
+ glob patterns.
+
+ Alternate pattern notations must be specified explicitly.
+
+ To use a plain path name without any pattern matching, start it
+ with "path:". These path names must completely match starting at
+ the current repository root.
+
+ To use an extended glob, start a name with "glob:". Globs are
+ rooted at the current directory; a glob such as "``*.c``" will
+ only match files in the current directory ending with ".c".
+
+ The supported glob syntax extensions are "``**``" to match any
+ string across path separators and "{a,b}" to mean "a or b".
+
+ To use a Perl/Python regular expression, start a name with "re:".
+ Regexp pattern matching is anchored at the root of the repository.
+
+ Plain examples::
+
+ path:foo/bar a name bar in a directory named foo in the root
+ of the repository
+ path:path:name a file or directory named "path:name"
+
+ Glob examples::
+
+ glob:*.c any name ending in ".c" in the current directory
+ *.c any name ending in ".c" in the current directory
+ **.c any name ending in ".c" in any subdirectory of the
+ current directory including itself.
+ foo/*.c any name ending in ".c" in the directory foo
+ foo/**.c any name ending in ".c" in any subdirectory of foo
+ including itself.
+
+ Regexp examples::
+
+ re:.*\.c$ any name ending in ".c", anywhere in the repository
+
+ ''')),
+
+ (['environment', 'env'], _('Environment Variables'),
+ _(r'''
+HG
+ Path to the 'hg' executable, automatically passed when running
+ hooks, extensions or external tools. If unset or empty, this is
+ the hg executable's name if it's frozen, or an executable named
+ 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on
+ Windows) is searched.
+
+HGEDITOR
+ This is the name of the editor to run when committing. See EDITOR.
+
+ (deprecated, use .hgrc)
+
+HGENCODING
+ This overrides the default locale setting detected by Mercurial.
+ This setting is used to convert data including usernames,
+ changeset descriptions, tag names, and branches. This setting can
+ be overridden with the --encoding command-line option.
+
+HGENCODINGMODE
+ This sets Mercurial's behavior for handling unknown characters
+ while transcoding user input. The default is "strict", which
+ causes Mercurial to abort if it can't map a character. Other
+ settings include "replace", which replaces unknown characters, and
+ "ignore", which drops them. This setting can be overridden with
+ the --encodingmode command-line option.
+
+HGMERGE
+ An executable to use for resolving merge conflicts. The program
+ will be executed with three arguments: local file, remote file,
+ ancestor file.
+
+ (deprecated, use .hgrc)
+
+HGRCPATH
+ A list of files or directories to search for hgrc files. Item
+ separator is ":" on Unix, ";" on Windows. If HGRCPATH is not set,
+ platform default search path is used. If empty, only the .hg/hgrc
+ from the current repository is read.
+
+ For each element in HGRCPATH:
+
+ - if it's a directory, all files ending with .rc are added
+ - otherwise, the file itself will be added
+
+HGUSER
+ This is the string used as the author of a commit. If not set,
+ available values will be considered in this order:
+
+ - HGUSER (deprecated)
+ - hgrc files from the HGRCPATH
+ - EMAIL
+ - interactive prompt
+ - LOGNAME (with '@hostname' appended)
+
+ (deprecated, use .hgrc)
+
+EMAIL
+ May be used as the author of a commit; see HGUSER.
+
+LOGNAME
+ May be used as the author of a commit; see HGUSER.
+
+VISUAL
+ This is the name of the editor to use when committing. See EDITOR.
+
+EDITOR
+ Sometimes Mercurial needs to open a text file in an editor for a
+ user to modify, for example when writing commit messages. The
+ editor it uses is determined by looking at the environment
+ variables HGEDITOR, VISUAL and EDITOR, in that order. The first
+ non-empty one is chosen. If all of them are empty, the editor
+ defaults to 'vi'.
+
+PYTHONPATH
+ This is used by Python to find imported modules and may need to be
+ set appropriately if this Mercurial is not installed system-wide.
+ ''')),
+
+ (['revs', 'revisions'], _('Specifying Single Revisions'),
+ _(r'''
+ Mercurial supports several ways to specify individual revisions.
+
+ A plain integer is treated as a revision number. Negative integers
+ are treated as sequential offsets from the tip, with -1 denoting
+ the tip, -2 denoting the revision prior to the tip, and so forth.
+
+ A 40-digit hexadecimal string is treated as a unique revision
+ identifier.
+
+ A hexadecimal string less than 40 characters long is treated as a
+ unique revision identifier and is referred to as a short-form
+ identifier. A short-form identifier is only valid if it is the
+ prefix of exactly one full-length identifier.
+
+ Any other string is treated as a tag or branch name. A tag name is
+ a symbolic name associated with a revision identifier. A branch
+ name denotes the tipmost revision of that branch. Tag and branch
+ names must not contain the ":" character.
+
+ The reserved name "tip" is a special tag that always identifies
+ the most recent revision.
+
+ The reserved name "null" indicates the null revision. This is the
+ revision of an empty repository, and the parent of revision 0.
+
+ The reserved name "." indicates the working directory parent. If
+ no working directory is checked out, it is equivalent to null. If
+ an uncommitted merge is in progress, "." is the revision of the
+ first parent.
+ ''')),
+
+ (['mrevs', 'multirevs'], _('Specifying Multiple Revisions'),
+ _(r'''
+ When Mercurial accepts more than one revision, they may be
+ specified individually, or provided as a topologically continuous
+ range, separated by the ":" character.
+
+ The syntax of range notation is [BEGIN]:[END], where BEGIN and END
+ are revision identifiers. Both BEGIN and END are optional. If
+ BEGIN is not specified, it defaults to revision number 0. If END
+ is not specified, it defaults to the tip. The range ":" thus means
+ "all revisions".
+
+ If BEGIN is greater than END, revisions are treated in reverse
+ order.
+
+ A range acts as a closed interval. This means that a range of 3:5
+ gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
+ ''')),
+
+ (['diffs'], _('Diff Formats'),
+ _(r'''
+ Mercurial's default format for showing changes between two
+ versions of a file is compatible with the unified format of GNU
+ diff, which can be used by GNU patch and many other standard
+ tools.
+
+ While this standard format is often enough, it does not encode the
+ following information:
+
+ - executable status and other permission bits
+ - copy or rename information
+ - changes in binary files
+ - creation or deletion of empty files
+
+ Mercurial also supports the extended diff format from the git VCS
+ which addresses these limitations. The git diff format is not
+ produced by default because a few widespread tools still do not
+ understand this format.
+
+ This means that when generating diffs from a Mercurial repository
+ (e.g. with "hg export"), you should be careful about things like
+ file copies and renames or other things mentioned above, because
+ when applying a standard diff to a different repository, this
+ extra information is lost. Mercurial's internal operations (like
+ push and pull) are not affected by this, because they use an
+ internal binary format for communicating changes.
+
+ To make Mercurial produce the git extended diff format, use the
+ --git option available for many commands, or set 'git = True' in
+ the [diff] section of your hgrc. You do not need to set this
+ option when importing diffs in this format or using them in the mq
+ extension.
+ ''')),
+ (['templating', 'templates'], _('Template Usage'),
+ _(r'''
+ Mercurial allows you to customize output of commands through
+ templates. You can either pass in a template from the command
+ line, via the --template option, or select an existing
+ template-style (--style).
+
+ You can customize output for any "log-like" command: log,
+ outgoing, incoming, tip, parents, heads and glog.
+
+ Three styles are packaged with Mercurial: default (the style used
+ when no explicit preference is passed), compact and changelog.
+ Usage::
+
+ $ hg log -r1 --style changelog
+
+ A template is a piece of text, with markup to invoke variable
+ expansion::
+
+ $ hg log -r1 --template "{node}\n"
+ b56ce7b07c52de7d5fd79fb89701ea538af65746
+
+ Strings in curly braces are called keywords. The availability of
+ keywords depends on the exact context of the templater. These
+ keywords are usually available for templating a log-like command:
+
+ :author: String. The unmodified author of the changeset.
+ :branches: String. The name of the branch on which the changeset
+ was committed. Will be empty if the branch name was
+ default.
+ :date: Date information. The date when the changeset was
+ committed.
+ :desc: String. The text of the changeset description.
+ :diffstat: String. Statistics of changes with the following
+ format: "modified files: +added/-removed lines"
+ :files: List of strings. All files modified, added, or removed
+ by this changeset.
+ :file_adds: List of strings. Files added by this changeset.
+ :file_mods: List of strings. Files modified by this changeset.
+ :file_dels: List of strings. Files removed by this changeset.
+ :node: String. The changeset identification hash, as a
+ 40-character hexadecimal string.
+ :parents: List of strings. The parents of the changeset.
+ :rev: Integer. The repository-local changeset revision
+ number.
+ :tags: List of strings. Any tags associated with the
+ changeset.
+
+ The "date" keyword does not produce human-readable output. If you
+ want to use a date in your output, you can use a filter to process
+ it. Filters are functions which return a string based on the input
+ variable. You can also use a chain of filters to get the desired
+ output::
+
+ $ hg tip --template "{date|isodate}\n"
+ 2008-08-21 18:22 +0000
+
+ List of filters:
+
+ :addbreaks: Any text. Add an XHTML "<br />" tag before the end of
+ every line except the last.
+ :age: Date. Returns a human-readable date/time difference
+ between the given date/time and the current
+ date/time.
+ :basename: Any text. Treats the text as a path, and returns the
+ last component of the path after splitting by the
+ path separator (ignoring trailing separators). For
+ example, "foo/bar/baz" becomes "baz" and "foo/bar//"
+ becomes "bar".
+ :stripdir: Treat the text as path and strip a directory level,
+ if possible. For example, "foo" and "foo/bar" becomes
+ "foo".
+ :date: Date. Returns a date in a Unix date format, including
+ the timezone: "Mon Sep 04 15:13:13 2006 0700".
+ :domain: Any text. Finds the first string that looks like an
+ email address, and extracts just the domain
+ component. Example: 'User <user@example.com>' becomes
+ 'example.com'.
+ :email: Any text. Extracts the first string that looks like
+ an email address. Example: 'User <user@example.com>'
+ becomes 'user@example.com'.
+ :escape: Any text. Replaces the special XML/XHTML characters
+ "&", "<" and ">" with XML entities.
+ :fill68: Any text. Wraps the text to fit in 68 columns.
+ :fill76: Any text. Wraps the text to fit in 76 columns.
+ :firstline: Any text. Returns the first line of text.
+ :nonempty: Any text. Returns '(none)' if the string is empty.
+ :hgdate: Date. Returns the date as a pair of numbers:
+ "1157407993 25200" (Unix timestamp, timezone offset).
+ :isodate: Date. Returns the date in ISO 8601 format.
+ :localdate: Date. Converts a date to local date.
+ :obfuscate: Any text. Returns the input text rendered as a
+ sequence of XML entities.
+ :person: Any text. Returns the text before an email address.
+ :rfc822date: Date. Returns a date using the same format used in
+ email headers.
+ :short: Changeset hash. Returns the short form of a changeset
+ hash, i.e. a 12-byte hexadecimal string.
+ :shortdate: Date. Returns a date like "2006-09-18".
+ :strip: Any text. Strips all leading and trailing whitespace.
+ :tabindent: Any text. Returns the text, with every line except
+ the first starting with a tab character.
+ :urlescape: Any text. Escapes all "special" characters. For
+ example, "foo bar" becomes "foo%20bar".
+ :user: Any text. Returns the user portion of an email
+ address.
+ ''')),
+
+ (['urls'], _('URL Paths'),
+ _(r'''
+ Valid URLs are of the form::
+
+ local/filesystem/path[#revision]
+ file://local/filesystem/path[#revision]
+ http://[user[:pass]@]host[:port]/[path][#revision]
+ https://[user[:pass]@]host[:port]/[path][#revision]
+ ssh://[user[:pass]@]host[:port]/[path][#revision]
+
+ Paths in the local filesystem can either point to Mercurial
+ repositories or to bundle files (as created by 'hg bundle' or 'hg
+ incoming --bundle').
+
+ An optional identifier after # indicates a particular branch, tag,
+ or changeset to use from the remote repository. See also 'hg help
+ revisions'.
+
+ Some features, such as pushing to http:// and https:// URLs are
+ only possible if the feature is explicitly enabled on the remote
+ Mercurial server.
+
+ Some notes about using SSH with Mercurial:
+
+ - SSH requires an accessible shell account on the destination
+ machine and a copy of hg in the remote path or specified with as
+ remotecmd.
+ - path is relative to the remote user's home directory by default.
+ Use an extra slash at the start of a path to specify an absolute
+ path::
+
+ ssh://example.com//tmp/repository
+
+ - Mercurial doesn't use its own compression via SSH; the right
+ thing to do is to configure it in your ~/.ssh/config, e.g.::
+
+ Host *.mylocalnetwork.example.com
+ Compression no
+ Host *
+ Compression yes
+
+ Alternatively specify "ssh -C" as your ssh command in your hgrc
+ or with the --ssh command line option.
+
+ These URLs can all be stored in your hgrc with path aliases under
+ the [paths] section like so::
+
+ [paths]
+ alias1 = URL1
+ alias2 = URL2
+ ...
+
+ You can then use the alias for any command that uses a URL (for
+ example 'hg pull alias1' would pull from the 'alias1' path).
+
+ Two path aliases are special because they are used as defaults
+ when you do not provide the URL to a command:
+
+ default:
+ When you create a repository with hg clone, the clone command
+ saves the location of the source repository as the new
+ repository's 'default' path. This is then used when you omit
+ path from push- and pull-like commands (including incoming and
+ outgoing).
+
+ default-push:
+ The push command will look for a path named 'default-push', and
+ prefer it over 'default' if both are defined.
+ ''')),
+ (["extensions"], _("Using additional features"), extshelp),
+)
diff --git a/sys/src/cmd/hg/mercurial/hg.py b/sys/src/cmd/hg/mercurial/hg.py
new file mode 100644
index 000000000..504bc1256
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hg.py
@@ -0,0 +1,367 @@
+# hg.py - repository classes for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+from lock import release
+import localrepo, bundlerepo, httprepo, sshrepo, statichttprepo
+import lock, util, extensions, error
+import merge as _merge
+import verify as _verify
+import errno, os, shutil
+
+def _local(path):
+ return (os.path.isfile(util.drop_scheme('file', path)) and
+ bundlerepo or localrepo)
+
+def parseurl(url, revs=[]):
+ '''parse url#branch, returning url, branch + revs'''
+
+ if '#' not in url:
+ return url, (revs or None), revs and revs[-1] or None
+
+ url, branch = url.split('#', 1)
+ checkout = revs and revs[-1] or branch
+ return url, (revs or []) + [branch], checkout
+
+schemes = {
+ 'bundle': bundlerepo,
+ 'file': _local,
+ 'http': httprepo,
+ 'https': httprepo,
+ 'ssh': sshrepo,
+ 'static-http': statichttprepo,
+}
+
+def _lookup(path):
+ scheme = 'file'
+ if path:
+ c = path.find(':')
+ if c > 0:
+ scheme = path[:c]
+ thing = schemes.get(scheme) or schemes['file']
+ try:
+ return thing(path)
+ except TypeError:
+ return thing
+
+def islocal(repo):
+ '''return true if repo or path is local'''
+ if isinstance(repo, str):
+ try:
+ return _lookup(repo).islocal(repo)
+ except AttributeError:
+ return False
+ return repo.local()
+
+def repository(ui, path='', create=False):
+ """return a repository object for the specified path"""
+ repo = _lookup(path).instance(ui, path, create)
+ ui = getattr(repo, "ui", ui)
+ for name, module in extensions.extensions():
+ hook = getattr(module, 'reposetup', None)
+ if hook:
+ hook(ui, repo)
+ return repo
+
+def defaultdest(source):
+ '''return default destination of clone if none is given'''
+ return os.path.basename(os.path.normpath(source))
+
+def localpath(path):
+ if path.startswith('file://localhost/'):
+ return path[16:]
+ if path.startswith('file://'):
+ return path[7:]
+ if path.startswith('file:'):
+ return path[5:]
+ return path
+
+def share(ui, source, dest=None, update=True):
+ '''create a shared repository'''
+
+ if not islocal(source):
+ raise util.Abort(_('can only share local repositories'))
+
+ if not dest:
+ dest = os.path.basename(source)
+ else:
+ dest = ui.expandpath(dest)
+
+ if isinstance(source, str):
+ origsource = ui.expandpath(source)
+ source, rev, checkout = parseurl(origsource, '')
+ srcrepo = repository(ui, source)
+ else:
+ srcrepo = source
+ origsource = source = srcrepo.url()
+ checkout = None
+
+ sharedpath = srcrepo.sharedpath # if our source is already sharing
+
+ root = os.path.realpath(dest)
+ roothg = os.path.join(root, '.hg')
+
+ if os.path.exists(roothg):
+ raise util.Abort(_('destination already exists'))
+
+ if not os.path.isdir(root):
+ os.mkdir(root)
+ os.mkdir(roothg)
+
+ requirements = ''
+ try:
+ requirements = srcrepo.opener('requires').read()
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+
+ requirements += 'shared\n'
+ file(os.path.join(roothg, 'requires'), 'w').write(requirements)
+ file(os.path.join(roothg, 'sharedpath'), 'w').write(sharedpath)
+
+ default = srcrepo.ui.config('paths', 'default')
+ if default:
+ f = file(os.path.join(roothg, 'hgrc'), 'w')
+ f.write('[paths]\ndefault = %s\n' % default)
+ f.close()
+
+ r = repository(ui, root)
+
+ if update:
+ r.ui.status(_("updating working directory\n"))
+ if update is not True:
+ checkout = update
+ for test in (checkout, 'default', 'tip'):
+ try:
+ uprev = r.lookup(test)
+ break
+ except LookupError:
+ continue
+ _update(r, uprev)
+
+def clone(ui, source, dest=None, pull=False, rev=None, update=True,
+ stream=False):
+ """Make a copy of an existing repository.
+
+ Create a copy of an existing repository in a new directory. The
+ source and destination are URLs, as passed to the repository
+ function. Returns a pair of repository objects, the source and
+ newly created destination.
+
+ The location of the source is added to the new repository's
+ .hg/hgrc file, as the default to be used for future pulls and
+ pushes.
+
+ If an exception is raised, the partly cloned/updated destination
+ repository will be deleted.
+
+ Arguments:
+
+ source: repository object or URL
+
+ dest: URL of destination repository to create (defaults to base
+ name of source repository)
+
+ pull: always pull from source repository, even in local case
+
+ stream: stream raw data uncompressed from repository (fast over
+ LAN, slow over WAN)
+
+ rev: revision to clone up to (implies pull=True)
+
+ update: update working directory after clone completes, if
+ destination is local repository (True means update to default rev,
+ anything else is treated as a revision)
+ """
+
+ if isinstance(source, str):
+ origsource = ui.expandpath(source)
+ source, rev, checkout = parseurl(origsource, rev)
+ src_repo = repository(ui, source)
+ else:
+ src_repo = source
+ origsource = source = src_repo.url()
+ checkout = rev and rev[-1] or None
+
+ if dest is None:
+ dest = defaultdest(source)
+ ui.status(_("destination directory: %s\n") % dest)
+ else:
+ dest = ui.expandpath(dest)
+
+ dest = localpath(dest)
+ source = localpath(source)
+
+ if os.path.exists(dest):
+ if not os.path.isdir(dest):
+ raise util.Abort(_("destination '%s' already exists") % dest)
+ elif os.listdir(dest):
+ raise util.Abort(_("destination '%s' is not empty") % dest)
+
+ class DirCleanup(object):
+ def __init__(self, dir_):
+ self.rmtree = shutil.rmtree
+ self.dir_ = dir_
+ def close(self):
+ self.dir_ = None
+ def cleanup(self):
+ if self.dir_:
+ self.rmtree(self.dir_, True)
+
+ src_lock = dest_lock = dir_cleanup = None
+ try:
+ if islocal(dest):
+ dir_cleanup = DirCleanup(dest)
+
+ abspath = origsource
+ copy = False
+ if src_repo.cancopy() and islocal(dest):
+ abspath = os.path.abspath(util.drop_scheme('file', origsource))
+ copy = not pull and not rev
+
+ if copy:
+ try:
+ # we use a lock here because if we race with commit, we
+ # can end up with extra data in the cloned revlogs that's
+ # not pointed to by changesets, thus causing verify to
+ # fail
+ src_lock = src_repo.lock(wait=False)
+ except error.LockError:
+ copy = False
+
+ if copy:
+ src_repo.hook('preoutgoing', throw=True, source='clone')
+ hgdir = os.path.realpath(os.path.join(dest, ".hg"))
+ if not os.path.exists(dest):
+ os.mkdir(dest)
+ else:
+ # only clean up directories we create ourselves
+ dir_cleanup.dir_ = hgdir
+ try:
+ dest_path = hgdir
+ os.mkdir(dest_path)
+ except OSError, inst:
+ if inst.errno == errno.EEXIST:
+ dir_cleanup.close()
+ raise util.Abort(_("destination '%s' already exists")
+ % dest)
+ raise
+
+ for f in src_repo.store.copylist():
+ src = os.path.join(src_repo.path, f)
+ dst = os.path.join(dest_path, f)
+ dstbase = os.path.dirname(dst)
+ if dstbase and not os.path.exists(dstbase):
+ os.mkdir(dstbase)
+ if os.path.exists(src):
+ if dst.endswith('data'):
+ # lock to avoid premature writing to the target
+ dest_lock = lock.lock(os.path.join(dstbase, "lock"))
+ util.copyfiles(src, dst)
+
+ # we need to re-init the repo after manually copying the data
+ # into it
+ dest_repo = repository(ui, dest)
+ src_repo.hook('outgoing', source='clone', node='0'*40)
+ else:
+ try:
+ dest_repo = repository(ui, dest, create=True)
+ except OSError, inst:
+ if inst.errno == errno.EEXIST:
+ dir_cleanup.close()
+ raise util.Abort(_("destination '%s' already exists")
+ % dest)
+ raise
+
+ revs = None
+ if rev:
+ if 'lookup' not in src_repo.capabilities:
+ raise util.Abort(_("src repository does not support "
+ "revision lookup and so doesn't "
+ "support clone by revision"))
+ revs = [src_repo.lookup(r) for r in rev]
+ checkout = revs[0]
+ if dest_repo.local():
+ dest_repo.clone(src_repo, heads=revs, stream=stream)
+ elif src_repo.local():
+ src_repo.push(dest_repo, revs=revs)
+ else:
+ raise util.Abort(_("clone from remote to remote not supported"))
+
+ if dir_cleanup:
+ dir_cleanup.close()
+
+ if dest_repo.local():
+ fp = dest_repo.opener("hgrc", "w", text=True)
+ fp.write("[paths]\n")
+ fp.write("default = %s\n" % abspath)
+ fp.close()
+
+ dest_repo.ui.setconfig('paths', 'default', abspath)
+
+ if update:
+ dest_repo.ui.status(_("updating working directory\n"))
+ if update is not True:
+ checkout = update
+ for test in (checkout, 'default', 'tip'):
+ try:
+ uprev = dest_repo.lookup(test)
+ break
+ except:
+ continue
+ _update(dest_repo, uprev)
+
+ return src_repo, dest_repo
+ finally:
+ release(src_lock, dest_lock)
+ if dir_cleanup is not None:
+ dir_cleanup.cleanup()
+
+def _showstats(repo, stats):
+ stats = ((stats[0], _("updated")),
+ (stats[1], _("merged")),
+ (stats[2], _("removed")),
+ (stats[3], _("unresolved")))
+ note = ", ".join([_("%d files %s") % s for s in stats])
+ repo.ui.status("%s\n" % note)
+
+def update(repo, node):
+ """update the working directory to node, merging linear changes"""
+ stats = _merge.update(repo, node, False, False, None)
+ _showstats(repo, stats)
+ if stats[3]:
+ repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
+ return stats[3] > 0
+
+# naming conflict in clone()
+_update = update
+
+def clean(repo, node, show_stats=True):
+ """forcibly switch the working directory to node, clobbering changes"""
+ stats = _merge.update(repo, node, False, True, None)
+ if show_stats: _showstats(repo, stats)
+ return stats[3] > 0
+
+def merge(repo, node, force=None, remind=True):
+ """branch merge with node, resolving changes"""
+ stats = _merge.update(repo, node, True, force, False)
+ _showstats(repo, stats)
+ if stats[3]:
+ repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
+ "or 'hg up --clean' to abandon\n"))
+ elif remind:
+ repo.ui.status(_("(branch merge, don't forget to commit)\n"))
+ return stats[3] > 0
+
+def revert(repo, node, choose):
+ """revert changes to revision in node without updating dirstate"""
+ return _merge.update(repo, node, False, True, choose)[3] > 0
+
+def verify(repo):
+ """verify the consistency of a repository"""
+ return _verify.verify(repo)
diff --git a/sys/src/cmd/hg/mercurial/hgweb/__init__.py b/sys/src/cmd/hg/mercurial/hgweb/__init__.py
new file mode 100644
index 000000000..3cb3e95e2
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/__init__.py
@@ -0,0 +1,16 @@
+# hgweb/__init__.py - web interface to a mercurial repository
+#
+# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
+# Copyright 2005 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import hgweb_mod, hgwebdir_mod
+
+def hgweb(*args, **kwargs):
+ return hgweb_mod.hgweb(*args, **kwargs)
+
+def hgwebdir(*args, **kwargs):
+ return hgwebdir_mod.hgwebdir(*args, **kwargs)
+
diff --git a/sys/src/cmd/hg/mercurial/hgweb/__init__.pyc b/sys/src/cmd/hg/mercurial/hgweb/__init__.pyc
new file mode 100644
index 000000000..e1353d1dc
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/__init__.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/hgweb/common.py b/sys/src/cmd/hg/mercurial/hgweb/common.py
new file mode 100644
index 000000000..effa3d1f4
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/common.py
@@ -0,0 +1,105 @@
+# hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod
+#
+# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import errno, mimetypes, os
+
+HTTP_OK = 200
+HTTP_BAD_REQUEST = 400
+HTTP_UNAUTHORIZED = 401
+HTTP_FORBIDDEN = 403
+HTTP_NOT_FOUND = 404
+HTTP_METHOD_NOT_ALLOWED = 405
+HTTP_SERVER_ERROR = 500
+
+class ErrorResponse(Exception):
+ def __init__(self, code, message=None, headers=[]):
+ Exception.__init__(self)
+ self.code = code
+ self.headers = headers
+ if message is not None:
+ self.message = message
+ else:
+ self.message = _statusmessage(code)
+
+def _statusmessage(code):
+ from BaseHTTPServer import BaseHTTPRequestHandler
+ responses = BaseHTTPRequestHandler.responses
+ return responses.get(code, ('Error', 'Unknown error'))[0]
+
+def statusmessage(code):
+ return '%d %s' % (code, _statusmessage(code))
+
+def get_mtime(repo_path):
+ store_path = os.path.join(repo_path, ".hg")
+ if not os.path.isdir(os.path.join(store_path, "data")):
+ store_path = os.path.join(store_path, "store")
+ cl_path = os.path.join(store_path, "00changelog.i")
+ if os.path.exists(cl_path):
+ return os.stat(cl_path).st_mtime
+ else:
+ return os.stat(store_path).st_mtime
+
+def staticfile(directory, fname, req):
+ """return a file inside directory with guessed Content-Type header
+
+ fname always uses '/' as directory separator and isn't allowed to
+ contain unusual path components.
+ Content-Type is guessed using the mimetypes module.
+ Return an empty string if fname is illegal or file not found.
+
+ """
+ parts = fname.split('/')
+ for part in parts:
+ if (part in ('', os.curdir, os.pardir) or
+ os.sep in part or os.altsep is not None and os.altsep in part):
+ return ""
+ fpath = os.path.join(*parts)
+ if isinstance(directory, str):
+ directory = [directory]
+ for d in directory:
+ path = os.path.join(d, fpath)
+ if os.path.exists(path):
+ break
+ try:
+ os.stat(path)
+ ct = mimetypes.guess_type(path)[0] or "text/plain"
+ req.respond(HTTP_OK, ct, length = os.path.getsize(path))
+ return open(path, 'rb').read()
+ except TypeError:
+ raise ErrorResponse(HTTP_SERVER_ERROR, 'illegal filename')
+ except OSError, err:
+ if err.errno == errno.ENOENT:
+ raise ErrorResponse(HTTP_NOT_FOUND)
+ else:
+ raise ErrorResponse(HTTP_SERVER_ERROR, err.strerror)
+
+def paritygen(stripecount, offset=0):
+ """count parity of horizontal stripes for easier reading"""
+ if stripecount and offset:
+ # account for offset, e.g. due to building the list in reverse
+ count = (stripecount + offset) % stripecount
+ parity = (stripecount + offset) / stripecount & 1
+ else:
+ count = 0
+ parity = 0
+ while True:
+ yield parity
+ count += 1
+ if stripecount and count >= stripecount:
+ parity = 1 - parity
+ count = 0
+
+def get_contact(config):
+ """Return repo contact information or empty string.
+
+ web.contact is the primary source, but if that is not set, try
+ ui.username or $EMAIL as a fallback to display something useful.
+ """
+ return (config("web", "contact") or
+ config("ui", "username") or
+ os.environ.get("EMAIL") or "")
diff --git a/sys/src/cmd/hg/mercurial/hgweb/hgweb_mod.py b/sys/src/cmd/hg/mercurial/hgweb/hgweb_mod.py
new file mode 100644
index 000000000..31638106f
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/hgweb_mod.py
@@ -0,0 +1,315 @@
+# hgweb/hgweb_mod.py - Web interface for a repository.
+#
+# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os
+from mercurial import ui, hg, hook, error, encoding, templater
+from common import get_mtime, ErrorResponse
+from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
+from common import HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED
+from request import wsgirequest
+import webcommands, protocol, webutil
+
+perms = {
+ 'changegroup': 'pull',
+ 'changegroupsubset': 'pull',
+ 'unbundle': 'push',
+ 'stream_out': 'pull',
+}
+
+class hgweb(object):
+ def __init__(self, repo, name=None):
+ if isinstance(repo, str):
+ u = ui.ui()
+ u.setconfig('ui', 'report_untrusted', 'off')
+ u.setconfig('ui', 'interactive', 'off')
+ self.repo = hg.repository(u, repo)
+ else:
+ self.repo = repo
+
+ hook.redirect(True)
+ self.mtime = -1
+ self.reponame = name
+ self.archives = 'zip', 'gz', 'bz2'
+ self.stripecount = 1
+ # a repo owner may set web.templates in .hg/hgrc to get any file
+ # readable by the user running the CGI script
+ self.templatepath = self.config('web', 'templates')
+
+ # The CGI scripts are often run by a user different from the repo owner.
+ # Trust the settings from the .hg/hgrc files by default.
+ def config(self, section, name, default=None, untrusted=True):
+ return self.repo.ui.config(section, name, default,
+ untrusted=untrusted)
+
+ def configbool(self, section, name, default=False, untrusted=True):
+ return self.repo.ui.configbool(section, name, default,
+ untrusted=untrusted)
+
+ def configlist(self, section, name, default=None, untrusted=True):
+ return self.repo.ui.configlist(section, name, default,
+ untrusted=untrusted)
+
+ def refresh(self):
+ mtime = get_mtime(self.repo.root)
+ if mtime != self.mtime:
+ self.mtime = mtime
+ self.repo = hg.repository(self.repo.ui, self.repo.root)
+ self.maxchanges = int(self.config("web", "maxchanges", 10))
+ self.stripecount = int(self.config("web", "stripes", 1))
+ self.maxshortchanges = int(self.config("web", "maxshortchanges", 60))
+ self.maxfiles = int(self.config("web", "maxfiles", 10))
+ self.allowpull = self.configbool("web", "allowpull", True)
+ encoding.encoding = self.config("web", "encoding",
+ encoding.encoding)
+
+ def run(self):
+ if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
+ raise RuntimeError("This function is only intended to be "
+ "called while running as a CGI script.")
+ import mercurial.hgweb.wsgicgi as wsgicgi
+ wsgicgi.launch(self)
+
+ def __call__(self, env, respond):
+ req = wsgirequest(env, respond)
+ return self.run_wsgi(req)
+
+ def run_wsgi(self, req):
+
+ self.refresh()
+
+ # work with CGI variables to create coherent structure
+ # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
+
+ req.url = req.env['SCRIPT_NAME']
+ if not req.url.endswith('/'):
+ req.url += '/'
+ if 'REPO_NAME' in req.env:
+ req.url += req.env['REPO_NAME'] + '/'
+
+ if 'PATH_INFO' in req.env:
+ parts = req.env['PATH_INFO'].strip('/').split('/')
+ repo_parts = req.env.get('REPO_NAME', '').split('/')
+ if parts[:len(repo_parts)] == repo_parts:
+ parts = parts[len(repo_parts):]
+ query = '/'.join(parts)
+ else:
+ query = req.env['QUERY_STRING'].split('&', 1)[0]
+ query = query.split(';', 1)[0]
+
+ # process this if it's a protocol request
+ # protocol bits don't need to create any URLs
+ # and the clients always use the old URL structure
+
+ cmd = req.form.get('cmd', [''])[0]
+ if cmd and cmd in protocol.__all__:
+ if query:
+ raise ErrorResponse(HTTP_NOT_FOUND)
+ try:
+ if cmd in perms:
+ try:
+ self.check_perm(req, perms[cmd])
+ except ErrorResponse, inst:
+ if cmd == 'unbundle':
+ req.drain()
+ raise
+ method = getattr(protocol, cmd)
+ return method(self.repo, req)
+ except ErrorResponse, inst:
+ req.respond(inst, protocol.HGTYPE)
+ if not inst.message:
+ return []
+ return '0\n%s\n' % inst.message,
+
+ # translate user-visible url structure to internal structure
+
+ args = query.split('/', 2)
+ if 'cmd' not in req.form and args and args[0]:
+
+ cmd = args.pop(0)
+ style = cmd.rfind('-')
+ if style != -1:
+ req.form['style'] = [cmd[:style]]
+ cmd = cmd[style+1:]
+
+ # avoid accepting e.g. style parameter as command
+ if hasattr(webcommands, cmd):
+ req.form['cmd'] = [cmd]
+ else:
+ cmd = ''
+
+ if cmd == 'static':
+ req.form['file'] = ['/'.join(args)]
+ else:
+ if args and args[0]:
+ node = args.pop(0)
+ req.form['node'] = [node]
+ if args:
+ req.form['file'] = args
+
+ if cmd == 'archive':
+ fn = req.form['node'][0]
+ for type_, spec in self.archive_specs.iteritems():
+ ext = spec[2]
+ if fn.endswith(ext):
+ req.form['node'] = [fn[:-len(ext)]]
+ req.form['type'] = [type_]
+
+ # process the web interface request
+
+ try:
+ tmpl = self.templater(req)
+ ctype = tmpl('mimetype', encoding=encoding.encoding)
+ ctype = templater.stringify(ctype)
+
+ # check read permissions non-static content
+ if cmd != 'static':
+ self.check_perm(req, None)
+
+ if cmd == '':
+ req.form['cmd'] = [tmpl.cache['default']]
+ cmd = req.form['cmd'][0]
+
+ if cmd not in webcommands.__all__:
+ msg = 'no such method: %s' % cmd
+ raise ErrorResponse(HTTP_BAD_REQUEST, msg)
+ elif cmd == 'file' and 'raw' in req.form.get('style', []):
+ self.ctype = ctype
+ content = webcommands.rawfile(self, req, tmpl)
+ else:
+ content = getattr(webcommands, cmd)(self, req, tmpl)
+ req.respond(HTTP_OK, ctype)
+
+ return content
+
+ except error.LookupError, err:
+ req.respond(HTTP_NOT_FOUND, ctype)
+ msg = str(err)
+ if 'manifest' not in msg:
+ msg = 'revision not found: %s' % err.name
+ return tmpl('error', error=msg)
+ except (error.RepoError, error.RevlogError), inst:
+ req.respond(HTTP_SERVER_ERROR, ctype)
+ return tmpl('error', error=str(inst))
+ except ErrorResponse, inst:
+ req.respond(inst, ctype)
+ return tmpl('error', error=inst.message)
+
+ def templater(self, req):
+
+ # determine scheme, port and server name
+ # this is needed to create absolute urls
+
+ proto = req.env.get('wsgi.url_scheme')
+ if proto == 'https':
+ proto = 'https'
+ default_port = "443"
+ else:
+ proto = 'http'
+ default_port = "80"
+
+ port = req.env["SERVER_PORT"]
+ port = port != default_port and (":" + port) or ""
+ urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
+ staticurl = self.config("web", "staticurl") or req.url + 'static/'
+ if not staticurl.endswith('/'):
+ staticurl += '/'
+
+ # some functions for the templater
+
+ def header(**map):
+ yield tmpl('header', encoding=encoding.encoding, **map)
+
+ def footer(**map):
+ yield tmpl("footer", **map)
+
+ def motd(**map):
+ yield self.config("web", "motd", "")
+
+ # figure out which style to use
+
+ vars = {}
+ style = self.config("web", "style", "paper")
+ if 'style' in req.form:
+ style = req.form['style'][0]
+ vars['style'] = style
+
+ start = req.url[-1] == '?' and '&' or '?'
+ sessionvars = webutil.sessionvars(vars, start)
+ mapfile = templater.stylemap(style, self.templatepath)
+
+ if not self.reponame:
+ self.reponame = (self.config("web", "name")
+ or req.env.get('REPO_NAME')
+ or req.url.strip('/') or self.repo.root)
+
+ # create the templater
+
+ tmpl = templater.templater(mapfile,
+ defaults={"url": req.url,
+ "staticurl": staticurl,
+ "urlbase": urlbase,
+ "repo": self.reponame,
+ "header": header,
+ "footer": footer,
+ "motd": motd,
+ "sessionvars": sessionvars
+ })
+ return tmpl
+
+ def archivelist(self, nodeid):
+ allowed = self.configlist("web", "allow_archive")
+ for i, spec in self.archive_specs.iteritems():
+ if i in allowed or self.configbool("web", "allow" + i):
+ yield {"type" : i, "extension" : spec[2], "node" : nodeid}
+
+ archive_specs = {
+ 'bz2': ('application/x-tar', 'tbz2', '.tar.bz2', None),
+ 'gz': ('application/x-tar', 'tgz', '.tar.gz', None),
+ 'zip': ('application/zip', 'zip', '.zip', None),
+ }
+
+ def check_perm(self, req, op):
+ '''Check permission for operation based on request data (including
+ authentication info). Return if op allowed, else raise an ErrorResponse
+ exception.'''
+
+ user = req.env.get('REMOTE_USER')
+
+ deny_read = self.configlist('web', 'deny_read')
+ if deny_read and (not user or deny_read == ['*'] or user in deny_read):
+ raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized')
+
+ allow_read = self.configlist('web', 'allow_read')
+ result = (not allow_read) or (allow_read == ['*'])
+ if not (result or user in allow_read):
+ raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized')
+
+ if op == 'pull' and not self.allowpull:
+ raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized')
+ elif op == 'pull' or op is None: # op is None for interface requests
+ return
+
+ # enforce that you can only push using POST requests
+ if req.env['REQUEST_METHOD'] != 'POST':
+ msg = 'push requires POST request'
+ raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
+
+ # require ssl by default for pushing, auth info cannot be sniffed
+ # and replayed
+ scheme = req.env.get('wsgi.url_scheme')
+ if self.configbool('web', 'push_ssl', True) and scheme != 'https':
+ raise ErrorResponse(HTTP_OK, 'ssl required')
+
+ deny = self.configlist('web', 'deny_push')
+ if deny and (not user or deny == ['*'] or user in deny):
+ raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
+
+ allow = self.configlist('web', 'allow_push')
+ result = allow and (allow == ['*'] or user in allow)
+ if not result:
+ raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
diff --git a/sys/src/cmd/hg/mercurial/hgweb/hgwebdir_mod.py b/sys/src/cmd/hg/mercurial/hgweb/hgwebdir_mod.py
new file mode 100644
index 000000000..64cc99899
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/hgwebdir_mod.py
@@ -0,0 +1,333 @@
+# hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
+#
+# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os, re, time
+from mercurial.i18n import _
+from mercurial import ui, hg, util, templater
+from mercurial import error, encoding
+from common import ErrorResponse, get_mtime, staticfile, paritygen,\
+ get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
+from hgweb_mod import hgweb
+from request import wsgirequest
+import webutil
+
+def cleannames(items):
+ return [(util.pconvert(name).strip('/'), path) for name, path in items]
+
+def findrepos(paths):
+ repos = {}
+ for prefix, root in cleannames(paths):
+ roothead, roottail = os.path.split(root)
+ # "foo = /bar/*" makes every subrepo of /bar/ to be
+ # mounted as foo/subrepo
+ # and "foo = /bar/**" also recurses into the subdirectories,
+ # remember to use it without working dir.
+ try:
+ recurse = {'*': False, '**': True}[roottail]
+ except KeyError:
+ repos[prefix] = root
+ continue
+ roothead = os.path.normpath(roothead)
+ for path in util.walkrepos(roothead, followsym=True, recurse=recurse):
+ path = os.path.normpath(path)
+ name = util.pconvert(path[len(roothead):]).strip('/')
+ if prefix:
+ name = prefix + '/' + name
+ repos[name] = path
+ return repos.items()
+
+class hgwebdir(object):
+ refreshinterval = 20
+
+ def __init__(self, conf, baseui=None):
+ self.conf = conf
+ self.baseui = baseui
+ self.lastrefresh = 0
+ self.refresh()
+
+ def refresh(self):
+ if self.lastrefresh + self.refreshinterval > time.time():
+ return
+
+ if self.baseui:
+ self.ui = self.baseui.copy()
+ else:
+ self.ui = ui.ui()
+ self.ui.setconfig('ui', 'report_untrusted', 'off')
+ self.ui.setconfig('ui', 'interactive', 'off')
+
+ if not isinstance(self.conf, (dict, list, tuple)):
+ map = {'paths': 'hgweb-paths'}
+ self.ui.readconfig(self.conf, remap=map, trust=True)
+ paths = self.ui.configitems('hgweb-paths')
+ elif isinstance(self.conf, (list, tuple)):
+ paths = self.conf
+ elif isinstance(self.conf, dict):
+ paths = self.conf.items()
+
+ encoding.encoding = self.ui.config('web', 'encoding',
+ encoding.encoding)
+ self.motd = self.ui.config('web', 'motd')
+ self.style = self.ui.config('web', 'style', 'paper')
+ self.stripecount = self.ui.config('web', 'stripes', 1)
+ if self.stripecount:
+ self.stripecount = int(self.stripecount)
+ self._baseurl = self.ui.config('web', 'baseurl')
+
+ self.repos = findrepos(paths)
+ for prefix, root in self.ui.configitems('collections'):
+ prefix = util.pconvert(prefix)
+ for path in util.walkrepos(root, followsym=True):
+ repo = os.path.normpath(path)
+ name = util.pconvert(repo)
+ if name.startswith(prefix):
+ name = name[len(prefix):]
+ self.repos.append((name.lstrip('/'), repo))
+
+ self.repos.sort()
+ self.lastrefresh = time.time()
+
+ def run(self):
+ if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
+ raise RuntimeError("This function is only intended to be "
+ "called while running as a CGI script.")
+ import mercurial.hgweb.wsgicgi as wsgicgi
+ wsgicgi.launch(self)
+
+ def __call__(self, env, respond):
+ req = wsgirequest(env, respond)
+ return self.run_wsgi(req)
+
+ def read_allowed(self, ui, req):
+ """Check allow_read and deny_read config options of a repo's ui object
+ to determine user permissions. By default, with neither option set (or
+ both empty), allow all users to read the repo. There are two ways a
+ user can be denied read access: (1) deny_read is not empty, and the
+ user is unauthenticated or deny_read contains user (or *), and (2)
+ allow_read is not empty and the user is not in allow_read. Return True
+ if user is allowed to read the repo, else return False."""
+
+ user = req.env.get('REMOTE_USER')
+
+ deny_read = ui.configlist('web', 'deny_read', untrusted=True)
+ if deny_read and (not user or deny_read == ['*'] or user in deny_read):
+ return False
+
+ allow_read = ui.configlist('web', 'allow_read', untrusted=True)
+ # by default, allow reading if no allow_read option has been set
+ if (not allow_read) or (allow_read == ['*']) or (user in allow_read):
+ return True
+
+ return False
+
+ def run_wsgi(self, req):
+ try:
+ try:
+ self.refresh()
+
+ virtual = req.env.get("PATH_INFO", "").strip('/')
+ tmpl = self.templater(req)
+ ctype = tmpl('mimetype', encoding=encoding.encoding)
+ ctype = templater.stringify(ctype)
+
+ # a static file
+ if virtual.startswith('static/') or 'static' in req.form:
+ if virtual.startswith('static/'):
+ fname = virtual[7:]
+ else:
+ fname = req.form['static'][0]
+ static = templater.templatepath('static')
+ return (staticfile(static, fname, req),)
+
+ # top-level index
+ elif not virtual:
+ req.respond(HTTP_OK, ctype)
+ return self.makeindex(req, tmpl)
+
+ # nested indexes and hgwebs
+
+ repos = dict(self.repos)
+ while virtual:
+ real = repos.get(virtual)
+ if real:
+ req.env['REPO_NAME'] = virtual
+ try:
+ repo = hg.repository(self.ui, real)
+ return hgweb(repo).run_wsgi(req)
+ except IOError, inst:
+ msg = inst.strerror
+ raise ErrorResponse(HTTP_SERVER_ERROR, msg)
+ except error.RepoError, inst:
+ raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
+
+ # browse subdirectories
+ subdir = virtual + '/'
+ if [r for r in repos if r.startswith(subdir)]:
+ req.respond(HTTP_OK, ctype)
+ return self.makeindex(req, tmpl, subdir)
+
+ up = virtual.rfind('/')
+ if up < 0:
+ break
+ virtual = virtual[:up]
+
+ # prefixes not found
+ req.respond(HTTP_NOT_FOUND, ctype)
+ return tmpl("notfound", repo=virtual)
+
+ except ErrorResponse, err:
+ req.respond(err, ctype)
+ return tmpl('error', error=err.message or '')
+ finally:
+ tmpl = None
+
+ def makeindex(self, req, tmpl, subdir=""):
+
+ def archivelist(ui, nodeid, url):
+ allowed = ui.configlist("web", "allow_archive", untrusted=True)
+ for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
+ if i[0] in allowed or ui.configbool("web", "allow" + i[0],
+ untrusted=True):
+ yield {"type" : i[0], "extension": i[1],
+ "node": nodeid, "url": url}
+
+ sortdefault = 'name', False
+ def entries(sortcolumn="", descending=False, subdir="", **map):
+ rows = []
+ parity = paritygen(self.stripecount)
+ for name, path in self.repos:
+ if not name.startswith(subdir):
+ continue
+ name = name[len(subdir):]
+
+ u = self.ui.copy()
+ try:
+ u.readconfig(os.path.join(path, '.hg', 'hgrc'))
+ except Exception, e:
+ u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e))
+ continue
+ def get(section, name, default=None):
+ return u.config(section, name, default, untrusted=True)
+
+ if u.configbool("web", "hidden", untrusted=True):
+ continue
+
+ if not self.read_allowed(u, req):
+ continue
+
+ parts = [name]
+ if 'PATH_INFO' in req.env:
+ parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
+ if req.env['SCRIPT_NAME']:
+ parts.insert(0, req.env['SCRIPT_NAME'])
+ m = re.match('((?:https?://)?)(.*)', '/'.join(parts))
+ # squish repeated slashes out of the path component
+ url = m.group(1) + re.sub('/+', '/', m.group(2)) + '/'
+
+ # update time with local timezone
+ try:
+ d = (get_mtime(path), util.makedate()[1])
+ except OSError:
+ continue
+
+ contact = get_contact(get)
+ description = get("web", "description", "")
+ name = get("web", "name", name)
+ row = dict(contact=contact or "unknown",
+ contact_sort=contact.upper() or "unknown",
+ name=name,
+ name_sort=name,
+ url=url,
+ description=description or "unknown",
+ description_sort=description.upper() or "unknown",
+ lastchange=d,
+ lastchange_sort=d[1]-d[0],
+ archives=archivelist(u, "tip", url))
+ if (not sortcolumn or (sortcolumn, descending) == sortdefault):
+ # fast path for unsorted output
+ row['parity'] = parity.next()
+ yield row
+ else:
+ rows.append((row["%s_sort" % sortcolumn], row))
+ if rows:
+ rows.sort()
+ if descending:
+ rows.reverse()
+ for key, row in rows:
+ row['parity'] = parity.next()
+ yield row
+
+ self.refresh()
+ sortable = ["name", "description", "contact", "lastchange"]
+ sortcolumn, descending = sortdefault
+ if 'sort' in req.form:
+ sortcolumn = req.form['sort'][0]
+ descending = sortcolumn.startswith('-')
+ if descending:
+ sortcolumn = sortcolumn[1:]
+ if sortcolumn not in sortable:
+ sortcolumn = ""
+
+ sort = [("sort_%s" % column,
+ "%s%s" % ((not descending and column == sortcolumn)
+ and "-" or "", column))
+ for column in sortable]
+
+ self.refresh()
+ if self._baseurl is not None:
+ req.env['SCRIPT_NAME'] = self._baseurl
+
+ return tmpl("index", entries=entries, subdir=subdir,
+ sortcolumn=sortcolumn, descending=descending,
+ **dict(sort))
+
+ def templater(self, req):
+
+ def header(**map):
+ yield tmpl('header', encoding=encoding.encoding, **map)
+
+ def footer(**map):
+ yield tmpl("footer", **map)
+
+ def motd(**map):
+ if self.motd is not None:
+ yield self.motd
+ else:
+ yield config('web', 'motd', '')
+
+ def config(section, name, default=None, untrusted=True):
+ return self.ui.config(section, name, default, untrusted)
+
+ if self._baseurl is not None:
+ req.env['SCRIPT_NAME'] = self._baseurl
+
+ url = req.env.get('SCRIPT_NAME', '')
+ if not url.endswith('/'):
+ url += '/'
+
+ vars = {}
+ style = self.style
+ if 'style' in req.form:
+ vars['style'] = style = req.form['style'][0]
+ start = url[-1] == '?' and '&' or '?'
+ sessionvars = webutil.sessionvars(vars, start)
+
+ staticurl = config('web', 'staticurl') or url + 'static/'
+ if not staticurl.endswith('/'):
+ staticurl += '/'
+
+ style = 'style' in req.form and req.form['style'][0] or self.style
+ mapfile = templater.stylemap(style)
+ tmpl = templater.templater(mapfile,
+ defaults={"header": header,
+ "footer": footer,
+ "motd": motd,
+ "url": url,
+ "staticurl": staticurl,
+ "sessionvars": sessionvars})
+ return tmpl
diff --git a/sys/src/cmd/hg/mercurial/hgweb/protocol.py b/sys/src/cmd/hg/mercurial/hgweb/protocol.py
new file mode 100644
index 000000000..a411fdb97
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/protocol.py
@@ -0,0 +1,206 @@
+#
+# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import cStringIO, zlib, tempfile, errno, os, sys, urllib
+from mercurial import util, streamclone
+from mercurial.node import bin, hex
+from mercurial import changegroup as changegroupmod
+from common import ErrorResponse, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
+
+# __all__ is populated with the allowed commands. Be sure to add to it if
+# you're adding a new command, or the new command won't work.
+
+__all__ = [
+ 'lookup', 'heads', 'branches', 'between', 'changegroup',
+ 'changegroupsubset', 'capabilities', 'unbundle', 'stream_out',
+ 'branchmap',
+]
+
+HGTYPE = 'application/mercurial-0.1'
+
+def lookup(repo, req):
+ try:
+ r = hex(repo.lookup(req.form['key'][0]))
+ success = 1
+ except Exception, inst:
+ r = str(inst)
+ success = 0
+ resp = "%s %s\n" % (success, r)
+ req.respond(HTTP_OK, HGTYPE, length=len(resp))
+ yield resp
+
+def heads(repo, req):
+ resp = " ".join(map(hex, repo.heads())) + "\n"
+ req.respond(HTTP_OK, HGTYPE, length=len(resp))
+ yield resp
+
+def branchmap(repo, req):
+ branches = repo.branchmap()
+ heads = []
+ for branch, nodes in branches.iteritems():
+ branchname = urllib.quote(branch)
+ branchnodes = [hex(node) for node in nodes]
+ heads.append('%s %s' % (branchname, ' '.join(branchnodes)))
+ resp = '\n'.join(heads)
+ req.respond(HTTP_OK, HGTYPE, length=len(resp))
+ yield resp
+
+def branches(repo, req):
+ nodes = []
+ if 'nodes' in req.form:
+ nodes = map(bin, req.form['nodes'][0].split(" "))
+ resp = cStringIO.StringIO()
+ for b in repo.branches(nodes):
+ resp.write(" ".join(map(hex, b)) + "\n")
+ resp = resp.getvalue()
+ req.respond(HTTP_OK, HGTYPE, length=len(resp))
+ yield resp
+
+def between(repo, req):
+ if 'pairs' in req.form:
+ pairs = [map(bin, p.split("-"))
+ for p in req.form['pairs'][0].split(" ")]
+ resp = cStringIO.StringIO()
+ for b in repo.between(pairs):
+ resp.write(" ".join(map(hex, b)) + "\n")
+ resp = resp.getvalue()
+ req.respond(HTTP_OK, HGTYPE, length=len(resp))
+ yield resp
+
+def changegroup(repo, req):
+ req.respond(HTTP_OK, HGTYPE)
+ nodes = []
+
+ if 'roots' in req.form:
+ nodes = map(bin, req.form['roots'][0].split(" "))
+
+ z = zlib.compressobj()
+ f = repo.changegroup(nodes, 'serve')
+ while 1:
+ chunk = f.read(4096)
+ if not chunk:
+ break
+ yield z.compress(chunk)
+
+ yield z.flush()
+
+def changegroupsubset(repo, req):
+ req.respond(HTTP_OK, HGTYPE)
+ bases = []
+ heads = []
+
+ if 'bases' in req.form:
+ bases = [bin(x) for x in req.form['bases'][0].split(' ')]
+ if 'heads' in req.form:
+ heads = [bin(x) for x in req.form['heads'][0].split(' ')]
+
+ z = zlib.compressobj()
+ f = repo.changegroupsubset(bases, heads, 'serve')
+ while 1:
+ chunk = f.read(4096)
+ if not chunk:
+ break
+ yield z.compress(chunk)
+
+ yield z.flush()
+
+def capabilities(repo, req):
+ caps = ['lookup', 'changegroupsubset', 'branchmap']
+ if repo.ui.configbool('server', 'uncompressed', untrusted=True):
+ caps.append('stream=%d' % repo.changelog.version)
+ if changegroupmod.bundlepriority:
+ caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority))
+ rsp = ' '.join(caps)
+ req.respond(HTTP_OK, HGTYPE, length=len(rsp))
+ yield rsp
+
+def unbundle(repo, req):
+
+ proto = req.env.get('wsgi.url_scheme') or 'http'
+ their_heads = req.form['heads'][0].split(' ')
+
+ def check_heads():
+ heads = map(hex, repo.heads())
+ return their_heads == [hex('force')] or their_heads == heads
+
+ # fail early if possible
+ if not check_heads():
+ req.drain()
+ raise ErrorResponse(HTTP_OK, 'unsynced changes')
+
+ # do not lock repo until all changegroup data is
+ # streamed. save to temporary file.
+
+ fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
+ fp = os.fdopen(fd, 'wb+')
+ try:
+ length = int(req.env['CONTENT_LENGTH'])
+ for s in util.filechunkiter(req, limit=length):
+ fp.write(s)
+
+ try:
+ lock = repo.lock()
+ try:
+ if not check_heads():
+ raise ErrorResponse(HTTP_OK, 'unsynced changes')
+
+ fp.seek(0)
+ header = fp.read(6)
+ if header.startswith('HG') and not header.startswith('HG10'):
+ raise ValueError('unknown bundle version')
+ elif header not in changegroupmod.bundletypes:
+ raise ValueError('unknown bundle compression type')
+ gen = changegroupmod.unbundle(header, fp)
+
+ # send addchangegroup output to client
+
+ oldio = sys.stdout, sys.stderr
+ sys.stderr = sys.stdout = cStringIO.StringIO()
+
+ try:
+ url = 'remote:%s:%s:%s' % (
+ proto,
+ urllib.quote(req.env.get('REMOTE_HOST', '')),
+ urllib.quote(req.env.get('REMOTE_USER', '')))
+ try:
+ ret = repo.addchangegroup(gen, 'serve', url)
+ except util.Abort, inst:
+ sys.stdout.write("abort: %s\n" % inst)
+ ret = 0
+ finally:
+ val = sys.stdout.getvalue()
+ sys.stdout, sys.stderr = oldio
+ req.respond(HTTP_OK, HGTYPE)
+ return '%d\n%s' % (ret, val),
+ finally:
+ lock.release()
+ except ValueError, inst:
+ raise ErrorResponse(HTTP_OK, inst)
+ except (OSError, IOError), inst:
+ filename = getattr(inst, 'filename', '')
+ # Don't send our filesystem layout to the client
+ if filename.startswith(repo.root):
+ filename = filename[len(repo.root)+1:]
+ else:
+ filename = ''
+ error = getattr(inst, 'strerror', 'Unknown error')
+ if inst.errno == errno.ENOENT:
+ code = HTTP_NOT_FOUND
+ else:
+ code = HTTP_SERVER_ERROR
+ raise ErrorResponse(code, '%s: %s' % (error, filename))
+ finally:
+ fp.close()
+ os.unlink(tempname)
+
+def stream_out(repo, req):
+ req.respond(HTTP_OK, HGTYPE)
+ try:
+ for chunk in streamclone.stream_out(repo, untrusted=True):
+ yield chunk
+ except streamclone.StreamException, inst:
+ yield str(inst)
diff --git a/sys/src/cmd/hg/mercurial/hgweb/request.py b/sys/src/cmd/hg/mercurial/hgweb/request.py
new file mode 100644
index 000000000..4c7c5bf4b
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/request.py
@@ -0,0 +1,134 @@
+# hgweb/request.py - An http request from either CGI or the standalone server.
+#
+# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import socket, cgi, errno
+from mercurial import util
+from common import ErrorResponse, statusmessage
+
+shortcuts = {
+ 'cl': [('cmd', ['changelog']), ('rev', None)],
+ 'sl': [('cmd', ['shortlog']), ('rev', None)],
+ 'cs': [('cmd', ['changeset']), ('node', None)],
+ 'f': [('cmd', ['file']), ('filenode', None)],
+ 'fl': [('cmd', ['filelog']), ('filenode', None)],
+ 'fd': [('cmd', ['filediff']), ('node', None)],
+ 'fa': [('cmd', ['annotate']), ('filenode', None)],
+ 'mf': [('cmd', ['manifest']), ('manifest', None)],
+ 'ca': [('cmd', ['archive']), ('node', None)],
+ 'tags': [('cmd', ['tags'])],
+ 'tip': [('cmd', ['changeset']), ('node', ['tip'])],
+ 'static': [('cmd', ['static']), ('file', None)]
+}
+
+def expand(form):
+ for k in shortcuts.iterkeys():
+ if k in form:
+ for name, value in shortcuts[k]:
+ if value is None:
+ value = form[k]
+ form[name] = value
+ del form[k]
+ return form
+
+class wsgirequest(object):
+ def __init__(self, wsgienv, start_response):
+ version = wsgienv['wsgi.version']
+ if (version < (1, 0)) or (version >= (2, 0)):
+ raise RuntimeError("Unknown and unsupported WSGI version %d.%d"
+ % version)
+ self.inp = wsgienv['wsgi.input']
+ self.err = wsgienv['wsgi.errors']
+ self.threaded = wsgienv['wsgi.multithread']
+ self.multiprocess = wsgienv['wsgi.multiprocess']
+ self.run_once = wsgienv['wsgi.run_once']
+ self.env = wsgienv
+ self.form = expand(cgi.parse(self.inp, self.env, keep_blank_values=1))
+ self._start_response = start_response
+ self.server_write = None
+ self.headers = []
+
+ def __iter__(self):
+ return iter([])
+
+ def read(self, count=-1):
+ return self.inp.read(count)
+
+ def drain(self):
+ '''need to read all data from request, httplib is half-duplex'''
+ length = int(self.env.get('CONTENT_LENGTH', 0))
+ for s in util.filechunkiter(self.inp, limit=length):
+ pass
+
+ def respond(self, status, type=None, filename=None, length=0):
+ if self._start_response is not None:
+
+ self.httphdr(type, filename, length)
+ if not self.headers:
+ raise RuntimeError("request.write called before headers sent")
+
+ for k, v in self.headers:
+ if not isinstance(v, str):
+ raise TypeError('header value must be string: %r' % v)
+
+ if isinstance(status, ErrorResponse):
+ self.header(status.headers)
+ status = statusmessage(status.code)
+ elif status == 200:
+ status = '200 Script output follows'
+ elif isinstance(status, int):
+ status = statusmessage(status)
+
+ self.server_write = self._start_response(status, self.headers)
+ self._start_response = None
+ self.headers = []
+
+ def write(self, thing):
+ if hasattr(thing, "__iter__"):
+ for part in thing:
+ self.write(part)
+ else:
+ thing = str(thing)
+ try:
+ self.server_write(thing)
+ except socket.error, inst:
+ if inst[0] != errno.ECONNRESET:
+ raise
+
+ def writelines(self, lines):
+ for line in lines:
+ self.write(line)
+
+ def flush(self):
+ return None
+
+ def close(self):
+ return None
+
+ def header(self, headers=[('Content-Type','text/html')]):
+ self.headers.extend(headers)
+
+ def httphdr(self, type=None, filename=None, length=0, headers={}):
+ headers = headers.items()
+ if type is not None:
+ headers.append(('Content-Type', type))
+ if filename:
+ filename = (filename.split('/')[-1]
+ .replace('\\', '\\\\').replace('"', '\\"'))
+ headers.append(('Content-Disposition',
+ 'inline; filename="%s"' % filename))
+ if length:
+ headers.append(('Content-Length', str(length)))
+ self.header(headers)
+
+def wsgiapplication(app_maker):
+ '''For compatibility with old CGI scripts. A plain hgweb() or hgwebdir()
+ can and should now be used as a WSGI application.'''
+ application = app_maker()
+ def run_wsgi(env, respond):
+ return application(env, respond)
+ return run_wsgi
diff --git a/sys/src/cmd/hg/mercurial/hgweb/server.py b/sys/src/cmd/hg/mercurial/hgweb/server.py
new file mode 100644
index 000000000..a14bc757f
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/server.py
@@ -0,0 +1,298 @@
+# hgweb/server.py - The standalone hg web server.
+#
+# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os, sys, errno, urllib, BaseHTTPServer, socket, SocketServer, traceback
+from mercurial import hg, util, error
+from hgweb_mod import hgweb
+from hgwebdir_mod import hgwebdir
+from mercurial.i18n import _
+
+def _splitURI(uri):
+ """ Return path and query splited from uri
+
+ Just like CGI environment, the path is unquoted, the query is
+ not.
+ """
+ if '?' in uri:
+ path, query = uri.split('?', 1)
+ else:
+ path, query = uri, ''
+ return urllib.unquote(path), query
+
+class _error_logger(object):
+ def __init__(self, handler):
+ self.handler = handler
+ def flush(self):
+ pass
+ def write(self, str):
+ self.writelines(str.split('\n'))
+ def writelines(self, seq):
+ for msg in seq:
+ self.handler.log_error("HG error: %s", msg)
+
+class _hgwebhandler(BaseHTTPServer.BaseHTTPRequestHandler):
+
+ url_scheme = 'http'
+
+ def __init__(self, *args, **kargs):
+ self.protocol_version = 'HTTP/1.1'
+ BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kargs)
+
+ def _log_any(self, fp, format, *args):
+ fp.write("%s - - [%s] %s\n" % (self.client_address[0],
+ self.log_date_time_string(),
+ format % args))
+ fp.flush()
+
+ def log_error(self, format, *args):
+ self._log_any(self.server.errorlog, format, *args)
+
+ def log_message(self, format, *args):
+ self._log_any(self.server.accesslog, format, *args)
+
+ def do_write(self):
+ try:
+ self.do_hgweb()
+ except socket.error, inst:
+ if inst[0] != errno.EPIPE:
+ raise
+
+ def do_POST(self):
+ try:
+ self.do_write()
+ except StandardError:
+ self._start_response("500 Internal Server Error", [])
+ self._write("Internal Server Error")
+ tb = "".join(traceback.format_exception(*sys.exc_info()))
+ self.log_error("Exception happened during processing "
+ "request '%s':\n%s", self.path, tb)
+
+ def do_GET(self):
+ self.do_POST()
+
+ def do_hgweb(self):
+ path, query = _splitURI(self.path)
+
+ env = {}
+ env['GATEWAY_INTERFACE'] = 'CGI/1.1'
+ env['REQUEST_METHOD'] = self.command
+ env['SERVER_NAME'] = self.server.server_name
+ env['SERVER_PORT'] = str(self.server.server_port)
+ env['REQUEST_URI'] = self.path
+ env['SCRIPT_NAME'] = self.server.prefix
+ env['PATH_INFO'] = path[len(self.server.prefix):]
+ env['REMOTE_HOST'] = self.client_address[0]
+ env['REMOTE_ADDR'] = self.client_address[0]
+ if query:
+ env['QUERY_STRING'] = query
+
+ if self.headers.typeheader is None:
+ env['CONTENT_TYPE'] = self.headers.type
+ else:
+ env['CONTENT_TYPE'] = self.headers.typeheader
+ length = self.headers.getheader('content-length')
+ if length:
+ env['CONTENT_LENGTH'] = length
+ for header in [h for h in self.headers.keys()
+ if h not in ('content-type', 'content-length')]:
+ hkey = 'HTTP_' + header.replace('-', '_').upper()
+ hval = self.headers.getheader(header)
+ hval = hval.replace('\n', '').strip()
+ if hval:
+ env[hkey] = hval
+ env['SERVER_PROTOCOL'] = self.request_version
+ env['wsgi.version'] = (1, 0)
+ env['wsgi.url_scheme'] = self.url_scheme
+ env['wsgi.input'] = self.rfile
+ env['wsgi.errors'] = _error_logger(self)
+ env['wsgi.multithread'] = isinstance(self.server,
+ SocketServer.ThreadingMixIn)
+ env['wsgi.multiprocess'] = isinstance(self.server,
+ SocketServer.ForkingMixIn)
+ env['wsgi.run_once'] = 0
+
+ self.close_connection = True
+ self.saved_status = None
+ self.saved_headers = []
+ self.sent_headers = False
+ self.length = None
+ for chunk in self.server.application(env, self._start_response):
+ self._write(chunk)
+
+ def send_headers(self):
+ if not self.saved_status:
+ raise AssertionError("Sending headers before "
+ "start_response() called")
+ saved_status = self.saved_status.split(None, 1)
+ saved_status[0] = int(saved_status[0])
+ self.send_response(*saved_status)
+ should_close = True
+ for h in self.saved_headers:
+ self.send_header(*h)
+ if h[0].lower() == 'content-length':
+ should_close = False
+ self.length = int(h[1])
+ # The value of the Connection header is a list of case-insensitive
+ # tokens separated by commas and optional whitespace.
+ if 'close' in [token.strip().lower() for token in
+ self.headers.get('connection', '').split(',')]:
+ should_close = True
+ if should_close:
+ self.send_header('Connection', 'close')
+ self.close_connection = should_close
+ self.end_headers()
+ self.sent_headers = True
+
+ def _start_response(self, http_status, headers, exc_info=None):
+ code, msg = http_status.split(None, 1)
+ code = int(code)
+ self.saved_status = http_status
+ bad_headers = ('connection', 'transfer-encoding')
+ self.saved_headers = [h for h in headers
+ if h[0].lower() not in bad_headers]
+ return self._write
+
+ def _write(self, data):
+ if not self.saved_status:
+ raise AssertionError("data written before start_response() called")
+ elif not self.sent_headers:
+ self.send_headers()
+ if self.length is not None:
+ if len(data) > self.length:
+ raise AssertionError("Content-length header sent, but more "
+ "bytes than specified are being written.")
+ self.length = self.length - len(data)
+ self.wfile.write(data)
+ self.wfile.flush()
+
+class _shgwebhandler(_hgwebhandler):
+
+ url_scheme = 'https'
+
+ def setup(self):
+ self.connection = self.request
+ self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
+ self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+
+ def do_write(self):
+ from OpenSSL.SSL import SysCallError
+ try:
+ super(_shgwebhandler, self).do_write()
+ except SysCallError, inst:
+ if inst.args[0] != errno.EPIPE:
+ raise
+
+ def handle_one_request(self):
+ from OpenSSL.SSL import SysCallError, ZeroReturnError
+ try:
+ super(_shgwebhandler, self).handle_one_request()
+ except (SysCallError, ZeroReturnError):
+ self.close_connection = True
+ pass
+
+def create_server(ui, repo):
+ use_threads = True
+
+ def openlog(opt, default):
+ if opt and opt != '-':
+ return open(opt, 'a')
+ return default
+
+ if repo is None:
+ myui = ui
+ else:
+ myui = repo.ui
+ address = myui.config("web", "address", "")
+ port = int(myui.config("web", "port", 8000))
+ prefix = myui.config("web", "prefix", "")
+ if prefix:
+ prefix = "/" + prefix.strip("/")
+ use_ipv6 = myui.configbool("web", "ipv6")
+ webdir_conf = myui.config("web", "webdir_conf")
+ ssl_cert = myui.config("web", "certificate")
+ accesslog = openlog(myui.config("web", "accesslog", "-"), sys.stdout)
+ errorlog = openlog(myui.config("web", "errorlog", "-"), sys.stderr)
+
+ if use_threads:
+ try:
+ from threading import activeCount
+ except ImportError:
+ use_threads = False
+
+ if use_threads:
+ _mixin = SocketServer.ThreadingMixIn
+ else:
+ if hasattr(os, "fork"):
+ _mixin = SocketServer.ForkingMixIn
+ else:
+ class _mixin:
+ pass
+
+ class MercurialHTTPServer(object, _mixin, BaseHTTPServer.HTTPServer):
+
+ # SO_REUSEADDR has broken semantics on windows
+ if os.name == 'nt':
+ allow_reuse_address = 0
+
+ def __init__(self, *args, **kargs):
+ BaseHTTPServer.HTTPServer.__init__(self, *args, **kargs)
+ self.accesslog = accesslog
+ self.errorlog = errorlog
+ self.daemon_threads = True
+ def make_handler():
+ if webdir_conf:
+ hgwebobj = hgwebdir(webdir_conf, ui)
+ elif repo is not None:
+ hgwebobj = hgweb(hg.repository(repo.ui, repo.root))
+ else:
+ raise error.RepoError(_("There is no Mercurial repository"
+ " here (.hg not found)"))
+ return hgwebobj
+ self.application = make_handler()
+
+ if ssl_cert:
+ try:
+ from OpenSSL import SSL
+ ctx = SSL.Context(SSL.SSLv23_METHOD)
+ except ImportError:
+ raise util.Abort(_("SSL support is unavailable"))
+ ctx.use_privatekey_file(ssl_cert)
+ ctx.use_certificate_file(ssl_cert)
+ sock = socket.socket(self.address_family, self.socket_type)
+ self.socket = SSL.Connection(ctx, sock)
+ self.server_bind()
+ self.server_activate()
+
+ self.addr, self.port = self.socket.getsockname()[0:2]
+ self.prefix = prefix
+ self.fqaddr = socket.getfqdn(address)
+
+ class IPv6HTTPServer(MercurialHTTPServer):
+ address_family = getattr(socket, 'AF_INET6', None)
+
+ def __init__(self, *args, **kwargs):
+ if self.address_family is None:
+ raise error.RepoError(_('IPv6 is not available on this system'))
+ super(IPv6HTTPServer, self).__init__(*args, **kwargs)
+
+ if ssl_cert:
+ handler = _shgwebhandler
+ else:
+ handler = _hgwebhandler
+
+ # ugly hack due to python issue5853 (for threaded use)
+ import mimetypes; mimetypes.init()
+
+ try:
+ if use_ipv6:
+ return IPv6HTTPServer((address, port), handler)
+ else:
+ return MercurialHTTPServer((address, port), handler)
+ except socket.error, inst:
+ raise util.Abort(_("cannot start server at '%s:%d': %s")
+ % (address, port, inst.args[1]))
diff --git a/sys/src/cmd/hg/mercurial/hgweb/webcommands.py b/sys/src/cmd/hg/mercurial/hgweb/webcommands.py
new file mode 100644
index 000000000..c12425e02
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/webcommands.py
@@ -0,0 +1,690 @@
+#
+# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os, mimetypes, re, cgi, copy
+import webutil
+from mercurial import error, archival, templater, templatefilters
+from mercurial.node import short, hex
+from mercurial.util import binary
+from common import paritygen, staticfile, get_contact, ErrorResponse
+from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
+from mercurial import graphmod
+
+# __all__ is populated with the allowed commands. Be sure to add to it if
+# you're adding a new command, or the new command won't work.
+
+__all__ = [
+ 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
+ 'manifest', 'tags', 'branches', 'summary', 'filediff', 'diff', 'annotate',
+ 'filelog', 'archive', 'static', 'graph',
+]
+
+def log(web, req, tmpl):
+ if 'file' in req.form and req.form['file'][0]:
+ return filelog(web, req, tmpl)
+ else:
+ return changelog(web, req, tmpl)
+
+def rawfile(web, req, tmpl):
+ path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
+ if not path:
+ content = manifest(web, req, tmpl)
+ req.respond(HTTP_OK, web.ctype)
+ return content
+
+ try:
+ fctx = webutil.filectx(web.repo, req)
+ except error.LookupError, inst:
+ try:
+ content = manifest(web, req, tmpl)
+ req.respond(HTTP_OK, web.ctype)
+ return content
+ except ErrorResponse:
+ raise inst
+
+ path = fctx.path()
+ text = fctx.data()
+ mt = mimetypes.guess_type(path)[0]
+ if mt is None:
+ mt = binary(text) and 'application/octet-stream' or 'text/plain'
+
+ req.respond(HTTP_OK, mt, path, len(text))
+ return [text]
+
+def _filerevision(web, tmpl, fctx):
+ f = fctx.path()
+ text = fctx.data()
+ parity = paritygen(web.stripecount)
+
+ if binary(text):
+ mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
+ text = '(binary:%s)' % mt
+
+ def lines():
+ for lineno, t in enumerate(text.splitlines(True)):
+ yield {"line": t,
+ "lineid": "l%d" % (lineno + 1),
+ "linenumber": "% 6d" % (lineno + 1),
+ "parity": parity.next()}
+
+ return tmpl("filerevision",
+ file=f,
+ path=webutil.up(f),
+ text=lines(),
+ rev=fctx.rev(),
+ node=hex(fctx.node()),
+ author=fctx.user(),
+ date=fctx.date(),
+ desc=fctx.description(),
+ branch=webutil.nodebranchnodefault(fctx),
+ parent=webutil.parents(fctx),
+ child=webutil.children(fctx),
+ rename=webutil.renamelink(fctx),
+ permissions=fctx.manifest().flags(f))
+
+def file(web, req, tmpl):
+ path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
+ if not path:
+ return manifest(web, req, tmpl)
+ try:
+ return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
+ except error.LookupError, inst:
+ try:
+ return manifest(web, req, tmpl)
+ except ErrorResponse:
+ raise inst
+
+def _search(web, tmpl, query):
+
+ def changelist(**map):
+ cl = web.repo.changelog
+ count = 0
+ qw = query.lower().split()
+
+ def revgen():
+ for i in xrange(len(cl) - 1, 0, -100):
+ l = []
+ for j in xrange(max(0, i - 100), i + 1):
+ ctx = web.repo[j]
+ l.append(ctx)
+ l.reverse()
+ for e in l:
+ yield e
+
+ for ctx in revgen():
+ miss = 0
+ for q in qw:
+ if not (q in ctx.user().lower() or
+ q in ctx.description().lower() or
+ q in " ".join(ctx.files()).lower()):
+ miss = 1
+ break
+ if miss:
+ continue
+
+ count += 1
+ n = ctx.node()
+ showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
+ files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
+
+ yield tmpl('searchentry',
+ parity=parity.next(),
+ author=ctx.user(),
+ parent=webutil.parents(ctx),
+ child=webutil.children(ctx),
+ changelogtag=showtags,
+ desc=ctx.description(),
+ date=ctx.date(),
+ files=files,
+ rev=ctx.rev(),
+ node=hex(n),
+ tags=webutil.nodetagsdict(web.repo, n),
+ inbranch=webutil.nodeinbranch(web.repo, ctx),
+ branches=webutil.nodebranchdict(web.repo, ctx))
+
+ if count >= web.maxchanges:
+ break
+
+ cl = web.repo.changelog
+ parity = paritygen(web.stripecount)
+
+ return tmpl('search',
+ query=query,
+ node=hex(cl.tip()),
+ entries=changelist,
+ archives=web.archivelist("tip"))
+
+def changelog(web, req, tmpl, shortlog = False):
+ if 'node' in req.form:
+ ctx = webutil.changectx(web.repo, req)
+ else:
+ if 'rev' in req.form:
+ hi = req.form['rev'][0]
+ else:
+ hi = len(web.repo) - 1
+ try:
+ ctx = web.repo[hi]
+ except error.RepoError:
+ return _search(web, tmpl, hi) # XXX redirect to 404 page?
+
+ def changelist(limit=0, **map):
+ l = [] # build a list in forward order for efficiency
+ for i in xrange(start, end):
+ ctx = web.repo[i]
+ n = ctx.node()
+ showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
+ files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
+
+ l.insert(0, {"parity": parity.next(),
+ "author": ctx.user(),
+ "parent": webutil.parents(ctx, i - 1),
+ "child": webutil.children(ctx, i + 1),
+ "changelogtag": showtags,
+ "desc": ctx.description(),
+ "date": ctx.date(),
+ "files": files,
+ "rev": i,
+ "node": hex(n),
+ "tags": webutil.nodetagsdict(web.repo, n),
+ "inbranch": webutil.nodeinbranch(web.repo, ctx),
+ "branches": webutil.nodebranchdict(web.repo, ctx)
+ })
+
+ if limit > 0:
+ l = l[:limit]
+
+ for e in l:
+ yield e
+
+ maxchanges = shortlog and web.maxshortchanges or web.maxchanges
+ cl = web.repo.changelog
+ count = len(cl)
+ pos = ctx.rev()
+ start = max(0, pos - maxchanges + 1)
+ end = min(count, start + maxchanges)
+ pos = end - 1
+ parity = paritygen(web.stripecount, offset=start-end)
+
+ changenav = webutil.revnavgen(pos, maxchanges, count, web.repo.changectx)
+
+ return tmpl(shortlog and 'shortlog' or 'changelog',
+ changenav=changenav,
+ node=hex(ctx.node()),
+ rev=pos, changesets=count,
+ entries=lambda **x: changelist(limit=0,**x),
+ latestentry=lambda **x: changelist(limit=1,**x),
+ archives=web.archivelist("tip"))
+
+def shortlog(web, req, tmpl):
+ return changelog(web, req, tmpl, shortlog = True)
+
+def changeset(web, req, tmpl):
+ ctx = webutil.changectx(web.repo, req)
+ showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
+ showbranch = webutil.nodebranchnodefault(ctx)
+
+ files = []
+ parity = paritygen(web.stripecount)
+ for f in ctx.files():
+ template = f in ctx and 'filenodelink' or 'filenolink'
+ files.append(tmpl(template,
+ node=ctx.hex(), file=f,
+ parity=parity.next()))
+
+ parity = paritygen(web.stripecount)
+ diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity)
+ return tmpl('changeset',
+ diff=diffs,
+ rev=ctx.rev(),
+ node=ctx.hex(),
+ parent=webutil.parents(ctx),
+ child=webutil.children(ctx),
+ changesettag=showtags,
+ changesetbranch=showbranch,
+ author=ctx.user(),
+ desc=ctx.description(),
+ date=ctx.date(),
+ files=files,
+ archives=web.archivelist(ctx.hex()),
+ tags=webutil.nodetagsdict(web.repo, ctx.node()),
+ branch=webutil.nodebranchnodefault(ctx),
+ inbranch=webutil.nodeinbranch(web.repo, ctx),
+ branches=webutil.nodebranchdict(web.repo, ctx))
+
+rev = changeset
+
+def manifest(web, req, tmpl):
+ ctx = webutil.changectx(web.repo, req)
+ path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
+ mf = ctx.manifest()
+ node = ctx.node()
+
+ files = {}
+ dirs = {}
+ parity = paritygen(web.stripecount)
+
+ if path and path[-1] != "/":
+ path += "/"
+ l = len(path)
+ abspath = "/" + path
+
+ for f, n in mf.iteritems():
+ if f[:l] != path:
+ continue
+ remain = f[l:]
+ elements = remain.split('/')
+ if len(elements) == 1:
+ files[remain] = f
+ else:
+ h = dirs # need to retain ref to dirs (root)
+ for elem in elements[0:-1]:
+ if elem not in h:
+ h[elem] = {}
+ h = h[elem]
+ if len(h) > 1:
+ break
+ h[None] = None # denotes files present
+
+ if mf and not files and not dirs:
+ raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
+
+ def filelist(**map):
+ for f in sorted(files):
+ full = files[f]
+
+ fctx = ctx.filectx(full)
+ yield {"file": full,
+ "parity": parity.next(),
+ "basename": f,
+ "date": fctx.date(),
+ "size": fctx.size(),
+ "permissions": mf.flags(full)}
+
+ def dirlist(**map):
+ for d in sorted(dirs):
+
+ emptydirs = []
+ h = dirs[d]
+ while isinstance(h, dict) and len(h) == 1:
+ k,v = h.items()[0]
+ if v:
+ emptydirs.append(k)
+ h = v
+
+ path = "%s%s" % (abspath, d)
+ yield {"parity": parity.next(),
+ "path": path,
+ "emptydirs": "/".join(emptydirs),
+ "basename": d}
+
+ return tmpl("manifest",
+ rev=ctx.rev(),
+ node=hex(node),
+ path=abspath,
+ up=webutil.up(abspath),
+ upparity=parity.next(),
+ fentries=filelist,
+ dentries=dirlist,
+ archives=web.archivelist(hex(node)),
+ tags=webutil.nodetagsdict(web.repo, node),
+ inbranch=webutil.nodeinbranch(web.repo, ctx),
+ branches=webutil.nodebranchdict(web.repo, ctx))
+
+def tags(web, req, tmpl):
+ i = web.repo.tagslist()
+ i.reverse()
+ parity = paritygen(web.stripecount)
+
+ def entries(notip=False, limit=0, **map):
+ count = 0
+ for k, n in i:
+ if notip and k == "tip":
+ continue
+ if limit > 0 and count >= limit:
+ continue
+ count = count + 1
+ yield {"parity": parity.next(),
+ "tag": k,
+ "date": web.repo[n].date(),
+ "node": hex(n)}
+
+ return tmpl("tags",
+ node=hex(web.repo.changelog.tip()),
+ entries=lambda **x: entries(False,0, **x),
+ entriesnotip=lambda **x: entries(True,0, **x),
+ latestentry=lambda **x: entries(True,1, **x))
+
+def branches(web, req, tmpl):
+ b = web.repo.branchtags()
+ tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems())
+ heads = web.repo.heads()
+ parity = paritygen(web.stripecount)
+ sortkey = lambda ctx: ('close' not in ctx.extra(), ctx.rev())
+
+ def entries(limit, **map):
+ count = 0
+ for ctx in sorted(tips, key=sortkey, reverse=True):
+ if limit > 0 and count >= limit:
+ return
+ count += 1
+ if ctx.node() not in heads:
+ status = 'inactive'
+ elif not web.repo.branchheads(ctx.branch()):
+ status = 'closed'
+ else:
+ status = 'open'
+ yield {'parity': parity.next(),
+ 'branch': ctx.branch(),
+ 'status': status,
+ 'node': ctx.hex(),
+ 'date': ctx.date()}
+
+ return tmpl('branches', node=hex(web.repo.changelog.tip()),
+ entries=lambda **x: entries(0, **x),
+ latestentry=lambda **x: entries(1, **x))
+
+def summary(web, req, tmpl):
+ i = web.repo.tagslist()
+ i.reverse()
+
+ def tagentries(**map):
+ parity = paritygen(web.stripecount)
+ count = 0
+ for k, n in i:
+ if k == "tip": # skip tip
+ continue
+
+ count += 1
+ if count > 10: # limit to 10 tags
+ break
+
+ yield tmpl("tagentry",
+ parity=parity.next(),
+ tag=k,
+ node=hex(n),
+ date=web.repo[n].date())
+
+ def branches(**map):
+ parity = paritygen(web.stripecount)
+
+ b = web.repo.branchtags()
+ l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
+ for r,n,t in sorted(l):
+ yield {'parity': parity.next(),
+ 'branch': t,
+ 'node': hex(n),
+ 'date': web.repo[n].date()}
+
+ def changelist(**map):
+ parity = paritygen(web.stripecount, offset=start-end)
+ l = [] # build a list in forward order for efficiency
+ for i in xrange(start, end):
+ ctx = web.repo[i]
+ n = ctx.node()
+ hn = hex(n)
+
+ l.insert(0, tmpl(
+ 'shortlogentry',
+ parity=parity.next(),
+ author=ctx.user(),
+ desc=ctx.description(),
+ date=ctx.date(),
+ rev=i,
+ node=hn,
+ tags=webutil.nodetagsdict(web.repo, n),
+ inbranch=webutil.nodeinbranch(web.repo, ctx),
+ branches=webutil.nodebranchdict(web.repo, ctx)))
+
+ yield l
+
+ cl = web.repo.changelog
+ count = len(cl)
+ start = max(0, count - web.maxchanges)
+ end = min(count, start + web.maxchanges)
+
+ return tmpl("summary",
+ desc=web.config("web", "description", "unknown"),
+ owner=get_contact(web.config) or "unknown",
+ lastchange=cl.read(cl.tip())[2],
+ tags=tagentries,
+ branches=branches,
+ shortlog=changelist,
+ node=hex(cl.tip()),
+ archives=web.archivelist("tip"))
+
+def filediff(web, req, tmpl):
+ fctx, ctx = None, None
+ try:
+ fctx = webutil.filectx(web.repo, req)
+ except LookupError:
+ ctx = webutil.changectx(web.repo, req)
+ path = webutil.cleanpath(web.repo, req.form['file'][0])
+ if path not in ctx.files():
+ raise
+
+ if fctx is not None:
+ n = fctx.node()
+ path = fctx.path()
+ else:
+ n = ctx.node()
+ # path already defined in except clause
+
+ parity = paritygen(web.stripecount)
+ diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity)
+ rename = fctx and webutil.renamelink(fctx) or []
+ ctx = fctx and fctx or ctx
+ return tmpl("filediff",
+ file=path,
+ node=hex(n),
+ rev=ctx.rev(),
+ date=ctx.date(),
+ desc=ctx.description(),
+ author=ctx.user(),
+ rename=rename,
+ branch=webutil.nodebranchnodefault(ctx),
+ parent=webutil.parents(ctx),
+ child=webutil.children(ctx),
+ diff=diffs)
+
+diff = filediff
+
+def annotate(web, req, tmpl):
+ fctx = webutil.filectx(web.repo, req)
+ f = fctx.path()
+ parity = paritygen(web.stripecount)
+
+ def annotate(**map):
+ last = None
+ if binary(fctx.data()):
+ mt = (mimetypes.guess_type(fctx.path())[0]
+ or 'application/octet-stream')
+ lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
+ '(binary:%s)' % mt)])
+ else:
+ lines = enumerate(fctx.annotate(follow=True, linenumber=True))
+ for lineno, ((f, targetline), l) in lines:
+ fnode = f.filenode()
+
+ if last != fnode:
+ last = fnode
+
+ yield {"parity": parity.next(),
+ "node": hex(f.node()),
+ "rev": f.rev(),
+ "author": f.user(),
+ "desc": f.description(),
+ "file": f.path(),
+ "targetline": targetline,
+ "line": l,
+ "lineid": "l%d" % (lineno + 1),
+ "linenumber": "% 6d" % (lineno + 1)}
+
+ return tmpl("fileannotate",
+ file=f,
+ annotate=annotate,
+ path=webutil.up(f),
+ rev=fctx.rev(),
+ node=hex(fctx.node()),
+ author=fctx.user(),
+ date=fctx.date(),
+ desc=fctx.description(),
+ rename=webutil.renamelink(fctx),
+ branch=webutil.nodebranchnodefault(fctx),
+ parent=webutil.parents(fctx),
+ child=webutil.children(fctx),
+ permissions=fctx.manifest().flags(f))
+
+def filelog(web, req, tmpl):
+
+ try:
+ fctx = webutil.filectx(web.repo, req)
+ f = fctx.path()
+ fl = fctx.filelog()
+ except error.LookupError:
+ f = webutil.cleanpath(web.repo, req.form['file'][0])
+ fl = web.repo.file(f)
+ numrevs = len(fl)
+ if not numrevs: # file doesn't exist at all
+ raise
+ rev = webutil.changectx(web.repo, req).rev()
+ first = fl.linkrev(0)
+ if rev < first: # current rev is from before file existed
+ raise
+ frev = numrevs - 1
+ while fl.linkrev(frev) > rev:
+ frev -= 1
+ fctx = web.repo.filectx(f, fl.linkrev(frev))
+
+ count = fctx.filerev() + 1
+ pagelen = web.maxshortchanges
+ start = max(0, fctx.filerev() - pagelen + 1) # first rev on this page
+ end = min(count, start + pagelen) # last rev on this page
+ parity = paritygen(web.stripecount, offset=start-end)
+
+ def entries(limit=0, **map):
+ l = []
+
+ repo = web.repo
+ for i in xrange(start, end):
+ iterfctx = fctx.filectx(i)
+
+ l.insert(0, {"parity": parity.next(),
+ "filerev": i,
+ "file": f,
+ "node": hex(iterfctx.node()),
+ "author": iterfctx.user(),
+ "date": iterfctx.date(),
+ "rename": webutil.renamelink(iterfctx),
+ "parent": webutil.parents(iterfctx),
+ "child": webutil.children(iterfctx),
+ "desc": iterfctx.description(),
+ "tags": webutil.nodetagsdict(repo, iterfctx.node()),
+ "branch": webutil.nodebranchnodefault(iterfctx),
+ "inbranch": webutil.nodeinbranch(repo, iterfctx),
+ "branches": webutil.nodebranchdict(repo, iterfctx)})
+
+ if limit > 0:
+ l = l[:limit]
+
+ for e in l:
+ yield e
+
+ nodefunc = lambda x: fctx.filectx(fileid=x)
+ nav = webutil.revnavgen(end - 1, pagelen, count, nodefunc)
+ return tmpl("filelog", file=f, node=hex(fctx.node()), nav=nav,
+ entries=lambda **x: entries(limit=0, **x),
+ latestentry=lambda **x: entries(limit=1, **x))
+
+
+def archive(web, req, tmpl):
+ type_ = req.form.get('type', [None])[0]
+ allowed = web.configlist("web", "allow_archive")
+ key = req.form['node'][0]
+
+ if type_ not in web.archives:
+ msg = 'Unsupported archive type: %s' % type_
+ raise ErrorResponse(HTTP_NOT_FOUND, msg)
+
+ if not ((type_ in allowed or
+ web.configbool("web", "allow" + type_, False))):
+ msg = 'Archive type not allowed: %s' % type_
+ raise ErrorResponse(HTTP_FORBIDDEN, msg)
+
+ reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
+ cnode = web.repo.lookup(key)
+ arch_version = key
+ if cnode == key or key == 'tip':
+ arch_version = short(cnode)
+ name = "%s-%s" % (reponame, arch_version)
+ mimetype, artype, extension, encoding = web.archive_specs[type_]
+ headers = [
+ ('Content-Type', mimetype),
+ ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
+ ]
+ if encoding:
+ headers.append(('Content-Encoding', encoding))
+ req.header(headers)
+ req.respond(HTTP_OK)
+ archival.archive(web.repo, req, cnode, artype, prefix=name)
+ return []
+
+
+def static(web, req, tmpl):
+ fname = req.form['file'][0]
+ # a repo owner may set web.static in .hg/hgrc to get any file
+ # readable by the user running the CGI script
+ static = web.config("web", "static", None, untrusted=False)
+ if not static:
+ tp = web.templatepath or templater.templatepath()
+ if isinstance(tp, str):
+ tp = [tp]
+ static = [os.path.join(p, 'static') for p in tp]
+ return [staticfile(static, fname, req)]
+
+def graph(web, req, tmpl):
+ rev = webutil.changectx(web.repo, req).rev()
+ bg_height = 39
+
+ revcount = 25
+ if 'revcount' in req.form:
+ revcount = int(req.form.get('revcount', [revcount])[0])
+ tmpl.defaults['sessionvars']['revcount'] = revcount
+
+ lessvars = copy.copy(tmpl.defaults['sessionvars'])
+ lessvars['revcount'] = revcount / 2
+ morevars = copy.copy(tmpl.defaults['sessionvars'])
+ morevars['revcount'] = revcount * 2
+
+ max_rev = len(web.repo) - 1
+ revcount = min(max_rev, revcount)
+ revnode = web.repo.changelog.node(rev)
+ revnode_hex = hex(revnode)
+ uprev = min(max_rev, rev + revcount)
+ downrev = max(0, rev - revcount)
+ count = len(web.repo)
+ changenav = webutil.revnavgen(rev, revcount, count, web.repo.changectx)
+
+ dag = graphmod.revisions(web.repo, rev, downrev)
+ tree = list(graphmod.colored(dag))
+ canvasheight = (len(tree) + 1) * bg_height - 27;
+ data = []
+ for (id, type, ctx, vtx, edges) in tree:
+ if type != graphmod.CHANGESET:
+ continue
+ node = short(ctx.node())
+ age = templatefilters.age(ctx.date())
+ desc = templatefilters.firstline(ctx.description())
+ desc = cgi.escape(templatefilters.nonempty(desc))
+ user = cgi.escape(templatefilters.person(ctx.user()))
+ branch = ctx.branch()
+ branch = branch, web.repo.branchtags().get(branch) == ctx.node()
+ data.append((node, vtx, edges, desc, user, age, branch, ctx.tags()))
+
+ return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
+ lessvars=lessvars, morevars=morevars, downrev=downrev,
+ canvasheight=canvasheight, jsdata=data, bg_height=bg_height,
+ node=revnode_hex, changenav=changenav)
diff --git a/sys/src/cmd/hg/mercurial/hgweb/webutil.py b/sys/src/cmd/hg/mercurial/hgweb/webutil.py
new file mode 100644
index 000000000..bd29528f8
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/webutil.py
@@ -0,0 +1,218 @@
+# hgweb/webutil.py - utility library for the web interface.
+#
+# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os, copy
+from mercurial import match, patch, util, error
+from mercurial.node import hex, nullid
+
+def up(p):
+ if p[0] != "/":
+ p = "/" + p
+ if p[-1] == "/":
+ p = p[:-1]
+ up = os.path.dirname(p)
+ if up == "/":
+ return "/"
+ return up + "/"
+
+def revnavgen(pos, pagelen, limit, nodefunc):
+ def seq(factor, limit=None):
+ if limit:
+ yield limit
+ if limit >= 20 and limit <= 40:
+ yield 50
+ else:
+ yield 1 * factor
+ yield 3 * factor
+ for f in seq(factor * 10):
+ yield f
+
+ def nav(**map):
+ l = []
+ last = 0
+ for f in seq(1, pagelen):
+ if f < pagelen or f <= last:
+ continue
+ if f > limit:
+ break
+ last = f
+ if pos + f < limit:
+ l.append(("+%d" % f, hex(nodefunc(pos + f).node())))
+ if pos - f >= 0:
+ l.insert(0, ("-%d" % f, hex(nodefunc(pos - f).node())))
+
+ try:
+ yield {"label": "(0)", "node": hex(nodefunc('0').node())}
+
+ for label, node in l:
+ yield {"label": label, "node": node}
+
+ yield {"label": "tip", "node": "tip"}
+ except error.RepoError:
+ pass
+
+ return nav
+
+def _siblings(siblings=[], hiderev=None):
+ siblings = [s for s in siblings if s.node() != nullid]
+ if len(siblings) == 1 and siblings[0].rev() == hiderev:
+ return
+ for s in siblings:
+ d = {'node': hex(s.node()), 'rev': s.rev()}
+ d['user'] = s.user()
+ d['date'] = s.date()
+ d['description'] = s.description()
+ d['branch'] = s.branch()
+ if hasattr(s, 'path'):
+ d['file'] = s.path()
+ yield d
+
+def parents(ctx, hide=None):
+ return _siblings(ctx.parents(), hide)
+
+def children(ctx, hide=None):
+ return _siblings(ctx.children(), hide)
+
+def renamelink(fctx):
+ r = fctx.renamed()
+ if r:
+ return [dict(file=r[0], node=hex(r[1]))]
+ return []
+
+def nodetagsdict(repo, node):
+ return [{"name": i} for i in repo.nodetags(node)]
+
+def nodebranchdict(repo, ctx):
+ branches = []
+ branch = ctx.branch()
+ # If this is an empty repo, ctx.node() == nullid,
+ # ctx.branch() == 'default', but branchtags() is
+ # an empty dict. Using dict.get avoids a traceback.
+ if repo.branchtags().get(branch) == ctx.node():
+ branches.append({"name": branch})
+ return branches
+
+def nodeinbranch(repo, ctx):
+ branches = []
+ branch = ctx.branch()
+ if branch != 'default' and repo.branchtags().get(branch) != ctx.node():
+ branches.append({"name": branch})
+ return branches
+
+def nodebranchnodefault(ctx):
+ branches = []
+ branch = ctx.branch()
+ if branch != 'default':
+ branches.append({"name": branch})
+ return branches
+
+def showtag(repo, tmpl, t1, node=nullid, **args):
+ for t in repo.nodetags(node):
+ yield tmpl(t1, tag=t, **args)
+
+def cleanpath(repo, path):
+ path = path.lstrip('/')
+ return util.canonpath(repo.root, '', path)
+
+def changectx(repo, req):
+ changeid = "tip"
+ if 'node' in req.form:
+ changeid = req.form['node'][0]
+ elif 'manifest' in req.form:
+ changeid = req.form['manifest'][0]
+
+ try:
+ ctx = repo[changeid]
+ except error.RepoError:
+ man = repo.manifest
+ ctx = repo[man.linkrev(man.rev(man.lookup(changeid)))]
+
+ return ctx
+
+def filectx(repo, req):
+ path = cleanpath(repo, req.form['file'][0])
+ if 'node' in req.form:
+ changeid = req.form['node'][0]
+ else:
+ changeid = req.form['filenode'][0]
+ try:
+ fctx = repo[changeid][path]
+ except error.RepoError:
+ fctx = repo.filectx(path, fileid=changeid)
+
+ return fctx
+
+def listfilediffs(tmpl, files, node, max):
+ for f in files[:max]:
+ yield tmpl('filedifflink', node=hex(node), file=f)
+ if len(files) > max:
+ yield tmpl('fileellipses')
+
+def diffs(repo, tmpl, ctx, files, parity):
+
+ def countgen():
+ start = 1
+ while True:
+ yield start
+ start += 1
+
+ blockcount = countgen()
+ def prettyprintlines(diff):
+ blockno = blockcount.next()
+ for lineno, l in enumerate(diff.splitlines(True)):
+ lineno = "%d.%d" % (blockno, lineno + 1)
+ if l.startswith('+'):
+ ltype = "difflineplus"
+ elif l.startswith('-'):
+ ltype = "difflineminus"
+ elif l.startswith('@'):
+ ltype = "difflineat"
+ else:
+ ltype = "diffline"
+ yield tmpl(ltype,
+ line=l,
+ lineid="l%s" % lineno,
+ linenumber="% 8s" % lineno)
+
+ if files:
+ m = match.exact(repo.root, repo.getcwd(), files)
+ else:
+ m = match.always(repo.root, repo.getcwd())
+
+ diffopts = patch.diffopts(repo.ui, untrusted=True)
+ parents = ctx.parents()
+ node1 = parents and parents[0].node() or nullid
+ node2 = ctx.node()
+
+ block = []
+ for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
+ if chunk.startswith('diff') and block:
+ yield tmpl('diffblock', parity=parity.next(),
+ lines=prettyprintlines(''.join(block)))
+ block = []
+ if chunk.startswith('diff'):
+ chunk = ''.join(chunk.splitlines(True)[1:])
+ block.append(chunk)
+ yield tmpl('diffblock', parity=parity.next(),
+ lines=prettyprintlines(''.join(block)))
+
+class sessionvars(object):
+ def __init__(self, vars, start='?'):
+ self.start = start
+ self.vars = vars
+ def __getitem__(self, key):
+ return self.vars[key]
+ def __setitem__(self, key, value):
+ self.vars[key] = value
+ def __copy__(self):
+ return sessionvars(copy.copy(self.vars), self.start)
+ def __iter__(self):
+ separator = self.start
+ for key, value in self.vars.iteritems():
+ yield {'name': key, 'value': str(value), 'separator': separator}
+ separator = '&'
diff --git a/sys/src/cmd/hg/mercurial/hgweb/wsgicgi.py b/sys/src/cmd/hg/mercurial/hgweb/wsgicgi.py
new file mode 100644
index 000000000..9dfb76978
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hgweb/wsgicgi.py
@@ -0,0 +1,70 @@
+# hgweb/wsgicgi.py - CGI->WSGI translator
+#
+# Copyright 2006 Eric Hopper <hopper@omnifarious.org>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+#
+# This was originally copied from the public domain code at
+# http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
+
+import os, sys
+from mercurial import util
+
+def launch(application):
+ util.set_binary(sys.stdin)
+ util.set_binary(sys.stdout)
+
+ environ = dict(os.environ.iteritems())
+ environ.setdefault('PATH_INFO', '')
+ if '.cgi' in environ['PATH_INFO']:
+ environ['PATH_INFO'] = environ['PATH_INFO'].split('.cgi', 1)[1]
+
+ environ['wsgi.input'] = sys.stdin
+ environ['wsgi.errors'] = sys.stderr
+ environ['wsgi.version'] = (1, 0)
+ environ['wsgi.multithread'] = False
+ environ['wsgi.multiprocess'] = True
+ environ['wsgi.run_once'] = True
+
+ if environ.get('HTTPS','off').lower() in ('on','1','yes'):
+ environ['wsgi.url_scheme'] = 'https'
+ else:
+ environ['wsgi.url_scheme'] = 'http'
+
+ headers_set = []
+ headers_sent = []
+ out = sys.stdout
+
+ def write(data):
+ if not headers_set:
+ raise AssertionError("write() before start_response()")
+
+ elif not headers_sent:
+ # Before the first output, send the stored headers
+ status, response_headers = headers_sent[:] = headers_set
+ out.write('Status: %s\r\n' % status)
+ for header in response_headers:
+ out.write('%s: %s\r\n' % header)
+ out.write('\r\n')
+
+ out.write(data)
+ out.flush()
+
+ def start_response(status, response_headers, exc_info=None):
+ if exc_info:
+ try:
+ if headers_sent:
+ # Re-raise original exception if headers sent
+ raise exc_info[0](exc_info[1], exc_info[2])
+ finally:
+ exc_info = None # avoid dangling circular ref
+ elif headers_set:
+ raise AssertionError("Headers already set!")
+
+ headers_set[:] = [status, response_headers]
+ return write
+
+ content = application(environ, start_response)
+ for chunk in content:
+ write(chunk)
diff --git a/sys/src/cmd/hg/mercurial/hook.py b/sys/src/cmd/hg/mercurial/hook.py
new file mode 100644
index 000000000..c5b536df9
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/hook.py
@@ -0,0 +1,135 @@
+# hook.py - hook support for mercurial
+#
+# Copyright 2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import os, sys
+import extensions, util
+
+def _pythonhook(ui, repo, name, hname, funcname, args, throw):
+ '''call python hook. hook is callable object, looked up as
+ name in python module. if callable returns "true", hook
+ fails, else passes. if hook raises exception, treated as
+ hook failure. exception propagates if throw is "true".
+
+ reason for "true" meaning "hook failed" is so that
+ unmodified commands (e.g. mercurial.commands.update) can
+ be run as hooks without wrappers to convert return values.'''
+
+ ui.note(_("calling hook %s: %s\n") % (hname, funcname))
+ obj = funcname
+ if not hasattr(obj, '__call__'):
+ d = funcname.rfind('.')
+ if d == -1:
+ raise util.Abort(_('%s hook is invalid ("%s" not in '
+ 'a module)') % (hname, funcname))
+ modname = funcname[:d]
+ oldpaths = sys.path[:]
+ if hasattr(sys, "frozen"):
+ # binary installs require sys.path manipulation
+ path, name = os.path.split(modname)
+ if path and name:
+ sys.path.append(path)
+ modname = name
+ try:
+ obj = __import__(modname)
+ except ImportError:
+ try:
+ # extensions are loaded with hgext_ prefix
+ obj = __import__("hgext_%s" % modname)
+ except ImportError:
+ raise util.Abort(_('%s hook is invalid '
+ '(import of "%s" failed)') %
+ (hname, modname))
+ sys.path = oldpaths
+ try:
+ for p in funcname.split('.')[1:]:
+ obj = getattr(obj, p)
+ except AttributeError:
+ raise util.Abort(_('%s hook is invalid '
+ '("%s" is not defined)') %
+ (hname, funcname))
+ if not hasattr(obj, '__call__'):
+ raise util.Abort(_('%s hook is invalid '
+ '("%s" is not callable)') %
+ (hname, funcname))
+ try:
+ r = obj(ui=ui, repo=repo, hooktype=name, **args)
+ except KeyboardInterrupt:
+ raise
+ except Exception, exc:
+ if isinstance(exc, util.Abort):
+ ui.warn(_('error: %s hook failed: %s\n') %
+ (hname, exc.args[0]))
+ else:
+ ui.warn(_('error: %s hook raised an exception: '
+ '%s\n') % (hname, exc))
+ if throw:
+ raise
+ ui.traceback()
+ return True
+ if r:
+ if throw:
+ raise util.Abort(_('%s hook failed') % hname)
+ ui.warn(_('warning: %s hook failed\n') % hname)
+ return r
+
+def _exthook(ui, repo, name, cmd, args, throw):
+ ui.note(_("running hook %s: %s\n") % (name, cmd))
+
+ env = {}
+ for k, v in args.iteritems():
+ if hasattr(v, '__call__'):
+ v = v()
+ env['HG_' + k.upper()] = v
+
+ if repo:
+ cwd = repo.root
+ else:
+ cwd = os.getcwd()
+ r = util.system(cmd, environ=env, cwd=cwd)
+ if r:
+ desc, r = util.explain_exit(r)
+ if throw:
+ raise util.Abort(_('%s hook %s') % (name, desc))
+ ui.warn(_('warning: %s hook %s\n') % (name, desc))
+ return r
+
+_redirect = False
+def redirect(state):
+ global _redirect
+ _redirect = state
+
+def hook(ui, repo, name, throw=False, **args):
+ r = False
+
+ if _redirect:
+ # temporarily redirect stdout to stderr
+ oldstdout = os.dup(sys.__stdout__.fileno())
+ os.dup2(sys.__stderr__.fileno(), sys.__stdout__.fileno())
+
+ try:
+ for hname, cmd in ui.configitems('hooks'):
+ if hname.split('.')[0] != name or not cmd:
+ continue
+ if hasattr(cmd, '__call__'):
+ r = _pythonhook(ui, repo, name, hname, cmd, args, throw) or r
+ elif cmd.startswith('python:'):
+ if cmd.count(':') >= 2:
+ path, cmd = cmd[7:].rsplit(':', 1)
+ mod = extensions.loadpath(path, 'hghook.%s' % hname)
+ hookfn = getattr(mod, cmd)
+ else:
+ hookfn = cmd[7:].strip()
+ r = _pythonhook(ui, repo, name, hname, hookfn, args, throw) or r
+ else:
+ r = _exthook(ui, repo, hname, cmd, args, throw) or r
+ finally:
+ if _redirect:
+ os.dup2(oldstdout, sys.__stdout__.fileno())
+ os.close(oldstdout)
+
+ return r
diff --git a/sys/src/cmd/hg/mercurial/httprepo.py b/sys/src/cmd/hg/mercurial/httprepo.py
new file mode 100644
index 000000000..a766bf07a
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/httprepo.py
@@ -0,0 +1,258 @@
+# httprepo.py - HTTP repository proxy classes for mercurial
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import bin, hex, nullid
+from i18n import _
+import repo, changegroup, statichttprepo, error, url, util
+import os, urllib, urllib2, urlparse, zlib, httplib
+import errno, socket
+
+def zgenerator(f):
+ zd = zlib.decompressobj()
+ try:
+ for chunk in util.filechunkiter(f):
+ yield zd.decompress(chunk)
+ except httplib.HTTPException:
+ raise IOError(None, _('connection ended unexpectedly'))
+ yield zd.flush()
+
+class httprepository(repo.repository):
+ def __init__(self, ui, path):
+ self.path = path
+ self.caps = None
+ self.handler = None
+ scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
+ if query or frag:
+ raise util.Abort(_('unsupported URL component: "%s"') %
+ (query or frag))
+
+ # urllib cannot handle URLs with embedded user or passwd
+ self._url, authinfo = url.getauthinfo(path)
+
+ self.ui = ui
+ self.ui.debug(_('using %s\n') % self._url)
+
+ self.urlopener = url.opener(ui, authinfo)
+
+ def __del__(self):
+ for h in self.urlopener.handlers:
+ h.close()
+ if hasattr(h, "close_all"):
+ h.close_all()
+
+ def url(self):
+ return self.path
+
+ # look up capabilities only when needed
+
+ def get_caps(self):
+ if self.caps is None:
+ try:
+ self.caps = set(self.do_read('capabilities').split())
+ except error.RepoError:
+ self.caps = set()
+ self.ui.debug(_('capabilities: %s\n') %
+ (' '.join(self.caps or ['none'])))
+ return self.caps
+
+ capabilities = property(get_caps)
+
+ def lock(self):
+ raise util.Abort(_('operation not supported over http'))
+
+ def do_cmd(self, cmd, **args):
+ data = args.pop('data', None)
+ headers = args.pop('headers', {})
+ self.ui.debug(_("sending %s command\n") % cmd)
+ q = {"cmd": cmd}
+ q.update(args)
+ qs = '?%s' % urllib.urlencode(q)
+ cu = "%s%s" % (self._url, qs)
+ try:
+ if data:
+ self.ui.debug(_("sending %s bytes\n") % len(data))
+ resp = self.urlopener.open(urllib2.Request(cu, data, headers))
+ except urllib2.HTTPError, inst:
+ if inst.code == 401:
+ raise util.Abort(_('authorization failed'))
+ raise
+ except httplib.HTTPException, inst:
+ self.ui.debug(_('http error while sending %s command\n') % cmd)
+ self.ui.traceback()
+ raise IOError(None, inst)
+ except IndexError:
+ # this only happens with Python 2.3, later versions raise URLError
+ raise util.Abort(_('http error, possibly caused by proxy setting'))
+ # record the url we got redirected to
+ resp_url = resp.geturl()
+ if resp_url.endswith(qs):
+ resp_url = resp_url[:-len(qs)]
+ if self._url != resp_url:
+ self.ui.status(_('real URL is %s\n') % resp_url)
+ self._url = resp_url
+ try:
+ proto = resp.getheader('content-type')
+ except AttributeError:
+ proto = resp.headers['content-type']
+
+ safeurl = url.hidepassword(self._url)
+ # accept old "text/plain" and "application/hg-changegroup" for now
+ if not (proto.startswith('application/mercurial-') or
+ proto.startswith('text/plain') or
+ proto.startswith('application/hg-changegroup')):
+ self.ui.debug(_("requested URL: '%s'\n") % url.hidepassword(cu))
+ raise error.RepoError(_("'%s' does not appear to be an hg repository")
+ % safeurl)
+
+ if proto.startswith('application/mercurial-'):
+ try:
+ version = proto.split('-', 1)[1]
+ version_info = tuple([int(n) for n in version.split('.')])
+ except ValueError:
+ raise error.RepoError(_("'%s' sent a broken Content-Type "
+ "header (%s)") % (safeurl, proto))
+ if version_info > (0, 1):
+ raise error.RepoError(_("'%s' uses newer protocol %s") %
+ (safeurl, version))
+
+ return resp
+
+ def do_read(self, cmd, **args):
+ fp = self.do_cmd(cmd, **args)
+ try:
+ return fp.read()
+ finally:
+ # if using keepalive, allow connection to be reused
+ fp.close()
+
+ def lookup(self, key):
+ self.requirecap('lookup', _('look up remote revision'))
+ d = self.do_cmd("lookup", key = key).read()
+ success, data = d[:-1].split(' ', 1)
+ if int(success):
+ return bin(data)
+ raise error.RepoError(data)
+
+ def heads(self):
+ d = self.do_read("heads")
+ try:
+ return map(bin, d[:-1].split(" "))
+ except:
+ raise error.ResponseError(_("unexpected response:"), d)
+
+ def branchmap(self):
+ d = self.do_read("branchmap")
+ try:
+ branchmap = {}
+ for branchpart in d.splitlines():
+ branchheads = branchpart.split(' ')
+ branchname = urllib.unquote(branchheads[0])
+ branchheads = [bin(x) for x in branchheads[1:]]
+ branchmap[branchname] = branchheads
+ return branchmap
+ except:
+ raise error.ResponseError(_("unexpected response:"), d)
+
+ def branches(self, nodes):
+ n = " ".join(map(hex, nodes))
+ d = self.do_read("branches", nodes=n)
+ try:
+ br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
+ return br
+ except:
+ raise error.ResponseError(_("unexpected response:"), d)
+
+ def between(self, pairs):
+ batch = 8 # avoid giant requests
+ r = []
+ for i in xrange(0, len(pairs), batch):
+ n = " ".join(["-".join(map(hex, p)) for p in pairs[i:i + batch]])
+ d = self.do_read("between", pairs=n)
+ try:
+ r += [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
+ except:
+ raise error.ResponseError(_("unexpected response:"), d)
+ return r
+
+ def changegroup(self, nodes, kind):
+ n = " ".join(map(hex, nodes))
+ f = self.do_cmd("changegroup", roots=n)
+ return util.chunkbuffer(zgenerator(f))
+
+ def changegroupsubset(self, bases, heads, source):
+ self.requirecap('changegroupsubset', _('look up remote changes'))
+ baselst = " ".join([hex(n) for n in bases])
+ headlst = " ".join([hex(n) for n in heads])
+ f = self.do_cmd("changegroupsubset", bases=baselst, heads=headlst)
+ return util.chunkbuffer(zgenerator(f))
+
+ def unbundle(self, cg, heads, source):
+ # have to stream bundle to a temp file because we do not have
+ # http 1.1 chunked transfer.
+
+ type = ""
+ types = self.capable('unbundle')
+ # servers older than d1b16a746db6 will send 'unbundle' as a
+ # boolean capability
+ try:
+ types = types.split(',')
+ except AttributeError:
+ types = [""]
+ if types:
+ for x in types:
+ if x in changegroup.bundletypes:
+ type = x
+ break
+
+ tempname = changegroup.writebundle(cg, None, type)
+ fp = url.httpsendfile(tempname, "rb")
+ try:
+ try:
+ resp = self.do_read(
+ 'unbundle', data=fp,
+ headers={'Content-Type': 'application/octet-stream'},
+ heads=' '.join(map(hex, heads)))
+ resp_code, output = resp.split('\n', 1)
+ try:
+ ret = int(resp_code)
+ except ValueError, err:
+ raise error.ResponseError(
+ _('push failed (unexpected response):'), resp)
+ self.ui.write(output)
+ return ret
+ except socket.error, err:
+ if err[0] in (errno.ECONNRESET, errno.EPIPE):
+ raise util.Abort(_('push failed: %s') % err[1])
+ raise util.Abort(err[1])
+ finally:
+ fp.close()
+ os.unlink(tempname)
+
+ def stream_out(self):
+ return self.do_cmd('stream_out')
+
+class httpsrepository(httprepository):
+ def __init__(self, ui, path):
+ if not url.has_https:
+ raise util.Abort(_('Python support for SSL and HTTPS '
+ 'is not installed'))
+ httprepository.__init__(self, ui, path)
+
+def instance(ui, path, create):
+ if create:
+ raise util.Abort(_('cannot create new http repository'))
+ try:
+ if path.startswith('https:'):
+ inst = httpsrepository(ui, path)
+ else:
+ inst = httprepository(ui, path)
+ inst.between([(nullid, nullid)])
+ return inst
+ except error.RepoError:
+ ui.note('(falling back to static-http)\n')
+ return statichttprepo.instance(ui, "static-" + path, create)
diff --git a/sys/src/cmd/hg/mercurial/i18n.py b/sys/src/cmd/hg/mercurial/i18n.py
new file mode 100644
index 000000000..c8ef2e9a5
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/i18n.py
@@ -0,0 +1,52 @@
+# i18n.py - internationalization support for mercurial
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import encoding
+import gettext, sys, os
+
+# modelled after templater.templatepath:
+if hasattr(sys, 'frozen'):
+ module = sys.executable
+else:
+ module = __file__
+
+base = os.path.dirname(module)
+for dir in ('.', '..'):
+ localedir = os.path.normpath(os.path.join(base, dir, 'locale'))
+ if os.path.isdir(localedir):
+ break
+
+t = gettext.translation('hg', localedir, fallback=True)
+
+def gettext(message):
+ """Translate message.
+
+ The message is looked up in the catalog to get a Unicode string,
+ which is encoded in the local encoding before being returned.
+
+ Important: message is restricted to characters in the encoding
+ given by sys.getdefaultencoding() which is most likely 'ascii'.
+ """
+ # If message is None, t.ugettext will return u'None' as the
+ # translation whereas our callers expect us to return None.
+ if message is None:
+ return message
+
+ u = t.ugettext(message)
+ try:
+ # encoding.tolocal cannot be used since it will first try to
+ # decode the Unicode string. Calling u.decode(enc) really
+ # means u.encode(sys.getdefaultencoding()).decode(enc). Since
+ # the Python encoding defaults to 'ascii', this fails if the
+ # translated string use non-ASCII characters.
+ return u.encode(encoding.encoding, "replace")
+ except LookupError:
+ # An unknown encoding results in a LookupError.
+ return message
+
+_ = gettext
+
diff --git a/sys/src/cmd/hg/mercurial/i18n.pyc b/sys/src/cmd/hg/mercurial/i18n.pyc
new file mode 100644
index 000000000..ade9f1bfe
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/i18n.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/ignore.py b/sys/src/cmd/hg/mercurial/ignore.py
new file mode 100644
index 000000000..72532ea5d
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/ignore.py
@@ -0,0 +1,103 @@
+# ignore.py - ignored file handling for mercurial
+#
+# Copyright 2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import util, match
+import re
+
+_commentre = None
+
+def ignorepats(lines):
+ '''parse lines (iterable) of .hgignore text, returning a tuple of
+ (patterns, parse errors). These patterns should be given to compile()
+ to be validated and converted into a match function.'''
+ syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'}
+ syntax = 'relre:'
+ patterns = []
+ warnings = []
+
+ for line in lines:
+ if "#" in line:
+ global _commentre
+ if not _commentre:
+ _commentre = re.compile(r'((^|[^\\])(\\\\)*)#.*')
+ # remove comments prefixed by an even number of escapes
+ line = _commentre.sub(r'\1', line)
+ # fixup properly escaped comments that survived the above
+ line = line.replace("\\#", "#")
+ line = line.rstrip()
+ if not line:
+ continue
+
+ if line.startswith('syntax:'):
+ s = line[7:].strip()
+ try:
+ syntax = syntaxes[s]
+ except KeyError:
+ warnings.append(_("ignoring invalid syntax '%s'") % s)
+ continue
+ pat = syntax + line
+ for s, rels in syntaxes.iteritems():
+ if line.startswith(rels):
+ pat = line
+ break
+ elif line.startswith(s+':'):
+ pat = rels + line[len(s)+1:]
+ break
+ patterns.append(pat)
+
+ return patterns, warnings
+
+def ignore(root, files, warn):
+ '''return matcher covering patterns in 'files'.
+
+ the files parsed for patterns include:
+ .hgignore in the repository root
+ any additional files specified in the [ui] section of ~/.hgrc
+
+ trailing white space is dropped.
+ the escape character is backslash.
+ comments start with #.
+ empty lines are skipped.
+
+ lines can be of the following formats:
+
+ syntax: regexp # defaults following lines to non-rooted regexps
+ syntax: glob # defaults following lines to non-rooted globs
+ re:pattern # non-rooted regular expression
+ glob:pattern # non-rooted glob
+ pattern # pattern of the current default type'''
+
+ pats = {}
+ for f in files:
+ try:
+ pats[f] = []
+ fp = open(f)
+ pats[f], warnings = ignorepats(fp)
+ for warning in warnings:
+ warn("%s: %s\n" % (f, warning))
+ except IOError, inst:
+ if f != files[0]:
+ warn(_("skipping unreadable ignore file '%s': %s\n") %
+ (f, inst.strerror))
+
+ allpats = []
+ [allpats.extend(patlist) for patlist in pats.values()]
+ if not allpats:
+ return util.never
+
+ try:
+ ignorefunc = match.match(root, '', [], allpats)
+ except util.Abort:
+ # Re-raise an exception where the src is the right file
+ for f, patlist in pats.iteritems():
+ try:
+ match.match(root, '', [], patlist)
+ except util.Abort, inst:
+ raise util.Abort('%s: %s' % (f, inst[0]))
+
+ return ignorefunc
diff --git a/sys/src/cmd/hg/mercurial/keepalive.py b/sys/src/cmd/hg/mercurial/keepalive.py
new file mode 100644
index 000000000..aa19ffbed
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/keepalive.py
@@ -0,0 +1,671 @@
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330,
+# Boston, MA 02111-1307 USA
+
+# This file is part of urlgrabber, a high-level cross-protocol url-grabber
+# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
+
+# Modified by Benoit Boissinot:
+# - fix for digest auth (inspired from urllib2.py @ Python v2.4)
+# Modified by Dirkjan Ochtman:
+# - import md5 function from a local util module
+# Modified by Martin Geisler:
+# - moved md5 function from local util module to this module
+
+"""An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive.
+
+>>> import urllib2
+>>> from keepalive import HTTPHandler
+>>> keepalive_handler = HTTPHandler()
+>>> opener = urllib2.build_opener(keepalive_handler)
+>>> urllib2.install_opener(opener)
+>>>
+>>> fo = urllib2.urlopen('http://www.python.org')
+
+If a connection to a given host is requested, and all of the existing
+connections are still in use, another connection will be opened. If
+the handler tries to use an existing connection but it fails in some
+way, it will be closed and removed from the pool.
+
+To remove the handler, simply re-run build_opener with no arguments, and
+install that opener.
+
+You can explicitly close connections by using the close_connection()
+method of the returned file-like object (described below) or you can
+use the handler methods:
+
+ close_connection(host)
+ close_all()
+ open_connections()
+
+NOTE: using the close_connection and close_all methods of the handler
+should be done with care when using multiple threads.
+ * there is nothing that prevents another thread from creating new
+ connections immediately after connections are closed
+ * no checks are done to prevent in-use connections from being closed
+
+>>> keepalive_handler.close_all()
+
+EXTRA ATTRIBUTES AND METHODS
+
+ Upon a status of 200, the object returned has a few additional
+ attributes and methods, which should not be used if you want to
+ remain consistent with the normal urllib2-returned objects:
+
+ close_connection() - close the connection to the host
+ readlines() - you know, readlines()
+ status - the return status (ie 404)
+ reason - english translation of status (ie 'File not found')
+
+ If you want the best of both worlds, use this inside an
+ AttributeError-catching try:
+
+ >>> try: status = fo.status
+ >>> except AttributeError: status = None
+
+ Unfortunately, these are ONLY there if status == 200, so it's not
+ easy to distinguish between non-200 responses. The reason is that
+ urllib2 tries to do clever things with error codes 301, 302, 401,
+ and 407, and it wraps the object upon return.
+
+ For python versions earlier than 2.4, you can avoid this fancy error
+ handling by setting the module-level global HANDLE_ERRORS to zero.
+ You see, prior to 2.4, it's the HTTP Handler's job to determine what
+ to handle specially, and what to just pass up. HANDLE_ERRORS == 0
+ means "pass everything up". In python 2.4, however, this job no
+ longer belongs to the HTTP Handler and is now done by a NEW handler,
+ HTTPErrorProcessor. Here's the bottom line:
+
+ python version < 2.4
+ HANDLE_ERRORS == 1 (default) pass up 200, treat the rest as
+ errors
+ HANDLE_ERRORS == 0 pass everything up, error processing is
+ left to the calling code
+ python version >= 2.4
+ HANDLE_ERRORS == 1 pass up 200, treat the rest as errors
+ HANDLE_ERRORS == 0 (default) pass everything up, let the
+ other handlers (specifically,
+ HTTPErrorProcessor) decide what to do
+
+ In practice, setting the variable either way makes little difference
+ in python 2.4, so for the most consistent behavior across versions,
+ you probably just want to use the defaults, which will give you
+ exceptions on errors.
+
+"""
+
+# $Id: keepalive.py,v 1.14 2006/04/04 21:00:32 mstenner Exp $
+
+import urllib2
+import httplib
+import socket
+import thread
+
+DEBUG = None
+
+import sys
+if sys.version_info < (2, 4): HANDLE_ERRORS = 1
+else: HANDLE_ERRORS = 0
+
+class ConnectionManager:
+ """
+ The connection manager must be able to:
+ * keep track of all existing
+ """
+ def __init__(self):
+ self._lock = thread.allocate_lock()
+ self._hostmap = {} # map hosts to a list of connections
+ self._connmap = {} # map connections to host
+ self._readymap = {} # map connection to ready state
+
+ def add(self, host, connection, ready):
+ self._lock.acquire()
+ try:
+ if not host in self._hostmap: self._hostmap[host] = []
+ self._hostmap[host].append(connection)
+ self._connmap[connection] = host
+ self._readymap[connection] = ready
+ finally:
+ self._lock.release()
+
+ def remove(self, connection):
+ self._lock.acquire()
+ try:
+ try:
+ host = self._connmap[connection]
+ except KeyError:
+ pass
+ else:
+ del self._connmap[connection]
+ del self._readymap[connection]
+ self._hostmap[host].remove(connection)
+ if not self._hostmap[host]: del self._hostmap[host]
+ finally:
+ self._lock.release()
+
+ def set_ready(self, connection, ready):
+ try: self._readymap[connection] = ready
+ except KeyError: pass
+
+ def get_ready_conn(self, host):
+ conn = None
+ self._lock.acquire()
+ try:
+ if host in self._hostmap:
+ for c in self._hostmap[host]:
+ if self._readymap[c]:
+ self._readymap[c] = 0
+ conn = c
+ break
+ finally:
+ self._lock.release()
+ return conn
+
+ def get_all(self, host=None):
+ if host:
+ return list(self._hostmap.get(host, []))
+ else:
+ return dict(self._hostmap)
+
+class KeepAliveHandler:
+ def __init__(self):
+ self._cm = ConnectionManager()
+
+ #### Connection Management
+ def open_connections(self):
+ """return a list of connected hosts and the number of connections
+ to each. [('foo.com:80', 2), ('bar.org', 1)]"""
+ return [(host, len(li)) for (host, li) in self._cm.get_all().items()]
+
+ def close_connection(self, host):
+ """close connection(s) to <host>
+ host is the host:port spec, as in 'www.cnn.com:8080' as passed in.
+ no error occurs if there is no connection to that host."""
+ for h in self._cm.get_all(host):
+ self._cm.remove(h)
+ h.close()
+
+ def close_all(self):
+ """close all open connections"""
+ for host, conns in self._cm.get_all().iteritems():
+ for h in conns:
+ self._cm.remove(h)
+ h.close()
+
+ def _request_closed(self, request, host, connection):
+ """tells us that this request is now closed and the the
+ connection is ready for another request"""
+ self._cm.set_ready(connection, 1)
+
+ def _remove_connection(self, host, connection, close=0):
+ if close: connection.close()
+ self._cm.remove(connection)
+
+ #### Transaction Execution
+ def http_open(self, req):
+ return self.do_open(HTTPConnection, req)
+
+ def do_open(self, http_class, req):
+ host = req.get_host()
+ if not host:
+ raise urllib2.URLError('no host given')
+
+ try:
+ h = self._cm.get_ready_conn(host)
+ while h:
+ r = self._reuse_connection(h, req, host)
+
+ # if this response is non-None, then it worked and we're
+ # done. Break out, skipping the else block.
+ if r: break
+
+ # connection is bad - possibly closed by server
+ # discard it and ask for the next free connection
+ h.close()
+ self._cm.remove(h)
+ h = self._cm.get_ready_conn(host)
+ else:
+ # no (working) free connections were found. Create a new one.
+ h = http_class(host)
+ if DEBUG: DEBUG.info("creating new connection to %s (%d)",
+ host, id(h))
+ self._cm.add(host, h, 0)
+ self._start_transaction(h, req)
+ r = h.getresponse()
+ except (socket.error, httplib.HTTPException), err:
+ raise urllib2.URLError(err)
+
+ # if not a persistent connection, don't try to reuse it
+ if r.will_close: self._cm.remove(h)
+
+ if DEBUG: DEBUG.info("STATUS: %s, %s", r.status, r.reason)
+ r._handler = self
+ r._host = host
+ r._url = req.get_full_url()
+ r._connection = h
+ r.code = r.status
+ r.headers = r.msg
+ r.msg = r.reason
+
+ if r.status == 200 or not HANDLE_ERRORS:
+ return r
+ else:
+ return self.parent.error('http', req, r,
+ r.status, r.msg, r.headers)
+
+ def _reuse_connection(self, h, req, host):
+ """start the transaction with a re-used connection
+ return a response object (r) upon success or None on failure.
+ This DOES not close or remove bad connections in cases where
+ it returns. However, if an unexpected exception occurs, it
+ will close and remove the connection before re-raising.
+ """
+ try:
+ self._start_transaction(h, req)
+ r = h.getresponse()
+ # note: just because we got something back doesn't mean it
+ # worked. We'll check the version below, too.
+ except (socket.error, httplib.HTTPException):
+ r = None
+ except:
+ # adding this block just in case we've missed
+ # something we will still raise the exception, but
+ # lets try and close the connection and remove it
+ # first. We previously got into a nasty loop
+ # where an exception was uncaught, and so the
+ # connection stayed open. On the next try, the
+ # same exception was raised, etc. The tradeoff is
+ # that it's now possible this call will raise
+ # a DIFFERENT exception
+ if DEBUG: DEBUG.error("unexpected exception - closing " + \
+ "connection to %s (%d)", host, id(h))
+ self._cm.remove(h)
+ h.close()
+ raise
+
+ if r is None or r.version == 9:
+ # httplib falls back to assuming HTTP 0.9 if it gets a
+ # bad header back. This is most likely to happen if
+ # the socket has been closed by the server since we
+ # last used the connection.
+ if DEBUG: DEBUG.info("failed to re-use connection to %s (%d)",
+ host, id(h))
+ r = None
+ else:
+ if DEBUG: DEBUG.info("re-using connection to %s (%d)", host, id(h))
+
+ return r
+
+ def _start_transaction(self, h, req):
+ # What follows mostly reimplements HTTPConnection.request()
+ # except it adds self.parent.addheaders in the mix.
+ headers = req.headers.copy()
+ if sys.version_info >= (2, 4):
+ headers.update(req.unredirected_hdrs)
+ headers.update(self.parent.addheaders)
+ headers = dict((n.lower(), v) for n,v in headers.items())
+ skipheaders = {}
+ for n in ('host', 'accept-encoding'):
+ if n in headers:
+ skipheaders['skip_' + n.replace('-', '_')] = 1
+ try:
+ if req.has_data():
+ data = req.get_data()
+ h.putrequest('POST', req.get_selector(), **skipheaders)
+ if 'content-type' not in headers:
+ h.putheader('Content-type',
+ 'application/x-www-form-urlencoded')
+ if 'content-length' not in headers:
+ h.putheader('Content-length', '%d' % len(data))
+ else:
+ h.putrequest('GET', req.get_selector(), **skipheaders)
+ except (socket.error), err:
+ raise urllib2.URLError(err)
+ for k, v in headers.items():
+ h.putheader(k, v)
+ h.endheaders()
+ if req.has_data():
+ h.send(data)
+
+class HTTPHandler(KeepAliveHandler, urllib2.HTTPHandler):
+ pass
+
+class HTTPResponse(httplib.HTTPResponse):
+ # we need to subclass HTTPResponse in order to
+ # 1) add readline() and readlines() methods
+ # 2) add close_connection() methods
+ # 3) add info() and geturl() methods
+
+ # in order to add readline(), read must be modified to deal with a
+ # buffer. example: readline must read a buffer and then spit back
+ # one line at a time. The only real alternative is to read one
+ # BYTE at a time (ick). Once something has been read, it can't be
+ # put back (ok, maybe it can, but that's even uglier than this),
+ # so if you THEN do a normal read, you must first take stuff from
+ # the buffer.
+
+ # the read method wraps the original to accomodate buffering,
+ # although read() never adds to the buffer.
+ # Both readline and readlines have been stolen with almost no
+ # modification from socket.py
+
+
+ def __init__(self, sock, debuglevel=0, strict=0, method=None):
+ if method: # the httplib in python 2.3 uses the method arg
+ httplib.HTTPResponse.__init__(self, sock, debuglevel, method)
+ else: # 2.2 doesn't
+ httplib.HTTPResponse.__init__(self, sock, debuglevel)
+ self.fileno = sock.fileno
+ self.code = None
+ self._rbuf = ''
+ self._rbufsize = 8096
+ self._handler = None # inserted by the handler later
+ self._host = None # (same)
+ self._url = None # (same)
+ self._connection = None # (same)
+
+ _raw_read = httplib.HTTPResponse.read
+
+ def close(self):
+ if self.fp:
+ self.fp.close()
+ self.fp = None
+ if self._handler:
+ self._handler._request_closed(self, self._host,
+ self._connection)
+
+ def close_connection(self):
+ self._handler._remove_connection(self._host, self._connection, close=1)
+ self.close()
+
+ def info(self):
+ return self.headers
+
+ def geturl(self):
+ return self._url
+
+ def read(self, amt=None):
+ # the _rbuf test is only in this first if for speed. It's not
+ # logically necessary
+ if self._rbuf and not amt is None:
+ L = len(self._rbuf)
+ if amt > L:
+ amt -= L
+ else:
+ s = self._rbuf[:amt]
+ self._rbuf = self._rbuf[amt:]
+ return s
+
+ s = self._rbuf + self._raw_read(amt)
+ self._rbuf = ''
+ return s
+
+ # stolen from Python SVN #68532 to fix issue1088
+ def _read_chunked(self, amt):
+ chunk_left = self.chunk_left
+ value = ''
+
+ # XXX This accumulates chunks by repeated string concatenation,
+ # which is not efficient as the number or size of chunks gets big.
+ while True:
+ if chunk_left is None:
+ line = self.fp.readline()
+ i = line.find(';')
+ if i >= 0:
+ line = line[:i] # strip chunk-extensions
+ try:
+ chunk_left = int(line, 16)
+ except ValueError:
+ # close the connection as protocol synchronisation is
+ # probably lost
+ self.close()
+ raise httplib.IncompleteRead(value)
+ if chunk_left == 0:
+ break
+ if amt is None:
+ value += self._safe_read(chunk_left)
+ elif amt < chunk_left:
+ value += self._safe_read(amt)
+ self.chunk_left = chunk_left - amt
+ return value
+ elif amt == chunk_left:
+ value += self._safe_read(amt)
+ self._safe_read(2) # toss the CRLF at the end of the chunk
+ self.chunk_left = None
+ return value
+ else:
+ value += self._safe_read(chunk_left)
+ amt -= chunk_left
+
+ # we read the whole chunk, get another
+ self._safe_read(2) # toss the CRLF at the end of the chunk
+ chunk_left = None
+
+ # read and discard trailer up to the CRLF terminator
+ ### note: we shouldn't have any trailers!
+ while True:
+ line = self.fp.readline()
+ if not line:
+ # a vanishingly small number of sites EOF without
+ # sending the trailer
+ break
+ if line == '\r\n':
+ break
+
+ # we read everything; close the "file"
+ self.close()
+
+ return value
+
+ def readline(self, limit=-1):
+ i = self._rbuf.find('\n')
+ while i < 0 and not (0 < limit <= len(self._rbuf)):
+ new = self._raw_read(self._rbufsize)
+ if not new: break
+ i = new.find('\n')
+ if i >= 0: i = i + len(self._rbuf)
+ self._rbuf = self._rbuf + new
+ if i < 0: i = len(self._rbuf)
+ else: i = i+1
+ if 0 <= limit < len(self._rbuf): i = limit
+ data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
+ return data
+
+ def readlines(self, sizehint = 0):
+ total = 0
+ list = []
+ while 1:
+ line = self.readline()
+ if not line: break
+ list.append(line)
+ total += len(line)
+ if sizehint and total >= sizehint:
+ break
+ return list
+
+
+class HTTPConnection(httplib.HTTPConnection):
+ # use the modified response class
+ response_class = HTTPResponse
+
+#########################################################################
+##### TEST FUNCTIONS
+#########################################################################
+
+def error_handler(url):
+ global HANDLE_ERRORS
+ orig = HANDLE_ERRORS
+ keepalive_handler = HTTPHandler()
+ opener = urllib2.build_opener(keepalive_handler)
+ urllib2.install_opener(opener)
+ pos = {0: 'off', 1: 'on'}
+ for i in (0, 1):
+ print " fancy error handling %s (HANDLE_ERRORS = %i)" % (pos[i], i)
+ HANDLE_ERRORS = i
+ try:
+ fo = urllib2.urlopen(url)
+ fo.read()
+ fo.close()
+ try: status, reason = fo.status, fo.reason
+ except AttributeError: status, reason = None, None
+ except IOError, e:
+ print " EXCEPTION: %s" % e
+ raise
+ else:
+ print " status = %s, reason = %s" % (status, reason)
+ HANDLE_ERRORS = orig
+ hosts = keepalive_handler.open_connections()
+ print "open connections:", hosts
+ keepalive_handler.close_all()
+
+def md5(s):
+ try:
+ from hashlib import md5 as _md5
+ except ImportError:
+ from md5 import md5 as _md5
+ global md5
+ md5 = _md5
+ return _md5(s)
+
+def continuity(url):
+ format = '%25s: %s'
+
+ # first fetch the file with the normal http handler
+ opener = urllib2.build_opener()
+ urllib2.install_opener(opener)
+ fo = urllib2.urlopen(url)
+ foo = fo.read()
+ fo.close()
+ m = md5.new(foo)
+ print format % ('normal urllib', m.hexdigest())
+
+ # now install the keepalive handler and try again
+ opener = urllib2.build_opener(HTTPHandler())
+ urllib2.install_opener(opener)
+
+ fo = urllib2.urlopen(url)
+ foo = fo.read()
+ fo.close()
+ m = md5.new(foo)
+ print format % ('keepalive read', m.hexdigest())
+
+ fo = urllib2.urlopen(url)
+ foo = ''
+ while 1:
+ f = fo.readline()
+ if f: foo = foo + f
+ else: break
+ fo.close()
+ m = md5.new(foo)
+ print format % ('keepalive readline', m.hexdigest())
+
+def comp(N, url):
+ print ' making %i connections to:\n %s' % (N, url)
+
+ sys.stdout.write(' first using the normal urllib handlers')
+ # first use normal opener
+ opener = urllib2.build_opener()
+ urllib2.install_opener(opener)
+ t1 = fetch(N, url)
+ print ' TIME: %.3f s' % t1
+
+ sys.stdout.write(' now using the keepalive handler ')
+ # now install the keepalive handler and try again
+ opener = urllib2.build_opener(HTTPHandler())
+ urllib2.install_opener(opener)
+ t2 = fetch(N, url)
+ print ' TIME: %.3f s' % t2
+ print ' improvement factor: %.2f' % (t1/t2, )
+
+def fetch(N, url, delay=0):
+ import time
+ lens = []
+ starttime = time.time()
+ for i in range(N):
+ if delay and i > 0: time.sleep(delay)
+ fo = urllib2.urlopen(url)
+ foo = fo.read()
+ fo.close()
+ lens.append(len(foo))
+ diff = time.time() - starttime
+
+ j = 0
+ for i in lens[1:]:
+ j = j + 1
+ if not i == lens[0]:
+ print "WARNING: inconsistent length on read %i: %i" % (j, i)
+
+ return diff
+
+def test_timeout(url):
+ global DEBUG
+ dbbackup = DEBUG
+ class FakeLogger:
+ def debug(self, msg, *args): print msg % args
+ info = warning = error = debug
+ DEBUG = FakeLogger()
+ print " fetching the file to establish a connection"
+ fo = urllib2.urlopen(url)
+ data1 = fo.read()
+ fo.close()
+
+ i = 20
+ print " waiting %i seconds for the server to close the connection" % i
+ while i > 0:
+ sys.stdout.write('\r %2i' % i)
+ sys.stdout.flush()
+ time.sleep(1)
+ i -= 1
+ sys.stderr.write('\r')
+
+ print " fetching the file a second time"
+ fo = urllib2.urlopen(url)
+ data2 = fo.read()
+ fo.close()
+
+ if data1 == data2:
+ print ' data are identical'
+ else:
+ print ' ERROR: DATA DIFFER'
+
+ DEBUG = dbbackup
+
+
+def test(url, N=10):
+ print "checking error hander (do this on a non-200)"
+ try: error_handler(url)
+ except IOError:
+ print "exiting - exception will prevent further tests"
+ sys.exit()
+ print
+ print "performing continuity test (making sure stuff isn't corrupted)"
+ continuity(url)
+ print
+ print "performing speed comparison"
+ comp(N, url)
+ print
+ print "performing dropped-connection check"
+ test_timeout(url)
+
+if __name__ == '__main__':
+ import time
+ import sys
+ try:
+ N = int(sys.argv[1])
+ url = sys.argv[2]
+ except:
+ print "%s <integer> <url>" % sys.argv[0]
+ else:
+ test(url, N)
diff --git a/sys/src/cmd/hg/mercurial/localrepo.py b/sys/src/cmd/hg/mercurial/localrepo.py
new file mode 100644
index 000000000..85ec689f6
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/localrepo.py
@@ -0,0 +1,2156 @@
+# localrepo.py - read/write repository class for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import bin, hex, nullid, nullrev, short
+from i18n import _
+import repo, changegroup, subrepo
+import changelog, dirstate, filelog, manifest, context
+import lock, transaction, store, encoding
+import util, extensions, hook, error
+import match as match_
+import merge as merge_
+import tags as tags_
+from lock import release
+import weakref, stat, errno, os, time, inspect
+propertycache = util.propertycache
+
+class localrepository(repo.repository):
+ capabilities = set(('lookup', 'changegroupsubset', 'branchmap'))
+ supported = set('revlogv1 store fncache shared'.split())
+
+ def __init__(self, baseui, path=None, create=0):
+ repo.repository.__init__(self)
+ self.root = os.path.realpath(path)
+ self.path = os.path.join(self.root, ".hg")
+ self.origroot = path
+ self.opener = util.opener(self.path)
+ self.wopener = util.opener(self.root)
+ self.baseui = baseui
+ self.ui = baseui.copy()
+
+ try:
+ self.ui.readconfig(self.join("hgrc"), self.root)
+ extensions.loadall(self.ui)
+ except IOError:
+ pass
+
+ if not os.path.isdir(self.path):
+ if create:
+ if not os.path.exists(path):
+ os.mkdir(path)
+ os.mkdir(self.path)
+ requirements = ["revlogv1"]
+ if self.ui.configbool('format', 'usestore', True):
+ os.mkdir(os.path.join(self.path, "store"))
+ requirements.append("store")
+ if self.ui.configbool('format', 'usefncache', True):
+ requirements.append("fncache")
+ # create an invalid changelog
+ self.opener("00changelog.i", "a").write(
+ '\0\0\0\2' # represents revlogv2
+ ' dummy changelog to prevent using the old repo layout'
+ )
+ reqfile = self.opener("requires", "w")
+ for r in requirements:
+ reqfile.write("%s\n" % r)
+ reqfile.close()
+ else:
+ raise error.RepoError(_("repository %s not found") % path)
+ elif create:
+ raise error.RepoError(_("repository %s already exists") % path)
+ else:
+ # find requirements
+ requirements = set()
+ try:
+ requirements = set(self.opener("requires").read().splitlines())
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+ for r in requirements - self.supported:
+ raise error.RepoError(_("requirement '%s' not supported") % r)
+
+ self.sharedpath = self.path
+ try:
+ s = os.path.realpath(self.opener("sharedpath").read())
+ if not os.path.exists(s):
+ raise error.RepoError(
+ _('.hg/sharedpath points to nonexistent directory %s') % s)
+ self.sharedpath = s
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+
+ self.store = store.store(requirements, self.sharedpath, util.opener)
+ self.spath = self.store.path
+ self.sopener = self.store.opener
+ self.sjoin = self.store.join
+ self.opener.createmode = self.store.createmode
+
+ # These two define the set of tags for this repository. _tags
+ # maps tag name to node; _tagtypes maps tag name to 'global' or
+ # 'local'. (Global tags are defined by .hgtags across all
+ # heads, and local tags are defined in .hg/localtags.) They
+ # constitute the in-memory cache of tags.
+ self._tags = None
+ self._tagtypes = None
+
+ self.branchcache = None
+ self._ubranchcache = None # UTF-8 version of branchcache
+ self._branchcachetip = None
+ self.nodetagscache = None
+ self.filterpats = {}
+ self._datafilters = {}
+ self._transref = self._lockref = self._wlockref = None
+
+ @propertycache
+ def changelog(self):
+ c = changelog.changelog(self.sopener)
+ if 'HG_PENDING' in os.environ:
+ p = os.environ['HG_PENDING']
+ if p.startswith(self.root):
+ c.readpending('00changelog.i.a')
+ self.sopener.defversion = c.version
+ return c
+
+ @propertycache
+ def manifest(self):
+ return manifest.manifest(self.sopener)
+
+ @propertycache
+ def dirstate(self):
+ return dirstate.dirstate(self.opener, self.ui, self.root)
+
+ def __getitem__(self, changeid):
+ if changeid is None:
+ return context.workingctx(self)
+ return context.changectx(self, changeid)
+
+ def __nonzero__(self):
+ return True
+
+ def __len__(self):
+ return len(self.changelog)
+
+ def __iter__(self):
+ for i in xrange(len(self)):
+ yield i
+
+ def url(self):
+ return 'file:' + self.root
+
+ def hook(self, name, throw=False, **args):
+ return hook.hook(self.ui, self, name, throw, **args)
+
+ tag_disallowed = ':\r\n'
+
+ def _tag(self, names, node, message, local, user, date, extra={}):
+ if isinstance(names, str):
+ allchars = names
+ names = (names,)
+ else:
+ allchars = ''.join(names)
+ for c in self.tag_disallowed:
+ if c in allchars:
+ raise util.Abort(_('%r cannot be used in a tag name') % c)
+
+ for name in names:
+ self.hook('pretag', throw=True, node=hex(node), tag=name,
+ local=local)
+
+ def writetags(fp, names, munge, prevtags):
+ fp.seek(0, 2)
+ if prevtags and prevtags[-1] != '\n':
+ fp.write('\n')
+ for name in names:
+ m = munge and munge(name) or name
+ if self._tagtypes and name in self._tagtypes:
+ old = self._tags.get(name, nullid)
+ fp.write('%s %s\n' % (hex(old), m))
+ fp.write('%s %s\n' % (hex(node), m))
+ fp.close()
+
+ prevtags = ''
+ if local:
+ try:
+ fp = self.opener('localtags', 'r+')
+ except IOError:
+ fp = self.opener('localtags', 'a')
+ else:
+ prevtags = fp.read()
+
+ # local tags are stored in the current charset
+ writetags(fp, names, None, prevtags)
+ for name in names:
+ self.hook('tag', node=hex(node), tag=name, local=local)
+ return
+
+ try:
+ fp = self.wfile('.hgtags', 'rb+')
+ except IOError:
+ fp = self.wfile('.hgtags', 'ab')
+ else:
+ prevtags = fp.read()
+
+ # committed tags are stored in UTF-8
+ writetags(fp, names, encoding.fromlocal, prevtags)
+
+ if '.hgtags' not in self.dirstate:
+ self.add(['.hgtags'])
+
+ m = match_.exact(self.root, '', ['.hgtags'])
+ tagnode = self.commit(message, user, date, extra=extra, match=m)
+
+ for name in names:
+ self.hook('tag', node=hex(node), tag=name, local=local)
+
+ return tagnode
+
+ def tag(self, names, node, message, local, user, date):
+ '''tag a revision with one or more symbolic names.
+
+ names is a list of strings or, when adding a single tag, names may be a
+ string.
+
+ if local is True, the tags are stored in a per-repository file.
+ otherwise, they are stored in the .hgtags file, and a new
+ changeset is committed with the change.
+
+ keyword arguments:
+
+ local: whether to store tags in non-version-controlled file
+ (default False)
+
+ message: commit message to use if committing
+
+ user: name of user to use if committing
+
+ date: date tuple to use if committing'''
+
+ for x in self.status()[:5]:
+ if '.hgtags' in x:
+ raise util.Abort(_('working copy of .hgtags is changed '
+ '(please commit .hgtags manually)'))
+
+ self.tags() # instantiate the cache
+ self._tag(names, node, message, local, user, date)
+
+ def tags(self):
+ '''return a mapping of tag to node'''
+ if self._tags is None:
+ (self._tags, self._tagtypes) = self._findtags()
+
+ return self._tags
+
+ def _findtags(self):
+ '''Do the hard work of finding tags. Return a pair of dicts
+ (tags, tagtypes) where tags maps tag name to node, and tagtypes
+ maps tag name to a string like \'global\' or \'local\'.
+ Subclasses or extensions are free to add their own tags, but
+ should be aware that the returned dicts will be retained for the
+ duration of the localrepo object.'''
+
+ # XXX what tagtype should subclasses/extensions use? Currently
+ # mq and bookmarks add tags, but do not set the tagtype at all.
+ # Should each extension invent its own tag type? Should there
+ # be one tagtype for all such "virtual" tags? Or is the status
+ # quo fine?
+
+ alltags = {} # map tag name to (node, hist)
+ tagtypes = {}
+
+ tags_.findglobaltags(self.ui, self, alltags, tagtypes)
+ tags_.readlocaltags(self.ui, self, alltags, tagtypes)
+
+ # Build the return dicts. Have to re-encode tag names because
+ # the tags module always uses UTF-8 (in order not to lose info
+ # writing to the cache), but the rest of Mercurial wants them in
+ # local encoding.
+ tags = {}
+ for (name, (node, hist)) in alltags.iteritems():
+ if node != nullid:
+ tags[encoding.tolocal(name)] = node
+ tags['tip'] = self.changelog.tip()
+ tagtypes = dict([(encoding.tolocal(name), value)
+ for (name, value) in tagtypes.iteritems()])
+ return (tags, tagtypes)
+
+ def tagtype(self, tagname):
+ '''
+ return the type of the given tag. result can be:
+
+ 'local' : a local tag
+ 'global' : a global tag
+ None : tag does not exist
+ '''
+
+ self.tags()
+
+ return self._tagtypes.get(tagname)
+
+ def tagslist(self):
+ '''return a list of tags ordered by revision'''
+ l = []
+ for t, n in self.tags().iteritems():
+ try:
+ r = self.changelog.rev(n)
+ except:
+ r = -2 # sort to the beginning of the list if unknown
+ l.append((r, t, n))
+ return [(t, n) for r, t, n in sorted(l)]
+
+ def nodetags(self, node):
+ '''return the tags associated with a node'''
+ if not self.nodetagscache:
+ self.nodetagscache = {}
+ for t, n in self.tags().iteritems():
+ self.nodetagscache.setdefault(n, []).append(t)
+ return self.nodetagscache.get(node, [])
+
+ def _branchtags(self, partial, lrev):
+ # TODO: rename this function?
+ tiprev = len(self) - 1
+ if lrev != tiprev:
+ self._updatebranchcache(partial, lrev+1, tiprev+1)
+ self._writebranchcache(partial, self.changelog.tip(), tiprev)
+
+ return partial
+
+ def branchmap(self):
+ tip = self.changelog.tip()
+ if self.branchcache is not None and self._branchcachetip == tip:
+ return self.branchcache
+
+ oldtip = self._branchcachetip
+ self._branchcachetip = tip
+ if self.branchcache is None:
+ self.branchcache = {} # avoid recursion in changectx
+ else:
+ self.branchcache.clear() # keep using the same dict
+ if oldtip is None or oldtip not in self.changelog.nodemap:
+ partial, last, lrev = self._readbranchcache()
+ else:
+ lrev = self.changelog.rev(oldtip)
+ partial = self._ubranchcache
+
+ self._branchtags(partial, lrev)
+ # this private cache holds all heads (not just tips)
+ self._ubranchcache = partial
+
+ # the branch cache is stored on disk as UTF-8, but in the local
+ # charset internally
+ for k, v in partial.iteritems():
+ self.branchcache[encoding.tolocal(k)] = v
+ return self.branchcache
+
+
+ def branchtags(self):
+ '''return a dict where branch names map to the tipmost head of
+ the branch, open heads come before closed'''
+ bt = {}
+ for bn, heads in self.branchmap().iteritems():
+ head = None
+ for i in range(len(heads)-1, -1, -1):
+ h = heads[i]
+ if 'close' not in self.changelog.read(h)[5]:
+ head = h
+ break
+ # no open heads were found
+ if head is None:
+ head = heads[-1]
+ bt[bn] = head
+ return bt
+
+
+ def _readbranchcache(self):
+ partial = {}
+ try:
+ f = self.opener("branchheads.cache")
+ lines = f.read().split('\n')
+ f.close()
+ except (IOError, OSError):
+ return {}, nullid, nullrev
+
+ try:
+ last, lrev = lines.pop(0).split(" ", 1)
+ last, lrev = bin(last), int(lrev)
+ if lrev >= len(self) or self[lrev].node() != last:
+ # invalidate the cache
+ raise ValueError('invalidating branch cache (tip differs)')
+ for l in lines:
+ if not l: continue
+ node, label = l.split(" ", 1)
+ partial.setdefault(label.strip(), []).append(bin(node))
+ except KeyboardInterrupt:
+ raise
+ except Exception, inst:
+ if self.ui.debugflag:
+ self.ui.warn(str(inst), '\n')
+ partial, last, lrev = {}, nullid, nullrev
+ return partial, last, lrev
+
+ def _writebranchcache(self, branches, tip, tiprev):
+ try:
+ f = self.opener("branchheads.cache", "w", atomictemp=True)
+ f.write("%s %s\n" % (hex(tip), tiprev))
+ for label, nodes in branches.iteritems():
+ for node in nodes:
+ f.write("%s %s\n" % (hex(node), label))
+ f.rename()
+ except (IOError, OSError):
+ pass
+
+ def _updatebranchcache(self, partial, start, end):
+ # collect new branch entries
+ newbranches = {}
+ for r in xrange(start, end):
+ c = self[r]
+ newbranches.setdefault(c.branch(), []).append(c.node())
+ # if older branchheads are reachable from new ones, they aren't
+ # really branchheads. Note checking parents is insufficient:
+ # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
+ for branch, newnodes in newbranches.iteritems():
+ bheads = partial.setdefault(branch, [])
+ bheads.extend(newnodes)
+ if len(bheads) < 2:
+ continue
+ newbheads = []
+ # starting from tip means fewer passes over reachable
+ while newnodes:
+ latest = newnodes.pop()
+ if latest not in bheads:
+ continue
+ minbhrev = self[min([self[bh].rev() for bh in bheads])].node()
+ reachable = self.changelog.reachable(latest, minbhrev)
+ bheads = [b for b in bheads if b not in reachable]
+ newbheads.insert(0, latest)
+ bheads.extend(newbheads)
+ partial[branch] = bheads
+
+ def lookup(self, key):
+ if isinstance(key, int):
+ return self.changelog.node(key)
+ elif key == '.':
+ return self.dirstate.parents()[0]
+ elif key == 'null':
+ return nullid
+ elif key == 'tip':
+ return self.changelog.tip()
+ n = self.changelog._match(key)
+ if n:
+ return n
+ if key in self.tags():
+ return self.tags()[key]
+ if key in self.branchtags():
+ return self.branchtags()[key]
+ n = self.changelog._partialmatch(key)
+ if n:
+ return n
+
+ # can't find key, check if it might have come from damaged dirstate
+ if key in self.dirstate.parents():
+ raise error.Abort(_("working directory has unknown parent '%s'!")
+ % short(key))
+ try:
+ if len(key) == 20:
+ key = hex(key)
+ except:
+ pass
+ raise error.RepoError(_("unknown revision '%s'") % key)
+
+ def local(self):
+ return True
+
+ def join(self, f):
+ return os.path.join(self.path, f)
+
+ def wjoin(self, f):
+ return os.path.join(self.root, f)
+
+ def rjoin(self, f):
+ return os.path.join(self.root, util.pconvert(f))
+
+ def file(self, f):
+ if f[0] == '/':
+ f = f[1:]
+ return filelog.filelog(self.sopener, f)
+
+ def changectx(self, changeid):
+ return self[changeid]
+
+ def parents(self, changeid=None):
+ '''get list of changectxs for parents of changeid'''
+ return self[changeid].parents()
+
+ def filectx(self, path, changeid=None, fileid=None):
+ """changeid can be a changeset revision, node, or tag.
+ fileid can be a file revision or node."""
+ return context.filectx(self, path, changeid, fileid)
+
+ def getcwd(self):
+ return self.dirstate.getcwd()
+
+ def pathto(self, f, cwd=None):
+ return self.dirstate.pathto(f, cwd)
+
+ def wfile(self, f, mode='r'):
+ return self.wopener(f, mode)
+
+ def _link(self, f):
+ return os.path.islink(self.wjoin(f))
+
+ def _filter(self, filter, filename, data):
+ if filter not in self.filterpats:
+ l = []
+ for pat, cmd in self.ui.configitems(filter):
+ if cmd == '!':
+ continue
+ mf = match_.match(self.root, '', [pat])
+ fn = None
+ params = cmd
+ for name, filterfn in self._datafilters.iteritems():
+ if cmd.startswith(name):
+ fn = filterfn
+ params = cmd[len(name):].lstrip()
+ break
+ if not fn:
+ fn = lambda s, c, **kwargs: util.filter(s, c)
+ # Wrap old filters not supporting keyword arguments
+ if not inspect.getargspec(fn)[2]:
+ oldfn = fn
+ fn = lambda s, c, **kwargs: oldfn(s, c)
+ l.append((mf, fn, params))
+ self.filterpats[filter] = l
+
+ for mf, fn, cmd in self.filterpats[filter]:
+ if mf(filename):
+ self.ui.debug(_("filtering %s through %s\n") % (filename, cmd))
+ data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
+ break
+
+ return data
+
+ def adddatafilter(self, name, filter):
+ self._datafilters[name] = filter
+
+ def wread(self, filename):
+ if self._link(filename):
+ data = os.readlink(self.wjoin(filename))
+ else:
+ data = self.wopener(filename, 'r').read()
+ return self._filter("encode", filename, data)
+
+ def wwrite(self, filename, data, flags):
+ data = self._filter("decode", filename, data)
+ try:
+ os.unlink(self.wjoin(filename))
+ except OSError:
+ pass
+ if 'l' in flags:
+ self.wopener.symlink(data, filename)
+ else:
+ self.wopener(filename, 'w').write(data)
+ if 'x' in flags:
+ util.set_flags(self.wjoin(filename), False, True)
+
+ def wwritedata(self, filename, data):
+ return self._filter("decode", filename, data)
+
+ def transaction(self):
+ tr = self._transref and self._transref() or None
+ if tr and tr.running():
+ return tr.nest()
+
+ # abort here if the journal already exists
+ if os.path.exists(self.sjoin("journal")):
+ raise error.RepoError(_("journal already exists - run hg recover"))
+
+ # save dirstate for rollback
+ try:
+ ds = self.opener("dirstate").read()
+ except IOError:
+ ds = ""
+ self.opener("journal.dirstate", "w").write(ds)
+ self.opener("journal.branch", "w").write(self.dirstate.branch())
+
+ renames = [(self.sjoin("journal"), self.sjoin("undo")),
+ (self.join("journal.dirstate"), self.join("undo.dirstate")),
+ (self.join("journal.branch"), self.join("undo.branch"))]
+ tr = transaction.transaction(self.ui.warn, self.sopener,
+ self.sjoin("journal"),
+ aftertrans(renames),
+ self.store.createmode)
+ self._transref = weakref.ref(tr)
+ return tr
+
+ def recover(self):
+ lock = self.lock()
+ try:
+ if os.path.exists(self.sjoin("journal")):
+ self.ui.status(_("rolling back interrupted transaction\n"))
+ transaction.rollback(self.sopener, self.sjoin("journal"), self.ui.warn)
+ self.invalidate()
+ return True
+ else:
+ self.ui.warn(_("no interrupted transaction available\n"))
+ return False
+ finally:
+ lock.release()
+
+ def rollback(self):
+ wlock = lock = None
+ try:
+ wlock = self.wlock()
+ lock = self.lock()
+ if os.path.exists(self.sjoin("undo")):
+ self.ui.status(_("rolling back last transaction\n"))
+ transaction.rollback(self.sopener, self.sjoin("undo"), self.ui.warn)
+ util.rename(self.join("undo.dirstate"), self.join("dirstate"))
+ try:
+ branch = self.opener("undo.branch").read()
+ self.dirstate.setbranch(branch)
+ except IOError:
+ self.ui.warn(_("Named branch could not be reset, "
+ "current branch still is: %s\n")
+ % encoding.tolocal(self.dirstate.branch()))
+ self.invalidate()
+ self.dirstate.invalidate()
+ self.destroyed()
+ else:
+ self.ui.warn(_("no rollback information available\n"))
+ finally:
+ release(lock, wlock)
+
+ def invalidate(self):
+ for a in "changelog manifest".split():
+ if a in self.__dict__:
+ delattr(self, a)
+ self._tags = None
+ self._tagtypes = None
+ self.nodetagscache = None
+ self.branchcache = None
+ self._ubranchcache = None
+ self._branchcachetip = None
+
+ def _lock(self, lockname, wait, releasefn, acquirefn, desc):
+ try:
+ l = lock.lock(lockname, 0, releasefn, desc=desc)
+ except error.LockHeld, inst:
+ if not wait:
+ raise
+ self.ui.warn(_("waiting for lock on %s held by %r\n") %
+ (desc, inst.locker))
+ # default to 600 seconds timeout
+ l = lock.lock(lockname, int(self.ui.config("ui", "timeout", "600")),
+ releasefn, desc=desc)
+ if acquirefn:
+ acquirefn()
+ return l
+
+ def lock(self, wait=True):
+ '''Lock the repository store (.hg/store) and return a weak reference
+ to the lock. Use this before modifying the store (e.g. committing or
+ stripping). If you are opening a transaction, get a lock as well.)'''
+ l = self._lockref and self._lockref()
+ if l is not None and l.held:
+ l.lock()
+ return l
+
+ l = self._lock(self.sjoin("lock"), wait, None, self.invalidate,
+ _('repository %s') % self.origroot)
+ self._lockref = weakref.ref(l)
+ return l
+
+ def wlock(self, wait=True):
+ '''Lock the non-store parts of the repository (everything under
+ .hg except .hg/store) and return a weak reference to the lock.
+ Use this before modifying files in .hg.'''
+ l = self._wlockref and self._wlockref()
+ if l is not None and l.held:
+ l.lock()
+ return l
+
+ l = self._lock(self.join("wlock"), wait, self.dirstate.write,
+ self.dirstate.invalidate, _('working directory of %s') %
+ self.origroot)
+ self._wlockref = weakref.ref(l)
+ return l
+
+ def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
+ """
+ commit an individual file as part of a larger transaction
+ """
+
+ fname = fctx.path()
+ text = fctx.data()
+ flog = self.file(fname)
+ fparent1 = manifest1.get(fname, nullid)
+ fparent2 = fparent2o = manifest2.get(fname, nullid)
+
+ meta = {}
+ copy = fctx.renamed()
+ if copy and copy[0] != fname:
+ # Mark the new revision of this file as a copy of another
+ # file. This copy data will effectively act as a parent
+ # of this new revision. If this is a merge, the first
+ # parent will be the nullid (meaning "look up the copy data")
+ # and the second one will be the other parent. For example:
+ #
+ # 0 --- 1 --- 3 rev1 changes file foo
+ # \ / rev2 renames foo to bar and changes it
+ # \- 2 -/ rev3 should have bar with all changes and
+ # should record that bar descends from
+ # bar in rev2 and foo in rev1
+ #
+ # this allows this merge to succeed:
+ #
+ # 0 --- 1 --- 3 rev4 reverts the content change from rev2
+ # \ / merging rev3 and rev4 should use bar@rev2
+ # \- 2 --- 4 as the merge base
+ #
+
+ cfname = copy[0]
+ crev = manifest1.get(cfname)
+ newfparent = fparent2
+
+ if manifest2: # branch merge
+ if fparent2 == nullid or crev is None: # copied on remote side
+ if cfname in manifest2:
+ crev = manifest2[cfname]
+ newfparent = fparent1
+
+ # find source in nearest ancestor if we've lost track
+ if not crev:
+ self.ui.debug(_(" %s: searching for copy revision for %s\n") %
+ (fname, cfname))
+ for ancestor in self['.'].ancestors():
+ if cfname in ancestor:
+ crev = ancestor[cfname].filenode()
+ break
+
+ self.ui.debug(_(" %s: copy %s:%s\n") % (fname, cfname, hex(crev)))
+ meta["copy"] = cfname
+ meta["copyrev"] = hex(crev)
+ fparent1, fparent2 = nullid, newfparent
+ elif fparent2 != nullid:
+ # is one parent an ancestor of the other?
+ fparentancestor = flog.ancestor(fparent1, fparent2)
+ if fparentancestor == fparent1:
+ fparent1, fparent2 = fparent2, nullid
+ elif fparentancestor == fparent2:
+ fparent2 = nullid
+
+ # is the file changed?
+ if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
+ changelist.append(fname)
+ return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
+
+ # are just the flags changed during merge?
+ if fparent1 != fparent2o and manifest1.flags(fname) != fctx.flags():
+ changelist.append(fname)
+
+ return fparent1
+
+ def commit(self, text="", user=None, date=None, match=None, force=False,
+ editor=False, extra={}):
+ """Add a new revision to current repository.
+
+ Revision information is gathered from the working directory,
+ match can be used to filter the committed files. If editor is
+ supplied, it is called to get a commit message.
+ """
+
+ def fail(f, msg):
+ raise util.Abort('%s: %s' % (f, msg))
+
+ if not match:
+ match = match_.always(self.root, '')
+
+ if not force:
+ vdirs = []
+ match.dir = vdirs.append
+ match.bad = fail
+
+ wlock = self.wlock()
+ try:
+ p1, p2 = self.dirstate.parents()
+ wctx = self[None]
+
+ if (not force and p2 != nullid and match and
+ (match.files() or match.anypats())):
+ raise util.Abort(_('cannot partially commit a merge '
+ '(do not specify files or patterns)'))
+
+ changes = self.status(match=match, clean=force)
+ if force:
+ changes[0].extend(changes[6]) # mq may commit unchanged files
+
+ # check subrepos
+ subs = []
+ for s in wctx.substate:
+ if match(s) and wctx.sub(s).dirty():
+ subs.append(s)
+ if subs and '.hgsubstate' not in changes[0]:
+ changes[0].insert(0, '.hgsubstate')
+
+ # make sure all explicit patterns are matched
+ if not force and match.files():
+ matched = set(changes[0] + changes[1] + changes[2])
+
+ for f in match.files():
+ if f == '.' or f in matched or f in wctx.substate:
+ continue
+ if f in changes[3]: # missing
+ fail(f, _('file not found!'))
+ if f in vdirs: # visited directory
+ d = f + '/'
+ for mf in matched:
+ if mf.startswith(d):
+ break
+ else:
+ fail(f, _("no match under directory!"))
+ elif f not in self.dirstate:
+ fail(f, _("file not tracked!"))
+
+ if (not force and not extra.get("close") and p2 == nullid
+ and not (changes[0] or changes[1] or changes[2])
+ and self[None].branch() == self['.'].branch()):
+ return None
+
+ ms = merge_.mergestate(self)
+ for f in changes[0]:
+ if f in ms and ms[f] == 'u':
+ raise util.Abort(_("unresolved merge conflicts "
+ "(see hg resolve)"))
+
+ cctx = context.workingctx(self, (p1, p2), text, user, date,
+ extra, changes)
+ if editor:
+ cctx._text = editor(self, cctx, subs)
+
+ # commit subs
+ if subs:
+ state = wctx.substate.copy()
+ for s in subs:
+ self.ui.status(_('committing subrepository %s\n') % s)
+ sr = wctx.sub(s).commit(cctx._text, user, date)
+ state[s] = (state[s][0], sr)
+ subrepo.writestate(self, state)
+
+ ret = self.commitctx(cctx, True)
+
+ # update dirstate and mergestate
+ for f in changes[0] + changes[1]:
+ self.dirstate.normal(f)
+ for f in changes[2]:
+ self.dirstate.forget(f)
+ self.dirstate.setparents(ret)
+ ms.reset()
+
+ return ret
+
+ finally:
+ wlock.release()
+
+ def commitctx(self, ctx, error=False):
+ """Add a new revision to current repository.
+
+ Revision information is passed via the context argument.
+ """
+
+ tr = lock = None
+ removed = ctx.removed()
+ p1, p2 = ctx.p1(), ctx.p2()
+ m1 = p1.manifest().copy()
+ m2 = p2.manifest()
+ user = ctx.user()
+
+ xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
+ self.hook("precommit", throw=True, parent1=xp1, parent2=xp2)
+
+ lock = self.lock()
+ try:
+ tr = self.transaction()
+ trp = weakref.proxy(tr)
+
+ # check in files
+ new = {}
+ changed = []
+ linkrev = len(self)
+ for f in sorted(ctx.modified() + ctx.added()):
+ self.ui.note(f + "\n")
+ try:
+ fctx = ctx[f]
+ new[f] = self._filecommit(fctx, m1, m2, linkrev, trp,
+ changed)
+ m1.set(f, fctx.flags())
+ except (OSError, IOError):
+ if error:
+ self.ui.warn(_("trouble committing %s!\n") % f)
+ raise
+ else:
+ removed.append(f)
+
+ # update manifest
+ m1.update(new)
+ removed = [f for f in sorted(removed) if f in m1 or f in m2]
+ drop = [f for f in removed if f in m1]
+ for f in drop:
+ del m1[f]
+ mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(),
+ p2.manifestnode(), (new, drop))
+
+ # update changelog
+ self.changelog.delayupdate()
+ n = self.changelog.add(mn, changed + removed, ctx.description(),
+ trp, p1.node(), p2.node(),
+ user, ctx.date(), ctx.extra().copy())
+ p = lambda: self.changelog.writepending() and self.root or ""
+ self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
+ parent2=xp2, pending=p)
+ self.changelog.finalize(trp)
+ tr.close()
+
+ if self.branchcache:
+ self.branchtags()
+
+ self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2)
+ return n
+ finally:
+ del tr
+ lock.release()
+
+ def destroyed(self):
+ '''Inform the repository that nodes have been destroyed.
+ Intended for use by strip and rollback, so there's a common
+ place for anything that has to be done after destroying history.'''
+ # XXX it might be nice if we could take the list of destroyed
+ # nodes, but I don't see an easy way for rollback() to do that
+
+ # Ensure the persistent tag cache is updated. Doing it now
+ # means that the tag cache only has to worry about destroyed
+ # heads immediately after a strip/rollback. That in turn
+ # guarantees that "cachetip == currenttip" (comparing both rev
+ # and node) always means no nodes have been added or destroyed.
+
+ # XXX this is suboptimal when qrefresh'ing: we strip the current
+ # head, refresh the tag cache, then immediately add a new head.
+ # But I think doing it this way is necessary for the "instant
+ # tag cache retrieval" case to work.
+ tags_.findglobaltags(self.ui, self, {}, {})
+
+ def walk(self, match, node=None):
+ '''
+ walk recursively through the directory tree or a given
+ changeset, finding all files matched by the match
+ function
+ '''
+ return self[node].walk(match)
+
+ def status(self, node1='.', node2=None, match=None,
+ ignored=False, clean=False, unknown=False):
+ """return status of files between two nodes or node and working directory
+
+ If node1 is None, use the first dirstate parent instead.
+ If node2 is None, compare node1 with working directory.
+ """
+
+ def mfmatches(ctx):
+ mf = ctx.manifest().copy()
+ for fn in mf.keys():
+ if not match(fn):
+ del mf[fn]
+ return mf
+
+ if isinstance(node1, context.changectx):
+ ctx1 = node1
+ else:
+ ctx1 = self[node1]
+ if isinstance(node2, context.changectx):
+ ctx2 = node2
+ else:
+ ctx2 = self[node2]
+
+ working = ctx2.rev() is None
+ parentworking = working and ctx1 == self['.']
+ match = match or match_.always(self.root, self.getcwd())
+ listignored, listclean, listunknown = ignored, clean, unknown
+
+ # load earliest manifest first for caching reasons
+ if not working and ctx2.rev() < ctx1.rev():
+ ctx2.manifest()
+
+ if not parentworking:
+ def bad(f, msg):
+ if f not in ctx1:
+ self.ui.warn('%s: %s\n' % (self.dirstate.pathto(f), msg))
+ match.bad = bad
+
+ if working: # we need to scan the working dir
+ s = self.dirstate.status(match, listignored, listclean, listunknown)
+ cmp, modified, added, removed, deleted, unknown, ignored, clean = s
+
+ # check for any possibly clean files
+ if parentworking and cmp:
+ fixup = []
+ # do a full compare of any files that might have changed
+ for f in sorted(cmp):
+ if (f not in ctx1 or ctx2.flags(f) != ctx1.flags(f)
+ or ctx1[f].cmp(ctx2[f].data())):
+ modified.append(f)
+ else:
+ fixup.append(f)
+
+ if listclean:
+ clean += fixup
+
+ # update dirstate for files that are actually clean
+ if fixup:
+ try:
+ # updating the dirstate is optional
+ # so we don't wait on the lock
+ wlock = self.wlock(False)
+ try:
+ for f in fixup:
+ self.dirstate.normal(f)
+ finally:
+ wlock.release()
+ except error.LockError:
+ pass
+
+ if not parentworking:
+ mf1 = mfmatches(ctx1)
+ if working:
+ # we are comparing working dir against non-parent
+ # generate a pseudo-manifest for the working dir
+ mf2 = mfmatches(self['.'])
+ for f in cmp + modified + added:
+ mf2[f] = None
+ mf2.set(f, ctx2.flags(f))
+ for f in removed:
+ if f in mf2:
+ del mf2[f]
+ else:
+ # we are comparing two revisions
+ deleted, unknown, ignored = [], [], []
+ mf2 = mfmatches(ctx2)
+
+ modified, added, clean = [], [], []
+ for fn in mf2:
+ if fn in mf1:
+ if (mf1.flags(fn) != mf2.flags(fn) or
+ (mf1[fn] != mf2[fn] and
+ (mf2[fn] or ctx1[fn].cmp(ctx2[fn].data())))):
+ modified.append(fn)
+ elif listclean:
+ clean.append(fn)
+ del mf1[fn]
+ else:
+ added.append(fn)
+ removed = mf1.keys()
+
+ r = modified, added, removed, deleted, unknown, ignored, clean
+ [l.sort() for l in r]
+ return r
+
+ def add(self, list):
+ wlock = self.wlock()
+ try:
+ rejected = []
+ for f in list:
+ p = self.wjoin(f)
+ try:
+ st = os.lstat(p)
+ except:
+ self.ui.warn(_("%s does not exist!\n") % f)
+ rejected.append(f)
+ continue
+ if st.st_size > 10000000:
+ self.ui.warn(_("%s: files over 10MB may cause memory and"
+ " performance problems\n"
+ "(use 'hg revert %s' to unadd the file)\n")
+ % (f, f))
+ if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
+ self.ui.warn(_("%s not added: only files and symlinks "
+ "supported currently\n") % f)
+ rejected.append(p)
+ elif self.dirstate[f] in 'amn':
+ self.ui.warn(_("%s already tracked!\n") % f)
+ elif self.dirstate[f] == 'r':
+ self.dirstate.normallookup(f)
+ else:
+ self.dirstate.add(f)
+ return rejected
+ finally:
+ wlock.release()
+
+ def forget(self, list):
+ wlock = self.wlock()
+ try:
+ for f in list:
+ if self.dirstate[f] != 'a':
+ self.ui.warn(_("%s not added!\n") % f)
+ else:
+ self.dirstate.forget(f)
+ finally:
+ wlock.release()
+
+ def remove(self, list, unlink=False):
+ if unlink:
+ for f in list:
+ try:
+ util.unlink(self.wjoin(f))
+ except OSError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+ wlock = self.wlock()
+ try:
+ for f in list:
+ if unlink and os.path.exists(self.wjoin(f)):
+ self.ui.warn(_("%s still exists!\n") % f)
+ elif self.dirstate[f] == 'a':
+ self.dirstate.forget(f)
+ elif f not in self.dirstate:
+ self.ui.warn(_("%s not tracked!\n") % f)
+ else:
+ self.dirstate.remove(f)
+ finally:
+ wlock.release()
+
+ def undelete(self, list):
+ manifests = [self.manifest.read(self.changelog.read(p)[0])
+ for p in self.dirstate.parents() if p != nullid]
+ wlock = self.wlock()
+ try:
+ for f in list:
+ if self.dirstate[f] != 'r':
+ self.ui.warn(_("%s not removed!\n") % f)
+ else:
+ m = f in manifests[0] and manifests[0] or manifests[1]
+ t = self.file(f).read(m[f])
+ self.wwrite(f, t, m.flags(f))
+ self.dirstate.normal(f)
+ finally:
+ wlock.release()
+
+ def copy(self, source, dest):
+ p = self.wjoin(dest)
+ if not (os.path.exists(p) or os.path.islink(p)):
+ self.ui.warn(_("%s does not exist!\n") % dest)
+ elif not (os.path.isfile(p) or os.path.islink(p)):
+ self.ui.warn(_("copy failed: %s is not a file or a "
+ "symbolic link\n") % dest)
+ else:
+ wlock = self.wlock()
+ try:
+ if self.dirstate[dest] in '?r':
+ self.dirstate.add(dest)
+ self.dirstate.copy(source, dest)
+ finally:
+ wlock.release()
+
+ def heads(self, start=None):
+ heads = self.changelog.heads(start)
+ # sort the output in rev descending order
+ heads = [(-self.changelog.rev(h), h) for h in heads]
+ return [n for (r, n) in sorted(heads)]
+
+ def branchheads(self, branch=None, start=None, closed=False):
+ if branch is None:
+ branch = self[None].branch()
+ branches = self.branchmap()
+ if branch not in branches:
+ return []
+ bheads = branches[branch]
+ # the cache returns heads ordered lowest to highest
+ bheads.reverse()
+ if start is not None:
+ # filter out the heads that cannot be reached from startrev
+ bheads = self.changelog.nodesbetween([start], bheads)[2]
+ if not closed:
+ bheads = [h for h in bheads if
+ ('close' not in self.changelog.read(h)[5])]
+ return bheads
+
+ def branches(self, nodes):
+ if not nodes:
+ nodes = [self.changelog.tip()]
+ b = []
+ for n in nodes:
+ t = n
+ while 1:
+ p = self.changelog.parents(n)
+ if p[1] != nullid or p[0] == nullid:
+ b.append((t, n, p[0], p[1]))
+ break
+ n = p[0]
+ return b
+
+ def between(self, pairs):
+ r = []
+
+ for top, bottom in pairs:
+ n, l, i = top, [], 0
+ f = 1
+
+ while n != bottom and n != nullid:
+ p = self.changelog.parents(n)[0]
+ if i == f:
+ l.append(n)
+ f = f * 2
+ n = p
+ i += 1
+
+ r.append(l)
+
+ return r
+
+ def findincoming(self, remote, base=None, heads=None, force=False):
+ """Return list of roots of the subsets of missing nodes from remote
+
+ If base dict is specified, assume that these nodes and their parents
+ exist on the remote side and that no child of a node of base exists
+ in both remote and self.
+ Furthermore base will be updated to include the nodes that exists
+ in self and remote but no children exists in self and remote.
+ If a list of heads is specified, return only nodes which are heads
+ or ancestors of these heads.
+
+ All the ancestors of base are in self and in remote.
+ All the descendants of the list returned are missing in self.
+ (and so we know that the rest of the nodes are missing in remote, see
+ outgoing)
+ """
+ return self.findcommonincoming(remote, base, heads, force)[1]
+
+ def findcommonincoming(self, remote, base=None, heads=None, force=False):
+ """Return a tuple (common, missing roots, heads) used to identify
+ missing nodes from remote.
+
+ If base dict is specified, assume that these nodes and their parents
+ exist on the remote side and that no child of a node of base exists
+ in both remote and self.
+ Furthermore base will be updated to include the nodes that exists
+ in self and remote but no children exists in self and remote.
+ If a list of heads is specified, return only nodes which are heads
+ or ancestors of these heads.
+
+ All the ancestors of base are in self and in remote.
+ """
+ m = self.changelog.nodemap
+ search = []
+ fetch = set()
+ seen = set()
+ seenbranch = set()
+ if base is None:
+ base = {}
+
+ if not heads:
+ heads = remote.heads()
+
+ if self.changelog.tip() == nullid:
+ base[nullid] = 1
+ if heads != [nullid]:
+ return [nullid], [nullid], list(heads)
+ return [nullid], [], []
+
+ # assume we're closer to the tip than the root
+ # and start by examining the heads
+ self.ui.status(_("searching for changes\n"))
+
+ unknown = []
+ for h in heads:
+ if h not in m:
+ unknown.append(h)
+ else:
+ base[h] = 1
+
+ heads = unknown
+ if not unknown:
+ return base.keys(), [], []
+
+ req = set(unknown)
+ reqcnt = 0
+
+ # search through remote branches
+ # a 'branch' here is a linear segment of history, with four parts:
+ # head, root, first parent, second parent
+ # (a branch always has two parents (or none) by definition)
+ unknown = remote.branches(unknown)
+ while unknown:
+ r = []
+ while unknown:
+ n = unknown.pop(0)
+ if n[0] in seen:
+ continue
+
+ self.ui.debug(_("examining %s:%s\n")
+ % (short(n[0]), short(n[1])))
+ if n[0] == nullid: # found the end of the branch
+ pass
+ elif n in seenbranch:
+ self.ui.debug(_("branch already found\n"))
+ continue
+ elif n[1] and n[1] in m: # do we know the base?
+ self.ui.debug(_("found incomplete branch %s:%s\n")
+ % (short(n[0]), short(n[1])))
+ search.append(n[0:2]) # schedule branch range for scanning
+ seenbranch.add(n)
+ else:
+ if n[1] not in seen and n[1] not in fetch:
+ if n[2] in m and n[3] in m:
+ self.ui.debug(_("found new changeset %s\n") %
+ short(n[1]))
+ fetch.add(n[1]) # earliest unknown
+ for p in n[2:4]:
+ if p in m:
+ base[p] = 1 # latest known
+
+ for p in n[2:4]:
+ if p not in req and p not in m:
+ r.append(p)
+ req.add(p)
+ seen.add(n[0])
+
+ if r:
+ reqcnt += 1
+ self.ui.debug(_("request %d: %s\n") %
+ (reqcnt, " ".join(map(short, r))))
+ for p in xrange(0, len(r), 10):
+ for b in remote.branches(r[p:p+10]):
+ self.ui.debug(_("received %s:%s\n") %
+ (short(b[0]), short(b[1])))
+ unknown.append(b)
+
+ # do binary search on the branches we found
+ while search:
+ newsearch = []
+ reqcnt += 1
+ for n, l in zip(search, remote.between(search)):
+ l.append(n[1])
+ p = n[0]
+ f = 1
+ for i in l:
+ self.ui.debug(_("narrowing %d:%d %s\n") % (f, len(l), short(i)))
+ if i in m:
+ if f <= 2:
+ self.ui.debug(_("found new branch changeset %s\n") %
+ short(p))
+ fetch.add(p)
+ base[i] = 1
+ else:
+ self.ui.debug(_("narrowed branch search to %s:%s\n")
+ % (short(p), short(i)))
+ newsearch.append((p, i))
+ break
+ p, f = i, f * 2
+ search = newsearch
+
+ # sanity check our fetch list
+ for f in fetch:
+ if f in m:
+ raise error.RepoError(_("already have changeset ")
+ + short(f[:4]))
+
+ if base.keys() == [nullid]:
+ if force:
+ self.ui.warn(_("warning: repository is unrelated\n"))
+ else:
+ raise util.Abort(_("repository is unrelated"))
+
+ self.ui.debug(_("found new changesets starting at ") +
+ " ".join([short(f) for f in fetch]) + "\n")
+
+ self.ui.debug(_("%d total queries\n") % reqcnt)
+
+ return base.keys(), list(fetch), heads
+
+ def findoutgoing(self, remote, base=None, heads=None, force=False):
+ """Return list of nodes that are roots of subsets not in remote
+
+ If base dict is specified, assume that these nodes and their parents
+ exist on the remote side.
+ If a list of heads is specified, return only nodes which are heads
+ or ancestors of these heads, and return a second element which
+ contains all remote heads which get new children.
+ """
+ if base is None:
+ base = {}
+ self.findincoming(remote, base, heads, force=force)
+
+ self.ui.debug(_("common changesets up to ")
+ + " ".join(map(short, base.keys())) + "\n")
+
+ remain = set(self.changelog.nodemap)
+
+ # prune everything remote has from the tree
+ remain.remove(nullid)
+ remove = base.keys()
+ while remove:
+ n = remove.pop(0)
+ if n in remain:
+ remain.remove(n)
+ for p in self.changelog.parents(n):
+ remove.append(p)
+
+ # find every node whose parents have been pruned
+ subset = []
+ # find every remote head that will get new children
+ updated_heads = set()
+ for n in remain:
+ p1, p2 = self.changelog.parents(n)
+ if p1 not in remain and p2 not in remain:
+ subset.append(n)
+ if heads:
+ if p1 in heads:
+ updated_heads.add(p1)
+ if p2 in heads:
+ updated_heads.add(p2)
+
+ # this is the set of all roots we have to push
+ if heads:
+ return subset, list(updated_heads)
+ else:
+ return subset
+
+ def pull(self, remote, heads=None, force=False):
+ lock = self.lock()
+ try:
+ common, fetch, rheads = self.findcommonincoming(remote, heads=heads,
+ force=force)
+ if fetch == [nullid]:
+ self.ui.status(_("requesting all changes\n"))
+
+ if not fetch:
+ self.ui.status(_("no changes found\n"))
+ return 0
+
+ if heads is None and remote.capable('changegroupsubset'):
+ heads = rheads
+
+ if heads is None:
+ cg = remote.changegroup(fetch, 'pull')
+ else:
+ if not remote.capable('changegroupsubset'):
+ raise util.Abort(_("Partial pull cannot be done because "
+ "other repository doesn't support "
+ "changegroupsubset."))
+ cg = remote.changegroupsubset(fetch, heads, 'pull')
+ return self.addchangegroup(cg, 'pull', remote.url())
+ finally:
+ lock.release()
+
+ def push(self, remote, force=False, revs=None):
+ # there are two ways to push to remote repo:
+ #
+ # addchangegroup assumes local user can lock remote
+ # repo (local filesystem, old ssh servers).
+ #
+ # unbundle assumes local user cannot lock remote repo (new ssh
+ # servers, http servers).
+
+ if remote.capable('unbundle'):
+ return self.push_unbundle(remote, force, revs)
+ return self.push_addchangegroup(remote, force, revs)
+
+ def prepush(self, remote, force, revs):
+ common = {}
+ remote_heads = remote.heads()
+ inc = self.findincoming(remote, common, remote_heads, force=force)
+
+ update, updated_heads = self.findoutgoing(remote, common, remote_heads)
+ if revs is not None:
+ msng_cl, bases, heads = self.changelog.nodesbetween(update, revs)
+ else:
+ bases, heads = update, self.changelog.heads()
+
+ def checkbranch(lheads, rheads, updatelh):
+ '''
+ check whether there are more local heads than remote heads on
+ a specific branch.
+
+ lheads: local branch heads
+ rheads: remote branch heads
+ updatelh: outgoing local branch heads
+ '''
+
+ warn = 0
+
+ if not revs and len(lheads) > len(rheads):
+ warn = 1
+ else:
+ updatelheads = [self.changelog.heads(x, lheads)
+ for x in updatelh]
+ newheads = set(sum(updatelheads, [])) & set(lheads)
+
+ if not newheads:
+ return True
+
+ for r in rheads:
+ if r in self.changelog.nodemap:
+ desc = self.changelog.heads(r, heads)
+ l = [h for h in heads if h in desc]
+ if not l:
+ newheads.add(r)
+ else:
+ newheads.add(r)
+ if len(newheads) > len(rheads):
+ warn = 1
+
+ if warn:
+ if not rheads: # new branch requires --force
+ self.ui.warn(_("abort: push creates new"
+ " remote branch '%s'!\n") %
+ self[updatelh[0]].branch())
+ else:
+ self.ui.warn(_("abort: push creates new remote heads!\n"))
+
+ self.ui.status(_("(did you forget to merge?"
+ " use push -f to force)\n"))
+ return False
+ return True
+
+ if not bases:
+ self.ui.status(_("no changes found\n"))
+ return None, 1
+ elif not force:
+ # Check for each named branch if we're creating new remote heads.
+ # To be a remote head after push, node must be either:
+ # - unknown locally
+ # - a local outgoing head descended from update
+ # - a remote head that's known locally and not
+ # ancestral to an outgoing head
+ #
+ # New named branches cannot be created without --force.
+
+ if remote_heads != [nullid]:
+ if remote.capable('branchmap'):
+ localhds = {}
+ if not revs:
+ localhds = self.branchmap()
+ else:
+ for n in heads:
+ branch = self[n].branch()
+ if branch in localhds:
+ localhds[branch].append(n)
+ else:
+ localhds[branch] = [n]
+
+ remotehds = remote.branchmap()
+
+ for lh in localhds:
+ if lh in remotehds:
+ rheads = remotehds[lh]
+ else:
+ rheads = []
+ lheads = localhds[lh]
+ updatelh = [upd for upd in update
+ if self[upd].branch() == lh]
+ if not updatelh:
+ continue
+ if not checkbranch(lheads, rheads, updatelh):
+ return None, 0
+ else:
+ if not checkbranch(heads, remote_heads, update):
+ return None, 0
+
+ if inc:
+ self.ui.warn(_("note: unsynced remote changes!\n"))
+
+
+ if revs is None:
+ # use the fast path, no race possible on push
+ cg = self._changegroup(common.keys(), 'push')
+ else:
+ cg = self.changegroupsubset(update, revs, 'push')
+ return cg, remote_heads
+
+ def push_addchangegroup(self, remote, force, revs):
+ lock = remote.lock()
+ try:
+ ret = self.prepush(remote, force, revs)
+ if ret[0] is not None:
+ cg, remote_heads = ret
+ return remote.addchangegroup(cg, 'push', self.url())
+ return ret[1]
+ finally:
+ lock.release()
+
+ def push_unbundle(self, remote, force, revs):
+ # local repo finds heads on server, finds out what revs it
+ # must push. once revs transferred, if server finds it has
+ # different heads (someone else won commit/push race), server
+ # aborts.
+
+ ret = self.prepush(remote, force, revs)
+ if ret[0] is not None:
+ cg, remote_heads = ret
+ if force: remote_heads = ['force']
+ return remote.unbundle(cg, remote_heads, 'push')
+ return ret[1]
+
+ def changegroupinfo(self, nodes, source):
+ if self.ui.verbose or source == 'bundle':
+ self.ui.status(_("%d changesets found\n") % len(nodes))
+ if self.ui.debugflag:
+ self.ui.debug(_("list of changesets:\n"))
+ for node in nodes:
+ self.ui.debug("%s\n" % hex(node))
+
+ def changegroupsubset(self, bases, heads, source, extranodes=None):
+ """This function generates a changegroup consisting of all the nodes
+ that are descendents of any of the bases, and ancestors of any of
+ the heads.
+
+ It is fairly complex as determining which filenodes and which
+ manifest nodes need to be included for the changeset to be complete
+ is non-trivial.
+
+ Another wrinkle is doing the reverse, figuring out which changeset in
+ the changegroup a particular filenode or manifestnode belongs to.
+
+ The caller can specify some nodes that must be included in the
+ changegroup using the extranodes argument. It should be a dict
+ where the keys are the filenames (or 1 for the manifest), and the
+ values are lists of (node, linknode) tuples, where node is a wanted
+ node and linknode is the changelog node that should be transmitted as
+ the linkrev.
+ """
+
+ if extranodes is None:
+ # can we go through the fast path ?
+ heads.sort()
+ allheads = self.heads()
+ allheads.sort()
+ if heads == allheads:
+ common = []
+ # parents of bases are known from both sides
+ for n in bases:
+ for p in self.changelog.parents(n):
+ if p != nullid:
+ common.append(p)
+ return self._changegroup(common, source)
+
+ self.hook('preoutgoing', throw=True, source=source)
+
+ # Set up some initial variables
+ # Make it easy to refer to self.changelog
+ cl = self.changelog
+ # msng is short for missing - compute the list of changesets in this
+ # changegroup.
+ msng_cl_lst, bases, heads = cl.nodesbetween(bases, heads)
+ self.changegroupinfo(msng_cl_lst, source)
+ # Some bases may turn out to be superfluous, and some heads may be
+ # too. nodesbetween will return the minimal set of bases and heads
+ # necessary to re-create the changegroup.
+
+ # Known heads are the list of heads that it is assumed the recipient
+ # of this changegroup will know about.
+ knownheads = set()
+ # We assume that all parents of bases are known heads.
+ for n in bases:
+ knownheads.update(cl.parents(n))
+ knownheads.discard(nullid)
+ knownheads = list(knownheads)
+ if knownheads:
+ # Now that we know what heads are known, we can compute which
+ # changesets are known. The recipient must know about all
+ # changesets required to reach the known heads from the null
+ # changeset.
+ has_cl_set, junk, junk = cl.nodesbetween(None, knownheads)
+ junk = None
+ # Transform the list into a set.
+ has_cl_set = set(has_cl_set)
+ else:
+ # If there were no known heads, the recipient cannot be assumed to
+ # know about any changesets.
+ has_cl_set = set()
+
+ # Make it easy to refer to self.manifest
+ mnfst = self.manifest
+ # We don't know which manifests are missing yet
+ msng_mnfst_set = {}
+ # Nor do we know which filenodes are missing.
+ msng_filenode_set = {}
+
+ junk = mnfst.index[len(mnfst) - 1] # Get around a bug in lazyindex
+ junk = None
+
+ # A changeset always belongs to itself, so the changenode lookup
+ # function for a changenode is identity.
+ def identity(x):
+ return x
+
+ # If we determine that a particular file or manifest node must be a
+ # node that the recipient of the changegroup will already have, we can
+ # also assume the recipient will have all the parents. This function
+ # prunes them from the set of missing nodes.
+ def prune_parents(revlog, hasset, msngset):
+ haslst = list(hasset)
+ haslst.sort(key=revlog.rev)
+ for node in haslst:
+ parentlst = [p for p in revlog.parents(node) if p != nullid]
+ while parentlst:
+ n = parentlst.pop()
+ if n not in hasset:
+ hasset.add(n)
+ p = [p for p in revlog.parents(n) if p != nullid]
+ parentlst.extend(p)
+ for n in hasset:
+ msngset.pop(n, None)
+
+ # This is a function generating function used to set up an environment
+ # for the inner function to execute in.
+ def manifest_and_file_collector(changedfileset):
+ # This is an information gathering function that gathers
+ # information from each changeset node that goes out as part of
+ # the changegroup. The information gathered is a list of which
+ # manifest nodes are potentially required (the recipient may
+ # already have them) and total list of all files which were
+ # changed in any changeset in the changegroup.
+ #
+ # We also remember the first changenode we saw any manifest
+ # referenced by so we can later determine which changenode 'owns'
+ # the manifest.
+ def collect_manifests_and_files(clnode):
+ c = cl.read(clnode)
+ for f in c[3]:
+ # This is to make sure we only have one instance of each
+ # filename string for each filename.
+ changedfileset.setdefault(f, f)
+ msng_mnfst_set.setdefault(c[0], clnode)
+ return collect_manifests_and_files
+
+ # Figure out which manifest nodes (of the ones we think might be part
+ # of the changegroup) the recipient must know about and remove them
+ # from the changegroup.
+ def prune_manifests():
+ has_mnfst_set = set()
+ for n in msng_mnfst_set:
+ # If a 'missing' manifest thinks it belongs to a changenode
+ # the recipient is assumed to have, obviously the recipient
+ # must have that manifest.
+ linknode = cl.node(mnfst.linkrev(mnfst.rev(n)))
+ if linknode in has_cl_set:
+ has_mnfst_set.add(n)
+ prune_parents(mnfst, has_mnfst_set, msng_mnfst_set)
+
+ # Use the information collected in collect_manifests_and_files to say
+ # which changenode any manifestnode belongs to.
+ def lookup_manifest_link(mnfstnode):
+ return msng_mnfst_set[mnfstnode]
+
+ # A function generating function that sets up the initial environment
+ # the inner function.
+ def filenode_collector(changedfiles):
+ next_rev = [0]
+ # This gathers information from each manifestnode included in the
+ # changegroup about which filenodes the manifest node references
+ # so we can include those in the changegroup too.
+ #
+ # It also remembers which changenode each filenode belongs to. It
+ # does this by assuming the a filenode belongs to the changenode
+ # the first manifest that references it belongs to.
+ def collect_msng_filenodes(mnfstnode):
+ r = mnfst.rev(mnfstnode)
+ if r == next_rev[0]:
+ # If the last rev we looked at was the one just previous,
+ # we only need to see a diff.
+ deltamf = mnfst.readdelta(mnfstnode)
+ # For each line in the delta
+ for f, fnode in deltamf.iteritems():
+ f = changedfiles.get(f, None)
+ # And if the file is in the list of files we care
+ # about.
+ if f is not None:
+ # Get the changenode this manifest belongs to
+ clnode = msng_mnfst_set[mnfstnode]
+ # Create the set of filenodes for the file if
+ # there isn't one already.
+ ndset = msng_filenode_set.setdefault(f, {})
+ # And set the filenode's changelog node to the
+ # manifest's if it hasn't been set already.
+ ndset.setdefault(fnode, clnode)
+ else:
+ # Otherwise we need a full manifest.
+ m = mnfst.read(mnfstnode)
+ # For every file in we care about.
+ for f in changedfiles:
+ fnode = m.get(f, None)
+ # If it's in the manifest
+ if fnode is not None:
+ # See comments above.
+ clnode = msng_mnfst_set[mnfstnode]
+ ndset = msng_filenode_set.setdefault(f, {})
+ ndset.setdefault(fnode, clnode)
+ # Remember the revision we hope to see next.
+ next_rev[0] = r + 1
+ return collect_msng_filenodes
+
+ # We have a list of filenodes we think we need for a file, lets remove
+ # all those we know the recipient must have.
+ def prune_filenodes(f, filerevlog):
+ msngset = msng_filenode_set[f]
+ hasset = set()
+ # If a 'missing' filenode thinks it belongs to a changenode we
+ # assume the recipient must have, then the recipient must have
+ # that filenode.
+ for n in msngset:
+ clnode = cl.node(filerevlog.linkrev(filerevlog.rev(n)))
+ if clnode in has_cl_set:
+ hasset.add(n)
+ prune_parents(filerevlog, hasset, msngset)
+
+ # A function generator function that sets up the a context for the
+ # inner function.
+ def lookup_filenode_link_func(fname):
+ msngset = msng_filenode_set[fname]
+ # Lookup the changenode the filenode belongs to.
+ def lookup_filenode_link(fnode):
+ return msngset[fnode]
+ return lookup_filenode_link
+
+ # Add the nodes that were explicitly requested.
+ def add_extra_nodes(name, nodes):
+ if not extranodes or name not in extranodes:
+ return
+
+ for node, linknode in extranodes[name]:
+ if node not in nodes:
+ nodes[node] = linknode
+
+ # Now that we have all theses utility functions to help out and
+ # logically divide up the task, generate the group.
+ def gengroup():
+ # The set of changed files starts empty.
+ changedfiles = {}
+ # Create a changenode group generator that will call our functions
+ # back to lookup the owning changenode and collect information.
+ group = cl.group(msng_cl_lst, identity,
+ manifest_and_file_collector(changedfiles))
+ for chnk in group:
+ yield chnk
+
+ # The list of manifests has been collected by the generator
+ # calling our functions back.
+ prune_manifests()
+ add_extra_nodes(1, msng_mnfst_set)
+ msng_mnfst_lst = msng_mnfst_set.keys()
+ # Sort the manifestnodes by revision number.
+ msng_mnfst_lst.sort(key=mnfst.rev)
+ # Create a generator for the manifestnodes that calls our lookup
+ # and data collection functions back.
+ group = mnfst.group(msng_mnfst_lst, lookup_manifest_link,
+ filenode_collector(changedfiles))
+ for chnk in group:
+ yield chnk
+
+ # These are no longer needed, dereference and toss the memory for
+ # them.
+ msng_mnfst_lst = None
+ msng_mnfst_set.clear()
+
+ if extranodes:
+ for fname in extranodes:
+ if isinstance(fname, int):
+ continue
+ msng_filenode_set.setdefault(fname, {})
+ changedfiles[fname] = 1
+ # Go through all our files in order sorted by name.
+ for fname in sorted(changedfiles):
+ filerevlog = self.file(fname)
+ if not len(filerevlog):
+ raise util.Abort(_("empty or missing revlog for %s") % fname)
+ # Toss out the filenodes that the recipient isn't really
+ # missing.
+ if fname in msng_filenode_set:
+ prune_filenodes(fname, filerevlog)
+ add_extra_nodes(fname, msng_filenode_set[fname])
+ msng_filenode_lst = msng_filenode_set[fname].keys()
+ else:
+ msng_filenode_lst = []
+ # If any filenodes are left, generate the group for them,
+ # otherwise don't bother.
+ if len(msng_filenode_lst) > 0:
+ yield changegroup.chunkheader(len(fname))
+ yield fname
+ # Sort the filenodes by their revision #
+ msng_filenode_lst.sort(key=filerevlog.rev)
+ # Create a group generator and only pass in a changenode
+ # lookup function as we need to collect no information
+ # from filenodes.
+ group = filerevlog.group(msng_filenode_lst,
+ lookup_filenode_link_func(fname))
+ for chnk in group:
+ yield chnk
+ if fname in msng_filenode_set:
+ # Don't need this anymore, toss it to free memory.
+ del msng_filenode_set[fname]
+ # Signal that no more groups are left.
+ yield changegroup.closechunk()
+
+ if msng_cl_lst:
+ self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source)
+
+ return util.chunkbuffer(gengroup())
+
+ def changegroup(self, basenodes, source):
+ # to avoid a race we use changegroupsubset() (issue1320)
+ return self.changegroupsubset(basenodes, self.heads(), source)
+
+ def _changegroup(self, common, source):
+ """Generate a changegroup of all nodes that we have that a recipient
+ doesn't.
+
+ This is much easier than the previous function as we can assume that
+ the recipient has any changenode we aren't sending them.
+
+ common is the set of common nodes between remote and self"""
+
+ self.hook('preoutgoing', throw=True, source=source)
+
+ cl = self.changelog
+ nodes = cl.findmissing(common)
+ revset = set([cl.rev(n) for n in nodes])
+ self.changegroupinfo(nodes, source)
+
+ def identity(x):
+ return x
+
+ def gennodelst(log):
+ for r in log:
+ if log.linkrev(r) in revset:
+ yield log.node(r)
+
+ def changed_file_collector(changedfileset):
+ def collect_changed_files(clnode):
+ c = cl.read(clnode)
+ changedfileset.update(c[3])
+ return collect_changed_files
+
+ def lookuprevlink_func(revlog):
+ def lookuprevlink(n):
+ return cl.node(revlog.linkrev(revlog.rev(n)))
+ return lookuprevlink
+
+ def gengroup():
+ # construct a list of all changed files
+ changedfiles = set()
+
+ for chnk in cl.group(nodes, identity,
+ changed_file_collector(changedfiles)):
+ yield chnk
+
+ mnfst = self.manifest
+ nodeiter = gennodelst(mnfst)
+ for chnk in mnfst.group(nodeiter, lookuprevlink_func(mnfst)):
+ yield chnk
+
+ for fname in sorted(changedfiles):
+ filerevlog = self.file(fname)
+ if not len(filerevlog):
+ raise util.Abort(_("empty or missing revlog for %s") % fname)
+ nodeiter = gennodelst(filerevlog)
+ nodeiter = list(nodeiter)
+ if nodeiter:
+ yield changegroup.chunkheader(len(fname))
+ yield fname
+ lookup = lookuprevlink_func(filerevlog)
+ for chnk in filerevlog.group(nodeiter, lookup):
+ yield chnk
+
+ yield changegroup.closechunk()
+
+ if nodes:
+ self.hook('outgoing', node=hex(nodes[0]), source=source)
+
+ return util.chunkbuffer(gengroup())
+
+ def addchangegroup(self, source, srctype, url, emptyok=False):
+ """add changegroup to repo.
+
+ return values:
+ - nothing changed or no source: 0
+ - more heads than before: 1+added heads (2..n)
+ - less heads than before: -1-removed heads (-2..-n)
+ - number of heads stays the same: 1
+ """
+ def csmap(x):
+ self.ui.debug(_("add changeset %s\n") % short(x))
+ return len(cl)
+
+ def revmap(x):
+ return cl.rev(x)
+
+ if not source:
+ return 0
+
+ self.hook('prechangegroup', throw=True, source=srctype, url=url)
+
+ changesets = files = revisions = 0
+
+ # write changelog data to temp files so concurrent readers will not see
+ # inconsistent view
+ cl = self.changelog
+ cl.delayupdate()
+ oldheads = len(cl.heads())
+
+ tr = self.transaction()
+ try:
+ trp = weakref.proxy(tr)
+ # pull off the changeset group
+ self.ui.status(_("adding changesets\n"))
+ clstart = len(cl)
+ chunkiter = changegroup.chunkiter(source)
+ if cl.addgroup(chunkiter, csmap, trp) is None and not emptyok:
+ raise util.Abort(_("received changelog group is empty"))
+ clend = len(cl)
+ changesets = clend - clstart
+
+ # pull off the manifest group
+ self.ui.status(_("adding manifests\n"))
+ chunkiter = changegroup.chunkiter(source)
+ # no need to check for empty manifest group here:
+ # if the result of the merge of 1 and 2 is the same in 3 and 4,
+ # no new manifest will be created and the manifest group will
+ # be empty during the pull
+ self.manifest.addgroup(chunkiter, revmap, trp)
+
+ # process the files
+ self.ui.status(_("adding file changes\n"))
+ while 1:
+ f = changegroup.getchunk(source)
+ if not f:
+ break
+ self.ui.debug(_("adding %s revisions\n") % f)
+ fl = self.file(f)
+ o = len(fl)
+ chunkiter = changegroup.chunkiter(source)
+ if fl.addgroup(chunkiter, revmap, trp) is None:
+ raise util.Abort(_("received file revlog group is empty"))
+ revisions += len(fl) - o
+ files += 1
+
+ newheads = len(cl.heads())
+ heads = ""
+ if oldheads and newheads != oldheads:
+ heads = _(" (%+d heads)") % (newheads - oldheads)
+
+ self.ui.status(_("added %d changesets"
+ " with %d changes to %d files%s\n")
+ % (changesets, revisions, files, heads))
+
+ if changesets > 0:
+ p = lambda: cl.writepending() and self.root or ""
+ self.hook('pretxnchangegroup', throw=True,
+ node=hex(cl.node(clstart)), source=srctype,
+ url=url, pending=p)
+
+ # make changelog see real files again
+ cl.finalize(trp)
+
+ tr.close()
+ finally:
+ del tr
+
+ if changesets > 0:
+ # forcefully update the on-disk branch cache
+ self.ui.debug(_("updating the branch cache\n"))
+ self.branchtags()
+ self.hook("changegroup", node=hex(cl.node(clstart)),
+ source=srctype, url=url)
+
+ for i in xrange(clstart, clend):
+ self.hook("incoming", node=hex(cl.node(i)),
+ source=srctype, url=url)
+
+ # never return 0 here:
+ if newheads < oldheads:
+ return newheads - oldheads - 1
+ else:
+ return newheads - oldheads + 1
+
+
+ def stream_in(self, remote):
+ fp = remote.stream_out()
+ l = fp.readline()
+ try:
+ resp = int(l)
+ except ValueError:
+ raise error.ResponseError(
+ _('Unexpected response from remote server:'), l)
+ if resp == 1:
+ raise util.Abort(_('operation forbidden by server'))
+ elif resp == 2:
+ raise util.Abort(_('locking the remote repository failed'))
+ elif resp != 0:
+ raise util.Abort(_('the server sent an unknown error code'))
+ self.ui.status(_('streaming all changes\n'))
+ l = fp.readline()
+ try:
+ total_files, total_bytes = map(int, l.split(' ', 1))
+ except (ValueError, TypeError):
+ raise error.ResponseError(
+ _('Unexpected response from remote server:'), l)
+ self.ui.status(_('%d files to transfer, %s of data\n') %
+ (total_files, util.bytecount(total_bytes)))
+ start = time.time()
+ for i in xrange(total_files):
+ # XXX doesn't support '\n' or '\r' in filenames
+ l = fp.readline()
+ try:
+ name, size = l.split('\0', 1)
+ size = int(size)
+ except (ValueError, TypeError):
+ raise error.ResponseError(
+ _('Unexpected response from remote server:'), l)
+ self.ui.debug(_('adding %s (%s)\n') % (name, util.bytecount(size)))
+ # for backwards compat, name was partially encoded
+ ofp = self.sopener(store.decodedir(name), 'w')
+ for chunk in util.filechunkiter(fp, limit=size):
+ ofp.write(chunk)
+ ofp.close()
+ elapsed = time.time() - start
+ if elapsed <= 0:
+ elapsed = 0.001
+ self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %
+ (util.bytecount(total_bytes), elapsed,
+ util.bytecount(total_bytes / elapsed)))
+ self.invalidate()
+ return len(self.heads()) + 1
+
+ def clone(self, remote, heads=[], stream=False):
+ '''clone remote repository.
+
+ keyword arguments:
+ heads: list of revs to clone (forces use of pull)
+ stream: use streaming clone if possible'''
+
+ # now, all clients that can request uncompressed clones can
+ # read repo formats supported by all servers that can serve
+ # them.
+
+ # if revlog format changes, client will have to check version
+ # and format flags on "stream" capability, and use
+ # uncompressed only if compatible.
+
+ if stream and not heads and remote.capable('stream'):
+ return self.stream_in(remote)
+ return self.pull(remote, heads)
+
+# used to avoid circular references so destructors work
+def aftertrans(files):
+ renamefiles = [tuple(t) for t in files]
+ def a():
+ for src, dest in renamefiles:
+ util.rename(src, dest)
+ return a
+
+def instance(ui, path, create):
+ return localrepository(ui, util.drop_scheme('file', path), create)
+
+def islocal(path):
+ return True
diff --git a/sys/src/cmd/hg/mercurial/lock.py b/sys/src/cmd/hg/mercurial/lock.py
new file mode 100644
index 000000000..a3d116e6a
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/lock.py
@@ -0,0 +1,137 @@
+# lock.py - simple advisory locking scheme for mercurial
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import util, error
+import errno, os, socket, time
+import warnings
+
+class lock(object):
+ '''An advisory lock held by one process to control access to a set
+ of files. Non-cooperating processes or incorrectly written scripts
+ can ignore Mercurial's locking scheme and stomp all over the
+ repository, so don't do that.
+
+ Typically used via localrepository.lock() to lock the repository
+ store (.hg/store/) or localrepository.wlock() to lock everything
+ else under .hg/.'''
+
+ # lock is symlink on platforms that support it, file on others.
+
+ # symlink is used because create of directory entry and contents
+ # are atomic even over nfs.
+
+ # old-style lock: symlink to pid
+ # new-style lock: symlink to hostname:pid
+
+ _host = None
+
+ def __init__(self, file, timeout=-1, releasefn=None, desc=None):
+ self.f = file
+ self.held = 0
+ self.timeout = timeout
+ self.releasefn = releasefn
+ self.desc = desc
+ self.lock()
+
+ def __del__(self):
+ if self.held:
+ warnings.warn("use lock.release instead of del lock",
+ category=DeprecationWarning,
+ stacklevel=2)
+
+ # ensure the lock will be removed
+ # even if recursive locking did occur
+ self.held = 1
+
+ self.release()
+
+ def lock(self):
+ timeout = self.timeout
+ while 1:
+ try:
+ self.trylock()
+ return 1
+ except error.LockHeld, inst:
+ if timeout != 0:
+ time.sleep(1)
+ if timeout > 0:
+ timeout -= 1
+ continue
+ raise error.LockHeld(errno.ETIMEDOUT, inst.filename, self.desc,
+ inst.locker)
+
+ def trylock(self):
+ if self.held:
+ self.held += 1
+ return
+ if lock._host is None:
+ lock._host = socket.gethostname()
+ lockname = '%s:%s' % (lock._host, os.getpid())
+ while not self.held:
+ try:
+ util.makelock(lockname, self.f)
+ self.held = 1
+ except (OSError, IOError), why:
+ if why.errno == errno.EEXIST:
+ locker = self.testlock()
+ if locker is not None:
+ raise error.LockHeld(errno.EAGAIN, self.f, self.desc,
+ locker)
+ else:
+ raise error.LockUnavailable(why.errno, why.strerror,
+ why.filename, self.desc)
+
+ def testlock(self):
+ """return id of locker if lock is valid, else None.
+
+ If old-style lock, we cannot tell what machine locker is on.
+ with new-style lock, if locker is on this machine, we can
+ see if locker is alive. If locker is on this machine but
+ not alive, we can safely break lock.
+
+ The lock file is only deleted when None is returned.
+
+ """
+ locker = util.readlock(self.f)
+ try:
+ host, pid = locker.split(":", 1)
+ except ValueError:
+ return locker
+ if host != lock._host:
+ return locker
+ try:
+ pid = int(pid)
+ except:
+ return locker
+ if util.testpid(pid):
+ return locker
+ # if locker dead, break lock. must do this with another lock
+ # held, or can race and break valid lock.
+ try:
+ l = lock(self.f + '.break')
+ l.trylock()
+ os.unlink(self.f)
+ l.release()
+ except error.LockError:
+ return locker
+
+ def release(self):
+ if self.held > 1:
+ self.held -= 1
+ elif self.held is 1:
+ self.held = 0
+ if self.releasefn:
+ self.releasefn()
+ try:
+ os.unlink(self.f)
+ except: pass
+
+def release(*locks):
+ for lock in locks:
+ if lock is not None:
+ lock.release()
+
diff --git a/sys/src/cmd/hg/mercurial/lock.pyc b/sys/src/cmd/hg/mercurial/lock.pyc
new file mode 100644
index 000000000..c3546fda6
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/lock.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/lsprof.py b/sys/src/cmd/hg/mercurial/lsprof.py
new file mode 100644
index 000000000..07f9425ff
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/lsprof.py
@@ -0,0 +1,113 @@
+#! /usr/bin/env python
+
+import sys
+from _lsprof import Profiler, profiler_entry
+
+__all__ = ['profile', 'Stats']
+
+def profile(f, *args, **kwds):
+ """XXX docstring"""
+ p = Profiler()
+ p.enable(subcalls=True, builtins=True)
+ try:
+ f(*args, **kwds)
+ finally:
+ p.disable()
+ return Stats(p.getstats())
+
+
+class Stats(object):
+ """XXX docstring"""
+
+ def __init__(self, data):
+ self.data = data
+
+ def sort(self, crit="inlinetime"):
+ """XXX docstring"""
+ if crit not in profiler_entry.__dict__:
+ raise ValueError("Can't sort by %s" % crit)
+ self.data.sort(key=lambda x: getattr(x, crit), reverse=True)
+ for e in self.data:
+ if e.calls:
+ e.calls.sort(key=lambda x: getattr(x, crit), reverse=True)
+
+ def pprint(self, top=None, file=None, limit=None, climit=None):
+ """XXX docstring"""
+ if file is None:
+ file = sys.stdout
+ d = self.data
+ if top is not None:
+ d = d[:top]
+ cols = "% 12s %12s %11.4f %11.4f %s\n"
+ hcols = "% 12s %12s %12s %12s %s\n"
+ file.write(hcols % ("CallCount", "Recursive", "Total(ms)",
+ "Inline(ms)", "module:lineno(function)"))
+ count = 0
+ for e in d:
+ file.write(cols % (e.callcount, e.reccallcount, e.totaltime,
+ e.inlinetime, label(e.code)))
+ count += 1
+ if limit is not None and count == limit:
+ return
+ ccount = 0
+ if e.calls:
+ for se in e.calls:
+ file.write(cols % ("+%s" % se.callcount, se.reccallcount,
+ se.totaltime, se.inlinetime,
+ "+%s" % label(se.code)))
+ count += 1
+ ccount += 1
+ if limit is not None and count == limit:
+ return
+ if climit is not None and ccount == climit:
+ break
+
+ def freeze(self):
+ """Replace all references to code objects with string
+ descriptions; this makes it possible to pickle the instance."""
+
+ # this code is probably rather ickier than it needs to be!
+ for i in range(len(self.data)):
+ e = self.data[i]
+ if not isinstance(e.code, str):
+ self.data[i] = type(e)((label(e.code),) + e[1:])
+ if e.calls:
+ for j in range(len(e.calls)):
+ se = e.calls[j]
+ if not isinstance(se.code, str):
+ e.calls[j] = type(se)((label(se.code),) + se[1:])
+
+_fn2mod = {}
+
+def label(code):
+ if isinstance(code, str):
+ return code
+ try:
+ mname = _fn2mod[code.co_filename]
+ except KeyError:
+ for k, v in list(sys.modules.iteritems()):
+ if v is None:
+ continue
+ if not hasattr(v, '__file__'):
+ continue
+ if not isinstance(v.__file__, str):
+ continue
+ if v.__file__.startswith(code.co_filename):
+ mname = _fn2mod[code.co_filename] = k
+ break
+ else:
+ mname = _fn2mod[code.co_filename] = '<%s>'%code.co_filename
+
+ return '%s:%d(%s)' % (mname, code.co_firstlineno, code.co_name)
+
+
+if __name__ == '__main__':
+ import os
+ sys.argv = sys.argv[1:]
+ if not sys.argv:
+ print >> sys.stderr, "usage: lsprof.py <script> <arguments...>"
+ sys.exit(2)
+ sys.path.insert(0, os.path.abspath(os.path.dirname(sys.argv[0])))
+ stats = profile(execfile, sys.argv[0], globals(), locals())
+ stats.sort()
+ stats.pprint()
diff --git a/sys/src/cmd/hg/mercurial/lsprofcalltree.py b/sys/src/cmd/hg/mercurial/lsprofcalltree.py
new file mode 100644
index 000000000..358b951d1
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/lsprofcalltree.py
@@ -0,0 +1,86 @@
+"""
+lsprofcalltree.py - lsprof output which is readable by kcachegrind
+
+Authors:
+ * David Allouche <david <at> allouche.net>
+ * Jp Calderone & Itamar Shtull-Trauring
+ * Johan Dahlin
+
+This software may be used and distributed according to the terms
+of the GNU General Public License, incorporated herein by reference.
+"""
+
+def label(code):
+ if isinstance(code, str):
+ return '~' + code # built-in functions ('~' sorts at the end)
+ else:
+ return '%s %s:%d' % (code.co_name,
+ code.co_filename,
+ code.co_firstlineno)
+
+class KCacheGrind(object):
+ def __init__(self, profiler):
+ self.data = profiler.getstats()
+ self.out_file = None
+
+ def output(self, out_file):
+ self.out_file = out_file
+ print >> out_file, 'events: Ticks'
+ self._print_summary()
+ for entry in self.data:
+ self._entry(entry)
+
+ def _print_summary(self):
+ max_cost = 0
+ for entry in self.data:
+ totaltime = int(entry.totaltime * 1000)
+ max_cost = max(max_cost, totaltime)
+ print >> self.out_file, 'summary: %d' % (max_cost,)
+
+ def _entry(self, entry):
+ out_file = self.out_file
+
+ code = entry.code
+ #print >> out_file, 'ob=%s' % (code.co_filename,)
+ if isinstance(code, str):
+ print >> out_file, 'fi=~'
+ else:
+ print >> out_file, 'fi=%s' % (code.co_filename,)
+ print >> out_file, 'fn=%s' % (label(code),)
+
+ inlinetime = int(entry.inlinetime * 1000)
+ if isinstance(code, str):
+ print >> out_file, '0 ', inlinetime
+ else:
+ print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime)
+
+ # recursive calls are counted in entry.calls
+ if entry.calls:
+ calls = entry.calls
+ else:
+ calls = []
+
+ if isinstance(code, str):
+ lineno = 0
+ else:
+ lineno = code.co_firstlineno
+
+ for subentry in calls:
+ self._subentry(lineno, subentry)
+ print >> out_file
+
+ def _subentry(self, lineno, subentry):
+ out_file = self.out_file
+ code = subentry.code
+ #print >> out_file, 'cob=%s' % (code.co_filename,)
+ print >> out_file, 'cfn=%s' % (label(code),)
+ if isinstance(code, str):
+ print >> out_file, 'cfi=~'
+ print >> out_file, 'calls=%d 0' % (subentry.callcount,)
+ else:
+ print >> out_file, 'cfi=%s' % (code.co_filename,)
+ print >> out_file, 'calls=%d %d' % (
+ subentry.callcount, code.co_firstlineno)
+
+ totaltime = int(subentry.totaltime * 1000)
+ print >> out_file, '%d %d' % (lineno, totaltime)
diff --git a/sys/src/cmd/hg/mercurial/mail.py b/sys/src/cmd/hg/mercurial/mail.py
new file mode 100644
index 000000000..3d8222c4f
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/mail.py
@@ -0,0 +1,190 @@
+# mail.py - mail sending bits for mercurial
+#
+# Copyright 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import util, encoding
+import os, smtplib, socket, quopri
+import email.Header, email.MIMEText, email.Utils
+
+def _smtp(ui):
+ '''build an smtp connection and return a function to send mail'''
+ local_hostname = ui.config('smtp', 'local_hostname')
+ s = smtplib.SMTP(local_hostname=local_hostname)
+ mailhost = ui.config('smtp', 'host')
+ if not mailhost:
+ raise util.Abort(_('no [smtp]host in hgrc - cannot send mail'))
+ mailport = int(ui.config('smtp', 'port', 25))
+ ui.note(_('sending mail: smtp host %s, port %s\n') %
+ (mailhost, mailport))
+ s.connect(host=mailhost, port=mailport)
+ if ui.configbool('smtp', 'tls'):
+ if not hasattr(socket, 'ssl'):
+ raise util.Abort(_("can't use TLS: Python SSL support "
+ "not installed"))
+ ui.note(_('(using tls)\n'))
+ s.ehlo()
+ s.starttls()
+ s.ehlo()
+ username = ui.config('smtp', 'username')
+ password = ui.config('smtp', 'password')
+ if username and not password:
+ password = ui.getpass()
+ if username and password:
+ ui.note(_('(authenticating to mail server as %s)\n') %
+ (username))
+ try:
+ s.login(username, password)
+ except smtplib.SMTPException, inst:
+ raise util.Abort(inst)
+
+ def send(sender, recipients, msg):
+ try:
+ return s.sendmail(sender, recipients, msg)
+ except smtplib.SMTPRecipientsRefused, inst:
+ recipients = [r[1] for r in inst.recipients.values()]
+ raise util.Abort('\n' + '\n'.join(recipients))
+ except smtplib.SMTPException, inst:
+ raise util.Abort(inst)
+
+ return send
+
+def _sendmail(ui, sender, recipients, msg):
+ '''send mail using sendmail.'''
+ program = ui.config('email', 'method')
+ cmdline = '%s -f %s %s' % (program, util.email(sender),
+ ' '.join(map(util.email, recipients)))
+ ui.note(_('sending mail: %s\n') % cmdline)
+ fp = util.popen(cmdline, 'w')
+ fp.write(msg)
+ ret = fp.close()
+ if ret:
+ raise util.Abort('%s %s' % (
+ os.path.basename(program.split(None, 1)[0]),
+ util.explain_exit(ret)[0]))
+
+def connect(ui):
+ '''make a mail connection. return a function to send mail.
+ call as sendmail(sender, list-of-recipients, msg).'''
+ if ui.config('email', 'method', 'smtp') == 'smtp':
+ return _smtp(ui)
+ return lambda s, r, m: _sendmail(ui, s, r, m)
+
+def sendmail(ui, sender, recipients, msg):
+ send = connect(ui)
+ return send(sender, recipients, msg)
+
+def validateconfig(ui):
+ '''determine if we have enough config data to try sending email.'''
+ method = ui.config('email', 'method', 'smtp')
+ if method == 'smtp':
+ if not ui.config('smtp', 'host'):
+ raise util.Abort(_('smtp specified as email transport, '
+ 'but no smtp host configured'))
+ else:
+ if not util.find_exe(method):
+ raise util.Abort(_('%r specified as email transport, '
+ 'but not in PATH') % method)
+
+def mimetextpatch(s, subtype='plain', display=False):
+ '''If patch in utf-8 transfer-encode it.'''
+
+ enc = None
+ for line in s.splitlines():
+ if len(line) > 950:
+ s = quopri.encodestring(s)
+ enc = "quoted-printable"
+ break
+
+ cs = 'us-ascii'
+ if not display:
+ try:
+ s.decode('us-ascii')
+ except UnicodeDecodeError:
+ try:
+ s.decode('utf-8')
+ cs = 'utf-8'
+ except UnicodeDecodeError:
+ # We'll go with us-ascii as a fallback.
+ pass
+
+ msg = email.MIMEText.MIMEText(s, subtype, cs)
+ if enc:
+ del msg['Content-Transfer-Encoding']
+ msg['Content-Transfer-Encoding'] = enc
+ return msg
+
+def _charsets(ui):
+ '''Obtains charsets to send mail parts not containing patches.'''
+ charsets = [cs.lower() for cs in ui.configlist('email', 'charsets')]
+ fallbacks = [encoding.fallbackencoding.lower(),
+ encoding.encoding.lower(), 'utf-8']
+ for cs in fallbacks: # find unique charsets while keeping order
+ if cs not in charsets:
+ charsets.append(cs)
+ return [cs for cs in charsets if not cs.endswith('ascii')]
+
+def _encode(ui, s, charsets):
+ '''Returns (converted) string, charset tuple.
+ Finds out best charset by cycling through sendcharsets in descending
+ order. Tries both encoding and fallbackencoding for input. Only as
+ last resort send as is in fake ascii.
+ Caveat: Do not use for mail parts containing patches!'''
+ try:
+ s.decode('ascii')
+ except UnicodeDecodeError:
+ sendcharsets = charsets or _charsets(ui)
+ for ics in (encoding.encoding, encoding.fallbackencoding):
+ try:
+ u = s.decode(ics)
+ except UnicodeDecodeError:
+ continue
+ for ocs in sendcharsets:
+ try:
+ return u.encode(ocs), ocs
+ except UnicodeEncodeError:
+ pass
+ except LookupError:
+ ui.warn(_('ignoring invalid sendcharset: %s\n') % ocs)
+ # if ascii, or all conversion attempts fail, send (broken) ascii
+ return s, 'us-ascii'
+
+def headencode(ui, s, charsets=None, display=False):
+ '''Returns RFC-2047 compliant header from given string.'''
+ if not display:
+ # split into words?
+ s, cs = _encode(ui, s, charsets)
+ return str(email.Header.Header(s, cs))
+ return s
+
+def addressencode(ui, address, charsets=None, display=False):
+ '''Turns address into RFC-2047 compliant header.'''
+ if display or not address:
+ return address or ''
+ name, addr = email.Utils.parseaddr(address)
+ name = headencode(ui, name, charsets)
+ try:
+ acc, dom = addr.split('@')
+ acc = acc.encode('ascii')
+ dom = dom.encode('idna')
+ addr = '%s@%s' % (acc, dom)
+ except UnicodeDecodeError:
+ raise util.Abort(_('invalid email address: %s') % addr)
+ except ValueError:
+ try:
+ # too strict?
+ addr = addr.encode('ascii')
+ except UnicodeDecodeError:
+ raise util.Abort(_('invalid local address: %s') % addr)
+ return email.Utils.formataddr((name, addr))
+
+def mimeencode(ui, s, charsets=None, display=False):
+ '''creates mime text object, encodes it if needed, and sets
+ charset and transfer-encoding accordingly.'''
+ cs = 'us-ascii'
+ if not display:
+ s, cs = _encode(ui, s, charsets)
+ return email.MIMEText.MIMEText(s, 'plain', cs)
diff --git a/sys/src/cmd/hg/mercurial/manifest.py b/sys/src/cmd/hg/mercurial/manifest.py
new file mode 100644
index 000000000..7f7558403
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/manifest.py
@@ -0,0 +1,201 @@
+# manifest.py - manifest revision class for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import mdiff, parsers, error, revlog
+import array, struct
+
+class manifestdict(dict):
+ def __init__(self, mapping=None, flags=None):
+ if mapping is None: mapping = {}
+ if flags is None: flags = {}
+ dict.__init__(self, mapping)
+ self._flags = flags
+ def flags(self, f):
+ return self._flags.get(f, "")
+ def set(self, f, flags):
+ self._flags[f] = flags
+ def copy(self):
+ return manifestdict(dict.copy(self), dict.copy(self._flags))
+
+class manifest(revlog.revlog):
+ def __init__(self, opener):
+ self.mapcache = None
+ self.listcache = None
+ revlog.revlog.__init__(self, opener, "00manifest.i")
+
+ def parse(self, lines):
+ mfdict = manifestdict()
+ parsers.parse_manifest(mfdict, mfdict._flags, lines)
+ return mfdict
+
+ def readdelta(self, node):
+ r = self.rev(node)
+ return self.parse(mdiff.patchtext(self.revdiff(r - 1, r)))
+
+ def read(self, node):
+ if node == revlog.nullid:
+ return manifestdict() # don't upset local cache
+ if self.mapcache and self.mapcache[0] == node:
+ return self.mapcache[1]
+ text = self.revision(node)
+ self.listcache = array.array('c', text)
+ mapping = self.parse(text)
+ self.mapcache = (node, mapping)
+ return mapping
+
+ def _search(self, m, s, lo=0, hi=None):
+ '''return a tuple (start, end) that says where to find s within m.
+
+ If the string is found m[start:end] are the line containing
+ that string. If start == end the string was not found and
+ they indicate the proper sorted insertion point. This was
+ taken from bisect_left, and modified to find line start/end as
+ it goes along.
+
+ m should be a buffer or a string
+ s is a string'''
+ def advance(i, c):
+ while i < lenm and m[i] != c:
+ i += 1
+ return i
+ if not s:
+ return (lo, lo)
+ lenm = len(m)
+ if not hi:
+ hi = lenm
+ while lo < hi:
+ mid = (lo + hi) // 2
+ start = mid
+ while start > 0 and m[start-1] != '\n':
+ start -= 1
+ end = advance(start, '\0')
+ if m[start:end] < s:
+ # we know that after the null there are 40 bytes of sha1
+ # this translates to the bisect lo = mid + 1
+ lo = advance(end + 40, '\n') + 1
+ else:
+ # this translates to the bisect hi = mid
+ hi = start
+ end = advance(lo, '\0')
+ found = m[lo:end]
+ if cmp(s, found) == 0:
+ # we know that after the null there are 40 bytes of sha1
+ end = advance(end + 40, '\n')
+ return (lo, end+1)
+ else:
+ return (lo, lo)
+
+ def find(self, node, f):
+ '''look up entry for a single file efficiently.
+ return (node, flags) pair if found, (None, None) if not.'''
+ if self.mapcache and node == self.mapcache[0]:
+ return self.mapcache[1].get(f), self.mapcache[1].flags(f)
+ text = self.revision(node)
+ start, end = self._search(text, f)
+ if start == end:
+ return None, None
+ l = text[start:end]
+ f, n = l.split('\0')
+ return revlog.bin(n[:40]), n[40:-1]
+
+ def add(self, map, transaction, link, p1=None, p2=None,
+ changed=None):
+ # apply the changes collected during the bisect loop to our addlist
+ # return a delta suitable for addrevision
+ def addlistdelta(addlist, x):
+ # start from the bottom up
+ # so changes to the offsets don't mess things up.
+ i = len(x)
+ while i > 0:
+ i -= 1
+ start = x[i][0]
+ end = x[i][1]
+ if x[i][2]:
+ addlist[start:end] = array.array('c', x[i][2])
+ else:
+ del addlist[start:end]
+ return "".join([struct.pack(">lll", d[0], d[1], len(d[2])) + d[2]
+ for d in x ])
+
+ def checkforbidden(l):
+ for f in l:
+ if '\n' in f or '\r' in f:
+ raise error.RevlogError(
+ _("'\\n' and '\\r' disallowed in filenames: %r") % f)
+
+ # if we're using the listcache, make sure it is valid and
+ # parented by the same node we're diffing against
+ if not (changed and self.listcache and p1 and self.mapcache[0] == p1):
+ files = sorted(map)
+ checkforbidden(files)
+
+ # if this is changed to support newlines in filenames,
+ # be sure to check the templates/ dir again (especially *-raw.tmpl)
+ hex, flags = revlog.hex, map.flags
+ text = ["%s\000%s%s\n" % (f, hex(map[f]), flags(f))
+ for f in files]
+ self.listcache = array.array('c', "".join(text))
+ cachedelta = None
+ else:
+ addlist = self.listcache
+
+ checkforbidden(changed[0])
+ # combine the changed lists into one list for sorting
+ work = [[x, 0] for x in changed[0]]
+ work[len(work):] = [[x, 1] for x in changed[1]]
+ work.sort()
+
+ delta = []
+ dstart = None
+ dend = None
+ dline = [""]
+ start = 0
+ # zero copy representation of addlist as a buffer
+ addbuf = buffer(addlist)
+
+ # start with a readonly loop that finds the offset of
+ # each line and creates the deltas
+ for w in work:
+ f = w[0]
+ # bs will either be the index of the item or the insert point
+ start, end = self._search(addbuf, f, start)
+ if w[1] == 0:
+ l = "%s\000%s%s\n" % (f, revlog.hex(map[f]), map.flags(f))
+ else:
+ l = ""
+ if start == end and w[1] == 1:
+ # item we want to delete was not found, error out
+ raise AssertionError(
+ _("failed to remove %s from manifest") % f)
+ if dstart != None and dstart <= start and dend >= start:
+ if dend < end:
+ dend = end
+ if l:
+ dline.append(l)
+ else:
+ if dstart != None:
+ delta.append([dstart, dend, "".join(dline)])
+ dstart = start
+ dend = end
+ dline = [l]
+
+ if dstart != None:
+ delta.append([dstart, dend, "".join(dline)])
+ # apply the delta to the addlist, and get a delta for addrevision
+ cachedelta = addlistdelta(addlist, delta)
+
+ # the delta is only valid if we've been processing the tip revision
+ if self.mapcache[0] != self.tip():
+ cachedelta = None
+ self.listcache = addlist
+
+ n = self.addrevision(buffer(self.listcache), transaction, link,
+ p1, p2, cachedelta)
+ self.mapcache = (n, map)
+
+ return n
diff --git a/sys/src/cmd/hg/mercurial/match.py b/sys/src/cmd/hg/mercurial/match.py
new file mode 100644
index 000000000..34b6fc1e8
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/match.py
@@ -0,0 +1,249 @@
+# match.py - filename matching
+#
+# Copyright 2008, 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import re
+import util
+
+class match(object):
+ def __init__(self, root, cwd, patterns, include=[], exclude=[],
+ default='glob', exact=False):
+ """build an object to match a set of file patterns
+
+ arguments:
+ root - the canonical root of the tree you're matching against
+ cwd - the current working directory, if relevant
+ patterns - patterns to find
+ include - patterns to include
+ exclude - patterns to exclude
+ default - if a pattern in names has no explicit type, assume this one
+ exact - patterns are actually literals
+
+ a pattern is one of:
+ 'glob:<glob>' - a glob relative to cwd
+ 're:<regexp>' - a regular expression
+ 'path:<path>' - a path relative to canonroot
+ 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
+ 'relpath:<path>' - a path relative to cwd
+ 'relre:<regexp>' - a regexp that needn't match the start of a name
+ '<something>' - a pattern of the specified default type
+ """
+
+ self._root = root
+ self._cwd = cwd
+ self._files = []
+ self._anypats = bool(include or exclude)
+
+ if include:
+ im = _buildmatch(_normalize(include, 'glob', root, cwd), '(?:/|$)')
+ if exclude:
+ em = _buildmatch(_normalize(exclude, 'glob', root, cwd), '(?:/|$)')
+ if exact:
+ self._files = patterns
+ pm = self.exact
+ elif patterns:
+ pats = _normalize(patterns, default, root, cwd)
+ self._files = _roots(pats)
+ self._anypats = self._anypats or _anypats(pats)
+ pm = _buildmatch(pats, '$')
+
+ if patterns or exact:
+ if include:
+ if exclude:
+ m = lambda f: im(f) and not em(f) and pm(f)
+ else:
+ m = lambda f: im(f) and pm(f)
+ else:
+ if exclude:
+ m = lambda f: not em(f) and pm(f)
+ else:
+ m = pm
+ else:
+ if include:
+ if exclude:
+ m = lambda f: im(f) and not em(f)
+ else:
+ m = im
+ else:
+ if exclude:
+ m = lambda f: not em(f)
+ else:
+ m = lambda f: True
+
+ self.matchfn = m
+ self._fmap = set(self._files)
+
+ def __call__(self, fn):
+ return self.matchfn(fn)
+ def __iter__(self):
+ for f in self._files:
+ yield f
+ def bad(self, f, msg):
+ '''callback for each explicit file that can't be
+ found/accessed, with an error message
+ '''
+ pass
+ def dir(self, f):
+ pass
+ def missing(self, f):
+ pass
+ def exact(self, f):
+ return f in self._fmap
+ def rel(self, f):
+ return util.pathto(self._root, self._cwd, f)
+ def files(self):
+ return self._files
+ def anypats(self):
+ return self._anypats
+
+class exact(match):
+ def __init__(self, root, cwd, files):
+ match.__init__(self, root, cwd, files, exact = True)
+
+class always(match):
+ def __init__(self, root, cwd):
+ match.__init__(self, root, cwd, [])
+
+def patkind(pat):
+ return _patsplit(pat, None)[0]
+
+def _patsplit(pat, default):
+ """Split a string into an optional pattern kind prefix and the
+ actual pattern."""
+ if ':' in pat:
+ kind, val = pat.split(':', 1)
+ if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre'):
+ return kind, val
+ return default, pat
+
+def _globre(pat):
+ "convert a glob pattern into a regexp"
+ i, n = 0, len(pat)
+ res = ''
+ group = 0
+ escape = re.escape
+ def peek(): return i < n and pat[i]
+ while i < n:
+ c = pat[i]
+ i = i+1
+ if c not in '*?[{},\\':
+ res += escape(c)
+ elif c == '*':
+ if peek() == '*':
+ i += 1
+ res += '.*'
+ else:
+ res += '[^/]*'
+ elif c == '?':
+ res += '.'
+ elif c == '[':
+ j = i
+ if j < n and pat[j] in '!]':
+ j += 1
+ while j < n and pat[j] != ']':
+ j += 1
+ if j >= n:
+ res += '\\['
+ else:
+ stuff = pat[i:j].replace('\\','\\\\')
+ i = j + 1
+ if stuff[0] == '!':
+ stuff = '^' + stuff[1:]
+ elif stuff[0] == '^':
+ stuff = '\\' + stuff
+ res = '%s[%s]' % (res, stuff)
+ elif c == '{':
+ group += 1
+ res += '(?:'
+ elif c == '}' and group:
+ res += ')'
+ group -= 1
+ elif c == ',' and group:
+ res += '|'
+ elif c == '\\':
+ p = peek()
+ if p:
+ i += 1
+ res += escape(p)
+ else:
+ res += escape(c)
+ else:
+ res += escape(c)
+ return res
+
+def _regex(kind, name, tail):
+ '''convert a pattern into a regular expression'''
+ if not name:
+ return ''
+ if kind == 're':
+ return name
+ elif kind == 'path':
+ return '^' + re.escape(name) + '(?:/|$)'
+ elif kind == 'relglob':
+ return '(?:|.*/)' + _globre(name) + tail
+ elif kind == 'relpath':
+ return re.escape(name) + '(?:/|$)'
+ elif kind == 'relre':
+ if name.startswith('^'):
+ return name
+ return '.*' + name
+ return _globre(name) + tail
+
+def _buildmatch(pats, tail):
+ """build a matching function from a set of patterns"""
+ try:
+ pat = '(?:%s)' % '|'.join([_regex(k, p, tail) for (k, p) in pats])
+ if len(pat) > 20000:
+ raise OverflowError()
+ return re.compile(pat).match
+ except OverflowError:
+ # We're using a Python with a tiny regex engine and we
+ # made it explode, so we'll divide the pattern list in two
+ # until it works
+ l = len(pats)
+ if l < 2:
+ raise
+ a, b = _buildmatch(pats[:l//2], tail), _buildmatch(pats[l//2:], tail)
+ return lambda s: a(s) or b(s)
+ except re.error:
+ for k, p in pats:
+ try:
+ re.compile('(?:%s)' % _regex(k, p, tail))
+ except re.error:
+ raise util.Abort("invalid pattern (%s): %s" % (k, p))
+ raise util.Abort("invalid pattern")
+
+def _normalize(names, default, root, cwd):
+ pats = []
+ for kind, name in [_patsplit(p, default) for p in names]:
+ if kind in ('glob', 'relpath'):
+ name = util.canonpath(root, cwd, name)
+ elif kind in ('relglob', 'path'):
+ name = util.normpath(name)
+
+ pats.append((kind, name))
+ return pats
+
+def _roots(patterns):
+ r = []
+ for kind, name in patterns:
+ if kind == 'glob': # find the non-glob prefix
+ root = []
+ for p in name.split('/'):
+ if '[' in p or '{' in p or '*' in p or '?' in p:
+ break
+ root.append(p)
+ r.append('/'.join(root) or '.')
+ elif kind in ('relpath', 'path'):
+ r.append(name or '.')
+ elif kind == 'relglob':
+ r.append('.')
+ return r
+
+def _anypats(patterns):
+ for kind, name in patterns:
+ if kind in ('glob', 're', 'relglob', 'relre'):
+ return True
diff --git a/sys/src/cmd/hg/mercurial/mdiff.py b/sys/src/cmd/hg/mercurial/mdiff.py
new file mode 100644
index 000000000..44d4d4560
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/mdiff.py
@@ -0,0 +1,269 @@
+# mdiff.py - diff and patch routines for mercurial
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import bdiff, mpatch, util
+import re, struct
+
+def splitnewlines(text):
+ '''like str.splitlines, but only split on newlines.'''
+ lines = [l + '\n' for l in text.split('\n')]
+ if lines:
+ if lines[-1] == '\n':
+ lines.pop()
+ else:
+ lines[-1] = lines[-1][:-1]
+ return lines
+
+class diffopts(object):
+ '''context is the number of context lines
+ text treats all files as text
+ showfunc enables diff -p output
+ git enables the git extended patch format
+ nodates removes dates from diff headers
+ ignorews ignores all whitespace changes in the diff
+ ignorewsamount ignores changes in the amount of whitespace
+ ignoreblanklines ignores changes whose lines are all blank'''
+
+ defaults = {
+ 'context': 3,
+ 'text': False,
+ 'showfunc': False,
+ 'git': False,
+ 'nodates': False,
+ 'ignorews': False,
+ 'ignorewsamount': False,
+ 'ignoreblanklines': False,
+ }
+
+ __slots__ = defaults.keys()
+
+ def __init__(self, **opts):
+ for k in self.__slots__:
+ v = opts.get(k)
+ if v is None:
+ v = self.defaults[k]
+ setattr(self, k, v)
+
+ try:
+ self.context = int(self.context)
+ except ValueError:
+ raise util.Abort(_('diff context lines count must be '
+ 'an integer, not %r') % self.context)
+
+defaultopts = diffopts()
+
+def wsclean(opts, text):
+ if opts.ignorews:
+ text = re.sub('[ \t]+', '', text)
+ elif opts.ignorewsamount:
+ text = re.sub('[ \t]+', ' ', text)
+ text = re.sub('[ \t]+\n', '\n', text)
+ if opts.ignoreblanklines:
+ text = re.sub('\n+', '', text)
+ return text
+
+def diffline(revs, a, b, opts):
+ parts = ['diff']
+ if opts.git:
+ parts.append('--git')
+ if revs and not opts.git:
+ parts.append(' '.join(["-r %s" % rev for rev in revs]))
+ if opts.git:
+ parts.append('a/%s' % a)
+ parts.append('b/%s' % b)
+ else:
+ parts.append(a)
+ return ' '.join(parts) + '\n'
+
+def unidiff(a, ad, b, bd, fn1, fn2, r=None, opts=defaultopts):
+ def datetag(date, addtab=True):
+ if not opts.git and not opts.nodates:
+ return '\t%s\n' % date
+ if addtab and ' ' in fn1:
+ return '\t\n'
+ return '\n'
+
+ if not a and not b: return ""
+ epoch = util.datestr((0, 0))
+
+ if not opts.text and (util.binary(a) or util.binary(b)):
+ if a and b and len(a) == len(b) and a == b:
+ return ""
+ l = ['Binary file %s has changed\n' % fn1]
+ elif not a:
+ b = splitnewlines(b)
+ if a is None:
+ l1 = '--- /dev/null%s' % datetag(epoch, False)
+ else:
+ l1 = "--- %s%s" % ("a/" + fn1, datetag(ad))
+ l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd))
+ l3 = "@@ -0,0 +1,%d @@\n" % len(b)
+ l = [l1, l2, l3] + ["+" + e for e in b]
+ elif not b:
+ a = splitnewlines(a)
+ l1 = "--- %s%s" % ("a/" + fn1, datetag(ad))
+ if b is None:
+ l2 = '+++ /dev/null%s' % datetag(epoch, False)
+ else:
+ l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd))
+ l3 = "@@ -1,%d +0,0 @@\n" % len(a)
+ l = [l1, l2, l3] + ["-" + e for e in a]
+ else:
+ al = splitnewlines(a)
+ bl = splitnewlines(b)
+ l = list(bunidiff(a, b, al, bl, "a/" + fn1, "b/" + fn2, opts=opts))
+ if not l: return ""
+ # difflib uses a space, rather than a tab
+ l[0] = "%s%s" % (l[0][:-2], datetag(ad))
+ l[1] = "%s%s" % (l[1][:-2], datetag(bd))
+
+ for ln in xrange(len(l)):
+ if l[ln][-1] != '\n':
+ l[ln] += "\n\ No newline at end of file\n"
+
+ if r:
+ l.insert(0, diffline(r, fn1, fn2, opts))
+
+ return "".join(l)
+
+# somewhat self contained replacement for difflib.unified_diff
+# t1 and t2 are the text to be diffed
+# l1 and l2 are the text broken up into lines
+# header1 and header2 are the filenames for the diff output
+def bunidiff(t1, t2, l1, l2, header1, header2, opts=defaultopts):
+ def contextend(l, len):
+ ret = l + opts.context
+ if ret > len:
+ ret = len
+ return ret
+
+ def contextstart(l):
+ ret = l - opts.context
+ if ret < 0:
+ return 0
+ return ret
+
+ def yieldhunk(hunk, header):
+ if header:
+ for x in header:
+ yield x
+ (astart, a2, bstart, b2, delta) = hunk
+ aend = contextend(a2, len(l1))
+ alen = aend - astart
+ blen = b2 - bstart + aend - a2
+
+ func = ""
+ if opts.showfunc:
+ # walk backwards from the start of the context
+ # to find a line starting with an alphanumeric char.
+ for x in xrange(astart - 1, -1, -1):
+ t = l1[x].rstrip()
+ if funcre.match(t):
+ func = ' ' + t[:40]
+ break
+
+ yield "@@ -%d,%d +%d,%d @@%s\n" % (astart + 1, alen,
+ bstart + 1, blen, func)
+ for x in delta:
+ yield x
+ for x in xrange(a2, aend):
+ yield ' ' + l1[x]
+
+ header = [ "--- %s\t\n" % header1, "+++ %s\t\n" % header2 ]
+
+ if opts.showfunc:
+ funcre = re.compile('\w')
+
+ # bdiff.blocks gives us the matching sequences in the files. The loop
+ # below finds the spaces between those matching sequences and translates
+ # them into diff output.
+ #
+ diff = bdiff.blocks(t1, t2)
+ hunk = None
+ for i, s1 in enumerate(diff):
+ # The first match is special.
+ # we've either found a match starting at line 0 or a match later
+ # in the file. If it starts later, old and new below will both be
+ # empty and we'll continue to the next match.
+ if i > 0:
+ s = diff[i-1]
+ else:
+ s = [0, 0, 0, 0]
+ delta = []
+ a1 = s[1]
+ a2 = s1[0]
+ b1 = s[3]
+ b2 = s1[2]
+
+ old = l1[a1:a2]
+ new = l2[b1:b2]
+
+ # bdiff sometimes gives huge matches past eof, this check eats them,
+ # and deals with the special first match case described above
+ if not old and not new:
+ continue
+
+ if opts.ignorews or opts.ignorewsamount or opts.ignoreblanklines:
+ if wsclean(opts, "".join(old)) == wsclean(opts, "".join(new)):
+ continue
+
+ astart = contextstart(a1)
+ bstart = contextstart(b1)
+ prev = None
+ if hunk:
+ # join with the previous hunk if it falls inside the context
+ if astart < hunk[1] + opts.context + 1:
+ prev = hunk
+ astart = hunk[1]
+ bstart = hunk[3]
+ else:
+ for x in yieldhunk(hunk, header):
+ yield x
+ # we only want to yield the header if the files differ, and
+ # we only want to yield it once.
+ header = None
+ if prev:
+ # we've joined the previous hunk, record the new ending points.
+ hunk[1] = a2
+ hunk[3] = b2
+ delta = hunk[4]
+ else:
+ # create a new hunk
+ hunk = [ astart, a2, bstart, b2, delta ]
+
+ delta[len(delta):] = [ ' ' + x for x in l1[astart:a1] ]
+ delta[len(delta):] = [ '-' + x for x in old ]
+ delta[len(delta):] = [ '+' + x for x in new ]
+
+ if hunk:
+ for x in yieldhunk(hunk, header):
+ yield x
+
+def patchtext(bin):
+ pos = 0
+ t = []
+ while pos < len(bin):
+ p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
+ pos += 12
+ t.append(bin[pos:pos + l])
+ pos += l
+ return "".join(t)
+
+def patch(a, bin):
+ return mpatch.patches(a, [bin])
+
+# similar to difflib.SequenceMatcher.get_matching_blocks
+def get_matching_blocks(a, b):
+ return [(d[0], d[2], d[1] - d[0]) for d in bdiff.blocks(a, b)]
+
+def trivialdiffheader(length):
+ return struct.pack(">lll", 0, 0, length)
+
+patches = mpatch.patches
+patchedsize = mpatch.patchedsize
+textdiff = bdiff.bdiff
diff --git a/sys/src/cmd/hg/mercurial/merge.py b/sys/src/cmd/hg/mercurial/merge.py
new file mode 100644
index 000000000..fc04d040d
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/merge.py
@@ -0,0 +1,481 @@
+# merge.py - directory-level update/merge handling for Mercurial
+#
+# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import nullid, nullrev, hex, bin
+from i18n import _
+import util, filemerge, copies, subrepo
+import errno, os, shutil
+
+class mergestate(object):
+ '''track 3-way merge state of individual files'''
+ def __init__(self, repo):
+ self._repo = repo
+ self._read()
+ def reset(self, node=None):
+ self._state = {}
+ if node:
+ self._local = node
+ shutil.rmtree(self._repo.join("merge"), True)
+ def _read(self):
+ self._state = {}
+ try:
+ localnode = None
+ f = self._repo.opener("merge/state")
+ for i, l in enumerate(f):
+ if i == 0:
+ localnode = l[:-1]
+ else:
+ bits = l[:-1].split("\0")
+ self._state[bits[0]] = bits[1:]
+ self._local = bin(localnode)
+ except IOError, err:
+ if err.errno != errno.ENOENT:
+ raise
+ def _write(self):
+ f = self._repo.opener("merge/state", "w")
+ f.write(hex(self._local) + "\n")
+ for d, v in self._state.iteritems():
+ f.write("\0".join([d] + v) + "\n")
+ def add(self, fcl, fco, fca, fd, flags):
+ hash = util.sha1(fcl.path()).hexdigest()
+ self._repo.opener("merge/" + hash, "w").write(fcl.data())
+ self._state[fd] = ['u', hash, fcl.path(), fca.path(),
+ hex(fca.filenode()), fco.path(), flags]
+ self._write()
+ def __contains__(self, dfile):
+ return dfile in self._state
+ def __getitem__(self, dfile):
+ return self._state[dfile][0]
+ def __iter__(self):
+ l = self._state.keys()
+ l.sort()
+ for f in l:
+ yield f
+ def mark(self, dfile, state):
+ self._state[dfile][0] = state
+ self._write()
+ def resolve(self, dfile, wctx, octx):
+ if self[dfile] == 'r':
+ return 0
+ state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
+ f = self._repo.opener("merge/" + hash)
+ self._repo.wwrite(dfile, f.read(), flags)
+ fcd = wctx[dfile]
+ fco = octx[ofile]
+ fca = self._repo.filectx(afile, fileid=anode)
+ r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
+ if not r:
+ self.mark(dfile, 'r')
+ return r
+
+def _checkunknown(wctx, mctx):
+ "check for collisions between unknown files and files in mctx"
+ for f in wctx.unknown():
+ if f in mctx and mctx[f].cmp(wctx[f].data()):
+ raise util.Abort(_("untracked file in working directory differs"
+ " from file in requested revision: '%s'") % f)
+
+def _checkcollision(mctx):
+ "check for case folding collisions in the destination context"
+ folded = {}
+ for fn in mctx:
+ fold = fn.lower()
+ if fold in folded:
+ raise util.Abort(_("case-folding collision between %s and %s")
+ % (fn, folded[fold]))
+ folded[fold] = fn
+
+def _forgetremoved(wctx, mctx, branchmerge):
+ """
+ Forget removed files
+
+ If we're jumping between revisions (as opposed to merging), and if
+ neither the working directory nor the target rev has the file,
+ then we need to remove it from the dirstate, to prevent the
+ dirstate from listing the file when it is no longer in the
+ manifest.
+
+ If we're merging, and the other revision has removed a file
+ that is not present in the working directory, we need to mark it
+ as removed.
+ """
+
+ action = []
+ state = branchmerge and 'r' or 'f'
+ for f in wctx.deleted():
+ if f not in mctx:
+ action.append((f, state))
+
+ if not branchmerge:
+ for f in wctx.removed():
+ if f not in mctx:
+ action.append((f, "f"))
+
+ return action
+
+def manifestmerge(repo, p1, p2, pa, overwrite, partial):
+ """
+ Merge p1 and p2 with ancestor ma and generate merge action list
+
+ overwrite = whether we clobber working files
+ partial = function to filter file lists
+ """
+
+ def fmerge(f, f2, fa):
+ """merge flags"""
+ a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
+ if m == n: # flags agree
+ return m # unchanged
+ if m and n and not a: # flags set, don't agree, differ from parent
+ r = repo.ui.promptchoice(
+ _(" conflicting flags for %s\n"
+ "(n)one, e(x)ec or sym(l)ink?") % f,
+ (_("&None"), _("E&xec"), _("Sym&link")), 0)
+ if r == 1: return "x" # Exec
+ if r == 2: return "l" # Symlink
+ return ""
+ if m and m != a: # changed from a to m
+ return m
+ if n and n != a: # changed from a to n
+ return n
+ return '' # flag was cleared
+
+ def act(msg, m, f, *args):
+ repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
+ action.append((f, m) + args)
+
+ action, copy = [], {}
+
+ if overwrite:
+ pa = p1
+ elif pa == p2: # backwards
+ pa = p1.p1()
+ elif pa and repo.ui.configbool("merge", "followcopies", True):
+ dirs = repo.ui.configbool("merge", "followdirs", True)
+ copy, diverge = copies.copies(repo, p1, p2, pa, dirs)
+ for of, fl in diverge.iteritems():
+ act("divergent renames", "dr", of, fl)
+
+ repo.ui.note(_("resolving manifests\n"))
+ repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
+ repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
+
+ m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest()
+ copied = set(copy.values())
+
+ # Compare manifests
+ for f, n in m1.iteritems():
+ if partial and not partial(f):
+ continue
+ if f in m2:
+ rflags = fmerge(f, f, f)
+ a = ma.get(f, nullid)
+ if n == m2[f] or m2[f] == a: # same or local newer
+ if m1.flags(f) != rflags:
+ act("update permissions", "e", f, rflags)
+ elif n == a: # remote newer
+ act("remote is newer", "g", f, rflags)
+ else: # both changed
+ act("versions differ", "m", f, f, f, rflags, False)
+ elif f in copied: # files we'll deal with on m2 side
+ pass
+ elif f in copy:
+ f2 = copy[f]
+ if f2 not in m2: # directory rename
+ act("remote renamed directory to " + f2, "d",
+ f, None, f2, m1.flags(f))
+ else: # case 2 A,B/B/B or case 4,21 A/B/B
+ act("local copied/moved to " + f2, "m",
+ f, f2, f, fmerge(f, f2, f2), False)
+ elif f in ma: # clean, a different, no remote
+ if n != ma[f]:
+ if repo.ui.promptchoice(
+ _(" local changed %s which remote deleted\n"
+ "use (c)hanged version or (d)elete?") % f,
+ (_("&Changed"), _("&Delete")), 0):
+ act("prompt delete", "r", f)
+ else:
+ act("prompt keep", "a", f)
+ elif n[20:] == "a": # added, no remote
+ act("remote deleted", "f", f)
+ elif n[20:] != "u":
+ act("other deleted", "r", f)
+
+ for f, n in m2.iteritems():
+ if partial and not partial(f):
+ continue
+ if f in m1 or f in copied: # files already visited
+ continue
+ if f in copy:
+ f2 = copy[f]
+ if f2 not in m1: # directory rename
+ act("local renamed directory to " + f2, "d",
+ None, f, f2, m2.flags(f))
+ elif f2 in m2: # rename case 1, A/A,B/A
+ act("remote copied to " + f, "m",
+ f2, f, f, fmerge(f2, f, f2), False)
+ else: # case 3,20 A/B/A
+ act("remote moved to " + f, "m",
+ f2, f, f, fmerge(f2, f, f2), True)
+ elif f not in ma:
+ act("remote created", "g", f, m2.flags(f))
+ elif n != ma[f]:
+ if repo.ui.promptchoice(
+ _("remote changed %s which local deleted\n"
+ "use (c)hanged version or leave (d)eleted?") % f,
+ (_("&Changed"), _("&Deleted")), 0) == 0:
+ act("prompt recreating", "g", f, m2.flags(f))
+
+ return action
+
+def actionkey(a):
+ return a[1] == 'r' and -1 or 0, a
+
+def applyupdates(repo, action, wctx, mctx):
+ "apply the merge action list to the working directory"
+
+ updated, merged, removed, unresolved = 0, 0, 0, 0
+ ms = mergestate(repo)
+ ms.reset(wctx.parents()[0].node())
+ moves = []
+ action.sort(key=actionkey)
+ substate = wctx.substate # prime
+
+ # prescan for merges
+ for a in action:
+ f, m = a[:2]
+ if m == 'm': # merge
+ f2, fd, flags, move = a[2:]
+ if f == '.hgsubstate': # merged internally
+ continue
+ repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd))
+ fcl = wctx[f]
+ fco = mctx[f2]
+ fca = fcl.ancestor(fco) or repo.filectx(f, fileid=nullrev)
+ ms.add(fcl, fco, fca, fd, flags)
+ if f != fd and move:
+ moves.append(f)
+
+ # remove renamed files after safely stored
+ for f in moves:
+ if util.lexists(repo.wjoin(f)):
+ repo.ui.debug(_("removing %s\n") % f)
+ os.unlink(repo.wjoin(f))
+
+ audit_path = util.path_auditor(repo.root)
+
+ for a in action:
+ f, m = a[:2]
+ if f and f[0] == "/":
+ continue
+ if m == "r": # remove
+ repo.ui.note(_("removing %s\n") % f)
+ audit_path(f)
+ if f == '.hgsubstate': # subrepo states need updating
+ subrepo.submerge(repo, wctx, mctx, wctx)
+ try:
+ util.unlink(repo.wjoin(f))
+ except OSError, inst:
+ if inst.errno != errno.ENOENT:
+ repo.ui.warn(_("update failed to remove %s: %s!\n") %
+ (f, inst.strerror))
+ removed += 1
+ elif m == "m": # merge
+ if f == '.hgsubstate': # subrepo states need updating
+ subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx))
+ continue
+ f2, fd, flags, move = a[2:]
+ r = ms.resolve(fd, wctx, mctx)
+ if r is not None and r > 0:
+ unresolved += 1
+ else:
+ if r is None:
+ updated += 1
+ else:
+ merged += 1
+ util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
+ if f != fd and move and util.lexists(repo.wjoin(f)):
+ repo.ui.debug(_("removing %s\n") % f)
+ os.unlink(repo.wjoin(f))
+ elif m == "g": # get
+ flags = a[2]
+ repo.ui.note(_("getting %s\n") % f)
+ t = mctx.filectx(f).data()
+ repo.wwrite(f, t, flags)
+ updated += 1
+ if f == '.hgsubstate': # subrepo states need updating
+ subrepo.submerge(repo, wctx, mctx, wctx)
+ elif m == "d": # directory rename
+ f2, fd, flags = a[2:]
+ if f:
+ repo.ui.note(_("moving %s to %s\n") % (f, fd))
+ t = wctx.filectx(f).data()
+ repo.wwrite(fd, t, flags)
+ util.unlink(repo.wjoin(f))
+ if f2:
+ repo.ui.note(_("getting %s to %s\n") % (f2, fd))
+ t = mctx.filectx(f2).data()
+ repo.wwrite(fd, t, flags)
+ updated += 1
+ elif m == "dr": # divergent renames
+ fl = a[2]
+ repo.ui.warn(_("warning: detected divergent renames of %s to:\n") % f)
+ for nf in fl:
+ repo.ui.warn(" %s\n" % nf)
+ elif m == "e": # exec
+ flags = a[2]
+ util.set_flags(repo.wjoin(f), 'l' in flags, 'x' in flags)
+
+ return updated, merged, removed, unresolved
+
+def recordupdates(repo, action, branchmerge):
+ "record merge actions to the dirstate"
+
+ for a in action:
+ f, m = a[:2]
+ if m == "r": # remove
+ if branchmerge:
+ repo.dirstate.remove(f)
+ else:
+ repo.dirstate.forget(f)
+ elif m == "a": # re-add
+ if not branchmerge:
+ repo.dirstate.add(f)
+ elif m == "f": # forget
+ repo.dirstate.forget(f)
+ elif m == "e": # exec change
+ repo.dirstate.normallookup(f)
+ elif m == "g": # get
+ if branchmerge:
+ repo.dirstate.normaldirty(f)
+ else:
+ repo.dirstate.normal(f)
+ elif m == "m": # merge
+ f2, fd, flag, move = a[2:]
+ if branchmerge:
+ # We've done a branch merge, mark this file as merged
+ # so that we properly record the merger later
+ repo.dirstate.merge(fd)
+ if f != f2: # copy/rename
+ if move:
+ repo.dirstate.remove(f)
+ if f != fd:
+ repo.dirstate.copy(f, fd)
+ else:
+ repo.dirstate.copy(f2, fd)
+ else:
+ # We've update-merged a locally modified file, so
+ # we set the dirstate to emulate a normal checkout
+ # of that file some time in the past. Thus our
+ # merge will appear as a normal local file
+ # modification.
+ repo.dirstate.normallookup(fd)
+ if move:
+ repo.dirstate.forget(f)
+ elif m == "d": # directory rename
+ f2, fd, flag = a[2:]
+ if not f2 and f not in repo.dirstate:
+ # untracked file moved
+ continue
+ if branchmerge:
+ repo.dirstate.add(fd)
+ if f:
+ repo.dirstate.remove(f)
+ repo.dirstate.copy(f, fd)
+ if f2:
+ repo.dirstate.copy(f2, fd)
+ else:
+ repo.dirstate.normal(fd)
+ if f:
+ repo.dirstate.forget(f)
+
+def update(repo, node, branchmerge, force, partial):
+ """
+ Perform a merge between the working directory and the given node
+
+ branchmerge = whether to merge between branches
+ force = whether to force branch merging or file overwriting
+ partial = a function to filter file lists (dirstate not updated)
+ """
+
+ wlock = repo.wlock()
+ try:
+ wc = repo[None]
+ if node is None:
+ # tip of current branch
+ try:
+ node = repo.branchtags()[wc.branch()]
+ except KeyError:
+ if wc.branch() == "default": # no default branch!
+ node = repo.lookup("tip") # update to tip
+ else:
+ raise util.Abort(_("branch %s not found") % wc.branch())
+ overwrite = force and not branchmerge
+ pl = wc.parents()
+ p1, p2 = pl[0], repo[node]
+ pa = p1.ancestor(p2)
+ fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
+ fastforward = False
+
+ ### check phase
+ if not overwrite and len(pl) > 1:
+ raise util.Abort(_("outstanding uncommitted merges"))
+ if branchmerge:
+ if pa == p2:
+ raise util.Abort(_("can't merge with ancestor"))
+ elif pa == p1:
+ if p1.branch() != p2.branch():
+ fastforward = True
+ else:
+ raise util.Abort(_("nothing to merge (use 'hg update'"
+ " or check 'hg heads')"))
+ if not force and (wc.files() or wc.deleted()):
+ raise util.Abort(_("outstanding uncommitted changes "
+ "(use 'hg status' to list changes)"))
+ elif not overwrite:
+ if pa == p1 or pa == p2: # linear
+ pass # all good
+ elif p1.branch() == p2.branch():
+ if wc.files() or wc.deleted():
+ raise util.Abort(_("crosses branches (use 'hg merge' or "
+ "'hg update -C' to discard changes)"))
+ raise util.Abort(_("crosses branches (use 'hg merge' "
+ "or 'hg update -C')"))
+ elif wc.files() or wc.deleted():
+ raise util.Abort(_("crosses named branches (use "
+ "'hg update -C' to discard changes)"))
+ else:
+ # Allow jumping branches if there are no changes
+ overwrite = True
+
+ ### calculate phase
+ action = []
+ if not force:
+ _checkunknown(wc, p2)
+ if not util.checkcase(repo.path):
+ _checkcollision(p2)
+ action += _forgetremoved(wc, p2, branchmerge)
+ action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
+
+ ### apply phase
+ if not branchmerge: # just jump to the new rev
+ fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
+ if not partial:
+ repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
+
+ stats = applyupdates(repo, action, wc, p2)
+
+ if not partial:
+ recordupdates(repo, action, branchmerge)
+ repo.dirstate.setparents(fp1, fp2)
+ if not branchmerge and not fastforward:
+ repo.dirstate.setbranch(p2.branch())
+ repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
+
+ return stats
+ finally:
+ wlock.release()
diff --git a/sys/src/cmd/hg/mercurial/minirst.py b/sys/src/cmd/hg/mercurial/minirst.py
new file mode 100644
index 000000000..201c21d99
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/minirst.py
@@ -0,0 +1,343 @@
+# minirst.py - minimal reStructuredText parser
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+"""simplified reStructuredText parser.
+
+This parser knows just enough about reStructuredText to parse the
+Mercurial docstrings.
+
+It cheats in a major way: nested blocks are not really nested. They
+are just indented blocks that look like they are nested. This relies
+on the user to keep the right indentation for the blocks.
+
+It only supports a small subset of reStructuredText:
+
+- paragraphs
+
+- definition lists (must use ' ' to indent definitions)
+
+- lists (items must start with '-')
+
+- field lists (colons cannot be escaped)
+
+- literal blocks
+
+- option lists (supports only long options without arguments)
+
+- inline markup is not recognized at all.
+"""
+
+import re, sys, textwrap
+
+
+def findblocks(text):
+ """Find continuous blocks of lines in text.
+
+ Returns a list of dictionaries representing the blocks. Each block
+ has an 'indent' field and a 'lines' field.
+ """
+ blocks = [[]]
+ lines = text.splitlines()
+ for line in lines:
+ if line.strip():
+ blocks[-1].append(line)
+ elif blocks[-1]:
+ blocks.append([])
+ if not blocks[-1]:
+ del blocks[-1]
+
+ for i, block in enumerate(blocks):
+ indent = min((len(l) - len(l.lstrip())) for l in block)
+ blocks[i] = dict(indent=indent, lines=[l[indent:] for l in block])
+ return blocks
+
+
+def findliteralblocks(blocks):
+ """Finds literal blocks and adds a 'type' field to the blocks.
+
+ Literal blocks are given the type 'literal', all other blocks are
+ given type the 'paragraph'.
+ """
+ i = 0
+ while i < len(blocks):
+ # Searching for a block that looks like this:
+ #
+ # +------------------------------+
+ # | paragraph |
+ # | (ends with "::") |
+ # +------------------------------+
+ # +---------------------------+
+ # | indented literal block |
+ # +---------------------------+
+ blocks[i]['type'] = 'paragraph'
+ if blocks[i]['lines'][-1].endswith('::') and i+1 < len(blocks):
+ indent = blocks[i]['indent']
+ adjustment = blocks[i+1]['indent'] - indent
+
+ if blocks[i]['lines'] == ['::']:
+ # Expanded form: remove block
+ del blocks[i]
+ i -= 1
+ elif blocks[i]['lines'][-1].endswith(' ::'):
+ # Partially minimized form: remove space and both
+ # colons.
+ blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-3]
+ else:
+ # Fully minimized form: remove just one colon.
+ blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-1]
+
+ # List items are formatted with a hanging indent. We must
+ # correct for this here while we still have the original
+ # information on the indentation of the subsequent literal
+ # blocks available.
+ if blocks[i]['lines'][0].startswith('- '):
+ indent += 2
+ adjustment -= 2
+
+ # Mark the following indented blocks.
+ while i+1 < len(blocks) and blocks[i+1]['indent'] > indent:
+ blocks[i+1]['type'] = 'literal'
+ blocks[i+1]['indent'] -= adjustment
+ i += 1
+ i += 1
+ return blocks
+
+
+def findsections(blocks):
+ """Finds sections.
+
+ The blocks must have a 'type' field, i.e., they should have been
+ run through findliteralblocks first.
+ """
+ for block in blocks:
+ # Searching for a block that looks like this:
+ #
+ # +------------------------------+
+ # | Section title |
+ # | ------------- |
+ # +------------------------------+
+ if (block['type'] == 'paragraph' and
+ len(block['lines']) == 2 and
+ block['lines'][1] == '-' * len(block['lines'][0])):
+ block['type'] = 'section'
+ return blocks
+
+
+def findbulletlists(blocks):
+ """Finds bullet lists.
+
+ The blocks must have a 'type' field, i.e., they should have been
+ run through findliteralblocks first.
+ """
+ i = 0
+ while i < len(blocks):
+ # Searching for a paragraph that looks like this:
+ #
+ # +------+-----------------------+
+ # | "- " | list item |
+ # +------| (body elements)+ |
+ # +-----------------------+
+ if (blocks[i]['type'] == 'paragraph' and
+ blocks[i]['lines'][0].startswith('- ')):
+ items = []
+ for line in blocks[i]['lines']:
+ if line.startswith('- '):
+ items.append(dict(type='bullet', lines=[],
+ indent=blocks[i]['indent']))
+ line = line[2:]
+ items[-1]['lines'].append(line)
+ blocks[i:i+1] = items
+ i += len(items) - 1
+ i += 1
+ return blocks
+
+
+_optionre = re.compile(r'^(--[a-z-]+)((?:[ =][a-zA-Z][\w-]*)? +)(.*)$')
+def findoptionlists(blocks):
+ """Finds option lists.
+
+ The blocks must have a 'type' field, i.e., they should have been
+ run through findliteralblocks first.
+ """
+ i = 0
+ while i < len(blocks):
+ # Searching for a paragraph that looks like this:
+ #
+ # +----------------------------+-------------+
+ # | "--" option " " | description |
+ # +-------+--------------------+ |
+ # | (body elements)+ |
+ # +----------------------------------+
+ if (blocks[i]['type'] == 'paragraph' and
+ _optionre.match(blocks[i]['lines'][0])):
+ options = []
+ for line in blocks[i]['lines']:
+ m = _optionre.match(line)
+ if m:
+ option, arg, rest = m.groups()
+ width = len(option) + len(arg)
+ options.append(dict(type='option', lines=[],
+ indent=blocks[i]['indent'],
+ width=width))
+ options[-1]['lines'].append(line)
+ blocks[i:i+1] = options
+ i += len(options) - 1
+ i += 1
+ return blocks
+
+
+_fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):( +)(.*)')
+def findfieldlists(blocks):
+ """Finds fields lists.
+
+ The blocks must have a 'type' field, i.e., they should have been
+ run through findliteralblocks first.
+ """
+ i = 0
+ while i < len(blocks):
+ # Searching for a paragraph that looks like this:
+ #
+ #
+ # +--------------------+----------------------+
+ # | ":" field name ":" | field body |
+ # +-------+------------+ |
+ # | (body elements)+ |
+ # +-----------------------------------+
+ if (blocks[i]['type'] == 'paragraph' and
+ _fieldre.match(blocks[i]['lines'][0])):
+ indent = blocks[i]['indent']
+ fields = []
+ for line in blocks[i]['lines']:
+ m = _fieldre.match(line)
+ if m:
+ key, spaces, rest = m.groups()
+ width = 2 + len(key) + len(spaces)
+ fields.append(dict(type='field', lines=[],
+ indent=indent, width=width))
+ # Turn ":foo: bar" into "foo bar".
+ line = '%s %s%s' % (key, spaces, rest)
+ fields[-1]['lines'].append(line)
+ blocks[i:i+1] = fields
+ i += len(fields) - 1
+ i += 1
+ return blocks
+
+
+def finddefinitionlists(blocks):
+ """Finds definition lists.
+
+ The blocks must have a 'type' field, i.e., they should have been
+ run through findliteralblocks first.
+ """
+ i = 0
+ while i < len(blocks):
+ # Searching for a paragraph that looks like this:
+ #
+ # +----------------------------+
+ # | term |
+ # +--+-------------------------+--+
+ # | definition |
+ # | (body elements)+ |
+ # +----------------------------+
+ if (blocks[i]['type'] == 'paragraph' and
+ len(blocks[i]['lines']) > 1 and
+ not blocks[i]['lines'][0].startswith(' ') and
+ blocks[i]['lines'][1].startswith(' ')):
+ definitions = []
+ for line in blocks[i]['lines']:
+ if not line.startswith(' '):
+ definitions.append(dict(type='definition', lines=[],
+ indent=blocks[i]['indent']))
+ definitions[-1]['lines'].append(line)
+ definitions[-1]['hang'] = len(line) - len(line.lstrip())
+ blocks[i:i+1] = definitions
+ i += len(definitions) - 1
+ i += 1
+ return blocks
+
+
+def addmargins(blocks):
+ """Adds empty blocks for vertical spacing.
+
+ This groups bullets, options, and definitions together with no vertical
+ space between them, and adds an empty block between all other blocks.
+ """
+ i = 1
+ while i < len(blocks):
+ if (blocks[i]['type'] == blocks[i-1]['type'] and
+ blocks[i]['type'] in ('bullet', 'option', 'field', 'definition')):
+ i += 1
+ else:
+ blocks.insert(i, dict(lines=[''], indent=0, type='margin'))
+ i += 2
+ return blocks
+
+
+def formatblock(block, width):
+ """Format a block according to width."""
+ indent = ' ' * block['indent']
+ if block['type'] == 'margin':
+ return ''
+ elif block['type'] == 'literal':
+ indent += ' '
+ return indent + ('\n' + indent).join(block['lines'])
+ elif block['type'] == 'section':
+ return indent + ('\n' + indent).join(block['lines'])
+ elif block['type'] == 'definition':
+ term = indent + block['lines'][0]
+ defindent = indent + block['hang'] * ' '
+ text = ' '.join(map(str.strip, block['lines'][1:]))
+ return "%s\n%s" % (term, textwrap.fill(text, width=width,
+ initial_indent=defindent,
+ subsequent_indent=defindent))
+ else:
+ initindent = subindent = indent
+ text = ' '.join(map(str.strip, block['lines']))
+ if block['type'] == 'bullet':
+ initindent = indent + '- '
+ subindent = indent + ' '
+ elif block['type'] in ('option', 'field'):
+ subindent = indent + block['width'] * ' '
+
+ return textwrap.fill(text, width=width,
+ initial_indent=initindent,
+ subsequent_indent=subindent)
+
+
+def format(text, width):
+ """Parse and format the text according to width."""
+ blocks = findblocks(text)
+ blocks = findliteralblocks(blocks)
+ blocks = findsections(blocks)
+ blocks = findbulletlists(blocks)
+ blocks = findoptionlists(blocks)
+ blocks = findfieldlists(blocks)
+ blocks = finddefinitionlists(blocks)
+ blocks = addmargins(blocks)
+ return '\n'.join(formatblock(b, width) for b in blocks)
+
+
+if __name__ == "__main__":
+ from pprint import pprint
+
+ def debug(func, blocks):
+ blocks = func(blocks)
+ print "*** after %s:" % func.__name__
+ pprint(blocks)
+ print
+ return blocks
+
+ text = open(sys.argv[1]).read()
+ blocks = debug(findblocks, text)
+ blocks = debug(findliteralblocks, blocks)
+ blocks = debug(findsections, blocks)
+ blocks = debug(findbulletlists, blocks)
+ blocks = debug(findoptionlists, blocks)
+ blocks = debug(findfieldlists, blocks)
+ blocks = debug(finddefinitionlists, blocks)
+ blocks = debug(addmargins, blocks)
+ print '\n'.join(formatblock(b, 30) for b in blocks)
diff --git a/sys/src/cmd/hg/mercurial/mpatch.c b/sys/src/cmd/hg/mercurial/mpatch.c
new file mode 100644
index 000000000..d9ceefcae
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/mpatch.c
@@ -0,0 +1,444 @@
+/*
+ mpatch.c - efficient binary patching for Mercurial
+
+ This implements a patch algorithm that's O(m + nlog n) where m is the
+ size of the output and n is the number of patches.
+
+ Given a list of binary patches, it unpacks each into a hunk list,
+ then combines the hunk lists with a treewise recursion to form a
+ single hunk list. This hunk list is then applied to the original
+ text.
+
+ The text (or binary) fragments are copied directly from their source
+ Python objects into a preallocated output string to avoid the
+ allocation of intermediate Python objects. Working memory is about 2x
+ the total number of hunks.
+
+ Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+
+ This software may be used and distributed according to the terms
+ of the GNU General Public License, incorporated herein by reference.
+*/
+
+#include <Python.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Definitions to get compatibility with python 2.4 and earlier which
+ does not have Py_ssize_t. See also PEP 353.
+ Note: msvc (8 or earlier) does not have ssize_t, so we use Py_ssize_t.
+*/
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+#ifdef _WIN32
+# ifdef _MSC_VER
+/* msvc 6.0 has problems */
+# define inline __inline
+typedef unsigned long uint32_t;
+# else
+# include <stdint.h>
+# endif
+static uint32_t ntohl(uint32_t x)
+{
+ return ((x & 0x000000ffUL) << 24) |
+ ((x & 0x0000ff00UL) << 8) |
+ ((x & 0x00ff0000UL) >> 8) |
+ ((x & 0xff000000UL) >> 24);
+}
+#else
+/* not windows */
+# include <sys/types.h>
+# if defined __BEOS__ && !defined __HAIKU__
+# include <ByteOrder.h>
+# else
+# include <arpa/inet.h>
+# endif
+# include <inttypes.h>
+#endif
+
+static char mpatch_doc[] = "Efficient binary patching.";
+static PyObject *mpatch_Error;
+
+struct frag {
+ int start, end, len;
+ const char *data;
+};
+
+struct flist {
+ struct frag *base, *head, *tail;
+};
+
+static struct flist *lalloc(int size)
+{
+ struct flist *a = NULL;
+
+ if (size < 1)
+ size = 1;
+
+ a = (struct flist *)malloc(sizeof(struct flist));
+ if (a) {
+ a->base = (struct frag *)malloc(sizeof(struct frag) * size);
+ if (a->base) {
+ a->head = a->tail = a->base;
+ return a;
+ }
+ free(a);
+ a = NULL;
+ }
+ if (!PyErr_Occurred())
+ PyErr_NoMemory();
+ return NULL;
+}
+
+static void lfree(struct flist *a)
+{
+ if (a) {
+ free(a->base);
+ free(a);
+ }
+}
+
+static int lsize(struct flist *a)
+{
+ return a->tail - a->head;
+}
+
+/* move hunks in source that are less cut to dest, compensating
+ for changes in offset. the last hunk may be split if necessary.
+*/
+static int gather(struct flist *dest, struct flist *src, int cut, int offset)
+{
+ struct frag *d = dest->tail, *s = src->head;
+ int postend, c, l;
+
+ while (s != src->tail) {
+ if (s->start + offset >= cut)
+ break; /* we've gone far enough */
+
+ postend = offset + s->start + s->len;
+ if (postend <= cut) {
+ /* save this hunk */
+ offset += s->start + s->len - s->end;
+ *d++ = *s++;
+ }
+ else {
+ /* break up this hunk */
+ c = cut - offset;
+ if (s->end < c)
+ c = s->end;
+ l = cut - offset - s->start;
+ if (s->len < l)
+ l = s->len;
+
+ offset += s->start + l - c;
+
+ d->start = s->start;
+ d->end = c;
+ d->len = l;
+ d->data = s->data;
+ d++;
+ s->start = c;
+ s->len = s->len - l;
+ s->data = s->data + l;
+
+ break;
+ }
+ }
+
+ dest->tail = d;
+ src->head = s;
+ return offset;
+}
+
+/* like gather, but with no output list */
+static int discard(struct flist *src, int cut, int offset)
+{
+ struct frag *s = src->head;
+ int postend, c, l;
+
+ while (s != src->tail) {
+ if (s->start + offset >= cut)
+ break;
+
+ postend = offset + s->start + s->len;
+ if (postend <= cut) {
+ offset += s->start + s->len - s->end;
+ s++;
+ }
+ else {
+ c = cut - offset;
+ if (s->end < c)
+ c = s->end;
+ l = cut - offset - s->start;
+ if (s->len < l)
+ l = s->len;
+
+ offset += s->start + l - c;
+ s->start = c;
+ s->len = s->len - l;
+ s->data = s->data + l;
+
+ break;
+ }
+ }
+
+ src->head = s;
+ return offset;
+}
+
+/* combine hunk lists a and b, while adjusting b for offset changes in a/
+ this deletes a and b and returns the resultant list. */
+static struct flist *combine(struct flist *a, struct flist *b)
+{
+ struct flist *c = NULL;
+ struct frag *bh, *ct;
+ int offset = 0, post;
+
+ if (a && b)
+ c = lalloc((lsize(a) + lsize(b)) * 2);
+
+ if (c) {
+
+ for (bh = b->head; bh != b->tail; bh++) {
+ /* save old hunks */
+ offset = gather(c, a, bh->start, offset);
+
+ /* discard replaced hunks */
+ post = discard(a, bh->end, offset);
+
+ /* insert new hunk */
+ ct = c->tail;
+ ct->start = bh->start - offset;
+ ct->end = bh->end - post;
+ ct->len = bh->len;
+ ct->data = bh->data;
+ c->tail++;
+ offset = post;
+ }
+
+ /* hold on to tail from a */
+ memcpy(c->tail, a->head, sizeof(struct frag) * lsize(a));
+ c->tail += lsize(a);
+ }
+
+ lfree(a);
+ lfree(b);
+ return c;
+}
+
+/* decode a binary patch into a hunk list */
+static struct flist *decode(const char *bin, int len)
+{
+ struct flist *l;
+ struct frag *lt;
+ const char *data = bin + 12, *end = bin + len;
+ char decode[12]; /* for dealing with alignment issues */
+
+ /* assume worst case size, we won't have many of these lists */
+ l = lalloc(len / 12);
+ if (!l)
+ return NULL;
+
+ lt = l->tail;
+
+ while (data <= end) {
+ memcpy(decode, bin, 12);
+ lt->start = ntohl(*(uint32_t *)decode);
+ lt->end = ntohl(*(uint32_t *)(decode + 4));
+ lt->len = ntohl(*(uint32_t *)(decode + 8));
+ if (lt->start > lt->end)
+ break; /* sanity check */
+ bin = data + lt->len;
+ if (bin < data)
+ break; /* big data + big (bogus) len can wrap around */
+ lt->data = data;
+ data = bin + 12;
+ lt++;
+ }
+
+ if (bin != end) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(mpatch_Error, "patch cannot be decoded");
+ lfree(l);
+ return NULL;
+ }
+
+ l->tail = lt;
+ return l;
+}
+
+/* calculate the size of resultant text */
+static int calcsize(int len, struct flist *l)
+{
+ int outlen = 0, last = 0;
+ struct frag *f = l->head;
+
+ while (f != l->tail) {
+ if (f->start < last || f->end > len) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(mpatch_Error,
+ "invalid patch");
+ return -1;
+ }
+ outlen += f->start - last;
+ last = f->end;
+ outlen += f->len;
+ f++;
+ }
+
+ outlen += len - last;
+ return outlen;
+}
+
+static int apply(char *buf, const char *orig, int len, struct flist *l)
+{
+ struct frag *f = l->head;
+ int last = 0;
+ char *p = buf;
+
+ while (f != l->tail) {
+ if (f->start < last || f->end > len) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(mpatch_Error,
+ "invalid patch");
+ return 0;
+ }
+ memcpy(p, orig + last, f->start - last);
+ p += f->start - last;
+ memcpy(p, f->data, f->len);
+ last = f->end;
+ p += f->len;
+ f++;
+ }
+ memcpy(p, orig + last, len - last);
+ return 1;
+}
+
+/* recursively generate a patch of all bins between start and end */
+static struct flist *fold(PyObject *bins, int start, int end)
+{
+ int len;
+ Py_ssize_t blen;
+ const char *buffer;
+
+ if (start + 1 == end) {
+ /* trivial case, output a decoded list */
+ PyObject *tmp = PyList_GetItem(bins, start);
+ if (!tmp)
+ return NULL;
+ if (PyObject_AsCharBuffer(tmp, &buffer, &blen))
+ return NULL;
+ return decode(buffer, blen);
+ }
+
+ /* divide and conquer, memory management is elsewhere */
+ len = (end - start) / 2;
+ return combine(fold(bins, start, start + len),
+ fold(bins, start + len, end));
+}
+
+static PyObject *
+patches(PyObject *self, PyObject *args)
+{
+ PyObject *text, *bins, *result;
+ struct flist *patch;
+ const char *in;
+ char *out;
+ int len, outlen;
+ Py_ssize_t inlen;
+
+ if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins))
+ return NULL;
+
+ len = PyList_Size(bins);
+ if (!len) {
+ /* nothing to do */
+ Py_INCREF(text);
+ return text;
+ }
+
+ if (PyObject_AsCharBuffer(text, &in, &inlen))
+ return NULL;
+
+ patch = fold(bins, 0, len);
+ if (!patch)
+ return NULL;
+
+ outlen = calcsize(inlen, patch);
+ if (outlen < 0) {
+ result = NULL;
+ goto cleanup;
+ }
+ result = PyString_FromStringAndSize(NULL, outlen);
+ if (!result) {
+ result = NULL;
+ goto cleanup;
+ }
+ out = PyString_AsString(result);
+ if (!apply(out, in, inlen, patch)) {
+ Py_DECREF(result);
+ result = NULL;
+ }
+cleanup:
+ lfree(patch);
+ return result;
+}
+
+/* calculate size of a patched file directly */
+static PyObject *
+patchedsize(PyObject *self, PyObject *args)
+{
+ long orig, start, end, len, outlen = 0, last = 0;
+ int patchlen;
+ char *bin, *binend, *data;
+ char decode[12]; /* for dealing with alignment issues */
+
+ if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen))
+ return NULL;
+
+ binend = bin + patchlen;
+ data = bin + 12;
+
+ while (data <= binend) {
+ memcpy(decode, bin, 12);
+ start = ntohl(*(uint32_t *)decode);
+ end = ntohl(*(uint32_t *)(decode + 4));
+ len = ntohl(*(uint32_t *)(decode + 8));
+ if (start > end)
+ break; /* sanity check */
+ bin = data + len;
+ if (bin < data)
+ break; /* big data + big (bogus) len can wrap around */
+ data = bin + 12;
+ outlen += start - last;
+ last = end;
+ outlen += len;
+ }
+
+ if (bin != binend) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(mpatch_Error, "patch cannot be decoded");
+ return NULL;
+ }
+
+ outlen += orig - last;
+ return Py_BuildValue("l", outlen);
+}
+
+static PyMethodDef methods[] = {
+ {"patches", patches, METH_VARARGS, "apply a series of patches\n"},
+ {"patchedsize", patchedsize, METH_VARARGS, "calculed patched size\n"},
+ {NULL, NULL}
+};
+
+PyMODINIT_FUNC
+initmpatch(void)
+{
+ Py_InitModule3("mpatch", methods, mpatch_doc);
+ mpatch_Error = PyErr_NewException("mpatch.mpatchError", NULL, NULL);
+}
+
diff --git a/sys/src/cmd/hg/mercurial/node.py b/sys/src/cmd/hg/mercurial/node.py
new file mode 100644
index 000000000..2a3be39c1
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/node.py
@@ -0,0 +1,18 @@
+# node.py - basic nodeid manipulation for mercurial
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import binascii
+
+nullrev = -1
+nullid = "\0" * 20
+
+# This ugly style has a noticeable effect in manifest parsing
+hex = binascii.hexlify
+bin = binascii.unhexlify
+
+def short(node):
+ return hex(node[:6])
diff --git a/sys/src/cmd/hg/mercurial/node.pyc b/sys/src/cmd/hg/mercurial/node.pyc
new file mode 100644
index 000000000..184373c1d
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/node.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/osutil.c b/sys/src/cmd/hg/mercurial/osutil.c
new file mode 100644
index 000000000..a9874d0c9
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/osutil.c
@@ -0,0 +1,534 @@
+/*
+ osutil.c - native operating system services
+
+ Copyright 2007 Matt Mackall and others
+
+ This software may be used and distributed according to the terms of
+ the GNU General Public License, incorporated herein by reference.
+*/
+
+#define _ATFILE_SOURCE
+#include <Python.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32
+# include <windows.h>
+# include <io.h>
+#else
+# include <dirent.h>
+# include <sys/stat.h>
+# include <sys/types.h>
+# include <unistd.h>
+#endif
+
+// some platforms lack the PATH_MAX definition (eg. GNU/Hurd)
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+#ifdef _WIN32
+/*
+stat struct compatible with hg expectations
+Mercurial only uses st_mode, st_size and st_mtime
+the rest is kept to minimize changes between implementations
+*/
+struct hg_stat {
+ int st_dev;
+ int st_mode;
+ int st_nlink;
+ __int64 st_size;
+ int st_mtime;
+ int st_ctime;
+};
+struct listdir_stat {
+ PyObject_HEAD
+ struct hg_stat st;
+};
+#else
+struct listdir_stat {
+ PyObject_HEAD
+ struct stat st;
+};
+#endif
+
+#define listdir_slot(name) \
+ static PyObject *listdir_stat_##name(PyObject *self, void *x) \
+ { \
+ return PyInt_FromLong(((struct listdir_stat *)self)->st.name); \
+ }
+
+listdir_slot(st_dev)
+listdir_slot(st_mode)
+listdir_slot(st_nlink)
+#ifdef _WIN32
+static PyObject *listdir_stat_st_size(PyObject *self, void *x)
+{
+ return PyLong_FromLongLong(
+ (PY_LONG_LONG)((struct listdir_stat *)self)->st.st_size);
+}
+#else
+listdir_slot(st_size)
+#endif
+listdir_slot(st_mtime)
+listdir_slot(st_ctime)
+
+static struct PyGetSetDef listdir_stat_getsets[] = {
+ {"st_dev", listdir_stat_st_dev, 0, 0, 0},
+ {"st_mode", listdir_stat_st_mode, 0, 0, 0},
+ {"st_nlink", listdir_stat_st_nlink, 0, 0, 0},
+ {"st_size", listdir_stat_st_size, 0, 0, 0},
+ {"st_mtime", listdir_stat_st_mtime, 0, 0, 0},
+ {"st_ctime", listdir_stat_st_ctime, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyObject *listdir_stat_new(PyTypeObject *t, PyObject *a, PyObject *k)
+{
+ return t->tp_alloc(t, 0);
+}
+
+static void listdir_stat_dealloc(PyObject *o)
+{
+ o->ob_type->tp_free(o);
+}
+
+static PyTypeObject listdir_stat_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "osutil.stat", /*tp_name*/
+ sizeof(struct listdir_stat), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)listdir_stat_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "stat objects", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ listdir_stat_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ listdir_stat_new, /* tp_new */
+};
+
+#ifdef _WIN32
+
+static int to_python_time(const FILETIME *tm)
+{
+ /* number of seconds between epoch and January 1 1601 */
+ const __int64 a0 = (__int64)134774L * (__int64)24L * (__int64)3600L;
+ /* conversion factor from 100ns to 1s */
+ const __int64 a1 = 10000000;
+ /* explicit (int) cast to suspend compiler warnings */
+ return (int)((((__int64)tm->dwHighDateTime << 32)
+ + tm->dwLowDateTime) / a1 - a0);
+}
+
+static PyObject *make_item(const WIN32_FIND_DATAA *fd, int wantstat)
+{
+ PyObject *py_st;
+ struct hg_stat *stp;
+
+ int kind = (fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ ? _S_IFDIR : _S_IFREG;
+
+ if (!wantstat)
+ return Py_BuildValue("si", fd->cFileName, kind);
+
+ py_st = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
+ if (!py_st)
+ return NULL;
+
+ stp = &((struct listdir_stat *)py_st)->st;
+ /*
+ use kind as st_mode
+ rwx bits on Win32 are meaningless
+ and Hg does not use them anyway
+ */
+ stp->st_mode = kind;
+ stp->st_mtime = to_python_time(&fd->ftLastWriteTime);
+ stp->st_ctime = to_python_time(&fd->ftCreationTime);
+ if (kind == _S_IFREG)
+ stp->st_size = ((__int64)fd->nFileSizeHigh << 32)
+ + fd->nFileSizeLow;
+ return Py_BuildValue("siN", fd->cFileName,
+ kind, py_st);
+}
+
+static PyObject *_listdir(char *path, int plen, int wantstat, char *skip)
+{
+ PyObject *rval = NULL; /* initialize - return value */
+ PyObject *list;
+ HANDLE fh;
+ WIN32_FIND_DATAA fd;
+ char *pattern;
+
+ /* build the path + \* pattern string */
+ pattern = malloc(plen+3); /* path + \* + \0 */
+ if (!pattern) {
+ PyErr_NoMemory();
+ goto error_nomem;
+ }
+ strcpy(pattern, path);
+
+ if (plen > 0) {
+ char c = path[plen-1];
+ if (c != ':' && c != '/' && c != '\\')
+ pattern[plen++] = '\\';
+ }
+ strcpy(pattern + plen, "*");
+
+ fh = FindFirstFileA(pattern, &fd);
+ if (fh == INVALID_HANDLE_VALUE) {
+ PyErr_SetFromWindowsErrWithFilename(GetLastError(), path);
+ goto error_file;
+ }
+
+ list = PyList_New(0);
+ if (!list)
+ goto error_list;
+
+ do {
+ PyObject *item;
+
+ if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ if (!strcmp(fd.cFileName, ".")
+ || !strcmp(fd.cFileName, ".."))
+ continue;
+
+ if (skip && !strcmp(fd.cFileName, skip)) {
+ rval = PyList_New(0);
+ goto error;
+ }
+ }
+
+ item = make_item(&fd, wantstat);
+ if (!item)
+ goto error;
+
+ if (PyList_Append(list, item)) {
+ Py_XDECREF(item);
+ goto error;
+ }
+
+ Py_XDECREF(item);
+ } while (FindNextFileA(fh, &fd));
+
+ if (GetLastError() != ERROR_NO_MORE_FILES) {
+ PyErr_SetFromWindowsErrWithFilename(GetLastError(), path);
+ goto error;
+ }
+
+ rval = list;
+ Py_XINCREF(rval);
+error:
+ Py_XDECREF(list);
+error_list:
+ FindClose(fh);
+error_file:
+ free(pattern);
+error_nomem:
+ return rval;
+}
+
+#else
+
+int entkind(struct dirent *ent)
+{
+#ifdef DT_REG
+ switch (ent->d_type) {
+ case DT_REG: return S_IFREG;
+ case DT_DIR: return S_IFDIR;
+ case DT_LNK: return S_IFLNK;
+ case DT_BLK: return S_IFBLK;
+ case DT_CHR: return S_IFCHR;
+ case DT_FIFO: return S_IFIFO;
+ case DT_SOCK: return S_IFSOCK;
+ }
+#endif
+ return -1;
+}
+
+static PyObject *_listdir(char *path, int pathlen, int keepstat, char *skip)
+{
+ PyObject *list, *elem, *stat, *ret = NULL;
+ char fullpath[PATH_MAX + 10];
+ int kind, err;
+ struct stat st;
+ struct dirent *ent;
+ DIR *dir;
+#ifdef AT_SYMLINK_NOFOLLOW
+ int dfd = -1;
+#endif
+
+ if (pathlen >= PATH_MAX) {
+ PyErr_SetString(PyExc_ValueError, "path too long");
+ goto error_value;
+ }
+ strncpy(fullpath, path, PATH_MAX);
+ fullpath[pathlen] = '/';
+
+#ifdef AT_SYMLINK_NOFOLLOW
+ dfd = open(path, O_RDONLY);
+ if (dfd == -1) {
+ PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
+ goto error_value;
+ }
+ dir = fdopendir(dfd);
+#else
+ dir = opendir(path);
+#endif
+ if (!dir) {
+ PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
+ goto error_dir;
+ }
+
+ list = PyList_New(0);
+ if (!list)
+ goto error_list;
+
+ while ((ent = readdir(dir))) {
+ if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
+ continue;
+
+ kind = entkind(ent);
+ if (kind == -1 || keepstat) {
+#ifdef AT_SYMLINK_NOFOLLOW
+ err = fstatat(dfd, ent->d_name, &st,
+ AT_SYMLINK_NOFOLLOW);
+#else
+ strncpy(fullpath + pathlen + 1, ent->d_name,
+ PATH_MAX - pathlen);
+ fullpath[PATH_MAX] = 0;
+ err = lstat(fullpath, &st);
+#endif
+ if (err == -1) {
+ strncpy(fullpath + pathlen + 1, ent->d_name,
+ PATH_MAX - pathlen);
+ fullpath[PATH_MAX] = 0;
+ PyErr_SetFromErrnoWithFilename(PyExc_OSError,
+ fullpath);
+ goto error;
+ }
+ kind = st.st_mode & S_IFMT;
+ }
+
+ /* quit early? */
+ if (skip && kind == S_IFDIR && !strcmp(ent->d_name, skip)) {
+ ret = PyList_New(0);
+ goto error;
+ }
+
+ if (keepstat) {
+ stat = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
+ if (!stat)
+ goto error;
+ memcpy(&((struct listdir_stat *)stat)->st, &st, sizeof(st));
+ elem = Py_BuildValue("siN", ent->d_name, kind, stat);
+ } else
+ elem = Py_BuildValue("si", ent->d_name, kind);
+ if (!elem)
+ goto error;
+
+ PyList_Append(list, elem);
+ Py_DECREF(elem);
+ }
+
+ ret = list;
+ Py_INCREF(ret);
+
+error:
+ Py_DECREF(list);
+error_list:
+ closedir(dir);
+error_dir:
+#ifdef AT_SYMLINK_NOFOLLOW
+ close(dfd);
+#endif
+error_value:
+ return ret;
+}
+
+#endif /* ndef _WIN32 */
+
+static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyObject *statobj = NULL; /* initialize - optional arg */
+ PyObject *skipobj = NULL; /* initialize - optional arg */
+ char *path, *skip = NULL;
+ int wantstat, plen;
+
+ static char *kwlist[] = {"path", "stat", "skip", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|OO:listdir",
+ kwlist, &path, &plen, &statobj, &skipobj))
+ return NULL;
+
+ wantstat = statobj && PyObject_IsTrue(statobj);
+
+ if (skipobj && skipobj != Py_None) {
+ skip = PyString_AsString(skipobj);
+ if (!skip)
+ return NULL;
+ }
+
+ return _listdir(path, plen, wantstat, skip);
+}
+
+#ifdef _WIN32
+static PyObject *posixfile(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"name", "mode", "buffering", NULL};
+ PyObject *file_obj = NULL;
+ char *name = NULL;
+ char *mode = "rb";
+ DWORD access = 0;
+ DWORD creation;
+ HANDLE handle;
+ int fd, flags = 0;
+ int bufsize = -1;
+ char m0, m1, m2;
+ char fpmode[4];
+ int fppos = 0;
+ int plus;
+ FILE *fp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:posixfile", kwlist,
+ Py_FileSystemDefaultEncoding,
+ &name, &mode, &bufsize))
+ return NULL;
+
+ m0 = mode[0];
+ m1 = m0 ? mode[1] : '\0';
+ m2 = m1 ? mode[2] : '\0';
+ plus = m1 == '+' || m2 == '+';
+
+ fpmode[fppos++] = m0;
+ if (m1 == 'b' || m2 == 'b') {
+ flags = _O_BINARY;
+ fpmode[fppos++] = 'b';
+ }
+ else
+ flags = _O_TEXT;
+ if (plus) {
+ flags |= _O_RDWR;
+ access = GENERIC_READ | GENERIC_WRITE;
+ fpmode[fppos++] = '+';
+ }
+ fpmode[fppos++] = '\0';
+
+ switch (m0) {
+ case 'r':
+ creation = OPEN_EXISTING;
+ if (!plus) {
+ flags |= _O_RDONLY;
+ access = GENERIC_READ;
+ }
+ break;
+ case 'w':
+ creation = CREATE_ALWAYS;
+ if (!plus) {
+ access = GENERIC_WRITE;
+ flags |= _O_WRONLY;
+ }
+ break;
+ case 'a':
+ creation = OPEN_ALWAYS;
+ flags |= _O_APPEND;
+ if (!plus) {
+ flags |= _O_WRONLY;
+ access = GENERIC_WRITE;
+ }
+ break;
+ default:
+ PyErr_Format(PyExc_ValueError,
+ "mode string must begin with one of 'r', 'w', "
+ "or 'a', not '%c'", m0);
+ goto bail;
+ }
+
+ handle = CreateFile(name, access,
+ FILE_SHARE_READ | FILE_SHARE_WRITE |
+ FILE_SHARE_DELETE,
+ NULL,
+ creation,
+ FILE_ATTRIBUTE_NORMAL,
+ 0);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ PyErr_SetFromWindowsErrWithFilename(GetLastError(), name);
+ goto bail;
+ }
+
+ fd = _open_osfhandle((intptr_t) handle, flags);
+ if (fd == -1) {
+ CloseHandle(handle);
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
+ goto bail;
+ }
+
+ fp = _fdopen(fd, fpmode);
+ if (fp == NULL) {
+ _close(fd);
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
+ goto bail;
+ }
+
+ file_obj = PyFile_FromFile(fp, name, mode, fclose);
+ if (file_obj == NULL) {
+ fclose(fp);
+ goto bail;
+ }
+
+ PyFile_SetBufSize(file_obj, bufsize);
+bail:
+ PyMem_Free(name);
+ return file_obj;
+}
+#endif
+
+static char osutil_doc[] = "Native operating system services.";
+
+static PyMethodDef methods[] = {
+ {"listdir", (PyCFunction)listdir, METH_VARARGS | METH_KEYWORDS,
+ "list a directory\n"},
+#ifdef _WIN32
+ {"posixfile", (PyCFunction)posixfile, METH_VARARGS | METH_KEYWORDS,
+ "Open a file with POSIX-like semantics.\n"
+"On error, this function may raise either a WindowsError or an IOError."},
+#endif
+ {NULL, NULL}
+};
+
+PyMODINIT_FUNC initosutil(void)
+{
+ if (PyType_Ready(&listdir_stat_type) == -1)
+ return;
+
+ Py_InitModule3("osutil", methods, osutil_doc);
+}
diff --git a/sys/src/cmd/hg/mercurial/parsers.c b/sys/src/cmd/hg/mercurial/parsers.c
new file mode 100644
index 000000000..93c10c05d
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/parsers.c
@@ -0,0 +1,435 @@
+/*
+ parsers.c - efficient content parsing
+
+ Copyright 2008 Matt Mackall <mpm@selenic.com> and others
+
+ This software may be used and distributed according to the terms of
+ the GNU General Public License, incorporated herein by reference.
+*/
+
+#include <Python.h>
+#include <ctype.h>
+#include <string.h>
+
+static int hexdigit(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+
+ PyErr_SetString(PyExc_ValueError, "input contains non-hex character");
+ return 0;
+}
+
+/*
+ * Turn a hex-encoded string into binary.
+ */
+static PyObject *unhexlify(const char *str, int len)
+{
+ PyObject *ret;
+ const char *c;
+ char *d;
+
+ ret = PyString_FromStringAndSize(NULL, len / 2);
+ if (!ret)
+ return NULL;
+
+ d = PyString_AS_STRING(ret);
+ for (c = str; c < str + len;) {
+ int hi = hexdigit(*c++);
+ int lo = hexdigit(*c++);
+ *d++ = (hi << 4) | lo;
+ }
+
+ return ret;
+}
+
+/*
+ * This code assumes that a manifest is stitched together with newline
+ * ('\n') characters.
+ */
+static PyObject *parse_manifest(PyObject *self, PyObject *args)
+{
+ PyObject *mfdict, *fdict;
+ char *str, *cur, *start, *zero;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest",
+ &PyDict_Type, &mfdict,
+ &PyDict_Type, &fdict,
+ &str, &len))
+ goto quit;
+
+ for (start = cur = str, zero = NULL; cur < str + len; cur++) {
+ PyObject *file = NULL, *node = NULL;
+ PyObject *flags = NULL;
+ int nlen;
+
+ if (!*cur) {
+ zero = cur;
+ continue;
+ }
+ else if (*cur != '\n')
+ continue;
+
+ if (!zero) {
+ PyErr_SetString(PyExc_ValueError,
+ "manifest entry has no separator");
+ goto quit;
+ }
+
+ file = PyString_FromStringAndSize(start, zero - start);
+ if (!file)
+ goto bail;
+
+ nlen = cur - zero - 1;
+
+ node = unhexlify(zero + 1, nlen > 40 ? 40 : nlen);
+ if (!node)
+ goto bail;
+
+ if (nlen > 40) {
+ PyObject *flags;
+
+ flags = PyString_FromStringAndSize(zero + 41,
+ nlen - 40);
+ if (!flags)
+ goto bail;
+
+ if (PyDict_SetItem(fdict, file, flags) == -1)
+ goto bail;
+ }
+
+ if (PyDict_SetItem(mfdict, file, node) == -1)
+ goto bail;
+
+ start = cur + 1;
+ zero = NULL;
+
+ Py_XDECREF(flags);
+ Py_XDECREF(node);
+ Py_XDECREF(file);
+ continue;
+ bail:
+ Py_XDECREF(flags);
+ Py_XDECREF(node);
+ Py_XDECREF(file);
+ goto quit;
+ }
+
+ if (len > 0 && *(cur - 1) != '\n') {
+ PyErr_SetString(PyExc_ValueError,
+ "manifest contains trailing garbage");
+ goto quit;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+quit:
+ return NULL;
+}
+
+#ifdef _WIN32
+# ifdef _MSC_VER
+/* msvc 6.0 has problems */
+# define inline __inline
+typedef unsigned long uint32_t;
+typedef unsigned __int64 uint64_t;
+# else
+# include <stdint.h>
+# endif
+static uint32_t ntohl(uint32_t x)
+{
+ return ((x & 0x000000ffUL) << 24) |
+ ((x & 0x0000ff00UL) << 8) |
+ ((x & 0x00ff0000UL) >> 8) |
+ ((x & 0xff000000UL) >> 24);
+}
+#else
+/* not windows */
+# include <sys/types.h>
+# if defined __BEOS__ && !defined __HAIKU__
+# include <ByteOrder.h>
+# else
+# include <arpa/inet.h>
+# endif
+# include <inttypes.h>
+#endif
+
+static PyObject *parse_dirstate(PyObject *self, PyObject *args)
+{
+ PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
+ PyObject *fname = NULL, *cname = NULL, *entry = NULL;
+ char *str, *cur, *end, *cpos;
+ int state, mode, size, mtime;
+ unsigned int flen;
+ int len;
+ char decode[16]; /* for alignment */
+
+ if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
+ &PyDict_Type, &dmap,
+ &PyDict_Type, &cmap,
+ &str, &len))
+ goto quit;
+
+ /* read parents */
+ if (len < 40)
+ goto quit;
+
+ parents = Py_BuildValue("s#s#", str, 20, str + 20, 20);
+ if (!parents)
+ goto quit;
+
+ /* read filenames */
+ cur = str + 40;
+ end = str + len;
+
+ while (cur < end - 17) {
+ /* unpack header */
+ state = *cur;
+ memcpy(decode, cur + 1, 16);
+ mode = ntohl(*(uint32_t *)(decode));
+ size = ntohl(*(uint32_t *)(decode + 4));
+ mtime = ntohl(*(uint32_t *)(decode + 8));
+ flen = ntohl(*(uint32_t *)(decode + 12));
+ cur += 17;
+ if (flen > end - cur) {
+ PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
+ goto quit;
+ }
+
+ entry = Py_BuildValue("ciii", state, mode, size, mtime);
+ if (!entry)
+ goto quit;
+ PyObject_GC_UnTrack(entry); /* don't waste time with this */
+
+ cpos = memchr(cur, 0, flen);
+ if (cpos) {
+ fname = PyString_FromStringAndSize(cur, cpos - cur);
+ cname = PyString_FromStringAndSize(cpos + 1,
+ flen - (cpos - cur) - 1);
+ if (!fname || !cname ||
+ PyDict_SetItem(cmap, fname, cname) == -1 ||
+ PyDict_SetItem(dmap, fname, entry) == -1)
+ goto quit;
+ Py_DECREF(cname);
+ } else {
+ fname = PyString_FromStringAndSize(cur, flen);
+ if (!fname ||
+ PyDict_SetItem(dmap, fname, entry) == -1)
+ goto quit;
+ }
+ cur += flen;
+ Py_DECREF(fname);
+ Py_DECREF(entry);
+ fname = cname = entry = NULL;
+ }
+
+ ret = parents;
+ Py_INCREF(ret);
+quit:
+ Py_XDECREF(fname);
+ Py_XDECREF(cname);
+ Py_XDECREF(entry);
+ Py_XDECREF(parents);
+ return ret;
+}
+
+const char nullid[20];
+const int nullrev = -1;
+
+/* create an index tuple, insert into the nodemap */
+static PyObject * _build_idx_entry(PyObject *nodemap, int n, uint64_t offset_flags,
+ int comp_len, int uncomp_len, int base_rev,
+ int link_rev, int parent_1, int parent_2,
+ const char *c_node_id)
+{
+ int err;
+ PyObject *entry, *node_id, *n_obj;
+
+ node_id = PyString_FromStringAndSize(c_node_id, 20);
+ n_obj = PyInt_FromLong(n);
+ if (!node_id || !n_obj)
+ err = -1;
+ else
+ err = PyDict_SetItem(nodemap, node_id, n_obj);
+
+ Py_XDECREF(n_obj);
+ if (err)
+ goto error_dealloc;
+
+ entry = Py_BuildValue("LiiiiiiN", offset_flags, comp_len,
+ uncomp_len, base_rev, link_rev,
+ parent_1, parent_2, node_id);
+ if (!entry)
+ goto error_dealloc;
+ PyObject_GC_UnTrack(entry); /* don't waste time with this */
+
+ return entry;
+
+error_dealloc:
+ Py_XDECREF(node_id);
+ return NULL;
+}
+
+/* RevlogNG format (all in big endian, data may be inlined):
+ * 6 bytes: offset
+ * 2 bytes: flags
+ * 4 bytes: compressed length
+ * 4 bytes: uncompressed length
+ * 4 bytes: base revision
+ * 4 bytes: link revision
+ * 4 bytes: parent 1 revision
+ * 4 bytes: parent 2 revision
+ * 32 bytes: nodeid (only 20 bytes used)
+ */
+static int _parse_index_ng (const char *data, int size, int inlined,
+ PyObject *index, PyObject *nodemap)
+{
+ PyObject *entry;
+ int n = 0, err;
+ uint64_t offset_flags;
+ int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
+ const char *c_node_id;
+ const char *end = data + size;
+ char decode[64]; /* to enforce alignment with inline data */
+
+ while (data < end) {
+ unsigned int step;
+
+ memcpy(decode, data, 64);
+ offset_flags = ntohl(*((uint32_t *) (decode + 4)));
+ if (n == 0) /* mask out version number for the first entry */
+ offset_flags &= 0xFFFF;
+ else {
+ uint32_t offset_high = ntohl(*((uint32_t *) decode));
+ offset_flags |= ((uint64_t) offset_high) << 32;
+ }
+
+ comp_len = ntohl(*((uint32_t *) (decode + 8)));
+ uncomp_len = ntohl(*((uint32_t *) (decode + 12)));
+ base_rev = ntohl(*((uint32_t *) (decode + 16)));
+ link_rev = ntohl(*((uint32_t *) (decode + 20)));
+ parent_1 = ntohl(*((uint32_t *) (decode + 24)));
+ parent_2 = ntohl(*((uint32_t *) (decode + 28)));
+ c_node_id = decode + 32;
+
+ entry = _build_idx_entry(nodemap, n, offset_flags,
+ comp_len, uncomp_len, base_rev,
+ link_rev, parent_1, parent_2,
+ c_node_id);
+ if (!entry)
+ return 0;
+
+ if (inlined) {
+ err = PyList_Append(index, entry);
+ Py_DECREF(entry);
+ if (err)
+ return 0;
+ } else
+ PyList_SET_ITEM(index, n, entry); /* steals reference */
+
+ n++;
+ step = 64 + (inlined ? comp_len : 0);
+ if (end - data < step)
+ break;
+ data += step;
+ }
+ if (data != end) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_ValueError, "corrupt index file");
+ return 0;
+ }
+
+ /* create the nullid/nullrev entry in the nodemap and the
+ * magic nullid entry in the index at [-1] */
+ entry = _build_idx_entry(nodemap,
+ nullrev, 0, 0, 0, -1, -1, -1, -1, nullid);
+ if (!entry)
+ return 0;
+ if (inlined) {
+ err = PyList_Append(index, entry);
+ Py_DECREF(entry);
+ if (err)
+ return 0;
+ } else
+ PyList_SET_ITEM(index, n, entry); /* steals reference */
+
+ return 1;
+}
+
+/* This function parses a index file and returns a Python tuple of the
+ * following format: (index, nodemap, cache)
+ *
+ * index: a list of tuples containing the RevlogNG records
+ * nodemap: a dict mapping node ids to indices in the index list
+ * cache: if data is inlined, a tuple (index_file_content, 0) else None
+ */
+static PyObject *parse_index(PyObject *self, PyObject *args)
+{
+ const char *data;
+ int size, inlined;
+ PyObject *rval = NULL, *index = NULL, *nodemap = NULL, *cache = NULL;
+ PyObject *data_obj = NULL, *inlined_obj;
+
+ if (!PyArg_ParseTuple(args, "s#O", &data, &size, &inlined_obj))
+ return NULL;
+ inlined = inlined_obj && PyObject_IsTrue(inlined_obj);
+
+ /* If no data is inlined, we know the size of the index list in
+ * advance: size divided by size of one one revlog record (64 bytes)
+ * plus one for the nullid */
+ index = inlined ? PyList_New(0) : PyList_New(size / 64 + 1);
+ if (!index)
+ goto quit;
+
+ nodemap = PyDict_New();
+ if (!nodemap)
+ goto quit;
+
+ /* set up the cache return value */
+ if (inlined) {
+ /* Note that the reference to data_obj is only borrowed */
+ data_obj = PyTuple_GET_ITEM(args, 0);
+ cache = Py_BuildValue("iO", 0, data_obj);
+ if (!cache)
+ goto quit;
+ } else {
+ cache = Py_None;
+ Py_INCREF(Py_None);
+ }
+
+ /* actually populate the index and the nodemap with data */
+ if (!_parse_index_ng (data, size, inlined, index, nodemap))
+ goto quit;
+
+ rval = Py_BuildValue("NNN", index, nodemap, cache);
+ if (!rval)
+ goto quit;
+ return rval;
+
+quit:
+ Py_XDECREF(index);
+ Py_XDECREF(nodemap);
+ Py_XDECREF(cache);
+ Py_XDECREF(rval);
+ return NULL;
+}
+
+
+static char parsers_doc[] = "Efficient content parsing.";
+
+static PyMethodDef methods[] = {
+ {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
+ {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"},
+ {"parse_index", parse_index, METH_VARARGS, "parse a revlog index\n"},
+ {NULL, NULL}
+};
+
+PyMODINIT_FUNC initparsers(void)
+{
+ Py_InitModule3("parsers", methods, parsers_doc);
+}
diff --git a/sys/src/cmd/hg/mercurial/patch.py b/sys/src/cmd/hg/mercurial/patch.py
new file mode 100644
index 000000000..d04a76aaf
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/patch.py
@@ -0,0 +1,1454 @@
+# patch.py - patch file parsing routines
+#
+# Copyright 2006 Brendan Cully <brendan@kublai.com>
+# Copyright 2007 Chris Mason <chris.mason@oracle.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+from node import hex, nullid, short
+import base85, cmdutil, mdiff, util, diffhelpers, copies
+import cStringIO, email.Parser, os, re
+import sys, tempfile, zlib
+
+gitre = re.compile('diff --git a/(.*) b/(.*)')
+
+class PatchError(Exception):
+ pass
+
+class NoHunks(PatchError):
+ pass
+
+# helper functions
+
+def copyfile(src, dst, basedir):
+ abssrc, absdst = [util.canonpath(basedir, basedir, x) for x in [src, dst]]
+ if os.path.exists(absdst):
+ raise util.Abort(_("cannot create %s: destination already exists") %
+ dst)
+
+ dstdir = os.path.dirname(absdst)
+ if dstdir and not os.path.isdir(dstdir):
+ try:
+ os.makedirs(dstdir)
+ except IOError:
+ raise util.Abort(
+ _("cannot create %s: unable to create destination directory")
+ % dst)
+
+ util.copyfile(abssrc, absdst)
+
+# public functions
+
+def extract(ui, fileobj):
+ '''extract patch from data read from fileobj.
+
+ patch can be a normal patch or contained in an email message.
+
+ return tuple (filename, message, user, date, node, p1, p2).
+ Any item in the returned tuple can be None. If filename is None,
+ fileobj did not contain a patch. Caller must unlink filename when done.'''
+
+ # attempt to detect the start of a patch
+ # (this heuristic is borrowed from quilt)
+ diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |'
+ r'retrieving revision [0-9]+(\.[0-9]+)*$|'
+ r'(---|\*\*\*)[ \t])', re.MULTILINE)
+
+ fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
+ tmpfp = os.fdopen(fd, 'w')
+ try:
+ msg = email.Parser.Parser().parse(fileobj)
+
+ subject = msg['Subject']
+ user = msg['From']
+ gitsendmail = 'git-send-email' in msg.get('X-Mailer', '')
+ # should try to parse msg['Date']
+ date = None
+ nodeid = None
+ branch = None
+ parents = []
+
+ if subject:
+ if subject.startswith('[PATCH'):
+ pend = subject.find(']')
+ if pend >= 0:
+ subject = subject[pend+1:].lstrip()
+ subject = subject.replace('\n\t', ' ')
+ ui.debug('Subject: %s\n' % subject)
+ if user:
+ ui.debug('From: %s\n' % user)
+ diffs_seen = 0
+ ok_types = ('text/plain', 'text/x-diff', 'text/x-patch')
+ message = ''
+ for part in msg.walk():
+ content_type = part.get_content_type()
+ ui.debug('Content-Type: %s\n' % content_type)
+ if content_type not in ok_types:
+ continue
+ payload = part.get_payload(decode=True)
+ m = diffre.search(payload)
+ if m:
+ hgpatch = False
+ ignoretext = False
+
+ ui.debug(_('found patch at byte %d\n') % m.start(0))
+ diffs_seen += 1
+ cfp = cStringIO.StringIO()
+ for line in payload[:m.start(0)].splitlines():
+ if line.startswith('# HG changeset patch'):
+ ui.debug(_('patch generated by hg export\n'))
+ hgpatch = True
+ # drop earlier commit message content
+ cfp.seek(0)
+ cfp.truncate()
+ subject = None
+ elif hgpatch:
+ if line.startswith('# User '):
+ user = line[7:]
+ ui.debug('From: %s\n' % user)
+ elif line.startswith("# Date "):
+ date = line[7:]
+ elif line.startswith("# Branch "):
+ branch = line[9:]
+ elif line.startswith("# Node ID "):
+ nodeid = line[10:]
+ elif line.startswith("# Parent "):
+ parents.append(line[10:])
+ elif line == '---' and gitsendmail:
+ ignoretext = True
+ if not line.startswith('# ') and not ignoretext:
+ cfp.write(line)
+ cfp.write('\n')
+ message = cfp.getvalue()
+ if tmpfp:
+ tmpfp.write(payload)
+ if not payload.endswith('\n'):
+ tmpfp.write('\n')
+ elif not diffs_seen and message and content_type == 'text/plain':
+ message += '\n' + payload
+ except:
+ tmpfp.close()
+ os.unlink(tmpname)
+ raise
+
+ if subject and not message.startswith(subject):
+ message = '%s\n%s' % (subject, message)
+ tmpfp.close()
+ if not diffs_seen:
+ os.unlink(tmpname)
+ return None, message, user, date, branch, None, None, None
+ p1 = parents and parents.pop(0) or None
+ p2 = parents and parents.pop(0) or None
+ return tmpname, message, user, date, branch, nodeid, p1, p2
+
+GP_PATCH = 1 << 0 # we have to run patch
+GP_FILTER = 1 << 1 # there's some copy/rename operation
+GP_BINARY = 1 << 2 # there's a binary patch
+
+class patchmeta(object):
+ """Patched file metadata
+
+ 'op' is the performed operation within ADD, DELETE, RENAME, MODIFY
+ or COPY. 'path' is patched file path. 'oldpath' is set to the
+ origin file when 'op' is either COPY or RENAME, None otherwise. If
+ file mode is changed, 'mode' is a tuple (islink, isexec) where
+ 'islink' is True if the file is a symlink and 'isexec' is True if
+ the file is executable. Otherwise, 'mode' is None.
+ """
+ def __init__(self, path):
+ self.path = path
+ self.oldpath = None
+ self.mode = None
+ self.op = 'MODIFY'
+ self.lineno = 0
+ self.binary = False
+
+ def setmode(self, mode):
+ islink = mode & 020000
+ isexec = mode & 0100
+ self.mode = (islink, isexec)
+
+def readgitpatch(lr):
+ """extract git-style metadata about patches from <patchname>"""
+
+ # Filter patch for git information
+ gp = None
+ gitpatches = []
+ # Can have a git patch with only metadata, causing patch to complain
+ dopatch = 0
+
+ lineno = 0
+ for line in lr:
+ lineno += 1
+ line = line.rstrip(' \r\n')
+ if line.startswith('diff --git'):
+ m = gitre.match(line)
+ if m:
+ if gp:
+ gitpatches.append(gp)
+ src, dst = m.group(1, 2)
+ gp = patchmeta(dst)
+ gp.lineno = lineno
+ elif gp:
+ if line.startswith('--- '):
+ if gp.op in ('COPY', 'RENAME'):
+ dopatch |= GP_FILTER
+ gitpatches.append(gp)
+ gp = None
+ dopatch |= GP_PATCH
+ continue
+ if line.startswith('rename from '):
+ gp.op = 'RENAME'
+ gp.oldpath = line[12:]
+ elif line.startswith('rename to '):
+ gp.path = line[10:]
+ elif line.startswith('copy from '):
+ gp.op = 'COPY'
+ gp.oldpath = line[10:]
+ elif line.startswith('copy to '):
+ gp.path = line[8:]
+ elif line.startswith('deleted file'):
+ gp.op = 'DELETE'
+ # is the deleted file a symlink?
+ gp.setmode(int(line[-6:], 8))
+ elif line.startswith('new file mode '):
+ gp.op = 'ADD'
+ gp.setmode(int(line[-6:], 8))
+ elif line.startswith('new mode '):
+ gp.setmode(int(line[-6:], 8))
+ elif line.startswith('GIT binary patch'):
+ dopatch |= GP_BINARY
+ gp.binary = True
+ if gp:
+ gitpatches.append(gp)
+
+ if not gitpatches:
+ dopatch = GP_PATCH
+
+ return (dopatch, gitpatches)
+
+class linereader(object):
+ # simple class to allow pushing lines back into the input stream
+ def __init__(self, fp, textmode=False):
+ self.fp = fp
+ self.buf = []
+ self.textmode = textmode
+
+ def push(self, line):
+ if line is not None:
+ self.buf.append(line)
+
+ def readline(self):
+ if self.buf:
+ l = self.buf[0]
+ del self.buf[0]
+ return l
+ l = self.fp.readline()
+ if self.textmode and l.endswith('\r\n'):
+ l = l[:-2] + '\n'
+ return l
+
+ def __iter__(self):
+ while 1:
+ l = self.readline()
+ if not l:
+ break
+ yield l
+
+# @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
+unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
+contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
+
+class patchfile(object):
+ def __init__(self, ui, fname, opener, missing=False, eol=None):
+ self.fname = fname
+ self.eol = eol
+ self.opener = opener
+ self.ui = ui
+ self.lines = []
+ self.exists = False
+ self.missing = missing
+ if not missing:
+ try:
+ self.lines = self.readlines(fname)
+ self.exists = True
+ except IOError:
+ pass
+ else:
+ self.ui.warn(_("unable to find '%s' for patching\n") % self.fname)
+
+ self.hash = {}
+ self.dirty = 0
+ self.offset = 0
+ self.rej = []
+ self.fileprinted = False
+ self.printfile(False)
+ self.hunks = 0
+
+ def readlines(self, fname):
+ fp = self.opener(fname, 'r')
+ try:
+ return list(linereader(fp, self.eol is not None))
+ finally:
+ fp.close()
+
+ def writelines(self, fname, lines):
+ fp = self.opener(fname, 'w')
+ try:
+ if self.eol and self.eol != '\n':
+ for l in lines:
+ if l and l[-1] == '\n':
+ l = l[:-1] + self.eol
+ fp.write(l)
+ else:
+ fp.writelines(lines)
+ finally:
+ fp.close()
+
+ def unlink(self, fname):
+ os.unlink(fname)
+
+ def printfile(self, warn):
+ if self.fileprinted:
+ return
+ if warn or self.ui.verbose:
+ self.fileprinted = True
+ s = _("patching file %s\n") % self.fname
+ if warn:
+ self.ui.warn(s)
+ else:
+ self.ui.note(s)
+
+
+ def findlines(self, l, linenum):
+ # looks through the hash and finds candidate lines. The
+ # result is a list of line numbers sorted based on distance
+ # from linenum
+
+ try:
+ cand = self.hash[l]
+ except:
+ return []
+
+ if len(cand) > 1:
+ # resort our list of potentials forward then back.
+ cand.sort(key=lambda x: abs(x - linenum))
+ return cand
+
+ def hashlines(self):
+ self.hash = {}
+ for x, s in enumerate(self.lines):
+ self.hash.setdefault(s, []).append(x)
+
+ def write_rej(self):
+ # our rejects are a little different from patch(1). This always
+ # creates rejects in the same form as the original patch. A file
+ # header is inserted so that you can run the reject through patch again
+ # without having to type the filename.
+
+ if not self.rej:
+ return
+
+ fname = self.fname + ".rej"
+ self.ui.warn(
+ _("%d out of %d hunks FAILED -- saving rejects to file %s\n") %
+ (len(self.rej), self.hunks, fname))
+
+ def rejlines():
+ base = os.path.basename(self.fname)
+ yield "--- %s\n+++ %s\n" % (base, base)
+ for x in self.rej:
+ for l in x.hunk:
+ yield l
+ if l[-1] != '\n':
+ yield "\n\ No newline at end of file\n"
+
+ self.writelines(fname, rejlines())
+
+ def write(self, dest=None):
+ if not self.dirty:
+ return
+ if not dest:
+ dest = self.fname
+ self.writelines(dest, self.lines)
+
+ def close(self):
+ self.write()
+ self.write_rej()
+
+ def apply(self, h, reverse):
+ if not h.complete():
+ raise PatchError(_("bad hunk #%d %s (%d %d %d %d)") %
+ (h.number, h.desc, len(h.a), h.lena, len(h.b),
+ h.lenb))
+
+ self.hunks += 1
+ if reverse:
+ h.reverse()
+
+ if self.missing:
+ self.rej.append(h)
+ return -1
+
+ if self.exists and h.createfile():
+ self.ui.warn(_("file %s already exists\n") % self.fname)
+ self.rej.append(h)
+ return -1
+
+ if isinstance(h, githunk):
+ if h.rmfile():
+ self.unlink(self.fname)
+ else:
+ self.lines[:] = h.new()
+ self.offset += len(h.new())
+ self.dirty = 1
+ return 0
+
+ # fast case first, no offsets, no fuzz
+ old = h.old()
+ # patch starts counting at 1 unless we are adding the file
+ if h.starta == 0:
+ start = 0
+ else:
+ start = h.starta + self.offset - 1
+ orig_start = start
+ if diffhelpers.testhunk(old, self.lines, start) == 0:
+ if h.rmfile():
+ self.unlink(self.fname)
+ else:
+ self.lines[start : start + h.lena] = h.new()
+ self.offset += h.lenb - h.lena
+ self.dirty = 1
+ return 0
+
+ # ok, we couldn't match the hunk. Lets look for offsets and fuzz it
+ self.hashlines()
+ if h.hunk[-1][0] != ' ':
+ # if the hunk tried to put something at the bottom of the file
+ # override the start line and use eof here
+ search_start = len(self.lines)
+ else:
+ search_start = orig_start
+
+ for fuzzlen in xrange(3):
+ for toponly in [ True, False ]:
+ old = h.old(fuzzlen, toponly)
+
+ cand = self.findlines(old[0][1:], search_start)
+ for l in cand:
+ if diffhelpers.testhunk(old, self.lines, l) == 0:
+ newlines = h.new(fuzzlen, toponly)
+ self.lines[l : l + len(old)] = newlines
+ self.offset += len(newlines) - len(old)
+ self.dirty = 1
+ if fuzzlen:
+ fuzzstr = "with fuzz %d " % fuzzlen
+ f = self.ui.warn
+ self.printfile(True)
+ else:
+ fuzzstr = ""
+ f = self.ui.note
+ offset = l - orig_start - fuzzlen
+ if offset == 1:
+ msg = _("Hunk #%d succeeded at %d %s"
+ "(offset %d line).\n")
+ else:
+ msg = _("Hunk #%d succeeded at %d %s"
+ "(offset %d lines).\n")
+ f(msg % (h.number, l+1, fuzzstr, offset))
+ return fuzzlen
+ self.printfile(True)
+ self.ui.warn(_("Hunk #%d FAILED at %d\n") % (h.number, orig_start))
+ self.rej.append(h)
+ return -1
+
+class hunk(object):
+ def __init__(self, desc, num, lr, context, create=False, remove=False):
+ self.number = num
+ self.desc = desc
+ self.hunk = [ desc ]
+ self.a = []
+ self.b = []
+ if context:
+ self.read_context_hunk(lr)
+ else:
+ self.read_unified_hunk(lr)
+ self.create = create
+ self.remove = remove and not create
+
+ def read_unified_hunk(self, lr):
+ m = unidesc.match(self.desc)
+ if not m:
+ raise PatchError(_("bad hunk #%d") % self.number)
+ self.starta, foo, self.lena, self.startb, foo2, self.lenb = m.groups()
+ if self.lena is None:
+ self.lena = 1
+ else:
+ self.lena = int(self.lena)
+ if self.lenb is None:
+ self.lenb = 1
+ else:
+ self.lenb = int(self.lenb)
+ self.starta = int(self.starta)
+ self.startb = int(self.startb)
+ diffhelpers.addlines(lr, self.hunk, self.lena, self.lenb, self.a, self.b)
+ # if we hit eof before finishing out the hunk, the last line will
+ # be zero length. Lets try to fix it up.
+ while len(self.hunk[-1]) == 0:
+ del self.hunk[-1]
+ del self.a[-1]
+ del self.b[-1]
+ self.lena -= 1
+ self.lenb -= 1
+
+ def read_context_hunk(self, lr):
+ self.desc = lr.readline()
+ m = contextdesc.match(self.desc)
+ if not m:
+ raise PatchError(_("bad hunk #%d") % self.number)
+ foo, self.starta, foo2, aend, foo3 = m.groups()
+ self.starta = int(self.starta)
+ if aend is None:
+ aend = self.starta
+ self.lena = int(aend) - self.starta
+ if self.starta:
+ self.lena += 1
+ for x in xrange(self.lena):
+ l = lr.readline()
+ if l.startswith('---'):
+ lr.push(l)
+ break
+ s = l[2:]
+ if l.startswith('- ') or l.startswith('! '):
+ u = '-' + s
+ elif l.startswith(' '):
+ u = ' ' + s
+ else:
+ raise PatchError(_("bad hunk #%d old text line %d") %
+ (self.number, x))
+ self.a.append(u)
+ self.hunk.append(u)
+
+ l = lr.readline()
+ if l.startswith('\ '):
+ s = self.a[-1][:-1]
+ self.a[-1] = s
+ self.hunk[-1] = s
+ l = lr.readline()
+ m = contextdesc.match(l)
+ if not m:
+ raise PatchError(_("bad hunk #%d") % self.number)
+ foo, self.startb, foo2, bend, foo3 = m.groups()
+ self.startb = int(self.startb)
+ if bend is None:
+ bend = self.startb
+ self.lenb = int(bend) - self.startb
+ if self.startb:
+ self.lenb += 1
+ hunki = 1
+ for x in xrange(self.lenb):
+ l = lr.readline()
+ if l.startswith('\ '):
+ s = self.b[-1][:-1]
+ self.b[-1] = s
+ self.hunk[hunki-1] = s
+ continue
+ if not l:
+ lr.push(l)
+ break
+ s = l[2:]
+ if l.startswith('+ ') or l.startswith('! '):
+ u = '+' + s
+ elif l.startswith(' '):
+ u = ' ' + s
+ elif len(self.b) == 0:
+ # this can happen when the hunk does not add any lines
+ lr.push(l)
+ break
+ else:
+ raise PatchError(_("bad hunk #%d old text line %d") %
+ (self.number, x))
+ self.b.append(s)
+ while True:
+ if hunki >= len(self.hunk):
+ h = ""
+ else:
+ h = self.hunk[hunki]
+ hunki += 1
+ if h == u:
+ break
+ elif h.startswith('-'):
+ continue
+ else:
+ self.hunk.insert(hunki-1, u)
+ break
+
+ if not self.a:
+ # this happens when lines were only added to the hunk
+ for x in self.hunk:
+ if x.startswith('-') or x.startswith(' '):
+ self.a.append(x)
+ if not self.b:
+ # this happens when lines were only deleted from the hunk
+ for x in self.hunk:
+ if x.startswith('+') or x.startswith(' '):
+ self.b.append(x[1:])
+ # @@ -start,len +start,len @@
+ self.desc = "@@ -%d,%d +%d,%d @@\n" % (self.starta, self.lena,
+ self.startb, self.lenb)
+ self.hunk[0] = self.desc
+
+ def reverse(self):
+ self.create, self.remove = self.remove, self.create
+ origlena = self.lena
+ origstarta = self.starta
+ self.lena = self.lenb
+ self.starta = self.startb
+ self.lenb = origlena
+ self.startb = origstarta
+ self.a = []
+ self.b = []
+ # self.hunk[0] is the @@ description
+ for x in xrange(1, len(self.hunk)):
+ o = self.hunk[x]
+ if o.startswith('-'):
+ n = '+' + o[1:]
+ self.b.append(o[1:])
+ elif o.startswith('+'):
+ n = '-' + o[1:]
+ self.a.append(n)
+ else:
+ n = o
+ self.b.append(o[1:])
+ self.a.append(o)
+ self.hunk[x] = o
+
+ def fix_newline(self):
+ diffhelpers.fix_newline(self.hunk, self.a, self.b)
+
+ def complete(self):
+ return len(self.a) == self.lena and len(self.b) == self.lenb
+
+ def createfile(self):
+ return self.starta == 0 and self.lena == 0 and self.create
+
+ def rmfile(self):
+ return self.startb == 0 and self.lenb == 0 and self.remove
+
+ def fuzzit(self, l, fuzz, toponly):
+ # this removes context lines from the top and bottom of list 'l'. It
+ # checks the hunk to make sure only context lines are removed, and then
+ # returns a new shortened list of lines.
+ fuzz = min(fuzz, len(l)-1)
+ if fuzz:
+ top = 0
+ bot = 0
+ hlen = len(self.hunk)
+ for x in xrange(hlen-1):
+ # the hunk starts with the @@ line, so use x+1
+ if self.hunk[x+1][0] == ' ':
+ top += 1
+ else:
+ break
+ if not toponly:
+ for x in xrange(hlen-1):
+ if self.hunk[hlen-bot-1][0] == ' ':
+ bot += 1
+ else:
+ break
+
+ # top and bot now count context in the hunk
+ # adjust them if either one is short
+ context = max(top, bot, 3)
+ if bot < context:
+ bot = max(0, fuzz - (context - bot))
+ else:
+ bot = min(fuzz, bot)
+ if top < context:
+ top = max(0, fuzz - (context - top))
+ else:
+ top = min(fuzz, top)
+
+ return l[top:len(l)-bot]
+ return l
+
+ def old(self, fuzz=0, toponly=False):
+ return self.fuzzit(self.a, fuzz, toponly)
+
+ def newctrl(self):
+ res = []
+ for x in self.hunk:
+ c = x[0]
+ if c == ' ' or c == '+':
+ res.append(x)
+ return res
+
+ def new(self, fuzz=0, toponly=False):
+ return self.fuzzit(self.b, fuzz, toponly)
+
+class githunk(object):
+ """A git hunk"""
+ def __init__(self, gitpatch):
+ self.gitpatch = gitpatch
+ self.text = None
+ self.hunk = []
+
+ def createfile(self):
+ return self.gitpatch.op in ('ADD', 'RENAME', 'COPY')
+
+ def rmfile(self):
+ return self.gitpatch.op == 'DELETE'
+
+ def complete(self):
+ return self.text is not None
+
+ def new(self):
+ return [self.text]
+
+class binhunk(githunk):
+ 'A binary patch file. Only understands literals so far.'
+ def __init__(self, gitpatch):
+ super(binhunk, self).__init__(gitpatch)
+ self.hunk = ['GIT binary patch\n']
+
+ def extract(self, lr):
+ line = lr.readline()
+ self.hunk.append(line)
+ while line and not line.startswith('literal '):
+ line = lr.readline()
+ self.hunk.append(line)
+ if not line:
+ raise PatchError(_('could not extract binary patch'))
+ size = int(line[8:].rstrip())
+ dec = []
+ line = lr.readline()
+ self.hunk.append(line)
+ while len(line) > 1:
+ l = line[0]
+ if l <= 'Z' and l >= 'A':
+ l = ord(l) - ord('A') + 1
+ else:
+ l = ord(l) - ord('a') + 27
+ dec.append(base85.b85decode(line[1:-1])[:l])
+ line = lr.readline()
+ self.hunk.append(line)
+ text = zlib.decompress(''.join(dec))
+ if len(text) != size:
+ raise PatchError(_('binary patch is %d bytes, not %d') %
+ len(text), size)
+ self.text = text
+
+class symlinkhunk(githunk):
+ """A git symlink hunk"""
+ def __init__(self, gitpatch, hunk):
+ super(symlinkhunk, self).__init__(gitpatch)
+ self.hunk = hunk
+
+ def complete(self):
+ return True
+
+ def fix_newline(self):
+ return
+
+def parsefilename(str):
+ # --- filename \t|space stuff
+ s = str[4:].rstrip('\r\n')
+ i = s.find('\t')
+ if i < 0:
+ i = s.find(' ')
+ if i < 0:
+ return s
+ return s[:i]
+
+def selectfile(afile_orig, bfile_orig, hunk, strip, reverse):
+ def pathstrip(path, count=1):
+ pathlen = len(path)
+ i = 0
+ if count == 0:
+ return '', path.rstrip()
+ while count > 0:
+ i = path.find('/', i)
+ if i == -1:
+ raise PatchError(_("unable to strip away %d dirs from %s") %
+ (count, path))
+ i += 1
+ # consume '//' in the path
+ while i < pathlen - 1 and path[i] == '/':
+ i += 1
+ count -= 1
+ return path[:i].lstrip(), path[i:].rstrip()
+
+ nulla = afile_orig == "/dev/null"
+ nullb = bfile_orig == "/dev/null"
+ abase, afile = pathstrip(afile_orig, strip)
+ gooda = not nulla and util.lexists(afile)
+ bbase, bfile = pathstrip(bfile_orig, strip)
+ if afile == bfile:
+ goodb = gooda
+ else:
+ goodb = not nullb and os.path.exists(bfile)
+ createfunc = hunk.createfile
+ if reverse:
+ createfunc = hunk.rmfile
+ missing = not goodb and not gooda and not createfunc()
+
+ # some diff programs apparently produce create patches where the
+ # afile is not /dev/null, but rather the same name as the bfile
+ if missing and afile == bfile:
+ # this isn't very pretty
+ hunk.create = True
+ if createfunc():
+ missing = False
+ else:
+ hunk.create = False
+
+ # If afile is "a/b/foo" and bfile is "a/b/foo.orig" we assume the
+ # diff is between a file and its backup. In this case, the original
+ # file should be patched (see original mpatch code).
+ isbackup = (abase == bbase and bfile.startswith(afile))
+ fname = None
+ if not missing:
+ if gooda and goodb:
+ fname = isbackup and afile or bfile
+ elif gooda:
+ fname = afile
+
+ if not fname:
+ if not nullb:
+ fname = isbackup and afile or bfile
+ elif not nulla:
+ fname = afile
+ else:
+ raise PatchError(_("undefined source and destination files"))
+
+ return fname, missing
+
+def scangitpatch(lr, firstline):
+ """
+ Git patches can emit:
+ - rename a to b
+ - change b
+ - copy a to c
+ - change c
+
+ We cannot apply this sequence as-is, the renamed 'a' could not be
+ found for it would have been renamed already. And we cannot copy
+ from 'b' instead because 'b' would have been changed already. So
+ we scan the git patch for copy and rename commands so we can
+ perform the copies ahead of time.
+ """
+ pos = 0
+ try:
+ pos = lr.fp.tell()
+ fp = lr.fp
+ except IOError:
+ fp = cStringIO.StringIO(lr.fp.read())
+ gitlr = linereader(fp, lr.textmode)
+ gitlr.push(firstline)
+ (dopatch, gitpatches) = readgitpatch(gitlr)
+ fp.seek(pos)
+ return dopatch, gitpatches
+
+def iterhunks(ui, fp, sourcefile=None, textmode=False):
+ """Read a patch and yield the following events:
+ - ("file", afile, bfile, firsthunk): select a new target file.
+ - ("hunk", hunk): a new hunk is ready to be applied, follows a
+ "file" event.
+ - ("git", gitchanges): current diff is in git format, gitchanges
+ maps filenames to gitpatch records. Unique event.
+
+ If textmode is True, input line-endings are normalized to LF.
+ """
+ changed = {}
+ current_hunk = None
+ afile = ""
+ bfile = ""
+ state = None
+ hunknum = 0
+ emitfile = False
+ git = False
+
+ # our states
+ BFILE = 1
+ context = None
+ lr = linereader(fp, textmode)
+ dopatch = True
+ # gitworkdone is True if a git operation (copy, rename, ...) was
+ # performed already for the current file. Useful when the file
+ # section may have no hunk.
+ gitworkdone = False
+
+ while True:
+ newfile = False
+ x = lr.readline()
+ if not x:
+ break
+ if current_hunk:
+ if x.startswith('\ '):
+ current_hunk.fix_newline()
+ yield 'hunk', current_hunk
+ current_hunk = None
+ gitworkdone = False
+ if ((sourcefile or state == BFILE) and ((not context and x[0] == '@') or
+ ((context is not False) and x.startswith('***************')))):
+ try:
+ if context is None and x.startswith('***************'):
+ context = True
+ gpatch = changed.get(bfile)
+ create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
+ remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE'
+ current_hunk = hunk(x, hunknum + 1, lr, context, create, remove)
+ if remove:
+ gpatch = changed.get(afile[2:])
+ if gpatch and gpatch.mode[0]:
+ current_hunk = symlinkhunk(gpatch, current_hunk)
+ except PatchError, err:
+ ui.debug(err)
+ current_hunk = None
+ continue
+ hunknum += 1
+ if emitfile:
+ emitfile = False
+ yield 'file', (afile, bfile, current_hunk)
+ elif state == BFILE and x.startswith('GIT binary patch'):
+ current_hunk = binhunk(changed[bfile])
+ hunknum += 1
+ if emitfile:
+ emitfile = False
+ yield 'file', ('a/' + afile, 'b/' + bfile, current_hunk)
+ current_hunk.extract(lr)
+ elif x.startswith('diff --git'):
+ # check for git diff, scanning the whole patch file if needed
+ m = gitre.match(x)
+ if m:
+ afile, bfile = m.group(1, 2)
+ if not git:
+ git = True
+ dopatch, gitpatches = scangitpatch(lr, x)
+ yield 'git', gitpatches
+ for gp in gitpatches:
+ changed[gp.path] = gp
+ # else error?
+ # copy/rename + modify should modify target, not source
+ gp = changed.get(bfile)
+ if gp and gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD'):
+ afile = bfile
+ gitworkdone = True
+ newfile = True
+ elif x.startswith('---'):
+ # check for a unified diff
+ l2 = lr.readline()
+ if not l2.startswith('+++'):
+ lr.push(l2)
+ continue
+ newfile = True
+ context = False
+ afile = parsefilename(x)
+ bfile = parsefilename(l2)
+ elif x.startswith('***'):
+ # check for a context diff
+ l2 = lr.readline()
+ if not l2.startswith('---'):
+ lr.push(l2)
+ continue
+ l3 = lr.readline()
+ lr.push(l3)
+ if not l3.startswith("***************"):
+ lr.push(l2)
+ continue
+ newfile = True
+ context = True
+ afile = parsefilename(x)
+ bfile = parsefilename(l2)
+
+ if newfile:
+ emitfile = True
+ state = BFILE
+ hunknum = 0
+ if current_hunk:
+ if current_hunk.complete():
+ yield 'hunk', current_hunk
+ else:
+ raise PatchError(_("malformed patch %s %s") % (afile,
+ current_hunk.desc))
+
+ if hunknum == 0 and dopatch and not gitworkdone:
+ raise NoHunks
+
+def applydiff(ui, fp, changed, strip=1, sourcefile=None, reverse=False,
+ eol=None):
+ """
+ Reads a patch from fp and tries to apply it.
+
+ The dict 'changed' is filled in with all of the filenames changed
+ by the patch. Returns 0 for a clean patch, -1 if any rejects were
+ found and 1 if there was any fuzz.
+
+ If 'eol' is None, the patch content and patched file are read in
+ binary mode. Otherwise, line endings are ignored when patching then
+ normalized to 'eol' (usually '\n' or \r\n').
+ """
+ rejects = 0
+ err = 0
+ current_file = None
+ gitpatches = None
+ opener = util.opener(os.getcwd())
+ textmode = eol is not None
+
+ def closefile():
+ if not current_file:
+ return 0
+ current_file.close()
+ return len(current_file.rej)
+
+ for state, values in iterhunks(ui, fp, sourcefile, textmode):
+ if state == 'hunk':
+ if not current_file:
+ continue
+ current_hunk = values
+ ret = current_file.apply(current_hunk, reverse)
+ if ret >= 0:
+ changed.setdefault(current_file.fname, None)
+ if ret > 0:
+ err = 1
+ elif state == 'file':
+ rejects += closefile()
+ afile, bfile, first_hunk = values
+ try:
+ if sourcefile:
+ current_file = patchfile(ui, sourcefile, opener, eol=eol)
+ else:
+ current_file, missing = selectfile(afile, bfile, first_hunk,
+ strip, reverse)
+ current_file = patchfile(ui, current_file, opener, missing, eol)
+ except PatchError, err:
+ ui.warn(str(err) + '\n')
+ current_file, current_hunk = None, None
+ rejects += 1
+ continue
+ elif state == 'git':
+ gitpatches = values
+ cwd = os.getcwd()
+ for gp in gitpatches:
+ if gp.op in ('COPY', 'RENAME'):
+ copyfile(gp.oldpath, gp.path, cwd)
+ changed[gp.path] = gp
+ else:
+ raise util.Abort(_('unsupported parser state: %s') % state)
+
+ rejects += closefile()
+
+ if rejects:
+ return -1
+ return err
+
+def diffopts(ui, opts={}, untrusted=False):
+ def get(key, name=None, getter=ui.configbool):
+ return (opts.get(key) or
+ getter('diff', name or key, None, untrusted=untrusted))
+ return mdiff.diffopts(
+ text=opts.get('text'),
+ git=get('git'),
+ nodates=get('nodates'),
+ showfunc=get('show_function', 'showfunc'),
+ ignorews=get('ignore_all_space', 'ignorews'),
+ ignorewsamount=get('ignore_space_change', 'ignorewsamount'),
+ ignoreblanklines=get('ignore_blank_lines', 'ignoreblanklines'),
+ context=get('unified', getter=ui.config))
+
+def updatedir(ui, repo, patches, similarity=0):
+ '''Update dirstate after patch application according to metadata'''
+ if not patches:
+ return
+ copies = []
+ removes = set()
+ cfiles = patches.keys()
+ cwd = repo.getcwd()
+ if cwd:
+ cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
+ for f in patches:
+ gp = patches[f]
+ if not gp:
+ continue
+ if gp.op == 'RENAME':
+ copies.append((gp.oldpath, gp.path))
+ removes.add(gp.oldpath)
+ elif gp.op == 'COPY':
+ copies.append((gp.oldpath, gp.path))
+ elif gp.op == 'DELETE':
+ removes.add(gp.path)
+ for src, dst in copies:
+ repo.copy(src, dst)
+ if (not similarity) and removes:
+ repo.remove(sorted(removes), True)
+ for f in patches:
+ gp = patches[f]
+ if gp and gp.mode:
+ islink, isexec = gp.mode
+ dst = repo.wjoin(gp.path)
+ # patch won't create empty files
+ if gp.op == 'ADD' and not os.path.exists(dst):
+ flags = (isexec and 'x' or '') + (islink and 'l' or '')
+ repo.wwrite(gp.path, '', flags)
+ elif gp.op != 'DELETE':
+ util.set_flags(dst, islink, isexec)
+ cmdutil.addremove(repo, cfiles, similarity=similarity)
+ files = patches.keys()
+ files.extend([r for r in removes if r not in files])
+ return sorted(files)
+
+def externalpatch(patcher, args, patchname, ui, strip, cwd, files):
+ """use <patcher> to apply <patchname> to the working directory.
+ returns whether patch was applied with fuzz factor."""
+
+ fuzz = False
+ if cwd:
+ args.append('-d %s' % util.shellquote(cwd))
+ fp = util.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip,
+ util.shellquote(patchname)))
+
+ for line in fp:
+ line = line.rstrip()
+ ui.note(line + '\n')
+ if line.startswith('patching file '):
+ pf = util.parse_patch_output(line)
+ printed_file = False
+ files.setdefault(pf, None)
+ elif line.find('with fuzz') >= 0:
+ fuzz = True
+ if not printed_file:
+ ui.warn(pf + '\n')
+ printed_file = True
+ ui.warn(line + '\n')
+ elif line.find('saving rejects to file') >= 0:
+ ui.warn(line + '\n')
+ elif line.find('FAILED') >= 0:
+ if not printed_file:
+ ui.warn(pf + '\n')
+ printed_file = True
+ ui.warn(line + '\n')
+ code = fp.close()
+ if code:
+ raise PatchError(_("patch command failed: %s") %
+ util.explain_exit(code)[0])
+ return fuzz
+
+def internalpatch(patchobj, ui, strip, cwd, files={}, eolmode='strict'):
+ """use builtin patch to apply <patchobj> to the working directory.
+ returns whether patch was applied with fuzz factor."""
+
+ if eolmode is None:
+ eolmode = ui.config('patch', 'eol', 'strict')
+ try:
+ eol = {'strict': None, 'crlf': '\r\n', 'lf': '\n'}[eolmode.lower()]
+ except KeyError:
+ raise util.Abort(_('Unsupported line endings type: %s') % eolmode)
+
+ try:
+ fp = open(patchobj, 'rb')
+ except TypeError:
+ fp = patchobj
+ if cwd:
+ curdir = os.getcwd()
+ os.chdir(cwd)
+ try:
+ ret = applydiff(ui, fp, files, strip=strip, eol=eol)
+ finally:
+ if cwd:
+ os.chdir(curdir)
+ if ret < 0:
+ raise PatchError
+ return ret > 0
+
+def patch(patchname, ui, strip=1, cwd=None, files={}, eolmode='strict'):
+ """Apply <patchname> to the working directory.
+
+ 'eolmode' specifies how end of lines should be handled. It can be:
+ - 'strict': inputs are read in binary mode, EOLs are preserved
+ - 'crlf': EOLs are ignored when patching and reset to CRLF
+ - 'lf': EOLs are ignored when patching and reset to LF
+ - None: get it from user settings, default to 'strict'
+ 'eolmode' is ignored when using an external patcher program.
+
+ Returns whether patch was applied with fuzz factor.
+ """
+ patcher = ui.config('ui', 'patch')
+ args = []
+ try:
+ if patcher:
+ return externalpatch(patcher, args, patchname, ui, strip, cwd,
+ files)
+ else:
+ try:
+ return internalpatch(patchname, ui, strip, cwd, files, eolmode)
+ except NoHunks:
+ patcher = util.find_exe('gpatch') or util.find_exe('patch') or 'patch'
+ ui.debug(_('no valid hunks found; trying with %r instead\n') %
+ patcher)
+ if util.needbinarypatch():
+ args.append('--binary')
+ return externalpatch(patcher, args, patchname, ui, strip, cwd,
+ files)
+ except PatchError, err:
+ s = str(err)
+ if s:
+ raise util.Abort(s)
+ else:
+ raise util.Abort(_('patch failed to apply'))
+
+def b85diff(to, tn):
+ '''print base85-encoded binary diff'''
+ def gitindex(text):
+ if not text:
+ return '0' * 40
+ l = len(text)
+ s = util.sha1('blob %d\0' % l)
+ s.update(text)
+ return s.hexdigest()
+
+ def fmtline(line):
+ l = len(line)
+ if l <= 26:
+ l = chr(ord('A') + l - 1)
+ else:
+ l = chr(l - 26 + ord('a') - 1)
+ return '%c%s\n' % (l, base85.b85encode(line, True))
+
+ def chunk(text, csize=52):
+ l = len(text)
+ i = 0
+ while i < l:
+ yield text[i:i+csize]
+ i += csize
+
+ tohash = gitindex(to)
+ tnhash = gitindex(tn)
+ if tohash == tnhash:
+ return ""
+
+ # TODO: deltas
+ ret = ['index %s..%s\nGIT binary patch\nliteral %s\n' %
+ (tohash, tnhash, len(tn))]
+ for l in chunk(zlib.compress(tn)):
+ ret.append(fmtline(l))
+ ret.append('\n')
+ return ''.join(ret)
+
+def _addmodehdr(header, omode, nmode):
+ if omode != nmode:
+ header.append('old mode %s\n' % omode)
+ header.append('new mode %s\n' % nmode)
+
+def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None):
+ '''yields diff of changes to files between two nodes, or node and
+ working directory.
+
+ if node1 is None, use first dirstate parent instead.
+ if node2 is None, compare node1 with working directory.'''
+
+ if opts is None:
+ opts = mdiff.defaultopts
+
+ if not node1:
+ node1 = repo.dirstate.parents()[0]
+
+ def lrugetfilectx():
+ cache = {}
+ order = []
+ def getfilectx(f, ctx):
+ fctx = ctx.filectx(f, filelog=cache.get(f))
+ if f not in cache:
+ if len(cache) > 20:
+ del cache[order.pop(0)]
+ cache[f] = fctx._filelog
+ else:
+ order.remove(f)
+ order.append(f)
+ return fctx
+ return getfilectx
+ getfilectx = lrugetfilectx()
+
+ ctx1 = repo[node1]
+ ctx2 = repo[node2]
+
+ if not changes:
+ changes = repo.status(ctx1, ctx2, match=match)
+ modified, added, removed = changes[:3]
+
+ if not modified and not added and not removed:
+ return
+
+ date1 = util.datestr(ctx1.date())
+ man1 = ctx1.manifest()
+
+ if repo.ui.quiet:
+ r = None
+ else:
+ hexfunc = repo.ui.debugflag and hex or short
+ r = [hexfunc(node) for node in [node1, node2] if node]
+
+ if opts.git:
+ copy, diverge = copies.copies(repo, ctx1, ctx2, repo[nullid])
+ copy = copy.copy()
+ for k, v in copy.items():
+ copy[v] = k
+
+ gone = set()
+ gitmode = {'l': '120000', 'x': '100755', '': '100644'}
+
+ for f in sorted(modified + added + removed):
+ to = None
+ tn = None
+ dodiff = True
+ header = []
+ if f in man1:
+ to = getfilectx(f, ctx1).data()
+ if f not in removed:
+ tn = getfilectx(f, ctx2).data()
+ a, b = f, f
+ if opts.git:
+ if f in added:
+ mode = gitmode[ctx2.flags(f)]
+ if f in copy:
+ a = copy[f]
+ omode = gitmode[man1.flags(a)]
+ _addmodehdr(header, omode, mode)
+ if a in removed and a not in gone:
+ op = 'rename'
+ gone.add(a)
+ else:
+ op = 'copy'
+ header.append('%s from %s\n' % (op, a))
+ header.append('%s to %s\n' % (op, f))
+ to = getfilectx(a, ctx1).data()
+ else:
+ header.append('new file mode %s\n' % mode)
+ if util.binary(tn):
+ dodiff = 'binary'
+ elif f in removed:
+ # have we already reported a copy above?
+ if f in copy and copy[f] in added and copy[copy[f]] == f:
+ dodiff = False
+ else:
+ header.append('deleted file mode %s\n' %
+ gitmode[man1.flags(f)])
+ else:
+ omode = gitmode[man1.flags(f)]
+ nmode = gitmode[ctx2.flags(f)]
+ _addmodehdr(header, omode, nmode)
+ if util.binary(to) or util.binary(tn):
+ dodiff = 'binary'
+ r = None
+ header.insert(0, mdiff.diffline(r, a, b, opts))
+ if dodiff:
+ if dodiff == 'binary':
+ text = b85diff(to, tn)
+ else:
+ text = mdiff.unidiff(to, date1,
+ # ctx2 date may be dynamic
+ tn, util.datestr(ctx2.date()),
+ a, b, r, opts=opts)
+ if header and (text or len(header) > 1):
+ yield ''.join(header)
+ if text:
+ yield text
+
+def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
+ opts=None):
+ '''export changesets as hg patches.'''
+
+ total = len(revs)
+ revwidth = max([len(str(rev)) for rev in revs])
+
+ def single(rev, seqno, fp):
+ ctx = repo[rev]
+ node = ctx.node()
+ parents = [p.node() for p in ctx.parents() if p]
+ branch = ctx.branch()
+ if switch_parent:
+ parents.reverse()
+ prev = (parents and parents[0]) or nullid
+
+ if not fp:
+ fp = cmdutil.make_file(repo, template, node, total=total,
+ seqno=seqno, revwidth=revwidth,
+ mode='ab')
+ if fp != sys.stdout and hasattr(fp, 'name'):
+ repo.ui.note("%s\n" % fp.name)
+
+ fp.write("# HG changeset patch\n")
+ fp.write("# User %s\n" % ctx.user())
+ fp.write("# Date %d %d\n" % ctx.date())
+ if branch and (branch != 'default'):
+ fp.write("# Branch %s\n" % branch)
+ fp.write("# Node ID %s\n" % hex(node))
+ fp.write("# Parent %s\n" % hex(prev))
+ if len(parents) > 1:
+ fp.write("# Parent %s\n" % hex(parents[1]))
+ fp.write(ctx.description().rstrip())
+ fp.write("\n\n")
+
+ for chunk in diff(repo, prev, node, opts=opts):
+ fp.write(chunk)
+
+ for seqno, rev in enumerate(revs):
+ single(rev, seqno+1, fp)
+
+def diffstatdata(lines):
+ filename, adds, removes = None, 0, 0
+ for line in lines:
+ if line.startswith('diff'):
+ if filename:
+ yield (filename, adds, removes)
+ # set numbers to 0 anyway when starting new file
+ adds, removes = 0, 0
+ if line.startswith('diff --git'):
+ filename = gitre.search(line).group(1)
+ else:
+ # format: "diff -r ... -r ... filename"
+ filename = line.split(None, 5)[-1]
+ elif line.startswith('+') and not line.startswith('+++'):
+ adds += 1
+ elif line.startswith('-') and not line.startswith('---'):
+ removes += 1
+ if filename:
+ yield (filename, adds, removes)
+
+def diffstat(lines, width=80):
+ output = []
+ stats = list(diffstatdata(lines))
+
+ maxtotal, maxname = 0, 0
+ totaladds, totalremoves = 0, 0
+ for filename, adds, removes in stats:
+ totaladds += adds
+ totalremoves += removes
+ maxname = max(maxname, len(filename))
+ maxtotal = max(maxtotal, adds+removes)
+
+ countwidth = len(str(maxtotal))
+ graphwidth = width - countwidth - maxname - 6
+ if graphwidth < 10:
+ graphwidth = 10
+
+ def scale(i):
+ if maxtotal <= graphwidth:
+ return i
+ # If diffstat runs out of room it doesn't print anything,
+ # which isn't very useful, so always print at least one + or -
+ # if there were at least some changes.
+ return max(i * graphwidth // maxtotal, int(bool(i)))
+
+ for filename, adds, removes in stats:
+ pluses = '+' * scale(adds)
+ minuses = '-' * scale(removes)
+ output.append(' %-*s | %*.d %s%s\n' % (maxname, filename, countwidth,
+ adds+removes, pluses, minuses))
+
+ if stats:
+ output.append(_(' %d files changed, %d insertions(+), %d deletions(-)\n')
+ % (len(stats), totaladds, totalremoves))
+
+ return ''.join(output)
diff --git a/sys/src/cmd/hg/mercurial/posix.py b/sys/src/cmd/hg/mercurial/posix.py
new file mode 100644
index 000000000..09fd7cdc5
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/posix.py
@@ -0,0 +1,252 @@
+# posix.py - Posix utility function implementations for Mercurial
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import osutil
+import os, sys, errno, stat, getpass, pwd, grp, fcntl
+
+posixfile = open
+nulldev = '/dev/null'
+normpath = os.path.normpath
+samestat = os.path.samestat
+expandglobs = False
+
+umask = os.umask(0)
+os.umask(umask)
+
+def openhardlinks():
+ '''return true if it is safe to hold open file handles to hardlinks'''
+ return True
+
+def rcfiles(path):
+ rcs = [os.path.join(path, 'hgrc')]
+ rcdir = os.path.join(path, 'hgrc.d')
+ try:
+ rcs.extend([os.path.join(rcdir, f)
+ for f, kind in osutil.listdir(rcdir)
+ if f.endswith(".rc")])
+ except OSError:
+ pass
+ return rcs
+
+def system_rcpath():
+ path = []
+ # old mod_python does not set sys.argv
+ if len(getattr(sys, 'argv', [])) > 0:
+ path.extend(rcfiles(os.path.dirname(sys.argv[0]) +
+ '/../etc/mercurial'))
+ path.extend(rcfiles('/etc/mercurial'))
+ return path
+
+def user_rcpath():
+ return [os.path.expanduser('~/.hgrc')]
+
+def parse_patch_output(output_line):
+ """parses the output produced by patch and returns the filename"""
+ pf = output_line[14:]
+ if os.sys.platform == 'OpenVMS':
+ if pf[0] == '`':
+ pf = pf[1:-1] # Remove the quotes
+ else:
+ if pf.startswith("'") and pf.endswith("'") and " " in pf:
+ pf = pf[1:-1] # Remove the quotes
+ return pf
+
+def sshargs(sshcmd, host, user, port):
+ '''Build argument list for ssh'''
+ args = user and ("%s@%s" % (user, host)) or host
+ return port and ("%s -p %s" % (args, port)) or args
+
+def is_exec(f):
+ """check whether a file is executable"""
+ return (os.lstat(f).st_mode & 0100 != 0)
+
+def set_flags(f, l, x):
+ s = os.lstat(f).st_mode
+ if l:
+ if not stat.S_ISLNK(s):
+ # switch file to link
+ data = open(f).read()
+ os.unlink(f)
+ try:
+ os.symlink(data, f)
+ except:
+ # failed to make a link, rewrite file
+ open(f, "w").write(data)
+ # no chmod needed at this point
+ return
+ if stat.S_ISLNK(s):
+ # switch link to file
+ data = os.readlink(f)
+ os.unlink(f)
+ open(f, "w").write(data)
+ s = 0666 & ~umask # avoid restatting for chmod
+
+ sx = s & 0100
+ if x and not sx:
+ # Turn on +x for every +r bit when making a file executable
+ # and obey umask.
+ os.chmod(f, s | (s & 0444) >> 2 & ~umask)
+ elif not x and sx:
+ # Turn off all +x bits
+ os.chmod(f, s & 0666)
+
+def set_binary(fd):
+ pass
+
+def pconvert(path):
+ return path
+
+def localpath(path):
+ return path
+
+if sys.platform == 'darwin':
+ def realpath(path):
+ '''
+ Returns the true, canonical file system path equivalent to the given
+ path.
+
+ Equivalent means, in this case, resulting in the same, unique
+ file system link to the path. Every file system entry, whether a file,
+ directory, hard link or symbolic link or special, will have a single
+ path preferred by the system, but may allow multiple, differing path
+ lookups to point to it.
+
+ Most regular UNIX file systems only allow a file system entry to be
+ looked up by its distinct path. Obviously, this does not apply to case
+ insensitive file systems, whether case preserving or not. The most
+ complex issue to deal with is file systems transparently reencoding the
+ path, such as the non-standard Unicode normalisation required for HFS+
+ and HFSX.
+ '''
+ # Constants copied from /usr/include/sys/fcntl.h
+ F_GETPATH = 50
+ O_SYMLINK = 0x200000
+
+ try:
+ fd = os.open(path, O_SYMLINK)
+ except OSError, err:
+ if err.errno is errno.ENOENT:
+ return path
+ raise
+
+ try:
+ return fcntl.fcntl(fd, F_GETPATH, '\0' * 1024).rstrip('\0')
+ finally:
+ os.close(fd)
+else:
+ # Fallback to the likely inadequate Python builtin function.
+ realpath = os.path.realpath
+
+def shellquote(s):
+ if os.sys.platform == 'OpenVMS':
+ return '"%s"' % s
+ else:
+ return "'%s'" % s.replace("'", "'\\''")
+
+def quotecommand(cmd):
+ return cmd
+
+def popen(command, mode='r'):
+ return os.popen(command, mode)
+
+def testpid(pid):
+ '''return False if pid dead, True if running or not sure'''
+ if os.sys.platform == 'OpenVMS':
+ return True
+ try:
+ os.kill(pid, 0)
+ return True
+ except OSError, inst:
+ return inst.errno != errno.ESRCH
+
+def explain_exit(code):
+ """return a 2-tuple (desc, code) describing a process's status"""
+ if os.WIFEXITED(code):
+ val = os.WEXITSTATUS(code)
+ return _("exited with status %d") % val, val
+ elif os.WIFSIGNALED(code):
+ val = os.WTERMSIG(code)
+ return _("killed by signal %d") % val, val
+ elif os.WIFSTOPPED(code):
+ val = os.WSTOPSIG(code)
+ return _("stopped by signal %d") % val, val
+ raise ValueError(_("invalid exit code"))
+
+def isowner(st):
+ """Return True if the stat object st is from the current user."""
+ return st.st_uid == os.getuid()
+
+def find_exe(command):
+ '''Find executable for command searching like which does.
+ If command is a basename then PATH is searched for command.
+ PATH isn't searched if command is an absolute or relative path.
+ If command isn't found None is returned.'''
+ if sys.platform == 'OpenVMS':
+ return command
+
+ def findexisting(executable):
+ 'Will return executable if existing file'
+ if os.path.exists(executable):
+ return executable
+ return None
+
+ if os.sep in command:
+ return findexisting(command)
+
+ for path in os.environ.get('PATH', '').split(os.pathsep):
+ executable = findexisting(os.path.join(path, command))
+ if executable is not None:
+ return executable
+ return None
+
+def set_signal_handler():
+ pass
+
+def statfiles(files):
+ 'Stat each file in files and yield stat or None if file does not exist.'
+ lstat = os.lstat
+ for nf in files:
+ try:
+ st = lstat(nf)
+ except OSError, err:
+ if err.errno not in (errno.ENOENT, errno.ENOTDIR):
+ raise
+ st = None
+ yield st
+
+def getuser():
+ '''return name of current user'''
+ return getpass.getuser()
+
+def expand_glob(pats):
+ '''On Windows, expand the implicit globs in a list of patterns'''
+ return list(pats)
+
+def username(uid=None):
+ """Return the name of the user with the given uid.
+
+ If uid is None, return the name of the current user."""
+
+ if uid is None:
+ uid = os.getuid()
+ try:
+ return pwd.getpwuid(uid)[0]
+ except KeyError:
+ return str(uid)
+
+def groupname(gid=None):
+ """Return the name of the group with the given gid.
+
+ If gid is None, return the name of the current group."""
+
+ if gid is None:
+ gid = os.getgid()
+ try:
+ return grp.getgrgid(gid)[0]
+ except KeyError:
+ return str(gid)
diff --git a/sys/src/cmd/hg/mercurial/posix.pyc b/sys/src/cmd/hg/mercurial/posix.pyc
new file mode 100644
index 000000000..e16563527
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/posix.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/pure/base85.py b/sys/src/cmd/hg/mercurial/pure/base85.py
new file mode 100644
index 000000000..88cb1ce8c
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/pure/base85.py
@@ -0,0 +1,74 @@
+# base85.py: pure python base85 codec
+#
+# Copyright (C) 2009 Brendan Cully <brendan@kublai.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import struct
+
+_b85chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+ "abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"
+_b85chars2 = [(a + b) for a in _b85chars for b in _b85chars]
+_b85dec = {}
+
+def _mkb85dec():
+ for i, c in enumerate(_b85chars):
+ _b85dec[c] = i
+
+def b85encode(text, pad=False):
+ """encode text in base85 format"""
+ l = len(text)
+ r = l % 4
+ if r:
+ text += '\0' * (4 - r)
+ longs = len(text) >> 2
+ words = struct.unpack('>%dL' % (longs), text)
+
+ out = ''.join(_b85chars[(word // 52200625) % 85] +
+ _b85chars2[(word // 7225) % 7225] +
+ _b85chars2[word % 7225]
+ for word in words)
+
+ if pad:
+ return out
+
+ # Trim padding
+ olen = l % 4
+ if olen:
+ olen += 1
+ olen += l // 4 * 5
+ return out[:olen]
+
+def b85decode(text):
+ """decode base85-encoded text"""
+ if not _b85dec:
+ _mkb85dec()
+
+ l = len(text)
+ out = []
+ for i in range(0, len(text), 5):
+ chunk = text[i:i+5]
+ acc = 0
+ for j, c in enumerate(chunk):
+ try:
+ acc = acc * 85 + _b85dec[c]
+ except KeyError:
+ raise TypeError('Bad base85 character at byte %d' % (i + j))
+ if acc > 4294967295:
+ raise OverflowError('Base85 overflow in hunk starting at byte %d' % i)
+ out.append(acc)
+
+ # Pad final chunk if necessary
+ cl = l % 5
+ if cl:
+ acc *= 85 ** (5 - cl)
+ if cl > 1:
+ acc += 0xffffff >> (cl - 2) * 8
+ out[-1] = acc
+
+ out = struct.pack('>%dL' % (len(out)), *out)
+ if cl:
+ out = out[:-(5 - cl)]
+
+ return out
diff --git a/sys/src/cmd/hg/mercurial/pure/bdiff.py b/sys/src/cmd/hg/mercurial/pure/bdiff.py
new file mode 100644
index 000000000..70fa54478
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/pure/bdiff.py
@@ -0,0 +1,76 @@
+# bdiff.py - Python implementation of bdiff.c
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import struct, difflib
+
+def splitnewlines(text):
+ '''like str.splitlines, but only split on newlines.'''
+ lines = [l + '\n' for l in text.split('\n')]
+ if lines:
+ if lines[-1] == '\n':
+ lines.pop()
+ else:
+ lines[-1] = lines[-1][:-1]
+ return lines
+
+def _normalizeblocks(a, b, blocks):
+ prev = None
+ for curr in blocks:
+ if prev is None:
+ prev = curr
+ continue
+ shift = 0
+
+ a1, b1, l1 = prev
+ a1end = a1 + l1
+ b1end = b1 + l1
+
+ a2, b2, l2 = curr
+ a2end = a2 + l2
+ b2end = b2 + l2
+ if a1end == a2:
+ while a1end+shift < a2end and a[a1end+shift] == b[b1end+shift]:
+ shift += 1
+ elif b1end == b2:
+ while b1end+shift < b2end and a[a1end+shift] == b[b1end+shift]:
+ shift += 1
+ yield a1, b1, l1+shift
+ prev = a2+shift, b2+shift, l2-shift
+ yield prev
+
+def bdiff(a, b):
+ a = str(a).splitlines(True)
+ b = str(b).splitlines(True)
+
+ if not a:
+ s = "".join(b)
+ return s and (struct.pack(">lll", 0, 0, len(s)) + s)
+
+ bin = []
+ p = [0]
+ for i in a: p.append(p[-1] + len(i))
+
+ d = difflib.SequenceMatcher(None, a, b).get_matching_blocks()
+ d = _normalizeblocks(a, b, d)
+ la = 0
+ lb = 0
+ for am, bm, size in d:
+ s = "".join(b[lb:bm])
+ if am > la or s:
+ bin.append(struct.pack(">lll", p[la], p[am], len(s)) + s)
+ la = am + size
+ lb = bm + size
+
+ return "".join(bin)
+
+def blocks(a, b):
+ an = splitnewlines(a)
+ bn = splitnewlines(b)
+ d = difflib.SequenceMatcher(None, an, bn).get_matching_blocks()
+ d = _normalizeblocks(an, bn, d)
+ return [(i, i + n, j, j + n) for (i, j, n) in d]
+
diff --git a/sys/src/cmd/hg/mercurial/pure/diffhelpers.py b/sys/src/cmd/hg/mercurial/pure/diffhelpers.py
new file mode 100644
index 000000000..e7f2e915e
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/pure/diffhelpers.py
@@ -0,0 +1,56 @@
+# diffhelpers.py - pure Python implementation of diffhelpers.c
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+def addlines(fp, hunk, lena, lenb, a, b):
+ while True:
+ todoa = lena - len(a)
+ todob = lenb - len(b)
+ num = max(todoa, todob)
+ if num == 0:
+ break
+ for i in xrange(num):
+ s = fp.readline()
+ c = s[0]
+ if s == "\\ No newline at end of file\n":
+ fix_newline(hunk, a, b)
+ continue
+ if c == "\n":
+ # Some patches may be missing the control char
+ # on empty lines. Supply a leading space.
+ s = " \n"
+ hunk.append(s)
+ if c == "+":
+ b.append(s[1:])
+ elif c == "-":
+ a.append(s)
+ else:
+ b.append(s[1:])
+ a.append(s)
+ return 0
+
+def fix_newline(hunk, a, b):
+ l = hunk[-1]
+ c = l[0]
+ hline = l[:-1]
+
+ if c == " " or c == "+":
+ b[-1] = l[1:-1]
+ if c == " " or c == "-":
+ a[-1] = hline
+ hunk[-1] = hline
+ return 0
+
+
+def testhunk(a, b, bstart):
+ alen = len(a)
+ blen = len(b)
+ if alen > blen - bstart:
+ return -1
+ for i in xrange(alen):
+ if a[i][1:] != b[i + bstart]:
+ return -1
+ return 0
diff --git a/sys/src/cmd/hg/mercurial/pure/mpatch.py b/sys/src/cmd/hg/mercurial/pure/mpatch.py
new file mode 100644
index 000000000..dd2d84098
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/pure/mpatch.py
@@ -0,0 +1,116 @@
+# mpatch.py - Python implementation of mpatch.c
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import struct
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+
+# This attempts to apply a series of patches in time proportional to
+# the total size of the patches, rather than patches * len(text). This
+# means rather than shuffling strings around, we shuffle around
+# pointers to fragments with fragment lists.
+#
+# When the fragment lists get too long, we collapse them. To do this
+# efficiently, we do all our operations inside a buffer created by
+# mmap and simply use memmove. This avoids creating a bunch of large
+# temporary string buffers.
+
+def patches(a, bins):
+ if not bins: return a
+
+ plens = [len(x) for x in bins]
+ pl = sum(plens)
+ bl = len(a) + pl
+ tl = bl + bl + pl # enough for the patches and two working texts
+ b1, b2 = 0, bl
+
+ if not tl: return a
+
+ m = StringIO()
+ def move(dest, src, count):
+ """move count bytes from src to dest
+
+ The file pointer is left at the end of dest.
+ """
+ m.seek(src)
+ buf = m.read(count)
+ m.seek(dest)
+ m.write(buf)
+
+ # load our original text
+ m.write(a)
+ frags = [(len(a), b1)]
+
+ # copy all the patches into our segment so we can memmove from them
+ pos = b2 + bl
+ m.seek(pos)
+ for p in bins: m.write(p)
+
+ def pull(dst, src, l): # pull l bytes from src
+ while l:
+ f = src.pop(0)
+ if f[0] > l: # do we need to split?
+ src.insert(0, (f[0] - l, f[1] + l))
+ dst.append((l, f[1]))
+ return
+ dst.append(f)
+ l -= f[0]
+
+ def collect(buf, list):
+ start = buf
+ for l, p in list:
+ move(buf, p, l)
+ buf += l
+ return (buf - start, start)
+
+ for plen in plens:
+ # if our list gets too long, execute it
+ if len(frags) > 128:
+ b2, b1 = b1, b2
+ frags = [collect(b1, frags)]
+
+ new = []
+ end = pos + plen
+ last = 0
+ while pos < end:
+ m.seek(pos)
+ p1, p2, l = struct.unpack(">lll", m.read(12))
+ pull(new, frags, p1 - last) # what didn't change
+ pull([], frags, p2 - p1) # what got deleted
+ new.append((l, pos + 12)) # what got added
+ pos += l + 12
+ last = p2
+ frags = new + frags # what was left at the end
+
+ t = collect(b2, frags)
+
+ m.seek(t[1])
+ return m.read(t[0])
+
+def patchedsize(orig, delta):
+ outlen, last, bin = 0, 0, 0
+ binend = len(delta)
+ data = 12
+
+ while data <= binend:
+ decode = delta[bin:bin + 12]
+ start, end, length = struct.unpack(">lll", decode)
+ if start > end:
+ break
+ bin = data + length
+ data = bin + 12
+ outlen += start - last
+ last = end
+ outlen += length
+
+ if bin != binend:
+ raise Exception("patch cannot be decoded")
+
+ outlen += orig - last
+ return outlen
diff --git a/sys/src/cmd/hg/mercurial/pure/osutil.py b/sys/src/cmd/hg/mercurial/pure/osutil.py
new file mode 100644
index 000000000..86e8291f6
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/pure/osutil.py
@@ -0,0 +1,52 @@
+# osutil.py - pure Python version of osutil.c
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import os
+import stat as _stat
+
+posixfile = open
+
+def _mode_to_kind(mode):
+ if _stat.S_ISREG(mode): return _stat.S_IFREG
+ if _stat.S_ISDIR(mode): return _stat.S_IFDIR
+ if _stat.S_ISLNK(mode): return _stat.S_IFLNK
+ if _stat.S_ISBLK(mode): return _stat.S_IFBLK
+ if _stat.S_ISCHR(mode): return _stat.S_IFCHR
+ if _stat.S_ISFIFO(mode): return _stat.S_IFIFO
+ if _stat.S_ISSOCK(mode): return _stat.S_IFSOCK
+ return mode
+
+def listdir(path, stat=False, skip=None):
+ '''listdir(path, stat=False) -> list_of_tuples
+
+ Return a sorted list containing information about the entries
+ in the directory.
+
+ If stat is True, each element is a 3-tuple:
+
+ (name, type, stat object)
+
+ Otherwise, each element is a 2-tuple:
+
+ (name, type)
+ '''
+ result = []
+ prefix = path
+ if not prefix.endswith(os.sep):
+ prefix += os.sep
+ names = os.listdir(path)
+ names.sort()
+ for fn in names:
+ st = os.lstat(prefix + fn)
+ if fn == skip and _stat.S_ISDIR(st.st_mode):
+ return []
+ if stat:
+ result.append((fn, _mode_to_kind(st.st_mode), st))
+ else:
+ result.append((fn, _mode_to_kind(st.st_mode)))
+ return result
+
diff --git a/sys/src/cmd/hg/mercurial/pure/parsers.py b/sys/src/cmd/hg/mercurial/pure/parsers.py
new file mode 100644
index 000000000..feebb6a18
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/pure/parsers.py
@@ -0,0 +1,90 @@
+# parsers.py - Python implementation of parsers.c
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from mercurial.node import bin, nullid, nullrev
+from mercurial import util
+import struct, zlib
+
+_pack = struct.pack
+_unpack = struct.unpack
+_compress = zlib.compress
+_decompress = zlib.decompress
+_sha = util.sha1
+
+def parse_manifest(mfdict, fdict, lines):
+ for l in lines.splitlines():
+ f, n = l.split('\0')
+ if len(n) > 40:
+ fdict[f] = n[40:]
+ mfdict[f] = bin(n[:40])
+ else:
+ mfdict[f] = bin(n)
+
+def parse_index(data, inline):
+ def gettype(q):
+ return int(q & 0xFFFF)
+
+ def offset_type(offset, type):
+ return long(long(offset) << 16 | type)
+
+ indexformatng = ">Qiiiiii20s12x"
+
+ s = struct.calcsize(indexformatng)
+ index = []
+ cache = None
+ nodemap = {nullid: nullrev}
+ n = off = 0
+ # if we're not using lazymap, always read the whole index
+ l = len(data) - s
+ append = index.append
+ if inline:
+ cache = (0, data)
+ while off <= l:
+ e = _unpack(indexformatng, data[off:off + s])
+ nodemap[e[7]] = n
+ append(e)
+ n += 1
+ if e[1] < 0:
+ break
+ off += e[1] + s
+ else:
+ while off <= l:
+ e = _unpack(indexformatng, data[off:off + s])
+ nodemap[e[7]] = n
+ append(e)
+ n += 1
+ off += s
+
+ e = list(index[0])
+ type = gettype(e[0])
+ e[0] = offset_type(0, type)
+ index[0] = tuple(e)
+
+ # add the magic null revision at -1
+ index.append((0, 0, 0, -1, -1, -1, -1, nullid))
+
+ return index, nodemap, cache
+
+def parse_dirstate(dmap, copymap, st):
+ parents = [st[:20], st[20: 40]]
+ # deref fields so they will be local in loop
+ format = ">cllll"
+ e_size = struct.calcsize(format)
+ pos1 = 40
+ l = len(st)
+
+ # the inner loop
+ while pos1 < l:
+ pos2 = pos1 + e_size
+ e = _unpack(">cllll", st[pos1:pos2]) # a literal here is faster
+ pos1 = pos2 + e[4]
+ f = st[pos2:pos1]
+ if '\0' in f:
+ f, c = f.split('\0')
+ copymap[f] = c
+ dmap[f] = e[:4]
+ return parents
diff --git a/sys/src/cmd/hg/mercurial/repair.py b/sys/src/cmd/hg/mercurial/repair.py
new file mode 100644
index 000000000..f4d8d2641
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/repair.py
@@ -0,0 +1,145 @@
+# repair.py - functions for repository repair for mercurial
+#
+# Copyright 2005, 2006 Chris Mason <mason@suse.com>
+# Copyright 2007 Matt Mackall
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import changegroup
+from node import nullrev, short
+from i18n import _
+import os
+
+def _bundle(repo, bases, heads, node, suffix, extranodes=None):
+ """create a bundle with the specified revisions as a backup"""
+ cg = repo.changegroupsubset(bases, heads, 'strip', extranodes)
+ backupdir = repo.join("strip-backup")
+ if not os.path.isdir(backupdir):
+ os.mkdir(backupdir)
+ name = os.path.join(backupdir, "%s-%s" % (short(node), suffix))
+ repo.ui.warn(_("saving bundle to %s\n") % name)
+ return changegroup.writebundle(cg, name, "HG10BZ")
+
+def _collectfiles(repo, striprev):
+ """find out the filelogs affected by the strip"""
+ files = set()
+
+ for x in xrange(striprev, len(repo)):
+ files.update(repo[x].files())
+
+ return sorted(files)
+
+def _collectextranodes(repo, files, link):
+ """return the nodes that have to be saved before the strip"""
+ def collectone(revlog):
+ extra = []
+ startrev = count = len(revlog)
+ # find the truncation point of the revlog
+ for i in xrange(count):
+ lrev = revlog.linkrev(i)
+ if lrev >= link:
+ startrev = i + 1
+ break
+
+ # see if any revision after that point has a linkrev less than link
+ # (we have to manually save these guys)
+ for i in xrange(startrev, count):
+ node = revlog.node(i)
+ lrev = revlog.linkrev(i)
+ if lrev < link:
+ extra.append((node, cl.node(lrev)))
+
+ return extra
+
+ extranodes = {}
+ cl = repo.changelog
+ extra = collectone(repo.manifest)
+ if extra:
+ extranodes[1] = extra
+ for fname in files:
+ f = repo.file(fname)
+ extra = collectone(f)
+ if extra:
+ extranodes[fname] = extra
+
+ return extranodes
+
+def strip(ui, repo, node, backup="all"):
+ cl = repo.changelog
+ # TODO delete the undo files, and handle undo of merge sets
+ striprev = cl.rev(node)
+
+ # Some revisions with rev > striprev may not be descendants of striprev.
+ # We have to find these revisions and put them in a bundle, so that
+ # we can restore them after the truncations.
+ # To create the bundle we use repo.changegroupsubset which requires
+ # the list of heads and bases of the set of interesting revisions.
+ # (head = revision in the set that has no descendant in the set;
+ # base = revision in the set that has no ancestor in the set)
+ tostrip = set((striprev,))
+ saveheads = set()
+ savebases = []
+ for r in xrange(striprev + 1, len(cl)):
+ parents = cl.parentrevs(r)
+ if parents[0] in tostrip or parents[1] in tostrip:
+ # r is a descendant of striprev
+ tostrip.add(r)
+ # if this is a merge and one of the parents does not descend
+ # from striprev, mark that parent as a savehead.
+ if parents[1] != nullrev:
+ for p in parents:
+ if p not in tostrip and p > striprev:
+ saveheads.add(p)
+ else:
+ # if no parents of this revision will be stripped, mark it as
+ # a savebase
+ if parents[0] < striprev and parents[1] < striprev:
+ savebases.append(cl.node(r))
+
+ saveheads.difference_update(parents)
+ saveheads.add(r)
+
+ saveheads = [cl.node(r) for r in saveheads]
+ files = _collectfiles(repo, striprev)
+
+ extranodes = _collectextranodes(repo, files, striprev)
+
+ # create a changegroup for all the branches we need to keep
+ if backup == "all":
+ _bundle(repo, [node], cl.heads(), node, 'backup')
+ if saveheads or extranodes:
+ chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp',
+ extranodes)
+
+ mfst = repo.manifest
+
+ tr = repo.transaction()
+ offset = len(tr.entries)
+
+ tr.startgroup()
+ cl.strip(striprev, tr)
+ mfst.strip(striprev, tr)
+ for fn in files:
+ repo.file(fn).strip(striprev, tr)
+ tr.endgroup()
+
+ try:
+ for i in xrange(offset, len(tr.entries)):
+ file, troffset, ignore = tr.entries[i]
+ repo.sopener(file, 'a').truncate(troffset)
+ tr.close()
+ except:
+ tr.abort()
+ raise
+
+ if saveheads or extranodes:
+ ui.status(_("adding branch\n"))
+ f = open(chgrpfile, "rb")
+ gen = changegroup.readbundle(f, chgrpfile)
+ repo.addchangegroup(gen, 'strip', 'bundle:' + chgrpfile, True)
+ f.close()
+ if backup != "strip":
+ os.unlink(chgrpfile)
+
+ repo.destroyed()
diff --git a/sys/src/cmd/hg/mercurial/repo.py b/sys/src/cmd/hg/mercurial/repo.py
new file mode 100644
index 000000000..00cc1cf84
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/repo.py
@@ -0,0 +1,43 @@
+# repo.py - repository base classes for mercurial
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import error
+
+class repository(object):
+ def capable(self, name):
+ '''tell whether repo supports named capability.
+ return False if not supported.
+ if boolean capability, return True.
+ if string capability, return string.'''
+ if name in self.capabilities:
+ return True
+ name_eq = name + '='
+ for cap in self.capabilities:
+ if cap.startswith(name_eq):
+ return cap[len(name_eq):]
+ return False
+
+ def requirecap(self, name, purpose):
+ '''raise an exception if the given capability is not present'''
+ if not self.capable(name):
+ raise error.CapabilityError(
+ _('cannot %s; remote repository does not '
+ 'support the %r capability') % (purpose, name))
+
+ def local(self):
+ return False
+
+ def cancopy(self):
+ return self.local()
+
+ def rjoin(self, path):
+ url = self.url()
+ if url.endswith('/'):
+ return url + path
+ return url + '/' + path
diff --git a/sys/src/cmd/hg/mercurial/revlog.py b/sys/src/cmd/hg/mercurial/revlog.py
new file mode 100644
index 000000000..2b2d4acb9
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/revlog.py
@@ -0,0 +1,1376 @@
+# revlog.py - storage back-end for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+"""Storage back-end for Mercurial.
+
+This provides efficient delta storage with O(1) retrieve and append
+and O(changes) merge between branches.
+"""
+
+# import stuff from node for others to import from revlog
+from node import bin, hex, nullid, nullrev, short #@UnusedImport
+from i18n import _
+import changegroup, ancestor, mdiff, parsers, error, util
+import struct, zlib, errno
+
+_pack = struct.pack
+_unpack = struct.unpack
+_compress = zlib.compress
+_decompress = zlib.decompress
+_sha = util.sha1
+
+# revlog flags
+REVLOGV0 = 0
+REVLOGNG = 1
+REVLOGNGINLINEDATA = (1 << 16)
+REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA
+REVLOG_DEFAULT_FORMAT = REVLOGNG
+REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS
+
+_prereadsize = 1048576
+
+RevlogError = error.RevlogError
+LookupError = error.LookupError
+
+def getoffset(q):
+ return int(q >> 16)
+
+def gettype(q):
+ return int(q & 0xFFFF)
+
+def offset_type(offset, type):
+ return long(long(offset) << 16 | type)
+
+nullhash = _sha(nullid)
+
+def hash(text, p1, p2):
+ """generate a hash from the given text and its parent hashes
+
+ This hash combines both the current file contents and its history
+ in a manner that makes it easy to distinguish nodes with the same
+ content in the revision graph.
+ """
+ # As of now, if one of the parent node is null, p2 is null
+ if p2 == nullid:
+ # deep copy of a hash is faster than creating one
+ s = nullhash.copy()
+ s.update(p1)
+ else:
+ # none of the parent nodes are nullid
+ l = [p1, p2]
+ l.sort()
+ s = _sha(l[0])
+ s.update(l[1])
+ s.update(text)
+ return s.digest()
+
+def compress(text):
+ """ generate a possibly-compressed representation of text """
+ if not text:
+ return ("", text)
+ l = len(text)
+ bin = None
+ if l < 44:
+ pass
+ elif l > 1000000:
+ # zlib makes an internal copy, thus doubling memory usage for
+ # large files, so lets do this in pieces
+ z = zlib.compressobj()
+ p = []
+ pos = 0
+ while pos < l:
+ pos2 = pos + 2**20
+ p.append(z.compress(text[pos:pos2]))
+ pos = pos2
+ p.append(z.flush())
+ if sum(map(len, p)) < l:
+ bin = "".join(p)
+ else:
+ bin = _compress(text)
+ if bin is None or len(bin) > l:
+ if text[0] == '\0':
+ return ("", text)
+ return ('u', text)
+ return ("", bin)
+
+def decompress(bin):
+ """ decompress the given input """
+ if not bin:
+ return bin
+ t = bin[0]
+ if t == '\0':
+ return bin
+ if t == 'x':
+ return _decompress(bin)
+ if t == 'u':
+ return bin[1:]
+ raise RevlogError(_("unknown compression type %r") % t)
+
+class lazyparser(object):
+ """
+ this class avoids the need to parse the entirety of large indices
+ """
+
+ # lazyparser is not safe to use on windows if win32 extensions not
+ # available. it keeps file handle open, which make it not possible
+ # to break hardlinks on local cloned repos.
+
+ def __init__(self, dataf):
+ try:
+ size = util.fstat(dataf).st_size
+ except AttributeError:
+ size = 0
+ self.dataf = dataf
+ self.s = struct.calcsize(indexformatng)
+ self.datasize = size
+ self.l = size/self.s
+ self.index = [None] * self.l
+ self.map = {nullid: nullrev}
+ self.allmap = 0
+ self.all = 0
+ self.mapfind_count = 0
+
+ def loadmap(self):
+ """
+ during a commit, we need to make sure the rev being added is
+ not a duplicate. This requires loading the entire index,
+ which is fairly slow. loadmap can load up just the node map,
+ which takes much less time.
+ """
+ if self.allmap:
+ return
+ end = self.datasize
+ self.allmap = 1
+ cur = 0
+ count = 0
+ blocksize = self.s * 256
+ self.dataf.seek(0)
+ while cur < end:
+ data = self.dataf.read(blocksize)
+ off = 0
+ for x in xrange(256):
+ n = data[off + ngshaoffset:off + ngshaoffset + 20]
+ self.map[n] = count
+ count += 1
+ if count >= self.l:
+ break
+ off += self.s
+ cur += blocksize
+
+ def loadblock(self, blockstart, blocksize, data=None):
+ if self.all:
+ return
+ if data is None:
+ self.dataf.seek(blockstart)
+ if blockstart + blocksize > self.datasize:
+ # the revlog may have grown since we've started running,
+ # but we don't have space in self.index for more entries.
+ # limit blocksize so that we don't get too much data.
+ blocksize = max(self.datasize - blockstart, 0)
+ data = self.dataf.read(blocksize)
+ lend = len(data) / self.s
+ i = blockstart / self.s
+ off = 0
+ # lazyindex supports __delitem__
+ if lend > len(self.index) - i:
+ lend = len(self.index) - i
+ for x in xrange(lend):
+ if self.index[i + x] is None:
+ b = data[off : off + self.s]
+ self.index[i + x] = b
+ n = b[ngshaoffset:ngshaoffset + 20]
+ self.map[n] = i + x
+ off += self.s
+
+ def findnode(self, node):
+ """search backwards through the index file for a specific node"""
+ if self.allmap:
+ return None
+
+ # hg log will cause many many searches for the manifest
+ # nodes. After we get called a few times, just load the whole
+ # thing.
+ if self.mapfind_count > 8:
+ self.loadmap()
+ if node in self.map:
+ return node
+ return None
+ self.mapfind_count += 1
+ last = self.l - 1
+ while self.index[last] != None:
+ if last == 0:
+ self.all = 1
+ self.allmap = 1
+ return None
+ last -= 1
+ end = (last + 1) * self.s
+ blocksize = self.s * 256
+ while end >= 0:
+ start = max(end - blocksize, 0)
+ self.dataf.seek(start)
+ data = self.dataf.read(end - start)
+ findend = end - start
+ while True:
+ # we're searching backwards, so we have to make sure
+ # we don't find a changeset where this node is a parent
+ off = data.find(node, 0, findend)
+ findend = off
+ if off >= 0:
+ i = off / self.s
+ off = i * self.s
+ n = data[off + ngshaoffset:off + ngshaoffset + 20]
+ if n == node:
+ self.map[n] = i + start / self.s
+ return node
+ else:
+ break
+ end -= blocksize
+ return None
+
+ def loadindex(self, i=None, end=None):
+ if self.all:
+ return
+ all = False
+ if i is None:
+ blockstart = 0
+ blocksize = (65536 / self.s) * self.s
+ end = self.datasize
+ all = True
+ else:
+ if end:
+ blockstart = i * self.s
+ end = end * self.s
+ blocksize = end - blockstart
+ else:
+ blockstart = (i & ~1023) * self.s
+ blocksize = self.s * 1024
+ end = blockstart + blocksize
+ while blockstart < end:
+ self.loadblock(blockstart, blocksize)
+ blockstart += blocksize
+ if all:
+ self.all = True
+
+class lazyindex(object):
+ """a lazy version of the index array"""
+ def __init__(self, parser):
+ self.p = parser
+ def __len__(self):
+ return len(self.p.index)
+ def load(self, pos):
+ if pos < 0:
+ pos += len(self.p.index)
+ self.p.loadindex(pos)
+ return self.p.index[pos]
+ def __getitem__(self, pos):
+ return _unpack(indexformatng, self.p.index[pos] or self.load(pos))
+ def __setitem__(self, pos, item):
+ self.p.index[pos] = _pack(indexformatng, *item)
+ def __delitem__(self, pos):
+ del self.p.index[pos]
+ def insert(self, pos, e):
+ self.p.index.insert(pos, _pack(indexformatng, *e))
+ def append(self, e):
+ self.p.index.append(_pack(indexformatng, *e))
+
+class lazymap(object):
+ """a lazy version of the node map"""
+ def __init__(self, parser):
+ self.p = parser
+ def load(self, key):
+ n = self.p.findnode(key)
+ if n is None:
+ raise KeyError(key)
+ def __contains__(self, key):
+ if key in self.p.map:
+ return True
+ self.p.loadmap()
+ return key in self.p.map
+ def __iter__(self):
+ yield nullid
+ for i in xrange(self.p.l):
+ ret = self.p.index[i]
+ if not ret:
+ self.p.loadindex(i)
+ ret = self.p.index[i]
+ if isinstance(ret, str):
+ ret = _unpack(indexformatng, ret)
+ yield ret[7]
+ def __getitem__(self, key):
+ try:
+ return self.p.map[key]
+ except KeyError:
+ try:
+ self.load(key)
+ return self.p.map[key]
+ except KeyError:
+ raise KeyError("node " + hex(key))
+ def __setitem__(self, key, val):
+ self.p.map[key] = val
+ def __delitem__(self, key):
+ del self.p.map[key]
+
+indexformatv0 = ">4l20s20s20s"
+v0shaoffset = 56
+
+class revlogoldio(object):
+ def __init__(self):
+ self.size = struct.calcsize(indexformatv0)
+
+ def parseindex(self, fp, data, inline):
+ s = self.size
+ index = []
+ nodemap = {nullid: nullrev}
+ n = off = 0
+ if len(data) == _prereadsize:
+ data += fp.read() # read the rest
+ l = len(data)
+ while off + s <= l:
+ cur = data[off:off + s]
+ off += s
+ e = _unpack(indexformatv0, cur)
+ # transform to revlogv1 format
+ e2 = (offset_type(e[0], 0), e[1], -1, e[2], e[3],
+ nodemap.get(e[4], nullrev), nodemap.get(e[5], nullrev), e[6])
+ index.append(e2)
+ nodemap[e[6]] = n
+ n += 1
+
+ return index, nodemap, None
+
+ def packentry(self, entry, node, version, rev):
+ e2 = (getoffset(entry[0]), entry[1], entry[3], entry[4],
+ node(entry[5]), node(entry[6]), entry[7])
+ return _pack(indexformatv0, *e2)
+
+# index ng:
+# 6 bytes offset
+# 2 bytes flags
+# 4 bytes compressed length
+# 4 bytes uncompressed length
+# 4 bytes: base rev
+# 4 bytes link rev
+# 4 bytes parent 1 rev
+# 4 bytes parent 2 rev
+# 32 bytes: nodeid
+indexformatng = ">Qiiiiii20s12x"
+ngshaoffset = 32
+versionformat = ">I"
+
+class revlogio(object):
+ def __init__(self):
+ self.size = struct.calcsize(indexformatng)
+
+ def parseindex(self, fp, data, inline):
+ if len(data) == _prereadsize:
+ if util.openhardlinks() and not inline:
+ # big index, let's parse it on demand
+ parser = lazyparser(fp)
+ index = lazyindex(parser)
+ nodemap = lazymap(parser)
+ e = list(index[0])
+ type = gettype(e[0])
+ e[0] = offset_type(0, type)
+ index[0] = e
+ return index, nodemap, None
+ else:
+ data += fp.read()
+
+ # call the C implementation to parse the index data
+ index, nodemap, cache = parsers.parse_index(data, inline)
+ return index, nodemap, cache
+
+ def packentry(self, entry, node, version, rev):
+ p = _pack(indexformatng, *entry)
+ if rev == 0:
+ p = _pack(versionformat, version) + p[4:]
+ return p
+
+class revlog(object):
+ """
+ the underlying revision storage object
+
+ A revlog consists of two parts, an index and the revision data.
+
+ The index is a file with a fixed record size containing
+ information on each revision, including its nodeid (hash), the
+ nodeids of its parents, the position and offset of its data within
+ the data file, and the revision it's based on. Finally, each entry
+ contains a linkrev entry that can serve as a pointer to external
+ data.
+
+ The revision data itself is a linear collection of data chunks.
+ Each chunk represents a revision and is usually represented as a
+ delta against the previous chunk. To bound lookup time, runs of
+ deltas are limited to about 2 times the length of the original
+ version data. This makes retrieval of a version proportional to
+ its size, or O(1) relative to the number of revisions.
+
+ Both pieces of the revlog are written to in an append-only
+ fashion, which means we never need to rewrite a file to insert or
+ remove data, and can use some simple techniques to avoid the need
+ for locking while reading.
+ """
+ def __init__(self, opener, indexfile):
+ """
+ create a revlog object
+
+ opener is a function that abstracts the file opening operation
+ and can be used to implement COW semantics or the like.
+ """
+ self.indexfile = indexfile
+ self.datafile = indexfile[:-2] + ".d"
+ self.opener = opener
+ self._cache = None
+ self._chunkcache = (0, '')
+ self.nodemap = {nullid: nullrev}
+ self.index = []
+
+ v = REVLOG_DEFAULT_VERSION
+ if hasattr(opener, "defversion"):
+ v = opener.defversion
+ if v & REVLOGNG:
+ v |= REVLOGNGINLINEDATA
+
+ i = ''
+ try:
+ f = self.opener(self.indexfile)
+ i = f.read(_prereadsize)
+ if len(i) > 0:
+ v = struct.unpack(versionformat, i[:4])[0]
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+
+ self.version = v
+ self._inline = v & REVLOGNGINLINEDATA
+ flags = v & ~0xFFFF
+ fmt = v & 0xFFFF
+ if fmt == REVLOGV0 and flags:
+ raise RevlogError(_("index %s unknown flags %#04x for format v0")
+ % (self.indexfile, flags >> 16))
+ elif fmt == REVLOGNG and flags & ~REVLOGNGINLINEDATA:
+ raise RevlogError(_("index %s unknown flags %#04x for revlogng")
+ % (self.indexfile, flags >> 16))
+ elif fmt > REVLOGNG:
+ raise RevlogError(_("index %s unknown format %d")
+ % (self.indexfile, fmt))
+
+ self._io = revlogio()
+ if self.version == REVLOGV0:
+ self._io = revlogoldio()
+ if i:
+ try:
+ d = self._io.parseindex(f, i, self._inline)
+ except (ValueError, IndexError), e:
+ raise RevlogError(_("index %s is corrupted") % (self.indexfile))
+ self.index, self.nodemap, self._chunkcache = d
+ if not self._chunkcache:
+ self._chunkclear()
+
+ # add the magic null revision at -1 (if it hasn't been done already)
+ if (self.index == [] or isinstance(self.index, lazyindex) or
+ self.index[-1][7] != nullid) :
+ self.index.append((0, 0, 0, -1, -1, -1, -1, nullid))
+
+ def _loadindex(self, start, end):
+ """load a block of indexes all at once from the lazy parser"""
+ if isinstance(self.index, lazyindex):
+ self.index.p.loadindex(start, end)
+
+ def _loadindexmap(self):
+ """loads both the map and the index from the lazy parser"""
+ if isinstance(self.index, lazyindex):
+ p = self.index.p
+ p.loadindex()
+ self.nodemap = p.map
+
+ def _loadmap(self):
+ """loads the map from the lazy parser"""
+ if isinstance(self.nodemap, lazymap):
+ self.nodemap.p.loadmap()
+ self.nodemap = self.nodemap.p.map
+
+ def tip(self):
+ return self.node(len(self.index) - 2)
+ def __len__(self):
+ return len(self.index) - 1
+ def __iter__(self):
+ for i in xrange(len(self)):
+ yield i
+ def rev(self, node):
+ try:
+ return self.nodemap[node]
+ except KeyError:
+ raise LookupError(node, self.indexfile, _('no node'))
+ def node(self, rev):
+ return self.index[rev][7]
+ def linkrev(self, rev):
+ return self.index[rev][4]
+ def parents(self, node):
+ i = self.index
+ d = i[self.rev(node)]
+ return i[d[5]][7], i[d[6]][7] # map revisions to nodes inline
+ def parentrevs(self, rev):
+ return self.index[rev][5:7]
+ def start(self, rev):
+ return int(self.index[rev][0] >> 16)
+ def end(self, rev):
+ return self.start(rev) + self.length(rev)
+ def length(self, rev):
+ return self.index[rev][1]
+ def base(self, rev):
+ return self.index[rev][3]
+
+ def size(self, rev):
+ """return the length of the uncompressed text for a given revision"""
+ l = self.index[rev][2]
+ if l >= 0:
+ return l
+
+ t = self.revision(self.node(rev))
+ return len(t)
+
+ # Alternate implementation. The advantage to this code is it
+ # will be faster for a single revision. However, the results
+ # are not cached, so finding the size of every revision will
+ # be slower.
+ #
+ # if self.cache and self.cache[1] == rev:
+ # return len(self.cache[2])
+ #
+ # base = self.base(rev)
+ # if self.cache and self.cache[1] >= base and self.cache[1] < rev:
+ # base = self.cache[1]
+ # text = self.cache[2]
+ # else:
+ # text = self.revision(self.node(base))
+ #
+ # l = len(text)
+ # for x in xrange(base + 1, rev + 1):
+ # l = mdiff.patchedsize(l, self._chunk(x))
+ # return l
+
+ def reachable(self, node, stop=None):
+ """return the set of all nodes ancestral to a given node, including
+ the node itself, stopping when stop is matched"""
+ reachable = set((node,))
+ visit = [node]
+ if stop:
+ stopn = self.rev(stop)
+ else:
+ stopn = 0
+ while visit:
+ n = visit.pop(0)
+ if n == stop:
+ continue
+ if n == nullid:
+ continue
+ for p in self.parents(n):
+ if self.rev(p) < stopn:
+ continue
+ if p not in reachable:
+ reachable.add(p)
+ visit.append(p)
+ return reachable
+
+ def ancestors(self, *revs):
+ 'Generate the ancestors of revs using a breadth-first visit'
+ visit = list(revs)
+ seen = set([nullrev])
+ while visit:
+ for parent in self.parentrevs(visit.pop(0)):
+ if parent not in seen:
+ visit.append(parent)
+ seen.add(parent)
+ yield parent
+
+ def descendants(self, *revs):
+ 'Generate the descendants of revs in topological order'
+ seen = set(revs)
+ for i in xrange(min(revs) + 1, len(self)):
+ for x in self.parentrevs(i):
+ if x != nullrev and x in seen:
+ seen.add(i)
+ yield i
+ break
+
+ def findmissing(self, common=None, heads=None):
+ '''
+ returns the topologically sorted list of nodes from the set:
+ missing = (ancestors(heads) \ ancestors(common))
+
+ where ancestors() is the set of ancestors from heads, heads included
+
+ if heads is None, the heads of the revlog are used
+ if common is None, nullid is assumed to be a common node
+ '''
+ if common is None:
+ common = [nullid]
+ if heads is None:
+ heads = self.heads()
+
+ common = [self.rev(n) for n in common]
+ heads = [self.rev(n) for n in heads]
+
+ # we want the ancestors, but inclusive
+ has = set(self.ancestors(*common))
+ has.add(nullrev)
+ has.update(common)
+
+ # take all ancestors from heads that aren't in has
+ missing = set()
+ visit = [r for r in heads if r not in has]
+ while visit:
+ r = visit.pop(0)
+ if r in missing:
+ continue
+ else:
+ missing.add(r)
+ for p in self.parentrevs(r):
+ if p not in has:
+ visit.append(p)
+ missing = list(missing)
+ missing.sort()
+ return [self.node(r) for r in missing]
+
+ def nodesbetween(self, roots=None, heads=None):
+ """Return a tuple containing three elements. Elements 1 and 2 contain
+ a final list bases and heads after all the unreachable ones have been
+ pruned. Element 0 contains a topologically sorted list of all
+
+ nodes that satisfy these constraints:
+ 1. All nodes must be descended from a node in roots (the nodes on
+ roots are considered descended from themselves).
+ 2. All nodes must also be ancestors of a node in heads (the nodes in
+ heads are considered to be their own ancestors).
+
+ If roots is unspecified, nullid is assumed as the only root.
+ If heads is unspecified, it is taken to be the output of the
+ heads method (i.e. a list of all nodes in the repository that
+ have no children)."""
+ nonodes = ([], [], [])
+ if roots is not None:
+ roots = list(roots)
+ if not roots:
+ return nonodes
+ lowestrev = min([self.rev(n) for n in roots])
+ else:
+ roots = [nullid] # Everybody's a descendent of nullid
+ lowestrev = nullrev
+ if (lowestrev == nullrev) and (heads is None):
+ # We want _all_ the nodes!
+ return ([self.node(r) for r in self], [nullid], list(self.heads()))
+ if heads is None:
+ # All nodes are ancestors, so the latest ancestor is the last
+ # node.
+ highestrev = len(self) - 1
+ # Set ancestors to None to signal that every node is an ancestor.
+ ancestors = None
+ # Set heads to an empty dictionary for later discovery of heads
+ heads = {}
+ else:
+ heads = list(heads)
+ if not heads:
+ return nonodes
+ ancestors = set()
+ # Turn heads into a dictionary so we can remove 'fake' heads.
+ # Also, later we will be using it to filter out the heads we can't
+ # find from roots.
+ heads = dict.fromkeys(heads, 0)
+ # Start at the top and keep marking parents until we're done.
+ nodestotag = set(heads)
+ # Remember where the top was so we can use it as a limit later.
+ highestrev = max([self.rev(n) for n in nodestotag])
+ while nodestotag:
+ # grab a node to tag
+ n = nodestotag.pop()
+ # Never tag nullid
+ if n == nullid:
+ continue
+ # A node's revision number represents its place in a
+ # topologically sorted list of nodes.
+ r = self.rev(n)
+ if r >= lowestrev:
+ if n not in ancestors:
+ # If we are possibly a descendent of one of the roots
+ # and we haven't already been marked as an ancestor
+ ancestors.add(n) # Mark as ancestor
+ # Add non-nullid parents to list of nodes to tag.
+ nodestotag.update([p for p in self.parents(n) if
+ p != nullid])
+ elif n in heads: # We've seen it before, is it a fake head?
+ # So it is, real heads should not be the ancestors of
+ # any other heads.
+ heads.pop(n)
+ if not ancestors:
+ return nonodes
+ # Now that we have our set of ancestors, we want to remove any
+ # roots that are not ancestors.
+
+ # If one of the roots was nullid, everything is included anyway.
+ if lowestrev > nullrev:
+ # But, since we weren't, let's recompute the lowest rev to not
+ # include roots that aren't ancestors.
+
+ # Filter out roots that aren't ancestors of heads
+ roots = [n for n in roots if n in ancestors]
+ # Recompute the lowest revision
+ if roots:
+ lowestrev = min([self.rev(n) for n in roots])
+ else:
+ # No more roots? Return empty list
+ return nonodes
+ else:
+ # We are descending from nullid, and don't need to care about
+ # any other roots.
+ lowestrev = nullrev
+ roots = [nullid]
+ # Transform our roots list into a set.
+ descendents = set(roots)
+ # Also, keep the original roots so we can filter out roots that aren't
+ # 'real' roots (i.e. are descended from other roots).
+ roots = descendents.copy()
+ # Our topologically sorted list of output nodes.
+ orderedout = []
+ # Don't start at nullid since we don't want nullid in our output list,
+ # and if nullid shows up in descedents, empty parents will look like
+ # they're descendents.
+ for r in xrange(max(lowestrev, 0), highestrev + 1):
+ n = self.node(r)
+ isdescendent = False
+ if lowestrev == nullrev: # Everybody is a descendent of nullid
+ isdescendent = True
+ elif n in descendents:
+ # n is already a descendent
+ isdescendent = True
+ # This check only needs to be done here because all the roots
+ # will start being marked is descendents before the loop.
+ if n in roots:
+ # If n was a root, check if it's a 'real' root.
+ p = tuple(self.parents(n))
+ # If any of its parents are descendents, it's not a root.
+ if (p[0] in descendents) or (p[1] in descendents):
+ roots.remove(n)
+ else:
+ p = tuple(self.parents(n))
+ # A node is a descendent if either of its parents are
+ # descendents. (We seeded the dependents list with the roots
+ # up there, remember?)
+ if (p[0] in descendents) or (p[1] in descendents):
+ descendents.add(n)
+ isdescendent = True
+ if isdescendent and ((ancestors is None) or (n in ancestors)):
+ # Only include nodes that are both descendents and ancestors.
+ orderedout.append(n)
+ if (ancestors is not None) and (n in heads):
+ # We're trying to figure out which heads are reachable
+ # from roots.
+ # Mark this head as having been reached
+ heads[n] = 1
+ elif ancestors is None:
+ # Otherwise, we're trying to discover the heads.
+ # Assume this is a head because if it isn't, the next step
+ # will eventually remove it.
+ heads[n] = 1
+ # But, obviously its parents aren't.
+ for p in self.parents(n):
+ heads.pop(p, None)
+ heads = [n for n in heads.iterkeys() if heads[n] != 0]
+ roots = list(roots)
+ assert orderedout
+ assert roots
+ assert heads
+ return (orderedout, roots, heads)
+
+ def heads(self, start=None, stop=None):
+ """return the list of all nodes that have no children
+
+ if start is specified, only heads that are descendants of
+ start will be returned
+ if stop is specified, it will consider all the revs from stop
+ as if they had no children
+ """
+ if start is None and stop is None:
+ count = len(self)
+ if not count:
+ return [nullid]
+ ishead = [1] * (count + 1)
+ index = self.index
+ for r in xrange(count):
+ e = index[r]
+ ishead[e[5]] = ishead[e[6]] = 0
+ return [self.node(r) for r in xrange(count) if ishead[r]]
+
+ if start is None:
+ start = nullid
+ if stop is None:
+ stop = []
+ stoprevs = set([self.rev(n) for n in stop])
+ startrev = self.rev(start)
+ reachable = set((startrev,))
+ heads = set((startrev,))
+
+ parentrevs = self.parentrevs
+ for r in xrange(startrev + 1, len(self)):
+ for p in parentrevs(r):
+ if p in reachable:
+ if r not in stoprevs:
+ reachable.add(r)
+ heads.add(r)
+ if p in heads and p not in stoprevs:
+ heads.remove(p)
+
+ return [self.node(r) for r in heads]
+
+ def children(self, node):
+ """find the children of a given node"""
+ c = []
+ p = self.rev(node)
+ for r in range(p + 1, len(self)):
+ prevs = [pr for pr in self.parentrevs(r) if pr != nullrev]
+ if prevs:
+ for pr in prevs:
+ if pr == p:
+ c.append(self.node(r))
+ elif p == nullrev:
+ c.append(self.node(r))
+ return c
+
+ def _match(self, id):
+ if isinstance(id, (long, int)):
+ # rev
+ return self.node(id)
+ if len(id) == 20:
+ # possibly a binary node
+ # odds of a binary node being all hex in ASCII are 1 in 10**25
+ try:
+ node = id
+ self.rev(node) # quick search the index
+ return node
+ except LookupError:
+ pass # may be partial hex id
+ try:
+ # str(rev)
+ rev = int(id)
+ if str(rev) != id:
+ raise ValueError
+ if rev < 0:
+ rev = len(self) + rev
+ if rev < 0 or rev >= len(self):
+ raise ValueError
+ return self.node(rev)
+ except (ValueError, OverflowError):
+ pass
+ if len(id) == 40:
+ try:
+ # a full hex nodeid?
+ node = bin(id)
+ self.rev(node)
+ return node
+ except (TypeError, LookupError):
+ pass
+
+ def _partialmatch(self, id):
+ if len(id) < 40:
+ try:
+ # hex(node)[:...]
+ l = len(id) // 2 # grab an even number of digits
+ bin_id = bin(id[:l*2])
+ nl = [n for n in self.nodemap if n[:l] == bin_id]
+ nl = [n for n in nl if hex(n).startswith(id)]
+ if len(nl) > 0:
+ if len(nl) == 1:
+ return nl[0]
+ raise LookupError(id, self.indexfile,
+ _('ambiguous identifier'))
+ return None
+ except TypeError:
+ pass
+
+ def lookup(self, id):
+ """locate a node based on:
+ - revision number or str(revision number)
+ - nodeid or subset of hex nodeid
+ """
+ n = self._match(id)
+ if n is not None:
+ return n
+ n = self._partialmatch(id)
+ if n:
+ return n
+
+ raise LookupError(id, self.indexfile, _('no match found'))
+
+ def cmp(self, node, text):
+ """compare text with a given file revision"""
+ p1, p2 = self.parents(node)
+ return hash(text, p1, p2) != node
+
+ def _addchunk(self, offset, data):
+ o, d = self._chunkcache
+ # try to add to existing cache
+ if o + len(d) == offset and len(d) + len(data) < _prereadsize:
+ self._chunkcache = o, d + data
+ else:
+ self._chunkcache = offset, data
+
+ def _loadchunk(self, offset, length):
+ if self._inline:
+ df = self.opener(self.indexfile)
+ else:
+ df = self.opener(self.datafile)
+
+ readahead = max(65536, length)
+ df.seek(offset)
+ d = df.read(readahead)
+ self._addchunk(offset, d)
+ if readahead > length:
+ return d[:length]
+ return d
+
+ def _getchunk(self, offset, length):
+ o, d = self._chunkcache
+ l = len(d)
+
+ # is it in the cache?
+ cachestart = offset - o
+ cacheend = cachestart + length
+ if cachestart >= 0 and cacheend <= l:
+ if cachestart == 0 and cacheend == l:
+ return d # avoid a copy
+ return d[cachestart:cacheend]
+
+ return self._loadchunk(offset, length)
+
+ def _chunkraw(self, startrev, endrev):
+ start = self.start(startrev)
+ length = self.end(endrev) - start
+ if self._inline:
+ start += (startrev + 1) * self._io.size
+ return self._getchunk(start, length)
+
+ def _chunk(self, rev):
+ return decompress(self._chunkraw(rev, rev))
+
+ def _chunkclear(self):
+ self._chunkcache = (0, '')
+
+ def revdiff(self, rev1, rev2):
+ """return or calculate a delta between two revisions"""
+ if rev1 + 1 == rev2 and self.base(rev1) == self.base(rev2):
+ return self._chunk(rev2)
+
+ return mdiff.textdiff(self.revision(self.node(rev1)),
+ self.revision(self.node(rev2)))
+
+ def revision(self, node):
+ """return an uncompressed revision of a given node"""
+ if node == nullid:
+ return ""
+ if self._cache and self._cache[0] == node:
+ return str(self._cache[2])
+
+ # look up what we need to read
+ text = None
+ rev = self.rev(node)
+ base = self.base(rev)
+
+ # check rev flags
+ if self.index[rev][0] & 0xFFFF:
+ raise RevlogError(_('incompatible revision flag %x') %
+ (self.index[rev][0] & 0xFFFF))
+
+ # do we have useful data cached?
+ if self._cache and self._cache[1] >= base and self._cache[1] < rev:
+ base = self._cache[1]
+ text = str(self._cache[2])
+
+ self._loadindex(base, rev + 1)
+ self._chunkraw(base, rev)
+ if text is None:
+ text = self._chunk(base)
+
+ bins = [self._chunk(r) for r in xrange(base + 1, rev + 1)]
+ text = mdiff.patches(text, bins)
+ p1, p2 = self.parents(node)
+ if node != hash(text, p1, p2):
+ raise RevlogError(_("integrity check failed on %s:%d")
+ % (self.indexfile, rev))
+
+ self._cache = (node, rev, text)
+ return text
+
+ def checkinlinesize(self, tr, fp=None):
+ if not self._inline or (self.start(-2) + self.length(-2)) < 131072:
+ return
+
+ trinfo = tr.find(self.indexfile)
+ if trinfo is None:
+ raise RevlogError(_("%s not found in the transaction")
+ % self.indexfile)
+
+ trindex = trinfo[2]
+ dataoff = self.start(trindex)
+
+ tr.add(self.datafile, dataoff)
+
+ if fp:
+ fp.flush()
+ fp.close()
+
+ df = self.opener(self.datafile, 'w')
+ try:
+ for r in self:
+ df.write(self._chunkraw(r, r))
+ finally:
+ df.close()
+
+ fp = self.opener(self.indexfile, 'w', atomictemp=True)
+ self.version &= ~(REVLOGNGINLINEDATA)
+ self._inline = False
+ for i in self:
+ e = self._io.packentry(self.index[i], self.node, self.version, i)
+ fp.write(e)
+
+ # if we don't call rename, the temp file will never replace the
+ # real index
+ fp.rename()
+
+ tr.replace(self.indexfile, trindex * self._io.size)
+ self._chunkclear()
+
+ def addrevision(self, text, transaction, link, p1, p2, d=None):
+ """add a revision to the log
+
+ text - the revision data to add
+ transaction - the transaction object used for rollback
+ link - the linkrev data to add
+ p1, p2 - the parent nodeids of the revision
+ d - an optional precomputed delta
+ """
+ dfh = None
+ if not self._inline:
+ dfh = self.opener(self.datafile, "a")
+ ifh = self.opener(self.indexfile, "a+")
+ try:
+ return self._addrevision(text, transaction, link, p1, p2, d, ifh, dfh)
+ finally:
+ if dfh:
+ dfh.close()
+ ifh.close()
+
+ def _addrevision(self, text, transaction, link, p1, p2, d, ifh, dfh):
+ node = hash(text, p1, p2)
+ if node in self.nodemap:
+ return node
+
+ curr = len(self)
+ prev = curr - 1
+ base = self.base(prev)
+ offset = self.end(prev)
+
+ if curr:
+ if not d:
+ ptext = self.revision(self.node(prev))
+ d = mdiff.textdiff(ptext, text)
+ data = compress(d)
+ l = len(data[1]) + len(data[0])
+ dist = l + offset - self.start(base)
+
+ # full versions are inserted when the needed deltas
+ # become comparable to the uncompressed text
+ if not curr or dist > len(text) * 2:
+ data = compress(text)
+ l = len(data[1]) + len(data[0])
+ base = curr
+
+ e = (offset_type(offset, 0), l, len(text),
+ base, link, self.rev(p1), self.rev(p2), node)
+ self.index.insert(-1, e)
+ self.nodemap[node] = curr
+
+ entry = self._io.packentry(e, self.node, self.version, curr)
+ if not self._inline:
+ transaction.add(self.datafile, offset)
+ transaction.add(self.indexfile, curr * len(entry))
+ if data[0]:
+ dfh.write(data[0])
+ dfh.write(data[1])
+ dfh.flush()
+ ifh.write(entry)
+ else:
+ offset += curr * self._io.size
+ transaction.add(self.indexfile, offset, curr)
+ ifh.write(entry)
+ ifh.write(data[0])
+ ifh.write(data[1])
+ self.checkinlinesize(transaction, ifh)
+
+ self._cache = (node, curr, text)
+ return node
+
+ def ancestor(self, a, b):
+ """calculate the least common ancestor of nodes a and b"""
+
+ def parents(rev):
+ return [p for p in self.parentrevs(rev) if p != nullrev]
+
+ c = ancestor.ancestor(self.rev(a), self.rev(b), parents)
+ if c is None:
+ return nullid
+
+ return self.node(c)
+
+ def group(self, nodelist, lookup, infocollect=None):
+ """calculate a delta group
+
+ Given a list of changeset revs, return a set of deltas and
+ metadata corresponding to nodes. the first delta is
+ parent(nodes[0]) -> nodes[0] the receiver is guaranteed to
+ have this parent as it has all history before these
+ changesets. parent is parent[0]
+ """
+
+ revs = [self.rev(n) for n in nodelist]
+
+ # if we don't have any revisions touched by these changesets, bail
+ if not revs:
+ yield changegroup.closechunk()
+ return
+
+ # add the parent of the first rev
+ p = self.parentrevs(revs[0])[0]
+ revs.insert(0, p)
+
+ # build deltas
+ for d in xrange(len(revs) - 1):
+ a, b = revs[d], revs[d + 1]
+ nb = self.node(b)
+
+ if infocollect is not None:
+ infocollect(nb)
+
+ p = self.parents(nb)
+ meta = nb + p[0] + p[1] + lookup(nb)
+ if a == -1:
+ d = self.revision(nb)
+ meta += mdiff.trivialdiffheader(len(d))
+ else:
+ d = self.revdiff(a, b)
+ yield changegroup.chunkheader(len(meta) + len(d))
+ yield meta
+ if len(d) > 2**20:
+ pos = 0
+ while pos < len(d):
+ pos2 = pos + 2 ** 18
+ yield d[pos:pos2]
+ pos = pos2
+ else:
+ yield d
+
+ yield changegroup.closechunk()
+
+ def addgroup(self, revs, linkmapper, transaction):
+ """
+ add a delta group
+
+ given a set of deltas, add them to the revision log. the
+ first delta is against its parent, which should be in our
+ log, the rest are against the previous delta.
+ """
+
+ #track the base of the current delta log
+ r = len(self)
+ t = r - 1
+ node = None
+
+ base = prev = nullrev
+ start = end = textlen = 0
+ if r:
+ end = self.end(t)
+
+ ifh = self.opener(self.indexfile, "a+")
+ isize = r * self._io.size
+ if self._inline:
+ transaction.add(self.indexfile, end + isize, r)
+ dfh = None
+ else:
+ transaction.add(self.indexfile, isize, r)
+ transaction.add(self.datafile, end)
+ dfh = self.opener(self.datafile, "a")
+
+ try:
+ # loop through our set of deltas
+ chain = None
+ for chunk in revs:
+ node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
+ link = linkmapper(cs)
+ if node in self.nodemap:
+ # this can happen if two branches make the same change
+ chain = node
+ continue
+ delta = buffer(chunk, 80)
+ del chunk
+
+ for p in (p1, p2):
+ if not p in self.nodemap:
+ raise LookupError(p, self.indexfile, _('unknown parent'))
+
+ if not chain:
+ # retrieve the parent revision of the delta chain
+ chain = p1
+ if not chain in self.nodemap:
+ raise LookupError(chain, self.indexfile, _('unknown base'))
+
+ # full versions are inserted when the needed deltas become
+ # comparable to the uncompressed text or when the previous
+ # version is not the one we have a delta against. We use
+ # the size of the previous full rev as a proxy for the
+ # current size.
+
+ if chain == prev:
+ cdelta = compress(delta)
+ cdeltalen = len(cdelta[0]) + len(cdelta[1])
+ textlen = mdiff.patchedsize(textlen, delta)
+
+ if chain != prev or (end - start + cdeltalen) > textlen * 2:
+ # flush our writes here so we can read it in revision
+ if dfh:
+ dfh.flush()
+ ifh.flush()
+ text = self.revision(chain)
+ if len(text) == 0:
+ # skip over trivial delta header
+ text = buffer(delta, 12)
+ else:
+ text = mdiff.patches(text, [delta])
+ del delta
+ chk = self._addrevision(text, transaction, link, p1, p2, None,
+ ifh, dfh)
+ if not dfh and not self._inline:
+ # addrevision switched from inline to conventional
+ # reopen the index
+ dfh = self.opener(self.datafile, "a")
+ ifh = self.opener(self.indexfile, "a")
+ if chk != node:
+ raise RevlogError(_("consistency error adding group"))
+ textlen = len(text)
+ else:
+ e = (offset_type(end, 0), cdeltalen, textlen, base,
+ link, self.rev(p1), self.rev(p2), node)
+ self.index.insert(-1, e)
+ self.nodemap[node] = r
+ entry = self._io.packentry(e, self.node, self.version, r)
+ if self._inline:
+ ifh.write(entry)
+ ifh.write(cdelta[0])
+ ifh.write(cdelta[1])
+ self.checkinlinesize(transaction, ifh)
+ if not self._inline:
+ dfh = self.opener(self.datafile, "a")
+ ifh = self.opener(self.indexfile, "a")
+ else:
+ dfh.write(cdelta[0])
+ dfh.write(cdelta[1])
+ ifh.write(entry)
+
+ t, r, chain, prev = r, r + 1, node, node
+ base = self.base(t)
+ start = self.start(base)
+ end = self.end(t)
+ finally:
+ if dfh:
+ dfh.close()
+ ifh.close()
+
+ return node
+
+ def strip(self, minlink, transaction):
+ """truncate the revlog on the first revision with a linkrev >= minlink
+
+ This function is called when we're stripping revision minlink and
+ its descendants from the repository.
+
+ We have to remove all revisions with linkrev >= minlink, because
+ the equivalent changelog revisions will be renumbered after the
+ strip.
+
+ So we truncate the revlog on the first of these revisions, and
+ trust that the caller has saved the revisions that shouldn't be
+ removed and that it'll readd them after this truncation.
+ """
+ if len(self) == 0:
+ return
+
+ if isinstance(self.index, lazyindex):
+ self._loadindexmap()
+
+ for rev in self:
+ if self.index[rev][4] >= minlink:
+ break
+ else:
+ return
+
+ # first truncate the files on disk
+ end = self.start(rev)
+ if not self._inline:
+ transaction.add(self.datafile, end)
+ end = rev * self._io.size
+ else:
+ end += rev * self._io.size
+
+ transaction.add(self.indexfile, end)
+
+ # then reset internal state in memory to forget those revisions
+ self._cache = None
+ self._chunkclear()
+ for x in xrange(rev, len(self)):
+ del self.nodemap[self.node(x)]
+
+ del self.index[rev:-1]
+
+ def checksize(self):
+ expected = 0
+ if len(self):
+ expected = max(0, self.end(len(self) - 1))
+
+ try:
+ f = self.opener(self.datafile)
+ f.seek(0, 2)
+ actual = f.tell()
+ dd = actual - expected
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+ dd = 0
+
+ try:
+ f = self.opener(self.indexfile)
+ f.seek(0, 2)
+ actual = f.tell()
+ s = self._io.size
+ i = max(0, actual // s)
+ di = actual - (i * s)
+ if self._inline:
+ databytes = 0
+ for r in self:
+ databytes += max(0, self.length(r))
+ dd = 0
+ di = actual - len(self) * s - databytes
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+ di = 0
+
+ return (dd, di)
+
+ def files(self):
+ res = [ self.indexfile ]
+ if not self._inline:
+ res.append(self.datafile)
+ return res
diff --git a/sys/src/cmd/hg/mercurial/simplemerge.py b/sys/src/cmd/hg/mercurial/simplemerge.py
new file mode 100644
index 000000000..d876b47b9
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/simplemerge.py
@@ -0,0 +1,451 @@
+#!/usr/bin/env python
+# Copyright (C) 2004, 2005 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# mbp: "you know that thing where cvs gives you conflict markers?"
+# s: "i hate that."
+
+from i18n import _
+import util, mdiff
+import sys, os
+
+class CantReprocessAndShowBase(Exception):
+ pass
+
+def intersect(ra, rb):
+ """Given two ranges return the range where they intersect or None.
+
+ >>> intersect((0, 10), (0, 6))
+ (0, 6)
+ >>> intersect((0, 10), (5, 15))
+ (5, 10)
+ >>> intersect((0, 10), (10, 15))
+ >>> intersect((0, 9), (10, 15))
+ >>> intersect((0, 9), (7, 15))
+ (7, 9)
+ """
+ assert ra[0] <= ra[1]
+ assert rb[0] <= rb[1]
+
+ sa = max(ra[0], rb[0])
+ sb = min(ra[1], rb[1])
+ if sa < sb:
+ return sa, sb
+ else:
+ return None
+
+def compare_range(a, astart, aend, b, bstart, bend):
+ """Compare a[astart:aend] == b[bstart:bend], without slicing.
+ """
+ if (aend-astart) != (bend-bstart):
+ return False
+ for ia, ib in zip(xrange(astart, aend), xrange(bstart, bend)):
+ if a[ia] != b[ib]:
+ return False
+ else:
+ return True
+
+class Merge3Text(object):
+ """3-way merge of texts.
+
+ Given strings BASE, OTHER, THIS, tries to produce a combined text
+ incorporating the changes from both BASE->OTHER and BASE->THIS."""
+ def __init__(self, basetext, atext, btext, base=None, a=None, b=None):
+ self.basetext = basetext
+ self.atext = atext
+ self.btext = btext
+ if base is None:
+ base = mdiff.splitnewlines(basetext)
+ if a is None:
+ a = mdiff.splitnewlines(atext)
+ if b is None:
+ b = mdiff.splitnewlines(btext)
+ self.base = base
+ self.a = a
+ self.b = b
+
+ def merge_lines(self,
+ name_a=None,
+ name_b=None,
+ name_base=None,
+ start_marker='<<<<<<<',
+ mid_marker='=======',
+ end_marker='>>>>>>>',
+ base_marker=None,
+ reprocess=False):
+ """Return merge in cvs-like form.
+ """
+ self.conflicts = False
+ newline = '\n'
+ if len(self.a) > 0:
+ if self.a[0].endswith('\r\n'):
+ newline = '\r\n'
+ elif self.a[0].endswith('\r'):
+ newline = '\r'
+ if base_marker and reprocess:
+ raise CantReprocessAndShowBase()
+ if name_a:
+ start_marker = start_marker + ' ' + name_a
+ if name_b:
+ end_marker = end_marker + ' ' + name_b
+ if name_base and base_marker:
+ base_marker = base_marker + ' ' + name_base
+ merge_regions = self.merge_regions()
+ if reprocess is True:
+ merge_regions = self.reprocess_merge_regions(merge_regions)
+ for t in merge_regions:
+ what = t[0]
+ if what == 'unchanged':
+ for i in range(t[1], t[2]):
+ yield self.base[i]
+ elif what == 'a' or what == 'same':
+ for i in range(t[1], t[2]):
+ yield self.a[i]
+ elif what == 'b':
+ for i in range(t[1], t[2]):
+ yield self.b[i]
+ elif what == 'conflict':
+ self.conflicts = True
+ yield start_marker + newline
+ for i in range(t[3], t[4]):
+ yield self.a[i]
+ if base_marker is not None:
+ yield base_marker + newline
+ for i in range(t[1], t[2]):
+ yield self.base[i]
+ yield mid_marker + newline
+ for i in range(t[5], t[6]):
+ yield self.b[i]
+ yield end_marker + newline
+ else:
+ raise ValueError(what)
+
+ def merge_annotated(self):
+ """Return merge with conflicts, showing origin of lines.
+
+ Most useful for debugging merge.
+ """
+ for t in self.merge_regions():
+ what = t[0]
+ if what == 'unchanged':
+ for i in range(t[1], t[2]):
+ yield 'u | ' + self.base[i]
+ elif what == 'a' or what == 'same':
+ for i in range(t[1], t[2]):
+ yield what[0] + ' | ' + self.a[i]
+ elif what == 'b':
+ for i in range(t[1], t[2]):
+ yield 'b | ' + self.b[i]
+ elif what == 'conflict':
+ yield '<<<<\n'
+ for i in range(t[3], t[4]):
+ yield 'A | ' + self.a[i]
+ yield '----\n'
+ for i in range(t[5], t[6]):
+ yield 'B | ' + self.b[i]
+ yield '>>>>\n'
+ else:
+ raise ValueError(what)
+
+ def merge_groups(self):
+ """Yield sequence of line groups. Each one is a tuple:
+
+ 'unchanged', lines
+ Lines unchanged from base
+
+ 'a', lines
+ Lines taken from a
+
+ 'same', lines
+ Lines taken from a (and equal to b)
+
+ 'b', lines
+ Lines taken from b
+
+ 'conflict', base_lines, a_lines, b_lines
+ Lines from base were changed to either a or b and conflict.
+ """
+ for t in self.merge_regions():
+ what = t[0]
+ if what == 'unchanged':
+ yield what, self.base[t[1]:t[2]]
+ elif what == 'a' or what == 'same':
+ yield what, self.a[t[1]:t[2]]
+ elif what == 'b':
+ yield what, self.b[t[1]:t[2]]
+ elif what == 'conflict':
+ yield (what,
+ self.base[t[1]:t[2]],
+ self.a[t[3]:t[4]],
+ self.b[t[5]:t[6]])
+ else:
+ raise ValueError(what)
+
+ def merge_regions(self):
+ """Return sequences of matching and conflicting regions.
+
+ This returns tuples, where the first value says what kind we
+ have:
+
+ 'unchanged', start, end
+ Take a region of base[start:end]
+
+ 'same', astart, aend
+ b and a are different from base but give the same result
+
+ 'a', start, end
+ Non-clashing insertion from a[start:end]
+
+ Method is as follows:
+
+ The two sequences align only on regions which match the base
+ and both descendents. These are found by doing a two-way diff
+ of each one against the base, and then finding the
+ intersections between those regions. These "sync regions"
+ are by definition unchanged in both and easily dealt with.
+
+ The regions in between can be in any of three cases:
+ conflicted, or changed on only one side.
+ """
+
+ # section a[0:ia] has been disposed of, etc
+ iz = ia = ib = 0
+
+ for zmatch, zend, amatch, aend, bmatch, bend in self.find_sync_regions():
+ #print 'match base [%d:%d]' % (zmatch, zend)
+
+ matchlen = zend - zmatch
+ assert matchlen >= 0
+ assert matchlen == (aend - amatch)
+ assert matchlen == (bend - bmatch)
+
+ len_a = amatch - ia
+ len_b = bmatch - ib
+ len_base = zmatch - iz
+ assert len_a >= 0
+ assert len_b >= 0
+ assert len_base >= 0
+
+ #print 'unmatched a=%d, b=%d' % (len_a, len_b)
+
+ if len_a or len_b:
+ # try to avoid actually slicing the lists
+ equal_a = compare_range(self.a, ia, amatch,
+ self.base, iz, zmatch)
+ equal_b = compare_range(self.b, ib, bmatch,
+ self.base, iz, zmatch)
+ same = compare_range(self.a, ia, amatch,
+ self.b, ib, bmatch)
+
+ if same:
+ yield 'same', ia, amatch
+ elif equal_a and not equal_b:
+ yield 'b', ib, bmatch
+ elif equal_b and not equal_a:
+ yield 'a', ia, amatch
+ elif not equal_a and not equal_b:
+ yield 'conflict', iz, zmatch, ia, amatch, ib, bmatch
+ else:
+ raise AssertionError("can't handle a=b=base but unmatched")
+
+ ia = amatch
+ ib = bmatch
+ iz = zmatch
+
+ # if the same part of the base was deleted on both sides
+ # that's OK, we can just skip it.
+
+
+ if matchlen > 0:
+ assert ia == amatch
+ assert ib == bmatch
+ assert iz == zmatch
+
+ yield 'unchanged', zmatch, zend
+ iz = zend
+ ia = aend
+ ib = bend
+
+ def reprocess_merge_regions(self, merge_regions):
+ """Where there are conflict regions, remove the agreed lines.
+
+ Lines where both A and B have made the same changes are
+ eliminated.
+ """
+ for region in merge_regions:
+ if region[0] != "conflict":
+ yield region
+ continue
+ type, iz, zmatch, ia, amatch, ib, bmatch = region
+ a_region = self.a[ia:amatch]
+ b_region = self.b[ib:bmatch]
+ matches = mdiff.get_matching_blocks(''.join(a_region),
+ ''.join(b_region))
+ next_a = ia
+ next_b = ib
+ for region_ia, region_ib, region_len in matches[:-1]:
+ region_ia += ia
+ region_ib += ib
+ reg = self.mismatch_region(next_a, region_ia, next_b,
+ region_ib)
+ if reg is not None:
+ yield reg
+ yield 'same', region_ia, region_len+region_ia
+ next_a = region_ia + region_len
+ next_b = region_ib + region_len
+ reg = self.mismatch_region(next_a, amatch, next_b, bmatch)
+ if reg is not None:
+ yield reg
+
+ def mismatch_region(next_a, region_ia, next_b, region_ib):
+ if next_a < region_ia or next_b < region_ib:
+ return 'conflict', None, None, next_a, region_ia, next_b, region_ib
+ mismatch_region = staticmethod(mismatch_region)
+
+ def find_sync_regions(self):
+ """Return a list of sync regions, where both descendents match the base.
+
+ Generates a list of (base1, base2, a1, a2, b1, b2). There is
+ always a zero-length sync region at the end of all the files.
+ """
+
+ ia = ib = 0
+ amatches = mdiff.get_matching_blocks(self.basetext, self.atext)
+ bmatches = mdiff.get_matching_blocks(self.basetext, self.btext)
+ len_a = len(amatches)
+ len_b = len(bmatches)
+
+ sl = []
+
+ while ia < len_a and ib < len_b:
+ abase, amatch, alen = amatches[ia]
+ bbase, bmatch, blen = bmatches[ib]
+
+ # there is an unconflicted block at i; how long does it
+ # extend? until whichever one ends earlier.
+ i = intersect((abase, abase+alen), (bbase, bbase+blen))
+ if i:
+ intbase = i[0]
+ intend = i[1]
+ intlen = intend - intbase
+
+ # found a match of base[i[0], i[1]]; this may be less than
+ # the region that matches in either one
+ assert intlen <= alen
+ assert intlen <= blen
+ assert abase <= intbase
+ assert bbase <= intbase
+
+ asub = amatch + (intbase - abase)
+ bsub = bmatch + (intbase - bbase)
+ aend = asub + intlen
+ bend = bsub + intlen
+
+ assert self.base[intbase:intend] == self.a[asub:aend], \
+ (self.base[intbase:intend], self.a[asub:aend])
+
+ assert self.base[intbase:intend] == self.b[bsub:bend]
+
+ sl.append((intbase, intend,
+ asub, aend,
+ bsub, bend))
+
+ # advance whichever one ends first in the base text
+ if (abase + alen) < (bbase + blen):
+ ia += 1
+ else:
+ ib += 1
+
+ intbase = len(self.base)
+ abase = len(self.a)
+ bbase = len(self.b)
+ sl.append((intbase, intbase, abase, abase, bbase, bbase))
+
+ return sl
+
+ def find_unconflicted(self):
+ """Return a list of ranges in base that are not conflicted."""
+ am = mdiff.get_matching_blocks(self.basetext, self.atext)
+ bm = mdiff.get_matching_blocks(self.basetext, self.btext)
+
+ unc = []
+
+ while am and bm:
+ # there is an unconflicted block at i; how long does it
+ # extend? until whichever one ends earlier.
+ a1 = am[0][0]
+ a2 = a1 + am[0][2]
+ b1 = bm[0][0]
+ b2 = b1 + bm[0][2]
+ i = intersect((a1, a2), (b1, b2))
+ if i:
+ unc.append(i)
+
+ if a2 < b2:
+ del am[0]
+ else:
+ del bm[0]
+
+ return unc
+
+def simplemerge(ui, local, base, other, **opts):
+ def readfile(filename):
+ f = open(filename, "rb")
+ text = f.read()
+ f.close()
+ if util.binary(text):
+ msg = _("%s looks like a binary file.") % filename
+ if not opts.get('text'):
+ raise util.Abort(msg)
+ elif not opts.get('quiet'):
+ ui.warn(_('warning: %s\n') % msg)
+ return text
+
+ name_a = local
+ name_b = other
+ labels = opts.get('label', [])
+ if labels:
+ name_a = labels.pop(0)
+ if labels:
+ name_b = labels.pop(0)
+ if labels:
+ raise util.Abort(_("can only specify two labels."))
+
+ localtext = readfile(local)
+ basetext = readfile(base)
+ othertext = readfile(other)
+
+ local = os.path.realpath(local)
+ if not opts.get('print'):
+ opener = util.opener(os.path.dirname(local))
+ out = opener(os.path.basename(local), "w", atomictemp=True)
+ else:
+ out = sys.stdout
+
+ reprocess = not opts.get('no_minimal')
+
+ m3 = Merge3Text(basetext, localtext, othertext)
+ for line in m3.merge_lines(name_a=name_a, name_b=name_b,
+ reprocess=reprocess):
+ out.write(line)
+
+ if not opts.get('print'):
+ out.rename()
+
+ if m3.conflicts:
+ if not opts.get('quiet'):
+ ui.warn(_("warning: conflicts during merge.\n"))
+ return 1
diff --git a/sys/src/cmd/hg/mercurial/sshrepo.py b/sys/src/cmd/hg/mercurial/sshrepo.py
new file mode 100644
index 000000000..c6915bf65
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/sshrepo.py
@@ -0,0 +1,260 @@
+# sshrepo.py - ssh repository proxy class for mercurial
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import bin, hex
+from i18n import _
+import repo, util, error
+import re, urllib
+
+class remotelock(object):
+ def __init__(self, repo):
+ self.repo = repo
+ def release(self):
+ self.repo.unlock()
+ self.repo = None
+ def __del__(self):
+ if self.repo:
+ self.release()
+
+class sshrepository(repo.repository):
+ def __init__(self, ui, path, create=0):
+ self._url = path
+ self.ui = ui
+
+ m = re.match(r'^ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?$', path)
+ if not m:
+ self.abort(error.RepoError(_("couldn't parse location %s") % path))
+
+ self.user = m.group(2)
+ self.host = m.group(3)
+ self.port = m.group(5)
+ self.path = m.group(7) or "."
+
+ sshcmd = self.ui.config("ui", "ssh", "ssh")
+ remotecmd = self.ui.config("ui", "remotecmd", "hg")
+
+ args = util.sshargs(sshcmd, self.host, self.user, self.port)
+
+ if create:
+ cmd = '%s %s "%s init %s"'
+ cmd = cmd % (sshcmd, args, remotecmd, self.path)
+
+ ui.note(_('running %s\n') % cmd)
+ res = util.system(cmd)
+ if res != 0:
+ self.abort(error.RepoError(_("could not create remote repo")))
+
+ self.validate_repo(ui, sshcmd, args, remotecmd)
+
+ def url(self):
+ return self._url
+
+ def validate_repo(self, ui, sshcmd, args, remotecmd):
+ # cleanup up previous run
+ self.cleanup()
+
+ cmd = '%s %s "%s -R %s serve --stdio"'
+ cmd = cmd % (sshcmd, args, remotecmd, self.path)
+
+ cmd = util.quotecommand(cmd)
+ ui.note(_('running %s\n') % cmd)
+ self.pipeo, self.pipei, self.pipee = util.popen3(cmd)
+
+ # skip any noise generated by remote shell
+ self.do_cmd("hello")
+ r = self.do_cmd("between", pairs=("%s-%s" % ("0"*40, "0"*40)))
+ lines = ["", "dummy"]
+ max_noise = 500
+ while lines[-1] and max_noise:
+ l = r.readline()
+ self.readerr()
+ if lines[-1] == "1\n" and l == "\n":
+ break
+ if l:
+ ui.debug(_("remote: "), l)
+ lines.append(l)
+ max_noise -= 1
+ else:
+ self.abort(error.RepoError(_("no suitable response from remote hg")))
+
+ self.capabilities = set()
+ for l in reversed(lines):
+ if l.startswith("capabilities:"):
+ self.capabilities.update(l[:-1].split(":")[1].split())
+ break
+
+ def readerr(self):
+ while 1:
+ size = util.fstat(self.pipee).st_size
+ if size == 0: break
+ l = self.pipee.readline()
+ if not l: break
+ self.ui.status(_("remote: "), l)
+
+ def abort(self, exception):
+ self.cleanup()
+ raise exception
+
+ def cleanup(self):
+ try:
+ self.pipeo.close()
+ self.pipei.close()
+ # read the error descriptor until EOF
+ for l in self.pipee:
+ self.ui.status(_("remote: "), l)
+ self.pipee.close()
+ except:
+ pass
+
+ __del__ = cleanup
+
+ def do_cmd(self, cmd, **args):
+ self.ui.debug(_("sending %s command\n") % cmd)
+ self.pipeo.write("%s\n" % cmd)
+ for k, v in args.iteritems():
+ self.pipeo.write("%s %d\n" % (k, len(v)))
+ self.pipeo.write(v)
+ self.pipeo.flush()
+
+ return self.pipei
+
+ def call(self, cmd, **args):
+ self.do_cmd(cmd, **args)
+ return self._recv()
+
+ def _recv(self):
+ l = self.pipei.readline()
+ self.readerr()
+ try:
+ l = int(l)
+ except:
+ self.abort(error.ResponseError(_("unexpected response:"), l))
+ return self.pipei.read(l)
+
+ def _send(self, data, flush=False):
+ self.pipeo.write("%d\n" % len(data))
+ if data:
+ self.pipeo.write(data)
+ if flush:
+ self.pipeo.flush()
+ self.readerr()
+
+ def lock(self):
+ self.call("lock")
+ return remotelock(self)
+
+ def unlock(self):
+ self.call("unlock")
+
+ def lookup(self, key):
+ self.requirecap('lookup', _('look up remote revision'))
+ d = self.call("lookup", key=key)
+ success, data = d[:-1].split(" ", 1)
+ if int(success):
+ return bin(data)
+ else:
+ self.abort(error.RepoError(data))
+
+ def heads(self):
+ d = self.call("heads")
+ try:
+ return map(bin, d[:-1].split(" "))
+ except:
+ self.abort(error.ResponseError(_("unexpected response:"), d))
+
+ def branchmap(self):
+ d = self.call("branchmap")
+ try:
+ branchmap = {}
+ for branchpart in d.splitlines():
+ branchheads = branchpart.split(' ')
+ branchname = urllib.unquote(branchheads[0])
+ branchheads = [bin(x) for x in branchheads[1:]]
+ branchmap[branchname] = branchheads
+ return branchmap
+ except:
+ raise error.ResponseError(_("unexpected response:"), d)
+
+ def branches(self, nodes):
+ n = " ".join(map(hex, nodes))
+ d = self.call("branches", nodes=n)
+ try:
+ br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
+ return br
+ except:
+ self.abort(error.ResponseError(_("unexpected response:"), d))
+
+ def between(self, pairs):
+ n = " ".join(["-".join(map(hex, p)) for p in pairs])
+ d = self.call("between", pairs=n)
+ try:
+ p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
+ return p
+ except:
+ self.abort(error.ResponseError(_("unexpected response:"), d))
+
+ def changegroup(self, nodes, kind):
+ n = " ".join(map(hex, nodes))
+ return self.do_cmd("changegroup", roots=n)
+
+ def changegroupsubset(self, bases, heads, kind):
+ self.requirecap('changegroupsubset', _('look up remote changes'))
+ bases = " ".join(map(hex, bases))
+ heads = " ".join(map(hex, heads))
+ return self.do_cmd("changegroupsubset", bases=bases, heads=heads)
+
+ def unbundle(self, cg, heads, source):
+ d = self.call("unbundle", heads=' '.join(map(hex, heads)))
+ if d:
+ # remote may send "unsynced changes"
+ self.abort(error.RepoError(_("push refused: %s") % d))
+
+ while 1:
+ d = cg.read(4096)
+ if not d:
+ break
+ self._send(d)
+
+ self._send("", flush=True)
+
+ r = self._recv()
+ if r:
+ # remote may send "unsynced changes"
+ self.abort(error.RepoError(_("push failed: %s") % r))
+
+ r = self._recv()
+ try:
+ return int(r)
+ except:
+ self.abort(error.ResponseError(_("unexpected response:"), r))
+
+ def addchangegroup(self, cg, source, url):
+ d = self.call("addchangegroup")
+ if d:
+ self.abort(error.RepoError(_("push refused: %s") % d))
+ while 1:
+ d = cg.read(4096)
+ if not d:
+ break
+ self.pipeo.write(d)
+ self.readerr()
+
+ self.pipeo.flush()
+
+ self.readerr()
+ r = self._recv()
+ if not r:
+ return 1
+ try:
+ return int(r)
+ except:
+ self.abort(error.ResponseError(_("unexpected response:"), r))
+
+ def stream_out(self):
+ return self.do_cmd('stream_out')
+
+instance = sshrepository
diff --git a/sys/src/cmd/hg/mercurial/sshserver.py b/sys/src/cmd/hg/mercurial/sshserver.py
new file mode 100644
index 000000000..d5fccbc43
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/sshserver.py
@@ -0,0 +1,225 @@
+# sshserver.py - ssh protocol server support for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+from node import bin, hex
+import streamclone, util, hook
+import os, sys, tempfile, urllib
+
+class sshserver(object):
+ def __init__(self, ui, repo):
+ self.ui = ui
+ self.repo = repo
+ self.lock = None
+ self.fin = sys.stdin
+ self.fout = sys.stdout
+
+ hook.redirect(True)
+ sys.stdout = sys.stderr
+
+ # Prevent insertion/deletion of CRs
+ util.set_binary(self.fin)
+ util.set_binary(self.fout)
+
+ def getarg(self):
+ argline = self.fin.readline()[:-1]
+ arg, l = argline.split()
+ val = self.fin.read(int(l))
+ return arg, val
+
+ def respond(self, v):
+ self.fout.write("%d\n" % len(v))
+ self.fout.write(v)
+ self.fout.flush()
+
+ def serve_forever(self):
+ try:
+ while self.serve_one(): pass
+ finally:
+ if self.lock is not None:
+ self.lock.release()
+ sys.exit(0)
+
+ def serve_one(self):
+ cmd = self.fin.readline()[:-1]
+ if cmd:
+ impl = getattr(self, 'do_' + cmd, None)
+ if impl: impl()
+ else: self.respond("")
+ return cmd != ''
+
+ def do_lookup(self):
+ arg, key = self.getarg()
+ assert arg == 'key'
+ try:
+ r = hex(self.repo.lookup(key))
+ success = 1
+ except Exception, inst:
+ r = str(inst)
+ success = 0
+ self.respond("%s %s\n" % (success, r))
+
+ def do_branchmap(self):
+ branchmap = self.repo.branchmap()
+ heads = []
+ for branch, nodes in branchmap.iteritems():
+ branchname = urllib.quote(branch)
+ branchnodes = [hex(node) for node in nodes]
+ heads.append('%s %s' % (branchname, ' '.join(branchnodes)))
+ self.respond('\n'.join(heads))
+
+ def do_heads(self):
+ h = self.repo.heads()
+ self.respond(" ".join(map(hex, h)) + "\n")
+
+ def do_hello(self):
+ '''the hello command returns a set of lines describing various
+ interesting things about the server, in an RFC822-like format.
+ Currently the only one defined is "capabilities", which
+ consists of a line in the form:
+
+ capabilities: space separated list of tokens
+ '''
+
+ caps = ['unbundle', 'lookup', 'changegroupsubset', 'branchmap']
+ if self.ui.configbool('server', 'uncompressed'):
+ caps.append('stream=%d' % self.repo.changelog.version)
+ self.respond("capabilities: %s\n" % (' '.join(caps),))
+
+ def do_lock(self):
+ '''DEPRECATED - allowing remote client to lock repo is not safe'''
+
+ self.lock = self.repo.lock()
+ self.respond("")
+
+ def do_unlock(self):
+ '''DEPRECATED'''
+
+ if self.lock:
+ self.lock.release()
+ self.lock = None
+ self.respond("")
+
+ def do_branches(self):
+ arg, nodes = self.getarg()
+ nodes = map(bin, nodes.split(" "))
+ r = []
+ for b in self.repo.branches(nodes):
+ r.append(" ".join(map(hex, b)) + "\n")
+ self.respond("".join(r))
+
+ def do_between(self):
+ arg, pairs = self.getarg()
+ pairs = [map(bin, p.split("-")) for p in pairs.split(" ")]
+ r = []
+ for b in self.repo.between(pairs):
+ r.append(" ".join(map(hex, b)) + "\n")
+ self.respond("".join(r))
+
+ def do_changegroup(self):
+ nodes = []
+ arg, roots = self.getarg()
+ nodes = map(bin, roots.split(" "))
+
+ cg = self.repo.changegroup(nodes, 'serve')
+ while True:
+ d = cg.read(4096)
+ if not d:
+ break
+ self.fout.write(d)
+
+ self.fout.flush()
+
+ def do_changegroupsubset(self):
+ argmap = dict([self.getarg(), self.getarg()])
+ bases = [bin(n) for n in argmap['bases'].split(' ')]
+ heads = [bin(n) for n in argmap['heads'].split(' ')]
+
+ cg = self.repo.changegroupsubset(bases, heads, 'serve')
+ while True:
+ d = cg.read(4096)
+ if not d:
+ break
+ self.fout.write(d)
+
+ self.fout.flush()
+
+ def do_addchangegroup(self):
+ '''DEPRECATED'''
+
+ if not self.lock:
+ self.respond("not locked")
+ return
+
+ self.respond("")
+ r = self.repo.addchangegroup(self.fin, 'serve', self.client_url())
+ self.respond(str(r))
+
+ def client_url(self):
+ client = os.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
+ return 'remote:ssh:' + client
+
+ def do_unbundle(self):
+ their_heads = self.getarg()[1].split()
+
+ def check_heads():
+ heads = map(hex, self.repo.heads())
+ return their_heads == [hex('force')] or their_heads == heads
+
+ # fail early if possible
+ if not check_heads():
+ self.respond(_('unsynced changes'))
+ return
+
+ self.respond('')
+
+ # write bundle data to temporary file because it can be big
+ tempname = fp = None
+ try:
+ fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
+ fp = os.fdopen(fd, 'wb+')
+
+ count = int(self.fin.readline())
+ while count:
+ fp.write(self.fin.read(count))
+ count = int(self.fin.readline())
+
+ was_locked = self.lock is not None
+ if not was_locked:
+ self.lock = self.repo.lock()
+ try:
+ if not check_heads():
+ # someone else committed/pushed/unbundled while we
+ # were transferring data
+ self.respond(_('unsynced changes'))
+ return
+ self.respond('')
+
+ # push can proceed
+
+ fp.seek(0)
+ r = self.repo.addchangegroup(fp, 'serve', self.client_url())
+ self.respond(str(r))
+ finally:
+ if not was_locked:
+ self.lock.release()
+ self.lock = None
+ finally:
+ if fp is not None:
+ fp.close()
+ if tempname is not None:
+ os.unlink(tempname)
+
+ def do_stream_out(self):
+ try:
+ for chunk in streamclone.stream_out(self.repo):
+ self.fout.write(chunk)
+ self.fout.flush()
+ except streamclone.StreamException, inst:
+ self.fout.write(str(inst))
+ self.fout.flush()
diff --git a/sys/src/cmd/hg/mercurial/statichttprepo.py b/sys/src/cmd/hg/mercurial/statichttprepo.py
new file mode 100644
index 000000000..0913d2fbb
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/statichttprepo.py
@@ -0,0 +1,134 @@
+# statichttprepo.py - simple http repository class for mercurial
+#
+# This provides read-only repo access to repositories exported via static http
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import changelog, byterange, url, error
+import localrepo, manifest, util, store
+import urllib, urllib2, errno
+
+class httprangereader(object):
+ def __init__(self, url, opener):
+ # we assume opener has HTTPRangeHandler
+ self.url = url
+ self.pos = 0
+ self.opener = opener
+ def seek(self, pos):
+ self.pos = pos
+ def read(self, bytes=None):
+ req = urllib2.Request(self.url)
+ end = ''
+ if bytes:
+ end = self.pos + bytes - 1
+ req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
+
+ try:
+ f = self.opener.open(req)
+ data = f.read()
+ if hasattr(f, 'getcode'):
+ # python 2.6+
+ code = f.getcode()
+ elif hasattr(f, 'code'):
+ # undocumented attribute, seems to be set in 2.4 and 2.5
+ code = f.code
+ else:
+ # Don't know how to check, hope for the best.
+ code = 206
+ except urllib2.HTTPError, inst:
+ num = inst.code == 404 and errno.ENOENT or None
+ raise IOError(num, inst)
+ except urllib2.URLError, inst:
+ raise IOError(None, inst.reason[1])
+
+ if code == 200:
+ # HTTPRangeHandler does nothing if remote does not support
+ # Range headers and returns the full entity. Let's slice it.
+ if bytes:
+ data = data[self.pos:self.pos + bytes]
+ else:
+ data = data[self.pos:]
+ elif bytes:
+ data = data[:bytes]
+ self.pos += len(data)
+ return data
+
+def build_opener(ui, authinfo):
+ # urllib cannot handle URLs with embedded user or passwd
+ urlopener = url.opener(ui, authinfo)
+ urlopener.add_handler(byterange.HTTPRangeHandler())
+
+ def opener(base):
+ """return a function that opens files over http"""
+ p = base
+ def o(path, mode="r"):
+ f = "/".join((p, urllib.quote(path)))
+ return httprangereader(f, urlopener)
+ return o
+
+ return opener
+
+class statichttprepository(localrepo.localrepository):
+ def __init__(self, ui, path):
+ self._url = path
+ self.ui = ui
+
+ self.path, authinfo = url.getauthinfo(path.rstrip('/') + "/.hg")
+
+ opener = build_opener(ui, authinfo)
+ self.opener = opener(self.path)
+
+ # find requirements
+ try:
+ requirements = self.opener("requires").read().splitlines()
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+ # check if it is a non-empty old-style repository
+ try:
+ self.opener("00changelog.i").read(1)
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+ # we do not care about empty old-style repositories here
+ msg = _("'%s' does not appear to be an hg repository") % path
+ raise error.RepoError(msg)
+ requirements = []
+
+ # check them
+ for r in requirements:
+ if r not in self.supported:
+ raise error.RepoError(_("requirement '%s' not supported") % r)
+
+ # setup store
+ def pjoin(a, b):
+ return a + '/' + b
+ self.store = store.store(requirements, self.path, opener, pjoin)
+ self.spath = self.store.path
+ self.sopener = self.store.opener
+ self.sjoin = self.store.join
+
+ self.manifest = manifest.manifest(self.sopener)
+ self.changelog = changelog.changelog(self.sopener)
+ self._tags = None
+ self.nodetagscache = None
+ self.encodepats = None
+ self.decodepats = None
+
+ def url(self):
+ return self._url
+
+ def local(self):
+ return False
+
+ def lock(self, wait=True):
+ raise util.Abort(_('cannot lock static-http repository'))
+
+def instance(ui, path, create):
+ if create:
+ raise util.Abort(_('cannot create new static-http repository'))
+ return statichttprepository(ui, path[7:])
diff --git a/sys/src/cmd/hg/mercurial/store.py b/sys/src/cmd/hg/mercurial/store.py
new file mode 100644
index 000000000..eec9dd519
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/store.py
@@ -0,0 +1,333 @@
+# store.py - repository store handling for Mercurial
+#
+# Copyright 2008 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import osutil, util
+import os, stat
+
+_sha = util.sha1
+
+# This avoids a collision between a file named foo and a dir named
+# foo.i or foo.d
+def encodedir(path):
+ if not path.startswith('data/'):
+ return path
+ return (path
+ .replace(".hg/", ".hg.hg/")
+ .replace(".i/", ".i.hg/")
+ .replace(".d/", ".d.hg/"))
+
+def decodedir(path):
+ if not path.startswith('data/'):
+ return path
+ return (path
+ .replace(".d.hg/", ".d/")
+ .replace(".i.hg/", ".i/")
+ .replace(".hg.hg/", ".hg/"))
+
+def _buildencodefun():
+ e = '_'
+ win_reserved = [ord(x) for x in '\\:*?"<>|']
+ cmap = dict([ (chr(x), chr(x)) for x in xrange(127) ])
+ for x in (range(32) + range(126, 256) + win_reserved):
+ cmap[chr(x)] = "~%02x" % x
+ for x in range(ord("A"), ord("Z")+1) + [ord(e)]:
+ cmap[chr(x)] = e + chr(x).lower()
+ dmap = {}
+ for k, v in cmap.iteritems():
+ dmap[v] = k
+ def decode(s):
+ i = 0
+ while i < len(s):
+ for l in xrange(1, 4):
+ try:
+ yield dmap[s[i:i+l]]
+ i += l
+ break
+ except KeyError:
+ pass
+ else:
+ raise KeyError
+ return (lambda s: "".join([cmap[c] for c in encodedir(s)]),
+ lambda s: decodedir("".join(list(decode(s)))))
+
+encodefilename, decodefilename = _buildencodefun()
+
+def _build_lower_encodefun():
+ win_reserved = [ord(x) for x in '\\:*?"<>|']
+ cmap = dict([ (chr(x), chr(x)) for x in xrange(127) ])
+ for x in (range(32) + range(126, 256) + win_reserved):
+ cmap[chr(x)] = "~%02x" % x
+ for x in range(ord("A"), ord("Z")+1):
+ cmap[chr(x)] = chr(x).lower()
+ return lambda s: "".join([cmap[c] for c in s])
+
+lowerencode = _build_lower_encodefun()
+
+_windows_reserved_filenames = '''con prn aux nul
+ com1 com2 com3 com4 com5 com6 com7 com8 com9
+ lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9'''.split()
+def auxencode(path):
+ res = []
+ for n in path.split('/'):
+ if n:
+ base = n.split('.')[0]
+ if base and (base in _windows_reserved_filenames):
+ # encode third letter ('aux' -> 'au~78')
+ ec = "~%02x" % ord(n[2])
+ n = n[0:2] + ec + n[3:]
+ if n[-1] in '. ':
+ # encode last period or space ('foo...' -> 'foo..~2e')
+ n = n[:-1] + "~%02x" % ord(n[-1])
+ res.append(n)
+ return '/'.join(res)
+
+MAX_PATH_LEN_IN_HGSTORE = 120
+DIR_PREFIX_LEN = 8
+_MAX_SHORTENED_DIRS_LEN = 8 * (DIR_PREFIX_LEN + 1) - 4
+def hybridencode(path):
+ '''encodes path with a length limit
+
+ Encodes all paths that begin with 'data/', according to the following.
+
+ Default encoding (reversible):
+
+ Encodes all uppercase letters 'X' as '_x'. All reserved or illegal
+ characters are encoded as '~xx', where xx is the two digit hex code
+ of the character (see encodefilename).
+ Relevant path components consisting of Windows reserved filenames are
+ masked by encoding the third character ('aux' -> 'au~78', see auxencode).
+
+ Hashed encoding (not reversible):
+
+ If the default-encoded path is longer than MAX_PATH_LEN_IN_HGSTORE, a
+ non-reversible hybrid hashing of the path is done instead.
+ This encoding uses up to DIR_PREFIX_LEN characters of all directory
+ levels of the lowerencoded path, but not more levels than can fit into
+ _MAX_SHORTENED_DIRS_LEN.
+ Then follows the filler followed by the sha digest of the full path.
+ The filler is the beginning of the basename of the lowerencoded path
+ (the basename is everything after the last path separator). The filler
+ is as long as possible, filling in characters from the basename until
+ the encoded path has MAX_PATH_LEN_IN_HGSTORE characters (or all chars
+ of the basename have been taken).
+ The extension (e.g. '.i' or '.d') is preserved.
+
+ The string 'data/' at the beginning is replaced with 'dh/', if the hashed
+ encoding was used.
+ '''
+ if not path.startswith('data/'):
+ return path
+ # escape directories ending with .i and .d
+ path = encodedir(path)
+ ndpath = path[len('data/'):]
+ res = 'data/' + auxencode(encodefilename(ndpath))
+ if len(res) > MAX_PATH_LEN_IN_HGSTORE:
+ digest = _sha(path).hexdigest()
+ aep = auxencode(lowerencode(ndpath))
+ _root, ext = os.path.splitext(aep)
+ parts = aep.split('/')
+ basename = parts[-1]
+ sdirs = []
+ for p in parts[:-1]:
+ d = p[:DIR_PREFIX_LEN]
+ if d[-1] in '. ':
+ # Windows can't access dirs ending in period or space
+ d = d[:-1] + '_'
+ t = '/'.join(sdirs) + '/' + d
+ if len(t) > _MAX_SHORTENED_DIRS_LEN:
+ break
+ sdirs.append(d)
+ dirs = '/'.join(sdirs)
+ if len(dirs) > 0:
+ dirs += '/'
+ res = 'dh/' + dirs + digest + ext
+ space_left = MAX_PATH_LEN_IN_HGSTORE - len(res)
+ if space_left > 0:
+ filler = basename[:space_left]
+ res = 'dh/' + dirs + filler + digest + ext
+ return res
+
+def _calcmode(path):
+ try:
+ # files in .hg/ will be created using this mode
+ mode = os.stat(path).st_mode
+ # avoid some useless chmods
+ if (0777 & ~util.umask) == (0777 & mode):
+ mode = None
+ except OSError:
+ mode = None
+ return mode
+
+_data = 'data 00manifest.d 00manifest.i 00changelog.d 00changelog.i'
+
+class basicstore(object):
+ '''base class for local repository stores'''
+ def __init__(self, path, opener, pathjoiner):
+ self.pathjoiner = pathjoiner
+ self.path = path
+ self.createmode = _calcmode(path)
+ op = opener(self.path)
+ op.createmode = self.createmode
+ self.opener = lambda f, *args, **kw: op(encodedir(f), *args, **kw)
+
+ def join(self, f):
+ return self.pathjoiner(self.path, encodedir(f))
+
+ def _walk(self, relpath, recurse):
+ '''yields (unencoded, encoded, size)'''
+ path = self.pathjoiner(self.path, relpath)
+ striplen = len(self.path) + len(os.sep)
+ l = []
+ if os.path.isdir(path):
+ visit = [path]
+ while visit:
+ p = visit.pop()
+ for f, kind, st in osutil.listdir(p, stat=True):
+ fp = self.pathjoiner(p, f)
+ if kind == stat.S_IFREG and f[-2:] in ('.d', '.i'):
+ n = util.pconvert(fp[striplen:])
+ l.append((decodedir(n), n, st.st_size))
+ elif kind == stat.S_IFDIR and recurse:
+ visit.append(fp)
+ return sorted(l)
+
+ def datafiles(self):
+ return self._walk('data', True)
+
+ def walk(self):
+ '''yields (unencoded, encoded, size)'''
+ # yield data files first
+ for x in self.datafiles():
+ yield x
+ # yield manifest before changelog
+ for x in reversed(self._walk('', False)):
+ yield x
+
+ def copylist(self):
+ return ['requires'] + _data.split()
+
+class encodedstore(basicstore):
+ def __init__(self, path, opener, pathjoiner):
+ self.pathjoiner = pathjoiner
+ self.path = self.pathjoiner(path, 'store')
+ self.createmode = _calcmode(self.path)
+ op = opener(self.path)
+ op.createmode = self.createmode
+ self.opener = lambda f, *args, **kw: op(encodefilename(f), *args, **kw)
+
+ def datafiles(self):
+ for a, b, size in self._walk('data', True):
+ try:
+ a = decodefilename(a)
+ except KeyError:
+ a = None
+ yield a, b, size
+
+ def join(self, f):
+ return self.pathjoiner(self.path, encodefilename(f))
+
+ def copylist(self):
+ return (['requires', '00changelog.i'] +
+ [self.pathjoiner('store', f) for f in _data.split()])
+
+class fncache(object):
+ # the filename used to be partially encoded
+ # hence the encodedir/decodedir dance
+ def __init__(self, opener):
+ self.opener = opener
+ self.entries = None
+
+ def _load(self):
+ '''fill the entries from the fncache file'''
+ self.entries = set()
+ try:
+ fp = self.opener('fncache', mode='rb')
+ except IOError:
+ # skip nonexistent file
+ return
+ for n, line in enumerate(fp):
+ if (len(line) < 2) or (line[-1] != '\n'):
+ t = _('invalid entry in fncache, line %s') % (n + 1)
+ raise util.Abort(t)
+ self.entries.add(decodedir(line[:-1]))
+ fp.close()
+
+ def rewrite(self, files):
+ fp = self.opener('fncache', mode='wb')
+ for p in files:
+ fp.write(encodedir(p) + '\n')
+ fp.close()
+ self.entries = set(files)
+
+ def add(self, fn):
+ if self.entries is None:
+ self._load()
+ self.opener('fncache', 'ab').write(encodedir(fn) + '\n')
+
+ def __contains__(self, fn):
+ if self.entries is None:
+ self._load()
+ return fn in self.entries
+
+ def __iter__(self):
+ if self.entries is None:
+ self._load()
+ return iter(self.entries)
+
+class fncachestore(basicstore):
+ def __init__(self, path, opener, pathjoiner):
+ self.pathjoiner = pathjoiner
+ self.path = self.pathjoiner(path, 'store')
+ self.createmode = _calcmode(self.path)
+ op = opener(self.path)
+ op.createmode = self.createmode
+ fnc = fncache(op)
+ self.fncache = fnc
+
+ def fncacheopener(path, mode='r', *args, **kw):
+ if (mode not in ('r', 'rb')
+ and path.startswith('data/')
+ and path not in fnc):
+ fnc.add(path)
+ return op(hybridencode(path), mode, *args, **kw)
+ self.opener = fncacheopener
+
+ def join(self, f):
+ return self.pathjoiner(self.path, hybridencode(f))
+
+ def datafiles(self):
+ rewrite = False
+ existing = []
+ pjoin = self.pathjoiner
+ spath = self.path
+ for f in self.fncache:
+ ef = hybridencode(f)
+ try:
+ st = os.stat(pjoin(spath, ef))
+ yield f, ef, st.st_size
+ existing.append(f)
+ except OSError:
+ # nonexistent entry
+ rewrite = True
+ if rewrite:
+ # rewrite fncache to remove nonexistent entries
+ # (may be caused by rollback / strip)
+ self.fncache.rewrite(existing)
+
+ def copylist(self):
+ d = _data + ' dh fncache'
+ return (['requires', '00changelog.i'] +
+ [self.pathjoiner('store', f) for f in d.split()])
+
+def store(requirements, path, opener, pathjoiner=None):
+ pathjoiner = pathjoiner or os.path.join
+ if 'store' in requirements:
+ if 'fncache' in requirements:
+ return fncachestore(path, opener, pathjoiner)
+ return encodedstore(path, opener, pathjoiner)
+ return basicstore(path, opener, pathjoiner)
diff --git a/sys/src/cmd/hg/mercurial/streamclone.py b/sys/src/cmd/hg/mercurial/streamclone.py
new file mode 100644
index 000000000..82cd2f730
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/streamclone.py
@@ -0,0 +1,67 @@
+# streamclone.py - streaming clone server support for mercurial
+#
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import util, error
+from i18n import _
+
+from mercurial import store
+
+class StreamException(Exception):
+ def __init__(self, code):
+ Exception.__init__(self)
+ self.code = code
+ def __str__(self):
+ return '%i\n' % self.code
+
+# if server supports streaming clone, it advertises "stream"
+# capability with value that is version+flags of repo it is serving.
+# client only streams if it can read that repo format.
+
+# stream file format is simple.
+#
+# server writes out line that says how many files, how many total
+# bytes. separator is ascii space, byte counts are strings.
+#
+# then for each file:
+#
+# server writes out line that says filename, how many bytes in
+# file. separator is ascii nul, byte count is string.
+#
+# server writes out raw file data.
+
+def stream_out(repo, untrusted=False):
+ '''stream out all metadata files in repository.
+ writes to file-like object, must support write() and optional flush().'''
+
+ if not repo.ui.configbool('server', 'uncompressed', untrusted=untrusted):
+ raise StreamException(1)
+
+ entries = []
+ total_bytes = 0
+ try:
+ # get consistent snapshot of repo, lock during scan
+ lock = repo.lock()
+ try:
+ repo.ui.debug(_('scanning\n'))
+ for name, ename, size in repo.store.walk():
+ # for backwards compat, name was partially encoded
+ entries.append((store.encodedir(name), size))
+ total_bytes += size
+ finally:
+ lock.release()
+ except error.LockError:
+ raise StreamException(2)
+
+ yield '0\n'
+ repo.ui.debug(_('%d files, %d bytes to transfer\n') %
+ (len(entries), total_bytes))
+ yield '%d %d\n' % (len(entries), total_bytes)
+ for name, size in entries:
+ repo.ui.debug(_('sending %s (%d bytes)\n') % (name, size))
+ yield '%s\0%d\n' % (name, size)
+ for chunk in util.filechunkiter(repo.sopener(name), limit=size):
+ yield chunk
diff --git a/sys/src/cmd/hg/mercurial/strutil.py b/sys/src/cmd/hg/mercurial/strutil.py
new file mode 100644
index 000000000..fab37c419
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/strutil.py
@@ -0,0 +1,34 @@
+# strutil.py - string utilities for Mercurial
+#
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+def findall(haystack, needle, start=0, end=None):
+ if end is None:
+ end = len(haystack)
+ if end < 0:
+ end += len(haystack)
+ if start < 0:
+ start += len(haystack)
+ while start < end:
+ c = haystack.find(needle, start, end)
+ if c == -1:
+ break
+ yield c
+ start = c + 1
+
+def rfindall(haystack, needle, start=0, end=None):
+ if end is None:
+ end = len(haystack)
+ if end < 0:
+ end += len(haystack)
+ if start < 0:
+ start += len(haystack)
+ while end >= 0:
+ c = haystack.rfind(needle, start, end)
+ if c == -1:
+ break
+ yield c
+ end = c - 1
diff --git a/sys/src/cmd/hg/mercurial/subrepo.py b/sys/src/cmd/hg/mercurial/subrepo.py
new file mode 100644
index 000000000..0eb313fe0
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/subrepo.py
@@ -0,0 +1,197 @@
+# subrepo.py - sub-repository handling for Mercurial
+#
+# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import errno, os
+from i18n import _
+import config, util, node, error
+hg = None
+
+nullstate = ('', '')
+
+def state(ctx):
+ p = config.config()
+ def read(f, sections=None, remap=None):
+ if f in ctx:
+ try:
+ p.parse(f, ctx[f].data(), sections, remap)
+ except IOError, err:
+ if err.errno != errno.ENOENT:
+ raise
+ read('.hgsub')
+
+ rev = {}
+ if '.hgsubstate' in ctx:
+ try:
+ for l in ctx['.hgsubstate'].data().splitlines():
+ revision, path = l.split()
+ rev[path] = revision
+ except IOError, err:
+ if err.errno != errno.ENOENT:
+ raise
+
+ state = {}
+ for path, src in p[''].items():
+ state[path] = (src, rev.get(path, ''))
+
+ return state
+
+def writestate(repo, state):
+ repo.wwrite('.hgsubstate',
+ ''.join(['%s %s\n' % (state[s][1], s)
+ for s in sorted(state)]), '')
+
+def submerge(repo, wctx, mctx, actx):
+ if mctx == actx: # backwards?
+ actx = wctx.p1()
+ s1 = wctx.substate
+ s2 = mctx.substate
+ sa = actx.substate
+ sm = {}
+
+ for s, l in s1.items():
+ a = sa.get(s, nullstate)
+ if s in s2:
+ r = s2[s]
+ if l == r or r == a: # no change or local is newer
+ sm[s] = l
+ continue
+ elif l == a: # other side changed
+ wctx.sub(s).get(r)
+ sm[s] = r
+ elif l[0] != r[0]: # sources differ
+ if repo.ui.promptchoice(
+ _(' subrepository sources for %s differ\n'
+ 'use (l)ocal source (%s) or (r)emote source (%s)?')
+ % (s, l[0], r[0]),
+ (_('&Local'), _('&Remote')), 0):
+ wctx.sub(s).get(r)
+ sm[s] = r
+ elif l[1] == a[1]: # local side is unchanged
+ wctx.sub(s).get(r)
+ sm[s] = r
+ else:
+ wctx.sub(s).merge(r)
+ sm[s] = l
+ elif l == a: # remote removed, local unchanged
+ wctx.sub(s).remove()
+ else:
+ if repo.ui.promptchoice(
+ _(' local changed subrepository %s which remote removed\n'
+ 'use (c)hanged version or (d)elete?') % s,
+ (_('&Changed'), _('&Delete')), 0):
+ wctx.sub(s).remove()
+
+ for s, r in s2.items():
+ if s in s1:
+ continue
+ elif s not in sa:
+ wctx.sub(s).get(r)
+ sm[s] = r
+ elif r != sa[s]:
+ if repo.ui.promptchoice(
+ _(' remote changed subrepository %s which local removed\n'
+ 'use (c)hanged version or (d)elete?') % s,
+ (_('&Changed'), _('&Delete')), 0) == 0:
+ wctx.sub(s).get(r)
+ sm[s] = r
+
+ # record merged .hgsubstate
+ writestate(repo, sm)
+
+def _abssource(repo, push=False):
+ if hasattr(repo, '_subparent'):
+ source = repo._subsource
+ if source.startswith('/') or '://' in source:
+ return source
+ parent = _abssource(repo._subparent)
+ if '://' in parent:
+ if parent[-1] == '/':
+ parent = parent[:-1]
+ return parent + '/' + source
+ return os.path.join(parent, repo._subsource)
+ if push and repo.ui.config('paths', 'default-push'):
+ return repo.ui.config('paths', 'default-push', repo.root)
+ return repo.ui.config('paths', 'default', repo.root)
+
+def subrepo(ctx, path):
+ # subrepo inherently violates our import layering rules
+ # because it wants to make repo objects from deep inside the stack
+ # so we manually delay the circular imports to not break
+ # scripts that don't use our demand-loading
+ global hg
+ import hg as h
+ hg = h
+
+ util.path_auditor(ctx._repo.root)(path)
+ state = ctx.substate.get(path, nullstate)
+ if state[0].startswith('['): # future expansion
+ raise error.Abort('unknown subrepo source %s' % state[0])
+ return hgsubrepo(ctx, path, state)
+
+class hgsubrepo(object):
+ def __init__(self, ctx, path, state):
+ self._path = path
+ self._state = state
+ r = ctx._repo
+ root = r.wjoin(path)
+ if os.path.exists(os.path.join(root, '.hg')):
+ self._repo = hg.repository(r.ui, root)
+ else:
+ util.makedirs(root)
+ self._repo = hg.repository(r.ui, root, create=True)
+ self._repo._subparent = r
+ self._repo._subsource = state[0]
+
+ def dirty(self):
+ r = self._state[1]
+ if r == '':
+ return True
+ w = self._repo[None]
+ if w.p1() != self._repo[r]: # version checked out changed
+ return True
+ return w.dirty() # working directory changed
+
+ def commit(self, text, user, date):
+ n = self._repo.commit(text, user, date)
+ if not n:
+ return self._repo['.'].hex() # different version checked out
+ return node.hex(n)
+
+ def remove(self):
+ # we can't fully delete the repository as it may contain
+ # local-only history
+ self._repo.ui.note(_('removing subrepo %s\n') % self._path)
+ hg.clean(self._repo, node.nullid, False)
+
+ def get(self, state):
+ source, revision = state
+ try:
+ self._repo.lookup(revision)
+ except error.RepoError:
+ self._repo._subsource = source
+ self._repo.ui.status(_('pulling subrepo %s\n') % self._path)
+ srcurl = _abssource(self._repo)
+ other = hg.repository(self._repo.ui, srcurl)
+ self._repo.pull(other)
+
+ hg.clean(self._repo, revision, False)
+
+ def merge(self, state):
+ hg.merge(self._repo, state[1], remind=False)
+
+ def push(self, force):
+ # push subrepos depth-first for coherent ordering
+ c = self._repo['']
+ subs = c.substate # only repos that are committed
+ for s in sorted(subs):
+ c.sub(s).push(force)
+
+ self._repo.ui.status(_('pushing subrepo %s\n') % self._path)
+ dsturl = _abssource(self._repo, True)
+ other = hg.repository(self._repo.ui, dsturl)
+ self._repo.push(other, force)
+
diff --git a/sys/src/cmd/hg/mercurial/tags.py b/sys/src/cmd/hg/mercurial/tags.py
new file mode 100644
index 000000000..0d9a85dd9
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/tags.py
@@ -0,0 +1,338 @@
+# tags.py - read tag info from local repository
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com>
+# Copyright 2009 Greg Ward <greg@gerg.ca>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+# Currently this module only deals with reading and caching tags.
+# Eventually, it could take care of updating (adding/removing/moving)
+# tags too.
+
+import os
+from node import nullid, bin, hex, short
+from i18n import _
+import encoding
+import error
+
+def _debugalways(ui, *msg):
+ ui.write(*msg)
+
+def _debugconditional(ui, *msg):
+ ui.debug(*msg)
+
+def _debugnever(ui, *msg):
+ pass
+
+_debug = _debugalways
+_debug = _debugnever
+
+def findglobaltags1(ui, repo, alltags, tagtypes):
+ '''Find global tags in repo by reading .hgtags from every head that
+ has a distinct version of it. Updates the dicts alltags, tagtypes
+ in place: alltags maps tag name to (node, hist) pair (see _readtags()
+ below), and tagtypes maps tag name to tag type ('global' in this
+ case).'''
+
+ seen = set()
+ fctx = None
+ ctxs = [] # list of filectx
+ for node in repo.heads():
+ try:
+ fnode = repo[node].filenode('.hgtags')
+ except error.LookupError:
+ continue
+ if fnode not in seen:
+ seen.add(fnode)
+ if not fctx:
+ fctx = repo.filectx('.hgtags', fileid=fnode)
+ else:
+ fctx = fctx.filectx(fnode)
+ ctxs.append(fctx)
+
+ # read the tags file from each head, ending with the tip
+ for fctx in reversed(ctxs):
+ filetags = _readtags(
+ ui, repo, fctx.data().splitlines(), fctx)
+ _updatetags(filetags, "global", alltags, tagtypes)
+
+def findglobaltags2(ui, repo, alltags, tagtypes):
+ '''Same as findglobaltags1(), but with caching.'''
+ # This is so we can be lazy and assume alltags contains only global
+ # tags when we pass it to _writetagcache().
+ assert len(alltags) == len(tagtypes) == 0, \
+ "findglobaltags() should be called first"
+
+ (heads, tagfnode, cachetags, shouldwrite) = _readtagcache(ui, repo)
+ if cachetags is not None:
+ assert not shouldwrite
+ # XXX is this really 100% correct? are there oddball special
+ # cases where a global tag should outrank a local tag but won't,
+ # because cachetags does not contain rank info?
+ _updatetags(cachetags, 'global', alltags, tagtypes)
+ return
+
+ _debug(ui, "reading tags from %d head(s): %s\n"
+ % (len(heads), map(short, reversed(heads))))
+ seen = set() # set of fnode
+ fctx = None
+ for head in reversed(heads): # oldest to newest
+ assert head in repo.changelog.nodemap, \
+ "tag cache returned bogus head %s" % short(head)
+
+ fnode = tagfnode.get(head)
+ if fnode and fnode not in seen:
+ seen.add(fnode)
+ if not fctx:
+ fctx = repo.filectx('.hgtags', fileid=fnode)
+ else:
+ fctx = fctx.filectx(fnode)
+
+ filetags = _readtags(ui, repo, fctx.data().splitlines(), fctx)
+ _updatetags(filetags, 'global', alltags, tagtypes)
+
+ # and update the cache (if necessary)
+ if shouldwrite:
+ _writetagcache(ui, repo, heads, tagfnode, alltags)
+
+# Set this to findglobaltags1 to disable tag caching.
+findglobaltags = findglobaltags2
+
+def readlocaltags(ui, repo, alltags, tagtypes):
+ '''Read local tags in repo. Update alltags and tagtypes.'''
+ try:
+ # localtags is in the local encoding; re-encode to UTF-8 on
+ # input for consistency with the rest of this module.
+ data = repo.opener("localtags").read()
+ filetags = _readtags(
+ ui, repo, data.splitlines(), "localtags",
+ recode=encoding.fromlocal)
+ _updatetags(filetags, "local", alltags, tagtypes)
+ except IOError:
+ pass
+
+def _readtags(ui, repo, lines, fn, recode=None):
+ '''Read tag definitions from a file (or any source of lines).
+ Return a mapping from tag name to (node, hist): node is the node id
+ from the last line read for that name, and hist is the list of node
+ ids previously associated with it (in file order). All node ids are
+ binary, not hex.'''
+
+ filetags = {} # map tag name to (node, hist)
+ count = 0
+
+ def warn(msg):
+ ui.warn(_("%s, line %s: %s\n") % (fn, count, msg))
+
+ for line in lines:
+ count += 1
+ if not line:
+ continue
+ try:
+ (nodehex, name) = line.split(" ", 1)
+ except ValueError:
+ warn(_("cannot parse entry"))
+ continue
+ name = name.strip()
+ if recode:
+ name = recode(name)
+ try:
+ nodebin = bin(nodehex)
+ except TypeError:
+ warn(_("node '%s' is not well formed") % nodehex)
+ continue
+ if nodebin not in repo.changelog.nodemap:
+ # silently ignore as pull -r might cause this
+ continue
+
+ # update filetags
+ hist = []
+ if name in filetags:
+ n, hist = filetags[name]
+ hist.append(n)
+ filetags[name] = (nodebin, hist)
+ return filetags
+
+def _updatetags(filetags, tagtype, alltags, tagtypes):
+ '''Incorporate the tag info read from one file into the two
+ dictionaries, alltags and tagtypes, that contain all tag
+ info (global across all heads plus local).'''
+
+ for name, nodehist in filetags.iteritems():
+ if name not in alltags:
+ alltags[name] = nodehist
+ tagtypes[name] = tagtype
+ continue
+
+ # we prefer alltags[name] if:
+ # it supercedes us OR
+ # mutual supercedes and it has a higher rank
+ # otherwise we win because we're tip-most
+ anode, ahist = nodehist
+ bnode, bhist = alltags[name]
+ if (bnode != anode and anode in bhist and
+ (bnode not in ahist or len(bhist) > len(ahist))):
+ anode = bnode
+ ahist.extend([n for n in bhist if n not in ahist])
+ alltags[name] = anode, ahist
+ tagtypes[name] = tagtype
+
+
+# The tag cache only stores info about heads, not the tag contents
+# from each head. I.e. it doesn't try to squeeze out the maximum
+# performance, but is simpler has a better chance of actually
+# working correctly. And this gives the biggest performance win: it
+# avoids looking up .hgtags in the manifest for every head, and it
+# can avoid calling heads() at all if there have been no changes to
+# the repo.
+
+def _readtagcache(ui, repo):
+ '''Read the tag cache and return a tuple (heads, fnodes, cachetags,
+ shouldwrite). If the cache is completely up-to-date, cachetags is a
+ dict of the form returned by _readtags(); otherwise, it is None and
+ heads and fnodes are set. In that case, heads is the list of all
+ heads currently in the repository (ordered from tip to oldest) and
+ fnodes is a mapping from head to .hgtags filenode. If those two are
+ set, caller is responsible for reading tag info from each head.'''
+
+ try:
+ cachefile = repo.opener('tags.cache', 'r')
+ _debug(ui, 'reading tag cache from %s\n' % cachefile.name)
+ except IOError:
+ cachefile = None
+
+ # The cache file consists of lines like
+ # <headrev> <headnode> [<tagnode>]
+ # where <headrev> and <headnode> redundantly identify a repository
+ # head from the time the cache was written, and <tagnode> is the
+ # filenode of .hgtags on that head. Heads with no .hgtags file will
+ # have no <tagnode>. The cache is ordered from tip to oldest (which
+ # is part of why <headrev> is there: a quick visual check is all
+ # that's required to ensure correct order).
+ #
+ # This information is enough to let us avoid the most expensive part
+ # of finding global tags, which is looking up <tagnode> in the
+ # manifest for each head.
+ cacherevs = [] # list of headrev
+ cacheheads = [] # list of headnode
+ cachefnode = {} # map headnode to filenode
+ if cachefile:
+ for line in cachefile:
+ if line == "\n":
+ break
+ line = line.rstrip().split()
+ cacherevs.append(int(line[0]))
+ headnode = bin(line[1])
+ cacheheads.append(headnode)
+ if len(line) == 3:
+ fnode = bin(line[2])
+ cachefnode[headnode] = fnode
+
+ tipnode = repo.changelog.tip()
+ tiprev = len(repo.changelog) - 1
+
+ # Case 1 (common): tip is the same, so nothing has changed.
+ # (Unchanged tip trivially means no changesets have been added.
+ # But, thanks to localrepository.destroyed(), it also means none
+ # have been destroyed by strip or rollback.)
+ if cacheheads and cacheheads[0] == tipnode and cacherevs[0] == tiprev:
+ _debug(ui, "tag cache: tip unchanged\n")
+ tags = _readtags(ui, repo, cachefile, cachefile.name)
+ cachefile.close()
+ return (None, None, tags, False)
+ if cachefile:
+ cachefile.close() # ignore rest of file
+
+ repoheads = repo.heads()
+ # Case 2 (uncommon): empty repo; get out quickly and don't bother
+ # writing an empty cache.
+ if repoheads == [nullid]:
+ return ([], {}, {}, False)
+
+ # Case 3 (uncommon): cache file missing or empty.
+ if not cacheheads:
+ _debug(ui, 'tag cache: cache file missing or empty\n')
+
+ # Case 4 (uncommon): tip rev decreased. This should only happen
+ # when we're called from localrepository.destroyed(). Refresh the
+ # cache so future invocations will not see disappeared heads in the
+ # cache.
+ elif cacheheads and tiprev < cacherevs[0]:
+ _debug(ui,
+ 'tag cache: tip rev decremented (from %d to %d), '
+ 'so we must be destroying nodes\n'
+ % (cacherevs[0], tiprev))
+
+ # Case 5 (common): tip has changed, so we've added/replaced heads.
+ else:
+ _debug(ui,
+ 'tag cache: tip has changed (%d:%s); must find new heads\n'
+ % (tiprev, short(tipnode)))
+
+ # Luckily, the code to handle cases 3, 4, 5 is the same. So the
+ # above if/elif/else can disappear once we're confident this thing
+ # actually works and we don't need the debug output.
+
+ # N.B. in case 4 (nodes destroyed), "new head" really means "newly
+ # exposed".
+ newheads = [head
+ for head in repoheads
+ if head not in set(cacheheads)]
+ _debug(ui, 'tag cache: found %d head(s) not in cache: %s\n'
+ % (len(newheads), map(short, newheads)))
+
+ # Now we have to lookup the .hgtags filenode for every new head.
+ # This is the most expensive part of finding tags, so performance
+ # depends primarily on the size of newheads. Worst case: no cache
+ # file, so newheads == repoheads.
+ for head in newheads:
+ cctx = repo[head]
+ try:
+ fnode = cctx.filenode('.hgtags')
+ cachefnode[head] = fnode
+ except error.LookupError:
+ # no .hgtags file on this head
+ pass
+
+ # Caller has to iterate over all heads, but can use the filenodes in
+ # cachefnode to get to each .hgtags revision quickly.
+ return (repoheads, cachefnode, None, True)
+
+def _writetagcache(ui, repo, heads, tagfnode, cachetags):
+
+ cachefile = repo.opener('tags.cache', 'w', atomictemp=True)
+ _debug(ui, 'writing cache file %s\n' % cachefile.name)
+
+ realheads = repo.heads() # for sanity checks below
+ for head in heads:
+ # temporary sanity checks; these can probably be removed
+ # once this code has been in crew for a few weeks
+ assert head in repo.changelog.nodemap, \
+ 'trying to write non-existent node %s to tag cache' % short(head)
+ assert head in realheads, \
+ 'trying to write non-head %s to tag cache' % short(head)
+ assert head != nullid, \
+ 'trying to write nullid to tag cache'
+
+ # This can't fail because of the first assert above. When/if we
+ # remove that assert, we might want to catch LookupError here
+ # and downgrade it to a warning.
+ rev = repo.changelog.rev(head)
+
+ fnode = tagfnode.get(head)
+ if fnode:
+ cachefile.write('%d %s %s\n' % (rev, hex(head), hex(fnode)))
+ else:
+ cachefile.write('%d %s\n' % (rev, hex(head)))
+
+ # Tag names in the cache are in UTF-8 -- which is the whole reason
+ # we keep them in UTF-8 throughout this module. If we converted
+ # them local encoding on input, we would lose info writing them to
+ # the cache.
+ cachefile.write('\n')
+ for (name, (node, hist)) in cachetags.iteritems():
+ cachefile.write("%s %s\n" % (hex(node), name))
+
+ cachefile.rename()
+ cachefile.close()
diff --git a/sys/src/cmd/hg/mercurial/templatefilters.py b/sys/src/cmd/hg/mercurial/templatefilters.py
new file mode 100644
index 000000000..34358d26b
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/templatefilters.py
@@ -0,0 +1,211 @@
+# template-filters.py - common template expansion filters
+#
+# Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import cgi, re, os, time, urllib, textwrap
+import util, encoding
+
+def stringify(thing):
+ '''turn nested template iterator into string.'''
+ if hasattr(thing, '__iter__') and not isinstance(thing, str):
+ return "".join([stringify(t) for t in thing if t is not None])
+ return str(thing)
+
+agescales = [("second", 1),
+ ("minute", 60),
+ ("hour", 3600),
+ ("day", 3600 * 24),
+ ("week", 3600 * 24 * 7),
+ ("month", 3600 * 24 * 30),
+ ("year", 3600 * 24 * 365)]
+
+agescales.reverse()
+
+def age(date):
+ '''turn a (timestamp, tzoff) tuple into an age string.'''
+
+ def plural(t, c):
+ if c == 1:
+ return t
+ return t + "s"
+ def fmt(t, c):
+ return "%d %s" % (c, plural(t, c))
+
+ now = time.time()
+ then = date[0]
+ if then > now:
+ return 'in the future'
+
+ delta = max(1, int(now - then))
+ for t, s in agescales:
+ n = delta // s
+ if n >= 2 or s == 1:
+ return fmt(t, n)
+
+para_re = None
+space_re = None
+
+def fill(text, width):
+ '''fill many paragraphs.'''
+ global para_re, space_re
+ if para_re is None:
+ para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M)
+ space_re = re.compile(r' +')
+
+ def findparas():
+ start = 0
+ while True:
+ m = para_re.search(text, start)
+ if not m:
+ w = len(text)
+ while w > start and text[w-1].isspace(): w -= 1
+ yield text[start:w], text[w:]
+ break
+ yield text[start:m.start(0)], m.group(1)
+ start = m.end(1)
+
+ return "".join([space_re.sub(' ', textwrap.fill(para, width)) + rest
+ for para, rest in findparas()])
+
+def firstline(text):
+ '''return the first line of text'''
+ try:
+ return text.splitlines(True)[0].rstrip('\r\n')
+ except IndexError:
+ return ''
+
+def nl2br(text):
+ '''replace raw newlines with xhtml line breaks.'''
+ return text.replace('\n', '<br/>\n')
+
+def obfuscate(text):
+ text = unicode(text, encoding.encoding, 'replace')
+ return ''.join(['&#%d;' % ord(c) for c in text])
+
+def domain(author):
+ '''get domain of author, or empty string if none.'''
+ f = author.find('@')
+ if f == -1: return ''
+ author = author[f+1:]
+ f = author.find('>')
+ if f >= 0: author = author[:f]
+ return author
+
+def person(author):
+ '''get name of author, or else username.'''
+ if not '@' in author: return author
+ f = author.find('<')
+ if f == -1: return util.shortuser(author)
+ return author[:f].rstrip()
+
+def indent(text, prefix):
+ '''indent each non-empty line of text after first with prefix.'''
+ lines = text.splitlines()
+ num_lines = len(lines)
+ def indenter():
+ for i in xrange(num_lines):
+ l = lines[i]
+ if i and l.strip():
+ yield prefix
+ yield l
+ if i < num_lines - 1 or text.endswith('\n'):
+ yield '\n'
+ return "".join(indenter())
+
+def permissions(flags):
+ if "l" in flags:
+ return "lrwxrwxrwx"
+ if "x" in flags:
+ return "-rwxr-xr-x"
+ return "-rw-r--r--"
+
+def xmlescape(text):
+ text = (text
+ .replace('&', '&amp;')
+ .replace('<', '&lt;')
+ .replace('>', '&gt;')
+ .replace('"', '&quot;')
+ .replace("'", '&#39;')) # &apos; invalid in HTML
+ return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
+
+_escapes = [
+ ('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'),
+ ('\r', '\\r'), ('\f', '\\f'), ('\b', '\\b'),
+]
+
+def jsonescape(s):
+ for k, v in _escapes:
+ s = s.replace(k, v)
+ return s
+
+def json(obj):
+ if obj is None or obj is False or obj is True:
+ return {None: 'null', False: 'false', True: 'true'}[obj]
+ elif isinstance(obj, int) or isinstance(obj, float):
+ return str(obj)
+ elif isinstance(obj, str):
+ return '"%s"' % jsonescape(obj)
+ elif isinstance(obj, unicode):
+ return json(obj.encode('utf-8'))
+ elif hasattr(obj, 'keys'):
+ out = []
+ for k, v in obj.iteritems():
+ s = '%s: %s' % (json(k), json(v))
+ out.append(s)
+ return '{' + ', '.join(out) + '}'
+ elif hasattr(obj, '__iter__'):
+ out = []
+ for i in obj:
+ out.append(json(i))
+ return '[' + ', '.join(out) + ']'
+ else:
+ raise TypeError('cannot encode type %s' % obj.__class__.__name__)
+
+def stripdir(text):
+ '''Treat the text as path and strip a directory level, if possible.'''
+ dir = os.path.dirname(text)
+ if dir == "":
+ return os.path.basename(text)
+ else:
+ return dir
+
+def nonempty(str):
+ return str or "(none)"
+
+filters = {
+ "addbreaks": nl2br,
+ "basename": os.path.basename,
+ "stripdir": stripdir,
+ "age": age,
+ "date": lambda x: util.datestr(x),
+ "domain": domain,
+ "email": util.email,
+ "escape": lambda x: cgi.escape(x, True),
+ "fill68": lambda x: fill(x, width=68),
+ "fill76": lambda x: fill(x, width=76),
+ "firstline": firstline,
+ "tabindent": lambda x: indent(x, '\t'),
+ "hgdate": lambda x: "%d %d" % x,
+ "isodate": lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2'),
+ "isodatesec": lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2'),
+ "json": json,
+ "jsonescape": jsonescape,
+ "localdate": lambda x: (x[0], util.makedate()[1]),
+ "nonempty": nonempty,
+ "obfuscate": obfuscate,
+ "permissions": permissions,
+ "person": person,
+ "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2"),
+ "rfc3339date": lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2"),
+ "short": lambda x: x[:12],
+ "shortdate": util.shortdate,
+ "stringify": stringify,
+ "strip": lambda x: x.strip(),
+ "urlescape": lambda x: urllib.quote(x),
+ "user": lambda x: util.shortuser(x),
+ "stringescape": lambda x: x.encode('string_escape'),
+ "xmlescape": xmlescape,
+}
diff --git a/sys/src/cmd/hg/mercurial/templater.py b/sys/src/cmd/hg/mercurial/templater.py
new file mode 100644
index 000000000..86a674fbb
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/templater.py
@@ -0,0 +1,245 @@
+# templater.py - template expansion for output
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import re, sys, os
+import util, config, templatefilters
+
+path = ['templates', '../templates']
+stringify = templatefilters.stringify
+
+def parsestring(s, quoted=True):
+ '''parse a string using simple c-like syntax.
+ string must be in quotes if quoted is True.'''
+ if quoted:
+ if len(s) < 2 or s[0] != s[-1]:
+ raise SyntaxError(_('unmatched quotes'))
+ return s[1:-1].decode('string_escape')
+
+ return s.decode('string_escape')
+
+class engine(object):
+ '''template expansion engine.
+
+ template expansion works like this. a map file contains key=value
+ pairs. if value is quoted, it is treated as string. otherwise, it
+ is treated as name of template file.
+
+ templater is asked to expand a key in map. it looks up key, and
+ looks for strings like this: {foo}. it expands {foo} by looking up
+ foo in map, and substituting it. expansion is recursive: it stops
+ when there is no more {foo} to replace.
+
+ expansion also allows formatting and filtering.
+
+ format uses key to expand each item in list. syntax is
+ {key%format}.
+
+ filter uses function to transform value. syntax is
+ {key|filter1|filter2|...}.'''
+
+ template_re = re.compile(r'{([\w\|%]+)}|#([\w\|%]+)#')
+
+ def __init__(self, loader, filters={}, defaults={}):
+ self.loader = loader
+ self.filters = filters
+ self.defaults = defaults
+ self.cache = {}
+
+ def process(self, t, map):
+ '''Perform expansion. t is name of map element to expand. map contains
+ added elements for use during expansion. Is a generator.'''
+ tmpl = self.loader(t)
+ iters = [self._process(tmpl, map)]
+ while iters:
+ try:
+ item = iters[0].next()
+ except StopIteration:
+ iters.pop(0)
+ continue
+ if isinstance(item, str):
+ yield item
+ elif item is None:
+ yield ''
+ elif hasattr(item, '__iter__'):
+ iters.insert(0, iter(item))
+ else:
+ yield str(item)
+
+ def _format(self, expr, get, map):
+ key, format = expr.split('%')
+ v = get(key)
+ if not hasattr(v, '__iter__'):
+ raise SyntaxError(_("error expanding '%s%%%s'") % (key, format))
+ lm = map.copy()
+ for i in v:
+ lm.update(i)
+ yield self.process(format, lm)
+
+ def _filter(self, expr, get, map):
+ if expr not in self.cache:
+ parts = expr.split('|')
+ val = parts[0]
+ try:
+ filters = [self.filters[f] for f in parts[1:]]
+ except KeyError, i:
+ raise SyntaxError(_("unknown filter '%s'") % i[0])
+ def apply(get):
+ x = get(val)
+ for f in filters:
+ x = f(x)
+ return x
+ self.cache[expr] = apply
+ return self.cache[expr](get)
+
+ def _process(self, tmpl, map):
+ '''Render a template. Returns a generator.'''
+
+ def get(key):
+ v = map.get(key)
+ if v is None:
+ v = self.defaults.get(key, '')
+ if hasattr(v, '__call__'):
+ v = v(**map)
+ return v
+
+ while tmpl:
+ m = self.template_re.search(tmpl)
+ if not m:
+ yield tmpl
+ break
+
+ start, end = m.span(0)
+ variants = m.groups()
+ expr = variants[0] or variants[1]
+
+ if start:
+ yield tmpl[:start]
+ tmpl = tmpl[end:]
+
+ if '%' in expr:
+ yield self._format(expr, get, map)
+ elif '|' in expr:
+ yield self._filter(expr, get, map)
+ else:
+ yield get(expr)
+
+engines = {'default': engine}
+
+class templater(object):
+
+ def __init__(self, mapfile, filters={}, defaults={}, cache={},
+ minchunk=1024, maxchunk=65536):
+ '''set up template engine.
+ mapfile is name of file to read map definitions from.
+ filters is dict of functions. each transforms a value into another.
+ defaults is dict of default map definitions.'''
+ self.mapfile = mapfile or 'template'
+ self.cache = cache.copy()
+ self.map = {}
+ self.base = (mapfile and os.path.dirname(mapfile)) or ''
+ self.filters = templatefilters.filters.copy()
+ self.filters.update(filters)
+ self.defaults = defaults
+ self.minchunk, self.maxchunk = minchunk, maxchunk
+ self.engines = {}
+
+ if not mapfile:
+ return
+ if not os.path.exists(mapfile):
+ raise util.Abort(_('style not found: %s') % mapfile)
+
+ conf = config.config()
+ conf.read(mapfile)
+
+ for key, val in conf[''].items():
+ if val[0] in "'\"":
+ try:
+ self.cache[key] = parsestring(val)
+ except SyntaxError, inst:
+ raise SyntaxError('%s: %s' %
+ (conf.source('', key), inst.args[0]))
+ else:
+ val = 'default', val
+ if ':' in val[1]:
+ val = val[1].split(':', 1)
+ self.map[key] = val[0], os.path.join(self.base, val[1])
+
+ def __contains__(self, key):
+ return key in self.cache or key in self.map
+
+ def load(self, t):
+ '''Get the template for the given template name. Use a local cache.'''
+ if not t in self.cache:
+ try:
+ self.cache[t] = open(self.map[t][1]).read()
+ except IOError, inst:
+ raise IOError(inst.args[0], _('template file %s: %s') %
+ (self.map[t][1], inst.args[1]))
+ return self.cache[t]
+
+ def __call__(self, t, **map):
+ ttype = t in self.map and self.map[t][0] or 'default'
+ proc = self.engines.get(ttype)
+ if proc is None:
+ proc = engines[ttype](self.load, self.filters, self.defaults)
+ self.engines[ttype] = proc
+
+ stream = proc.process(t, map)
+ if self.minchunk:
+ stream = util.increasingchunks(stream, min=self.minchunk,
+ max=self.maxchunk)
+ return stream
+
+def templatepath(name=None):
+ '''return location of template file or directory (if no name).
+ returns None if not found.'''
+ normpaths = []
+
+ # executable version (py2exe) doesn't support __file__
+ if hasattr(sys, 'frozen'):
+ module = sys.executable
+ else:
+ module = __file__
+ for f in path:
+ if f.startswith('/'):
+ p = f
+ else:
+ fl = f.split('/')
+ p = os.path.join(os.path.dirname(module), *fl)
+ if name:
+ p = os.path.join(p, name)
+ if name and os.path.exists(p):
+ return os.path.normpath(p)
+ elif os.path.isdir(p):
+ normpaths.append(os.path.normpath(p))
+
+ return normpaths
+
+def stylemap(style, paths=None):
+ """Return path to mapfile for a given style.
+
+ Searches mapfile in the following locations:
+ 1. templatepath/style/map
+ 2. templatepath/map-style
+ 3. templatepath/map
+ """
+
+ if paths is None:
+ paths = templatepath()
+ elif isinstance(paths, str):
+ paths = [paths]
+
+ locations = style and [os.path.join(style, "map"), "map-" + style] or []
+ locations.append("map")
+ for path in paths:
+ for location in locations:
+ mapfile = os.path.join(path, location)
+ if os.path.isfile(mapfile):
+ return mapfile
+
+ raise RuntimeError("No hgweb templates found in %r" % paths)
diff --git a/sys/src/cmd/hg/mercurial/transaction.py b/sys/src/cmd/hg/mercurial/transaction.py
new file mode 100644
index 000000000..8eabacc54
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/transaction.py
@@ -0,0 +1,165 @@
+# transaction.py - simple journalling scheme for mercurial
+#
+# This transaction scheme is intended to gracefully handle program
+# errors and interruptions. More serious failures like system crashes
+# can be recovered with an fsck-like tool. As the whole repository is
+# effectively log-structured, this should amount to simply truncating
+# anything that isn't referenced in the changelog.
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import os, errno
+import error
+
+def active(func):
+ def _active(self, *args, **kwds):
+ if self.count == 0:
+ raise error.Abort(_(
+ 'cannot use transaction when it is already committed/aborted'))
+ return func(self, *args, **kwds)
+ return _active
+
+def _playback(journal, report, opener, entries, unlink=True):
+ for f, o, ignore in entries:
+ if o or not unlink:
+ try:
+ opener(f, 'a').truncate(o)
+ except:
+ report(_("failed to truncate %s\n") % f)
+ raise
+ else:
+ try:
+ fn = opener(f).name
+ os.unlink(fn)
+ except IOError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+ os.unlink(journal)
+
+class transaction(object):
+ def __init__(self, report, opener, journal, after=None, createmode=None):
+ self.journal = None
+
+ self.count = 1
+ self.report = report
+ self.opener = opener
+ self.after = after
+ self.entries = []
+ self.map = {}
+ self.journal = journal
+ self._queue = []
+
+ self.file = open(self.journal, "w")
+ if createmode is not None:
+ os.chmod(self.journal, createmode & 0666)
+
+ def __del__(self):
+ if self.journal:
+ if self.entries: self._abort()
+ self.file.close()
+
+ @active
+ def startgroup(self):
+ self._queue.append([])
+
+ @active
+ def endgroup(self):
+ q = self._queue.pop()
+ d = ''.join(['%s\0%d\n' % (x[0], x[1]) for x in q])
+ self.entries.extend(q)
+ self.file.write(d)
+ self.file.flush()
+
+ @active
+ def add(self, file, offset, data=None):
+ if file in self.map: return
+
+ if self._queue:
+ self._queue[-1].append((file, offset, data))
+ return
+
+ self.entries.append((file, offset, data))
+ self.map[file] = len(self.entries) - 1
+ # add enough data to the journal to do the truncate
+ self.file.write("%s\0%d\n" % (file, offset))
+ self.file.flush()
+
+ @active
+ def find(self, file):
+ if file in self.map:
+ return self.entries[self.map[file]]
+ return None
+
+ @active
+ def replace(self, file, offset, data=None):
+ '''
+ replace can only replace already committed entries
+ that are not pending in the queue
+ '''
+
+ if file not in self.map:
+ raise KeyError(file)
+ index = self.map[file]
+ self.entries[index] = (file, offset, data)
+ self.file.write("%s\0%d\n" % (file, offset))
+ self.file.flush()
+
+ @active
+ def nest(self):
+ self.count += 1
+ return self
+
+ def running(self):
+ return self.count > 0
+
+ @active
+ def close(self):
+ '''commit the transaction'''
+ self.count -= 1
+ if self.count != 0:
+ return
+ self.file.close()
+ self.entries = []
+ if self.after:
+ self.after()
+ else:
+ os.unlink(self.journal)
+ self.journal = None
+
+ @active
+ def abort(self):
+ '''abort the transaction (generally called on error, or when the
+ transaction is not explicitly committed before going out of
+ scope)'''
+ self._abort()
+
+ def _abort(self):
+ self.count = 0
+ self.file.close()
+
+ if not self.entries: return
+
+ self.report(_("transaction abort!\n"))
+
+ try:
+ try:
+ _playback(self.journal, self.report, self.opener, self.entries, False)
+ self.report(_("rollback completed\n"))
+ except:
+ self.report(_("rollback failed - please run hg recover\n"))
+ finally:
+ self.journal = None
+
+
+def rollback(opener, file, report):
+ entries = []
+
+ for l in open(file).readlines():
+ f, o = l.split('\0')
+ entries.append((f, int(o), None))
+
+ _playback(file, report, opener, entries)
diff --git a/sys/src/cmd/hg/mercurial/ui.py b/sys/src/cmd/hg/mercurial/ui.py
new file mode 100644
index 000000000..bd122f74a
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/ui.py
@@ -0,0 +1,381 @@
+# ui.py - user interface bits for mercurial
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import errno, getpass, os, socket, sys, tempfile, traceback
+import config, util, error
+
+_booleans = {'1': True, 'yes': True, 'true': True, 'on': True,
+ '0': False, 'no': False, 'false': False, 'off': False}
+
+class ui(object):
+ def __init__(self, src=None):
+ self._buffers = []
+ self.quiet = self.verbose = self.debugflag = self._traceback = False
+ self._reportuntrusted = True
+ self._ocfg = config.config() # overlay
+ self._tcfg = config.config() # trusted
+ self._ucfg = config.config() # untrusted
+ self._trustusers = set()
+ self._trustgroups = set()
+
+ if src:
+ self._tcfg = src._tcfg.copy()
+ self._ucfg = src._ucfg.copy()
+ self._ocfg = src._ocfg.copy()
+ self._trustusers = src._trustusers.copy()
+ self._trustgroups = src._trustgroups.copy()
+ self.fixconfig()
+ else:
+ # we always trust global config files
+ for f in util.rcpath():
+ self.readconfig(f, trust=True)
+
+ def copy(self):
+ return self.__class__(self)
+
+ def _is_trusted(self, fp, f):
+ st = util.fstat(fp)
+ if util.isowner(st):
+ return True
+
+ tusers, tgroups = self._trustusers, self._trustgroups
+ if '*' in tusers or '*' in tgroups:
+ return True
+
+ user = util.username(st.st_uid)
+ group = util.groupname(st.st_gid)
+ if user in tusers or group in tgroups or user == util.username():
+ return True
+
+ if self._reportuntrusted:
+ self.warn(_('Not trusting file %s from untrusted '
+ 'user %s, group %s\n') % (f, user, group))
+ return False
+
+ def readconfig(self, filename, root=None, trust=False,
+ sections=None, remap=None):
+ try:
+ fp = open(filename)
+ except IOError:
+ if not sections: # ignore unless we were looking for something
+ return
+ raise
+
+ cfg = config.config()
+ trusted = sections or trust or self._is_trusted(fp, filename)
+
+ try:
+ cfg.read(filename, fp, sections=sections, remap=remap)
+ except error.ConfigError, inst:
+ if trusted:
+ raise
+ self.warn(_("Ignored: %s\n") % str(inst))
+
+ if trusted:
+ self._tcfg.update(cfg)
+ self._tcfg.update(self._ocfg)
+ self._ucfg.update(cfg)
+ self._ucfg.update(self._ocfg)
+
+ if root is None:
+ root = os.path.expanduser('~')
+ self.fixconfig(root=root)
+
+ def fixconfig(self, root=None):
+ # translate paths relative to root (or home) into absolute paths
+ root = root or os.getcwd()
+ for c in self._tcfg, self._ucfg, self._ocfg:
+ for n, p in c.items('paths'):
+ if p and "://" not in p and not os.path.isabs(p):
+ c.set("paths", n, os.path.normpath(os.path.join(root, p)))
+
+ # update ui options
+ self.debugflag = self.configbool('ui', 'debug')
+ self.verbose = self.debugflag or self.configbool('ui', 'verbose')
+ self.quiet = not self.debugflag and self.configbool('ui', 'quiet')
+ if self.verbose and self.quiet:
+ self.quiet = self.verbose = False
+ self._reportuntrusted = self.configbool("ui", "report_untrusted", True)
+ self._traceback = self.configbool('ui', 'traceback', False)
+
+ # update trust information
+ self._trustusers.update(self.configlist('trusted', 'users'))
+ self._trustgroups.update(self.configlist('trusted', 'groups'))
+
+ def setconfig(self, section, name, value):
+ for cfg in (self._ocfg, self._tcfg, self._ucfg):
+ cfg.set(section, name, value)
+ self.fixconfig()
+
+ def _data(self, untrusted):
+ return untrusted and self._ucfg or self._tcfg
+
+ def configsource(self, section, name, untrusted=False):
+ return self._data(untrusted).source(section, name) or 'none'
+
+ def config(self, section, name, default=None, untrusted=False):
+ value = self._data(untrusted).get(section, name, default)
+ if self.debugflag and not untrusted and self._reportuntrusted:
+ uvalue = self._ucfg.get(section, name)
+ if uvalue is not None and uvalue != value:
+ self.debug(_("ignoring untrusted configuration option "
+ "%s.%s = %s\n") % (section, name, uvalue))
+ return value
+
+ def configbool(self, section, name, default=False, untrusted=False):
+ v = self.config(section, name, None, untrusted)
+ if v is None:
+ return default
+ if v.lower() not in _booleans:
+ raise error.ConfigError(_("%s.%s not a boolean ('%s')")
+ % (section, name, v))
+ return _booleans[v.lower()]
+
+ def configlist(self, section, name, default=None, untrusted=False):
+ """Return a list of comma/space separated strings"""
+ result = self.config(section, name, untrusted=untrusted)
+ if result is None:
+ result = default or []
+ if isinstance(result, basestring):
+ result = result.replace(",", " ").split()
+ return result
+
+ def has_section(self, section, untrusted=False):
+ '''tell whether section exists in config.'''
+ return section in self._data(untrusted)
+
+ def configitems(self, section, untrusted=False):
+ items = self._data(untrusted).items(section)
+ if self.debugflag and not untrusted and self._reportuntrusted:
+ for k, v in self._ucfg.items(section):
+ if self._tcfg.get(section, k) != v:
+ self.debug(_("ignoring untrusted configuration option "
+ "%s.%s = %s\n") % (section, k, v))
+ return items
+
+ def walkconfig(self, untrusted=False):
+ cfg = self._data(untrusted)
+ for section in cfg.sections():
+ for name, value in self.configitems(section, untrusted):
+ yield section, name, str(value).replace('\n', '\\n')
+
+ def username(self):
+ """Return default username to be used in commits.
+
+ Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
+ and stop searching if one of these is set.
+ If not found and ui.askusername is True, ask the user, else use
+ ($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
+ """
+ user = os.environ.get("HGUSER")
+ if user is None:
+ user = self.config("ui", "username")
+ if user is None:
+ user = os.environ.get("EMAIL")
+ if user is None and self.configbool("ui", "askusername"):
+ user = self.prompt(_("enter a commit username:"), default=None)
+ if user is None:
+ try:
+ user = '%s@%s' % (util.getuser(), socket.getfqdn())
+ self.warn(_("No username found, using '%s' instead\n") % user)
+ except KeyError:
+ pass
+ if not user:
+ raise util.Abort(_("Please specify a username."))
+ if "\n" in user:
+ raise util.Abort(_("username %s contains a newline\n") % repr(user))
+ return user
+
+ def shortuser(self, user):
+ """Return a short representation of a user name or email address."""
+ if not self.verbose: user = util.shortuser(user)
+ return user
+
+ def _path(self, loc):
+ p = self.config('paths', loc)
+ if p and '%%' in p:
+ self.warn('(deprecated \'%%\' in path %s=%s from %s)\n' %
+ (loc, p, self.configsource('paths', loc)))
+ p = p.replace('%%', '%')
+ return p
+
+ def expandpath(self, loc, default=None):
+ """Return repository location relative to cwd or from [paths]"""
+ if "://" in loc or os.path.isdir(os.path.join(loc, '.hg')):
+ return loc
+
+ path = self._path(loc)
+ if not path and default is not None:
+ path = self._path(default)
+ return path or loc
+
+ def pushbuffer(self):
+ self._buffers.append([])
+
+ def popbuffer(self):
+ return "".join(self._buffers.pop())
+
+ def write(self, *args):
+ if self._buffers:
+ self._buffers[-1].extend([str(a) for a in args])
+ else:
+ for a in args:
+ sys.stdout.write(str(a))
+
+ def write_err(self, *args):
+ try:
+ if not sys.stdout.closed: sys.stdout.flush()
+ for a in args:
+ sys.stderr.write(str(a))
+ # stderr may be buffered under win32 when redirected to files,
+ # including stdout.
+ if not sys.stderr.closed: sys.stderr.flush()
+ except IOError, inst:
+ if inst.errno != errno.EPIPE:
+ raise
+
+ def flush(self):
+ try: sys.stdout.flush()
+ except: pass
+ try: sys.stderr.flush()
+ except: pass
+
+ def interactive(self):
+ i = self.configbool("ui", "interactive", None)
+ if i is None:
+ return sys.stdin.isatty()
+ return i
+
+ def _readline(self, prompt=''):
+ if sys.stdin.isatty():
+ try:
+ # magically add command line editing support, where
+ # available
+ import readline
+ # force demandimport to really load the module
+ readline.read_history_file
+ # windows sometimes raises something other than ImportError
+ except Exception:
+ pass
+ line = raw_input(prompt)
+ # When stdin is in binary mode on Windows, it can cause
+ # raw_input() to emit an extra trailing carriage return
+ if os.linesep == '\r\n' and line and line[-1] == '\r':
+ line = line[:-1]
+ return line
+
+ def prompt(self, msg, default="y"):
+ """Prompt user with msg, read response.
+ If ui is not interactive, the default is returned.
+ """
+ if not self.interactive():
+ self.write(msg, ' ', default, "\n")
+ return default
+ try:
+ r = self._readline(msg + ' ')
+ if not r:
+ return default
+ return r
+ except EOFError:
+ raise util.Abort(_('response expected'))
+
+ def promptchoice(self, msg, choices, default=0):
+ """Prompt user with msg, read response, and ensure it matches
+ one of the provided choices. The index of the choice is returned.
+ choices is a sequence of acceptable responses with the format:
+ ('&None', 'E&xec', 'Sym&link') Responses are case insensitive.
+ If ui is not interactive, the default is returned.
+ """
+ resps = [s[s.index('&')+1].lower() for s in choices]
+ while True:
+ r = self.prompt(msg, resps[default])
+ if r.lower() in resps:
+ return resps.index(r.lower())
+ self.write(_("unrecognized response\n"))
+
+
+ def getpass(self, prompt=None, default=None):
+ if not self.interactive(): return default
+ try:
+ return getpass.getpass(prompt or _('password: '))
+ except EOFError:
+ raise util.Abort(_('response expected'))
+ def status(self, *msg):
+ if not self.quiet: self.write(*msg)
+ def warn(self, *msg):
+ self.write_err(*msg)
+ def note(self, *msg):
+ if self.verbose: self.write(*msg)
+ def debug(self, *msg):
+ if self.debugflag: self.write(*msg)
+ def edit(self, text, user):
+ (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
+ text=True)
+ try:
+ f = os.fdopen(fd, "w")
+ f.write(text)
+ f.close()
+
+ editor = self.geteditor()
+
+ util.system("%s \"%s\"" % (editor, name),
+ environ={'HGUSER': user},
+ onerr=util.Abort, errprefix=_("edit failed"))
+
+ f = open(name)
+ t = f.read()
+ f.close()
+ finally:
+ os.unlink(name)
+
+ return t
+
+ def traceback(self):
+ '''print exception traceback if traceback printing enabled.
+ only to call in exception handler. returns true if traceback
+ printed.'''
+ if self._traceback:
+ traceback.print_exc()
+ return self._traceback
+
+ def geteditor(self):
+ '''return editor to use'''
+ return (os.environ.get("HGEDITOR") or
+ self.config("ui", "editor") or
+ os.environ.get("VISUAL") or
+ os.environ.get("EDITOR", "vi"))
+
+ def progress(self, topic, pos, item="", unit="", total=None):
+ '''show a progress message
+
+ With stock hg, this is simply a debug message that is hidden
+ by default, but with extensions or GUI tools it may be
+ visible. 'topic' is the current operation, 'item' is a
+ non-numeric marker of the current position (ie the currently
+ in-process file), 'pos' is the current numeric position (ie
+ revision, bytes, etc.), units is a corresponding unit label,
+ and total is the highest expected pos.
+
+ Multiple nested topics may be active at a time. All topics
+ should be marked closed by setting pos to None at termination.
+ '''
+
+ if pos == None or not self.debugflag:
+ return
+
+ if units:
+ units = ' ' + units
+ if item:
+ item = ' ' + item
+
+ if total:
+ pct = 100.0 * pos / total
+ ui.debug('%s:%s %s/%s%s (%4.2g%%)\n'
+ % (topic, item, pos, total, units, pct))
+ else:
+ ui.debug('%s:%s %s%s\n' % (topic, item, pos, units))
diff --git a/sys/src/cmd/hg/mercurial/ui.pyc b/sys/src/cmd/hg/mercurial/ui.pyc
new file mode 100644
index 000000000..b3d59a2d3
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/ui.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/url.py b/sys/src/cmd/hg/mercurial/url.py
new file mode 100644
index 000000000..131d95550
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/url.py
@@ -0,0 +1,533 @@
+# url.py - HTTP handling for mercurial
+#
+# Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
+# Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import urllib, urllib2, urlparse, httplib, os, re, socket, cStringIO
+from i18n import _
+import keepalive, util
+
+def hidepassword(url):
+ '''hide user credential in a url string'''
+ scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
+ netloc = re.sub('([^:]*):([^@]*)@(.*)', r'\1:***@\3', netloc)
+ return urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
+
+def removeauth(url):
+ '''remove all authentication information from a url string'''
+ scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
+ netloc = netloc[netloc.find('@')+1:]
+ return urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
+
+def netlocsplit(netloc):
+ '''split [user[:passwd]@]host[:port] into 4-tuple.'''
+
+ a = netloc.find('@')
+ if a == -1:
+ user, passwd = None, None
+ else:
+ userpass, netloc = netloc[:a], netloc[a+1:]
+ c = userpass.find(':')
+ if c == -1:
+ user, passwd = urllib.unquote(userpass), None
+ else:
+ user = urllib.unquote(userpass[:c])
+ passwd = urllib.unquote(userpass[c+1:])
+ c = netloc.find(':')
+ if c == -1:
+ host, port = netloc, None
+ else:
+ host, port = netloc[:c], netloc[c+1:]
+ return host, port, user, passwd
+
+def netlocunsplit(host, port, user=None, passwd=None):
+ '''turn host, port, user, passwd into [user[:passwd]@]host[:port].'''
+ if port:
+ hostport = host + ':' + port
+ else:
+ hostport = host
+ if user:
+ if passwd:
+ userpass = urllib.quote(user) + ':' + urllib.quote(passwd)
+ else:
+ userpass = urllib.quote(user)
+ return userpass + '@' + hostport
+ return hostport
+
+_safe = ('abcdefghijklmnopqrstuvwxyz'
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ '0123456789' '_.-/')
+_safeset = None
+_hex = None
+def quotepath(path):
+ '''quote the path part of a URL
+
+ This is similar to urllib.quote, but it also tries to avoid
+ quoting things twice (inspired by wget):
+
+ >>> quotepath('abc def')
+ 'abc%20def'
+ >>> quotepath('abc%20def')
+ 'abc%20def'
+ >>> quotepath('abc%20 def')
+ 'abc%20%20def'
+ >>> quotepath('abc def%20')
+ 'abc%20def%20'
+ >>> quotepath('abc def%2')
+ 'abc%20def%252'
+ >>> quotepath('abc def%')
+ 'abc%20def%25'
+ '''
+ global _safeset, _hex
+ if _safeset is None:
+ _safeset = set(_safe)
+ _hex = set('abcdefABCDEF0123456789')
+ l = list(path)
+ for i in xrange(len(l)):
+ c = l[i]
+ if c == '%' and i + 2 < len(l) and (l[i+1] in _hex and l[i+2] in _hex):
+ pass
+ elif c not in _safeset:
+ l[i] = '%%%02X' % ord(c)
+ return ''.join(l)
+
+class passwordmgr(urllib2.HTTPPasswordMgrWithDefaultRealm):
+ def __init__(self, ui):
+ urllib2.HTTPPasswordMgrWithDefaultRealm.__init__(self)
+ self.ui = ui
+
+ def find_user_password(self, realm, authuri):
+ authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
+ self, realm, authuri)
+ user, passwd = authinfo
+ if user and passwd:
+ self._writedebug(user, passwd)
+ return (user, passwd)
+
+ if not user:
+ auth = self.readauthtoken(authuri)
+ if auth:
+ user, passwd = auth.get('username'), auth.get('password')
+ if not user or not passwd:
+ if not self.ui.interactive():
+ raise util.Abort(_('http authorization required'))
+
+ self.ui.write(_("http authorization required\n"))
+ self.ui.status(_("realm: %s\n") % realm)
+ if user:
+ self.ui.status(_("user: %s\n") % user)
+ else:
+ user = self.ui.prompt(_("user:"), default=None)
+
+ if not passwd:
+ passwd = self.ui.getpass()
+
+ self.add_password(realm, authuri, user, passwd)
+ self._writedebug(user, passwd)
+ return (user, passwd)
+
+ def _writedebug(self, user, passwd):
+ msg = _('http auth: user %s, password %s\n')
+ self.ui.debug(msg % (user, passwd and '*' * len(passwd) or 'not set'))
+
+ def readauthtoken(self, uri):
+ # Read configuration
+ config = dict()
+ for key, val in self.ui.configitems('auth'):
+ group, setting = key.split('.', 1)
+ gdict = config.setdefault(group, dict())
+ gdict[setting] = val
+
+ # Find the best match
+ scheme, hostpath = uri.split('://', 1)
+ bestlen = 0
+ bestauth = None
+ for auth in config.itervalues():
+ prefix = auth.get('prefix')
+ if not prefix: continue
+ p = prefix.split('://', 1)
+ if len(p) > 1:
+ schemes, prefix = [p[0]], p[1]
+ else:
+ schemes = (auth.get('schemes') or 'https').split()
+ if (prefix == '*' or hostpath.startswith(prefix)) and \
+ len(prefix) > bestlen and scheme in schemes:
+ bestlen = len(prefix)
+ bestauth = auth
+ return bestauth
+
+class proxyhandler(urllib2.ProxyHandler):
+ def __init__(self, ui):
+ proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
+ # XXX proxyauthinfo = None
+
+ if proxyurl:
+ # proxy can be proper url or host[:port]
+ if not (proxyurl.startswith('http:') or
+ proxyurl.startswith('https:')):
+ proxyurl = 'http://' + proxyurl + '/'
+ snpqf = urlparse.urlsplit(proxyurl)
+ proxyscheme, proxynetloc, proxypath, proxyquery, proxyfrag = snpqf
+ hpup = netlocsplit(proxynetloc)
+
+ proxyhost, proxyport, proxyuser, proxypasswd = hpup
+ if not proxyuser:
+ proxyuser = ui.config("http_proxy", "user")
+ proxypasswd = ui.config("http_proxy", "passwd")
+
+ # see if we should use a proxy for this url
+ no_list = [ "localhost", "127.0.0.1" ]
+ no_list.extend([p.lower() for
+ p in ui.configlist("http_proxy", "no")])
+ no_list.extend([p.strip().lower() for
+ p in os.getenv("no_proxy", '').split(',')
+ if p.strip()])
+ # "http_proxy.always" config is for running tests on localhost
+ if ui.configbool("http_proxy", "always"):
+ self.no_list = []
+ else:
+ self.no_list = no_list
+
+ proxyurl = urlparse.urlunsplit((
+ proxyscheme, netlocunsplit(proxyhost, proxyport,
+ proxyuser, proxypasswd or ''),
+ proxypath, proxyquery, proxyfrag))
+ proxies = {'http': proxyurl, 'https': proxyurl}
+ ui.debug(_('proxying through http://%s:%s\n') %
+ (proxyhost, proxyport))
+ else:
+ proxies = {}
+
+ # urllib2 takes proxy values from the environment and those
+ # will take precedence if found, so drop them
+ for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]:
+ try:
+ if env in os.environ:
+ del os.environ[env]
+ except OSError:
+ pass
+
+ urllib2.ProxyHandler.__init__(self, proxies)
+ self.ui = ui
+
+ def proxy_open(self, req, proxy, type_):
+ host = req.get_host().split(':')[0]
+ if host in self.no_list:
+ return None
+
+ # work around a bug in Python < 2.4.2
+ # (it leaves a "\n" at the end of Proxy-authorization headers)
+ baseclass = req.__class__
+ class _request(baseclass):
+ def add_header(self, key, val):
+ if key.lower() == 'proxy-authorization':
+ val = val.strip()
+ return baseclass.add_header(self, key, val)
+ req.__class__ = _request
+
+ return urllib2.ProxyHandler.proxy_open(self, req, proxy, type_)
+
+class httpsendfile(file):
+ def __len__(self):
+ return os.fstat(self.fileno()).st_size
+
+def _gen_sendfile(connection):
+ def _sendfile(self, data):
+ # send a file
+ if isinstance(data, httpsendfile):
+ # if auth required, some data sent twice, so rewind here
+ data.seek(0)
+ for chunk in util.filechunkiter(data):
+ connection.send(self, chunk)
+ else:
+ connection.send(self, data)
+ return _sendfile
+
+has_https = hasattr(urllib2, 'HTTPSHandler')
+if has_https:
+ try:
+ # avoid using deprecated/broken FakeSocket in python 2.6
+ import ssl
+ _ssl_wrap_socket = ssl.wrap_socket
+ except ImportError:
+ def _ssl_wrap_socket(sock, key_file, cert_file):
+ ssl = socket.ssl(sock, key_file, cert_file)
+ return httplib.FakeSocket(sock, ssl)
+
+class httpconnection(keepalive.HTTPConnection):
+ # must be able to send big bundle as stream.
+ send = _gen_sendfile(keepalive.HTTPConnection)
+
+ def _proxytunnel(self):
+ proxyheaders = dict(
+ [(x, self.headers[x]) for x in self.headers
+ if x.lower().startswith('proxy-')])
+ self._set_hostport(self.host, self.port)
+ self.send('CONNECT %s:%d HTTP/1.0\r\n' % (self.realhost, self.realport))
+ for header in proxyheaders.iteritems():
+ self.send('%s: %s\r\n' % header)
+ self.send('\r\n')
+
+ # majority of the following code is duplicated from
+ # httplib.HTTPConnection as there are no adequate places to
+ # override functions to provide the needed functionality
+ res = self.response_class(self.sock,
+ strict=self.strict,
+ method=self._method)
+
+ while True:
+ version, status, reason = res._read_status()
+ if status != httplib.CONTINUE:
+ break
+ while True:
+ skip = res.fp.readline().strip()
+ if not skip:
+ break
+ res.status = status
+ res.reason = reason.strip()
+
+ if res.status == 200:
+ while True:
+ line = res.fp.readline()
+ if line == '\r\n':
+ break
+ return True
+
+ if version == 'HTTP/1.0':
+ res.version = 10
+ elif version.startswith('HTTP/1.'):
+ res.version = 11
+ elif version == 'HTTP/0.9':
+ res.version = 9
+ else:
+ raise httplib.UnknownProtocol(version)
+
+ if res.version == 9:
+ res.length = None
+ res.chunked = 0
+ res.will_close = 1
+ res.msg = httplib.HTTPMessage(cStringIO.StringIO())
+ return False
+
+ res.msg = httplib.HTTPMessage(res.fp)
+ res.msg.fp = None
+
+ # are we using the chunked-style of transfer encoding?
+ trenc = res.msg.getheader('transfer-encoding')
+ if trenc and trenc.lower() == "chunked":
+ res.chunked = 1
+ res.chunk_left = None
+ else:
+ res.chunked = 0
+
+ # will the connection close at the end of the response?
+ res.will_close = res._check_close()
+
+ # do we have a Content-Length?
+ # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
+ length = res.msg.getheader('content-length')
+ if length and not res.chunked:
+ try:
+ res.length = int(length)
+ except ValueError:
+ res.length = None
+ else:
+ if res.length < 0: # ignore nonsensical negative lengths
+ res.length = None
+ else:
+ res.length = None
+
+ # does the body have a fixed length? (of zero)
+ if (status == httplib.NO_CONTENT or status == httplib.NOT_MODIFIED or
+ 100 <= status < 200 or # 1xx codes
+ res._method == 'HEAD'):
+ res.length = 0
+
+ # if the connection remains open, and we aren't using chunked, and
+ # a content-length was not provided, then assume that the connection
+ # WILL close.
+ if (not res.will_close and
+ not res.chunked and
+ res.length is None):
+ res.will_close = 1
+
+ self.proxyres = res
+
+ return False
+
+ def connect(self):
+ if has_https and self.realhost: # use CONNECT proxy
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.sock.connect((self.host, self.port))
+ if self._proxytunnel():
+ # we do not support client x509 certificates
+ self.sock = _ssl_wrap_socket(self.sock, None, None)
+ else:
+ keepalive.HTTPConnection.connect(self)
+
+ def getresponse(self):
+ proxyres = getattr(self, 'proxyres', None)
+ if proxyres:
+ if proxyres.will_close:
+ self.close()
+ self.proxyres = None
+ return proxyres
+ return keepalive.HTTPConnection.getresponse(self)
+
+class httphandler(keepalive.HTTPHandler):
+ def http_open(self, req):
+ return self.do_open(httpconnection, req)
+
+ def _start_transaction(self, h, req):
+ if req.get_selector() == req.get_full_url(): # has proxy
+ urlparts = urlparse.urlparse(req.get_selector())
+ if urlparts[0] == 'https': # only use CONNECT for HTTPS
+ if ':' in urlparts[1]:
+ realhost, realport = urlparts[1].split(':')
+ realport = int(realport)
+ else:
+ realhost = urlparts[1]
+ realport = 443
+
+ h.realhost = realhost
+ h.realport = realport
+ h.headers = req.headers.copy()
+ h.headers.update(self.parent.addheaders)
+ return keepalive.HTTPHandler._start_transaction(self, h, req)
+
+ h.realhost = None
+ h.realport = None
+ h.headers = None
+ return keepalive.HTTPHandler._start_transaction(self, h, req)
+
+ def __del__(self):
+ self.close_all()
+
+if has_https:
+ class httpsconnection(httplib.HTTPSConnection):
+ response_class = keepalive.HTTPResponse
+ # must be able to send big bundle as stream.
+ send = _gen_sendfile(httplib.HTTPSConnection)
+
+ class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler):
+ def __init__(self, ui):
+ keepalive.KeepAliveHandler.__init__(self)
+ urllib2.HTTPSHandler.__init__(self)
+ self.ui = ui
+ self.pwmgr = passwordmgr(self.ui)
+
+ def https_open(self, req):
+ self.auth = self.pwmgr.readauthtoken(req.get_full_url())
+ return self.do_open(self._makeconnection, req)
+
+ def _makeconnection(self, host, port=443, *args, **kwargs):
+ keyfile = None
+ certfile = None
+
+ if args: # key_file
+ keyfile = args.pop(0)
+ if args: # cert_file
+ certfile = args.pop(0)
+
+ # if the user has specified different key/cert files in
+ # hgrc, we prefer these
+ if self.auth and 'key' in self.auth and 'cert' in self.auth:
+ keyfile = self.auth['key']
+ certfile = self.auth['cert']
+
+ # let host port take precedence
+ if ':' in host and '[' not in host or ']:' in host:
+ host, port = host.rsplit(':', 1)
+ port = int(port)
+ if '[' in host:
+ host = host[1:-1]
+
+ return httpsconnection(host, port, keyfile, certfile, *args, **kwargs)
+
+# In python < 2.5 AbstractDigestAuthHandler raises a ValueError if
+# it doesn't know about the auth type requested. This can happen if
+# somebody is using BasicAuth and types a bad password.
+class httpdigestauthhandler(urllib2.HTTPDigestAuthHandler):
+ def http_error_auth_reqed(self, auth_header, host, req, headers):
+ try:
+ return urllib2.HTTPDigestAuthHandler.http_error_auth_reqed(
+ self, auth_header, host, req, headers)
+ except ValueError, inst:
+ arg = inst.args[0]
+ if arg.startswith("AbstractDigestAuthHandler doesn't know "):
+ return
+ raise
+
+def getauthinfo(path):
+ scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
+ if not urlpath:
+ urlpath = '/'
+ if scheme != 'file':
+ # XXX: why are we quoting the path again with some smart
+ # heuristic here? Anyway, it cannot be done with file://
+ # urls since path encoding is os/fs dependent (see
+ # urllib.pathname2url() for details).
+ urlpath = quotepath(urlpath)
+ host, port, user, passwd = netlocsplit(netloc)
+
+ # urllib cannot handle URLs with embedded user or passwd
+ url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
+ urlpath, query, frag))
+ if user:
+ netloc = host
+ if port:
+ netloc += ':' + port
+ # Python < 2.4.3 uses only the netloc to search for a password
+ authinfo = (None, (url, netloc), user, passwd or '')
+ else:
+ authinfo = None
+ return url, authinfo
+
+handlerfuncs = []
+
+def opener(ui, authinfo=None):
+ '''
+ construct an opener suitable for urllib2
+ authinfo will be added to the password manager
+ '''
+ handlers = [httphandler()]
+ if has_https:
+ handlers.append(httpshandler(ui))
+
+ handlers.append(proxyhandler(ui))
+
+ passmgr = passwordmgr(ui)
+ if authinfo is not None:
+ passmgr.add_password(*authinfo)
+ user, passwd = authinfo[2:4]
+ ui.debug(_('http auth: user %s, password %s\n') %
+ (user, passwd and '*' * len(passwd) or 'not set'))
+
+ handlers.extend((urllib2.HTTPBasicAuthHandler(passmgr),
+ httpdigestauthhandler(passmgr)))
+ handlers.extend([h(ui, passmgr) for h in handlerfuncs])
+ opener = urllib2.build_opener(*handlers)
+
+ # 1.0 here is the _protocol_ version
+ opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
+ opener.addheaders.append(('Accept', 'application/mercurial-0.1'))
+ return opener
+
+scheme_re = re.compile(r'^([a-zA-Z0-9+-.]+)://')
+
+def open(ui, url, data=None):
+ scheme = None
+ m = scheme_re.search(url)
+ if m:
+ scheme = m.group(1).lower()
+ if not scheme:
+ path = util.normpath(os.path.abspath(url))
+ url = 'file://' + urllib.pathname2url(path)
+ authinfo = None
+ else:
+ url, authinfo = getauthinfo(url)
+ return opener(ui, authinfo).open(url, data)
diff --git a/sys/src/cmd/hg/mercurial/util.py b/sys/src/cmd/hg/mercurial/util.py
new file mode 100644
index 000000000..02ff43d7f
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/util.py
@@ -0,0 +1,1284 @@
+# util.py - Mercurial utility functions and platform specfic implementations
+#
+# Copyright 2005 K. Thananchayan <thananck@yahoo.com>
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+"""Mercurial utility functions and platform specfic implementations.
+
+This contains helper routines that are independent of the SCM core and
+hide platform-specific details from the core.
+"""
+
+from i18n import _
+import error, osutil
+import cStringIO, errno, re, shutil, sys, tempfile, traceback
+import os, stat, time, calendar, random, textwrap
+import imp
+
+# Python compatibility
+
+def sha1(s):
+ return _fastsha1(s)
+
+def _fastsha1(s):
+ # This function will import sha1 from hashlib or sha (whichever is
+ # available) and overwrite itself with it on the first call.
+ # Subsequent calls will go directly to the imported function.
+ try:
+ from hashlib import sha1 as _sha1
+ except ImportError:
+ from sha import sha as _sha1
+ global _fastsha1, sha1
+ _fastsha1 = sha1 = _sha1
+ return _sha1(s)
+
+import subprocess
+closefds = os.name == 'posix'
+def popen2(cmd):
+ # Setting bufsize to -1 lets the system decide the buffer size.
+ # The default for bufsize is 0, meaning unbuffered. This leads to
+ # poor performance on Mac OS X: http://bugs.python.org/issue4194
+ p = subprocess.Popen(cmd, shell=True, bufsize=-1,
+ close_fds=closefds,
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ return p.stdin, p.stdout
+def popen3(cmd):
+ p = subprocess.Popen(cmd, shell=True, bufsize=-1,
+ close_fds=closefds,
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ return p.stdin, p.stdout, p.stderr
+
+def version():
+ """Return version information if available."""
+ try:
+ import __version__
+ return __version__.version
+ except ImportError:
+ return 'unknown'
+
+# used by parsedate
+defaultdateformats = (
+ '%Y-%m-%d %H:%M:%S',
+ '%Y-%m-%d %I:%M:%S%p',
+ '%Y-%m-%d %H:%M',
+ '%Y-%m-%d %I:%M%p',
+ '%Y-%m-%d',
+ '%m-%d',
+ '%m/%d',
+ '%m/%d/%y',
+ '%m/%d/%Y',
+ '%a %b %d %H:%M:%S %Y',
+ '%a %b %d %I:%M:%S%p %Y',
+ '%a, %d %b %Y %H:%M:%S', # GNU coreutils "/bin/date --rfc-2822"
+ '%b %d %H:%M:%S %Y',
+ '%b %d %I:%M:%S%p %Y',
+ '%b %d %H:%M:%S',
+ '%b %d %I:%M:%S%p',
+ '%b %d %H:%M',
+ '%b %d %I:%M%p',
+ '%b %d %Y',
+ '%b %d',
+ '%H:%M:%S',
+ '%I:%M:%SP',
+ '%H:%M',
+ '%I:%M%p',
+)
+
+extendeddateformats = defaultdateformats + (
+ "%Y",
+ "%Y-%m",
+ "%b",
+ "%b %Y",
+ )
+
+def cachefunc(func):
+ '''cache the result of function calls'''
+ # XXX doesn't handle keywords args
+ cache = {}
+ if func.func_code.co_argcount == 1:
+ # we gain a small amount of time because
+ # we don't need to pack/unpack the list
+ def f(arg):
+ if arg not in cache:
+ cache[arg] = func(arg)
+ return cache[arg]
+ else:
+ def f(*args):
+ if args not in cache:
+ cache[args] = func(*args)
+ return cache[args]
+
+ return f
+
+def lrucachefunc(func):
+ '''cache most recent results of function calls'''
+ cache = {}
+ order = []
+ if func.func_code.co_argcount == 1:
+ def f(arg):
+ if arg not in cache:
+ if len(cache) > 20:
+ del cache[order.pop(0)]
+ cache[arg] = func(arg)
+ else:
+ order.remove(arg)
+ order.append(arg)
+ return cache[arg]
+ else:
+ def f(*args):
+ if args not in cache:
+ if len(cache) > 20:
+ del cache[order.pop(0)]
+ cache[args] = func(*args)
+ else:
+ order.remove(args)
+ order.append(args)
+ return cache[args]
+
+ return f
+
+class propertycache(object):
+ def __init__(self, func):
+ self.func = func
+ self.name = func.__name__
+ def __get__(self, obj, type=None):
+ result = self.func(obj)
+ setattr(obj, self.name, result)
+ return result
+
+def pipefilter(s, cmd):
+ '''filter string S through command CMD, returning its output'''
+ p = subprocess.Popen(cmd, shell=True, close_fds=closefds,
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ pout, perr = p.communicate(s)
+ return pout
+
+def tempfilter(s, cmd):
+ '''filter string S through a pair of temporary files with CMD.
+ CMD is used as a template to create the real command to be run,
+ with the strings INFILE and OUTFILE replaced by the real names of
+ the temporary files generated.'''
+ inname, outname = None, None
+ try:
+ infd, inname = tempfile.mkstemp(prefix='hg-filter-in-')
+ fp = os.fdopen(infd, 'wb')
+ fp.write(s)
+ fp.close()
+ outfd, outname = tempfile.mkstemp(prefix='hg-filter-out-')
+ os.close(outfd)
+ cmd = cmd.replace('INFILE', inname)
+ cmd = cmd.replace('OUTFILE', outname)
+ code = os.system(cmd)
+ if sys.platform == 'OpenVMS' and code & 1:
+ code = 0
+ if code: raise Abort(_("command '%s' failed: %s") %
+ (cmd, explain_exit(code)))
+ return open(outname, 'rb').read()
+ finally:
+ try:
+ if inname: os.unlink(inname)
+ except: pass
+ try:
+ if outname: os.unlink(outname)
+ except: pass
+
+filtertable = {
+ 'tempfile:': tempfilter,
+ 'pipe:': pipefilter,
+ }
+
+def filter(s, cmd):
+ "filter a string through a command that transforms its input to its output"
+ for name, fn in filtertable.iteritems():
+ if cmd.startswith(name):
+ return fn(s, cmd[len(name):].lstrip())
+ return pipefilter(s, cmd)
+
+def binary(s):
+ """return true if a string is binary data"""
+ return bool(s and '\0' in s)
+
+def increasingchunks(source, min=1024, max=65536):
+ '''return no less than min bytes per chunk while data remains,
+ doubling min after each chunk until it reaches max'''
+ def log2(x):
+ if not x:
+ return 0
+ i = 0
+ while x:
+ x >>= 1
+ i += 1
+ return i - 1
+
+ buf = []
+ blen = 0
+ for chunk in source:
+ buf.append(chunk)
+ blen += len(chunk)
+ if blen >= min:
+ if min < max:
+ min = min << 1
+ nmin = 1 << log2(blen)
+ if nmin > min:
+ min = nmin
+ if min > max:
+ min = max
+ yield ''.join(buf)
+ blen = 0
+ buf = []
+ if buf:
+ yield ''.join(buf)
+
+Abort = error.Abort
+
+def always(fn): return True
+def never(fn): return False
+
+def pathto(root, n1, n2):
+ '''return the relative path from one place to another.
+ root should use os.sep to separate directories
+ n1 should use os.sep to separate directories
+ n2 should use "/" to separate directories
+ returns an os.sep-separated path.
+
+ If n1 is a relative path, it's assumed it's
+ relative to root.
+ n2 should always be relative to root.
+ '''
+ if not n1: return localpath(n2)
+ if os.path.isabs(n1):
+ if os.path.splitdrive(root)[0] != os.path.splitdrive(n1)[0]:
+ return os.path.join(root, localpath(n2))
+ n2 = '/'.join((pconvert(root), n2))
+ a, b = splitpath(n1), n2.split('/')
+ a.reverse()
+ b.reverse()
+ while a and b and a[-1] == b[-1]:
+ a.pop()
+ b.pop()
+ b.reverse()
+ return os.sep.join((['..'] * len(a)) + b) or '.'
+
+def canonpath(root, cwd, myname):
+ """return the canonical path of myname, given cwd and root"""
+ if root == os.sep:
+ rootsep = os.sep
+ elif endswithsep(root):
+ rootsep = root
+ else:
+ rootsep = root + os.sep
+ name = myname
+ if not os.path.isabs(name):
+ name = os.path.join(root, cwd, name)
+ name = os.path.normpath(name)
+ audit_path = path_auditor(root)
+ if name != rootsep and name.startswith(rootsep):
+ name = name[len(rootsep):]
+ audit_path(name)
+ return pconvert(name)
+ elif name == root:
+ return ''
+ else:
+ # Determine whether `name' is in the hierarchy at or beneath `root',
+ # by iterating name=dirname(name) until that causes no change (can't
+ # check name == '/', because that doesn't work on windows). For each
+ # `name', compare dev/inode numbers. If they match, the list `rel'
+ # holds the reversed list of components making up the relative file
+ # name we want.
+ root_st = os.stat(root)
+ rel = []
+ while True:
+ try:
+ name_st = os.stat(name)
+ except OSError:
+ break
+ if samestat(name_st, root_st):
+ if not rel:
+ # name was actually the same as root (maybe a symlink)
+ return ''
+ rel.reverse()
+ name = os.path.join(*rel)
+ audit_path(name)
+ return pconvert(name)
+ dirname, basename = os.path.split(name)
+ rel.append(basename)
+ if dirname == name:
+ break
+ name = dirname
+
+ raise Abort('%s not under root' % myname)
+
+_hgexecutable = None
+
+def main_is_frozen():
+ """return True if we are a frozen executable.
+
+ The code supports py2exe (most common, Windows only) and tools/freeze
+ (portable, not much used).
+ """
+ return (hasattr(sys, "frozen") or # new py2exe
+ hasattr(sys, "importers") or # old py2exe
+ imp.is_frozen("__main__")) # tools/freeze
+
+def hgexecutable():
+ """return location of the 'hg' executable.
+
+ Defaults to $HG or 'hg' in the search path.
+ """
+ if _hgexecutable is None:
+ hg = os.environ.get('HG')
+ if hg:
+ set_hgexecutable(hg)
+ elif main_is_frozen():
+ set_hgexecutable(sys.executable)
+ else:
+ set_hgexecutable(find_exe('hg') or 'hg')
+ return _hgexecutable
+
+def set_hgexecutable(path):
+ """set location of the 'hg' executable"""
+ global _hgexecutable
+ _hgexecutable = path
+
+def system(cmd, environ={}, cwd=None, onerr=None, errprefix=None):
+ '''enhanced shell command execution.
+ run with environment maybe modified, maybe in different dir.
+
+ if command fails and onerr is None, return status. if ui object,
+ print error message and return status, else raise onerr object as
+ exception.'''
+ def py2shell(val):
+ 'convert python object into string that is useful to shell'
+ if val is None or val is False:
+ return '0'
+ if val is True:
+ return '1'
+ return str(val)
+ oldenv = {}
+ for k in environ:
+ oldenv[k] = os.environ.get(k)
+ if cwd is not None:
+ oldcwd = os.getcwd()
+ origcmd = cmd
+ if os.name == 'nt':
+ cmd = '"%s"' % cmd
+ try:
+ for k, v in environ.iteritems():
+ os.environ[k] = py2shell(v)
+ os.environ['HG'] = hgexecutable()
+ if cwd is not None and oldcwd != cwd:
+ os.chdir(cwd)
+ rc = os.system(cmd)
+ if sys.platform == 'OpenVMS' and rc & 1:
+ rc = 0
+ if rc and onerr:
+ errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]),
+ explain_exit(rc)[0])
+ if errprefix:
+ errmsg = '%s: %s' % (errprefix, errmsg)
+ try:
+ onerr.warn(errmsg + '\n')
+ except AttributeError:
+ raise onerr(errmsg)
+ return rc
+ finally:
+ for k, v in oldenv.iteritems():
+ if v is None:
+ del os.environ[k]
+ else:
+ os.environ[k] = v
+ if cwd is not None and oldcwd != cwd:
+ os.chdir(oldcwd)
+
+def checksignature(func):
+ '''wrap a function with code to check for calling errors'''
+ def check(*args, **kwargs):
+ try:
+ return func(*args, **kwargs)
+ except TypeError:
+ if len(traceback.extract_tb(sys.exc_info()[2])) == 1:
+ raise error.SignatureError
+ raise
+
+ return check
+
+# os.path.lexists is not available on python2.3
+def lexists(filename):
+ "test whether a file with this name exists. does not follow symlinks"
+ try:
+ os.lstat(filename)
+ except:
+ return False
+ return True
+
+def rename(src, dst):
+ """forcibly rename a file"""
+ try:
+ os.rename(src, dst)
+ except OSError, err: # FIXME: check err (EEXIST ?)
+
+ # On windows, rename to existing file is not allowed, so we
+ # must delete destination first. But if a file is open, unlink
+ # schedules it for delete but does not delete it. Rename
+ # happens immediately even for open files, so we rename
+ # destination to a temporary name, then delete that. Then
+ # rename is safe to do.
+ # The temporary name is chosen at random to avoid the situation
+ # where a file is left lying around from a previous aborted run.
+ # The usual race condition this introduces can't be avoided as
+ # we need the name to rename into, and not the file itself. Due
+ # to the nature of the operation however, any races will at worst
+ # lead to the rename failing and the current operation aborting.
+
+ def tempname(prefix):
+ for tries in xrange(10):
+ temp = '%s-%08x' % (prefix, random.randint(0, 0xffffffff))
+ if not os.path.exists(temp):
+ return temp
+ raise IOError, (errno.EEXIST, "No usable temporary filename found")
+
+ temp = tempname(dst)
+ os.rename(dst, temp)
+ os.unlink(temp)
+ os.rename(src, dst)
+
+def unlink(f):
+ """unlink and remove the directory if it is empty"""
+ os.unlink(f)
+ # try removing directories that might now be empty
+ try:
+ os.removedirs(os.path.dirname(f))
+ except OSError:
+ pass
+
+def copyfile(src, dest):
+ "copy a file, preserving mode and atime/mtime"
+ if os.path.islink(src):
+ try:
+ os.unlink(dest)
+ except:
+ pass
+ os.symlink(os.readlink(src), dest)
+ else:
+ try:
+ shutil.copyfile(src, dest)
+ shutil.copystat(src, dest)
+ except shutil.Error, inst:
+ raise Abort(str(inst))
+
+def copyfiles(src, dst, hardlink=None):
+ """Copy a directory tree using hardlinks if possible"""
+
+ if hardlink is None:
+ hardlink = (os.stat(src).st_dev ==
+ os.stat(os.path.dirname(dst)).st_dev)
+
+ if os.path.isdir(src):
+ os.mkdir(dst)
+ for name, kind in osutil.listdir(src):
+ srcname = os.path.join(src, name)
+ dstname = os.path.join(dst, name)
+ copyfiles(srcname, dstname, hardlink)
+ else:
+ if hardlink:
+ try:
+ os_link(src, dst)
+ except (IOError, OSError):
+ hardlink = False
+ shutil.copy(src, dst)
+ else:
+ shutil.copy(src, dst)
+
+class path_auditor(object):
+ '''ensure that a filesystem path contains no banned components.
+ the following properties of a path are checked:
+
+ - under top-level .hg
+ - starts at the root of a windows drive
+ - contains ".."
+ - traverses a symlink (e.g. a/symlink_here/b)
+ - inside a nested repository'''
+
+ def __init__(self, root):
+ self.audited = set()
+ self.auditeddir = set()
+ self.root = root
+
+ def __call__(self, path):
+ if path in self.audited:
+ return
+ normpath = os.path.normcase(path)
+ parts = splitpath(normpath)
+ if (os.path.splitdrive(path)[0]
+ or parts[0].lower() in ('.hg', '.hg.', '')
+ or os.pardir in parts):
+ raise Abort(_("path contains illegal component: %s") % path)
+ if '.hg' in path.lower():
+ lparts = [p.lower() for p in parts]
+ for p in '.hg', '.hg.':
+ if p in lparts[1:]:
+ pos = lparts.index(p)
+ base = os.path.join(*parts[:pos])
+ raise Abort(_('path %r is inside repo %r') % (path, base))
+ def check(prefix):
+ curpath = os.path.join(self.root, prefix)
+ try:
+ st = os.lstat(curpath)
+ except OSError, err:
+ # EINVAL can be raised as invalid path syntax under win32.
+ # They must be ignored for patterns can be checked too.
+ if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
+ raise
+ else:
+ if stat.S_ISLNK(st.st_mode):
+ raise Abort(_('path %r traverses symbolic link %r') %
+ (path, prefix))
+ elif (stat.S_ISDIR(st.st_mode) and
+ os.path.isdir(os.path.join(curpath, '.hg'))):
+ raise Abort(_('path %r is inside repo %r') %
+ (path, prefix))
+ parts.pop()
+ prefixes = []
+ while parts:
+ prefix = os.sep.join(parts)
+ if prefix in self.auditeddir:
+ break
+ check(prefix)
+ prefixes.append(prefix)
+ parts.pop()
+
+ self.audited.add(path)
+ # only add prefixes to the cache after checking everything: we don't
+ # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
+ self.auditeddir.update(prefixes)
+
+def nlinks(pathname):
+ """Return number of hardlinks for the given file."""
+ return os.lstat(pathname).st_nlink
+
+if hasattr(os, 'link'):
+ os_link = os.link
+else:
+ def os_link(src, dst):
+ raise OSError(0, _("Hardlinks not supported"))
+
+def lookup_reg(key, name=None, scope=None):
+ return None
+
+if os.name == 'nt':
+ from windows import *
+else:
+ from posix import *
+
+def makelock(info, pathname):
+ try:
+ return os.symlink(info, pathname)
+ except OSError, why:
+ if why.errno == errno.EEXIST:
+ raise
+ except AttributeError: # no symlink in os
+ pass
+
+ ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
+ os.write(ld, info)
+ os.close(ld)
+
+def readlock(pathname):
+ try:
+ return os.readlink(pathname)
+ except OSError, why:
+ if why.errno not in (errno.EINVAL, errno.ENOSYS):
+ raise
+ except AttributeError: # no symlink in os
+ pass
+ return posixfile(pathname).read()
+
+def fstat(fp):
+ '''stat file object that may not have fileno method.'''
+ try:
+ return os.fstat(fp.fileno())
+ except AttributeError:
+ return os.stat(fp.name)
+
+# File system features
+
+def checkcase(path):
+ """
+ Check whether the given path is on a case-sensitive filesystem
+
+ Requires a path (like /foo/.hg) ending with a foldable final
+ directory component.
+ """
+ s1 = os.stat(path)
+ d, b = os.path.split(path)
+ p2 = os.path.join(d, b.upper())
+ if path == p2:
+ p2 = os.path.join(d, b.lower())
+ try:
+ s2 = os.stat(p2)
+ if s2 == s1:
+ return False
+ return True
+ except:
+ return True
+
+_fspathcache = {}
+def fspath(name, root):
+ '''Get name in the case stored in the filesystem
+
+ The name is either relative to root, or it is an absolute path starting
+ with root. Note that this function is unnecessary, and should not be
+ called, for case-sensitive filesystems (simply because it's expensive).
+ '''
+ # If name is absolute, make it relative
+ if name.lower().startswith(root.lower()):
+ l = len(root)
+ if name[l] == os.sep or name[l] == os.altsep:
+ l = l + 1
+ name = name[l:]
+
+ if not os.path.exists(os.path.join(root, name)):
+ return None
+
+ seps = os.sep
+ if os.altsep:
+ seps = seps + os.altsep
+ # Protect backslashes. This gets silly very quickly.
+ seps.replace('\\','\\\\')
+ pattern = re.compile(r'([^%s]+)|([%s]+)' % (seps, seps))
+ dir = os.path.normcase(os.path.normpath(root))
+ result = []
+ for part, sep in pattern.findall(name):
+ if sep:
+ result.append(sep)
+ continue
+
+ if dir not in _fspathcache:
+ _fspathcache[dir] = os.listdir(dir)
+ contents = _fspathcache[dir]
+
+ lpart = part.lower()
+ for n in contents:
+ if n.lower() == lpart:
+ result.append(n)
+ break
+ else:
+ # Cannot happen, as the file exists!
+ result.append(part)
+ dir = os.path.join(dir, lpart)
+
+ return ''.join(result)
+
+def checkexec(path):
+ """
+ Check whether the given path is on a filesystem with UNIX-like exec flags
+
+ Requires a directory (like /foo/.hg)
+ """
+
+ # VFAT on some Linux versions can flip mode but it doesn't persist
+ # a FS remount. Frequently we can detect it if files are created
+ # with exec bit on.
+
+ try:
+ EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
+ fh, fn = tempfile.mkstemp("", "", path)
+ try:
+ os.close(fh)
+ m = os.stat(fn).st_mode & 0777
+ new_file_has_exec = m & EXECFLAGS
+ os.chmod(fn, m ^ EXECFLAGS)
+ exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0777) == m)
+ finally:
+ os.unlink(fn)
+ except (IOError, OSError):
+ # we don't care, the user probably won't be able to commit anyway
+ return False
+ return not (new_file_has_exec or exec_flags_cannot_flip)
+
+def checklink(path):
+ """check whether the given path is on a symlink-capable filesystem"""
+ # mktemp is not racy because symlink creation will fail if the
+ # file already exists
+ name = tempfile.mktemp(dir=path)
+ try:
+ os.symlink(".", name)
+ os.unlink(name)
+ return True
+ except (OSError, AttributeError):
+ return False
+
+def needbinarypatch():
+ """return True if patches should be applied in binary mode by default."""
+ return os.name == 'nt'
+
+def endswithsep(path):
+ '''Check path ends with os.sep or os.altsep.'''
+ return path.endswith(os.sep) or os.altsep and path.endswith(os.altsep)
+
+def splitpath(path):
+ '''Split path by os.sep.
+ Note that this function does not use os.altsep because this is
+ an alternative of simple "xxx.split(os.sep)".
+ It is recommended to use os.path.normpath() before using this
+ function if need.'''
+ return path.split(os.sep)
+
+def gui():
+ '''Are we running in a GUI?'''
+ return os.name == "nt" or os.name == "mac" or os.environ.get("DISPLAY")
+
+def mktempcopy(name, emptyok=False, createmode=None):
+ """Create a temporary file with the same contents from name
+
+ The permission bits are copied from the original file.
+
+ If the temporary file is going to be truncated immediately, you
+ can use emptyok=True as an optimization.
+
+ Returns the name of the temporary file.
+ """
+ d, fn = os.path.split(name)
+ fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d)
+ os.close(fd)
+ # Temporary files are created with mode 0600, which is usually not
+ # what we want. If the original file already exists, just copy
+ # its mode. Otherwise, manually obey umask.
+ try:
+ st_mode = os.lstat(name).st_mode & 0777
+ except OSError, inst:
+ if inst.errno != errno.ENOENT:
+ raise
+ st_mode = createmode
+ if st_mode is None:
+ st_mode = ~umask
+ st_mode &= 0666
+ os.chmod(temp, st_mode)
+ if emptyok:
+ return temp
+ try:
+ try:
+ ifp = posixfile(name, "rb")
+ except IOError, inst:
+ if inst.errno == errno.ENOENT:
+ return temp
+ if not getattr(inst, 'filename', None):
+ inst.filename = name
+ raise
+ ofp = posixfile(temp, "wb")
+ for chunk in filechunkiter(ifp):
+ ofp.write(chunk)
+ ifp.close()
+ ofp.close()
+ except:
+ try: os.unlink(temp)
+ except: pass
+ raise
+ return temp
+
+class atomictempfile(object):
+ """file-like object that atomically updates a file
+
+ All writes will be redirected to a temporary copy of the original
+ file. When rename is called, the copy is renamed to the original
+ name, making the changes visible.
+ """
+ def __init__(self, name, mode, createmode):
+ self.__name = name
+ self._fp = None
+ self.temp = mktempcopy(name, emptyok=('w' in mode),
+ createmode=createmode)
+ self._fp = posixfile(self.temp, mode)
+
+ def __getattr__(self, name):
+ return getattr(self._fp, name)
+
+ def rename(self):
+ if not self._fp.closed:
+ self._fp.close()
+ rename(self.temp, localpath(self.__name))
+
+ def __del__(self):
+ if not self._fp:
+ return
+ if not self._fp.closed:
+ try:
+ os.unlink(self.temp)
+ except: pass
+ self._fp.close()
+
+def makedirs(name, mode=None):
+ """recursive directory creation with parent mode inheritance"""
+ try:
+ os.mkdir(name)
+ if mode is not None:
+ os.chmod(name, mode)
+ return
+ except OSError, err:
+ if err.errno == errno.EEXIST:
+ return
+ if err.errno != errno.ENOENT:
+ raise
+ parent = os.path.abspath(os.path.dirname(name))
+ makedirs(parent, mode)
+ makedirs(name, mode)
+
+class opener(object):
+ """Open files relative to a base directory
+
+ This class is used to hide the details of COW semantics and
+ remote file access from higher level code.
+ """
+ def __init__(self, base, audit=True):
+ self.base = base
+ if audit:
+ self.audit_path = path_auditor(base)
+ else:
+ self.audit_path = always
+ self.createmode = None
+
+ @propertycache
+ def _can_symlink(self):
+ return checklink(self.base)
+
+ def _fixfilemode(self, name):
+ if self.createmode is None:
+ return
+ os.chmod(name, self.createmode & 0666)
+
+ def __call__(self, path, mode="r", text=False, atomictemp=False):
+ self.audit_path(path)
+ f = os.path.join(self.base, path)
+
+ if not text and "b" not in mode:
+ mode += "b" # for that other OS
+
+ nlink = -1
+ if mode not in ("r", "rb"):
+ try:
+ nlink = nlinks(f)
+ except OSError:
+ nlink = 0
+ d = os.path.dirname(f)
+ if not os.path.isdir(d):
+ makedirs(d, self.createmode)
+ if atomictemp:
+ return atomictempfile(f, mode, self.createmode)
+ if nlink > 1:
+ rename(mktempcopy(f), f)
+ fp = posixfile(f, mode)
+ if nlink == 0:
+ self._fixfilemode(f)
+ return fp
+
+ def symlink(self, src, dst):
+ self.audit_path(dst)
+ linkname = os.path.join(self.base, dst)
+ try:
+ os.unlink(linkname)
+ except OSError:
+ pass
+
+ dirname = os.path.dirname(linkname)
+ if not os.path.exists(dirname):
+ makedirs(dirname, self.createmode)
+
+ if self._can_symlink:
+ try:
+ os.symlink(src, linkname)
+ except OSError, err:
+ raise OSError(err.errno, _('could not symlink to %r: %s') %
+ (src, err.strerror), linkname)
+ else:
+ f = self(dst, "w")
+ f.write(src)
+ f.close()
+ self._fixfilemode(dst)
+
+class chunkbuffer(object):
+ """Allow arbitrary sized chunks of data to be efficiently read from an
+ iterator over chunks of arbitrary size."""
+
+ def __init__(self, in_iter):
+ """in_iter is the iterator that's iterating over the input chunks.
+ targetsize is how big a buffer to try to maintain."""
+ self.iter = iter(in_iter)
+ self.buf = ''
+ self.targetsize = 2**16
+
+ def read(self, l):
+ """Read L bytes of data from the iterator of chunks of data.
+ Returns less than L bytes if the iterator runs dry."""
+ if l > len(self.buf) and self.iter:
+ # Clamp to a multiple of self.targetsize
+ targetsize = max(l, self.targetsize)
+ collector = cStringIO.StringIO()
+ collector.write(self.buf)
+ collected = len(self.buf)
+ for chunk in self.iter:
+ collector.write(chunk)
+ collected += len(chunk)
+ if collected >= targetsize:
+ break
+ if collected < targetsize:
+ self.iter = False
+ self.buf = collector.getvalue()
+ if len(self.buf) == l:
+ s, self.buf = str(self.buf), ''
+ else:
+ s, self.buf = self.buf[:l], buffer(self.buf, l)
+ return s
+
+def filechunkiter(f, size=65536, limit=None):
+ """Create a generator that produces the data in the file size
+ (default 65536) bytes at a time, up to optional limit (default is
+ to read all data). Chunks may be less than size bytes if the
+ chunk is the last chunk in the file, or the file is a socket or
+ some other type of file that sometimes reads less data than is
+ requested."""
+ assert size >= 0
+ assert limit is None or limit >= 0
+ while True:
+ if limit is None: nbytes = size
+ else: nbytes = min(limit, size)
+ s = nbytes and f.read(nbytes)
+ if not s: break
+ if limit: limit -= len(s)
+ yield s
+
+def makedate():
+ lt = time.localtime()
+ if lt[8] == 1 and time.daylight:
+ tz = time.altzone
+ else:
+ tz = time.timezone
+ return time.mktime(lt), tz
+
+def datestr(date=None, format='%a %b %d %H:%M:%S %Y %1%2'):
+ """represent a (unixtime, offset) tuple as a localized time.
+ unixtime is seconds since the epoch, and offset is the time zone's
+ number of seconds away from UTC. if timezone is false, do not
+ append time zone to string."""
+ t, tz = date or makedate()
+ if "%1" in format or "%2" in format:
+ sign = (tz > 0) and "-" or "+"
+ minutes = abs(tz) // 60
+ format = format.replace("%1", "%c%02d" % (sign, minutes // 60))
+ format = format.replace("%2", "%02d" % (minutes % 60))
+ s = time.strftime(format, time.gmtime(float(t) - tz))
+ return s
+
+def shortdate(date=None):
+ """turn (timestamp, tzoff) tuple into iso 8631 date."""
+ return datestr(date, format='%Y-%m-%d')
+
+def strdate(string, format, defaults=[]):
+ """parse a localized time string and return a (unixtime, offset) tuple.
+ if the string cannot be parsed, ValueError is raised."""
+ def timezone(string):
+ tz = string.split()[-1]
+ if tz[0] in "+-" and len(tz) == 5 and tz[1:].isdigit():
+ sign = (tz[0] == "+") and 1 or -1
+ hours = int(tz[1:3])
+ minutes = int(tz[3:5])
+ return -sign * (hours * 60 + minutes) * 60
+ if tz == "GMT" or tz == "UTC":
+ return 0
+ return None
+
+ # NOTE: unixtime = localunixtime + offset
+ offset, date = timezone(string), string
+ if offset != None:
+ date = " ".join(string.split()[:-1])
+
+ # add missing elements from defaults
+ for part in defaults:
+ found = [True for p in part if ("%"+p) in format]
+ if not found:
+ date += "@" + defaults[part]
+ format += "@%" + part[0]
+
+ timetuple = time.strptime(date, format)
+ localunixtime = int(calendar.timegm(timetuple))
+ if offset is None:
+ # local timezone
+ unixtime = int(time.mktime(timetuple))
+ offset = unixtime - localunixtime
+ else:
+ unixtime = localunixtime + offset
+ return unixtime, offset
+
+def parsedate(date, formats=None, defaults=None):
+ """parse a localized date/time string and return a (unixtime, offset) tuple.
+
+ The date may be a "unixtime offset" string or in one of the specified
+ formats. If the date already is a (unixtime, offset) tuple, it is returned.
+ """
+ if not date:
+ return 0, 0
+ if isinstance(date, tuple) and len(date) == 2:
+ return date
+ if not formats:
+ formats = defaultdateformats
+ date = date.strip()
+ try:
+ when, offset = map(int, date.split(' '))
+ except ValueError:
+ # fill out defaults
+ if not defaults:
+ defaults = {}
+ now = makedate()
+ for part in "d mb yY HI M S".split():
+ if part not in defaults:
+ if part[0] in "HMS":
+ defaults[part] = "00"
+ else:
+ defaults[part] = datestr(now, "%" + part[0])
+
+ for format in formats:
+ try:
+ when, offset = strdate(date, format, defaults)
+ except (ValueError, OverflowError):
+ pass
+ else:
+ break
+ else:
+ raise Abort(_('invalid date: %r ') % date)
+ # validate explicit (probably user-specified) date and
+ # time zone offset. values must fit in signed 32 bits for
+ # current 32-bit linux runtimes. timezones go from UTC-12
+ # to UTC+14
+ if abs(when) > 0x7fffffff:
+ raise Abort(_('date exceeds 32 bits: %d') % when)
+ if offset < -50400 or offset > 43200:
+ raise Abort(_('impossible time zone offset: %d') % offset)
+ return when, offset
+
+def matchdate(date):
+ """Return a function that matches a given date match specifier
+
+ Formats include:
+
+ '{date}' match a given date to the accuracy provided
+
+ '<{date}' on or before a given date
+
+ '>{date}' on or after a given date
+
+ """
+
+ def lower(date):
+ d = dict(mb="1", d="1")
+ return parsedate(date, extendeddateformats, d)[0]
+
+ def upper(date):
+ d = dict(mb="12", HI="23", M="59", S="59")
+ for days in "31 30 29".split():
+ try:
+ d["d"] = days
+ return parsedate(date, extendeddateformats, d)[0]
+ except:
+ pass
+ d["d"] = "28"
+ return parsedate(date, extendeddateformats, d)[0]
+
+ date = date.strip()
+ if date[0] == "<":
+ when = upper(date[1:])
+ return lambda x: x <= when
+ elif date[0] == ">":
+ when = lower(date[1:])
+ return lambda x: x >= when
+ elif date[0] == "-":
+ try:
+ days = int(date[1:])
+ except ValueError:
+ raise Abort(_("invalid day spec: %s") % date[1:])
+ when = makedate()[0] - days * 3600 * 24
+ return lambda x: x >= when
+ elif " to " in date:
+ a, b = date.split(" to ")
+ start, stop = lower(a), upper(b)
+ return lambda x: x >= start and x <= stop
+ else:
+ start, stop = lower(date), upper(date)
+ return lambda x: x >= start and x <= stop
+
+def shortuser(user):
+ """Return a short representation of a user name or email address."""
+ f = user.find('@')
+ if f >= 0:
+ user = user[:f]
+ f = user.find('<')
+ if f >= 0:
+ user = user[f+1:]
+ f = user.find(' ')
+ if f >= 0:
+ user = user[:f]
+ f = user.find('.')
+ if f >= 0:
+ user = user[:f]
+ return user
+
+def email(author):
+ '''get email of author.'''
+ r = author.find('>')
+ if r == -1: r = None
+ return author[author.find('<')+1:r]
+
+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])
+
+def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
+ '''yield every hg repository under path, recursively.'''
+ def errhandler(err):
+ if err.filename == path:
+ raise err
+ if followsym and hasattr(os.path, 'samestat'):
+ def _add_dir_if_not_there(dirlst, dirname):
+ match = False
+ samestat = os.path.samestat
+ dirstat = os.stat(dirname)
+ for lstdirstat in dirlst:
+ if samestat(dirstat, lstdirstat):
+ match = True
+ break
+ if not match:
+ dirlst.append(dirstat)
+ return not match
+ else:
+ followsym = False
+
+ if (seen_dirs is None) and followsym:
+ seen_dirs = []
+ _add_dir_if_not_there(seen_dirs, path)
+ for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
+ if '.hg' in dirs:
+ yield root # found a repository
+ qroot = os.path.join(root, '.hg', 'patches')
+ if os.path.isdir(os.path.join(qroot, '.hg')):
+ yield qroot # we have a patch queue repo here
+ if recurse:
+ # avoid recursing inside the .hg directory
+ dirs.remove('.hg')
+ else:
+ dirs[:] = [] # don't descend further
+ elif followsym:
+ newdirs = []
+ for d in dirs:
+ fname = os.path.join(root, d)
+ if _add_dir_if_not_there(seen_dirs, fname):
+ if os.path.islink(fname):
+ for hgname in walkrepos(fname, True, seen_dirs):
+ yield hgname
+ else:
+ newdirs.append(d)
+ dirs[:] = newdirs
+
+_rcpath = None
+
+def os_rcpath():
+ '''return default os-specific hgrc search path'''
+ path = system_rcpath()
+ path.extend(user_rcpath())
+ path = [os.path.normpath(f) for f in path]
+ return path
+
+def rcpath():
+ '''return hgrc search path. if env var HGRCPATH is set, use it.
+ for each item in path, if directory, use files ending in .rc,
+ else use item.
+ make HGRCPATH empty to only look in .hg/hgrc of current repo.
+ if no HGRCPATH, use default os-specific path.'''
+ global _rcpath
+ if _rcpath is None:
+ if 'HGRCPATH' in os.environ:
+ _rcpath = []
+ for p in os.environ['HGRCPATH'].split(os.pathsep):
+ if not p: continue
+ if os.path.isdir(p):
+ for f, kind in osutil.listdir(p):
+ if f.endswith('.rc'):
+ _rcpath.append(os.path.join(p, f))
+ else:
+ _rcpath.append(p)
+ else:
+ _rcpath = os_rcpath()
+ return _rcpath
+
+def bytecount(nbytes):
+ '''return byte count formatted as readable string, with units'''
+
+ units = (
+ (100, 1<<30, _('%.0f GB')),
+ (10, 1<<30, _('%.1f GB')),
+ (1, 1<<30, _('%.2f GB')),
+ (100, 1<<20, _('%.0f MB')),
+ (10, 1<<20, _('%.1f MB')),
+ (1, 1<<20, _('%.2f MB')),
+ (100, 1<<10, _('%.0f KB')),
+ (10, 1<<10, _('%.1f KB')),
+ (1, 1<<10, _('%.2f KB')),
+ (1, 1, _('%.0f bytes')),
+ )
+
+ for multiplier, divisor, format in units:
+ if nbytes >= divisor * multiplier:
+ return format % (nbytes / float(divisor))
+ return units[-1][2] % nbytes
+
+def drop_scheme(scheme, path):
+ sc = scheme + ':'
+ if path.startswith(sc):
+ path = path[len(sc):]
+ if path.startswith('//'):
+ path = path[2:]
+ return path
+
+def uirepr(s):
+ # Avoid double backslash in Windows path repr()
+ return repr(s).replace('\\\\', '\\')
+
+def termwidth():
+ if 'COLUMNS' in os.environ:
+ try:
+ return int(os.environ['COLUMNS'])
+ except ValueError:
+ pass
+ try:
+ import termios, array, fcntl
+ for dev in (sys.stdout, sys.stdin):
+ try:
+ try:
+ fd = dev.fileno()
+ except AttributeError:
+ continue
+ if not os.isatty(fd):
+ continue
+ arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8)
+ return array.array('h', arri)[1]
+ except ValueError:
+ pass
+ except ImportError:
+ pass
+ return 80
+
+def wrap(line, hangindent, width=None):
+ if width is None:
+ width = termwidth() - 2
+ padding = '\n' + ' ' * hangindent
+ return padding.join(textwrap.wrap(line, width=width - hangindent))
+
+def iterlines(iterator):
+ for chunk in iterator:
+ for line in chunk.splitlines():
+ yield line
diff --git a/sys/src/cmd/hg/mercurial/util.pyc b/sys/src/cmd/hg/mercurial/util.pyc
new file mode 100644
index 000000000..ea5af6dbd
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/util.pyc
Binary files differ
diff --git a/sys/src/cmd/hg/mercurial/verify.py b/sys/src/cmd/hg/mercurial/verify.py
new file mode 100644
index 000000000..17daf7662
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/verify.py
@@ -0,0 +1,258 @@
+# verify.py - repository integrity checking for Mercurial
+#
+# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from node import nullid, short
+from i18n import _
+import revlog, util, error
+
+def verify(repo):
+ lock = repo.lock()
+ try:
+ return _verify(repo)
+ finally:
+ lock.release()
+
+def _verify(repo):
+ mflinkrevs = {}
+ filelinkrevs = {}
+ filenodes = {}
+ revisions = 0
+ badrevs = set()
+ errors = [0]
+ warnings = [0]
+ ui = repo.ui
+ cl = repo.changelog
+ mf = repo.manifest
+
+ if not repo.cancopy():
+ raise util.Abort(_("cannot verify bundle or remote repos"))
+
+ def err(linkrev, msg, filename=None):
+ if linkrev != None:
+ badrevs.add(linkrev)
+ else:
+ linkrev = '?'
+ msg = "%s: %s" % (linkrev, msg)
+ if filename:
+ msg = "%s@%s" % (filename, msg)
+ ui.warn(" " + msg + "\n")
+ errors[0] += 1
+
+ def exc(linkrev, msg, inst, filename=None):
+ if isinstance(inst, KeyboardInterrupt):
+ ui.warn(_("interrupted"))
+ raise
+ err(linkrev, "%s: %s" % (msg, inst), filename)
+
+ def warn(msg):
+ ui.warn(msg + "\n")
+ warnings[0] += 1
+
+ def checklog(obj, name, linkrev):
+ if not len(obj) and (havecl or havemf):
+ err(linkrev, _("empty or missing %s") % name)
+ return
+
+ d = obj.checksize()
+ if d[0]:
+ err(None, _("data length off by %d bytes") % d[0], name)
+ if d[1]:
+ err(None, _("index contains %d extra bytes") % d[1], name)
+
+ if obj.version != revlog.REVLOGV0:
+ if not revlogv1:
+ warn(_("warning: `%s' uses revlog format 1") % name)
+ elif revlogv1:
+ warn(_("warning: `%s' uses revlog format 0") % name)
+
+ def checkentry(obj, i, node, seen, linkrevs, f):
+ lr = obj.linkrev(obj.rev(node))
+ if lr < 0 or (havecl and lr not in linkrevs):
+ if lr < 0 or lr >= len(cl):
+ msg = _("rev %d points to nonexistent changeset %d")
+ else:
+ msg = _("rev %d points to unexpected changeset %d")
+ err(None, msg % (i, lr), f)
+ if linkrevs:
+ warn(_(" (expected %s)") % " ".join(map(str, linkrevs)))
+ lr = None # can't be trusted
+
+ try:
+ p1, p2 = obj.parents(node)
+ if p1 not in seen and p1 != nullid:
+ err(lr, _("unknown parent 1 %s of %s") %
+ (short(p1), short(n)), f)
+ if p2 not in seen and p2 != nullid:
+ err(lr, _("unknown parent 2 %s of %s") %
+ (short(p2), short(p1)), f)
+ except Exception, inst:
+ exc(lr, _("checking parents of %s") % short(node), inst, f)
+
+ if node in seen:
+ err(lr, _("duplicate revision %d (%d)") % (i, seen[n]), f)
+ seen[n] = i
+ return lr
+
+ revlogv1 = cl.version != revlog.REVLOGV0
+ if ui.verbose or not revlogv1:
+ ui.status(_("repository uses revlog format %d\n") %
+ (revlogv1 and 1 or 0))
+
+ havecl = len(cl) > 0
+ havemf = len(mf) > 0
+
+ ui.status(_("checking changesets\n"))
+ seen = {}
+ checklog(cl, "changelog", 0)
+ for i in repo:
+ n = cl.node(i)
+ checkentry(cl, i, n, seen, [i], "changelog")
+
+ try:
+ changes = cl.read(n)
+ mflinkrevs.setdefault(changes[0], []).append(i)
+ for f in changes[3]:
+ filelinkrevs.setdefault(f, []).append(i)
+ except Exception, inst:
+ exc(i, _("unpacking changeset %s") % short(n), inst)
+
+ ui.status(_("checking manifests\n"))
+ seen = {}
+ checklog(mf, "manifest", 0)
+ for i in mf:
+ n = mf.node(i)
+ lr = checkentry(mf, i, n, seen, mflinkrevs.get(n, []), "manifest")
+ if n in mflinkrevs:
+ del mflinkrevs[n]
+ else:
+ err(lr, _("%s not in changesets") % short(n), "manifest")
+
+ try:
+ for f, fn in mf.readdelta(n).iteritems():
+ if not f:
+ err(lr, _("file without name in manifest"))
+ elif f != "/dev/null":
+ fns = filenodes.setdefault(f, {})
+ if fn not in fns:
+ fns[fn] = i
+ except Exception, inst:
+ exc(lr, _("reading manifest delta %s") % short(n), inst)
+
+ ui.status(_("crosschecking files in changesets and manifests\n"))
+
+ if havemf:
+ for c,m in sorted([(c, m) for m in mflinkrevs for c in mflinkrevs[m]]):
+ err(c, _("changeset refers to unknown manifest %s") % short(m))
+ mflinkrevs = None # del is bad here due to scope issues
+
+ for f in sorted(filelinkrevs):
+ if f not in filenodes:
+ lr = filelinkrevs[f][0]
+ err(lr, _("in changeset but not in manifest"), f)
+
+ if havecl:
+ for f in sorted(filenodes):
+ if f not in filelinkrevs:
+ try:
+ fl = repo.file(f)
+ lr = min([fl.linkrev(fl.rev(n)) for n in filenodes[f]])
+ except:
+ lr = None
+ err(lr, _("in manifest but not in changeset"), f)
+
+ ui.status(_("checking files\n"))
+
+ storefiles = set()
+ for f, f2, size in repo.store.datafiles():
+ if not f:
+ err(None, _("cannot decode filename '%s'") % f2)
+ elif size > 0:
+ storefiles.add(f)
+
+ files = sorted(set(filenodes) | set(filelinkrevs))
+ for f in files:
+ try:
+ linkrevs = filelinkrevs[f]
+ except KeyError:
+ # in manifest but not in changelog
+ linkrevs = []
+
+ if linkrevs:
+ lr = linkrevs[0]
+ else:
+ lr = None
+
+ try:
+ fl = repo.file(f)
+ except error.RevlogError, e:
+ err(lr, _("broken revlog! (%s)") % e, f)
+ continue
+
+ for ff in fl.files():
+ try:
+ storefiles.remove(ff)
+ except KeyError:
+ err(lr, _("missing revlog!"), ff)
+
+ checklog(fl, f, lr)
+ seen = {}
+ for i in fl:
+ revisions += 1
+ n = fl.node(i)
+ lr = checkentry(fl, i, n, seen, linkrevs, f)
+ if f in filenodes:
+ if havemf and n not in filenodes[f]:
+ err(lr, _("%s not in manifests") % (short(n)), f)
+ else:
+ del filenodes[f][n]
+
+ # verify contents
+ try:
+ t = fl.read(n)
+ rp = fl.renamed(n)
+ if len(t) != fl.size(i):
+ if len(fl.revision(n)) != fl.size(i):
+ err(lr, _("unpacked size is %s, %s expected") %
+ (len(t), fl.size(i)), f)
+ except Exception, inst:
+ exc(lr, _("unpacking %s") % short(n), inst, f)
+
+ # check renames
+ try:
+ if rp:
+ fl2 = repo.file(rp[0])
+ if not len(fl2):
+ err(lr, _("empty or missing copy source revlog %s:%s")
+ % (rp[0], short(rp[1])), f)
+ elif rp[1] == nullid:
+ ui.note(_("warning: %s@%s: copy source"
+ " revision is nullid %s:%s\n")
+ % (f, lr, rp[0], short(rp[1])))
+ else:
+ fl2.rev(rp[1])
+ except Exception, inst:
+ exc(lr, _("checking rename of %s") % short(n), inst, f)
+
+ # cross-check
+ if f in filenodes:
+ fns = [(mf.linkrev(l), n) for n,l in filenodes[f].iteritems()]
+ for lr, node in sorted(fns):
+ err(lr, _("%s in manifests not found") % short(node), f)
+
+ for f in storefiles:
+ warn(_("warning: orphan revlog '%s'") % f)
+
+ ui.status(_("%d files, %d changesets, %d total revisions\n") %
+ (len(files), len(cl), revisions))
+ if warnings[0]:
+ ui.warn(_("%d warnings encountered!\n") % warnings[0])
+ if errors[0]:
+ ui.warn(_("%d integrity errors encountered!\n") % errors[0])
+ if badrevs:
+ ui.warn(_("(first damaged changeset appears to be %d)\n")
+ % min(badrevs))
+ return 1
diff --git a/sys/src/cmd/hg/mercurial/win32.py b/sys/src/cmd/hg/mercurial/win32.py
new file mode 100644
index 000000000..08e35b011
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/win32.py
@@ -0,0 +1,144 @@
+# win32.py - utility functions that use win32 API
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+"""Utility functions that use win32 API.
+
+Mark Hammond's win32all package allows better functionality on
+Windows. This module overrides definitions in util.py. If not
+available, import of this module will fail, and generic code will be
+used.
+"""
+
+import win32api
+
+import errno, os, sys, pywintypes, win32con, win32file, win32process
+import winerror
+import osutil, encoding
+from win32com.shell import shell, shellcon
+
+def os_link(src, dst):
+ try:
+ win32file.CreateHardLink(dst, src)
+ # CreateHardLink sometimes succeeds on mapped drives but
+ # following nlinks() returns 1. Check it now and bail out.
+ if nlinks(src) < 2:
+ try:
+ win32file.DeleteFile(dst)
+ except:
+ pass
+ # Fake hardlinking error
+ raise OSError(errno.EINVAL, 'Hardlinking not supported')
+ except pywintypes.error, details:
+ raise OSError(errno.EINVAL, 'target implements hardlinks improperly')
+ except NotImplementedError: # Another fake error win Win98
+ raise OSError(errno.EINVAL, 'Hardlinking not supported')
+
+def nlinks(pathname):
+ """Return number of hardlinks for the given file."""
+ try:
+ fh = win32file.CreateFile(pathname,
+ win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
+ None, win32file.OPEN_EXISTING, 0, None)
+ res = win32file.GetFileInformationByHandle(fh)
+ fh.Close()
+ return res[7]
+ except pywintypes.error:
+ return os.lstat(pathname).st_nlink
+
+def testpid(pid):
+ '''return True if pid is still running or unable to
+ determine, False otherwise'''
+ try:
+ handle = win32api.OpenProcess(
+ win32con.PROCESS_QUERY_INFORMATION, False, pid)
+ if handle:
+ status = win32process.GetExitCodeProcess(handle)
+ return status == win32con.STILL_ACTIVE
+ except pywintypes.error, details:
+ return details[0] != winerror.ERROR_INVALID_PARAMETER
+ return True
+
+def lookup_reg(key, valname=None, scope=None):
+ ''' Look up a key/value name in the Windows registry.
+
+ valname: value name. If unspecified, the default value for the key
+ is used.
+ scope: optionally specify scope for registry lookup, this can be
+ a sequence of scopes to look up in order. Default (CURRENT_USER,
+ LOCAL_MACHINE).
+ '''
+ try:
+ from _winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, \
+ QueryValueEx, OpenKey
+ except ImportError:
+ return None
+
+ if scope is None:
+ scope = (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE)
+ elif not isinstance(scope, (list, tuple)):
+ scope = (scope,)
+ for s in scope:
+ try:
+ val = QueryValueEx(OpenKey(s, key), valname)[0]
+ # never let a Unicode string escape into the wild
+ return encoding.tolocal(val.encode('UTF-8'))
+ except EnvironmentError:
+ pass
+
+def system_rcpath_win32():
+ '''return default os-specific hgrc search path'''
+ proc = win32api.GetCurrentProcess()
+ try:
+ # This will fail on windows < NT
+ filename = win32process.GetModuleFileNameEx(proc, 0)
+ except:
+ filename = win32api.GetModuleFileName(0)
+ # Use mercurial.ini found in directory with hg.exe
+ progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
+ if os.path.isfile(progrc):
+ return [progrc]
+ # else look for a system rcpath in the registry
+ try:
+ value = win32api.RegQueryValue(
+ win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial')
+ rcpath = []
+ for p in value.split(os.pathsep):
+ if p.lower().endswith('mercurial.ini'):
+ rcpath.append(p)
+ elif os.path.isdir(p):
+ for f, kind in osutil.listdir(p):
+ if f.endswith('.rc'):
+ rcpath.append(os.path.join(p, f))
+ return rcpath
+ except pywintypes.error:
+ return []
+
+def user_rcpath_win32():
+ '''return os-specific hgrc search path to the user dir'''
+ userdir = os.path.expanduser('~')
+ if sys.getwindowsversion()[3] != 2 and userdir == '~':
+ # We are on win < nt: fetch the APPDATA directory location and use
+ # the parent directory as the user home dir.
+ appdir = shell.SHGetPathFromIDList(
+ shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
+ userdir = os.path.dirname(appdir)
+ return [os.path.join(userdir, 'mercurial.ini'),
+ os.path.join(userdir, '.hgrc')]
+
+def getuser():
+ '''return name of current user'''
+ return win32api.GetUserName()
+
+def set_signal_handler_win32():
+ """Register a termination handler for console events including
+ CTRL+C. python signal handlers do not work well with socket
+ operations.
+ """
+ def handler(event):
+ win32process.ExitProcess(1)
+ win32api.SetConsoleCtrlHandler(handler)
+
diff --git a/sys/src/cmd/hg/mercurial/windows.py b/sys/src/cmd/hg/mercurial/windows.py
new file mode 100644
index 000000000..5a903f1d6
--- /dev/null
+++ b/sys/src/cmd/hg/mercurial/windows.py
@@ -0,0 +1,292 @@
+# windows.py - Windows utility function implementations for Mercurial
+#
+# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+from i18n import _
+import osutil, error
+import errno, msvcrt, os, re, sys
+
+nulldev = 'NUL:'
+umask = 002
+
+# wrap osutil.posixfile to provide friendlier exceptions
+def posixfile(name, mode='r', buffering=-1):
+ try:
+ return osutil.posixfile(name, mode, buffering)
+ except WindowsError, err:
+ raise IOError(err.errno, err.strerror)
+posixfile.__doc__ = osutil.posixfile.__doc__
+
+class winstdout(object):
+ '''stdout on windows misbehaves if sent through a pipe'''
+
+ def __init__(self, fp):
+ self.fp = fp
+
+ def __getattr__(self, key):
+ return getattr(self.fp, key)
+
+ def close(self):
+ try:
+ self.fp.close()
+ except: pass
+
+ def write(self, s):
+ try:
+ # This is workaround for "Not enough space" error on
+ # writing large size of data to console.
+ limit = 16000
+ l = len(s)
+ start = 0
+ self.softspace = 0;
+ while start < l:
+ end = start + limit
+ self.fp.write(s[start:end])
+ start = end
+ except IOError, inst:
+ if inst.errno != 0: raise
+ self.close()
+ raise IOError(errno.EPIPE, 'Broken pipe')
+
+ def flush(self):
+ try:
+ return self.fp.flush()
+ except IOError, inst:
+ if inst.errno != errno.EINVAL: raise
+ self.close()
+ raise IOError(errno.EPIPE, 'Broken pipe')
+
+sys.stdout = winstdout(sys.stdout)
+
+def _is_win_9x():
+ '''return true if run on windows 95, 98 or me.'''
+ try:
+ return sys.getwindowsversion()[3] == 1
+ except AttributeError:
+ return 'command' in os.environ.get('comspec', '')
+
+def openhardlinks():
+ return not _is_win_9x() and "win32api" in globals()
+
+def system_rcpath():
+ try:
+ return system_rcpath_win32()
+ except:
+ return [r'c:\mercurial\mercurial.ini']
+
+def user_rcpath():
+ '''return os-specific hgrc search path to the user dir'''
+ try:
+ path = user_rcpath_win32()
+ except:
+ home = os.path.expanduser('~')
+ path = [os.path.join(home, 'mercurial.ini'),
+ os.path.join(home, '.hgrc')]
+ userprofile = os.environ.get('USERPROFILE')
+ if userprofile:
+ path.append(os.path.join(userprofile, 'mercurial.ini'))
+ path.append(os.path.join(userprofile, '.hgrc'))
+ return path
+
+def parse_patch_output(output_line):
+ """parses the output produced by patch and returns the filename"""
+ pf = output_line[14:]
+ if pf[0] == '`':
+ pf = pf[1:-1] # Remove the quotes
+ return pf
+
+def sshargs(sshcmd, host, user, port):
+ '''Build argument list for ssh or Plink'''
+ pflag = 'plink' in sshcmd.lower() and '-P' or '-p'
+ args = user and ("%s@%s" % (user, host)) or host
+ return port and ("%s %s %s" % (args, pflag, port)) or args
+
+def testpid(pid):
+ '''return False if pid dead, True if running or not known'''
+ return True
+
+def set_flags(f, l, x):
+ pass
+
+def set_binary(fd):
+ # When run without console, pipes may expose invalid
+ # fileno(), usually set to -1.
+ if hasattr(fd, 'fileno') and fd.fileno() >= 0:
+ msvcrt.setmode(fd.fileno(), os.O_BINARY)
+
+def pconvert(path):
+ return '/'.join(path.split(os.sep))
+
+def localpath(path):
+ return path.replace('/', '\\')
+
+def normpath(path):
+ return pconvert(os.path.normpath(path))
+
+def realpath(path):
+ '''
+ Returns the true, canonical file system path equivalent to the given
+ path.
+ '''
+ # TODO: There may be a more clever way to do this that also handles other,
+ # less common file systems.
+ return os.path.normpath(os.path.normcase(os.path.realpath(path)))
+
+def samestat(s1, s2):
+ return False
+
+# A sequence of backslashes is special iff it precedes a double quote:
+# - if there's an even number of backslashes, the double quote is not
+# quoted (i.e. it ends the quoted region)
+# - if there's an odd number of backslashes, the double quote is quoted
+# - in both cases, every pair of backslashes is unquoted into a single
+# backslash
+# (See http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx )
+# So, to quote a string, we must surround it in double quotes, double
+# the number of backslashes that preceed double quotes and add another
+# backslash before every double quote (being careful with the double
+# quote we've appended to the end)
+_quotere = None
+def shellquote(s):
+ global _quotere
+ if _quotere is None:
+ _quotere = re.compile(r'(\\*)("|\\$)')
+ return '"%s"' % _quotere.sub(r'\1\1\\\2', s)
+
+def quotecommand(cmd):
+ """Build a command string suitable for os.popen* calls."""
+ # The extra quotes are needed because popen* runs the command
+ # through the current COMSPEC. cmd.exe suppress enclosing quotes.
+ return '"' + cmd + '"'
+
+def popen(command, mode='r'):
+ # Work around "popen spawned process may not write to stdout
+ # under windows"
+ # http://bugs.python.org/issue1366
+ command += " 2> %s" % nulldev
+ return os.popen(quotecommand(command), mode)
+
+def explain_exit(code):
+ return _("exited with status %d") % code, code
+
+# if you change this stub into a real check, please try to implement the
+# username and groupname functions above, too.
+def isowner(st):
+ return True
+
+def find_exe(command):
+ '''Find executable for command searching like cmd.exe does.
+ If command is a basename then PATH is searched for command.
+ PATH isn't searched if command is an absolute or relative path.
+ An extension from PATHEXT is found and added if not present.
+ If command isn't found None is returned.'''
+ pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD')
+ pathexts = [ext for ext in pathext.lower().split(os.pathsep)]
+ if os.path.splitext(command)[1].lower() in pathexts:
+ pathexts = ['']
+
+ def findexisting(pathcommand):
+ 'Will append extension (if needed) and return existing file'
+ for ext in pathexts:
+ executable = pathcommand + ext
+ if os.path.exists(executable):
+ return executable
+ return None
+
+ if os.sep in command:
+ return findexisting(command)
+
+ for path in os.environ.get('PATH', '').split(os.pathsep):
+ executable = findexisting(os.path.join(path, command))
+ if executable is not None:
+ return executable
+ return None
+
+def set_signal_handler():
+ try:
+ set_signal_handler_win32()
+ except NameError:
+ pass
+
+def statfiles(files):
+ '''Stat each file in files and yield stat or None if file does not exist.
+ Cluster and cache stat per directory to minimize number of OS stat calls.'''
+ ncase = os.path.normcase
+ sep = os.sep
+ dircache = {} # dirname -> filename -> status | None if file does not exist
+ for nf in files:
+ nf = ncase(nf)
+ dir, base = os.path.split(nf)
+ if not dir:
+ dir = '.'
+ cache = dircache.get(dir, None)
+ if cache is None:
+ try:
+ dmap = dict([(ncase(n), s)
+ for n, k, s in osutil.listdir(dir, True)])
+ except OSError, err:
+ # handle directory not found in Python version prior to 2.5
+ # Python <= 2.4 returns native Windows code 3 in errno
+ # Python >= 2.5 returns ENOENT and adds winerror field
+ # EINVAL is raised if dir is not a directory.
+ if err.errno not in (3, errno.ENOENT, errno.EINVAL,
+ errno.ENOTDIR):
+ raise
+ dmap = {}
+ cache = dircache.setdefault(dir, dmap)
+ yield cache.get(base, None)
+
+def getuser():
+ '''return name of current user'''
+ raise error.Abort(_('user name not available - set USERNAME '
+ 'environment variable'))
+
+def username(uid=None):
+ """Return the name of the user with the given uid.
+
+ If uid is None, return the name of the current user."""
+ return None
+
+def groupname(gid=None):
+ """Return the name of the group with the given gid.
+
+ If gid is None, return the name of the current group."""
+ return None
+
+def _removedirs(name):
+ """special version of os.removedirs that does not remove symlinked
+ directories or junction points if they actually contain files"""
+ if osutil.listdir(name):
+ return
+ os.rmdir(name)
+ head, tail = os.path.split(name)
+ if not tail:
+ head, tail = os.path.split(head)
+ while head and tail:
+ try:
+ if osutil.listdir(name):
+ return
+ os.rmdir(head)
+ except:
+ break
+ head, tail = os.path.split(head)
+
+def unlink(f):
+ """unlink and remove the directory if it is empty"""
+ os.unlink(f)
+ # try removing directories that might now be empty
+ try:
+ _removedirs(os.path.dirname(f))
+ except OSError:
+ pass
+
+try:
+ # override functions with win32 versions if possible
+ from win32 import *
+except ImportError:
+ pass
+
+expandglobs = True
diff --git a/sys/src/cmd/hg/mkfile b/sys/src/cmd/hg/mkfile
new file mode 100644
index 000000000..e71f8d4c8
--- /dev/null
+++ b/sys/src/cmd/hg/mkfile
@@ -0,0 +1,17 @@
+default:V: none
+
+all clean nuke install installall:V:
+ echo nothing to be done
+
+none:VQ:
+ echo mk setup
+
+setup:V:
+ mkdir -p /sys/src/cmd/python/Extra/mercurial
+ cp mercurial/*.c /sys/src/cmd/python/Extra/mercurial
+ for(i in mercurial hgext){
+ mkdir -p /sys/lib/python/$i
+ dircp mercurial /sys/lib/python/$i
+ }
+ cp hg /rc/bin/hg
+ echo Now rebuild python!
diff --git a/sys/src/cmd/hg/setup.py b/sys/src/cmd/hg/setup.py
new file mode 100644
index 000000000..8a17333fd
--- /dev/null
+++ b/sys/src/cmd/hg/setup.py
@@ -0,0 +1,273 @@
+#!/usr/bin/env python
+#
+# This is the mercurial setup script.
+#
+# 'python setup.py install', or
+# 'python setup.py --help' for more options
+
+import sys
+if not hasattr(sys, 'version_info') or sys.version_info < (2, 4, 0, 'final'):
+ raise SystemExit("Mercurial requires Python 2.4 or later.")
+
+# Solaris Python packaging brain damage
+try:
+ import hashlib
+ sha = hashlib.sha1()
+except:
+ try:
+ import sha
+ except:
+ raise SystemExit(
+ "Couldn't import standard hashlib (incomplete Python install).")
+
+try:
+ import zlib
+except:
+ raise SystemExit(
+ "Couldn't import standard zlib (incomplete Python install).")
+
+import os, subprocess, time
+import shutil
+import tempfile
+from distutils.core import setup, Extension
+from distutils.dist import Distribution
+from distutils.command.install_data import install_data
+from distutils.command.build import build
+from distutils.command.build_py import build_py
+from distutils.spawn import spawn, find_executable
+from distutils.ccompiler import new_compiler
+
+extra = {}
+scripts = ['hg']
+if os.name == 'nt':
+ scripts.append('contrib/win32/hg.bat')
+
+# simplified version of distutils.ccompiler.CCompiler.has_function
+# that actually removes its temporary files.
+def has_function(cc, funcname):
+ tmpdir = tempfile.mkdtemp(prefix='hg-install-')
+ devnull = oldstderr = None
+ try:
+ try:
+ fname = os.path.join(tmpdir, 'funcname.c')
+ f = open(fname, 'w')
+ f.write('int main(void) {\n')
+ f.write(' %s();\n' % funcname)
+ f.write('}\n')
+ f.close()
+ # Redirect stderr to /dev/null to hide any error messages
+ # from the compiler.
+ # This will have to be changed if we ever have to check
+ # for a function on Windows.
+ devnull = open('/dev/null', 'w')
+ oldstderr = os.dup(sys.stderr.fileno())
+ os.dup2(devnull.fileno(), sys.stderr.fileno())
+ objects = cc.compile([fname], output_dir=tmpdir)
+ cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
+ except:
+ return False
+ return True
+ finally:
+ if oldstderr is not None:
+ os.dup2(oldstderr, sys.stderr.fileno())
+ if devnull is not None:
+ devnull.close()
+ shutil.rmtree(tmpdir)
+
+# py2exe needs to be installed to work
+try:
+ import py2exe
+
+ # Help py2exe to find win32com.shell
+ try:
+ import modulefinder
+ import win32com
+ for p in win32com.__path__[1:]: # Take the path to win32comext
+ modulefinder.AddPackagePath("win32com", p)
+ pn = "win32com.shell"
+ __import__(pn)
+ m = sys.modules[pn]
+ for p in m.__path__[1:]:
+ modulefinder.AddPackagePath(pn, p)
+ except ImportError:
+ pass
+
+ extra['console'] = ['hg']
+
+except ImportError:
+ pass
+
+version = None
+
+if os.path.isdir('.hg'):
+ # Execute hg out of this directory with a custom environment which
+ # includes the pure Python modules in mercurial/pure. We also take
+ # care to not use any hgrc files and do no localization.
+ pypath = ['mercurial', os.path.join('mercurial', 'pure')]
+ env = {'PYTHONPATH': os.pathsep.join(pypath),
+ 'HGRCPATH': '',
+ 'LANGUAGE': 'C'}
+ if 'SystemRoot' in os.environ:
+ # Copy SystemRoot into the custom environment for Python 2.6
+ # under Windows. Otherwise, the subprocess will fail with
+ # error 0xc0150004. See: http://bugs.python.org/issue3440
+ env['SystemRoot'] = os.environ['SystemRoot']
+ cmd = [sys.executable, 'hg', 'id', '-i', '-t']
+
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=env)
+ out, err = p.communicate()
+
+ # If root is executing setup.py, but the repository is owned by
+ # another user (as in "sudo python setup.py install") we will get
+ # trust warnings since the .hg/hgrc file is untrusted. That is
+ # fine, we don't want to load it anyway.
+ err = [e for e in err.splitlines()
+ if not e.startswith('Not trusting file')]
+ if err:
+ sys.stderr.write('warning: could not establish Mercurial '
+ 'version:\n%s\n' % '\n'.join(err))
+ else:
+ l = out.split()
+ while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
+ l.pop()
+ if l:
+ version = l[-1] # latest tag or revision number
+ if version.endswith('+'):
+ version += time.strftime('%Y%m%d')
+elif os.path.exists('.hg_archival.txt'):
+ hgarchival = open('.hg_archival.txt')
+ for line in hgarchival:
+ if line.startswith('node:'):
+ version = line.split(':')[1].strip()[:12]
+ break
+
+if version:
+ f = open("mercurial/__version__.py", "w")
+ f.write('# this file is autogenerated by setup.py\n')
+ f.write('version = "%s"\n' % version)
+ f.close()
+
+
+try:
+ from mercurial import __version__
+ version = __version__.version
+except ImportError:
+ version = 'unknown'
+
+class install_package_data(install_data):
+ def finalize_options(self):
+ self.set_undefined_options('install',
+ ('install_lib', 'install_dir'))
+ install_data.finalize_options(self)
+
+class build_mo(build):
+
+ description = "build translations (.mo files)"
+
+ def run(self):
+ if not find_executable('msgfmt'):
+ self.warn("could not find msgfmt executable, no translations "
+ "will be built")
+ return
+
+ podir = 'i18n'
+ if not os.path.isdir(podir):
+ self.warn("could not find %s/ directory" % podir)
+ return
+
+ join = os.path.join
+ for po in os.listdir(podir):
+ if not po.endswith('.po'):
+ continue
+ pofile = join(podir, po)
+ modir = join('locale', po[:-3], 'LC_MESSAGES')
+ mofile = join(modir, 'hg.mo')
+ cmd = ['msgfmt', '-v', '-o', mofile, pofile]
+ if sys.platform != 'sunos5':
+ # msgfmt on Solaris does not know about -c
+ cmd.append('-c')
+ self.mkpath(modir)
+ self.make_file([pofile], mofile, spawn, (cmd,))
+ self.distribution.data_files.append((join('mercurial', modir),
+ [mofile]))
+
+build.sub_commands.append(('build_mo', None))
+
+Distribution.pure = 0
+Distribution.global_options.append(('pure', None, "use pure (slow) Python "
+ "code instead of C extensions"))
+
+class hg_build_py(build_py):
+
+ def finalize_options(self):
+ build_py.finalize_options(self)
+
+ if self.distribution.pure:
+ if self.py_modules is None:
+ self.py_modules = []
+ for ext in self.distribution.ext_modules:
+ if ext.name.startswith("mercurial."):
+ self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
+ self.distribution.ext_modules = []
+
+ def find_modules(self):
+ modules = build_py.find_modules(self)
+ for module in modules:
+ if module[0] == "mercurial.pure":
+ if module[1] != "__init__":
+ yield ("mercurial", module[1], module[2])
+ else:
+ yield module
+
+cmdclass = {'install_data': install_package_data,
+ 'build_mo': build_mo,
+ 'build_py': hg_build_py}
+
+ext_modules=[
+ Extension('mercurial.base85', ['mercurial/base85.c']),
+ Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
+ Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
+ Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
+ Extension('mercurial.parsers', ['mercurial/parsers.c']),
+ Extension('mercurial.osutil', ['mercurial/osutil.c']),
+ ]
+
+packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
+ 'hgext.highlight', 'hgext.zeroconf', ]
+
+if sys.platform == 'linux2' and os.uname()[2] > '2.6':
+ # The inotify extension is only usable with Linux 2.6 kernels.
+ # You also need a reasonably recent C library.
+ cc = new_compiler()
+ if has_function(cc, 'inotify_add_watch'):
+ ext_modules.append(Extension('hgext.inotify.linux._inotify',
+ ['hgext/inotify/linux/_inotify.c']))
+ packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
+
+datafiles = []
+for root in ('templates', 'i18n'):
+ for dir, dirs, files in os.walk(root):
+ dirs[:] = [x for x in dirs if not x.startswith('.')]
+ files = [x for x in files if not x.startswith('.')]
+ datafiles.append((os.path.join('mercurial', dir),
+ [os.path.join(dir, file_) for file_ in files]))
+
+setup(name='mercurial',
+ version=version,
+ author='Matt Mackall',
+ author_email='mpm@selenic.com',
+ url='http://mercurial.selenic.com/',
+ description='Scalable distributed SCM',
+ license='GNU GPL',
+ scripts=scripts,
+ packages=packages,
+ ext_modules=ext_modules,
+ data_files=datafiles,
+ cmdclass=cmdclass,
+ options=dict(py2exe=dict(packages=['hgext', 'email']),
+ bdist_mpkg=dict(zipdist=True,
+ license='COPYING',
+ readme='contrib/macosx/Readme.html',
+ welcome='contrib/macosx/Welcome.html')),
+ **extra)
diff --git a/sys/src/cmd/hg/templates/atom/changelog.tmpl b/sys/src/cmd/hg/templates/atom/changelog.tmpl
new file mode 100644
index 000000000..29902ab21
--- /dev/null
+++ b/sys/src/cmd/hg/templates/atom/changelog.tmpl
@@ -0,0 +1,10 @@
+{header}
+ <!-- Changelog -->
+ <id>{urlbase}{url}</id>
+ <link rel="self" href="{urlbase}{url}atom-log"/>
+ <link rel="alternate" href="{urlbase}{url}"/>
+ <title>{repo|escape} Changelog</title>
+ {latestentry%feedupdated}
+
+{entries%changelogentry}
+</feed>
diff --git a/sys/src/cmd/hg/templates/atom/changelogentry.tmpl b/sys/src/cmd/hg/templates/atom/changelogentry.tmpl
new file mode 100644
index 000000000..02c2e9bd0
--- /dev/null
+++ b/sys/src/cmd/hg/templates/atom/changelogentry.tmpl
@@ -0,0 +1,16 @@
+ <entry>
+ <title>{desc|strip|firstline|strip|escape|nonempty}</title>
+ <id>{urlbase}{url}#changeset-{node}</id>
+ <link href="{urlbase}{url}rev/{node}"/>
+ <author>
+ <name>{author|person|escape}</name>
+ <email>{author|email|obfuscate}</email>
+ </author>
+ <updated>{date|rfc3339date}</updated>
+ <published>{date|rfc3339date}</published>
+ <content type="xhtml">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ <pre xml:space="preserve">{desc|escape|nonempty}</pre>
+ </div>
+ </content>
+ </entry>
diff --git a/sys/src/cmd/hg/templates/atom/error.tmpl b/sys/src/cmd/hg/templates/atom/error.tmpl
new file mode 100644
index 000000000..5735fbab5
--- /dev/null
+++ b/sys/src/cmd/hg/templates/atom/error.tmpl
@@ -0,0 +1,17 @@
+{header}
+ <!-- Error -->
+ <id>{urlbase}{url}</id>
+ <link rel="self" href="{urlbase}{url}atom-log"/>
+ <link rel="alternate" href="{urlbase}{url}"/>
+ <title>Error</title>
+ <updated>1970-01-01T00:00:00+00:00</updated>
+ <entry>
+ <title>Error</title>
+ <id>http://mercurial.selenic.com/#error</id>
+ <author>
+ <name>mercurial</name>
+ </author>
+ <updated>1970-01-01T00:00:00+00:00</updated>
+ <content type="text">{error|escape}</content>
+ </entry>
+</feed>
diff --git a/sys/src/cmd/hg/templates/atom/filelog.tmpl b/sys/src/cmd/hg/templates/atom/filelog.tmpl
new file mode 100644
index 000000000..99d4e9b89
--- /dev/null
+++ b/sys/src/cmd/hg/templates/atom/filelog.tmpl
@@ -0,0 +1,8 @@
+{header}
+ <id>{urlbase}{url}atom-log/tip/{file|escape}</id>
+ <link rel="self" href="{urlbase}{url}atom-log/tip/{file|urlescape}"/>
+ <title>{repo|escape}: {file|escape} history</title>
+ {latestentry%feedupdated}
+
+{entries%changelogentry}
+</feed>
diff --git a/sys/src/cmd/hg/templates/atom/header.tmpl b/sys/src/cmd/hg/templates/atom/header.tmpl
new file mode 100644
index 000000000..90ffceb77
--- /dev/null
+++ b/sys/src/cmd/hg/templates/atom/header.tmpl
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="{encoding}"?>
+<feed xmlns="http://www.w3.org/2005/Atom"> \ No newline at end of file
diff --git a/sys/src/cmd/hg/templates/atom/map b/sys/src/cmd/hg/templates/atom/map
new file mode 100644
index 000000000..c016b5590
--- /dev/null
+++ b/sys/src/cmd/hg/templates/atom/map
@@ -0,0 +1,11 @@
+default = 'changelog'
+feedupdated = '<updated>{date|rfc3339date}</updated>'
+mimetype = 'application/atom+xml; charset={encoding}'
+header = header.tmpl
+changelog = changelog.tmpl
+changelogentry = changelogentry.tmpl
+filelog = filelog.tmpl
+filelogentry = filelogentry.tmpl
+tags = tags.tmpl
+tagentry = tagentry.tmpl
+error = error.tmpl
diff --git a/sys/src/cmd/hg/templates/atom/tagentry.tmpl b/sys/src/cmd/hg/templates/atom/tagentry.tmpl
new file mode 100644
index 000000000..776d8a948
--- /dev/null
+++ b/sys/src/cmd/hg/templates/atom/tagentry.tmpl
@@ -0,0 +1,8 @@
+ <entry>
+ <title>{tag|escape}</title>
+ <link rel="alternate" href="{urlbase}{url}rev/{node}"/>
+ <id>{urlbase}{url}#tag-{node}</id>
+ <updated>{date|rfc3339date}</updated>
+ <published>{date|rfc3339date}</published>
+ <content type="text">{tag|strip|escape}</content>
+ </entry>
diff --git a/sys/src/cmd/hg/templates/atom/tags.tmpl b/sys/src/cmd/hg/templates/atom/tags.tmpl
new file mode 100644
index 000000000..82294ecb8
--- /dev/null
+++ b/sys/src/cmd/hg/templates/atom/tags.tmpl
@@ -0,0 +1,11 @@
+{header}
+ <id>{urlbase}{url}</id>
+ <link rel="self" href="{urlbase}{url}atom-tags"/>
+ <link rel="alternate" href="{urlbase}{url}tags"/>
+ <title>{repo|escape}: tags</title>
+ <summary>{repo|escape} tag history</summary>
+ <author><name>Mercurial SCM</name></author>
+ {latestentry%feedupdated}
+
+{entriesnotip%tagentry}
+</feed>
diff --git a/sys/src/cmd/hg/templates/coal/header.tmpl b/sys/src/cmd/hg/templates/coal/header.tmpl
new file mode 100644
index 000000000..ed0f42d38
--- /dev/null
+++ b/sys/src/cmd/hg/templates/coal/header.tmpl
@@ -0,0 +1,6 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+<head>
+<link rel="icon" href="{staticurl}hgicon.png" type="image/png" />
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="{staticurl}style-coal.css" type="text/css" />
diff --git a/sys/src/cmd/hg/templates/coal/map b/sys/src/cmd/hg/templates/coal/map
new file mode 100644
index 000000000..430580b6c
--- /dev/null
+++ b/sys/src/cmd/hg/templates/coal/map
@@ -0,0 +1,191 @@
+default = 'shortlog'
+
+mimetype = 'text/html; charset={encoding}'
+header = header.tmpl
+footer = ../paper/footer.tmpl
+search = ../paper/search.tmpl
+
+changelog = ../paper/shortlog.tmpl
+shortlog = ../paper/shortlog.tmpl
+shortlogentry = ../paper/shortlogentry.tmpl
+graph = ../paper/graph.tmpl
+
+naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
+filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenolink = '{file|escape} '
+fileellipses = '...'
+changelogentry = ../paper/shortlogentry.tmpl
+searchentry = ../paper/shortlogentry.tmpl
+changeset = ../paper/changeset.tmpl
+manifest = ../paper/manifest.tmpl
+
+direntry = '
+ <tr class="fileline parity{parity}">
+ <td class="name">
+ <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">
+ <img src="{staticurl}coal-folder.png" alt="dir."/> {basename|escape}/
+ </a>
+ <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
+ {emptydirs|escape}
+ </a>
+ </td>
+ <td class="size"></td>
+ <td class="permissions">drwxr-xr-x</td>
+ </tr>'
+
+fileentry = '
+ <tr class="fileline parity{parity}">
+ <td class="filename">
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ <img src="{staticurl}coal-file.png" alt="file"/> {basename|escape}
+ </a>
+ </td>
+ <td class="size">{size}</td>
+ <td class="permissions">{permissions|permissions}</td>
+ </tr>'
+
+filerevision = ../paper/filerevision.tmpl
+fileannotate = ../paper/fileannotate.tmpl
+filediff = ../paper/filediff.tmpl
+filelog = ../paper/filelog.tmpl
+fileline = '
+ <div class="parity{parity} source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</div>'
+filelogentry = ../paper/filelogentry.tmpl
+
+annotateline = '
+ <tr class="parity{parity}">
+ <td class="annotate">
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#{targetline}"
+ title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
+ </td>
+ <td class="source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</td>
+ </tr>'
+
+diffblock = '<div class="source bottomline parity{parity}"><pre>{lines}</pre></div>'
+difflineplus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="plusline">{line|escape}</span>'
+difflineminus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="minusline">{line|escape}</span>'
+difflineat = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="atline">{line|escape}</span>'
+diffline = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}'
+
+changelogparent = '
+ <tr>
+ <th class="parent">parent {rev}:</th>
+ <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+
+changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
+
+filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
+filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
+
+filerename = '{file|escape}@'
+filelogrename = '
+ <tr>
+ <th>base:</th>
+ <td>
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {file|escape}@{node|short}
+ </a>
+ </td>
+ </tr>'
+fileannotateparent = '
+ <tr>
+ <td class="metatag">parent:</td>
+ <td>
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {rename%filerename}{node|short}
+ </a>
+ </td>
+ </tr>'
+changesetchild = ' <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
+changelogchild = '
+ <tr>
+ <th class="child">child</th>
+ <td class="child">
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
+ {node|short}
+ </a>
+ </td>
+ </tr>'
+fileannotatechild = '
+ <tr>
+ <td class="metatag">child:</td>
+ <td>
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {node|short}
+ </a>
+ </td>
+ </tr>'
+tags = ../paper/tags.tmpl
+tagentry = '
+ <tr class="tagEntry parity{parity}">
+ <td>
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
+ {tag|escape}
+ </a>
+ </td>
+ <td class="node">
+ {node|short}
+ </td>
+ </tr>'
+branches = ../paper/branches.tmpl
+branchentry = '
+ <tr class="tagEntry parity{parity}">
+ <td>
+ <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
+ {branch|escape}
+ </a>
+ </td>
+ <td class="node">
+ {node|short}
+ </td>
+ </tr>'
+changelogtag = '<span class="tag">{name|escape}</span> '
+changesettag = '<span class="tag">{tag|escape}</span> '
+changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
+changelogbranchname = '<span class="branchname">{name|escape}</span> '
+
+filediffparent = '
+ <tr>
+ <th class="parent">parent {rev}:</th>
+ <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filelogparent = '
+ <tr>
+ <th>parent {rev}:</th>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filediffchild = '
+ <tr>
+ <th class="child">child {rev}:</th>
+ <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ </td>
+ </tr>'
+filelogchild = '
+ <tr>
+ <th>child {rev}:</th>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+
+indexentry = '
+ <tr class="parity{parity}">
+ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
+ <td>{description}</td>
+ <td>{contact|obfuscate}</td>
+ <td class="age">{lastchange|age} ago</td>
+ <td class="indexlinks">{archives%indexarchiveentry}</td>
+ </tr>\n'
+indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
+index = ../paper/index.tmpl
+archiveentry = '
+ <li>
+ <a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a>
+ </li>'
+notfound = ../paper/notfound.tmpl
+error = ../paper/error.tmpl
+urlparameter = '{separator}{name}={value|urlescape}'
+hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
diff --git a/sys/src/cmd/hg/templates/gitweb/branches.tmpl b/sys/src/cmd/hg/templates/gitweb/branches.tmpl
new file mode 100644
index 000000000..80ceb7e0b
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/branches.tmpl
@@ -0,0 +1,30 @@
+{header}
+<title>{repo|escape}: Branches</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-tags" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-tags" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / branches
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+branches |
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+<br/>
+</div>
+
+<div class="title">&nbsp;</div>
+<table cellspacing="0">
+{entries%branchentry}
+</table>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/changelog.tmpl b/sys/src/cmd/hg/templates/gitweb/changelog.tmpl
new file mode 100644
index 000000000..2b587a244
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/changelog.tmpl
@@ -0,0 +1,39 @@
+{header}
+<title>{repo|escape}: Changelog</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / changelog
+</div>
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<div class="search">
+<input type="text" name="rev" />
+</div>
+</form>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog/{rev}{sessionvars%urlparameter}">shortlog</a> |
+changelog |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>{archives%archiveentry}
+<br/>
+{changenav%naventry}<br/>
+</div>
+
+{entries%changelogentry}
+
+<div class="page_nav">
+{changenav%naventry}<br/>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/changelogentry.tmpl b/sys/src/cmd/hg/templates/gitweb/changelogentry.tmpl
new file mode 100644
index 000000000..2a7c3cb25
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/changelogentry.tmpl
@@ -0,0 +1,14 @@
+<div>
+<a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}"><span class="age">{date|age} ago</span>{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a>
+</div>
+<div class="title_text">
+<div class="log_link">
+<a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a><br/>
+</div>
+<i>{author|obfuscate} [{date|rfc822date}] rev {rev}</i><br/>
+</div>
+<div class="log_body">
+{desc|strip|escape|addbreaks|nonempty}
+<br/>
+<br/>
+</div>
diff --git a/sys/src/cmd/hg/templates/gitweb/changeset.tmpl b/sys/src/cmd/hg/templates/gitweb/changeset.tmpl
new file mode 100644
index 000000000..2487dd66e
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/changeset.tmpl
@@ -0,0 +1,50 @@
+{header}
+<title>{repo|escape}: changeset {rev}:{node|short}</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / changeset
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog/{rev}{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a> |
+changeset |
+<a href="{url}raw-rev/{node|short}">raw</a> {archives%archiveentry}<br/>
+</div>
+
+<div>
+<a class="title" href="{url}raw-rev/{node|short}">{desc|strip|escape|firstline|nonempty} <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a>
+</div>
+<div class="title_text">
+<table cellspacing="0">
+<tr><td>author</td><td>{author|obfuscate}</td></tr>
+<tr><td></td><td>{date|date} ({date|age} ago)</td></tr>
+{branch%changesetbranch}
+<tr><td>changeset {rev}</td><td style="font-family:monospace">{node|short}</td></tr>
+{parent%changesetparent}
+{child%changesetchild}
+</table></div>
+
+<div class="page_body">
+{desc|strip|escape|addbreaks|nonempty}
+</div>
+<div class="list_head"></div>
+<div class="title_text">
+<table cellspacing="0">
+{files}
+</table></div>
+
+<div class="page_body">{diff}</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/error.tmpl b/sys/src/cmd/hg/templates/gitweb/error.tmpl
new file mode 100644
index 000000000..25b71fc3a
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/error.tmpl
@@ -0,0 +1,25 @@
+{header}
+<title>{repo|escape}: Error</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / error
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> | <a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> | <a href="{url}log{sessionvars%urlparameter}">changelog</a> | <a href="{url}tags{sessionvars%urlparameter}">tags</a> | <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a><br/>
+</div>
+
+<div class="page_body">
+<br/>
+<i>An error occurred while processing your request</i><br/>
+<br/>
+{error|escape}
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/fileannotate.tmpl b/sys/src/cmd/hg/templates/gitweb/fileannotate.tmpl
new file mode 100644
index 000000000..87e8cc316
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/fileannotate.tmpl
@@ -0,0 +1,61 @@
+{header}
+<title>{repo|escape}: {file|escape}@{node|short} (annotated)</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / annotate
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a> |
+<a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
+<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
+<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
+annotate |
+<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
+<a href="{url}raw-annotate/{node|short}/{file|urlescape}">raw</a><br/>
+</div>
+
+<div class="title">{file|escape}</div>
+
+<div class="title_text">
+<table cellspacing="0">
+<tr>
+ <td>author</td>
+ <td>{author|obfuscate}</td></tr>
+<tr>
+ <td></td>
+ <td>{date|date} ({date|age} ago)</td></tr>
+{branch%filerevbranch}
+<tr>
+ <td>changeset {rev}</td>
+ <td style="font-family:monospace"><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>
+{parent%fileannotateparent}
+{child%fileannotatechild}
+<tr>
+ <td>permissions</td>
+ <td style="font-family:monospace">{permissions|permissions}</td></tr>
+</table>
+</div>
+
+<div class="page_path">
+{desc|strip|escape|addbreaks|nonempty}
+</div>
+<div class="page_body">
+<table>
+{annotate%annotateline}
+</table>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/filediff.tmpl b/sys/src/cmd/hg/templates/gitweb/filediff.tmpl
new file mode 100644
index 000000000..967d79098
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/filediff.tmpl
@@ -0,0 +1,47 @@
+{header}
+<title>{repo|escape}: diff {file|escape}</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / diff
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a> |
+<a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
+<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
+<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
+<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
+diff |
+<a href="{url}raw-diff/{node|short}/{file|urlescape}">raw</a><br/>
+</div>
+
+<div class="title">{file|escape}</div>
+
+<table>
+{branch%filerevbranch}
+<tr>
+ <td>changeset {rev}</td>
+ <td style="font-family:monospace"><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>
+{parent%filediffparent}
+{child%filediffchild}
+</table>
+
+<div class="list_head"></div>
+
+<div class="page_body">
+{diff}
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/filelog.tmpl b/sys/src/cmd/hg/templates/gitweb/filelog.tmpl
new file mode 100644
index 000000000..50f36c8eb
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/filelog.tmpl
@@ -0,0 +1,40 @@
+{header}
+<title>{repo|escape}: File revisions</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file revisions
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
+revisions |
+<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
+<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
+<a href="{url}rss-log/{node|short}/{file|urlescape}">rss</a>
+<br/>
+{nav%filenaventry}
+</div>
+
+<div class="title" >{file|urlescape}</div>
+
+<table>
+{entries%filelogentry}
+</table>
+
+<div class="page_nav">
+{nav%filenaventry}
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/filerevision.tmpl b/sys/src/cmd/hg/templates/gitweb/filerevision.tmpl
new file mode 100644
index 000000000..d64c632af
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/filerevision.tmpl
@@ -0,0 +1,60 @@
+{header}
+<title>{repo|escape}: {file|escape}@{node|short}</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file revision
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a> |
+<a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
+file |
+<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
+<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
+<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
+<a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a><br/>
+</div>
+
+<div class="title">{file|escape}</div>
+
+<div class="title_text">
+<table cellspacing="0">
+<tr>
+ <td>author</td>
+ <td>{author|obfuscate}</td></tr>
+<tr>
+ <td></td>
+ <td>{date|date} ({date|age} ago)</td></tr>
+{branch%filerevbranch}
+<tr>
+ <td>changeset {rev}</td>
+ <td style="font-family:monospace"><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>
+{parent%filerevparent}
+{child%filerevchild}
+<tr>
+ <td>permissions</td>
+ <td style="font-family:monospace">{permissions|permissions}</td></tr>
+</table>
+</div>
+
+<div class="page_path">
+{desc|strip|escape|addbreaks|nonempty}
+</div>
+
+<div class="page_body">
+{text%fileline}
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/footer.tmpl b/sys/src/cmd/hg/templates/gitweb/footer.tmpl
new file mode 100644
index 000000000..a5f74c38d
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/footer.tmpl
@@ -0,0 +1,11 @@
+<div class="page_footer">
+<div class="page_footer_text">{repo|escape}</div>
+<div class="rss_logo">
+<a href="{url}rss-log">RSS</a>
+<a href="{url}atom-log">Atom</a>
+</div>
+<br />
+{motd}
+</div>
+</body>
+</html>
diff --git a/sys/src/cmd/hg/templates/gitweb/graph.tmpl b/sys/src/cmd/hg/templates/gitweb/graph.tmpl
new file mode 100644
index 000000000..52b399ae5
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/graph.tmpl
@@ -0,0 +1,121 @@
+{header}
+<title>{repo|escape}: Graph</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+<!--[if IE]><script type="text/javascript" src="{staticurl}excanvas.js"></script><![endif]-->
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / graph
+</div>
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<div class="search">
+<input type="text" name="rev" />
+</div>
+</form>
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a> |
+graph |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+<br/>
+<a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
+<a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
+| {changenav%navgraphentry}<br/>
+</div>
+
+<div class="title">&nbsp;</div>
+
+<noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
+
+<div id="wrapper">
+<ul id="nodebgs"></ul>
+<canvas id="graph" width="224" height="{canvasheight}"></canvas>
+<ul id="graphnodes"></ul>
+</div>
+
+<script type="text/javascript" src="{staticurl}graph.js"></script>
+<script>
+<!-- hide script content
+
+var data = {jsdata|json};
+var graph = new Graph();
+graph.scale({bg_height});
+
+graph.edge = function(x0, y0, x1, y1, color) {
+
+ this.setColor(color, 0.0, 0.65);
+ this.ctx.beginPath();
+ this.ctx.moveTo(x0, y0);
+ this.ctx.lineTo(x1, y1);
+ this.ctx.stroke();
+
+}
+
+var revlink = '<li style="_STYLE"><span class="desc">';
+revlink += '<a class="list" href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID"><b>_DESC</b></a>';
+revlink += '</span> _TAGS';
+revlink += '<span class="info">_DATE ago, by _USER</span></li>';
+
+graph.vertex = function(x, y, color, parity, cur) {
+
+ this.ctx.beginPath();
+ color = this.setColor(color, 0.25, 0.75);
+ this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
+ this.ctx.fill();
+
+ var bg = '<li class="bg parity' + parity + '"></li>';
+ var left = (this.columns + 1) * this.bg_height;
+ var nstyle = 'padding-left: ' + left + 'px;';
+ var item = revlink.replace(/_STYLE/, nstyle);
+ item = item.replace(/_PARITY/, 'parity' + parity);
+ item = item.replace(/_NODEID/, cur[0]);
+ item = item.replace(/_NODEID/, cur[0]);
+ item = item.replace(/_DESC/, cur[3]);
+ item = item.replace(/_USER/, cur[4]);
+ item = item.replace(/_DATE/, cur[5]);
+
+ var tagspan = '';
+ if (cur[7].length || (cur[6][0] != 'default' || cur[6][1])) {
+ tagspan = '<span class="logtags">';
+ if (cur[6][1]) {
+ tagspan += '<span class="branchtag" title="' + cur[6][0] + '">';
+ tagspan += cur[6][0] + '</span> ';
+ } else if (!cur[6][1] && cur[6][0] != 'default') {
+ tagspan += '<span class="inbranchtag" title="' + cur[6][0] + '">';
+ tagspan += cur[6][0] + '</span> ';
+ }
+ if (cur[7].length) {
+ for (var t in cur[7]) {
+ var tag = cur[7][t];
+ tagspan += '<span class="tagtag">' + tag + '</span> ';
+ }
+ }
+ tagspan += '</span>';
+ }
+
+ item = item.replace(/_TAGS/, tagspan);
+ return [bg, item];
+
+}
+
+graph.render(data);
+
+// stop hiding script -->
+</script>
+
+<div class="page_nav">
+<a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
+<a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
+| {changenav%navgraphentry}
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/header.tmpl b/sys/src/cmd/hg/templates/gitweb/header.tmpl
new file mode 100644
index 000000000..f3df3d7c3
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/header.tmpl
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="{encoding}"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
+<head>
+<link rel="icon" href="{staticurl}hgicon.png" type="image/png" />
+<meta name="robots" content="index, nofollow"/>
+<link rel="stylesheet" href="{staticurl}style-gitweb.css" type="text/css" />
+
diff --git a/sys/src/cmd/hg/templates/gitweb/index.tmpl b/sys/src/cmd/hg/templates/gitweb/index.tmpl
new file mode 100644
index 000000000..858aaf1c7
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/index.tmpl
@@ -0,0 +1,26 @@
+{header}
+<title>Mercurial repositories index</title>
+</head>
+<body>
+
+<div class="page_header">
+ <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a>
+ Repositories list
+</div>
+
+<table cellspacing="0">
+ <tr>
+ <td><a href="?sort={sort_name}">Name</a></td>
+ <td><a href="?sort={sort_description}">Description</a></td>
+ <td><a href="?sort={sort_contact}">Contact</a></td>
+ <td><a href="?sort={sort_lastchange}">Last change</a></td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ </tr>
+ {entries%indexentry}
+</table>
+<div class="page_footer">
+{motd}
+</div>
+</body>
+</html>
diff --git a/sys/src/cmd/hg/templates/gitweb/manifest.tmpl b/sys/src/cmd/hg/templates/gitweb/manifest.tmpl
new file mode 100644
index 000000000..4bfb39f8f
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/manifest.tmpl
@@ -0,0 +1,38 @@
+{header}
+<title>{repo|escape}: files</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / files
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+files |
+<a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> {archives%archiveentry}<br/>
+</div>
+
+<div class="title">{path|escape} <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></div>
+<table cellspacing="0">
+<tr class="parity{upparity}">
+<td style="font-family:monospace">drwxr-xr-x</td>
+<td style="font-family:monospace"></td>
+<td style="font-family:monospace"></td>
+<td><a href="{url}file/{node|short}{up|urlescape}{sessionvars%urlparameter}">[up]</a></td>
+<td class="link">&nbsp;</td>
+</tr>
+{dentries%direntry}
+{fentries%fileentry}
+</table>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/map b/sys/src/cmd/hg/templates/gitweb/map
new file mode 100644
index 000000000..fc0fedd57
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/map
@@ -0,0 +1,248 @@
+default = 'summary'
+mimetype = 'text/html; charset={encoding}'
+header = header.tmpl
+footer = footer.tmpl
+search = search.tmpl
+changelog = changelog.tmpl
+summary = summary.tmpl
+error = error.tmpl
+notfound = notfound.tmpl
+naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
+filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenodelink = '
+ <tr class="parity{parity}">
+ <td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
+ <td></td>
+ <td class="link">
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
+ <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
+ <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
+ </td>
+ </tr>'
+filenolink = '
+ <tr class="parity{parity}">
+ <td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
+ <td></td>
+ <td class="link">
+ file |
+ annotate |
+ <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
+ <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
+ </td>
+ </tr>'
+fileellipses = '...'
+changelogentry = changelogentry.tmpl
+searchentry = changelogentry.tmpl
+changeset = changeset.tmpl
+manifest = manifest.tmpl
+direntry = '
+ <tr class="parity{parity}">
+ <td style="font-family:monospace">drwxr-xr-x</td>
+ <td style="font-family:monospace"></td>
+ <td style="font-family:monospace"></td>
+ <td>
+ <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
+ <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a>
+ </td>
+ <td class="link">
+ <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a>
+ </td>
+ </tr>'
+fileentry = '
+ <tr class="parity{parity}">
+ <td style="font-family:monospace">{permissions|permissions}</td>
+ <td style="font-family:monospace" align=right>{date|isodate}</td>
+ <td style="font-family:monospace" align=right>{size}</td>
+ <td class="list">
+ <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
+ </td>
+ <td class="link">
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
+ <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
+ </td>
+ </tr>'
+filerevision = filerevision.tmpl
+fileannotate = fileannotate.tmpl
+filediff = filediff.tmpl
+filelog = filelog.tmpl
+fileline = '
+ <div style="font-family:monospace" class="parity{parity}">
+ <pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</pre>
+ </div>'
+annotateline = '
+ <tr style="font-family:monospace" class="parity{parity}">
+ <td class="linenr" style="text-align: right;">
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
+ title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
+ </td>
+ <td><pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a></pre></td>
+ <td><pre>{line|escape}</pre></td>
+ </tr>'
+difflineplus = '<span style="color:#008800;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
+difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
+difflineat = '<span style="color:#990099;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
+diffline = '<span><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
+changelogparent = '
+ <tr>
+ <th class="parent">parent {rev}:</th>
+ <td class="parent">
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ </td>
+ </tr>'
+changesetbranch = '<tr><td>branch</td><td>{name}</td></tr>'
+changesetparent = '
+ <tr>
+ <td>parent {rev}</td>
+ <td style="font-family:monospace">
+ <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ </td>
+ </tr>'
+filerevbranch = '<tr><td>branch</td><td>{name}</td></tr>'
+filerevparent = '
+ <tr>
+ <td>parent {rev}</td>
+ <td style="font-family:monospace">
+ <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {rename%filerename}{node|short}
+ </a>
+ </td>
+ </tr>'
+filerename = '{file|escape}@'
+filelogrename = '| <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
+fileannotateparent = '
+ <tr>
+ <td>parent {rev}</td>
+ <td style="font-family:monospace">
+ <a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {rename%filerename}{node|short}
+ </a>
+ </td>
+ </tr>'
+changelogchild = '
+ <tr>
+ <th class="child">child {rev}:</th>
+ <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+changesetchild = '
+ <tr>
+ <td>child {rev}</td>
+ <td style="font-family:monospace">
+ <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ </td>
+ </tr>'
+filerevchild = '
+ <tr>
+ <td>child {rev}</td>
+ <td style="font-family:monospace">
+ <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+fileannotatechild = '
+ <tr>
+ <td>child {rev}</td>
+ <td style="font-family:monospace">
+ <a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+tags = tags.tmpl
+tagentry = '
+ <tr class="parity{parity}">
+ <td class="age"><i>{date|age} ago</i></td>
+ <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{tag|escape}</b></a></td>
+ <td class="link">
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
+ <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
+ <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+ </td>
+ </tr>'
+branches = branches.tmpl
+branchentry = '
+ <tr class="parity{parity}">
+ <td class="age"><i>{date|age} ago</i></td>
+ <td><a class="list" href="{url}shortlog/{node|short}{sessionvars%urlparameter}"><b>{node|short}</b></a></td>
+ <td class="{status}">{branch|escape}</td>
+ <td class="link">
+ <a href="{url}changeset/{node|short}{sessionvars%urlparameter}">changeset</a> |
+ <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
+ <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+ </td>
+ </tr>'
+diffblock = '<pre>{lines}</pre>'
+filediffparent = '
+ <tr>
+ <td>parent {rev}</td>
+ <td style="font-family:monospace">
+ <a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {node|short}
+ </a>
+ </td>
+ </tr>'
+filelogparent = '
+ <tr>
+ <td align="right">parent {rev}:&nbsp;</td>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filediffchild = '
+ <tr>
+ <td>child {rev}</td>
+ <td style="font-family:monospace">
+ <a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
+ </td>
+ </tr>'
+filelogchild = '
+ <tr>
+ <td align="right">child {rev}:&nbsp;</td>
+ <td><a href="{url}file{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+shortlog = shortlog.tmpl
+graph = graph.tmpl
+tagtag = '<span class="tagtag" title="{name}">{name}</span> '
+branchtag = '<span class="branchtag" title="{name}">{name}</span> '
+inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
+shortlogentry = '
+ <tr class="parity{parity}">
+ <td class="age"><i>{date|age} ago</i></td>
+ <td><i>{author|person}</i></td>
+ <td>
+ <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
+ <b>{desc|strip|firstline|escape|nonempty}</b>
+ <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span>
+ </a>
+ </td>
+ <td class="link" nowrap>
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
+ <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+ </td>
+ </tr>'
+filelogentry = '
+ <tr class="parity{parity}">
+ <td class="age"><i>{date|age} ago</i></td>
+ <td>
+ <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
+ <b>{desc|strip|firstline|escape|nonempty}</b>
+ </a>
+ </td>
+ <td class="link">
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> {rename%filelogrename}</td>
+ </tr>'
+archiveentry = ' | <a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
+indexentry = '
+ <tr class="parity{parity}">
+ <td>
+ <a class="list" href="{url}{sessionvars%urlparameter}">
+ <b>{name|escape}</b>
+ </a>
+ </td>
+ <td>{description}</td>
+ <td>{contact|obfuscate}</td>
+ <td class="age">{lastchange|age} ago</td>
+ <td class="indexlinks">{archives%indexarchiveentry}</td>
+ <td><div class="rss_logo"><a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a></div></td>
+ </tr>\n'
+indexarchiveentry = ' <a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
+index = index.tmpl
+urlparameter = '{separator}{name}={value|urlescape}'
+hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
diff --git a/sys/src/cmd/hg/templates/gitweb/notfound.tmpl b/sys/src/cmd/hg/templates/gitweb/notfound.tmpl
new file mode 100644
index 000000000..073bb11d4
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/notfound.tmpl
@@ -0,0 +1,18 @@
+{header}
+<title>Mercurial repository not found</title>
+</head>
+
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a> Not found: {repo|escape}
+</div>
+
+<div class="page_body">
+The specified repository "{repo|escape}" is unknown, sorry.
+<br/>
+<br/>
+Please go back to the <a href="{url}">main repository list page</a>.
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/search.tmpl b/sys/src/cmd/hg/templates/gitweb/search.tmpl
new file mode 100644
index 000000000..0ac85f238
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/search.tmpl
@@ -0,0 +1,36 @@
+{header}
+<title>{repo|escape}: Search</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / search
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<div class="search">
+<input type="text" name="rev" value="{query|escape}" />
+</div>
+</form>
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>{archives%archiveentry}
+<br/>
+</div>
+
+<div class="title">searching for {query|escape}</div>
+
+{entries}
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/shortlog.tmpl b/sys/src/cmd/hg/templates/gitweb/shortlog.tmpl
new file mode 100644
index 000000000..d40259739
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/shortlog.tmpl
@@ -0,0 +1,41 @@
+{header}
+<title>{repo|escape}: Shortlog</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / shortlog
+</div>
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<div class="search">
+<input type="text" name="rev" />
+</div>
+</form>
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+shortlog |
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>{archives%archiveentry}
+<br/>
+{changenav%navshortentry}<br/>
+</div>
+
+<div class="title">&nbsp;</div>
+<table cellspacing="0">
+{entries%shortlogentry}
+</table>
+
+<div class="page_nav">
+{changenav%navshortentry}
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/summary.tmpl b/sys/src/cmd/hg/templates/gitweb/summary.tmpl
new file mode 100644
index 000000000..f6473a5a9
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/summary.tmpl
@@ -0,0 +1,58 @@
+{header}
+<title>{repo|escape}: Summary</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / summary
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<div class="search">
+<input type="text" name="rev" />
+</div>
+</form>
+</div>
+
+<div class="page_nav">
+summary |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>{archives%archiveentry}
+<br/>
+</div>
+
+<div class="title">&nbsp;</div>
+<table cellspacing="0">
+<tr><td>description</td><td>{desc}</td></tr>
+<tr><td>owner</td><td>{owner|obfuscate}</td></tr>
+<tr><td>last change</td><td>{lastchange|rfc822date}</td></tr>
+</table>
+
+<div><a class="title" href="{url}shortlog{sessionvars%urlparameter}">changes</a></div>
+<table cellspacing="0">
+{shortlog}
+<tr class="light"><td colspan="4"><a class="list" href="{url}shortlog{sessionvars%urlparameter}">...</a></td></tr>
+</table>
+
+<div><a class="title" href="{url}tags{sessionvars%urlparameter}">tags</a></div>
+<table cellspacing="0">
+{tags}
+<tr class="light"><td colspan="3"><a class="list" href="{url}tags{sessionvars%urlparameter}">...</a></td></tr>
+</table>
+
+<div><a class="title" href="#">branches</a></div>
+<table cellspacing="0">
+{branches%branchentry}
+<tr class="light">
+ <td colspan="4"><a class="list" href="#">...</a></td>
+</tr>
+</table>
+{footer}
diff --git a/sys/src/cmd/hg/templates/gitweb/tags.tmpl b/sys/src/cmd/hg/templates/gitweb/tags.tmpl
new file mode 100644
index 000000000..b5e64b60e
--- /dev/null
+++ b/sys/src/cmd/hg/templates/gitweb/tags.tmpl
@@ -0,0 +1,30 @@
+{header}
+<title>{repo|escape}: Tags</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-tags" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-tags" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / tags
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+tags |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a> |
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+<br/>
+</div>
+
+<div class="title">&nbsp;</div>
+<table cellspacing="0">
+{entries%tagentry}
+</table>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/map-cmdline.changelog b/sys/src/cmd/hg/templates/map-cmdline.changelog
new file mode 100644
index 000000000..8ae39b59b
--- /dev/null
+++ b/sys/src/cmd/hg/templates/map-cmdline.changelog
@@ -0,0 +1,14 @@
+header = '{date|shortdate} {author|person} <{author|email}>\n\n'
+header_verbose = ''
+changeset = '\t* {files|stringify|fill68|tabindent}{desc|fill68|tabindent|strip}\n\t[{node|short}]{tags}\n\n'
+changeset_quiet = '\t* {desc|firstline|fill68|tabindent|strip}\n\n'
+changeset_verbose = '{date|isodate} {author|person} <{author|email}> ({node|short}{tags})\n\n\t* {file_adds|stringify|fill68|tabindent}{file_dels|stringify|fill68|tabindent}{files|stringify|fill68|tabindent}{desc|fill68|tabindent|strip}\n\n'
+start_tags = ' ['
+tag = '{tag}, '
+last_tag = '{tag}]'
+file = '{file}, '
+last_file = '{file}:\n\t'
+file_add = '{file_add}, '
+last_file_add = '{file_add}: new file.\n* '
+file_del = '{file_del}, '
+last_file_del = '{file_del}: deleted file.\n* '
diff --git a/sys/src/cmd/hg/templates/map-cmdline.compact b/sys/src/cmd/hg/templates/map-cmdline.compact
new file mode 100644
index 000000000..ee66bff97
--- /dev/null
+++ b/sys/src/cmd/hg/templates/map-cmdline.compact
@@ -0,0 +1,9 @@
+changeset = '{rev}{tags}{parents} {node|short} {date|isodate} {author|user}\n {desc|firstline|strip}\n\n'
+changeset_quiet = '{rev}:{node|short}\n'
+changeset_verbose = '{rev}{tags}{parents} {node|short} {date|isodate} {author}\n {desc|strip}\n\n'
+start_tags = '['
+tag = '{tag},'
+last_tag = '{tag}]'
+start_parents = ':'
+parent = '{rev},'
+last_parent = '{rev}'
diff --git a/sys/src/cmd/hg/templates/map-cmdline.default b/sys/src/cmd/hg/templates/map-cmdline.default
new file mode 100644
index 000000000..3ceb2973b
--- /dev/null
+++ b/sys/src/cmd/hg/templates/map-cmdline.default
@@ -0,0 +1,24 @@
+changeset = 'changeset: {rev}:{node|short}\n{branches}{tags}{parents}user: {author}\ndate: {date|date}\nsummary: {desc|firstline}\n\n'
+changeset_quiet = '{rev}:{node|short}\n'
+changeset_verbose = 'changeset: {rev}:{node|short}\n{branches}{tags}{parents}user: {author}\ndate: {date|date}\n{files}{file_copies}description:\n{desc|strip}\n\n\n'
+changeset_debug = 'changeset: {rev}:{node}\n{branches}{tags}{parents}{manifest}user: {author}\ndate: {date|date}\n{file_mods}{file_adds}{file_dels}{file_copies}{extras}description:\n{desc|strip}\n\n\n'
+start_files = 'files: '
+file = ' {file}'
+end_files = '\n'
+start_file_mods = 'files: '
+file_mod = ' {file_mod}'
+end_file_mods = '\n'
+start_file_adds = 'files+: '
+file_add = ' {file_add}'
+end_file_adds = '\n'
+start_file_dels = 'files-: '
+file_del = ' {file_del}'
+end_file_dels = '\n'
+start_file_copies = 'copies: '
+file_copy = ' {name} ({source})'
+end_file_copies = '\n'
+parent = 'parent: {rev}:{node|formatnode}\n'
+manifest = 'manifest: {rev}:{node}\n'
+branch = 'branch: {branch}\n'
+tag = 'tag: {tag}\n'
+extra = 'extra: {key}={value|stringescape}\n'
diff --git a/sys/src/cmd/hg/templates/monoblue/branches.tmpl b/sys/src/cmd/hg/templates/monoblue/branches.tmpl
new file mode 100644
index 000000000..2c75da03d
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/branches.tmpl
@@ -0,0 +1,36 @@
+{header}
+ <title>{repo|escape}: Branches</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / Branches</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}changelog{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li class="current">branches</li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <h2 class="no-link no-border">tags</h2>
+ <table cellspacing="0">
+{entries%branchentry}
+ </table>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/changelog.tmpl b/sys/src/cmd/hg/templates/monoblue/changelog.tmpl
new file mode 100644
index 000000000..8b361e585
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/changelog.tmpl
@@ -0,0 +1,40 @@
+{header}
+ <title>{repo|escape}: changelog</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / changelog</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li class="current">changelog</li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>{archives%archiveentry}</li>
+ </ul>
+ </div>
+
+ <h2 class="no-link no-border">changelog</h2>
+ <div>
+ {entries%changelogentry}
+ </div>
+
+ <div class="page-path">
+{changenav%naventry}
+ </div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/changelogentry.tmpl b/sys/src/cmd/hg/templates/monoblue/changelogentry.tmpl
new file mode 100644
index 000000000..df03c9758
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/changelogentry.tmpl
@@ -0,0 +1,6 @@
+<h3 class="changelog"><a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a></h3>
+<ul class="changelog-entry">
+ <li class="age">{date|age} ago</li>
+ <li>by <span class="name">{author|obfuscate}</span> <span class="revdate">[{date|rfc822date}] rev {rev}</span></li>
+ <li class="description">{desc|strip|escape|addbreaks|nonempty}</li>
+</ul>
diff --git a/sys/src/cmd/hg/templates/monoblue/changeset.tmpl b/sys/src/cmd/hg/templates/monoblue/changeset.tmpl
new file mode 100644
index 000000000..8919778f2
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/changeset.tmpl
@@ -0,0 +1,63 @@
+{header}
+<title>{repo|escape}: changeset {rev}:{node|short}</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / files</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}changelog{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <ul class="submenu">
+ <li class="current">changeset</li>
+ <li><a href="{url}raw-rev/{node|short}">raw</a> {archives%archiveentry}</li>
+ </ul>
+
+ <h2 class="no-link no-border">changeset</h2>
+
+ <h3 class="changeset"><a href="{url}raw-rev/{node|short}">{desc|strip|escape|firstline|nonempty} <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a></h3>
+ <p class="changeset-age"><span>{date|age} ago</span></p>
+
+ <dl class="overview">
+ <dt>author</dt>
+ <dd>{author|obfuscate}</dd>
+ <dt>date</dt>
+ <dd>{date|date}</dd>
+ {branch%changesetbranch}
+ <dt>changeset {rev}</dt>
+ <dd>{node|short}</dd>
+ {parent%changesetparent}
+ {child%changesetchild}
+ </dl>
+
+ <p class="description">{desc|strip|escape|addbreaks|nonempty}</p>
+
+ <table>
+ {files}
+ </table>
+
+ <div class="diff">
+ {diff}
+ </div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/error.tmpl b/sys/src/cmd/hg/templates/monoblue/error.tmpl
new file mode 100644
index 000000000..a7f23d20e
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/error.tmpl
@@ -0,0 +1,34 @@
+{header}
+ <title>{repo|escape}: Error</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / Not found: {repo|escape}</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li class="current">summary</li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <h2 class="no-link no-border">An error occurred while processing your request</h2>
+ <p class="normal">{error|escape}</p>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/fileannotate.tmpl b/sys/src/cmd/hg/templates/monoblue/fileannotate.tmpl
new file mode 100644
index 000000000..13094f699
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/fileannotate.tmpl
@@ -0,0 +1,63 @@
+{header}
+<title>{repo|escape}: {file|escape}@{node|short} (annotated)</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / annotate</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <ul class="submenu">
+ <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+ <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a></li>
+ <li class="current">annotate</li>
+ <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+ <li><a href="{url}raw-annotate/{node|short}/{file|urlescape}">raw</a></li>
+ </ul>
+
+ <h2 class="no-link no-border">{file|escape}@{node|short} (annotated)</h2>
+ <h3 class="changeset">{file|escape}</h3>
+ <p class="changeset-age"><span>{date|age} ago</span></p>
+
+ <dl class="overview">
+ <dt>author</dt>
+ <dd>{author|obfuscate}</dd>
+ <dt>date</dt>
+ <dd>{date|date}</dd>
+ {branch%filerevbranch}
+ <dt>changeset {rev}</dt>
+ <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>
+ {parent%fileannotateparent}
+ {child%fileannotatechild}
+ <dt>permissions</dt>
+ <dd>{permissions|permissions}</dd>
+ </dl>
+
+ <p class="description">{desc|strip|escape|addbreaks|nonempty}</p>
+
+ <table class="annotated">
+ {annotate%annotateline}
+ </table>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/filediff.tmpl b/sys/src/cmd/hg/templates/monoblue/filediff.tmpl
new file mode 100644
index 000000000..ccf2e8530
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/filediff.tmpl
@@ -0,0 +1,54 @@
+{header}
+<title>{repo|escape}: diff {file|escape}</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file diff</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <ul class="submenu">
+ <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+ <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a></li>
+ <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+ <li class="current">diff</li>
+ <li><a href="{url}raw-diff/{node|short}/{file|urlescape}">raw</a></li>
+ </ul>
+
+ <h2 class="no-link no-border">diff: {file|escape}</h2>
+ <h3 class="changeset">{file|escape}</h3>
+
+ <dl class="overview">
+ {branch%filerevbranch}
+ <dt>changeset {rev}</dt>
+ <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>
+ {parent%filediffparent}
+ {child%filediffchild}
+ </dl>
+
+ <div class="diff">
+ {diff}
+ </div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/filelog.tmpl b/sys/src/cmd/hg/templates/monoblue/filelog.tmpl
new file mode 100644
index 000000000..4ebc5cce8
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/filelog.tmpl
@@ -0,0 +1,49 @@
+{header}
+<title>{repo|escape}: File revisions</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file revisions</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <ul class="submenu">
+ <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+ <li class="current">revisions</li>
+ <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+ <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+ <li><a href="{url}rss-log/{node|short}/{file|urlescape}">rss</a></li>
+ </ul>
+
+ <h2 class="no-link no-border">{file|urlescape}</h2>
+
+ <table>
+ {entries%filelogentry}
+ </table>
+
+ <div class="page-path">
+ {nav%filenaventry}
+ </div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/filerevision.tmpl b/sys/src/cmd/hg/templates/monoblue/filerevision.tmpl
new file mode 100644
index 000000000..f58c63324
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/filerevision.tmpl
@@ -0,0 +1,63 @@
+{header}
+<title>{repo|escape}: {file|escape}@{node|short}</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file revision</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}changelog{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <ul class="submenu">
+ <li class="current">file</li>
+ <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a></li>
+ <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+ <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+ <li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
+ </ul>
+
+ <h2 class="no-link no-border">{file|escape}@{node|short}</h2>
+ <h3 class="changeset">{file|escape}</h3>
+ <p class="changeset-age"><span>{date|age} ago</span></p>
+
+ <dl class="overview">
+ <dt>author</dt>
+ <dd>{author|obfuscate}</dd>
+ <dt>date</dt>
+ <dd>{date|date}</dd>
+ {branch%filerevbranch}
+ <dt>changeset {rev}</dt>
+ <dd><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>
+ {parent%filerevparent}
+ {child%filerevchild}
+ <dt>permissions</dt>
+ <dd>{permissions|permissions}</dd>
+ </dl>
+
+ <p class="description">{desc|strip|escape|addbreaks|nonempty}</p>
+
+ <div class="source">
+ {text%fileline}
+ </div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/footer.tmpl b/sys/src/cmd/hg/templates/monoblue/footer.tmpl
new file mode 100644
index 000000000..cddaa9267
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/footer.tmpl
@@ -0,0 +1,22 @@
+ <div class="page-footer">
+ <p>Mercurial Repository: {repo|escape}</p>
+ <ul class="rss-logo">
+ <li><a href="{url}rss-log">RSS</a></li>
+ <li><a href="{url}atom-log">Atom</a></li>
+ </ul>
+ {motd}
+ </div>
+
+ <div id="powered-by">
+ <p><a href="http://mercurial.selenic.com/" title="Mercurial"><img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a></p>
+ </div>
+
+ <div id="corner-top-left"></div>
+ <div id="corner-top-right"></div>
+ <div id="corner-bottom-left"></div>
+ <div id="corner-bottom-right"></div>
+
+</div>
+
+</body>
+</html>
diff --git a/sys/src/cmd/hg/templates/monoblue/graph.tmpl b/sys/src/cmd/hg/templates/monoblue/graph.tmpl
new file mode 100644
index 000000000..ffd6b4771
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/graph.tmpl
@@ -0,0 +1,118 @@
+{header}
+ <title>{repo|escape}: graph</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+ <!--[if IE]><script type="text/javascript" src="{staticurl}excanvas.js"></script><![endif]-->
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / graph</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}changelog{sessionvars%urlparameter}">changelog</a></li>
+ <li class="current">graph</li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <h2 class="no-link no-border">graph</h2>
+
+ <div id="noscript">The revision graph only works with JavaScript-enabled browsers.</div>
+ <div id="wrapper">
+ <ul id="nodebgs"></ul>
+ <canvas id="graph" width="224" height="{canvasheight}"></canvas>
+ <ul id="graphnodes"></ul>
+ </div>
+
+ <script type="text/javascript" src="{staticurl}graph.js"></script>
+ <script>
+ <!-- hide script content
+
+ document.getElementById('noscript').style.display = 'none';
+
+ var data = {jsdata|json};
+ var graph = new Graph();
+ graph.scale({bg_height});
+
+ graph.edge = function(x0, y0, x1, y1, color) {
+
+ this.setColor(color, 0.0, 0.65);
+ this.ctx.beginPath();
+ this.ctx.moveTo(x0, y0);
+ this.ctx.lineTo(x1, y1);
+ this.ctx.stroke();
+
+ }
+
+ var revlink = '<li style="_STYLE"><span class="desc">';
+ revlink += '<a href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID">_DESC</a>';
+ revlink += '</span>_TAGS<span class="info">_DATE ago, by _USER</span></li>';
+
+ graph.vertex = function(x, y, color, parity, cur) {
+
+ this.ctx.beginPath();
+ color = this.setColor(color, 0.25, 0.75);
+ this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
+ this.ctx.fill();
+
+ var bg = '<li class="bg parity' + parity + '"></li>';
+ var left = (this.columns + 1) * this.bg_height;
+ var nstyle = 'padding-left: ' + left + 'px;';
+ var item = revlink.replace(/_STYLE/, nstyle);
+ item = item.replace(/_PARITY/, 'parity' + parity);
+ item = item.replace(/_NODEID/, cur[0]);
+ item = item.replace(/_NODEID/, cur[0]);
+ item = item.replace(/_DESC/, cur[3]);
+ item = item.replace(/_USER/, cur[4]);
+ item = item.replace(/_DATE/, cur[5]);
+
+ var tagspan = '';
+ if (cur[7].length || (cur[6][0] != 'default' || cur[6][1])) {
+ tagspan = '<span class="logtags">';
+ if (cur[6][1]) {
+ tagspan += '<span class="branchtag" title="' + cur[6][0] + '">';
+ tagspan += cur[6][0] + '</span> ';
+ } else if (!cur[6][1] && cur[6][0] != 'default') {
+ tagspan += '<span class="inbranchtag" title="' + cur[6][0] + '">';
+ tagspan += cur[6][0] + '</span> ';
+ }
+ if (cur[7].length) {
+ for (var t in cur[7]) {
+ var tag = cur[7][t];
+ tagspan += '<span class="tagtag">' + tag + '</span> ';
+ }
+ }
+ tagspan += '</span>';
+ }
+
+ item = item.replace(/_TAGS/, tagspan);
+ return [bg, item];
+
+ }
+
+ graph.render(data);
+
+ // stop hiding script -->
+ </script>
+
+ <div class="page-path">
+ <a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
+ <a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
+ | {changenav%navgraphentry}
+ </div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/header.tmpl b/sys/src/cmd/hg/templates/monoblue/header.tmpl
new file mode 100644
index 000000000..dd038847a
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/header.tmpl
@@ -0,0 +1,6 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <link rel="icon" href="{staticurl}hgicon.png" type="image/png" />
+ <meta name="robots" content="index, nofollow"/>
+ <link rel="stylesheet" href="{staticurl}style-monoblue.css" type="text/css" />
diff --git a/sys/src/cmd/hg/templates/monoblue/index.tmpl b/sys/src/cmd/hg/templates/monoblue/index.tmpl
new file mode 100644
index 000000000..e04f5c27e
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/index.tmpl
@@ -0,0 +1,39 @@
+{header}
+ <title>{repo|escape}: Mercurial repositories index</title>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1>Mercurial Repositories</h1>
+ <ul class="page-nav">
+ </ul>
+ </div>
+
+ <table cellspacing="0">
+ <tr>
+ <td><a href="?sort={sort_name}">Name</a></td>
+ <td><a href="?sort={sort_description}">Description</a></td>
+ <td><a href="?sort={sort_contact}">Contact</a></td>
+ <td><a href="?sort={sort_lastchange}">Last change</a></td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ </tr>
+ {entries%indexentry}
+ </table>
+ <div class="page-footer">
+ {motd}
+ </div>
+
+ <div id="powered-by">
+ <p><a href="http://mercurial.selenic.com/" title="Mercurial"><img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a></p>
+ </div>
+
+ <div id="corner-top-left"></div>
+ <div id="corner-top-right"></div>
+ <div id="corner-bottom-left"></div>
+ <div id="corner-bottom-right"></div>
+
+</div>
+</body>
+</html>
diff --git a/sys/src/cmd/hg/templates/monoblue/manifest.tmpl b/sys/src/cmd/hg/templates/monoblue/manifest.tmpl
new file mode 100644
index 000000000..f9da08199
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/manifest.tmpl
@@ -0,0 +1,51 @@
+{header}
+<title>{repo|escape}: files</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / files</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}changelog{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li class="current">files</li>
+ </ul>
+ </div>
+
+ <ul class="submenu">
+ <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> {archives%archiveentry}</li>
+ {archives%archiveentry}
+ </ul>
+
+ <h2 class="no-link no-border">files</h2>
+ <p class="files">{path|escape} <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></p>
+
+ <table>
+ <tr class="parity{upparity}">
+ <td>drwxr-xr-x</td>
+ <td></td>
+ <td></td>
+ <td><a href="{url}file/{node|short}{up|urlescape}{sessionvars%urlparameter}">[up]</a></td>
+ <td class="link">&nbsp;</td>
+ </tr>
+ {dentries%direntry}
+ {fentries%fileentry}
+ </table>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/map b/sys/src/cmd/hg/templates/monoblue/map
new file mode 100644
index 000000000..146e3f62f
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/map
@@ -0,0 +1,214 @@
+default = 'summary'
+mimetype = 'text/html; charset={encoding}'
+header = header.tmpl
+footer = footer.tmpl
+search = search.tmpl
+changelog = changelog.tmpl
+summary = summary.tmpl
+error = error.tmpl
+notfound = notfound.tmpl
+naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a>'
+filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenodelink = '
+ <tr class="parity{parity}">
+ <td><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
+ <td></td>
+ <td>
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
+ <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
+ <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
+ </td>
+ </tr>'
+filenolink = '
+ <tr class="parity{parity}">
+ <td>
+ <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td><td></td><td>file |
+ annotate |
+ <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
+ <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
+ </td>
+ </tr>'
+fileellipses = '...'
+changelogentry = changelogentry.tmpl
+searchentry = changelogentry.tmpl
+changeset = changeset.tmpl
+manifest = manifest.tmpl
+direntry = '
+ <tr class="parity{parity}">
+ <td>drwxr-xr-x</td>
+ <td></td>
+ <td></td>
+ <td><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
+ <td><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></td>
+ </tr>'
+fileentry = '
+ <tr class="parity{parity}">
+ <td>{permissions|permissions}</td>
+ <td>{date|isodate}</td>
+ <td>{size}</td>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
+ <td>
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
+ <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
+ </td>
+ </tr>'
+filerevision = filerevision.tmpl
+fileannotate = fileannotate.tmpl
+filediff = filediff.tmpl
+filelog = filelog.tmpl
+fileline = '
+ <div style="font-family:monospace" class="parity{parity}">
+ <pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</pre>
+ </div>'
+annotateline = '
+ <tr class="parity{parity}">
+ <td class="linenr">
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#{targetline}"
+ title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
+ </td>
+ <td class="lineno">
+ <a href="#{lineid}" id="{lineid}">{linenumber}</a>
+ </td>
+ <td class="source">{line|escape}</td>
+ </tr>'
+difflineplus = '<span style="color:#008800;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
+difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
+difflineat = '<span style="color:#990099;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
+diffline = '<span><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
+changelogparent = '
+ <tr>
+ <th class="parent">parent {rev}:</th>
+ <td class="parent">
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ </td>
+ </tr>'
+changesetbranch = '<dt>branch</dt><dd>{name}</dd>'
+changesetparent = '
+ <dt>parent {rev}</dt>
+ <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
+filerevbranch = '<dt>branch</dt><dd>{name}</dd>'
+filerevparent = '
+ <dt>parent {rev}</dt>
+ <dd>
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {rename%filerename}{node|short}
+ </a>
+ </dd>'
+filerename = '{file|escape}@'
+filelogrename = '| <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
+fileannotateparent = '
+ <dt>parent {rev}</dt>
+ <dd>
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {rename%filerename}{node|short}
+ </a>
+ </dd>'
+changelogchild = '
+ <dt>child {rev}:</dt>
+ <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
+changesetchild = '
+ <dt>child {rev}</dt>
+ <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
+filerevchild = '
+ <dt>child {rev}</dt>
+ <dd>
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
+ </dd>'
+fileannotatechild = '
+ <dt>child {rev}</dt>
+ <dd>
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
+ </dd>'
+tags = tags.tmpl
+tagentry = '
+ <tr class="parity{parity}">
+ <td class="nowrap">{date|age} ago</td>
+ <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td>
+ <td class="nowrap">
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
+ <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
+ <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+ </td>
+ </tr>'
+branches = branches.tmpl
+branchentry = '
+ <tr class="parity{parity}">
+ <td class="nowrap">{date|age} ago</td>
+ <td><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ <td class="{status}">{branch|escape}</td>
+ <td class="nowrap">
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
+ <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
+ <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+ </td>
+ </tr>'
+diffblock = '<pre>{lines}</pre>'
+filediffparent = '
+ <dt>parent {rev}</dt>
+ <dd><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
+filelogparent = '
+ <tr>
+ <td align="right">parent {rev}:&nbsp;</td>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filediffchild = '
+ <dt>child {rev}</dt>
+ <dd><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
+filelogchild = '
+ <tr>
+ <td align="right">child {rev}:&nbsp;</td>
+ <td><a href="{url}file{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+shortlog = shortlog.tmpl
+tagtag = '<span class="tagtag" title="{name}">{name}</span> '
+branchtag = '<span class="branchtag" title="{name}">{name}</span> '
+inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
+shortlogentry = '
+ <tr class="parity{parity}">
+ <td class="nowrap">{date|age} ago</td>
+ <td>{author|person}</td>
+ <td>
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
+ {desc|strip|firstline|escape|nonempty}
+ <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span>
+ </a>
+ </td>
+ <td class="nowrap">
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
+ <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+ </td>
+ </tr>'
+filelogentry = '
+ <tr class="parity{parity}">
+ <td class="nowrap">{date|age} ago</td>
+ <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td>
+ <td class="nowrap">
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
+ {rename%filelogrename}
+ </td>
+ </tr>'
+archiveentry = '<li><a href="{url}archive/{node|short}{extension}">{type|escape}</a></li>'
+indexentry = '
+ <tr class="parity{parity}">
+ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
+ <td>{description}</td>
+ <td>{contact|obfuscate}</td>
+ <td>{lastchange|age} ago</td>
+ <td class="indexlinks">{archives%indexarchiveentry}</td>
+ <td>
+ <div class="rss_logo">
+ <a href="{url}rss-log">RSS</a>
+ <a href="{url}atom-log">Atom</a>
+ </div>
+ </td>
+ </tr>\n'
+indexarchiveentry = '<a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
+index = index.tmpl
+urlparameter = '{separator}{name}={value|urlescape}'
+hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
+graph = graph.tmpl
diff --git a/sys/src/cmd/hg/templates/monoblue/notfound.tmpl b/sys/src/cmd/hg/templates/monoblue/notfound.tmpl
new file mode 100644
index 000000000..230bc04dc
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/notfound.tmpl
@@ -0,0 +1,35 @@
+{header}
+ <title>{repo|escape}: Mercurial repository not found</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / Not found: {repo|escape}</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li class="current">summary</li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>{archives%archiveentry}</li>
+ </ul>
+ </div>
+
+ <h2 class="no-link no-border">Not Found</h2>
+ <p class="normal">The specified repository "{repo|escape}" is unknown, sorry.</p>
+ <p class="normal">Please go back to the <a href="{url}">main repository list page</a>.</p>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/search.tmpl b/sys/src/cmd/hg/templates/monoblue/search.tmpl
new file mode 100644
index 000000000..7b37c52a9
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/search.tmpl
@@ -0,0 +1,34 @@
+{header}
+ <title>{repo|escape}: Search</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / search</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" value="{query|escape}" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>{archives%archiveentry}
+ </ul>
+ </div>
+
+ <h2 class="no-link no-border">searching for {query|escape}</h2>
+ {entries}
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/shortlog.tmpl b/sys/src/cmd/hg/templates/monoblue/shortlog.tmpl
new file mode 100644
index 000000000..5de092783
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/shortlog.tmpl
@@ -0,0 +1,41 @@
+{header}
+ <title>{repo|escape}: shortlog</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / shortlog</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li class="current">shortlog</li>
+ <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>{archives%archiveentry}</li>
+ </ul>
+ </div>
+
+ <h2 class="no-link no-border">shortlog</h2>
+
+ <table>
+{entries%shortlogentry}
+ </table>
+
+ <div class="page-path">
+{changenav%navshortentry}
+ </div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/summary.tmpl b/sys/src/cmd/hg/templates/monoblue/summary.tmpl
new file mode 100644
index 000000000..b1679655f
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/summary.tmpl
@@ -0,0 +1,66 @@
+{header}
+ <title>{repo|escape}: Summary</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / summary</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li class="current">summary</li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <h2 class="no-link no-border">Mercurial Repository Overview</h2>
+ <dl class="overview">
+ <dt>name</dt>
+ <dd>{repo|escape}</dd>
+ <dt>description</dt>
+ <dd>{desc}</dd>
+ <dt>owner</dt>
+ <dd>{owner|obfuscate}</dd>
+ <dt>last change</dt>
+ <dd>{lastchange|rfc822date}</dd>
+ </dl>
+
+ <h2><a href="{url}shortlog{sessionvars%urlparameter}">Changes</a></h2>
+ <table>
+{shortlog}
+ <tr class="light">
+ <td colspan="4"><a class="list" href="{url}shortlog{sessionvars%urlparameter}">...</a></td>
+ </tr>
+ </table>
+
+ <h2><a href="{url}tags{sessionvars%urlparameter}">Tags</a></h2>
+ <table>
+{tags}
+ <tr class="light">
+ <td colspan="3"><a class="list" href="{url}tags{sessionvars%urlparameter}">...</a></td>
+ </tr>
+ </table>
+
+ <h2 class="no-link">Branches</h2>
+ <table>
+ {branches%branchentry}
+ <tr class="light">
+ <td colspan="4"><a class="list" href="#">...</a></td>
+ </tr>
+ </table>
+{footer}
diff --git a/sys/src/cmd/hg/templates/monoblue/tags.tmpl b/sys/src/cmd/hg/templates/monoblue/tags.tmpl
new file mode 100644
index 000000000..54a672107
--- /dev/null
+++ b/sys/src/cmd/hg/templates/monoblue/tags.tmpl
@@ -0,0 +1,36 @@
+{header}
+ <title>{repo|escape}: Tags</title>
+ <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+ <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+ <div class="page-header">
+ <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / Tags</h1>
+
+ <form action="{url}log">
+ {sessionvars%hiddenformentry}
+ <dl class="search">
+ <dt><label>Search: </label></dt>
+ <dd><input type="text" name="rev" /></dd>
+ </dl>
+ </form>
+
+ <ul class="page-nav">
+ <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+ <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+ <li><a href="{url}changelog{sessionvars%urlparameter}">changelog</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li class="current">tags</li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a></li>
+ </ul>
+ </div>
+
+ <h2 class="no-link no-border">tags</h2>
+ <table cellspacing="0">
+{entries%tagentry}
+ </table>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/branches.tmpl b/sys/src/cmd/hg/templates/paper/branches.tmpl
new file mode 100644
index 000000000..e3648b867
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/branches.tmpl
@@ -0,0 +1,45 @@
+{header}
+<title>{repo|escape}: branches</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-tags" title="Atom feed for {repo|escape}: branches" />
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-tags" title="RSS feed for {repo|escape}: branches" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li class="active">branches</li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>branches</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<table class="bigtable">
+<tr>
+ <th>branch</th>
+ <th>node</th>
+</tr>
+{entries%branchentry}
+</table>
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/changeset.tmpl b/sys/src/cmd/hg/templates/paper/changeset.tmpl
new file mode 100644
index 000000000..cce7aaee7
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/changeset.tmpl
@@ -0,0 +1,71 @@
+{header}
+<title>{repo|escape}: {node|short}</title>
+</head>
+<body>
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+ <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+<ul>
+ <li class="active">changeset</li>
+ <li><a href="{url}raw-rev/{node|short}{sessionvars%urlparameter}">raw</a></li>
+ <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+ {archives%archiveentry}
+</ul>
+</div>
+
+<div class="main">
+
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>changeset {rev}:{node|short} {changesetbranch%changelogbranchname} {changesettag}</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="description">{desc|strip|escape|addbreaks|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th class="author">author</th>
+ <td class="author">{author|obfuscate}</td>
+</tr>
+<tr>
+ <th class="date">date</th>
+ <td class="date">{date|date} ({date|age} ago)</td></tr>
+<tr>
+ <th class="author">parents</th>
+ <td class="author">{parent%changesetparent}</td>
+</tr>
+<tr>
+ <th class="author">children</th>
+ <td class="author">{child%changesetchild}</td>
+</tr>
+<tr>
+ <th class="files">files</th>
+ <td class="files">{files}</td>
+</tr>
+</table>
+
+<div class="overflow">
+<div class="sourcefirst"> line diff</div>
+
+{diff}
+</div>
+
+</div>
+</div>
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/error.tmpl b/sys/src/cmd/hg/templates/paper/error.tmpl
new file mode 100644
index 000000000..d43102563
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/error.tmpl
@@ -0,0 +1,43 @@
+{header}
+<title>{repo|escape}: error</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+</div>
+
+<div class="main">
+
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>error</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30"></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="description">
+<p>
+An error occurred while processing your request:
+</p>
+<p>
+{error|escape}
+</p>
+</div>
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/fileannotate.tmpl b/sys/src/cmd/hg/templates/paper/fileannotate.tmpl
new file mode 100644
index 000000000..5465a48ca
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/fileannotate.tmpl
@@ -0,0 +1,77 @@
+{header}
+<title>{repo|escape}: {file|escape} annotate</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+
+<ul>
+<li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+<li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+<li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+<li class="active">annotate</li>
+<li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
+<li><a href="{url}raw-annotate/{node|short}/{file|urlescape}">raw</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>annotate {file|escape} @ {rev}:{node|short}</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="description">{desc|strip|escape|addbreaks|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th class="author">author</th>
+ <td class="author">{author|obfuscate}</td>
+</tr>
+<tr>
+ <th class="date">date</th>
+ <td class="date">{date|date} ({date|age} ago)</td>
+</tr>
+<tr>
+ <th class="author">parents</th>
+ <td class="author">{parent%filerevparent}</td>
+</tr>
+<tr>
+ <th class="author">children</th>
+ <td class="author">{child%filerevchild}</td>
+</tr>
+{changesettag}
+</table>
+
+<div class="overflow">
+<table class="bigtable">
+<tr>
+ <th class="annotate">rev</th>
+ <th class="line">&nbsp;&nbsp;line source</th>
+</tr>
+{annotate%annotateline}
+</table>
+</div>
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/filediff.tmpl b/sys/src/cmd/hg/templates/paper/filediff.tmpl
new file mode 100644
index 000000000..d031b68c4
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/filediff.tmpl
@@ -0,0 +1,72 @@
+{header}
+<title>{repo|escape}: {file|escape} diff</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+<ul>
+<li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+<li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+<li class="active">diff</li>
+<li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+<li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
+<li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>diff {file|escape} @ {rev}:{node|short}</h3>
+
+<form class="search" action="{url}log">
+<p>{sessionvars%hiddenformentry}</p>
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="description">{desc|strip|escape|addbreaks|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th>author</th>
+ <td>{author|obfuscate}</td>
+</tr>
+<tr>
+ <th>date</th>
+ <td>{date|date} ({date|age} ago)</td>
+</tr>
+<tr>
+ <th>parents</th>
+ <td>{parent%filerevparent}</td>
+</tr>
+<tr>
+ <th>children</th>
+ <td>{child%filerevchild}</td>
+</tr>
+{changesettag}
+</table>
+
+<div class="overflow">
+<div class="sourcefirst"> line diff</div>
+
+{diff}
+</div>
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/filelog.tmpl b/sys/src/cmd/hg/templates/paper/filelog.tmpl
new file mode 100644
index 000000000..3a2d28523
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/filelog.tmpl
@@ -0,0 +1,60 @@
+{header}
+<title>{repo|escape}: {file|escape} history</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log/tip/{file|urlescape}" title="Atom feed for {repo|escape}:{file}" />
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log/tip/{file|urlescape}" title="RSS feed for {repo|escape}:{file}" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+<ul>
+<li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+<li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+<li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+<li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+<li class="active">file log</li>
+<li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>log {file|escape}</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="navigate">{nav%filenaventry}</div>
+
+<table class="bigtable">
+ <tr>
+ <th class="age">age</th>
+ <th class="author">author</th>
+ <th class="description">description</th>
+ </tr>
+{entries%filelogentry}
+</table>
+
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/filelogentry.tmpl b/sys/src/cmd/hg/templates/paper/filelogentry.tmpl
new file mode 100644
index 000000000..43e068c84
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/filelogentry.tmpl
@@ -0,0 +1,5 @@
+ <tr class="parity{parity}">
+ <td class="age">{date|age}</td>
+ <td class="author">{author|person}</td>
+ <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}</td>
+ </tr>
diff --git a/sys/src/cmd/hg/templates/paper/filerevision.tmpl b/sys/src/cmd/hg/templates/paper/filerevision.tmpl
new file mode 100644
index 000000000..fec81b7b9
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/filerevision.tmpl
@@ -0,0 +1,72 @@
+{header}
+<title>{repo|escape}: {node|short} {file|escape}</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+<ul>
+<li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+<li class="active">file</li>
+<li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+<li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+<li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
+<li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>view {file|escape} @ {rev}:{node|short}</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="description">{desc|strip|escape|addbreaks|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th class="author">author</th>
+ <td class="author">{author|obfuscate}</td>
+</tr>
+<tr>
+ <th class="date">date</th>
+ <td class="date">{date|date} ({date|age} ago)</td>
+</tr>
+<tr>
+ <th class="author">parents</th>
+ <td class="author">{parent%filerevparent}</td>
+</tr>
+<tr>
+ <th class="author">children</th>
+ <td class="author">{child%filerevchild}</td>
+</tr>
+{changesettag}
+</table>
+
+<div class="overflow">
+<div class="sourcefirst"> line source</div>
+{text%fileline}
+<div class="sourcelast"></div>
+</div>
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/footer.tmpl b/sys/src/cmd/hg/templates/paper/footer.tmpl
new file mode 100644
index 000000000..6231a3c19
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/footer.tmpl
@@ -0,0 +1,4 @@
+{motd}
+
+</body>
+</html>
diff --git a/sys/src/cmd/hg/templates/paper/graph.tmpl b/sys/src/cmd/hg/templates/paper/graph.tmpl
new file mode 100644
index 000000000..78b035c47
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/graph.tmpl
@@ -0,0 +1,132 @@
+{header}
+<title>{repo|escape}: revision graph</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}: log" />
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}: log" />
+<!--[if IE]><script type="text/javascript" src="{staticurl}excanvas.js"></script><![endif]-->
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
+<li class="active">graph</li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+<ul>
+<li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>graph</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="navigate">
+<a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
+<a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
+| rev {rev}: {changenav%navgraphentry}
+</div>
+
+<noscript><p>The revision graph only works with JavaScript-enabled browsers.</p></noscript>
+
+<div id="wrapper">
+<ul id="nodebgs"></ul>
+<canvas id="graph" width="224" height="{canvasheight}"></canvas>
+<ul id="graphnodes"></ul>
+</div>
+
+<script type="text/javascript" src="{staticurl}graph.js"></script>
+<script type="text/javascript">
+<!-- hide script content
+
+var data = {jsdata|json};
+var graph = new Graph();
+graph.scale({bg_height});
+
+graph.edge = function(x0, y0, x1, y1, color) {
+
+ this.setColor(color, 0.0, 0.65);
+ this.ctx.beginPath();
+ this.ctx.moveTo(x0, y0);
+ this.ctx.lineTo(x1, y1);
+ this.ctx.stroke();
+
+}
+
+var revlink = '<li style="_STYLE"><span class="desc">';
+revlink += '<a href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID">_DESC</a>';
+revlink += '</span>_TAGS<span class="info">_DATE ago, by _USER</span></li>';
+
+graph.vertex = function(x, y, color, parity, cur) {
+
+ this.ctx.beginPath();
+ color = this.setColor(color, 0.25, 0.75);
+ this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
+ this.ctx.fill();
+
+ var bg = '<li class="bg parity' + parity + '"></li>';
+ var left = (this.columns + 1) * this.bg_height;
+ var nstyle = 'padding-left: ' + left + 'px;';
+ var item = revlink.replace(/_STYLE/, nstyle);
+ item = item.replace(/_PARITY/, 'parity' + parity);
+ item = item.replace(/_NODEID/, cur[0]);
+ item = item.replace(/_NODEID/, cur[0]);
+ item = item.replace(/_DESC/, cur[3]);
+ item = item.replace(/_USER/, cur[4]);
+ item = item.replace(/_DATE/, cur[5]);
+
+ var tagspan = '';
+ if (cur[7].length || (cur[6][0] != 'default' || cur[6][1])) {
+ tagspan = '<span class="logtags">';
+ if (cur[6][1]) {
+ tagspan += '<span class="branchhead" title="' + cur[6][0] + '">';
+ tagspan += cur[6][0] + '</span> ';
+ } else if (!cur[6][1] && cur[6][0] != 'default') {
+ tagspan += '<span class="branchname" title="' + cur[6][0] + '">';
+ tagspan += cur[6][0] + '</span> ';
+ }
+ if (cur[7].length) {
+ for (var t in cur[7]) {
+ var tag = cur[7][t];
+ tagspan += '<span class="tag">' + tag + '</span> ';
+ }
+ }
+ tagspan += '</span>';
+ }
+
+ item = item.replace(/_TAGS/, tagspan);
+ return [bg, item];
+
+}
+
+graph.render(data);
+
+// stop hiding script -->
+</script>
+
+<div class="navigate">
+<a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
+<a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
+| rev {rev}: {changenav%navgraphentry}
+</div>
+
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/header.tmpl b/sys/src/cmd/hg/templates/paper/header.tmpl
new file mode 100644
index 000000000..305bc2f35
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/header.tmpl
@@ -0,0 +1,6 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+<head>
+<link rel="icon" href="{staticurl}hgicon.png" type="image/png" />
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="{staticurl}style-paper.css" type="text/css" />
diff --git a/sys/src/cmd/hg/templates/paper/index.tmpl b/sys/src/cmd/hg/templates/paper/index.tmpl
new file mode 100644
index 000000000..35915b570
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/index.tmpl
@@ -0,0 +1,26 @@
+{header}
+<title>Mercurial repositories index</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
+</div>
+<div class="main">
+<h2>Mercurial Repositories</h2>
+
+<table class="bigtable">
+ <tr>
+ <th><a href="?sort={sort_name}">Name</a></th>
+ <th><a href="?sort={sort_description}">Description</a></th>
+ <th><a href="?sort={sort_contact}">Contact</a></th>
+ <th><a href="?sort={sort_lastchange}">Last change</a></th>
+ <th>&nbsp;</th>
+ </tr>
+ {entries%indexentry}
+</table>
+</div>
+</div>
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/manifest.tmpl b/sys/src/cmd/hg/templates/paper/manifest.tmpl
new file mode 100644
index 000000000..a5e65725d
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/manifest.tmpl
@@ -0,0 +1,54 @@
+{header}
+<title>{repo|escape}: {node|short} {path|escape}</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+<ul>
+<li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
+<li class="active">browse</li>
+</ul>
+<ul>
+{archives%archiveentry}
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>directory {path|escape} @ {rev}:{node|short} {tags%changelogtag}</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<table class="bigtable">
+<tr>
+ <th class="name">name</th>
+ <th class="size">size</th>
+ <th class="permissions">permissions</th>
+</tr>
+<tr class="fileline parity{upparity}">
+ <td class="name"><a href="{url}file/{node|short}{up|urlescape}{sessionvars%urlparameter}">[up]</a></td>
+ <td class="size"></td>
+ <td class="permissions">drwxr-xr-x</td>
+</tr>
+{dentries%direntry}
+{fentries%fileentry}
+</table>
+</div>
+</div>
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/map b/sys/src/cmd/hg/templates/paper/map
new file mode 100644
index 000000000..96b8a82e6
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/map
@@ -0,0 +1,191 @@
+default = 'shortlog'
+
+mimetype = 'text/html; charset={encoding}'
+header = header.tmpl
+footer = footer.tmpl
+search = search.tmpl
+
+changelog = shortlog.tmpl
+shortlog = shortlog.tmpl
+shortlogentry = shortlogentry.tmpl
+graph = graph.tmpl
+
+naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
+filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenolink = '{file|escape} '
+fileellipses = '...'
+changelogentry = shortlogentry.tmpl
+searchentry = shortlogentry.tmpl
+changeset = changeset.tmpl
+manifest = manifest.tmpl
+
+direntry = '
+ <tr class="fileline parity{parity}">
+ <td class="name">
+ <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">
+ <img src="{staticurl}coal-folder.png" alt="dir."/> {basename|escape}/
+ </a>
+ <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
+ {emptydirs|escape}
+ </a>
+ </td>
+ <td class="size"></td>
+ <td class="permissions">drwxr-xr-x</td>
+ </tr>'
+
+fileentry = '
+ <tr class="fileline parity{parity}">
+ <td class="filename">
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ <img src="{staticurl}coal-file.png" alt="file"/> {basename|escape}
+ </a>
+ </td>
+ <td class="size">{size}</td>
+ <td class="permissions">{permissions|permissions}</td>
+ </tr>'
+
+filerevision = filerevision.tmpl
+fileannotate = fileannotate.tmpl
+filediff = filediff.tmpl
+filelog = filelog.tmpl
+fileline = '
+ <div class="parity{parity} source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</div>'
+filelogentry = filelogentry.tmpl
+
+annotateline = '
+ <tr class="parity{parity}">
+ <td class="annotate">
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#{targetline}"
+ title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
+ </td>
+ <td class="source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</td>
+ </tr>'
+
+diffblock = '<div class="source bottomline parity{parity}"><pre>{lines}</pre></div>'
+difflineplus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="plusline">{line|escape}</span>'
+difflineminus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="minusline">{line|escape}</span>'
+difflineat = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="atline">{line|escape}</span>'
+diffline = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}'
+
+changelogparent = '
+ <tr>
+ <th class="parent">parent {rev}:</th>
+ <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+
+changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
+
+filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
+filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
+
+filerename = '{file|escape}@'
+filelogrename = '
+ <tr>
+ <th>base:</th>
+ <td>
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {file|escape}@{node|short}
+ </a>
+ </td>
+ </tr>'
+fileannotateparent = '
+ <tr>
+ <td class="metatag">parent:</td>
+ <td>
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {rename%filerename}{node|short}
+ </a>
+ </td>
+ </tr>'
+changesetchild = ' <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
+changelogchild = '
+ <tr>
+ <th class="child">child</th>
+ <td class="child">
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
+ {node|short}
+ </a>
+ </td>
+ </tr>'
+fileannotatechild = '
+ <tr>
+ <td class="metatag">child:</td>
+ <td>
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {node|short}
+ </a>
+ </td>
+ </tr>'
+tags = tags.tmpl
+tagentry = '
+ <tr class="tagEntry parity{parity}">
+ <td>
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
+ {tag|escape}
+ </a>
+ </td>
+ <td class="node">
+ {node|short}
+ </td>
+ </tr>'
+branches = branches.tmpl
+branchentry = '
+ <tr class="tagEntry parity{parity}">
+ <td>
+ <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
+ {branch|escape}
+ </a>
+ </td>
+ <td class="node">
+ {node|short}
+ </td>
+ </tr>'
+changelogtag = '<span class="tag">{name|escape}</span> '
+changesettag = '<span class="tag">{tag|escape}</span> '
+changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
+changelogbranchname = '<span class="branchname">{name|escape}</span> '
+
+filediffparent = '
+ <tr>
+ <th class="parent">parent {rev}:</th>
+ <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filelogparent = '
+ <tr>
+ <th>parent {rev}:</th>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filediffchild = '
+ <tr>
+ <th class="child">child {rev}:</th>
+ <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ </td>
+ </tr>'
+filelogchild = '
+ <tr>
+ <th>child {rev}:</th>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+
+indexentry = '
+ <tr class="parity{parity}">
+ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
+ <td>{description}</td>
+ <td>{contact|obfuscate}</td>
+ <td class="age">{lastchange|age} ago</td>
+ <td class="indexlinks">{archives%indexarchiveentry}</td>
+ </tr>\n'
+indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
+index = index.tmpl
+archiveentry = '
+ <li>
+ <a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a>
+ </li>'
+notfound = notfound.tmpl
+error = error.tmpl
+urlparameter = '{separator}{name}={value|urlescape}'
+hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
diff --git a/sys/src/cmd/hg/templates/paper/notfound.tmpl b/sys/src/cmd/hg/templates/paper/notfound.tmpl
new file mode 100644
index 000000000..e9e6ba420
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/notfound.tmpl
@@ -0,0 +1,12 @@
+{header}
+<title>Mercurial repository not found</title>
+</head>
+<body>
+
+<h2>Mercurial repository not found</h2>
+
+The specified repository "{repo|escape}" is unknown, sorry.
+
+Please go back to the <a href="{url}">main repository list page</a>.
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/search.tmpl b/sys/src/cmd/hg/templates/paper/search.tmpl
new file mode 100644
index 000000000..67b20c8bb
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/search.tmpl
@@ -0,0 +1,43 @@
+{header}
+<title>{repo|escape}: searching for {query|escape}</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
+</div>
+<ul>
+<li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>searching for '{query|escape}'</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30"></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<table class="bigtable">
+ <tr>
+ <th class="age">age</th>
+ <th class="author">author</th>
+ <th class="description">description</th>
+ </tr>
+{entries}
+</table>
+
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/shortlog.tmpl b/sys/src/cmd/hg/templates/paper/shortlog.tmpl
new file mode 100644
index 000000000..96fc6d9c2
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/shortlog.tmpl
@@ -0,0 +1,57 @@
+{header}
+<title>{repo|escape}: log</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}" />
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li class="active">log</li>
+<li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+<ul>
+<li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+{archives%archiveentry}
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>log</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<div class="navigate">rev {rev}: {changenav%navshortentry}</div>
+
+<table class="bigtable">
+ <tr>
+ <th class="age">age</th>
+ <th class="author">author</th>
+ <th class="description">description</th>
+ </tr>
+{entries%shortlogentry}
+</table>
+
+<div class="navigate">rev {rev}: {changenav%navshortentry}</div>
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/paper/shortlogentry.tmpl b/sys/src/cmd/hg/templates/paper/shortlogentry.tmpl
new file mode 100644
index 000000000..43e068c84
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/shortlogentry.tmpl
@@ -0,0 +1,5 @@
+ <tr class="parity{parity}">
+ <td class="age">{date|age}</td>
+ <td class="author">{author|person}</td>
+ <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}</td>
+ </tr>
diff --git a/sys/src/cmd/hg/templates/paper/tags.tmpl b/sys/src/cmd/hg/templates/paper/tags.tmpl
new file mode 100644
index 000000000..1566e9f6b
--- /dev/null
+++ b/sys/src/cmd/hg/templates/paper/tags.tmpl
@@ -0,0 +1,45 @@
+{header}
+<title>{repo|escape}: tags</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-tags" title="Atom feed for {repo|escape}: tags" />
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-tags" title="RSS feed for {repo|escape}: tags" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
+<li class="active">tags</li>
+<li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>tags</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+<table class="bigtable">
+<tr>
+ <th>tag</th>
+ <th>node</th>
+</tr>
+{entries%tagentry}
+</table>
+</div>
+</div>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/raw/changeset.tmpl b/sys/src/cmd/hg/templates/raw/changeset.tmpl
new file mode 100644
index 000000000..b59d99b59
--- /dev/null
+++ b/sys/src/cmd/hg/templates/raw/changeset.tmpl
@@ -0,0 +1,9 @@
+{header}
+# HG changeset patch
+# User {author}
+# Date {date|hgdate}
+# Node ID {node}
+{parent%changesetparent}
+{desc}
+
+{diff}
diff --git a/sys/src/cmd/hg/templates/raw/error.tmpl b/sys/src/cmd/hg/templates/raw/error.tmpl
new file mode 100644
index 000000000..9407c132d
--- /dev/null
+++ b/sys/src/cmd/hg/templates/raw/error.tmpl
@@ -0,0 +1,2 @@
+{header}
+error: {error}
diff --git a/sys/src/cmd/hg/templates/raw/fileannotate.tmpl b/sys/src/cmd/hg/templates/raw/fileannotate.tmpl
new file mode 100644
index 000000000..ad1bed62a
--- /dev/null
+++ b/sys/src/cmd/hg/templates/raw/fileannotate.tmpl
@@ -0,0 +1,5 @@
+{header}
+{annotate%annotateline}
+{footer}
+
+
diff --git a/sys/src/cmd/hg/templates/raw/filediff.tmpl b/sys/src/cmd/hg/templates/raw/filediff.tmpl
new file mode 100644
index 000000000..c4014bc69
--- /dev/null
+++ b/sys/src/cmd/hg/templates/raw/filediff.tmpl
@@ -0,0 +1,5 @@
+{header}
+{diff}
+{footer}
+
+
diff --git a/sys/src/cmd/hg/templates/raw/index.tmpl b/sys/src/cmd/hg/templates/raw/index.tmpl
new file mode 100644
index 000000000..29d7c9e1e
--- /dev/null
+++ b/sys/src/cmd/hg/templates/raw/index.tmpl
@@ -0,0 +1,2 @@
+{header}
+{entries%indexentry}
diff --git a/sys/src/cmd/hg/templates/raw/manifest.tmpl b/sys/src/cmd/hg/templates/raw/manifest.tmpl
new file mode 100644
index 000000000..8d4a934e9
--- /dev/null
+++ b/sys/src/cmd/hg/templates/raw/manifest.tmpl
@@ -0,0 +1,3 @@
+{header}
+{dentries%direntry}{fentries%fileentry}
+{footer}
diff --git a/sys/src/cmd/hg/templates/raw/map b/sys/src/cmd/hg/templates/raw/map
new file mode 100644
index 000000000..2c14d095b
--- /dev/null
+++ b/sys/src/cmd/hg/templates/raw/map
@@ -0,0 +1,23 @@
+mimetype = 'text/plain; charset={encoding}'
+header = ''
+footer = ''
+changeset = changeset.tmpl
+difflineplus = '{line}'
+difflineminus = '{line}'
+difflineat = '{line}'
+diffline = '{line}'
+changesetparent = '# Parent {node}'
+changesetchild = '# Child {node}'
+filenodelink = ''
+fileline = '{line}'
+diffblock = '{lines}'
+filediff = filediff.tmpl
+fileannotate = fileannotate.tmpl
+annotateline = '{author|user}@{rev}: {line}'
+manifest = manifest.tmpl
+direntry = 'drwxr-xr-x {basename}\n'
+fileentry = '{permissions|permissions} {size} {basename}\n'
+index = index.tmpl
+notfound = notfound.tmpl
+error = error.tmpl
+indexentry = '{url}\n'
diff --git a/sys/src/cmd/hg/templates/raw/notfound.tmpl b/sys/src/cmd/hg/templates/raw/notfound.tmpl
new file mode 100644
index 000000000..a7b325110
--- /dev/null
+++ b/sys/src/cmd/hg/templates/raw/notfound.tmpl
@@ -0,0 +1,2 @@
+{header}
+error: repository {repo} not found
diff --git a/sys/src/cmd/hg/templates/rss/changelog.tmpl b/sys/src/cmd/hg/templates/rss/changelog.tmpl
new file mode 100644
index 000000000..65b96ad9e
--- /dev/null
+++ b/sys/src/cmd/hg/templates/rss/changelog.tmpl
@@ -0,0 +1,6 @@
+{header}
+ <title>{repo|escape} Changelog</title>
+ <description>{repo|escape} Changelog</description>
+ {entries%changelogentry}
+ </channel>
+</rss> \ No newline at end of file
diff --git a/sys/src/cmd/hg/templates/rss/changelogentry.tmpl b/sys/src/cmd/hg/templates/rss/changelogentry.tmpl
new file mode 100644
index 000000000..12fe8e05c
--- /dev/null
+++ b/sys/src/cmd/hg/templates/rss/changelogentry.tmpl
@@ -0,0 +1,7 @@
+<item>
+ <title>{desc|strip|firstline|strip|escape}</title>
+ <guid isPermaLink="true">{urlbase}{url}rev/{node|short}</guid>
+ <description><![CDATA[{desc|strip|escape|addbreaks|nonempty}]]></description>
+ <author>{author|obfuscate}</author>
+ <pubDate>{date|rfc822date}</pubDate>
+</item>
diff --git a/sys/src/cmd/hg/templates/rss/error.tmpl b/sys/src/cmd/hg/templates/rss/error.tmpl
new file mode 100644
index 000000000..87e6009ce
--- /dev/null
+++ b/sys/src/cmd/hg/templates/rss/error.tmpl
@@ -0,0 +1,10 @@
+{header}
+ <title>Error</title>
+ <description>Error</description>
+ <item>
+ <title>Error</title>
+ <description>{error|escape}</description>
+ <guid>http://mercurial.selenic.com/#error</guid>
+ </item>
+ </channel>
+</rss>
diff --git a/sys/src/cmd/hg/templates/rss/filelog.tmpl b/sys/src/cmd/hg/templates/rss/filelog.tmpl
new file mode 100644
index 000000000..31f4dc78b
--- /dev/null
+++ b/sys/src/cmd/hg/templates/rss/filelog.tmpl
@@ -0,0 +1,6 @@
+{header}
+ <title>{repo|escape}: {file|escape} history</title>
+ <description>{file|escape} revision history</description>
+ {entries%filelogentry}
+ </channel>
+</rss>
diff --git a/sys/src/cmd/hg/templates/rss/filelogentry.tmpl b/sys/src/cmd/hg/templates/rss/filelogentry.tmpl
new file mode 100644
index 000000000..220dc4a24
--- /dev/null
+++ b/sys/src/cmd/hg/templates/rss/filelogentry.tmpl
@@ -0,0 +1,7 @@
+<item>
+ <title>{desc|strip|firstline|strip|escape}</title>
+ <link>{urlbase}{url}log{{node|short}}/{file|urlescape}</link>
+ <description><![CDATA[{desc|strip|escape|addbreaks|nonempty}]]></description>
+ <author>{author|obfuscate}</author>
+ <pubDate>{date|rfc822date}</pubDate>
+</item>
diff --git a/sys/src/cmd/hg/templates/rss/header.tmpl b/sys/src/cmd/hg/templates/rss/header.tmpl
new file mode 100644
index 000000000..ed29196d3
--- /dev/null
+++ b/sys/src/cmd/hg/templates/rss/header.tmpl
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="{encoding}"?>
+<rss version="2.0">
+ <channel>
+ <link>{urlbase}{url}</link>
+ <language>en-us</language>
diff --git a/sys/src/cmd/hg/templates/rss/map b/sys/src/cmd/hg/templates/rss/map
new file mode 100644
index 000000000..2f777b796
--- /dev/null
+++ b/sys/src/cmd/hg/templates/rss/map
@@ -0,0 +1,10 @@
+default = 'changelog'
+mimetype = 'text/xml; charset={encoding}'
+header = header.tmpl
+changelog = changelog.tmpl
+changelogentry = changelogentry.tmpl
+filelog = filelog.tmpl
+filelogentry = filelogentry.tmpl
+tags = tags.tmpl
+tagentry = tagentry.tmpl
+error = error.tmpl
diff --git a/sys/src/cmd/hg/templates/rss/tagentry.tmpl b/sys/src/cmd/hg/templates/rss/tagentry.tmpl
new file mode 100644
index 000000000..42fa038f6
--- /dev/null
+++ b/sys/src/cmd/hg/templates/rss/tagentry.tmpl
@@ -0,0 +1,6 @@
+<item>
+ <title>{tag|escape}</title>
+ <link>{urlbase}{url}rev/{node|short}</link>
+ <description><![CDATA[{tag|strip|escape|addbreaks}]]></description>
+ <pubDate>{date|rfc822date}</pubDate>
+</item>
diff --git a/sys/src/cmd/hg/templates/rss/tags.tmpl b/sys/src/cmd/hg/templates/rss/tags.tmpl
new file mode 100644
index 000000000..93f1e96b5
--- /dev/null
+++ b/sys/src/cmd/hg/templates/rss/tags.tmpl
@@ -0,0 +1,6 @@
+{header}
+ <title>{repo|escape}: tags </title>
+ <description>{repo|escape} tag history</description>
+ {entriesnotip%tagentry}
+ </channel>
+</rss>
diff --git a/sys/src/cmd/hg/templates/spartan/branches.tmpl b/sys/src/cmd/hg/templates/spartan/branches.tmpl
new file mode 100644
index 000000000..883050163
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/branches.tmpl
@@ -0,0 +1,26 @@
+{header}
+<title>{repo|escape}: branches</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-branches" title="Atom feed for {repo|escape}: branches">
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-branches" title="RSS feed for {repo|escape}: branches">
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}file/{node|short}/{sessionvars%urlparameter}">files</a>
+<a type="application/rss+xml" href="{url}rss-branches">rss</a>
+<a type="application/atom+xml" href="{url}atom-branches">atom</a>
+</div>
+
+<h2>branches:</h2>
+
+<ul id="tagEntries">
+{entries%branchentry}
+</ul>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/changelog.tmpl b/sys/src/cmd/hg/templates/spartan/changelog.tmpl
new file mode 100644
index 000000000..710d7b6ef
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/changelog.tmpl
@@ -0,0 +1,43 @@
+{header}
+<title>{repo|escape}: changelog</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}">
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}">
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}shortlog/{rev}{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+{archives%archiveentry}
+<a type="application/rss+xml" href="{url}rss-log">rss</a>
+<a type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}">atom</a>
+</div>
+
+<h2>changelog for {repo|escape}</h2>
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<p>
+<label for="search1">search:</label>
+<input name="rev" id="search1" type="text" size="30">
+navigate: <small class="navigate">{changenav%naventry}</small>
+</p>
+</form>
+
+{entries%changelogentry}
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<p>
+<label for="search2">search:</label>
+<input name="rev" id="search2" type="text" size="30">
+navigate: <small class="navigate">{changenav%naventry}</small>
+</p>
+</form>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/changelogentry.tmpl b/sys/src/cmd/hg/templates/spartan/changelogentry.tmpl
new file mode 100644
index 000000000..e4d2c0ef5
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/changelogentry.tmpl
@@ -0,0 +1,25 @@
+<table class="logEntry parity{parity}">
+ <tr>
+ <th class="age">{date|age} ago:</th>
+ <th class="firstline">{desc|strip|firstline|escape|nonempty}</th>
+ </tr>
+ <tr>
+ <th class="revision">changeset {rev}:</th>
+ <td class="node"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>
+ {parent%changelogparent}
+ {child%changelogchild}
+ {changelogtag}
+ <tr>
+ <th class="author">author:</th>
+ <td class="author">{author|obfuscate}</td>
+ </tr>
+ <tr>
+ <th class="date">date:</th>
+ <td class="date">{date|date}</td>
+ </tr>
+ <tr>
+ <th class="files"><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>:</th>
+ <td class="files">{files}</td>
+ </tr>
+</table>
diff --git a/sys/src/cmd/hg/templates/spartan/changeset.tmpl b/sys/src/cmd/hg/templates/spartan/changeset.tmpl
new file mode 100644
index 000000000..4826c08a1
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/changeset.tmpl
@@ -0,0 +1,51 @@
+{header}
+<title>{repo|escape}: changeset {node|short}</title>
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog/{rev}{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+<a href="{url}raw-rev/{node|short}">raw</a>
+{archives%archiveentry}
+</div>
+
+<h2>changeset: {desc|strip|escape|firstline|nonempty}</h2>
+
+<table id="changesetEntry">
+<tr>
+ <th class="changeset">changeset {rev}:</th>
+ <td class="changeset"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+</tr>
+{parent%changesetparent}
+{child%changesetchild}
+{changesettag}
+<tr>
+ <th class="author">author:</th>
+ <td class="author">{author|obfuscate}</td>
+</tr>
+<tr>
+ <th class="date">date:</th>
+ <td class="date">{date|date} ({date|age} ago)</td>
+</tr>
+<tr>
+ <th class="files">files:</th>
+ <td class="files">{files}</td>
+</tr>
+<tr>
+ <th class="description">description:</th>
+ <td class="description">{desc|strip|escape|addbreaks|nonempty}</td>
+</tr>
+</table>
+
+<div id="changesetDiff">
+{diff}
+</div>
+
+{footer}
+
+
diff --git a/sys/src/cmd/hg/templates/spartan/error.tmpl b/sys/src/cmd/hg/templates/spartan/error.tmpl
new file mode 100644
index 000000000..fc2c78866
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/error.tmpl
@@ -0,0 +1,15 @@
+{header}
+<title>Mercurial Error</title>
+</head>
+<body>
+
+<h2>Mercurial Error</h2>
+
+<p>
+An error occurred while processing your request:
+</p>
+<p>
+{error|escape}
+</p>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/fileannotate.tmpl b/sys/src/cmd/hg/templates/spartan/fileannotate.tmpl
new file mode 100644
index 000000000..2631fbe97
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/fileannotate.tmpl
@@ -0,0 +1,48 @@
+{header}
+<title>{repo|escape}: {file|escape} annotate</title>
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog/{rev}{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a>
+<a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a>
+<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>
+<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
+<a href="{url}raw-annotate/{node|short}/{file|urlescape}">raw</a>
+</div>
+
+<h2>Annotate {file|escape}</h2>
+
+<table>
+<tr>
+ <td class="metatag">changeset {rev}:</td>
+ <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>
+{parent%fileannotateparent}
+{child%fileannotatechild}
+<tr>
+ <td class="metatag">author:</td>
+ <td>{author|obfuscate}</td></tr>
+<tr>
+ <td class="metatag">date:</td>
+ <td>{date|date} ({date|age} ago)</td>
+</tr>
+<tr>
+ <td class="metatag">permissions:</td>
+ <td>{permissions|permissions}</td>
+</tr>
+<tr>
+ <td class="metatag">description:</td>
+ <td>{desc|strip|escape|addbreaks|nonempty}</td>
+</tr>
+</table>
+
+<table cellspacing="0" cellpadding="0">
+{annotate%annotateline}
+</table>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/filediff.tmpl b/sys/src/cmd/hg/templates/spartan/filediff.tmpl
new file mode 100644
index 000000000..2a6b60e53
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/filediff.tmpl
@@ -0,0 +1,36 @@
+{header}
+<title>{repo|escape}: {file|escape} diff</title>
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog/{rev}{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a>
+<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>
+<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
+<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
+<a href="{url}raw-diff/{node|short}/{file|urlescape}">raw</a>
+</div>
+
+<h2>{file|escape}</h2>
+
+<table id="filediffEntry">
+<tr>
+ <th class="revision">revision {rev}:</th>
+ <td class="revision"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+</tr>
+{parent%filediffparent}
+{child%filediffchild}
+</table>
+
+<div id="fileDiff">
+{diff}
+</div>
+
+{footer}
+
+
diff --git a/sys/src/cmd/hg/templates/spartan/filelog.tmpl b/sys/src/cmd/hg/templates/spartan/filelog.tmpl
new file mode 100644
index 000000000..0cb4e8990
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/filelog.tmpl
@@ -0,0 +1,28 @@
+{header}
+<title>{repo|escape}: {file|escape} history</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log/tip/{file|urlescape}" title="Atom feed for {repo|escape}:{file}">
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log/tip/{file|urlescape}" title="RSS feed for {repo|escape}:{file}">
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>
+<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
+<a type="application/rss+xml" href="{url}rss-log/tip/{file|urlescape}">rss</a>
+<a type="application/atom+xml" href="{url}atom-log/tip/{file|urlescape}" title="Atom feed for {repo|escape}:{file}">atom</a>
+</div>
+
+<h2>{file|escape} revision history</h2>
+
+<p>navigate: <small class="navigate">{nav%filenaventry}</small></p>
+
+{entries%filelogentry}
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/filelogentry.tmpl b/sys/src/cmd/hg/templates/spartan/filelogentry.tmpl
new file mode 100644
index 000000000..526016b84
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/filelogentry.tmpl
@@ -0,0 +1,25 @@
+<table class="logEntry parity{parity}">
+ <tr>
+ <th class="age">{date|age} ago:</th>
+ <th class="firstline"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></th>
+ </tr>
+ <tr>
+ <th class="revision">revision {filerev}:</td>
+ <td class="node">
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
+ <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">(diff)</a>
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">(annotate)</a>
+ </td>
+ </tr>
+ {rename%filelogrename}
+ <tr>
+ <th class="author">author:</th>
+ <td class="author">{author|obfuscate}</td>
+ </tr>
+ <tr>
+ <th class="date">date:</th>
+ <td class="date">{date|date}</td>
+ </tr>
+</table>
+
+
diff --git a/sys/src/cmd/hg/templates/spartan/filerevision.tmpl b/sys/src/cmd/hg/templates/spartan/filerevision.tmpl
new file mode 100644
index 000000000..b13695d23
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/filerevision.tmpl
@@ -0,0 +1,46 @@
+{header}
+<title>{repo|escape}:{file|escape}</title>
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog/{rev}{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a>
+<a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a>
+<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
+<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
+<a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a>
+</div>
+
+<h2>{file|escape}</h2>
+
+<table>
+<tr>
+ <td class="metatag">changeset {rev}:</td>
+ <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>
+{parent%filerevparent}
+{child%filerevchild}
+<tr>
+ <td class="metatag">author:</td>
+ <td>{author|obfuscate}</td></tr>
+<tr>
+ <td class="metatag">date:</td>
+ <td>{date|date} ({date|age} ago)</td></tr>
+<tr>
+ <td class="metatag">permissions:</td>
+ <td>{permissions|permissions}</td></tr>
+<tr>
+ <td class="metatag">description:</td>
+ <td>{desc|strip|escape|addbreaks|nonempty}</td>
+</tr>
+</table>
+
+<pre>
+{text%fileline}
+</pre>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/footer.tmpl b/sys/src/cmd/hg/templates/spartan/footer.tmpl
new file mode 100644
index 000000000..afcb2d08f
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/footer.tmpl
@@ -0,0 +1,8 @@
+{motd}
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
+</div>
+
+</body>
+</html>
diff --git a/sys/src/cmd/hg/templates/spartan/graph.tmpl b/sys/src/cmd/hg/templates/spartan/graph.tmpl
new file mode 100644
index 000000000..62c3ea0d6
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/graph.tmpl
@@ -0,0 +1,96 @@
+{header}
+<title>{repo|escape}: graph</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-tags" title="Atom feed for {repo|escape}: tags">
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-tags" title="RSS feed for {repo|escape}: tags">
+<!--[if IE]><script type="text/javascript" src="{staticurl}excanvas.js"></script><![endif]-->
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}file/{node|short}/{sessionvars%urlparameter}">files</a>
+</div>
+
+<h2>graph</h2>
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<p>
+<label for="search1">search:</label>
+<input name="rev" id="search1" type="text" size="30">
+navigate: <small class="navigate">{changenav%navgraphentry}</small>
+</p>
+</form>
+
+<noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
+
+<div id="wrapper">
+<ul id="nodebgs"></ul>
+<canvas id="graph" width="224" height="{canvasheight}"></canvas>
+<ul id="graphnodes"></ul>
+</div>
+
+<script type="text/javascript" src="{staticurl}graph.js"></script>
+<script type="text/javascript">
+<!-- hide script content
+
+var data = {jsdata|json};
+var graph = new Graph();
+graph.scale({bg_height});
+
+graph.edge = function(x0, y0, x1, y1, color) {
+
+ this.setColor(color, 0.0, 0.65);
+ this.ctx.beginPath();
+ this.ctx.moveTo(x0, y0);
+ this.ctx.lineTo(x1, y1);
+ this.ctx.stroke();
+
+}
+
+var revlink = '<li style="_STYLE"><span class="desc">';
+revlink += '<a href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID">_DESC</a>';
+revlink += '</span><span class="info">_DATE ago, by _USER</span></li>';
+
+graph.vertex = function(x, y, color, parity, cur) {
+
+ this.ctx.beginPath();
+ color = this.setColor(color, 0.25, 0.75);
+ this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
+ this.ctx.fill();
+
+ var bg = '<li class="bg parity' + parity + '"></li>';
+ var left = (this.columns + 1) * this.bg_height;
+ var nstyle = 'padding-left: ' + left + 'px;';
+ var item = revlink.replace(/_STYLE/, nstyle);
+ item = item.replace(/_PARITY/, 'parity' + parity);
+ item = item.replace(/_NODEID/, cur[0]);
+ item = item.replace(/_NODEID/, cur[0]);
+ item = item.replace(/_DESC/, cur[3]);
+ item = item.replace(/_USER/, cur[4]);
+ item = item.replace(/_DATE/, cur[5]);
+
+ return [bg, item];
+
+}
+
+graph.render(data);
+
+// stop hiding script -->
+</script>
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<p>
+<label for="search1">search:</label>
+<input name="rev" id="search1" type="text" size="30">
+navigate: <small class="navigate">{changenav%navgraphentry}</small>
+</p>
+</form>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/header.tmpl b/sys/src/cmd/hg/templates/spartan/header.tmpl
new file mode 100644
index 000000000..646b2fe30
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/header.tmpl
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<link rel="icon" href="{staticurl}hgicon.png" type="image/png">
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="{staticurl}style.css" type="text/css" />
diff --git a/sys/src/cmd/hg/templates/spartan/index.tmpl b/sys/src/cmd/hg/templates/spartan/index.tmpl
new file mode 100644
index 000000000..bf8d4de9f
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/index.tmpl
@@ -0,0 +1,19 @@
+{header}
+<title>Mercurial repositories index</title>
+</head>
+<body>
+
+<h2>Mercurial Repositories</h2>
+
+<table>
+ <tr>
+ <td><a href="?sort={sort_name}">Name</a></td>
+ <td><a href="?sort={sort_description}">Description</a></td>
+ <td><a href="?sort={sort_contact}">Contact</a></td>
+ <td><a href="?sort={sort_lastchange}">Last change</a></td>
+ <td>&nbsp;</td>
+ </tr>
+ {entries%indexentry}
+</table>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/manifest.tmpl b/sys/src/cmd/hg/templates/spartan/manifest.tmpl
new file mode 100644
index 000000000..5b2e881a8
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/manifest.tmpl
@@ -0,0 +1,28 @@
+{header}
+<title>{repo|escape}: files for changeset {node|short}</title>
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog/{rev}{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a>
+{archives%archiveentry}
+</div>
+
+<h2>files for changeset {node|short}: {path|escape}</h2>
+
+<table cellpadding="0" cellspacing="0">
+<tr class="parity{upparity}">
+ <td><tt>drwxr-xr-x</tt>&nbsp;
+ <td>&nbsp;
+ <td>&nbsp;
+ <td><a href="{url}file/{node|short}{up|urlescape}{sessionvars%urlparameter}">[up]</a>
+</tr>
+{dentries%direntry}
+{fentries%fileentry}
+</table>
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/map b/sys/src/cmd/hg/templates/spartan/map
new file mode 100644
index 000000000..4432972ef
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/map
@@ -0,0 +1,178 @@
+default = 'shortlog'
+mimetype = 'text/html; charset={encoding}'
+header = header.tmpl
+footer = footer.tmpl
+search = search.tmpl
+changelog = changelog.tmpl
+shortlog = shortlog.tmpl
+shortlogentry = shortlogentry.tmpl
+graph = graph.tmpl
+naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
+filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenolink = '{file|escape} '
+fileellipses = '...'
+changelogentry = changelogentry.tmpl
+searchentry = changelogentry.tmpl
+changeset = changeset.tmpl
+manifest = manifest.tmpl
+
+direntry = '
+ <tr class="parity{parity}">
+ <td><tt>drwxr-xr-x</tt>&nbsp;
+ <td>&nbsp;
+ <td>&nbsp;
+ <td>
+ <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}/</a>
+ <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
+ {emptydirs|urlescape}
+ </a>'
+
+fileentry = '
+ <tr class="parity{parity}">
+ <td><tt>{permissions|permissions}</tt>&nbsp;
+ <td align=right><tt class="date">{date|isodate}</tt>&nbsp;
+ <td align=right><tt>{size}</tt>&nbsp;
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>'
+
+filerevision = filerevision.tmpl
+fileannotate = fileannotate.tmpl
+filediff = filediff.tmpl
+filelog = filelog.tmpl
+fileline = '<div class="parity{parity}"><a class="lineno" href="#{lineid}" id="{lineid}">{linenumber}</a>&nbsp;{line|escape}</div>'
+filelogentry = filelogentry.tmpl
+
+# The &nbsp; ensures that all table cells have content (even if there
+# is an empty line in the annotated file), which in turn ensures that
+# all table rows have equal height.
+annotateline = '
+ <tr class="parity{parity}">
+ <td class="annotate">
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
+ title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
+ </td>
+ <td>
+ <a class="lineno" href="#{lineid}" id="{lineid}">{linenumber}</a>
+ </td>
+ <td><pre>&nbsp;{line|escape}</pre></td>
+ </tr>'
+difflineplus = '<span class="plusline"><a class="lineno" href="#{lineid}" id="{lineid}">{linenumber}</a>{line|escape}</span>'
+difflineminus = '<span class="minusline"><a class="lineno" href="#{lineid}" id="{lineid}">{linenumber}</a>{line|escape}</span>'
+difflineat = '<span class="atline"><a class="lineno" href="#{lineid}" id="{lineid}">{linenumber}</a>{line|escape}</span>'
+diffline = '<a class="lineno" href="#{lineid}" id="{lineid}">{linenumber}</a>{line|escape}'
+changelogparent = '
+ <tr>
+ <th class="parent">parent {rev}:</th>
+ <td class="parent">
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ </td>
+ </tr>'
+changesetparent = '
+ <tr>
+ <th class="parent">parent {rev}:</th>
+ <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filerevparent = '
+ <tr>
+ <td class="metatag">parent:</td>
+ <td>
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {rename%filerename}{node|short}
+ </a>
+ </td>
+ </tr>'
+filerename = '{file|escape}@'
+filelogrename = '
+ <tr>
+ <th>base:</th>
+ <td>
+ <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {file|escape}@{node|short}
+ </a>
+ </td>
+ </tr>'
+fileannotateparent = '
+ <tr>
+ <td class="metatag">parent:</td>
+ <td>
+ <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+ {rename%filerename}{node|short}
+ </a>
+ </td>
+ </tr>'
+changesetchild = '
+ <tr>
+ <th class="child">child {rev}:</th>
+ <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+changelogchild = '
+ <tr>
+ <th class="child">child {rev}:</th>
+ <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filerevchild = '
+ <tr>
+ <td class="metatag">child:</td>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+fileannotatechild = '
+ <tr>
+ <td class="metatag">child:</td>
+ <td><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+tags = tags.tmpl
+tagentry = '
+ <li class="tagEntry parity{parity}">
+ <tt class="node">{node}</tt>
+ <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a>
+ </li>'
+branches = branches.tmpl
+branchentry = '
+ <li class="tagEntry parity{parity}">
+ <tt class="node">{node}</tt>
+ <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">{branch|escape}</a>
+ </li>'
+diffblock = '<pre class="parity{parity}">{lines}</pre>'
+changelogtag = '<tr><th class="tag">tag:</th><td class="tag">{tag|escape}</td></tr>'
+changesettag = '<tr><th class="tag">tag:</th><td class="tag">{tag|escape}</td></tr>'
+filediffparent = '
+ <tr>
+ <th class="parent">parent {rev}:</th>
+ <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filelogparent = '
+ <tr>
+ <th>parent {rev}:</th>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filediffchild = '
+ <tr>
+ <th class="child">child {rev}:</th>
+ <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+filelogchild = '
+ <tr>
+ <th>child {rev}:</th>
+ <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
+ </tr>'
+indexentry = '
+ <tr class="parity{parity}">
+ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
+ <td>{description}</td>
+ <td>{contact|obfuscate}</td>
+ <td class="age">{lastchange|age} ago</td>
+ <td class="indexlinks">
+ <a href="{url}rss-log">RSS</a>
+ <a href="{url}atom-log">Atom</a>
+ {archives%archiveentry}
+ </td>
+ </tr>'
+index = index.tmpl
+archiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a> '
+notfound = notfound.tmpl
+error = error.tmpl
+urlparameter = '{separator}{name}={value|urlescape}'
+hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
diff --git a/sys/src/cmd/hg/templates/spartan/notfound.tmpl b/sys/src/cmd/hg/templates/spartan/notfound.tmpl
new file mode 100644
index 000000000..e9e6ba420
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/notfound.tmpl
@@ -0,0 +1,12 @@
+{header}
+<title>Mercurial repository not found</title>
+</head>
+<body>
+
+<h2>Mercurial repository not found</h2>
+
+The specified repository "{repo|escape}" is unknown, sorry.
+
+Please go back to the <a href="{url}">main repository list page</a>.
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/search.tmpl b/sys/src/cmd/hg/templates/spartan/search.tmpl
new file mode 100644
index 000000000..4987a5924
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/search.tmpl
@@ -0,0 +1,36 @@
+{header}
+<title>{repo|escape}: searching for {query|escape}</title>
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
+{archives%archiveentry}
+</div>
+
+<h2>searching for {query|escape}</h2>
+
+<form>
+{sessionvars%hiddenformentry}
+<p>
+search:
+<input name="rev" type="text" width="30" value="{query|escape}">
+</p>
+</form>
+
+{entries}
+
+<form>
+{sessionvars%hiddenformentry}
+<p>
+search:
+<input name="rev" type="text" width="30" value="{query|escape}">
+</p>
+</form>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/shortlog.tmpl b/sys/src/cmd/hg/templates/spartan/shortlog.tmpl
new file mode 100644
index 000000000..1560c63d2
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/shortlog.tmpl
@@ -0,0 +1,43 @@
+{header}
+<title>{repo|escape}: shortlog</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-log" title="Atom feed for {repo|escape}">
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-log" title="RSS feed for {repo|escape}">
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}file/{node|short}/{sessionvars%urlparameter}">files</a>
+{archives%archiveentry}
+<a type="application/rss+xml" href="{url}rss-log">rss</a>
+<a type="application/rss+xml" href="{url}atom-log" title="Atom feed for {repo|escape}">atom</a>
+</div>
+
+<h2>shortlog for {repo|escape}</h2>
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<p>
+<label for="search1">search:</label>
+<input name="rev" id="search1" type="text" size="30">
+navigate: <small class="navigate">{changenav%navshortentry}</small>
+</p>
+</form>
+
+{entries%shortlogentry}
+
+<form action="{url}log">
+{sessionvars%hiddenformentry}
+<p>
+<label for="search2">search:</label>
+<input name="rev" id="search2" type="text" size="30">
+navigate: <small class="navigate">{changenav%navshortentry}</small>
+</p>
+</form>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/spartan/shortlogentry.tmpl b/sys/src/cmd/hg/templates/spartan/shortlogentry.tmpl
new file mode 100644
index 000000000..b6857db80
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/shortlogentry.tmpl
@@ -0,0 +1,7 @@
+<table class="slogEntry parity{parity}">
+ <tr>
+ <td class="age">{date|age}</td>
+ <td class="author">{author|person}</td>
+ <td class="node"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td>
+ </tr>
+</table>
diff --git a/sys/src/cmd/hg/templates/spartan/tags.tmpl b/sys/src/cmd/hg/templates/spartan/tags.tmpl
new file mode 100644
index 000000000..029452d1b
--- /dev/null
+++ b/sys/src/cmd/hg/templates/spartan/tags.tmpl
@@ -0,0 +1,26 @@
+{header}
+<title>{repo|escape}: tags</title>
+<link rel="alternate" type="application/atom+xml"
+ href="{url}atom-tags" title="Atom feed for {repo|escape}: tags">
+<link rel="alternate" type="application/rss+xml"
+ href="{url}rss-tags" title="RSS feed for {repo|escape}: tags">
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log{sessionvars%urlparameter}">changelog</a>
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+<a href="{url}file/{node|short}/{sessionvars%urlparameter}">files</a>
+<a type="application/rss+xml" href="{url}rss-tags">rss</a>
+<a type="application/atom+xml" href="{url}atom-tags">atom</a>
+</div>
+
+<h2>tags:</h2>
+
+<ul id="tagEntries">
+{entries%tagentry}
+</ul>
+
+{footer}
diff --git a/sys/src/cmd/hg/templates/static/background.png b/sys/src/cmd/hg/templates/static/background.png
new file mode 100644
index 000000000..af8a0aa4e
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/background.png
Binary files differ
diff --git a/sys/src/cmd/hg/templates/static/coal-file.png b/sys/src/cmd/hg/templates/static/coal-file.png
new file mode 100644
index 000000000..7ecf4632e
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/coal-file.png
Binary files differ
diff --git a/sys/src/cmd/hg/templates/static/coal-folder.png b/sys/src/cmd/hg/templates/static/coal-folder.png
new file mode 100644
index 000000000..d1b8ecc07
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/coal-folder.png
Binary files differ
diff --git a/sys/src/cmd/hg/templates/static/excanvas.js b/sys/src/cmd/hg/templates/static/excanvas.js
new file mode 100644
index 000000000..9d71658ad
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/excanvas.js
@@ -0,0 +1,19 @@
+if(!window.CanvasRenderingContext2D){(function(){var I=Math,i=I.round,L=I.sin,M=I.cos,m=10,A=m/2,Q={init:function(a){var b=a||document;if(/MSIE/.test(navigator.userAgent)&&!window.opera){var c=this;b.attachEvent("onreadystatechange",function(){c.r(b)})}},r:function(a){if(a.readyState=="complete"){if(!a.namespaces["s"]){a.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml")}var b=a.createStyleSheet();b.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}";
+var c=a.getElementsByTagName("canvas");for(var d=0;d<c.length;d++){if(!c[d].getContext){this.initElement(c[d])}}}},q:function(a){var b=a.outerHTML,c=a.ownerDocument.createElement(b);if(b.slice(-2)!="/>"){var d="/"+a.tagName,e;while((e=a.nextSibling)&&e.tagName!=d){e.removeNode()}if(e){e.removeNode()}}a.parentNode.replaceChild(c,a);return c},initElement:function(a){a=this.q(a);a.getContext=function(){if(this.l){return this.l}return this.l=new K(this)};a.attachEvent("onpropertychange",V);a.attachEvent("onresize",
+W);var b=a.attributes;if(b.width&&b.width.specified){a.style.width=b.width.nodeValue+"px"}else{a.width=a.clientWidth}if(b.height&&b.height.specified){a.style.height=b.height.nodeValue+"px"}else{a.height=a.clientHeight}return a}};function V(a){var b=a.srcElement;switch(a.propertyName){case "width":b.style.width=b.attributes.width.nodeValue+"px";b.getContext().clearRect();break;case "height":b.style.height=b.attributes.height.nodeValue+"px";b.getContext().clearRect();break}}function W(a){var b=a.srcElement;
+if(b.firstChild){b.firstChild.style.width=b.clientWidth+"px";b.firstChild.style.height=b.clientHeight+"px"}}Q.init();var R=[];for(var E=0;E<16;E++){for(var F=0;F<16;F++){R[E*16+F]=E.toString(16)+F.toString(16)}}function J(){return[[1,0,0],[0,1,0],[0,0,1]]}function G(a,b){var c=J();for(var d=0;d<3;d++){for(var e=0;e<3;e++){var g=0;for(var h=0;h<3;h++){g+=a[d][h]*b[h][e]}c[d][e]=g}}return c}function N(a,b){b.fillStyle=a.fillStyle;b.lineCap=a.lineCap;b.lineJoin=a.lineJoin;b.lineWidth=a.lineWidth;b.miterLimit=
+a.miterLimit;b.shadowBlur=a.shadowBlur;b.shadowColor=a.shadowColor;b.shadowOffsetX=a.shadowOffsetX;b.shadowOffsetY=a.shadowOffsetY;b.strokeStyle=a.strokeStyle;b.d=a.d;b.e=a.e}function O(a){var b,c=1;a=String(a);if(a.substring(0,3)=="rgb"){var d=a.indexOf("(",3),e=a.indexOf(")",d+1),g=a.substring(d+1,e).split(",");b="#";for(var h=0;h<3;h++){b+=R[Number(g[h])]}if(g.length==4&&a.substr(3,1)=="a"){c=g[3]}}else{b=a}return[b,c]}function S(a){switch(a){case "butt":return"flat";case "round":return"round";
+case "square":default:return"square"}}function K(a){this.a=J();this.m=[];this.k=[];this.c=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=m*1;this.globalAlpha=1;this.canvas=a;var b=a.ownerDocument.createElement("div");b.style.width=a.clientWidth+"px";b.style.height=a.clientHeight+"px";b.style.overflow="hidden";b.style.position="absolute";a.appendChild(b);this.j=b;this.d=1;this.e=1}var j=K.prototype;j.clearRect=function(){this.j.innerHTML=
+"";this.c=[]};j.beginPath=function(){this.c=[]};j.moveTo=function(a,b){this.c.push({type:"moveTo",x:a,y:b});this.f=a;this.g=b};j.lineTo=function(a,b){this.c.push({type:"lineTo",x:a,y:b});this.f=a;this.g=b};j.bezierCurveTo=function(a,b,c,d,e,g){this.c.push({type:"bezierCurveTo",cp1x:a,cp1y:b,cp2x:c,cp2y:d,x:e,y:g});this.f=e;this.g=g};j.quadraticCurveTo=function(a,b,c,d){var e=this.f+0.6666666666666666*(a-this.f),g=this.g+0.6666666666666666*(b-this.g),h=e+(c-this.f)/3,l=g+(d-this.g)/3;this.bezierCurveTo(e,
+g,h,l,c,d)};j.arc=function(a,b,c,d,e,g){c*=m;var h=g?"at":"wa",l=a+M(d)*c-A,n=b+L(d)*c-A,o=a+M(e)*c-A,f=b+L(e)*c-A;if(l==o&&!g){l+=0.125}this.c.push({type:h,x:a,y:b,radius:c,xStart:l,yStart:n,xEnd:o,yEnd:f})};j.rect=function(a,b,c,d){this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath()};j.strokeRect=function(a,b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.stroke()};j.fillRect=function(a,
+b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.fill()};j.createLinearGradient=function(a,b,c,d){var e=new H("gradient");return e};j.createRadialGradient=function(a,b,c,d,e,g){var h=new H("gradientradial");h.n=c;h.o=g;h.i.x=a;h.i.y=b;return h};j.drawImage=function(a,b){var c,d,e,g,h,l,n,o,f=a.runtimeStyle.width,k=a.runtimeStyle.height;a.runtimeStyle.width="auto";a.runtimeStyle.height="auto";var q=a.width,r=a.height;a.runtimeStyle.width=
+f;a.runtimeStyle.height=k;if(arguments.length==3){c=arguments[1];d=arguments[2];h=(l=0);n=(e=q);o=(g=r)}else if(arguments.length==5){c=arguments[1];d=arguments[2];e=arguments[3];g=arguments[4];h=(l=0);n=q;o=r}else if(arguments.length==9){h=arguments[1];l=arguments[2];n=arguments[3];o=arguments[4];c=arguments[5];d=arguments[6];e=arguments[7];g=arguments[8]}else{throw"Invalid number of arguments";}var s=this.b(c,d),t=[],v=10,w=10;t.push(" <g_vml_:group",' coordsize="',m*v,",",m*w,'"',' coordorigin="0,0"',
+' style="width:',v,";height:",w,";position:absolute;");if(this.a[0][0]!=1||this.a[0][1]){var x=[];x.push("M11='",this.a[0][0],"',","M12='",this.a[1][0],"',","M21='",this.a[0][1],"',","M22='",this.a[1][1],"',","Dx='",i(s.x/m),"',","Dy='",i(s.y/m),"'");var p=s,y=this.b(c+e,d),z=this.b(c,d+g),B=this.b(c+e,d+g);p.x=Math.max(p.x,y.x,z.x,B.x);p.y=Math.max(p.y,y.y,z.y,B.y);t.push("padding:0 ",i(p.x/m),"px ",i(p.y/m),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",x.join(""),", sizingmethod='clip');")}else{t.push("top:",
+i(s.y/m),"px;left:",i(s.x/m),"px;")}t.push(' ">','<g_vml_:image src="',a.src,'"',' style="width:',m*e,";"," height:",m*g,';"',' cropleft="',h/q,'"',' croptop="',l/r,'"',' cropright="',(q-h-n)/q,'"',' cropbottom="',(r-l-o)/r,'"'," />","</g_vml_:group>");this.j.insertAdjacentHTML("BeforeEnd",t.join(""))};j.stroke=function(a){var b=[],c=O(a?this.fillStyle:this.strokeStyle),d=c[0],e=c[1]*this.globalAlpha,g=10,h=10;b.push("<g_vml_:shape",' fillcolor="',d,'"',' filled="',Boolean(a),'"',' style="position:absolute;width:',
+g,";height:",h,';"',' coordorigin="0 0" coordsize="',m*g," ",m*h,'"',' stroked="',!a,'"',' strokeweight="',this.lineWidth,'"',' strokecolor="',d,'"',' path="');var l={x:null,y:null},n={x:null,y:null};for(var o=0;o<this.c.length;o++){var f=this.c[o];if(f.type=="moveTo"){b.push(" m ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="lineTo"){b.push(" l ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="close"){b.push(" x ")}else if(f.type=="bezierCurveTo"){b.push(" c ");
+var k=this.b(f.x,f.y),q=this.b(f.cp1x,f.cp1y),r=this.b(f.cp2x,f.cp2y);b.push(i(q.x),",",i(q.y),",",i(r.x),",",i(r.y),",",i(k.x),",",i(k.y))}else if(f.type=="at"||f.type=="wa"){b.push(" ",f.type," ");var k=this.b(f.x,f.y),s=this.b(f.xStart,f.yStart),t=this.b(f.xEnd,f.yEnd);b.push(i(k.x-this.d*f.radius),",",i(k.y-this.e*f.radius)," ",i(k.x+this.d*f.radius),",",i(k.y+this.e*f.radius)," ",i(s.x),",",i(s.y)," ",i(t.x),",",i(t.y))}if(k){if(l.x==null||k.x<l.x){l.x=k.x}if(n.x==null||k.x>n.x){n.x=k.x}if(l.y==
+null||k.y<l.y){l.y=k.y}if(n.y==null||k.y>n.y){n.y=k.y}}}b.push(' ">');if(typeof this.fillStyle=="object"){var v={x:"50%",y:"50%"},w=n.x-l.x,x=n.y-l.y,p=w>x?w:x;v.x=i(this.fillStyle.i.x/w*100+50)+"%";v.y=i(this.fillStyle.i.y/x*100+50)+"%";var y=[];if(this.fillStyle.p=="gradientradial"){var z=this.fillStyle.n/p*100,B=this.fillStyle.o/p*100-z}else{var z=0,B=100}var C={offset:null,color:null},D={offset:null,color:null};this.fillStyle.h.sort(function(T,U){return T.offset-U.offset});for(var o=0;o<this.fillStyle.h.length;o++){var u=
+this.fillStyle.h[o];y.push(u.offset*B+z,"% ",u.color,",");if(u.offset>C.offset||C.offset==null){C.offset=u.offset;C.color=u.color}if(u.offset<D.offset||D.offset==null){D.offset=u.offset;D.color=u.color}}y.pop();b.push("<g_vml_:fill",' color="',D.color,'"',' color2="',C.color,'"',' type="',this.fillStyle.p,'"',' focusposition="',v.x,", ",v.y,'"',' colors="',y.join(""),'"',' opacity="',e,'" />')}else if(a){b.push('<g_vml_:fill color="',d,'" opacity="',e,'" />')}else{b.push("<g_vml_:stroke",' opacity="',
+e,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',S(this.lineCap),'"',' weight="',this.lineWidth,'px"',' color="',d,'" />')}b.push("</g_vml_:shape>");this.j.insertAdjacentHTML("beforeEnd",b.join(""));this.c=[]};j.fill=function(){this.stroke(true)};j.closePath=function(){this.c.push({type:"close"})};j.b=function(a,b){return{x:m*(a*this.a[0][0]+b*this.a[1][0]+this.a[2][0])-A,y:m*(a*this.a[0][1]+b*this.a[1][1]+this.a[2][1])-A}};j.save=function(){var a={};N(this,a);
+this.k.push(a);this.m.push(this.a);this.a=G(J(),this.a)};j.restore=function(){N(this.k.pop(),this);this.a=this.m.pop()};j.translate=function(a,b){var c=[[1,0,0],[0,1,0],[a,b,1]];this.a=G(c,this.a)};j.rotate=function(a){var b=M(a),c=L(a),d=[[b,c,0],[-c,b,0],[0,0,1]];this.a=G(d,this.a)};j.scale=function(a,b){this.d*=a;this.e*=b;var c=[[a,0,0],[0,b,0],[0,0,1]];this.a=G(c,this.a)};j.clip=function(){};j.arcTo=function(){};j.createPattern=function(){return new P};function H(a){this.p=a;this.n=0;this.o=
+0;this.h=[];this.i={x:0,y:0}}H.prototype.addColorStop=function(a,b){b=O(b);this.h.push({offset:1-a,color:b})};function P(){}G_vmlCanvasManager=Q;CanvasRenderingContext2D=K;CanvasGradient=H;CanvasPattern=P})()};
diff --git a/sys/src/cmd/hg/templates/static/graph.js b/sys/src/cmd/hg/templates/static/graph.js
new file mode 100644
index 000000000..0d4dcdde9
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/graph.js
@@ -0,0 +1,137 @@
+// branch_renderer.js - Rendering of branch DAGs on the client side
+//
+// Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
+// Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
+//
+// derived from code written by Scott James Remnant <scott@ubuntu.com>
+// Copyright 2005 Canonical Ltd.
+//
+// This software may be used and distributed according to the terms
+// of the GNU General Public License, incorporated herein by reference.
+
+var colors = [
+ [ 1.0, 0.0, 0.0 ],
+ [ 1.0, 1.0, 0.0 ],
+ [ 0.0, 1.0, 0.0 ],
+ [ 0.0, 1.0, 1.0 ],
+ [ 0.0, 0.0, 1.0 ],
+ [ 1.0, 0.0, 1.0 ]
+];
+
+function Graph() {
+
+ this.canvas = document.getElementById('graph');
+ if (navigator.userAgent.indexOf('MSIE') >= 0) this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
+ this.ctx = this.canvas.getContext('2d');
+ this.ctx.strokeStyle = 'rgb(0, 0, 0)';
+ this.ctx.fillStyle = 'rgb(0, 0, 0)';
+ this.cur = [0, 0];
+ this.line_width = 3;
+ this.bg = [0, 4];
+ this.cell = [2, 0];
+ this.columns = 0;
+ this.revlink = '';
+
+ this.scale = function(height) {
+ this.bg_height = height;
+ this.box_size = Math.floor(this.bg_height / 1.2);
+ this.cell_height = this.box_size;
+ }
+
+ function colorPart(num) {
+ num *= 255
+ num = num < 0 ? 0 : num;
+ num = num > 255 ? 255 : num;
+ var digits = Math.round(num).toString(16);
+ if (num < 16) {
+ return '0' + digits;
+ } else {
+ return digits;
+ }
+ }
+
+ this.setColor = function(color, bg, fg) {
+
+ // Set the colour.
+ //
+ // Picks a distinct colour based on an internal wheel; the bg
+ // parameter provides the value that should be assigned to the 'zero'
+ // colours and the fg parameter provides the multiplier that should be
+ // applied to the foreground colours.
+
+ color %= colors.length;
+ var red = (colors[color][0] * fg) || bg;
+ var green = (colors[color][1] * fg) || bg;
+ var blue = (colors[color][2] * fg) || bg;
+ red = Math.round(red * 255);
+ green = Math.round(green * 255);
+ blue = Math.round(blue * 255);
+ var s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
+ this.ctx.strokeStyle = s;
+ this.ctx.fillStyle = s;
+ return s;
+
+ }
+
+ this.render = function(data) {
+
+ var backgrounds = '';
+ var nodedata = '';
+
+ for (var i in data) {
+
+ var parity = i % 2;
+ this.cell[1] += this.bg_height;
+ this.bg[1] += this.bg_height;
+
+ var cur = data[i];
+ var node = cur[1];
+ var edges = cur[2];
+ var fold = false;
+
+ for (var j in edges) {
+
+ line = edges[j];
+ start = line[0];
+ end = line[1];
+ color = line[2];
+
+ if (end > this.columns || start > this.columns) {
+ this.columns += 1;
+ }
+
+ if (start == this.columns && start > end) {
+ var fold = true;
+ }
+
+ x0 = this.cell[0] + this.box_size * start + this.box_size / 2;
+ y0 = this.bg[1] - this.bg_height / 2;
+ x1 = this.cell[0] + this.box_size * end + this.box_size / 2;
+ y1 = this.bg[1] + this.bg_height / 2;
+
+ this.edge(x0, y0, x1, y1, color);
+
+ }
+
+ // Draw the revision node in the right column
+
+ column = node[0]
+ color = node[1]
+
+ radius = this.box_size / 8;
+ x = this.cell[0] + this.box_size * column + this.box_size / 2;
+ y = this.bg[1] - this.bg_height / 2;
+ var add = this.vertex(x, y, color, parity, cur);
+ backgrounds += add[0];
+ nodedata += add[1];
+
+ if (fold) this.columns -= 1;
+
+ }
+
+ document.getElementById('nodebgs').innerHTML += backgrounds;
+ document.getElementById('graphnodes').innerHTML += nodedata;
+
+ }
+
+}
diff --git a/sys/src/cmd/hg/templates/static/hgicon.png b/sys/src/cmd/hg/templates/static/hgicon.png
new file mode 100644
index 000000000..60effbc5e
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/hgicon.png
Binary files differ
diff --git a/sys/src/cmd/hg/templates/static/hglogo.png b/sys/src/cmd/hg/templates/static/hglogo.png
new file mode 100644
index 000000000..adc6e65d1
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/hglogo.png
Binary files differ
diff --git a/sys/src/cmd/hg/templates/static/style-coal.css b/sys/src/cmd/hg/templates/static/style-coal.css
new file mode 100644
index 000000000..9df71c7f1
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/style-coal.css
@@ -0,0 +1,265 @@
+body {
+ margin: 0;
+ padding: 0;
+ background: black url(background.png) repeat-x;
+ font-family: sans-serif;
+}
+
+.container {
+ padding-right: 150px;
+}
+
+.main {
+ position: relative;
+ background: white;
+ padding: 2em;
+ border-right: 15px solid black;
+ border-bottom: 15px solid black;
+}
+
+#.main {
+ width: 98%;
+}
+
+.overflow {
+ width: 100%;
+ overflow: auto;
+}
+
+.menu {
+ background: #999;
+ padding: 10px;
+ width: 75px;
+ margin: 0;
+ font-size: 80%;
+ text-align: left;
+ position: fixed;
+ top: 27px;
+ left: auto;
+ right: 27px;
+}
+
+#.menu {
+ position: absolute !important;
+ top:expression(eval(document.body.scrollTop + 27));
+}
+
+.menu ul {
+ list-style: none;
+ padding: 0;
+ margin: 10px 0 0 0;
+}
+
+.menu li {
+ margin-bottom: 3px;
+ padding: 2px 4px;
+ background: white;
+ color: black;
+ font-weight: normal;
+}
+
+.menu li.active {
+ background: black;
+ color: white;
+}
+
+.menu img {
+ width: 75px;
+ height: 90px;
+ border: 0;
+}
+
+.menu a { color: black; display: block; }
+
+.search {
+ position: absolute;
+ top: .7em;
+ right: 2em;
+}
+
+form.search div#hint {
+ display: none;
+ position: absolute;
+ top: 40px;
+ right: 0px;
+ width: 190px;
+ padding: 5px;
+ background: #ffc;
+ font-size: 70%;
+ border: 1px solid yellow;
+ -moz-border-radius: 5px; /* this works only in camino/firefox */
+ -webkit-border-radius: 5px; /* this is just for Safari */
+}
+
+form.search:hover div#hint { display: block; }
+
+a { text-decoration:none; }
+.age { white-space:nowrap; }
+.date { white-space:nowrap; }
+.indexlinks { white-space:nowrap; }
+.parity0 { background-color: #f0f0f0; }
+.parity1 { background-color: white; }
+.plusline { color: green; }
+.minusline { color: #dc143c; } /* crimson */
+.atline { color: purple; }
+
+.navigate {
+ text-align: right;
+ font-size: 60%;
+ margin: 1em 0;
+}
+
+.tag {
+ color: #999;
+ font-size: 70%;
+ font-weight: normal;
+ margin-left: .5em;
+ vertical-align: baseline;
+}
+
+.branchhead {
+ color: #000;
+ font-size: 80%;
+ font-weight: normal;
+ margin-left: .5em;
+ vertical-align: baseline;
+}
+
+ul#graphnodes .branchhead {
+ font-size: 75%;
+}
+
+.branchname {
+ color: #000;
+ font-size: 60%;
+ font-weight: normal;
+ margin-left: .5em;
+ vertical-align: baseline;
+}
+
+h3 .branchname {
+ font-size: 80%;
+}
+
+/* Common */
+pre { margin: 0; }
+
+h2 { font-size: 120%; border-bottom: 1px solid #999; }
+h2 a { color: #000; }
+h3 {
+ margin-top: -.7em;
+ font-size: 100%;
+}
+
+/* log and tags tables */
+.bigtable {
+ border-bottom: 1px solid #999;
+ border-collapse: collapse;
+ font-size: 90%;
+ width: 100%;
+ font-weight: normal;
+ text-align: left;
+}
+
+.bigtable td {
+ vertical-align: top;
+}
+
+.bigtable th {
+ padding: 1px 4px;
+ border-bottom: 1px solid #999;
+}
+.bigtable tr { border: none; }
+.bigtable .age { width: 6em; }
+.bigtable .author { width: 12em; }
+.bigtable .description { }
+.bigtable .node { width: 5em; font-family: monospace;}
+.bigtable .lineno { width: 2em; text-align: right;}
+.bigtable .lineno a { color: #999; font-size: smaller; font-family: monospace;}
+.bigtable .permissions { width: 8em; text-align: left;}
+.bigtable .size { width: 5em; text-align: right; }
+.bigtable .annotate { text-align: right; }
+.bigtable td.annotate { font-size: smaller; }
+.bigtable td.source { font-size: inherit; }
+
+.source, .sourcefirst, .sourcelast {
+ font-family: monospace;
+ white-space: pre;
+ padding: 1px 4px;
+ font-size: 90%;
+}
+.sourcefirst { border-bottom: 1px solid #999; font-weight: bold; }
+.sourcelast { border-top: 1px solid #999; }
+.source a { color: #999; font-size: smaller; font-family: monospace;}
+.bottomline { border-bottom: 1px solid #999; }
+
+.fileline { font-family: monospace; }
+.fileline img { border: 0; }
+
+.tagEntry .closed { color: #99f; }
+
+/* Changeset entry */
+#changesetEntry {
+ border-collapse: collapse;
+ font-size: 90%;
+ width: 100%;
+ margin-bottom: 1em;
+}
+
+#changesetEntry th {
+ padding: 1px 4px;
+ width: 4em;
+ text-align: right;
+ font-weight: normal;
+ color: #999;
+ margin-right: .5em;
+ vertical-align: top;
+}
+
+div.description {
+ border-left: 3px solid #999;
+ margin: 1em 0 1em 0;
+ padding: .3em;
+}
+
+/* Graph */
+div#wrapper {
+ position: relative;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+ margin: 0;
+ padding: 0;
+}
+
+canvas {
+ position: absolute;
+ z-index: 5;
+ top: -0.7em;
+ margin: 0;
+}
+
+ul#graphnodes {
+ position: absolute;
+ z-index: 10;
+ top: -1.0em;
+ list-style: none inside none;
+ padding: 0;
+}
+
+ul#nodebgs {
+ list-style: none inside none;
+ padding: 0;
+ margin: 0;
+ top: -0.7em;
+}
+
+ul#graphnodes li, ul#nodebgs li {
+ height: 39px;
+}
+
+ul#graphnodes li .info {
+ display: block;
+ font-size: 70%;
+ position: relative;
+ top: -3px;
+}
diff --git a/sys/src/cmd/hg/templates/static/style-gitweb.css b/sys/src/cmd/hg/templates/static/style-gitweb.css
new file mode 100644
index 000000000..09fc3dccc
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/style-gitweb.css
@@ -0,0 +1,123 @@
+body { font-family: sans-serif; font-size: 12px; margin:0px; border:solid #d9d8d1; border-width:1px; margin:10px; }
+a { color:#0000cc; }
+a:hover, a:visited, a:active { color:#880000; }
+div.page_header { height:25px; padding:8px; font-size:18px; font-weight:bold; background-color:#d9d8d1; }
+div.page_header a:visited { color:#0000cc; }
+div.page_header a:hover { color:#880000; }
+div.page_nav { padding:8px; }
+div.page_nav a:visited { color:#0000cc; }
+div.page_path { padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px}
+div.page_footer { padding:4px 8px; background-color: #d9d8d1; }
+div.page_footer_text { float:left; color:#555555; font-style:italic; }
+div.page_body { padding:8px; }
+div.title, a.title {
+ display:block; padding:6px 8px;
+ font-weight:bold; background-color:#edece6; text-decoration:none; color:#000000;
+}
+a.title:hover { background-color: #d9d8d1; }
+div.title_text { padding:6px 0px; border: solid #d9d8d1; border-width:0px 0px 1px; }
+div.log_body { padding:8px 8px 8px 150px; }
+.age { white-space:nowrap; }
+span.age { position:relative; float:left; width:142px; font-style:italic; }
+div.log_link {
+ padding:0px 8px;
+ font-size:10px; font-family:sans-serif; font-style:normal;
+ position:relative; float:left; width:136px;
+}
+div.list_head { padding:6px 8px 4px; border:solid #d9d8d1; border-width:1px 0px 0px; font-style:italic; }
+a.list { text-decoration:none; color:#000000; }
+a.list:hover { text-decoration:underline; color:#880000; }
+table { padding:8px 4px; }
+th { padding:2px 5px; font-size:12px; text-align:left; }
+tr.light:hover, .parity0:hover { background-color:#edece6; }
+tr.dark, .parity1 { background-color:#f6f6f0; }
+tr.dark:hover, .parity1:hover { background-color:#edece6; }
+td { padding:2px 5px; font-size:12px; vertical-align:top; }
+td.link { padding:2px 5px; font-family:sans-serif; font-size:10px; }
+td.indexlinks { white-space: nowrap; }
+td.indexlinks a {
+ padding: 2px 5px; line-height: 10px;
+ border: 1px solid;
+ color: #ffffff; background-color: #7777bb;
+ border-color: #aaaadd #333366 #333366 #aaaadd;
+ font-weight: bold; text-align: center; text-decoration: none;
+ font-size: 10px;
+}
+td.indexlinks a:hover { background-color: #6666aa; }
+div.pre { font-family:monospace; font-size:12px; white-space:pre; }
+div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; }
+div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; }
+div.search { margin:4px 8px; position:absolute; top:56px; right:12px }
+.linenr { color:#999999; text-decoration:none }
+div.rss_logo { float: right; white-space: nowrap; }
+div.rss_logo a {
+ padding:3px 6px; line-height:10px;
+ border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
+ color:#ffffff; background-color:#ff6600;
+ font-weight:bold; font-family:sans-serif; font-size:10px;
+ text-align:center; text-decoration:none;
+}
+div.rss_logo a:hover { background-color:#ee5500; }
+pre { margin: 0; }
+span.logtags span {
+ padding: 0px 4px;
+ font-size: 10px;
+ font-weight: normal;
+ border: 1px solid;
+ background-color: #ffaaff;
+ border-color: #ffccff #ff00ee #ff00ee #ffccff;
+}
+span.logtags span.tagtag {
+ background-color: #ffffaa;
+ border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
+}
+span.logtags span.branchtag {
+ background-color: #aaffaa;
+ border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
+}
+span.logtags span.inbranchtag {
+ background-color: #d5dde6;
+ border-color: #e3ecf4 #9398f4 #9398f4 #e3ecf4;
+}
+
+/* Graph */
+div#wrapper {
+ position: relative;
+ margin: 0;
+ padding: 0;
+ margin-top: 3px;
+}
+
+canvas {
+ position: absolute;
+ z-index: 5;
+ top: -0.9em;
+ margin: 0;
+}
+
+ul#nodebgs {
+ list-style: none inside none;
+ padding: 0;
+ margin: 0;
+ top: -0.7em;
+}
+
+ul#graphnodes li, ul#nodebgs li {
+ height: 39px;
+}
+
+ul#graphnodes {
+ position: absolute;
+ z-index: 10;
+ top: -0.8em;
+ list-style: none inside none;
+ padding: 0;
+}
+
+ul#graphnodes li .info {
+ display: block;
+ font-size: 100%;
+ position: relative;
+ top: -3px;
+ font-style: italic;
+}
diff --git a/sys/src/cmd/hg/templates/static/style-monoblue.css b/sys/src/cmd/hg/templates/static/style-monoblue.css
new file mode 100644
index 000000000..12611ea49
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/style-monoblue.css
@@ -0,0 +1,472 @@
+/*** Initial Settings ***/
+* {
+ margin: 0;
+ padding: 0;
+ font-weight: normal;
+ font-style: normal;
+}
+
+html {
+ font-size: 100%;
+ font-family: sans-serif;
+}
+
+body {
+ font-size: 77%;
+ margin: 15px 50px;
+ background: #4B4B4C;
+}
+
+a {
+ color:#0000cc;
+ text-decoration: none;
+}
+/*** end of Initial Settings ***/
+
+
+/** common settings **/
+div#container {
+ background: #FFFFFF;
+ position: relative;
+ color: #666;
+}
+
+div.page-header {
+ padding: 50px 20px 0;
+ background: #006699 top left repeat-x;
+ position: relative;
+}
+ div.page-header h1 {
+ margin: 10px 0 30px;
+ font-size: 1.8em;
+ font-weight: bold;
+ font-family: osaka,'MS P Gothic', Georgia, serif;
+ letter-spacing: 1px;
+ color: #DDD;
+ }
+ div.page-header h1 a {
+ font-weight: bold;
+ color: #FFF;
+ }
+ div.page-header a {
+ text-decoration: none;
+ }
+
+ div.page-header form {
+ position: absolute;
+ margin-bottom: 2px;
+ bottom: 0;
+ right: 20px;
+ }
+ div.page-header form label {
+ color: #DDD;
+ }
+ div.page-header form input {
+ padding: 2px;
+ border: solid 1px #DDD;
+ }
+ div.page-header form dl {
+ overflow: hidden;
+ }
+ div.page-header form dl dt {
+ font-size: 1.2em;
+ }
+ div.page-header form dl dt,
+ div.page-header form dl dd {
+ margin: 0 0 0 5px;
+ float: left;
+ height: 24px;
+ line-height: 20px;
+ }
+
+ ul.page-nav {
+ margin: 10px 0 0 0;
+ list-style-type: none;
+ overflow: hidden;
+ width: 800px;
+ }
+ ul.page-nav li {
+ margin: 0 2px 0 0;
+ float: left;
+ width: 80px;
+ height: 24px;
+ font-size: 1.1em;
+ line-height: 24px;
+ text-align: center;
+ }
+ ul.page-nav li.current {
+ background: #FFF;
+ }
+ ul.page-nav li a {
+ height: 24px;
+ color: #666;
+ background: #DDD;
+ display: block;
+ text-decoration: none;
+ }
+ ul.page-nav li a:hover {
+ color:#333;
+ background: #FFF;
+ }
+
+ul.submenu {
+ margin: 10px 0 -10px 20px;
+ list-style-type: none;
+}
+ul.submenu li {
+ margin: 0 10px 0 0;
+ font-size: 1.2em;
+ display: inline;
+}
+
+h2 {
+ margin: 20px 0 10px;
+ height: 30px;
+ line-height: 30px;
+ text-indent: 20px;
+ background: #FFF;
+ font-size: 1.2em;
+ border-top: dotted 1px #D5E1E6;
+ font-weight: bold;
+}
+h2.no-link {
+ color:#006699;
+}
+h2.no-border {
+ color: #FFF;
+ background: #006699;
+ border: 0;
+}
+h2 a {
+ font-weight:bold;
+ color:#006699;
+}
+
+div.page-path {
+ text-align: right;
+ padding: 20px 30px 10px 0;
+ border:solid #d9d8d1;
+ border-width:0px 0px 1px;
+ font-size: 1.2em;
+}
+
+div.page-footer {
+ margin: 50px 0 0;
+ position: relative;
+}
+ div.page-footer p {
+ position: relative;
+ left: 20px;
+ bottom: 5px;
+ font-size: 1.2em;
+ }
+
+ ul.rss-logo {
+ position: absolute;
+ top: -10px;
+ right: 20px;
+ height: 20px;
+ list-style-type: none;
+ }
+ ul.rss-logo li {
+ display: inline;
+ }
+ ul.rss-logo li a {
+ padding: 3px 6px;
+ line-height: 10px;
+ border:1px solid;
+ border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
+ color:#ffffff;
+ background-color:#ff6600;
+ font-weight:bold;
+ font-family:sans-serif;
+ font-size:10px;
+ text-align:center;
+ text-decoration:none;
+ }
+ div.rss-logo li a:hover {
+ background-color:#ee5500;
+ }
+
+p.normal {
+ margin: 20px 0 20px 30px;
+ font-size: 1.2em;
+}
+
+table {
+ margin: 10px 0 0 20px;
+ width: 95%;
+ border-collapse: collapse;
+}
+table tr td {
+ font-size: 1.1em;
+}
+table tr td.nowrap {
+ white-space: nowrap;
+}
+/*
+table tr.parity0:hover,
+table tr.parity1:hover {
+ background: #D5E1E6;
+}
+*/
+table tr.parity0 {
+ background: #F1F6F7;
+}
+table tr.parity1 {
+ background: #FFFFFF;
+}
+table tr td {
+ padding: 5px 5px;
+}
+table.annotated tr td {
+ padding: 0px 5px;
+}
+
+span.logtags span {
+ padding: 2px 6px;
+ font-weight: normal;
+ font-size: 11px;
+ border: 1px solid;
+ background-color: #ffaaff;
+ border-color: #ffccff #ff00ee #ff00ee #ffccff;
+}
+span.logtags span.tagtag {
+ background-color: #ffffaa;
+ border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
+}
+span.logtags span.branchtag {
+ background-color: #aaffaa;
+ border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
+}
+span.logtags span.inbranchtag {
+ background-color: #d5dde6;
+ border-color: #e3ecf4 #9398f4 #9398f4 #e3ecf4;
+}
+
+div.diff pre {
+ margin: 10px 0 0 0;
+}
+div.diff pre span {
+ font-family: monospace;
+ white-space: pre;
+ font-size: 1.2em;
+ padding: 3px 0;
+}
+td.source {
+ white-space: pre;
+ font-family: monospace;
+ margin: 10px 30px 0;
+ font-size: 1.2em;
+ font-family: monospace;
+}
+ div.source div.parity0,
+ div.source div.parity1 {
+ padding: 1px;
+ font-size: 1.2em;
+ }
+ div.source div.parity0 {
+ background: #F1F6F7;
+ }
+ div.source div.parity1 {
+ background: #FFFFFF;
+ }
+div.parity0:hover,
+div.parity1:hover {
+ background: #D5E1E6;
+}
+.linenr {
+ color: #999;
+ text-align: right;
+}
+.lineno {
+ text-align: right;
+}
+.lineno a {
+ color: #999;
+}
+td.linenr {
+ width: 60px;
+}
+
+div#powered-by {
+ position: absolute;
+ width: 75px;
+ top: 15px;
+ right: 20px;
+ font-size: 1.2em;
+}
+div#powered-by a {
+ color: #EEE;
+ text-decoration: none;
+}
+div#powered-by a:hover {
+ text-decoration: underline;
+}
+/*
+div#monoblue-corner-top-left {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 10px;
+ height: 10px;
+ background: url(./monoblue-corner.png) top left no-repeat !important;
+ background: none;
+}
+div#monoblue-corner-top-right {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 10px;
+ height: 10px;
+ background: url(./monoblue-corner.png) top right no-repeat !important;
+ background: none;
+}
+div#monoblue-corner-bottom-left {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 10px;
+ height: 10px;
+ background: url(./monoblue-corner.png) bottom left no-repeat !important;
+ background: none;
+}
+div#monoblue-corner-bottom-right {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ width: 10px;
+ height: 10px;
+ background: url(./monoblue-corner.png) bottom right no-repeat !important;
+ background: none;
+}
+*/
+/** end of common settings **/
+
+/** summary **/
+dl.overview {
+ margin: 0 0 0 30px;
+ font-size: 1.1em;
+ overflow: hidden;
+}
+ dl.overview dt,
+ dl.overview dd {
+ margin: 5px 0;
+ float: left;
+ }
+ dl.overview dt {
+ clear: left;
+ font-weight: bold;
+ width: 150px;
+ }
+/** end of summary **/
+
+/** chagelog **/
+h3.changelog {
+ margin: 20px 0 5px 30px;
+ padding: 0 0 2px;
+ font-size: 1.4em;
+ border-bottom: dotted 1px #D5E1E6;
+}
+ul.changelog-entry {
+ margin: 0 0 10px 30px;
+ list-style-type: none;
+ position: relative;
+}
+ul.changelog-entry li span.revdate {
+ font-size: 1.1em;
+}
+ul.changelog-entry li.age {
+ position: absolute;
+ top: -25px;
+ right: 10px;
+ font-size: 1.4em;
+ color: #CCC;
+ font-weight: bold;
+ font-style: italic;
+}
+ul.changelog-entry li span.name {
+ font-size: 1.2em;
+ font-weight: bold;
+}
+ul.changelog-entry li.description {
+ margin: 10px 0 0;
+ font-size: 1.1em;
+}
+/** end of changelog **/
+
+/** file **/
+p.files {
+ margin: 0 0 0 20px;
+ font-size: 2.0em;
+ font-weight: bold;
+}
+/** end of file **/
+
+/** changeset **/
+h3.changeset {
+ margin: 20px 0 5px 20px;
+ padding: 0 0 2px;
+ font-size: 1.6em;
+ border-bottom: dotted 1px #D5E1E6;
+}
+p.changeset-age {
+ position: relative;
+}
+p.changeset-age span {
+ position: absolute;
+ top: -25px;
+ right: 10px;
+ font-size: 1.4em;
+ color: #CCC;
+ font-weight: bold;
+ font-style: italic;
+}
+p.description {
+ margin: 10px 30px 0 30px;
+ padding: 10px;
+ border: solid 1px #CCC;
+ font-size: 1.2em;
+}
+/** end of changeset **/
+
+/** canvas **/
+div#wrapper {
+ position: relative;
+ font-size: 1.2em;
+}
+
+canvas {
+ position: absolute;
+ z-index: 5;
+ top: -0.7em;
+}
+
+ul#nodebgs li.parity0 {
+ background: #F1F6F7;
+}
+
+ul#nodebgs li.parity1 {
+ background: #FFFFFF;
+}
+
+ul#graphnodes {
+ position: absolute;
+ z-index: 10;
+ top: 7px;
+ list-style: none inside none;
+}
+
+ul#nodebgs {
+ list-style: none inside none;
+}
+
+ul#graphnodes li, ul#nodebgs li {
+ height: 39px;
+}
+
+ul#graphnodes li .info {
+ display: block;
+ position: relative;
+}
+/** end of canvas **/
diff --git a/sys/src/cmd/hg/templates/static/style-paper.css b/sys/src/cmd/hg/templates/static/style-paper.css
new file mode 100644
index 000000000..edb9beab6
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/style-paper.css
@@ -0,0 +1,254 @@
+body {
+ margin: 0;
+ padding: 0;
+ background: white;
+ font-family: sans-serif;
+}
+
+.container {
+ padding-left: 115px;
+}
+
+.main {
+ position: relative;
+ background: white;
+ padding: 2em 2em 2em 0;
+}
+
+#.main {
+ width: 98%;
+}
+
+.overflow {
+ width: 100%;
+ overflow: auto;
+}
+
+.menu {
+ width: 90px;
+ margin: 0;
+ font-size: 80%;
+ text-align: left;
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ right: auto;
+}
+
+.menu ul {
+ list-style: none;
+ padding: 0;
+ margin: 10px 0 0 0;
+ border-left: 2px solid #999;
+}
+
+.menu li {
+ margin-bottom: 3px;
+ padding: 2px 4px;
+ background: white;
+ color: black;
+ font-weight: normal;
+}
+
+.menu li.active {
+ font-weight: bold;
+}
+
+.menu img {
+ width: 75px;
+ height: 90px;
+ border: 0;
+}
+
+.menu a { color: black; display: block; }
+
+.search {
+ position: absolute;
+ top: .7em;
+ right: 2em;
+}
+
+form.search div#hint {
+ display: none;
+ position: absolute;
+ top: 40px;
+ right: 0px;
+ width: 190px;
+ padding: 5px;
+ background: #ffc;
+ font-size: 70%;
+ border: 1px solid yellow;
+ -moz-border-radius: 5px; /* this works only in camino/firefox */
+ -webkit-border-radius: 5px; /* this is just for Safari */
+}
+
+form.search:hover div#hint { display: block; }
+
+a { text-decoration:none; }
+.age { white-space:nowrap; }
+.date { white-space:nowrap; }
+.indexlinks { white-space:nowrap; }
+.parity0 { background-color: #f0f0f0; }
+.parity1 { background-color: white; }
+.plusline { color: green; }
+.minusline { color: #dc143c; } /* crimson */
+.atline { color: purple; }
+
+.navigate {
+ text-align: right;
+ font-size: 60%;
+ margin: 1em 0;
+}
+
+.tag {
+ color: #999;
+ font-size: 70%;
+ font-weight: normal;
+ margin-left: .5em;
+ vertical-align: baseline;
+}
+
+.branchhead {
+ color: #000;
+ font-size: 80%;
+ font-weight: normal;
+ margin-left: .5em;
+ vertical-align: baseline;
+}
+
+ul#graphnodes .branchhead {
+ font-size: 75%;
+}
+
+.branchname {
+ color: #000;
+ font-size: 60%;
+ font-weight: normal;
+ margin-left: .5em;
+ vertical-align: baseline;
+}
+
+h3 .branchname {
+ font-size: 80%;
+}
+
+/* Common */
+pre { margin: 0; }
+
+h2 { font-size: 120%; border-bottom: 1px solid #999; }
+h2 a { color: #000; }
+h3 {
+ margin-top: -.7em;
+ font-size: 100%;
+}
+
+/* log and tags tables */
+.bigtable {
+ border-bottom: 1px solid #999;
+ border-collapse: collapse;
+ font-size: 90%;
+ width: 100%;
+ font-weight: normal;
+ text-align: left;
+}
+
+.bigtable td {
+ vertical-align: top;
+}
+
+.bigtable th {
+ padding: 1px 4px;
+ border-bottom: 1px solid #999;
+}
+.bigtable tr { border: none; }
+.bigtable .age { width: 6em; }
+.bigtable .author { width: 12em; }
+.bigtable .description { }
+.bigtable .node { width: 5em; font-family: monospace;}
+.bigtable .permissions { width: 8em; text-align: left;}
+.bigtable .size { width: 5em; text-align: right; }
+.bigtable .annotate { text-align: right; }
+.bigtable td.annotate { font-size: smaller; }
+.bigtable td.source { font-size: inherit; }
+
+.source, .sourcefirst, .sourcelast {
+ font-family: monospace;
+ white-space: pre;
+ padding: 1px 4px;
+ font-size: 90%;
+}
+.sourcefirst { border-bottom: 1px solid #999; font-weight: bold; }
+.sourcelast { border-top: 1px solid #999; }
+.source a { color: #999; font-size: smaller; font-family: monospace;}
+.bottomline { border-bottom: 1px solid #999; }
+
+.fileline { font-family: monospace; }
+.fileline img { border: 0; }
+
+.tagEntry .closed { color: #99f; }
+
+/* Changeset entry */
+#changesetEntry {
+ border-collapse: collapse;
+ font-size: 90%;
+ width: 100%;
+ margin-bottom: 1em;
+}
+
+#changesetEntry th {
+ padding: 1px 4px;
+ width: 4em;
+ text-align: right;
+ font-weight: normal;
+ color: #999;
+ margin-right: .5em;
+ vertical-align: top;
+}
+
+div.description {
+ border-left: 2px solid #999;
+ margin: 1em 0 1em 0;
+ padding: .3em;
+}
+
+/* Graph */
+div#wrapper {
+ position: relative;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+ margin: 0;
+ padding: 0;
+}
+
+canvas {
+ position: absolute;
+ z-index: 5;
+ top: -0.7em;
+ margin: 0;
+}
+
+ul#graphnodes {
+ position: absolute;
+ z-index: 10;
+ top: -1.0em;
+ list-style: none inside none;
+ padding: 0;
+}
+
+ul#nodebgs {
+ list-style: none inside none;
+ padding: 0;
+ margin: 0;
+ top: -0.7em;
+}
+
+ul#graphnodes li, ul#nodebgs li {
+ height: 39px;
+}
+
+ul#graphnodes li .info {
+ display: block;
+ font-size: 70%;
+ position: relative;
+ top: -3px;
+}
diff --git a/sys/src/cmd/hg/templates/static/style.css b/sys/src/cmd/hg/templates/static/style.css
new file mode 100644
index 000000000..66bd96d49
--- /dev/null
+++ b/sys/src/cmd/hg/templates/static/style.css
@@ -0,0 +1,105 @@
+a { text-decoration:none; }
+.age { white-space:nowrap; }
+.date { white-space:nowrap; }
+.indexlinks { white-space:nowrap; }
+.parity0 { background-color: #ddd; }
+.parity1 { background-color: #eee; }
+.lineno { width: 60px; color: #aaa; font-size: smaller;
+ text-align: right; }
+.plusline { color: green; }
+.minusline { color: red; }
+.atline { color: purple; }
+.annotate { font-size: smaller; text-align: right; padding-right: 1em; }
+.buttons a {
+ background-color: #666;
+ padding: 2pt;
+ color: white;
+ font-family: sans;
+ font-weight: bold;
+}
+.navigate a {
+ background-color: #ccc;
+ padding: 2pt;
+ font-family: sans;
+ color: black;
+}
+
+.metatag {
+ background-color: #888;
+ color: white;
+ text-align: right;
+}
+
+/* Common */
+pre { margin: 0; }
+
+.logo {
+ float: right;
+ clear: right;
+}
+
+/* Changelog/Filelog entries */
+.logEntry { width: 100%; }
+.logEntry .age { width: 15%; }
+.logEntry th { font-weight: normal; text-align: right; vertical-align: top; }
+.logEntry th.age, .logEntry th.firstline { font-weight: bold; }
+.logEntry th.firstline { text-align: left; width: inherit; }
+
+/* Shortlog entries */
+.slogEntry { width: 100%; }
+.slogEntry .age { width: 8em; }
+.slogEntry td { font-weight: normal; text-align: left; vertical-align: top; }
+.slogEntry td.author { width: 15em; }
+
+/* Tag entries */
+#tagEntries { list-style: none; margin: 0; padding: 0; }
+#tagEntries .tagEntry { list-style: none; margin: 0; padding: 0; }
+
+/* Changeset entry */
+#changesetEntry { }
+#changesetEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
+#changesetEntry th.files, #changesetEntry th.description { vertical-align: top; }
+
+/* File diff view */
+#filediffEntry { }
+#filediffEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
+
+/* Graph */
+div#wrapper {
+ position: relative;
+ margin: 0;
+ padding: 0;
+}
+
+canvas {
+ position: absolute;
+ z-index: 5;
+ top: -0.6em;
+ margin: 0;
+}
+
+ul#nodebgs {
+ list-style: none inside none;
+ padding: 0;
+ margin: 0;
+ top: -0.7em;
+}
+
+ul#graphnodes li, ul#nodebgs li {
+ height: 39px;
+}
+
+ul#graphnodes {
+ position: absolute;
+ z-index: 10;
+ top: -0.85em;
+ list-style: none inside none;
+ padding: 0;
+}
+
+ul#graphnodes li .info {
+ display: block;
+ font-size: 70%;
+ position: relative;
+ top: -1px;
+}
diff --git a/sys/src/cmd/hg/templates/template-vars.txt b/sys/src/cmd/hg/templates/template-vars.txt
new file mode 100644
index 000000000..f434d7295
--- /dev/null
+++ b/sys/src/cmd/hg/templates/template-vars.txt
@@ -0,0 +1,37 @@
+repo the name of the repo
+rev a changeset.manifest revision
+node a changeset node
+changesets total number of changesets
+file a filename
+filerev a file revision
+filerevs total number of file revisions
+up the directory of the relevant file
+path a path in the manifest, starting with "/"
+basename a short pathname
+date a date string
+age age in hours, days, etc
+line a line of text (escaped)
+desc a description (escaped, with breaks)
+shortdesc a short description (escaped)
+author a name or email addressv(obfuscated)
+parent a list of the parent
+child a list of the children
+tags a list of tag
+
+header the global page header
+footer the global page footer
+
+files a list of file links
+file_copies a list of pairs of name, source filenames
+dirs a set of directory links
+diff a diff of one or more files
+annotate an annotated file
+entries the entries relevant to the page
+
+Templates and commands:
+ changelog(rev) - a page for browsing changesets
+ naventry - a link for jumping to a changeset number
+ filenodelink - jump to file diff
+ fileellipses - printed after maxfiles
+ changelogentry - an entry in the log
+ manifest - browse a manifest as a directory tree