##// END OF EJS Templates
hook: add a generic hook after transaction has been closed...
Pierre-Yves David -
r24282:db867981 default
parent child Browse files
Show More
@@ -1,1728 +1,1738
1 1 The Mercurial system uses a set of configuration files to control
2 2 aspects of its behavior.
3 3
4 4 The configuration files use a simple ini-file format. A configuration
5 5 file consists of sections, led by a ``[section]`` header and followed
6 6 by ``name = value`` entries::
7 7
8 8 [ui]
9 9 username = Firstname Lastname <firstname.lastname@example.net>
10 10 verbose = True
11 11
12 12 The above entries will be referred to as ``ui.username`` and
13 13 ``ui.verbose``, respectively. See the Syntax section below.
14 14
15 15 Files
16 16 =====
17 17
18 18 Mercurial reads configuration data from several files, if they exist.
19 19 These files do not exist by default and you will have to create the
20 20 appropriate configuration files yourself: global configuration like
21 21 the username setting is typically put into
22 22 ``%USERPROFILE%\mercurial.ini`` or ``$HOME/.hgrc`` and local
23 23 configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
24 24
25 25 The names of these files depend on the system on which Mercurial is
26 26 installed. ``*.rc`` files from a single directory are read in
27 27 alphabetical order, later ones overriding earlier ones. Where multiple
28 28 paths are given below, settings from earlier paths override later
29 29 ones.
30 30
31 31 .. container:: verbose.unix
32 32
33 33 On Unix, the following files are consulted:
34 34
35 35 - ``<repo>/.hg/hgrc`` (per-repository)
36 36 - ``$HOME/.hgrc`` (per-user)
37 37 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
38 38 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
39 39 - ``/etc/mercurial/hgrc`` (per-system)
40 40 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
41 41 - ``<internal>/default.d/*.rc`` (defaults)
42 42
43 43 .. container:: verbose.windows
44 44
45 45 On Windows, the following files are consulted:
46 46
47 47 - ``<repo>/.hg/hgrc`` (per-repository)
48 48 - ``%USERPROFILE%\.hgrc`` (per-user)
49 49 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
50 50 - ``%HOME%\.hgrc`` (per-user)
51 51 - ``%HOME%\Mercurial.ini`` (per-user)
52 52 - ``<install-dir>\Mercurial.ini`` (per-installation)
53 53 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
54 54 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-installation)
55 55 - ``<internal>/default.d/*.rc`` (defaults)
56 56
57 57 .. note::
58 58
59 59 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
60 60 is used when running 32-bit Python on 64-bit Windows.
61 61
62 62 .. container:: verbose.plan9
63 63
64 64 On Plan9, the following files are consulted:
65 65
66 66 - ``<repo>/.hg/hgrc`` (per-repository)
67 67 - ``$home/lib/hgrc`` (per-user)
68 68 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
69 69 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
70 70 - ``/lib/mercurial/hgrc`` (per-system)
71 71 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
72 72 - ``<internal>/default.d/*.rc`` (defaults)
73 73
74 74 Per-repository configuration options only apply in a
75 75 particular repository. This file is not version-controlled, and
76 76 will not get transferred during a "clone" operation. Options in
77 77 this file override options in all other configuration files. On
78 78 Plan 9 and Unix, most of this file will be ignored if it doesn't
79 79 belong to a trusted user or to a trusted group. See the documentation
80 80 for the ``[trusted]`` section below for more details.
81 81
82 82 Per-user configuration file(s) are for the user running Mercurial. On
83 83 Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these
84 84 files apply to all Mercurial commands executed by this user in any
85 85 directory. Options in these files override per-system and per-installation
86 86 options.
87 87
88 88 Per-installation configuration files are searched for in the
89 89 directory where Mercurial is installed. ``<install-root>`` is the
90 90 parent directory of the **hg** executable (or symlink) being run. For
91 91 example, if installed in ``/shared/tools/bin/hg``, Mercurial will look
92 92 in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply
93 93 to all Mercurial commands executed by any user in any directory.
94 94
95 95 Per-installation configuration files are for the system on
96 96 which Mercurial is running. Options in these files apply to all
97 97 Mercurial commands executed by any user in any directory. Registry
98 98 keys contain PATH-like strings, every part of which must reference
99 99 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
100 100 be read. Mercurial checks each of these locations in the specified
101 101 order until one or more configuration files are detected.
102 102
103 103 Per-system configuration files are for the system on which Mercurial
104 104 is running. Options in these files apply to all Mercurial commands
105 105 executed by any user in any directory. Options in these files
106 106 override per-installation options.
107 107
108 108 Mercurial comes with some default configuration. The default configuration
109 109 files are installed with Mercurial and will be overwritten on upgrades. Default
110 110 configuration files should never be edited by users or administrators but can
111 111 be overridden in other configuration files. So far the directory only contains
112 112 merge tool configuration but packagers can also put other default configuration
113 113 there.
114 114
115 115 Syntax
116 116 ======
117 117
118 118 A configuration file consists of sections, led by a ``[section]`` header
119 119 and followed by ``name = value`` entries (sometimes called
120 120 ``configuration keys``)::
121 121
122 122 [spam]
123 123 eggs=ham
124 124 green=
125 125 eggs
126 126
127 127 Each line contains one entry. If the lines that follow are indented,
128 128 they are treated as continuations of that entry. Leading whitespace is
129 129 removed from values. Empty lines are skipped. Lines beginning with
130 130 ``#`` or ``;`` are ignored and may be used to provide comments.
131 131
132 132 Configuration keys can be set multiple times, in which case Mercurial
133 133 will use the value that was configured last. As an example::
134 134
135 135 [spam]
136 136 eggs=large
137 137 ham=serrano
138 138 eggs=small
139 139
140 140 This would set the configuration key named ``eggs`` to ``small``.
141 141
142 142 It is also possible to define a section multiple times. A section can
143 143 be redefined on the same and/or on different configuration files. For
144 144 example::
145 145
146 146 [foo]
147 147 eggs=large
148 148 ham=serrano
149 149 eggs=small
150 150
151 151 [bar]
152 152 eggs=ham
153 153 green=
154 154 eggs
155 155
156 156 [foo]
157 157 ham=prosciutto
158 158 eggs=medium
159 159 bread=toasted
160 160
161 161 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
162 162 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
163 163 respectively. As you can see there only thing that matters is the last
164 164 value that was set for each of the configuration keys.
165 165
166 166 If a configuration key is set multiple times in different
167 167 configuration files the final value will depend on the order in which
168 168 the different configuration files are read, with settings from earlier
169 169 paths overriding later ones as described on the ``Files`` section
170 170 above.
171 171
172 172 A line of the form ``%include file`` will include ``file`` into the
173 173 current configuration file. The inclusion is recursive, which means
174 174 that included files can include other files. Filenames are relative to
175 175 the configuration file in which the ``%include`` directive is found.
176 176 Environment variables and ``~user`` constructs are expanded in
177 177 ``file``. This lets you do something like::
178 178
179 179 %include ~/.hgrc.d/$HOST.rc
180 180
181 181 to include a different configuration file on each computer you use.
182 182
183 183 A line with ``%unset name`` will remove ``name`` from the current
184 184 section, if it has been set previously.
185 185
186 186 The values are either free-form text strings, lists of text strings,
187 187 or Boolean values. Boolean values can be set to true using any of "1",
188 188 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
189 189 (all case insensitive).
190 190
191 191 List values are separated by whitespace or comma, except when values are
192 192 placed in double quotation marks::
193 193
194 194 allow_read = "John Doe, PhD", brian, betty
195 195
196 196 Quotation marks can be escaped by prefixing them with a backslash. Only
197 197 quotation marks at the beginning of a word is counted as a quotation
198 198 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
199 199
200 200 Sections
201 201 ========
202 202
203 203 This section describes the different sections that may appear in a
204 204 Mercurial configuration file, the purpose of each section, its possible
205 205 keys, and their possible values.
206 206
207 207 ``alias``
208 208 ---------
209 209
210 210 Defines command aliases.
211 211 Aliases allow you to define your own commands in terms of other
212 212 commands (or aliases), optionally including arguments. Positional
213 213 arguments in the form of ``$1``, ``$2``, etc in the alias definition
214 214 are expanded by Mercurial before execution. Positional arguments not
215 215 already used by ``$N`` in the definition are put at the end of the
216 216 command to be executed.
217 217
218 218 Alias definitions consist of lines of the form::
219 219
220 220 <alias> = <command> [<argument>]...
221 221
222 222 For example, this definition::
223 223
224 224 latest = log --limit 5
225 225
226 226 creates a new command ``latest`` that shows only the five most recent
227 227 changesets. You can define subsequent aliases using earlier ones::
228 228
229 229 stable5 = latest -b stable
230 230
231 231 .. note::
232 232
233 233 It is possible to create aliases with the same names as
234 234 existing commands, which will then override the original
235 235 definitions. This is almost always a bad idea!
236 236
237 237 An alias can start with an exclamation point (``!``) to make it a
238 238 shell alias. A shell alias is executed with the shell and will let you
239 239 run arbitrary commands. As an example, ::
240 240
241 241 echo = !echo $@
242 242
243 243 will let you do ``hg echo foo`` to have ``foo`` printed in your
244 244 terminal. A better example might be::
245 245
246 246 purge = !$HG status --no-status --unknown -0 | xargs -0 rm
247 247
248 248 which will make ``hg purge`` delete all unknown files in the
249 249 repository in the same manner as the purge extension.
250 250
251 251 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
252 252 expand to the command arguments. Unmatched arguments are
253 253 removed. ``$0`` expands to the alias name and ``$@`` expands to all
254 254 arguments separated by a space. ``"$@"`` (with quotes) expands to all
255 255 arguments quoted individually and separated by a space. These expansions
256 256 happen before the command is passed to the shell.
257 257
258 258 Shell aliases are executed in an environment where ``$HG`` expands to
259 259 the path of the Mercurial that was used to execute the alias. This is
260 260 useful when you want to call further Mercurial commands in a shell
261 261 alias, as was done above for the purge alias. In addition,
262 262 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
263 263 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
264 264
265 265 .. note::
266 266
267 267 Some global configuration options such as ``-R`` are
268 268 processed before shell aliases and will thus not be passed to
269 269 aliases.
270 270
271 271
272 272 ``annotate``
273 273 ------------
274 274
275 275 Settings used when displaying file annotations. All values are
276 276 Booleans and default to False. See ``diff`` section for related
277 277 options for the diff command.
278 278
279 279 ``ignorews``
280 280 Ignore white space when comparing lines.
281 281
282 282 ``ignorewsamount``
283 283 Ignore changes in the amount of white space.
284 284
285 285 ``ignoreblanklines``
286 286 Ignore changes whose lines are all blank.
287 287
288 288
289 289 ``auth``
290 290 --------
291 291
292 292 Authentication credentials for HTTP authentication. This section
293 293 allows you to store usernames and passwords for use when logging
294 294 *into* HTTP servers. See the ``[web]`` configuration section if
295 295 you want to configure *who* can login to your HTTP server.
296 296
297 297 Each line has the following format::
298 298
299 299 <name>.<argument> = <value>
300 300
301 301 where ``<name>`` is used to group arguments into authentication
302 302 entries. Example::
303 303
304 304 foo.prefix = hg.intevation.org/mercurial
305 305 foo.username = foo
306 306 foo.password = bar
307 307 foo.schemes = http https
308 308
309 309 bar.prefix = secure.example.org
310 310 bar.key = path/to/file.key
311 311 bar.cert = path/to/file.cert
312 312 bar.schemes = https
313 313
314 314 Supported arguments:
315 315
316 316 ``prefix``
317 317 Either ``*`` or a URI prefix with or without the scheme part.
318 318 The authentication entry with the longest matching prefix is used
319 319 (where ``*`` matches everything and counts as a match of length
320 320 1). If the prefix doesn't include a scheme, the match is performed
321 321 against the URI with its scheme stripped as well, and the schemes
322 322 argument, q.v., is then subsequently consulted.
323 323
324 324 ``username``
325 325 Optional. Username to authenticate with. If not given, and the
326 326 remote site requires basic or digest authentication, the user will
327 327 be prompted for it. Environment variables are expanded in the
328 328 username letting you do ``foo.username = $USER``. If the URI
329 329 includes a username, only ``[auth]`` entries with a matching
330 330 username or without a username will be considered.
331 331
332 332 ``password``
333 333 Optional. Password to authenticate with. If not given, and the
334 334 remote site requires basic or digest authentication, the user
335 335 will be prompted for it.
336 336
337 337 ``key``
338 338 Optional. PEM encoded client certificate key file. Environment
339 339 variables are expanded in the filename.
340 340
341 341 ``cert``
342 342 Optional. PEM encoded client certificate chain file. Environment
343 343 variables are expanded in the filename.
344 344
345 345 ``schemes``
346 346 Optional. Space separated list of URI schemes to use this
347 347 authentication entry with. Only used if the prefix doesn't include
348 348 a scheme. Supported schemes are http and https. They will match
349 349 static-http and static-https respectively, as well.
350 350 Default: https.
351 351
352 352 If no suitable authentication entry is found, the user is prompted
353 353 for credentials as usual if required by the remote.
354 354
355 355
356 356 ``committemplate``
357 357 ------------------
358 358
359 359 ``changeset`` configuration in this section is used as the template to
360 360 customize the text shown in the editor when committing.
361 361
362 362 In addition to pre-defined template keywords, commit log specific one
363 363 below can be used for customization:
364 364
365 365 ``extramsg``
366 366 String: Extra message (typically 'Leave message empty to abort
367 367 commit.'). This may be changed by some commands or extensions.
368 368
369 369 For example, the template configuration below shows as same text as
370 370 one shown by default::
371 371
372 372 [committemplate]
373 373 changeset = {desc}\n\n
374 374 HG: Enter commit message. Lines beginning with 'HG:' are removed.
375 375 HG: {extramsg}
376 376 HG: --
377 377 HG: user: {author}\n{ifeq(p2rev, "-1", "",
378 378 "HG: branch merge\n")
379 379 }HG: branch '{branch}'\n{if(currentbookmark,
380 380 "HG: bookmark '{currentbookmark}'\n") }{subrepos %
381 381 "HG: subrepo {subrepo}\n" }{file_adds %
382 382 "HG: added {file}\n" }{file_mods %
383 383 "HG: changed {file}\n" }{file_dels %
384 384 "HG: removed {file}\n" }{if(files, "",
385 385 "HG: no files changed\n")}
386 386
387 387 .. note::
388 388
389 389 For some problematic encodings (see :hg:`help win32mbcs` for
390 390 detail), this customization should be configured carefully, to
391 391 avoid showing broken characters.
392 392
393 393 For example, if multibyte character ending with backslash (0x5c) is
394 394 followed by ASCII character 'n' in the customized template,
395 395 sequence of backslash and 'n' is treated as line-feed unexpectedly
396 396 (and multibyte character is broken, too).
397 397
398 398 Customized template is used for commands below (``--edit`` may be
399 399 required):
400 400
401 401 - :hg:`backout`
402 402 - :hg:`commit`
403 403 - :hg:`fetch` (for merge commit only)
404 404 - :hg:`graft`
405 405 - :hg:`histedit`
406 406 - :hg:`import`
407 407 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
408 408 - :hg:`rebase`
409 409 - :hg:`shelve`
410 410 - :hg:`sign`
411 411 - :hg:`tag`
412 412 - :hg:`transplant`
413 413
414 414 Configuring items below instead of ``changeset`` allows showing
415 415 customized message only for specific actions, or showing different
416 416 messages for each action.
417 417
418 418 - ``changeset.backout`` for :hg:`backout`
419 419 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
420 420 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
421 421 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
422 422 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
423 423 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
424 424 - ``changeset.gpg.sign`` for :hg:`sign`
425 425 - ``changeset.graft`` for :hg:`graft`
426 426 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
427 427 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
428 428 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
429 429 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
430 430 - ``changeset.import.bypass`` for :hg:`import --bypass`
431 431 - ``changeset.import.normal.merge`` for :hg:`import` on merges
432 432 - ``changeset.import.normal.normal`` for :hg:`import` on other
433 433 - ``changeset.mq.qnew`` for :hg:`qnew`
434 434 - ``changeset.mq.qfold`` for :hg:`qfold`
435 435 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
436 436 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
437 437 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
438 438 - ``changeset.rebase.normal`` for :hg:`rebase` on other
439 439 - ``changeset.shelve.shelve`` for :hg:`shelve`
440 440 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
441 441 - ``changeset.tag.remove`` for :hg:`tag --remove`
442 442 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
443 443 - ``changeset.transplant.normal`` for :hg:`transplant` on other
444 444
445 445 These dot-separated lists of names are treated as hierarchical ones.
446 446 For example, ``changeset.tag.remove`` customizes the commit message
447 447 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
448 448 commit message for :hg:`tag` regardless of ``--remove`` option.
449 449
450 450 At the external editor invocation for committing, corresponding
451 451 dot-separated list of names without ``changeset.`` prefix
452 452 (e.g. ``commit.normal.normal``) is in ``HGEDITFORM`` environment variable.
453 453
454 454 In this section, items other than ``changeset`` can be referred from
455 455 others. For example, the configuration to list committed files up
456 456 below can be referred as ``{listupfiles}``::
457 457
458 458 [committemplate]
459 459 listupfiles = {file_adds %
460 460 "HG: added {file}\n" }{file_mods %
461 461 "HG: changed {file}\n" }{file_dels %
462 462 "HG: removed {file}\n" }{if(files, "",
463 463 "HG: no files changed\n")}
464 464
465 465 ``decode/encode``
466 466 -----------------
467 467
468 468 Filters for transforming files on checkout/checkin. This would
469 469 typically be used for newline processing or other
470 470 localization/canonicalization of files.
471 471
472 472 Filters consist of a filter pattern followed by a filter command.
473 473 Filter patterns are globs by default, rooted at the repository root.
474 474 For example, to match any file ending in ``.txt`` in the root
475 475 directory only, use the pattern ``*.txt``. To match any file ending
476 476 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
477 477 For each file only the first matching filter applies.
478 478
479 479 The filter command can start with a specifier, either ``pipe:`` or
480 480 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
481 481
482 482 A ``pipe:`` command must accept data on stdin and return the transformed
483 483 data on stdout.
484 484
485 485 Pipe example::
486 486
487 487 [encode]
488 488 # uncompress gzip files on checkin to improve delta compression
489 489 # note: not necessarily a good idea, just an example
490 490 *.gz = pipe: gunzip
491 491
492 492 [decode]
493 493 # recompress gzip files when writing them to the working dir (we
494 494 # can safely omit "pipe:", because it's the default)
495 495 *.gz = gzip
496 496
497 497 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
498 498 with the name of a temporary file that contains the data to be
499 499 filtered by the command. The string ``OUTFILE`` is replaced with the name
500 500 of an empty temporary file, where the filtered data must be written by
501 501 the command.
502 502
503 503 .. note::
504 504
505 505 The tempfile mechanism is recommended for Windows systems,
506 506 where the standard shell I/O redirection operators often have
507 507 strange effects and may corrupt the contents of your files.
508 508
509 509 This filter mechanism is used internally by the ``eol`` extension to
510 510 translate line ending characters between Windows (CRLF) and Unix (LF)
511 511 format. We suggest you use the ``eol`` extension for convenience.
512 512
513 513
514 514 ``defaults``
515 515 ------------
516 516
517 517 (defaults are deprecated. Don't use them. Use aliases instead)
518 518
519 519 Use the ``[defaults]`` section to define command defaults, i.e. the
520 520 default options/arguments to pass to the specified commands.
521 521
522 522 The following example makes :hg:`log` run in verbose mode, and
523 523 :hg:`status` show only the modified files, by default::
524 524
525 525 [defaults]
526 526 log = -v
527 527 status = -m
528 528
529 529 The actual commands, instead of their aliases, must be used when
530 530 defining command defaults. The command defaults will also be applied
531 531 to the aliases of the commands defined.
532 532
533 533
534 534 ``diff``
535 535 --------
536 536
537 537 Settings used when displaying diffs. Everything except for ``unified``
538 538 is a Boolean and defaults to False. See ``annotate`` section for
539 539 related options for the annotate command.
540 540
541 541 ``git``
542 542 Use git extended diff format.
543 543
544 544 ``nobinary``
545 545 Omit git binary patches.
546 546
547 547 ``nodates``
548 548 Don't include dates in diff headers.
549 549
550 550 ``noprefix``
551 551 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
552 552
553 553 ``showfunc``
554 554 Show which function each change is in.
555 555
556 556 ``ignorews``
557 557 Ignore white space when comparing lines.
558 558
559 559 ``ignorewsamount``
560 560 Ignore changes in the amount of white space.
561 561
562 562 ``ignoreblanklines``
563 563 Ignore changes whose lines are all blank.
564 564
565 565 ``unified``
566 566 Number of lines of context to show.
567 567
568 568 ``email``
569 569 ---------
570 570
571 571 Settings for extensions that send email messages.
572 572
573 573 ``from``
574 574 Optional. Email address to use in "From" header and SMTP envelope
575 575 of outgoing messages.
576 576
577 577 ``to``
578 578 Optional. Comma-separated list of recipients' email addresses.
579 579
580 580 ``cc``
581 581 Optional. Comma-separated list of carbon copy recipients'
582 582 email addresses.
583 583
584 584 ``bcc``
585 585 Optional. Comma-separated list of blind carbon copy recipients'
586 586 email addresses.
587 587
588 588 ``method``
589 589 Optional. Method to use to send email messages. If value is ``smtp``
590 590 (default), use SMTP (see the ``[smtp]`` section for configuration).
591 591 Otherwise, use as name of program to run that acts like sendmail
592 592 (takes ``-f`` option for sender, list of recipients on command line,
593 593 message on stdin). Normally, setting this to ``sendmail`` or
594 594 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
595 595
596 596 ``charsets``
597 597 Optional. Comma-separated list of character sets considered
598 598 convenient for recipients. Addresses, headers, and parts not
599 599 containing patches of outgoing messages will be encoded in the
600 600 first character set to which conversion from local encoding
601 601 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
602 602 conversion fails, the text in question is sent as is. Defaults to
603 603 empty (explicit) list.
604 604
605 605 Order of outgoing email character sets:
606 606
607 607 1. ``us-ascii``: always first, regardless of settings
608 608 2. ``email.charsets``: in order given by user
609 609 3. ``ui.fallbackencoding``: if not in email.charsets
610 610 4. ``$HGENCODING``: if not in email.charsets
611 611 5. ``utf-8``: always last, regardless of settings
612 612
613 613 Email example::
614 614
615 615 [email]
616 616 from = Joseph User <joe.user@example.com>
617 617 method = /usr/sbin/sendmail
618 618 # charsets for western Europeans
619 619 # us-ascii, utf-8 omitted, as they are tried first and last
620 620 charsets = iso-8859-1, iso-8859-15, windows-1252
621 621
622 622
623 623 ``extensions``
624 624 --------------
625 625
626 626 Mercurial has an extension mechanism for adding new features. To
627 627 enable an extension, create an entry for it in this section.
628 628
629 629 If you know that the extension is already in Python's search path,
630 630 you can give the name of the module, followed by ``=``, with nothing
631 631 after the ``=``.
632 632
633 633 Otherwise, give a name that you choose, followed by ``=``, followed by
634 634 the path to the ``.py`` file (including the file name extension) that
635 635 defines the extension.
636 636
637 637 To explicitly disable an extension that is enabled in an hgrc of
638 638 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
639 639 or ``foo = !`` when path is not supplied.
640 640
641 641 Example for ``~/.hgrc``::
642 642
643 643 [extensions]
644 644 # (the progress extension will get loaded from Mercurial's path)
645 645 progress =
646 646 # (this extension will get loaded from the file specified)
647 647 myfeature = ~/.hgext/myfeature.py
648 648
649 649
650 650 ``format``
651 651 ----------
652 652
653 653 ``usestore``
654 654 Enable or disable the "store" repository format which improves
655 655 compatibility with systems that fold case or otherwise mangle
656 656 filenames. Enabled by default. Disabling this option will allow
657 657 you to store longer filenames in some situations at the expense of
658 658 compatibility and ensures that the on-disk format of newly created
659 659 repositories will be compatible with Mercurial before version 0.9.4.
660 660
661 661 ``usefncache``
662 662 Enable or disable the "fncache" repository format which enhances
663 663 the "store" repository format (which has to be enabled to use
664 664 fncache) to allow longer filenames and avoids using Windows
665 665 reserved names, e.g. "nul". Enabled by default. Disabling this
666 666 option ensures that the on-disk format of newly created
667 667 repositories will be compatible with Mercurial before version 1.1.
668 668
669 669 ``dotencode``
670 670 Enable or disable the "dotencode" repository format which enhances
671 671 the "fncache" repository format (which has to be enabled to use
672 672 dotencode) to avoid issues with filenames starting with ._ on
673 673 Mac OS X and spaces on Windows. Enabled by default. Disabling this
674 674 option ensures that the on-disk format of newly created
675 675 repositories will be compatible with Mercurial before version 1.7.
676 676
677 677 ``graph``
678 678 ---------
679 679
680 680 Web graph view configuration. This section let you change graph
681 681 elements display properties by branches, for instance to make the
682 682 ``default`` branch stand out.
683 683
684 684 Each line has the following format::
685 685
686 686 <branch>.<argument> = <value>
687 687
688 688 where ``<branch>`` is the name of the branch being
689 689 customized. Example::
690 690
691 691 [graph]
692 692 # 2px width
693 693 default.width = 2
694 694 # red color
695 695 default.color = FF0000
696 696
697 697 Supported arguments:
698 698
699 699 ``width``
700 700 Set branch edges width in pixels.
701 701
702 702 ``color``
703 703 Set branch edges color in hexadecimal RGB notation.
704 704
705 705 ``hooks``
706 706 ---------
707 707
708 708 Commands or Python functions that get automatically executed by
709 709 various actions such as starting or finishing a commit. Multiple
710 710 hooks can be run for the same action by appending a suffix to the
711 711 action. Overriding a site-wide hook can be done by changing its
712 712 value or setting it to an empty string. Hooks can be prioritized
713 713 by adding a prefix of ``priority`` to the hook name on a new line
714 714 and setting the priority. The default priority is 0 if
715 715 not specified.
716 716
717 717 Example ``.hg/hgrc``::
718 718
719 719 [hooks]
720 720 # update working directory after adding changesets
721 721 changegroup.update = hg update
722 722 # do not use the site-wide hook
723 723 incoming =
724 724 incoming.email = /my/email/hook
725 725 incoming.autobuild = /my/build/hook
726 726 # force autobuild hook to run before other incoming hooks
727 727 priority.incoming.autobuild = 1
728 728
729 729 Most hooks are run with environment variables set that give useful
730 730 additional information. For each hook below, the environment
731 731 variables it is passed are listed with names of the form ``$HG_foo``.
732 732
733 733 ``changegroup``
734 734 Run after a changegroup has been added via push, pull or unbundle.
735 735 ID of the first new changeset is in ``$HG_NODE``. URL from which
736 736 changes came is in ``$HG_URL``.
737 737
738 738 ``commit``
739 739 Run after a changeset has been created in the local repository. ID
740 740 of the newly created changeset is in ``$HG_NODE``. Parent changeset
741 741 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
742 742
743 743 ``incoming``
744 744 Run after a changeset has been pulled, pushed, or unbundled into
745 745 the local repository. The ID of the newly arrived changeset is in
746 746 ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``.
747 747
748 748 ``outgoing``
749 749 Run after sending changes from local repository to another. ID of
750 750 first changeset sent is in ``$HG_NODE``. Source of operation is in
751 751 ``$HG_SOURCE``; see "preoutgoing" hook for description.
752 752
753 753 ``post-<command>``
754 754 Run after successful invocations of the associated command. The
755 755 contents of the command line are passed as ``$HG_ARGS`` and the result
756 756 code in ``$HG_RESULT``. Parsed command line arguments are passed as
757 757 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
758 758 the python data internally passed to <command>. ``$HG_OPTS`` is a
759 759 dictionary of options (with unspecified options set to their defaults).
760 760 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
761 761
762 762 ``pre-<command>``
763 763 Run before executing the associated command. The contents of the
764 764 command line are passed as ``$HG_ARGS``. Parsed command line arguments
765 765 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
766 766 representations of the data internally passed to <command>. ``$HG_OPTS``
767 767 is a dictionary of options (with unspecified options set to their
768 768 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
769 769 failure, the command doesn't execute and Mercurial returns the failure
770 770 code.
771 771
772 772 ``prechangegroup``
773 773 Run before a changegroup is added via push, pull or unbundle. Exit
774 774 status 0 allows the changegroup to proceed. Non-zero status will
775 775 cause the push, pull or unbundle to fail. URL from which changes
776 776 will come is in ``$HG_URL``.
777 777
778 778 ``precommit``
779 779 Run before starting a local commit. Exit status 0 allows the
780 780 commit to proceed. Non-zero status will cause the commit to fail.
781 781 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
782 782
783 783 ``prelistkeys``
784 784 Run before listing pushkeys (like bookmarks) in the
785 785 repository. Non-zero status will cause failure. The key namespace is
786 786 in ``$HG_NAMESPACE``.
787 787
788 788 ``preoutgoing``
789 789 Run before collecting changes to send from the local repository to
790 790 another. Non-zero status will cause failure. This lets you prevent
791 791 pull over HTTP or SSH. Also prevents against local pull, push
792 792 (outbound) or bundle commands, but not effective, since you can
793 793 just copy files instead then. Source of operation is in
794 794 ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
795 795 SSH or HTTP repository. If "push", "pull" or "bundle", operation
796 796 is happening on behalf of repository on same system.
797 797
798 798 ``prepushkey``
799 799 Run before a pushkey (like a bookmark) is added to the
800 800 repository. Non-zero status will cause the key to be rejected. The
801 801 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
802 802 the old value (if any) is in ``$HG_OLD``, and the new value is in
803 803 ``$HG_NEW``.
804 804
805 805 ``pretag``
806 806 Run before creating a tag. Exit status 0 allows the tag to be
807 807 created. Non-zero status will cause the tag to fail. ID of
808 808 changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag is
809 809 local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``.
810 810
811 811 ``pretxnopen``
812 812 Run before any new repository transaction is open. The reason for the
813 813 transaction will be in ``$HG_TXNNAME``. A non-zero status will
814 814 prevent the transaction from being opened.
815 815
816 ``txnclose``
817 Run after any repository transaction has been commited. At this
818 point, the transaction can no longer be rolled back. The hook will run
819 after the lock is released. The reason for the transaction will
820 be in ``$HG_TXNNAME``. The rest of the available data will vary
821 according the event that happened during the transaction. New changesets
822 will add ``$HG_NODE`` (id of the first added changeset), ``$HG_URL``
823 and ``$HG_SOURCE`` variables, bookmarks and phases changes will set
824 ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``, etc.
825
816 826 ``pretxnchangegroup``
817 827 Run after a changegroup has been added via push, pull or unbundle,
818 828 but before the transaction has been committed. Changegroup is
819 829 visible to hook program. This lets you validate incoming changes
820 830 before accepting them. Passed the ID of the first new changeset in
821 831 ``$HG_NODE``. Exit status 0 allows the transaction to commit. Non-zero
822 832 status will cause the transaction to be rolled back and the push,
823 833 pull or unbundle will fail. URL that was source of changes is in
824 834 ``$HG_URL``.
825 835
826 836 ``pretxncommit``
827 837 Run after a changeset has been created but the transaction not yet
828 838 committed. Changeset is visible to hook program. This lets you
829 839 validate commit message and changes. Exit status 0 allows the
830 840 commit to proceed. Non-zero status will cause the transaction to
831 841 be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset
832 842 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
833 843
834 844 ``preupdate``
835 845 Run before updating the working directory. Exit status 0 allows
836 846 the update to proceed. Non-zero status will prevent the update.
837 847 Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
838 848 of second new parent is in ``$HG_PARENT2``.
839 849
840 850 ``listkeys``
841 851 Run after listing pushkeys (like bookmarks) in the repository. The
842 852 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
843 853 dictionary containing the keys and values.
844 854
845 855 ``pushkey``
846 856 Run after a pushkey (like a bookmark) is added to the
847 857 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
848 858 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
849 859 value is in ``$HG_NEW``.
850 860
851 861 ``tag``
852 862 Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
853 863 Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
854 864 repository if ``$HG_LOCAL=0``.
855 865
856 866 ``update``
857 867 Run after updating the working directory. Changeset ID of first
858 868 new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is
859 869 in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
860 870 update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``.
861 871
862 872 .. note::
863 873
864 874 It is generally better to use standard hooks rather than the
865 875 generic pre- and post- command hooks as they are guaranteed to be
866 876 called in the appropriate contexts for influencing transactions.
867 877 Also, hooks like "commit" will be called in all contexts that
868 878 generate a commit (e.g. tag) and not just the commit command.
869 879
870 880 .. note::
871 881
872 882 Environment variables with empty values may not be passed to
873 883 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
874 884 will have an empty value under Unix-like platforms for non-merge
875 885 changesets, while it will not be available at all under Windows.
876 886
877 887 The syntax for Python hooks is as follows::
878 888
879 889 hookname = python:modulename.submodule.callable
880 890 hookname = python:/path/to/python/module.py:callable
881 891
882 892 Python hooks are run within the Mercurial process. Each hook is
883 893 called with at least three keyword arguments: a ui object (keyword
884 894 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
885 895 keyword that tells what kind of hook is used. Arguments listed as
886 896 environment variables above are passed as keyword arguments, with no
887 897 ``HG_`` prefix, and names in lower case.
888 898
889 899 If a Python hook returns a "true" value or raises an exception, this
890 900 is treated as a failure.
891 901
892 902
893 903 ``hostfingerprints``
894 904 --------------------
895 905
896 906 Fingerprints of the certificates of known HTTPS servers.
897 907 A HTTPS connection to a server with a fingerprint configured here will
898 908 only succeed if the servers certificate matches the fingerprint.
899 909 This is very similar to how ssh known hosts works.
900 910 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
901 911 The CA chain and web.cacerts is not used for servers with a fingerprint.
902 912
903 913 For example::
904 914
905 915 [hostfingerprints]
906 916 hg.intevation.org = fa:1f:d9:48:f1:e7:74:30:38:8d:d8:58:b6:94:b8:58:28:7d:8b:d0
907 917
908 918 This feature is only supported when using Python 2.6 or later.
909 919
910 920
911 921 ``http_proxy``
912 922 --------------
913 923
914 924 Used to access web-based Mercurial repositories through a HTTP
915 925 proxy.
916 926
917 927 ``host``
918 928 Host name and (optional) port of the proxy server, for example
919 929 "myproxy:8000".
920 930
921 931 ``no``
922 932 Optional. Comma-separated list of host names that should bypass
923 933 the proxy.
924 934
925 935 ``passwd``
926 936 Optional. Password to authenticate with at the proxy server.
927 937
928 938 ``user``
929 939 Optional. User name to authenticate with at the proxy server.
930 940
931 941 ``always``
932 942 Optional. Always use the proxy, even for localhost and any entries
933 943 in ``http_proxy.no``. True or False. Default: False.
934 944
935 945 ``merge-patterns``
936 946 ------------------
937 947
938 948 This section specifies merge tools to associate with particular file
939 949 patterns. Tools matched here will take precedence over the default
940 950 merge tool. Patterns are globs by default, rooted at the repository
941 951 root.
942 952
943 953 Example::
944 954
945 955 [merge-patterns]
946 956 **.c = kdiff3
947 957 **.jpg = myimgmerge
948 958
949 959 ``merge-tools``
950 960 ---------------
951 961
952 962 This section configures external merge tools to use for file-level
953 963 merges. This section has likely been preconfigured at install time.
954 964 Use :hg:`config merge-tools` to check the existing configuration.
955 965 Also see :hg:`help merge-tools` for more details.
956 966
957 967 Example ``~/.hgrc``::
958 968
959 969 [merge-tools]
960 970 # Override stock tool location
961 971 kdiff3.executable = ~/bin/kdiff3
962 972 # Specify command line
963 973 kdiff3.args = $base $local $other -o $output
964 974 # Give higher priority
965 975 kdiff3.priority = 1
966 976
967 977 # Changing the priority of preconfigured tool
968 978 vimdiff.priority = 0
969 979
970 980 # Define new tool
971 981 myHtmlTool.args = -m $local $other $base $output
972 982 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
973 983 myHtmlTool.priority = 1
974 984
975 985 Supported arguments:
976 986
977 987 ``priority``
978 988 The priority in which to evaluate this tool.
979 989 Default: 0.
980 990
981 991 ``executable``
982 992 Either just the name of the executable or its pathname. On Windows,
983 993 the path can use environment variables with ${ProgramFiles} syntax.
984 994 Default: the tool name.
985 995
986 996 ``args``
987 997 The arguments to pass to the tool executable. You can refer to the
988 998 files being merged as well as the output file through these
989 999 variables: ``$base``, ``$local``, ``$other``, ``$output``. The meaning
990 1000 of ``$local`` and ``$other`` can vary depending on which action is being
991 1001 performed. During and update or merge, ``$local`` represents the original
992 1002 state of the file, while ``$other`` represents the commit you are updating
993 1003 to or the commit you are merging with. During a rebase ``$local``
994 1004 represents the destination of the rebase, and ``$other`` represents the
995 1005 commit being rebased.
996 1006 Default: ``$local $base $other``
997 1007
998 1008 ``premerge``
999 1009 Attempt to run internal non-interactive 3-way merge tool before
1000 1010 launching external tool. Options are ``true``, ``false``, ``keep`` or
1001 1011 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1002 1012 premerge fails. The ``keep-merge3`` will do the same but include information
1003 1013 about the base of the merge in the marker (see internal :merge3 in
1004 1014 :hg:`help merge-tools`).
1005 1015 Default: True
1006 1016
1007 1017 ``binary``
1008 1018 This tool can merge binary files. Defaults to False, unless tool
1009 1019 was selected by file pattern match.
1010 1020
1011 1021 ``symlink``
1012 1022 This tool can merge symlinks. Defaults to False, even if tool was
1013 1023 selected by file pattern match.
1014 1024
1015 1025 ``check``
1016 1026 A list of merge success-checking options:
1017 1027
1018 1028 ``changed``
1019 1029 Ask whether merge was successful when the merged file shows no changes.
1020 1030 ``conflicts``
1021 1031 Check whether there are conflicts even though the tool reported success.
1022 1032 ``prompt``
1023 1033 Always prompt for merge success, regardless of success reported by tool.
1024 1034
1025 1035 ``fixeol``
1026 1036 Attempt to fix up EOL changes caused by the merge tool.
1027 1037 Default: False
1028 1038
1029 1039 ``gui``
1030 1040 This tool requires a graphical interface to run. Default: False
1031 1041
1032 1042 ``regkey``
1033 1043 Windows registry key which describes install location of this
1034 1044 tool. Mercurial will search for this key first under
1035 1045 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1036 1046 Default: None
1037 1047
1038 1048 ``regkeyalt``
1039 1049 An alternate Windows registry key to try if the first key is not
1040 1050 found. The alternate key uses the same ``regname`` and ``regappend``
1041 1051 semantics of the primary key. The most common use for this key
1042 1052 is to search for 32bit applications on 64bit operating systems.
1043 1053 Default: None
1044 1054
1045 1055 ``regname``
1046 1056 Name of value to read from specified registry key. Defaults to the
1047 1057 unnamed (default) value.
1048 1058
1049 1059 ``regappend``
1050 1060 String to append to the value read from the registry, typically
1051 1061 the executable name of the tool.
1052 1062 Default: None
1053 1063
1054 1064
1055 1065 ``patch``
1056 1066 ---------
1057 1067
1058 1068 Settings used when applying patches, for instance through the 'import'
1059 1069 command or with Mercurial Queues extension.
1060 1070
1061 1071 ``eol``
1062 1072 When set to 'strict' patch content and patched files end of lines
1063 1073 are preserved. When set to ``lf`` or ``crlf``, both files end of
1064 1074 lines are ignored when patching and the result line endings are
1065 1075 normalized to either LF (Unix) or CRLF (Windows). When set to
1066 1076 ``auto``, end of lines are again ignored while patching but line
1067 1077 endings in patched files are normalized to their original setting
1068 1078 on a per-file basis. If target file does not exist or has no end
1069 1079 of line, patch line endings are preserved.
1070 1080 Default: strict.
1071 1081
1072 1082
1073 1083 ``paths``
1074 1084 ---------
1075 1085
1076 1086 Assigns symbolic names to repositories. The left side is the
1077 1087 symbolic name, and the right gives the directory or URL that is the
1078 1088 location of the repository. Default paths can be declared by setting
1079 1089 the following entries.
1080 1090
1081 1091 ``default``
1082 1092 Directory or URL to use when pulling if no source is specified.
1083 1093 Default is set to repository from which the current repository was
1084 1094 cloned.
1085 1095
1086 1096 ``default-push``
1087 1097 Optional. Directory or URL to use when pushing if no destination
1088 1098 is specified.
1089 1099
1090 1100 Custom paths can be defined by assigning the path to a name that later can be
1091 1101 used from the command line. Example::
1092 1102
1093 1103 [paths]
1094 1104 my_path = http://example.com/path
1095 1105
1096 1106 To push to the path defined in ``my_path`` run the command::
1097 1107
1098 1108 hg push my_path
1099 1109
1100 1110
1101 1111 ``phases``
1102 1112 ----------
1103 1113
1104 1114 Specifies default handling of phases. See :hg:`help phases` for more
1105 1115 information about working with phases.
1106 1116
1107 1117 ``publish``
1108 1118 Controls draft phase behavior when working as a server. When true,
1109 1119 pushed changesets are set to public in both client and server and
1110 1120 pulled or cloned changesets are set to public in the client.
1111 1121 Default: True
1112 1122
1113 1123 ``new-commit``
1114 1124 Phase of newly-created commits.
1115 1125 Default: draft
1116 1126
1117 1127 ``checksubrepos``
1118 1128 Check the phase of the current revision of each subrepository. Allowed
1119 1129 values are "ignore", "follow" and "abort". For settings other than
1120 1130 "ignore", the phase of the current revision of each subrepository is
1121 1131 checked before committing the parent repository. If any of those phases is
1122 1132 greater than the phase of the parent repository (e.g. if a subrepo is in a
1123 1133 "secret" phase while the parent repo is in "draft" phase), the commit is
1124 1134 either aborted (if checksubrepos is set to "abort") or the higher phase is
1125 1135 used for the parent repository commit (if set to "follow").
1126 1136 Default: "follow"
1127 1137
1128 1138
1129 1139 ``profiling``
1130 1140 -------------
1131 1141
1132 1142 Specifies profiling type, format, and file output. Two profilers are
1133 1143 supported: an instrumenting profiler (named ``ls``), and a sampling
1134 1144 profiler (named ``stat``).
1135 1145
1136 1146 In this section description, 'profiling data' stands for the raw data
1137 1147 collected during profiling, while 'profiling report' stands for a
1138 1148 statistical text report generated from the profiling data. The
1139 1149 profiling is done using lsprof.
1140 1150
1141 1151 ``type``
1142 1152 The type of profiler to use.
1143 1153 Default: ls.
1144 1154
1145 1155 ``ls``
1146 1156 Use Python's built-in instrumenting profiler. This profiler
1147 1157 works on all platforms, but each line number it reports is the
1148 1158 first line of a function. This restriction makes it difficult to
1149 1159 identify the expensive parts of a non-trivial function.
1150 1160 ``stat``
1151 1161 Use a third-party statistical profiler, statprof. This profiler
1152 1162 currently runs only on Unix systems, and is most useful for
1153 1163 profiling commands that run for longer than about 0.1 seconds.
1154 1164
1155 1165 ``format``
1156 1166 Profiling format. Specific to the ``ls`` instrumenting profiler.
1157 1167 Default: text.
1158 1168
1159 1169 ``text``
1160 1170 Generate a profiling report. When saving to a file, it should be
1161 1171 noted that only the report is saved, and the profiling data is
1162 1172 not kept.
1163 1173 ``kcachegrind``
1164 1174 Format profiling data for kcachegrind use: when saving to a
1165 1175 file, the generated file can directly be loaded into
1166 1176 kcachegrind.
1167 1177
1168 1178 ``frequency``
1169 1179 Sampling frequency. Specific to the ``stat`` sampling profiler.
1170 1180 Default: 1000.
1171 1181
1172 1182 ``output``
1173 1183 File path where profiling data or report should be saved. If the
1174 1184 file exists, it is replaced. Default: None, data is printed on
1175 1185 stderr
1176 1186
1177 1187 ``sort``
1178 1188 Sort field. Specific to the ``ls`` instrumenting profiler.
1179 1189 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1180 1190 ``inlinetime``.
1181 1191 Default: inlinetime.
1182 1192
1183 1193 ``limit``
1184 1194 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1185 1195 Default: 30.
1186 1196
1187 1197 ``nested``
1188 1198 Show at most this number of lines of drill-down info after each main entry.
1189 1199 This can help explain the difference between Total and Inline.
1190 1200 Specific to the ``ls`` instrumenting profiler.
1191 1201 Default: 5.
1192 1202
1193 1203 ``revsetalias``
1194 1204 ---------------
1195 1205
1196 1206 Alias definitions for revsets. See :hg:`help revsets` for details.
1197 1207
1198 1208 ``server``
1199 1209 ----------
1200 1210
1201 1211 Controls generic server settings.
1202 1212
1203 1213 ``uncompressed``
1204 1214 Whether to allow clients to clone a repository using the
1205 1215 uncompressed streaming protocol. This transfers about 40% more
1206 1216 data than a regular clone, but uses less memory and CPU on both
1207 1217 server and client. Over a LAN (100 Mbps or better) or a very fast
1208 1218 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1209 1219 regular clone. Over most WAN connections (anything slower than
1210 1220 about 6 Mbps), uncompressed streaming is slower, because of the
1211 1221 extra data transfer overhead. This mode will also temporarily hold
1212 1222 the write lock while determining what data to transfer.
1213 1223 Default is True.
1214 1224
1215 1225 ``preferuncompressed``
1216 1226 When set, clients will try to use the uncompressed streaming
1217 1227 protocol. Default is False.
1218 1228
1219 1229 ``validate``
1220 1230 Whether to validate the completeness of pushed changesets by
1221 1231 checking that all new file revisions specified in manifests are
1222 1232 present. Default is False.
1223 1233
1224 1234 ``smtp``
1225 1235 --------
1226 1236
1227 1237 Configuration for extensions that need to send email messages.
1228 1238
1229 1239 ``host``
1230 1240 Host name of mail server, e.g. "mail.example.com".
1231 1241
1232 1242 ``port``
1233 1243 Optional. Port to connect to on mail server. Default: 465 (if
1234 1244 ``tls`` is smtps) or 25 (otherwise).
1235 1245
1236 1246 ``tls``
1237 1247 Optional. Method to enable TLS when connecting to mail server: starttls,
1238 1248 smtps or none. Default: none.
1239 1249
1240 1250 ``verifycert``
1241 1251 Optional. Verification for the certificate of mail server, when
1242 1252 ``tls`` is starttls or smtps. "strict", "loose" or False. For
1243 1253 "strict" or "loose", the certificate is verified as same as the
1244 1254 verification for HTTPS connections (see ``[hostfingerprints]`` and
1245 1255 ``[web] cacerts`` also). For "strict", sending email is also
1246 1256 aborted, if there is no configuration for mail server in
1247 1257 ``[hostfingerprints]`` and ``[web] cacerts``. --insecure for
1248 1258 :hg:`email` overwrites this as "loose". Default: "strict".
1249 1259
1250 1260 ``username``
1251 1261 Optional. User name for authenticating with the SMTP server.
1252 1262 Default: none.
1253 1263
1254 1264 ``password``
1255 1265 Optional. Password for authenticating with the SMTP server. If not
1256 1266 specified, interactive sessions will prompt the user for a
1257 1267 password; non-interactive sessions will fail. Default: none.
1258 1268
1259 1269 ``local_hostname``
1260 1270 Optional. It's the hostname that the sender can use to identify
1261 1271 itself to the MTA.
1262 1272
1263 1273
1264 1274 ``subpaths``
1265 1275 ------------
1266 1276
1267 1277 Subrepository source URLs can go stale if a remote server changes name
1268 1278 or becomes temporarily unavailable. This section lets you define
1269 1279 rewrite rules of the form::
1270 1280
1271 1281 <pattern> = <replacement>
1272 1282
1273 1283 where ``pattern`` is a regular expression matching a subrepository
1274 1284 source URL and ``replacement`` is the replacement string used to
1275 1285 rewrite it. Groups can be matched in ``pattern`` and referenced in
1276 1286 ``replacements``. For instance::
1277 1287
1278 1288 http://server/(.*)-hg/ = http://hg.server/\1/
1279 1289
1280 1290 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
1281 1291
1282 1292 Relative subrepository paths are first made absolute, and the
1283 1293 rewrite rules are then applied on the full (absolute) path. The rules
1284 1294 are applied in definition order.
1285 1295
1286 1296 ``trusted``
1287 1297 -----------
1288 1298
1289 1299 Mercurial will not use the settings in the
1290 1300 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
1291 1301 user or to a trusted group, as various hgrc features allow arbitrary
1292 1302 commands to be run. This issue is often encountered when configuring
1293 1303 hooks or extensions for shared repositories or servers. However,
1294 1304 the web interface will use some safe settings from the ``[web]``
1295 1305 section.
1296 1306
1297 1307 This section specifies what users and groups are trusted. The
1298 1308 current user is always trusted. To trust everybody, list a user or a
1299 1309 group with name ``*``. These settings must be placed in an
1300 1310 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
1301 1311 user or service running Mercurial.
1302 1312
1303 1313 ``users``
1304 1314 Comma-separated list of trusted users.
1305 1315
1306 1316 ``groups``
1307 1317 Comma-separated list of trusted groups.
1308 1318
1309 1319
1310 1320 ``ui``
1311 1321 ------
1312 1322
1313 1323 User interface controls.
1314 1324
1315 1325 ``archivemeta``
1316 1326 Whether to include the .hg_archival.txt file containing meta data
1317 1327 (hashes for the repository base and for tip) in archives created
1318 1328 by the :hg:`archive` command or downloaded via hgweb.
1319 1329 Default is True.
1320 1330
1321 1331 ``askusername``
1322 1332 Whether to prompt for a username when committing. If True, and
1323 1333 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
1324 1334 be prompted to enter a username. If no username is entered, the
1325 1335 default ``USER@HOST`` is used instead.
1326 1336 Default is False.
1327 1337
1328 1338 ``commitsubrepos``
1329 1339 Whether to commit modified subrepositories when committing the
1330 1340 parent repository. If False and one subrepository has uncommitted
1331 1341 changes, abort the commit.
1332 1342 Default is False.
1333 1343
1334 1344 ``debug``
1335 1345 Print debugging information. True or False. Default is False.
1336 1346
1337 1347 ``editor``
1338 1348 The editor to use during a commit. Default is ``$EDITOR`` or ``vi``.
1339 1349
1340 1350 ``fallbackencoding``
1341 1351 Encoding to try if it's not possible to decode the changelog using
1342 1352 UTF-8. Default is ISO-8859-1.
1343 1353
1344 1354 ``ignore``
1345 1355 A file to read per-user ignore patterns from. This file should be
1346 1356 in the same format as a repository-wide .hgignore file. Filenames
1347 1357 are relative to the repository root. This option supports hook syntax,
1348 1358 so if you want to specify multiple ignore files, you can do so by
1349 1359 setting something like ``ignore.other = ~/.hgignore2``. For details
1350 1360 of the ignore file format, see the ``hgignore(5)`` man page.
1351 1361
1352 1362 ``interactive``
1353 1363 Allow to prompt the user. True or False. Default is True.
1354 1364
1355 1365 ``logtemplate``
1356 1366 Template string for commands that print changesets.
1357 1367
1358 1368 ``merge``
1359 1369 The conflict resolution program to use during a manual merge.
1360 1370 For more information on merge tools see :hg:`help merge-tools`.
1361 1371 For configuring merge tools see the ``[merge-tools]`` section.
1362 1372
1363 1373 ``mergemarkers``
1364 1374 Sets the merge conflict marker label styling. The ``detailed``
1365 1375 style uses the ``mergemarkertemplate`` setting to style the labels.
1366 1376 The ``basic`` style just uses 'local' and 'other' as the marker label.
1367 1377 One of ``basic`` or ``detailed``.
1368 1378 Default is ``basic``.
1369 1379
1370 1380 ``mergemarkertemplate``
1371 1381 The template used to print the commit description next to each conflict
1372 1382 marker during merge conflicts. See :hg:`help templates` for the template
1373 1383 format.
1374 1384 Defaults to showing the hash, tags, branches, bookmarks, author, and
1375 1385 the first line of the commit description.
1376 1386 You have to pay attention to encodings of managed files, if you
1377 1387 use non-ASCII characters in tags, branches, bookmarks, author
1378 1388 and/or commit descriptions. At template expansion, non-ASCII
1379 1389 characters use the encoding specified by ``--encoding`` global
1380 1390 option, ``HGENCODING`` or other locale setting environment
1381 1391 variables. The difference of encoding between merged file and
1382 1392 conflict markers causes serious problem.
1383 1393
1384 1394 ``portablefilenames``
1385 1395 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
1386 1396 Default is ``warn``.
1387 1397 If set to ``warn`` (or ``true``), a warning message is printed on POSIX
1388 1398 platforms, if a file with a non-portable filename is added (e.g. a file
1389 1399 with a name that can't be created on Windows because it contains reserved
1390 1400 parts like ``AUX``, reserved characters like ``:``, or would cause a case
1391 1401 collision with an existing file).
1392 1402 If set to ``ignore`` (or ``false``), no warning is printed.
1393 1403 If set to ``abort``, the command is aborted.
1394 1404 On Windows, this configuration option is ignored and the command aborted.
1395 1405
1396 1406 ``quiet``
1397 1407 Reduce the amount of output printed. True or False. Default is False.
1398 1408
1399 1409 ``remotecmd``
1400 1410 remote command to use for clone/push/pull operations. Default is ``hg``.
1401 1411
1402 1412 ``reportoldssl``
1403 1413 Warn if an SSL certificate is unable to be used due to using Python
1404 1414 2.5 or earlier. True or False. Default is True.
1405 1415
1406 1416 ``report_untrusted``
1407 1417 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
1408 1418 trusted user or group. True or False. Default is True.
1409 1419
1410 1420 ``slash``
1411 1421 Display paths using a slash (``/``) as the path separator. This
1412 1422 only makes a difference on systems where the default path
1413 1423 separator is not the slash character (e.g. Windows uses the
1414 1424 backslash character (``\``)).
1415 1425 Default is False.
1416 1426
1417 1427 ``ssh``
1418 1428 command to use for SSH connections. Default is ``ssh``.
1419 1429
1420 1430 ``strict``
1421 1431 Require exact command names, instead of allowing unambiguous
1422 1432 abbreviations. True or False. Default is False.
1423 1433
1424 1434 ``style``
1425 1435 Name of style to use for command output.
1426 1436
1427 1437 ``timeout``
1428 1438 The timeout used when a lock is held (in seconds), a negative value
1429 1439 means no timeout. Default is 600.
1430 1440
1431 1441 ``traceback``
1432 1442 Mercurial always prints a traceback when an unknown exception
1433 1443 occurs. Setting this to True will make Mercurial print a traceback
1434 1444 on all exceptions, even those recognized by Mercurial (such as
1435 1445 IOError or MemoryError). Default is False.
1436 1446
1437 1447 ``username``
1438 1448 The committer of a changeset created when running "commit".
1439 1449 Typically a person's name and email address, e.g. ``Fred Widget
1440 1450 <fred@example.com>``. Default is ``$EMAIL`` or ``username@hostname``. If
1441 1451 the username in hgrc is empty, it has to be specified manually or
1442 1452 in a different hgrc file (e.g. ``$HOME/.hgrc``, if the admin set
1443 1453 ``username =`` in the system hgrc). Environment variables in the
1444 1454 username are expanded.
1445 1455
1446 1456 ``verbose``
1447 1457 Increase the amount of output printed. True or False. Default is False.
1448 1458
1449 1459
1450 1460 ``web``
1451 1461 -------
1452 1462
1453 1463 Web interface configuration. The settings in this section apply to
1454 1464 both the builtin webserver (started by :hg:`serve`) and the script you
1455 1465 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
1456 1466 and WSGI).
1457 1467
1458 1468 The Mercurial webserver does no authentication (it does not prompt for
1459 1469 usernames and passwords to validate *who* users are), but it does do
1460 1470 authorization (it grants or denies access for *authenticated users*
1461 1471 based on settings in this section). You must either configure your
1462 1472 webserver to do authentication for you, or disable the authorization
1463 1473 checks.
1464 1474
1465 1475 For a quick setup in a trusted environment, e.g., a private LAN, where
1466 1476 you want it to accept pushes from anybody, you can use the following
1467 1477 command line::
1468 1478
1469 1479 $ hg --config web.allow_push=* --config web.push_ssl=False serve
1470 1480
1471 1481 Note that this will allow anybody to push anything to the server and
1472 1482 that this should not be used for public servers.
1473 1483
1474 1484 The full set of options is:
1475 1485
1476 1486 ``accesslog``
1477 1487 Where to output the access log. Default is stdout.
1478 1488
1479 1489 ``address``
1480 1490 Interface address to bind to. Default is all.
1481 1491
1482 1492 ``allow_archive``
1483 1493 List of archive format (bz2, gz, zip) allowed for downloading.
1484 1494 Default is empty.
1485 1495
1486 1496 ``allowbz2``
1487 1497 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
1488 1498 revisions.
1489 1499 Default is False.
1490 1500
1491 1501 ``allowgz``
1492 1502 (DEPRECATED) Whether to allow .tar.gz downloading of repository
1493 1503 revisions.
1494 1504 Default is False.
1495 1505
1496 1506 ``allowpull``
1497 1507 Whether to allow pulling from the repository. Default is True.
1498 1508
1499 1509 ``allow_push``
1500 1510 Whether to allow pushing to the repository. If empty or not set,
1501 1511 push is not allowed. If the special value ``*``, any remote user can
1502 1512 push, including unauthenticated users. Otherwise, the remote user
1503 1513 must have been authenticated, and the authenticated user name must
1504 1514 be present in this list. The contents of the allow_push list are
1505 1515 examined after the deny_push list.
1506 1516
1507 1517 ``allow_read``
1508 1518 If the user has not already been denied repository access due to
1509 1519 the contents of deny_read, this list determines whether to grant
1510 1520 repository access to the user. If this list is not empty, and the
1511 1521 user is unauthenticated or not present in the list, then access is
1512 1522 denied for the user. If the list is empty or not set, then access
1513 1523 is permitted to all users by default. Setting allow_read to the
1514 1524 special value ``*`` is equivalent to it not being set (i.e. access
1515 1525 is permitted to all users). The contents of the allow_read list are
1516 1526 examined after the deny_read list.
1517 1527
1518 1528 ``allowzip``
1519 1529 (DEPRECATED) Whether to allow .zip downloading of repository
1520 1530 revisions. Default is False. This feature creates temporary files.
1521 1531
1522 1532 ``archivesubrepos``
1523 1533 Whether to recurse into subrepositories when archiving. Default is
1524 1534 False.
1525 1535
1526 1536 ``baseurl``
1527 1537 Base URL to use when publishing URLs in other locations, so
1528 1538 third-party tools like email notification hooks can construct
1529 1539 URLs. Example: ``http://hgserver/repos/``.
1530 1540
1531 1541 ``cacerts``
1532 1542 Path to file containing a list of PEM encoded certificate
1533 1543 authority certificates. Environment variables and ``~user``
1534 1544 constructs are expanded in the filename. If specified on the
1535 1545 client, then it will verify the identity of remote HTTPS servers
1536 1546 with these certificates.
1537 1547
1538 1548 This feature is only supported when using Python 2.6 or later. If you wish
1539 1549 to use it with earlier versions of Python, install the backported
1540 1550 version of the ssl library that is available from
1541 1551 ``http://pypi.python.org``.
1542 1552
1543 1553 To disable SSL verification temporarily, specify ``--insecure`` from
1544 1554 command line.
1545 1555
1546 1556 You can use OpenSSL's CA certificate file if your platform has
1547 1557 one. On most Linux systems this will be
1548 1558 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
1549 1559 generate this file manually. The form must be as follows::
1550 1560
1551 1561 -----BEGIN CERTIFICATE-----
1552 1562 ... (certificate in base64 PEM encoding) ...
1553 1563 -----END CERTIFICATE-----
1554 1564 -----BEGIN CERTIFICATE-----
1555 1565 ... (certificate in base64 PEM encoding) ...
1556 1566 -----END CERTIFICATE-----
1557 1567
1558 1568 ``cache``
1559 1569 Whether to support caching in hgweb. Defaults to True.
1560 1570
1561 1571 ``collapse``
1562 1572 With ``descend`` enabled, repositories in subdirectories are shown at
1563 1573 a single level alongside repositories in the current path. With
1564 1574 ``collapse`` also enabled, repositories residing at a deeper level than
1565 1575 the current path are grouped behind navigable directory entries that
1566 1576 lead to the locations of these repositories. In effect, this setting
1567 1577 collapses each collection of repositories found within a subdirectory
1568 1578 into a single entry for that subdirectory. Default is False.
1569 1579
1570 1580 ``comparisoncontext``
1571 1581 Number of lines of context to show in side-by-side file comparison. If
1572 1582 negative or the value ``full``, whole files are shown. Default is 5.
1573 1583 This setting can be overridden by a ``context`` request parameter to the
1574 1584 ``comparison`` command, taking the same values.
1575 1585
1576 1586 ``contact``
1577 1587 Name or email address of the person in charge of the repository.
1578 1588 Defaults to ui.username or ``$EMAIL`` or "unknown" if unset or empty.
1579 1589
1580 1590 ``deny_push``
1581 1591 Whether to deny pushing to the repository. If empty or not set,
1582 1592 push is not denied. If the special value ``*``, all remote users are
1583 1593 denied push. Otherwise, unauthenticated users are all denied, and
1584 1594 any authenticated user name present in this list is also denied. The
1585 1595 contents of the deny_push list are examined before the allow_push list.
1586 1596
1587 1597 ``deny_read``
1588 1598 Whether to deny reading/viewing of the repository. If this list is
1589 1599 not empty, unauthenticated users are all denied, and any
1590 1600 authenticated user name present in this list is also denied access to
1591 1601 the repository. If set to the special value ``*``, all remote users
1592 1602 are denied access (rarely needed ;). If deny_read is empty or not set,
1593 1603 the determination of repository access depends on the presence and
1594 1604 content of the allow_read list (see description). If both
1595 1605 deny_read and allow_read are empty or not set, then access is
1596 1606 permitted to all users by default. If the repository is being
1597 1607 served via hgwebdir, denied users will not be able to see it in
1598 1608 the list of repositories. The contents of the deny_read list have
1599 1609 priority over (are examined before) the contents of the allow_read
1600 1610 list.
1601 1611
1602 1612 ``descend``
1603 1613 hgwebdir indexes will not descend into subdirectories. Only repositories
1604 1614 directly in the current path will be shown (other repositories are still
1605 1615 available from the index corresponding to their containing path).
1606 1616
1607 1617 ``description``
1608 1618 Textual description of the repository's purpose or contents.
1609 1619 Default is "unknown".
1610 1620
1611 1621 ``encoding``
1612 1622 Character encoding name. Default is the current locale charset.
1613 1623 Example: "UTF-8"
1614 1624
1615 1625 ``errorlog``
1616 1626 Where to output the error log. Default is stderr.
1617 1627
1618 1628 ``guessmime``
1619 1629 Control MIME types for raw download of file content.
1620 1630 Set to True to let hgweb guess the content type from the file
1621 1631 extension. This will serve HTML files as ``text/html`` and might
1622 1632 allow cross-site scripting attacks when serving untrusted
1623 1633 repositories. Default is False.
1624 1634
1625 1635 ``hidden``
1626 1636 Whether to hide the repository in the hgwebdir index.
1627 1637 Default is False.
1628 1638
1629 1639 ``ipv6``
1630 1640 Whether to use IPv6. Default is False.
1631 1641
1632 1642 ``logoimg``
1633 1643 File name of the logo image that some templates display on each page.
1634 1644 The file name is relative to ``staticurl``. That is, the full path to
1635 1645 the logo image is "staticurl/logoimg".
1636 1646 If unset, ``hglogo.png`` will be used.
1637 1647
1638 1648 ``logourl``
1639 1649 Base URL to use for logos. If unset, ``http://mercurial.selenic.com/``
1640 1650 will be used.
1641 1651
1642 1652 ``maxchanges``
1643 1653 Maximum number of changes to list on the changelog. Default is 10.
1644 1654
1645 1655 ``maxfiles``
1646 1656 Maximum number of files to list per changeset. Default is 10.
1647 1657
1648 1658 ``maxshortchanges``
1649 1659 Maximum number of changes to list on the shortlog, graph or filelog
1650 1660 pages. Default is 60.
1651 1661
1652 1662 ``name``
1653 1663 Repository name to use in the web interface. Default is current
1654 1664 working directory.
1655 1665
1656 1666 ``port``
1657 1667 Port to listen on. Default is 8000.
1658 1668
1659 1669 ``prefix``
1660 1670 Prefix path to serve from. Default is '' (server root).
1661 1671
1662 1672 ``push_ssl``
1663 1673 Whether to require that inbound pushes be transported over SSL to
1664 1674 prevent password sniffing. Default is True.
1665 1675
1666 1676 ``staticurl``
1667 1677 Base URL to use for static files. If unset, static files (e.g. the
1668 1678 hgicon.png favicon) will be served by the CGI script itself. Use
1669 1679 this setting to serve them directly with the HTTP server.
1670 1680 Example: ``http://hgserver/static/``.
1671 1681
1672 1682 ``stripes``
1673 1683 How many lines a "zebra stripe" should span in multi-line output.
1674 1684 Default is 1; set to 0 to disable.
1675 1685
1676 1686 ``style``
1677 1687 Which template map style to use. The available options are the names of
1678 1688 subdirectories in the HTML templates path. Default is ``paper``.
1679 1689 Example: ``monoblue``
1680 1690
1681 1691 ``templates``
1682 1692 Where to find the HTML templates. The default path to the HTML templates
1683 1693 can be obtained from ``hg debuginstall``.
1684 1694
1685 1695 ``websub``
1686 1696 ----------
1687 1697
1688 1698 Web substitution filter definition. You can use this section to
1689 1699 define a set of regular expression substitution patterns which
1690 1700 let you automatically modify the hgweb server output.
1691 1701
1692 1702 The default hgweb templates only apply these substitution patterns
1693 1703 on the revision description fields. You can apply them anywhere
1694 1704 you want when you create your own templates by adding calls to the
1695 1705 "websub" filter (usually after calling the "escape" filter).
1696 1706
1697 1707 This can be used, for example, to convert issue references to links
1698 1708 to your issue tracker, or to convert "markdown-like" syntax into
1699 1709 HTML (see the examples below).
1700 1710
1701 1711 Each entry in this section names a substitution filter.
1702 1712 The value of each entry defines the substitution expression itself.
1703 1713 The websub expressions follow the old interhg extension syntax,
1704 1714 which in turn imitates the Unix sed replacement syntax::
1705 1715
1706 1716 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
1707 1717
1708 1718 You can use any separator other than "/". The final "i" is optional
1709 1719 and indicates that the search must be case insensitive.
1710 1720
1711 1721 Examples::
1712 1722
1713 1723 [websub]
1714 1724 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
1715 1725 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
1716 1726 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
1717 1727
1718 1728 ``worker``
1719 1729 ----------
1720 1730
1721 1731 Parallel master/worker configuration. We currently perform working
1722 1732 directory updates in parallel on Unix-like systems, which greatly
1723 1733 helps performance.
1724 1734
1725 1735 ``numcpus``
1726 1736 Number of CPUs to use for parallel operations. Default is 4 or the
1727 1737 number of CPUs on the system, whichever is larger. A zero or
1728 1738 negative value is treated as ``use the default``.
@@ -1,1858 +1,1868
1 1 # localrepo.py - read/write repository class for mercurial
2 2 #
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7 from node import hex, nullid, short
8 8 from i18n import _
9 9 import urllib
10 10 import peer, changegroup, subrepo, pushkey, obsolete, repoview
11 11 import changelog, dirstate, filelog, manifest, context, bookmarks, phases
12 12 import lock as lockmod
13 13 import transaction, store, encoding, exchange, bundle2
14 14 import scmutil, util, extensions, hook, error, revset
15 15 import match as matchmod
16 16 import merge as mergemod
17 17 import tags as tagsmod
18 18 from lock import release
19 19 import weakref, errno, os, time, inspect
20 20 import branchmap, pathutil
21 21 import namespaces
22 22 propertycache = util.propertycache
23 23 filecache = scmutil.filecache
24 24
25 25 class repofilecache(filecache):
26 26 """All filecache usage on repo are done for logic that should be unfiltered
27 27 """
28 28
29 29 def __get__(self, repo, type=None):
30 30 return super(repofilecache, self).__get__(repo.unfiltered(), type)
31 31 def __set__(self, repo, value):
32 32 return super(repofilecache, self).__set__(repo.unfiltered(), value)
33 33 def __delete__(self, repo):
34 34 return super(repofilecache, self).__delete__(repo.unfiltered())
35 35
36 36 class storecache(repofilecache):
37 37 """filecache for files in the store"""
38 38 def join(self, obj, fname):
39 39 return obj.sjoin(fname)
40 40
41 41 class unfilteredpropertycache(propertycache):
42 42 """propertycache that apply to unfiltered repo only"""
43 43
44 44 def __get__(self, repo, type=None):
45 45 unfi = repo.unfiltered()
46 46 if unfi is repo:
47 47 return super(unfilteredpropertycache, self).__get__(unfi)
48 48 return getattr(unfi, self.name)
49 49
50 50 class filteredpropertycache(propertycache):
51 51 """propertycache that must take filtering in account"""
52 52
53 53 def cachevalue(self, obj, value):
54 54 object.__setattr__(obj, self.name, value)
55 55
56 56
57 57 def hasunfilteredcache(repo, name):
58 58 """check if a repo has an unfilteredpropertycache value for <name>"""
59 59 return name in vars(repo.unfiltered())
60 60
61 61 def unfilteredmethod(orig):
62 62 """decorate method that always need to be run on unfiltered version"""
63 63 def wrapper(repo, *args, **kwargs):
64 64 return orig(repo.unfiltered(), *args, **kwargs)
65 65 return wrapper
66 66
67 67 moderncaps = set(('lookup', 'branchmap', 'pushkey', 'known', 'getbundle',
68 68 'unbundle'))
69 69 legacycaps = moderncaps.union(set(['changegroupsubset']))
70 70
71 71 class localpeer(peer.peerrepository):
72 72 '''peer for a local repo; reflects only the most recent API'''
73 73
74 74 def __init__(self, repo, caps=moderncaps):
75 75 peer.peerrepository.__init__(self)
76 76 self._repo = repo.filtered('served')
77 77 self.ui = repo.ui
78 78 self._caps = repo._restrictcapabilities(caps)
79 79 self.requirements = repo.requirements
80 80 self.supportedformats = repo.supportedformats
81 81
82 82 def close(self):
83 83 self._repo.close()
84 84
85 85 def _capabilities(self):
86 86 return self._caps
87 87
88 88 def local(self):
89 89 return self._repo
90 90
91 91 def canpush(self):
92 92 return True
93 93
94 94 def url(self):
95 95 return self._repo.url()
96 96
97 97 def lookup(self, key):
98 98 return self._repo.lookup(key)
99 99
100 100 def branchmap(self):
101 101 return self._repo.branchmap()
102 102
103 103 def heads(self):
104 104 return self._repo.heads()
105 105
106 106 def known(self, nodes):
107 107 return self._repo.known(nodes)
108 108
109 109 def getbundle(self, source, heads=None, common=None, bundlecaps=None,
110 110 format='HG10', **kwargs):
111 111 cg = exchange.getbundle(self._repo, source, heads=heads,
112 112 common=common, bundlecaps=bundlecaps, **kwargs)
113 113 if bundlecaps is not None and 'HG2Y' in bundlecaps:
114 114 # When requesting a bundle2, getbundle returns a stream to make the
115 115 # wire level function happier. We need to build a proper object
116 116 # from it in local peer.
117 117 cg = bundle2.unbundle20(self.ui, cg)
118 118 return cg
119 119
120 120 # TODO We might want to move the next two calls into legacypeer and add
121 121 # unbundle instead.
122 122
123 123 def unbundle(self, cg, heads, url):
124 124 """apply a bundle on a repo
125 125
126 126 This function handles the repo locking itself."""
127 127 try:
128 128 cg = exchange.readbundle(self.ui, cg, None)
129 129 ret = exchange.unbundle(self._repo, cg, heads, 'push', url)
130 130 if util.safehasattr(ret, 'getchunks'):
131 131 # This is a bundle20 object, turn it into an unbundler.
132 132 # This little dance should be dropped eventually when the API
133 133 # is finally improved.
134 134 stream = util.chunkbuffer(ret.getchunks())
135 135 ret = bundle2.unbundle20(self.ui, stream)
136 136 return ret
137 137 except error.PushRaced, exc:
138 138 raise error.ResponseError(_('push failed:'), str(exc))
139 139
140 140 def lock(self):
141 141 return self._repo.lock()
142 142
143 143 def addchangegroup(self, cg, source, url):
144 144 return changegroup.addchangegroup(self._repo, cg, source, url)
145 145
146 146 def pushkey(self, namespace, key, old, new):
147 147 return self._repo.pushkey(namespace, key, old, new)
148 148
149 149 def listkeys(self, namespace):
150 150 return self._repo.listkeys(namespace)
151 151
152 152 def debugwireargs(self, one, two, three=None, four=None, five=None):
153 153 '''used to test argument passing over the wire'''
154 154 return "%s %s %s %s %s" % (one, two, three, four, five)
155 155
156 156 class locallegacypeer(localpeer):
157 157 '''peer extension which implements legacy methods too; used for tests with
158 158 restricted capabilities'''
159 159
160 160 def __init__(self, repo):
161 161 localpeer.__init__(self, repo, caps=legacycaps)
162 162
163 163 def branches(self, nodes):
164 164 return self._repo.branches(nodes)
165 165
166 166 def between(self, pairs):
167 167 return self._repo.between(pairs)
168 168
169 169 def changegroup(self, basenodes, source):
170 170 return changegroup.changegroup(self._repo, basenodes, source)
171 171
172 172 def changegroupsubset(self, bases, heads, source):
173 173 return changegroup.changegroupsubset(self._repo, bases, heads, source)
174 174
175 175 class localrepository(object):
176 176
177 177 supportedformats = set(('revlogv1', 'generaldelta'))
178 178 _basesupported = supportedformats | set(('store', 'fncache', 'shared',
179 179 'dotencode'))
180 180 openerreqs = set(('revlogv1', 'generaldelta'))
181 181 requirements = ['revlogv1']
182 182 filtername = None
183 183
184 184 # a list of (ui, featureset) functions.
185 185 # only functions defined in module of enabled extensions are invoked
186 186 featuresetupfuncs = set()
187 187
188 188 def _baserequirements(self, create):
189 189 return self.requirements[:]
190 190
191 191 def __init__(self, baseui, path=None, create=False):
192 192 self.wvfs = scmutil.vfs(path, expandpath=True, realpath=True)
193 193 self.wopener = self.wvfs
194 194 self.root = self.wvfs.base
195 195 self.path = self.wvfs.join(".hg")
196 196 self.origroot = path
197 197 self.auditor = pathutil.pathauditor(self.root, self._checknested)
198 198 self.vfs = scmutil.vfs(self.path)
199 199 self.opener = self.vfs
200 200 self.baseui = baseui
201 201 self.ui = baseui.copy()
202 202 self.ui.copy = baseui.copy # prevent copying repo configuration
203 203 # A list of callback to shape the phase if no data were found.
204 204 # Callback are in the form: func(repo, roots) --> processed root.
205 205 # This list it to be filled by extension during repo setup
206 206 self._phasedefaults = []
207 207 try:
208 208 self.ui.readconfig(self.join("hgrc"), self.root)
209 209 extensions.loadall(self.ui)
210 210 except IOError:
211 211 pass
212 212
213 213 if self.featuresetupfuncs:
214 214 self.supported = set(self._basesupported) # use private copy
215 215 extmods = set(m.__name__ for n, m
216 216 in extensions.extensions(self.ui))
217 217 for setupfunc in self.featuresetupfuncs:
218 218 if setupfunc.__module__ in extmods:
219 219 setupfunc(self.ui, self.supported)
220 220 else:
221 221 self.supported = self._basesupported
222 222
223 223 if not self.vfs.isdir():
224 224 if create:
225 225 if not self.wvfs.exists():
226 226 self.wvfs.makedirs()
227 227 self.vfs.makedir(notindexed=True)
228 228 requirements = self._baserequirements(create)
229 229 if self.ui.configbool('format', 'usestore', True):
230 230 self.vfs.mkdir("store")
231 231 requirements.append("store")
232 232 if self.ui.configbool('format', 'usefncache', True):
233 233 requirements.append("fncache")
234 234 if self.ui.configbool('format', 'dotencode', True):
235 235 requirements.append('dotencode')
236 236 # create an invalid changelog
237 237 self.vfs.append(
238 238 "00changelog.i",
239 239 '\0\0\0\2' # represents revlogv2
240 240 ' dummy changelog to prevent using the old repo layout'
241 241 )
242 242 if self.ui.configbool('format', 'generaldelta', False):
243 243 requirements.append("generaldelta")
244 244 requirements = set(requirements)
245 245 else:
246 246 raise error.RepoError(_("repository %s not found") % path)
247 247 elif create:
248 248 raise error.RepoError(_("repository %s already exists") % path)
249 249 else:
250 250 try:
251 251 requirements = scmutil.readrequires(self.vfs, self.supported)
252 252 except IOError, inst:
253 253 if inst.errno != errno.ENOENT:
254 254 raise
255 255 requirements = set()
256 256
257 257 self.sharedpath = self.path
258 258 try:
259 259 vfs = scmutil.vfs(self.vfs.read("sharedpath").rstrip('\n'),
260 260 realpath=True)
261 261 s = vfs.base
262 262 if not vfs.exists():
263 263 raise error.RepoError(
264 264 _('.hg/sharedpath points to nonexistent directory %s') % s)
265 265 self.sharedpath = s
266 266 except IOError, inst:
267 267 if inst.errno != errno.ENOENT:
268 268 raise
269 269
270 270 self.store = store.store(requirements, self.sharedpath, scmutil.vfs)
271 271 self.spath = self.store.path
272 272 self.svfs = self.store.vfs
273 273 self.sopener = self.svfs
274 274 self.sjoin = self.store.join
275 275 self.vfs.createmode = self.store.createmode
276 276 self._applyrequirements(requirements)
277 277 if create:
278 278 self._writerequirements()
279 279
280 280
281 281 self._branchcaches = {}
282 282 self.filterpats = {}
283 283 self._datafilters = {}
284 284 self._transref = self._lockref = self._wlockref = None
285 285
286 286 # A cache for various files under .hg/ that tracks file changes,
287 287 # (used by the filecache decorator)
288 288 #
289 289 # Maps a property name to its util.filecacheentry
290 290 self._filecache = {}
291 291
292 292 # hold sets of revision to be filtered
293 293 # should be cleared when something might have changed the filter value:
294 294 # - new changesets,
295 295 # - phase change,
296 296 # - new obsolescence marker,
297 297 # - working directory parent change,
298 298 # - bookmark changes
299 299 self.filteredrevcache = {}
300 300
301 301 # generic mapping between names and nodes
302 302 self.names = namespaces.namespaces()
303 303
304 304 def close(self):
305 305 pass
306 306
307 307 def _restrictcapabilities(self, caps):
308 308 # bundle2 is not ready for prime time, drop it unless explicitly
309 309 # required by the tests (or some brave tester)
310 310 if self.ui.configbool('experimental', 'bundle2-exp', False):
311 311 caps = set(caps)
312 312 capsblob = bundle2.encodecaps(bundle2.getrepocaps(self))
313 313 caps.add('bundle2-exp=' + urllib.quote(capsblob))
314 314 return caps
315 315
316 316 def _applyrequirements(self, requirements):
317 317 self.requirements = requirements
318 318 self.svfs.options = dict((r, 1) for r in requirements
319 319 if r in self.openerreqs)
320 320 chunkcachesize = self.ui.configint('format', 'chunkcachesize')
321 321 if chunkcachesize is not None:
322 322 self.svfs.options['chunkcachesize'] = chunkcachesize
323 323 maxchainlen = self.ui.configint('format', 'maxchainlen')
324 324 if maxchainlen is not None:
325 325 self.svfs.options['maxchainlen'] = maxchainlen
326 326 manifestcachesize = self.ui.configint('format', 'manifestcachesize')
327 327 if manifestcachesize is not None:
328 328 self.svfs.options['manifestcachesize'] = manifestcachesize
329 329
330 330 def _writerequirements(self):
331 331 reqfile = self.vfs("requires", "w")
332 332 for r in sorted(self.requirements):
333 333 reqfile.write("%s\n" % r)
334 334 reqfile.close()
335 335
336 336 def _checknested(self, path):
337 337 """Determine if path is a legal nested repository."""
338 338 if not path.startswith(self.root):
339 339 return False
340 340 subpath = path[len(self.root) + 1:]
341 341 normsubpath = util.pconvert(subpath)
342 342
343 343 # XXX: Checking against the current working copy is wrong in
344 344 # the sense that it can reject things like
345 345 #
346 346 # $ hg cat -r 10 sub/x.txt
347 347 #
348 348 # if sub/ is no longer a subrepository in the working copy
349 349 # parent revision.
350 350 #
351 351 # However, it can of course also allow things that would have
352 352 # been rejected before, such as the above cat command if sub/
353 353 # is a subrepository now, but was a normal directory before.
354 354 # The old path auditor would have rejected by mistake since it
355 355 # panics when it sees sub/.hg/.
356 356 #
357 357 # All in all, checking against the working copy seems sensible
358 358 # since we want to prevent access to nested repositories on
359 359 # the filesystem *now*.
360 360 ctx = self[None]
361 361 parts = util.splitpath(subpath)
362 362 while parts:
363 363 prefix = '/'.join(parts)
364 364 if prefix in ctx.substate:
365 365 if prefix == normsubpath:
366 366 return True
367 367 else:
368 368 sub = ctx.sub(prefix)
369 369 return sub.checknested(subpath[len(prefix) + 1:])
370 370 else:
371 371 parts.pop()
372 372 return False
373 373
374 374 def peer(self):
375 375 return localpeer(self) # not cached to avoid reference cycle
376 376
377 377 def unfiltered(self):
378 378 """Return unfiltered version of the repository
379 379
380 380 Intended to be overwritten by filtered repo."""
381 381 return self
382 382
383 383 def filtered(self, name):
384 384 """Return a filtered version of a repository"""
385 385 # build a new class with the mixin and the current class
386 386 # (possibly subclass of the repo)
387 387 class proxycls(repoview.repoview, self.unfiltered().__class__):
388 388 pass
389 389 return proxycls(self, name)
390 390
391 391 @repofilecache('bookmarks')
392 392 def _bookmarks(self):
393 393 return bookmarks.bmstore(self)
394 394
395 395 @repofilecache('bookmarks.current')
396 396 def _bookmarkcurrent(self):
397 397 return bookmarks.readcurrent(self)
398 398
399 399 def bookmarkheads(self, bookmark):
400 400 name = bookmark.split('@', 1)[0]
401 401 heads = []
402 402 for mark, n in self._bookmarks.iteritems():
403 403 if mark.split('@', 1)[0] == name:
404 404 heads.append(n)
405 405 return heads
406 406
407 407 @storecache('phaseroots')
408 408 def _phasecache(self):
409 409 return phases.phasecache(self, self._phasedefaults)
410 410
411 411 @storecache('obsstore')
412 412 def obsstore(self):
413 413 # read default format for new obsstore.
414 414 defaultformat = self.ui.configint('format', 'obsstore-version', None)
415 415 # rely on obsstore class default when possible.
416 416 kwargs = {}
417 417 if defaultformat is not None:
418 418 kwargs['defaultformat'] = defaultformat
419 419 readonly = not obsolete.isenabled(self, obsolete.createmarkersopt)
420 420 store = obsolete.obsstore(self.svfs, readonly=readonly,
421 421 **kwargs)
422 422 if store and readonly:
423 423 # message is rare enough to not be translated
424 424 msg = 'obsolete feature not enabled but %i markers found!\n'
425 425 self.ui.warn(msg % len(list(store)))
426 426 return store
427 427
428 428 @storecache('00changelog.i')
429 429 def changelog(self):
430 430 c = changelog.changelog(self.svfs)
431 431 if 'HG_PENDING' in os.environ:
432 432 p = os.environ['HG_PENDING']
433 433 if p.startswith(self.root):
434 434 c.readpending('00changelog.i.a')
435 435 return c
436 436
437 437 @storecache('00manifest.i')
438 438 def manifest(self):
439 439 return manifest.manifest(self.svfs)
440 440
441 441 @repofilecache('dirstate')
442 442 def dirstate(self):
443 443 warned = [0]
444 444 def validate(node):
445 445 try:
446 446 self.changelog.rev(node)
447 447 return node
448 448 except error.LookupError:
449 449 if not warned[0]:
450 450 warned[0] = True
451 451 self.ui.warn(_("warning: ignoring unknown"
452 452 " working parent %s!\n") % short(node))
453 453 return nullid
454 454
455 455 return dirstate.dirstate(self.vfs, self.ui, self.root, validate)
456 456
457 457 def __getitem__(self, changeid):
458 458 if changeid is None:
459 459 return context.workingctx(self)
460 460 if isinstance(changeid, slice):
461 461 return [context.changectx(self, i)
462 462 for i in xrange(*changeid.indices(len(self)))
463 463 if i not in self.changelog.filteredrevs]
464 464 return context.changectx(self, changeid)
465 465
466 466 def __contains__(self, changeid):
467 467 try:
468 468 return bool(self.lookup(changeid))
469 469 except error.RepoLookupError:
470 470 return False
471 471
472 472 def __nonzero__(self):
473 473 return True
474 474
475 475 def __len__(self):
476 476 return len(self.changelog)
477 477
478 478 def __iter__(self):
479 479 return iter(self.changelog)
480 480
481 481 def revs(self, expr, *args):
482 482 '''Return a list of revisions matching the given revset'''
483 483 expr = revset.formatspec(expr, *args)
484 484 m = revset.match(None, expr)
485 485 return m(self)
486 486
487 487 def set(self, expr, *args):
488 488 '''
489 489 Yield a context for each matching revision, after doing arg
490 490 replacement via revset.formatspec
491 491 '''
492 492 for r in self.revs(expr, *args):
493 493 yield self[r]
494 494
495 495 def url(self):
496 496 return 'file:' + self.root
497 497
498 498 def hook(self, name, throw=False, **args):
499 499 """Call a hook, passing this repo instance.
500 500
501 501 This a convenience method to aid invoking hooks. Extensions likely
502 502 won't call this unless they have registered a custom hook or are
503 503 replacing code that is expected to call a hook.
504 504 """
505 505 return hook.hook(self.ui, self, name, throw, **args)
506 506
507 507 @unfilteredmethod
508 508 def _tag(self, names, node, message, local, user, date, extra={},
509 509 editor=False):
510 510 if isinstance(names, str):
511 511 names = (names,)
512 512
513 513 branches = self.branchmap()
514 514 for name in names:
515 515 self.hook('pretag', throw=True, node=hex(node), tag=name,
516 516 local=local)
517 517 if name in branches:
518 518 self.ui.warn(_("warning: tag %s conflicts with existing"
519 519 " branch name\n") % name)
520 520
521 521 def writetags(fp, names, munge, prevtags):
522 522 fp.seek(0, 2)
523 523 if prevtags and prevtags[-1] != '\n':
524 524 fp.write('\n')
525 525 for name in names:
526 526 m = munge and munge(name) or name
527 527 if (self._tagscache.tagtypes and
528 528 name in self._tagscache.tagtypes):
529 529 old = self.tags().get(name, nullid)
530 530 fp.write('%s %s\n' % (hex(old), m))
531 531 fp.write('%s %s\n' % (hex(node), m))
532 532 fp.close()
533 533
534 534 prevtags = ''
535 535 if local:
536 536 try:
537 537 fp = self.vfs('localtags', 'r+')
538 538 except IOError:
539 539 fp = self.vfs('localtags', 'a')
540 540 else:
541 541 prevtags = fp.read()
542 542
543 543 # local tags are stored in the current charset
544 544 writetags(fp, names, None, prevtags)
545 545 for name in names:
546 546 self.hook('tag', node=hex(node), tag=name, local=local)
547 547 return
548 548
549 549 try:
550 550 fp = self.wfile('.hgtags', 'rb+')
551 551 except IOError, e:
552 552 if e.errno != errno.ENOENT:
553 553 raise
554 554 fp = self.wfile('.hgtags', 'ab')
555 555 else:
556 556 prevtags = fp.read()
557 557
558 558 # committed tags are stored in UTF-8
559 559 writetags(fp, names, encoding.fromlocal, prevtags)
560 560
561 561 fp.close()
562 562
563 563 self.invalidatecaches()
564 564
565 565 if '.hgtags' not in self.dirstate:
566 566 self[None].add(['.hgtags'])
567 567
568 568 m = matchmod.exact(self.root, '', ['.hgtags'])
569 569 tagnode = self.commit(message, user, date, extra=extra, match=m,
570 570 editor=editor)
571 571
572 572 for name in names:
573 573 self.hook('tag', node=hex(node), tag=name, local=local)
574 574
575 575 return tagnode
576 576
577 577 def tag(self, names, node, message, local, user, date, editor=False):
578 578 '''tag a revision with one or more symbolic names.
579 579
580 580 names is a list of strings or, when adding a single tag, names may be a
581 581 string.
582 582
583 583 if local is True, the tags are stored in a per-repository file.
584 584 otherwise, they are stored in the .hgtags file, and a new
585 585 changeset is committed with the change.
586 586
587 587 keyword arguments:
588 588
589 589 local: whether to store tags in non-version-controlled file
590 590 (default False)
591 591
592 592 message: commit message to use if committing
593 593
594 594 user: name of user to use if committing
595 595
596 596 date: date tuple to use if committing'''
597 597
598 598 if not local:
599 599 m = matchmod.exact(self.root, '', ['.hgtags'])
600 600 if util.any(self.status(match=m, unknown=True, ignored=True)):
601 601 raise util.Abort(_('working copy of .hgtags is changed'),
602 602 hint=_('please commit .hgtags manually'))
603 603
604 604 self.tags() # instantiate the cache
605 605 self._tag(names, node, message, local, user, date, editor=editor)
606 606
607 607 @filteredpropertycache
608 608 def _tagscache(self):
609 609 '''Returns a tagscache object that contains various tags related
610 610 caches.'''
611 611
612 612 # This simplifies its cache management by having one decorated
613 613 # function (this one) and the rest simply fetch things from it.
614 614 class tagscache(object):
615 615 def __init__(self):
616 616 # These two define the set of tags for this repository. tags
617 617 # maps tag name to node; tagtypes maps tag name to 'global' or
618 618 # 'local'. (Global tags are defined by .hgtags across all
619 619 # heads, and local tags are defined in .hg/localtags.)
620 620 # They constitute the in-memory cache of tags.
621 621 self.tags = self.tagtypes = None
622 622
623 623 self.nodetagscache = self.tagslist = None
624 624
625 625 cache = tagscache()
626 626 cache.tags, cache.tagtypes = self._findtags()
627 627
628 628 return cache
629 629
630 630 def tags(self):
631 631 '''return a mapping of tag to node'''
632 632 t = {}
633 633 if self.changelog.filteredrevs:
634 634 tags, tt = self._findtags()
635 635 else:
636 636 tags = self._tagscache.tags
637 637 for k, v in tags.iteritems():
638 638 try:
639 639 # ignore tags to unknown nodes
640 640 self.changelog.rev(v)
641 641 t[k] = v
642 642 except (error.LookupError, ValueError):
643 643 pass
644 644 return t
645 645
646 646 def _findtags(self):
647 647 '''Do the hard work of finding tags. Return a pair of dicts
648 648 (tags, tagtypes) where tags maps tag name to node, and tagtypes
649 649 maps tag name to a string like \'global\' or \'local\'.
650 650 Subclasses or extensions are free to add their own tags, but
651 651 should be aware that the returned dicts will be retained for the
652 652 duration of the localrepo object.'''
653 653
654 654 # XXX what tagtype should subclasses/extensions use? Currently
655 655 # mq and bookmarks add tags, but do not set the tagtype at all.
656 656 # Should each extension invent its own tag type? Should there
657 657 # be one tagtype for all such "virtual" tags? Or is the status
658 658 # quo fine?
659 659
660 660 alltags = {} # map tag name to (node, hist)
661 661 tagtypes = {}
662 662
663 663 tagsmod.findglobaltags(self.ui, self, alltags, tagtypes)
664 664 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
665 665
666 666 # Build the return dicts. Have to re-encode tag names because
667 667 # the tags module always uses UTF-8 (in order not to lose info
668 668 # writing to the cache), but the rest of Mercurial wants them in
669 669 # local encoding.
670 670 tags = {}
671 671 for (name, (node, hist)) in alltags.iteritems():
672 672 if node != nullid:
673 673 tags[encoding.tolocal(name)] = node
674 674 tags['tip'] = self.changelog.tip()
675 675 tagtypes = dict([(encoding.tolocal(name), value)
676 676 for (name, value) in tagtypes.iteritems()])
677 677 return (tags, tagtypes)
678 678
679 679 def tagtype(self, tagname):
680 680 '''
681 681 return the type of the given tag. result can be:
682 682
683 683 'local' : a local tag
684 684 'global' : a global tag
685 685 None : tag does not exist
686 686 '''
687 687
688 688 return self._tagscache.tagtypes.get(tagname)
689 689
690 690 def tagslist(self):
691 691 '''return a list of tags ordered by revision'''
692 692 if not self._tagscache.tagslist:
693 693 l = []
694 694 for t, n in self.tags().iteritems():
695 695 l.append((self.changelog.rev(n), t, n))
696 696 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
697 697
698 698 return self._tagscache.tagslist
699 699
700 700 def nodetags(self, node):
701 701 '''return the tags associated with a node'''
702 702 if not self._tagscache.nodetagscache:
703 703 nodetagscache = {}
704 704 for t, n in self._tagscache.tags.iteritems():
705 705 nodetagscache.setdefault(n, []).append(t)
706 706 for tags in nodetagscache.itervalues():
707 707 tags.sort()
708 708 self._tagscache.nodetagscache = nodetagscache
709 709 return self._tagscache.nodetagscache.get(node, [])
710 710
711 711 def nodebookmarks(self, node):
712 712 marks = []
713 713 for bookmark, n in self._bookmarks.iteritems():
714 714 if n == node:
715 715 marks.append(bookmark)
716 716 return sorted(marks)
717 717
718 718 def branchmap(self):
719 719 '''returns a dictionary {branch: [branchheads]} with branchheads
720 720 ordered by increasing revision number'''
721 721 branchmap.updatecache(self)
722 722 return self._branchcaches[self.filtername]
723 723
724 724 def branchtip(self, branch, ignoremissing=False):
725 725 '''return the tip node for a given branch
726 726
727 727 If ignoremissing is True, then this method will not raise an error.
728 728 This is helpful for callers that only expect None for a missing branch
729 729 (e.g. namespace).
730 730
731 731 '''
732 732 try:
733 733 return self.branchmap().branchtip(branch)
734 734 except KeyError:
735 735 if not ignoremissing:
736 736 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
737 737 else:
738 738 pass
739 739
740 740 def lookup(self, key):
741 741 return self[key].node()
742 742
743 743 def lookupbranch(self, key, remote=None):
744 744 repo = remote or self
745 745 if key in repo.branchmap():
746 746 return key
747 747
748 748 repo = (remote and remote.local()) and remote or self
749 749 return repo[key].branch()
750 750
751 751 def known(self, nodes):
752 752 nm = self.changelog.nodemap
753 753 pc = self._phasecache
754 754 result = []
755 755 for n in nodes:
756 756 r = nm.get(n)
757 757 resp = not (r is None or pc.phase(self, r) >= phases.secret)
758 758 result.append(resp)
759 759 return result
760 760
761 761 def local(self):
762 762 return self
763 763
764 764 def cancopy(self):
765 765 # so statichttprepo's override of local() works
766 766 if not self.local():
767 767 return False
768 768 if not self.ui.configbool('phases', 'publish', True):
769 769 return True
770 770 # if publishing we can't copy if there is filtered content
771 771 return not self.filtered('visible').changelog.filteredrevs
772 772
773 773 def shared(self):
774 774 '''the type of shared repository (None if not shared)'''
775 775 if self.sharedpath != self.path:
776 776 return 'store'
777 777 return None
778 778
779 779 def join(self, f, *insidef):
780 780 return self.vfs.join(os.path.join(f, *insidef))
781 781
782 782 def wjoin(self, f, *insidef):
783 783 return self.vfs.reljoin(self.root, f, *insidef)
784 784
785 785 def file(self, f):
786 786 if f[0] == '/':
787 787 f = f[1:]
788 788 return filelog.filelog(self.svfs, f)
789 789
790 790 def changectx(self, changeid):
791 791 return self[changeid]
792 792
793 793 def parents(self, changeid=None):
794 794 '''get list of changectxs for parents of changeid'''
795 795 return self[changeid].parents()
796 796
797 797 def setparents(self, p1, p2=nullid):
798 798 self.dirstate.beginparentchange()
799 799 copies = self.dirstate.setparents(p1, p2)
800 800 pctx = self[p1]
801 801 if copies:
802 802 # Adjust copy records, the dirstate cannot do it, it
803 803 # requires access to parents manifests. Preserve them
804 804 # only for entries added to first parent.
805 805 for f in copies:
806 806 if f not in pctx and copies[f] in pctx:
807 807 self.dirstate.copy(copies[f], f)
808 808 if p2 == nullid:
809 809 for f, s in sorted(self.dirstate.copies().items()):
810 810 if f not in pctx and s not in pctx:
811 811 self.dirstate.copy(None, f)
812 812 self.dirstate.endparentchange()
813 813
814 814 def filectx(self, path, changeid=None, fileid=None):
815 815 """changeid can be a changeset revision, node, or tag.
816 816 fileid can be a file revision or node."""
817 817 return context.filectx(self, path, changeid, fileid)
818 818
819 819 def getcwd(self):
820 820 return self.dirstate.getcwd()
821 821
822 822 def pathto(self, f, cwd=None):
823 823 return self.dirstate.pathto(f, cwd)
824 824
825 825 def wfile(self, f, mode='r'):
826 826 return self.wvfs(f, mode)
827 827
828 828 def _link(self, f):
829 829 return self.wvfs.islink(f)
830 830
831 831 def _loadfilter(self, filter):
832 832 if filter not in self.filterpats:
833 833 l = []
834 834 for pat, cmd in self.ui.configitems(filter):
835 835 if cmd == '!':
836 836 continue
837 837 mf = matchmod.match(self.root, '', [pat])
838 838 fn = None
839 839 params = cmd
840 840 for name, filterfn in self._datafilters.iteritems():
841 841 if cmd.startswith(name):
842 842 fn = filterfn
843 843 params = cmd[len(name):].lstrip()
844 844 break
845 845 if not fn:
846 846 fn = lambda s, c, **kwargs: util.filter(s, c)
847 847 # Wrap old filters not supporting keyword arguments
848 848 if not inspect.getargspec(fn)[2]:
849 849 oldfn = fn
850 850 fn = lambda s, c, **kwargs: oldfn(s, c)
851 851 l.append((mf, fn, params))
852 852 self.filterpats[filter] = l
853 853 return self.filterpats[filter]
854 854
855 855 def _filter(self, filterpats, filename, data):
856 856 for mf, fn, cmd in filterpats:
857 857 if mf(filename):
858 858 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
859 859 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
860 860 break
861 861
862 862 return data
863 863
864 864 @unfilteredpropertycache
865 865 def _encodefilterpats(self):
866 866 return self._loadfilter('encode')
867 867
868 868 @unfilteredpropertycache
869 869 def _decodefilterpats(self):
870 870 return self._loadfilter('decode')
871 871
872 872 def adddatafilter(self, name, filter):
873 873 self._datafilters[name] = filter
874 874
875 875 def wread(self, filename):
876 876 if self._link(filename):
877 877 data = self.wvfs.readlink(filename)
878 878 else:
879 879 data = self.wvfs.read(filename)
880 880 return self._filter(self._encodefilterpats, filename, data)
881 881
882 882 def wwrite(self, filename, data, flags):
883 883 data = self._filter(self._decodefilterpats, filename, data)
884 884 if 'l' in flags:
885 885 self.wvfs.symlink(data, filename)
886 886 else:
887 887 self.wvfs.write(filename, data)
888 888 if 'x' in flags:
889 889 self.wvfs.setflags(filename, False, True)
890 890
891 891 def wwritedata(self, filename, data):
892 892 return self._filter(self._decodefilterpats, filename, data)
893 893
894 894 def currenttransaction(self):
895 895 """return the current transaction or None if non exists"""
896 896 tr = self._transref and self._transref() or None
897 897 if tr and tr.running():
898 898 return tr
899 899 return None
900 900
901 901 def transaction(self, desc, report=None):
902 902 tr = self.currenttransaction()
903 903 if tr is not None:
904 904 return tr.nest()
905 905
906 906 # abort here if the journal already exists
907 907 if self.svfs.exists("journal"):
908 908 raise error.RepoError(
909 909 _("abandoned transaction found"),
910 910 hint=_("run 'hg recover' to clean up transaction"))
911 911
912 912 self.hook('pretxnopen', throw=True, txnname=desc)
913 913
914 914 self._writejournal(desc)
915 915 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
916 916 rp = report and report or self.ui.warn
917 917 vfsmap = {'plain': self.vfs} # root of .hg/
918 918 tr = transaction.transaction(rp, self.svfs, vfsmap,
919 919 "journal",
920 920 "undo",
921 921 aftertrans(renames),
922 922 self.store.createmode)
923 923 # note: writing the fncache only during finalize mean that the file is
924 924 # outdated when running hooks. As fncache is used for streaming clone,
925 925 # this is not expected to break anything that happen during the hooks.
926 926 tr.addfinalize('flush-fncache', self.store.write)
927 # we must avoid cyclic reference between repo and transaction.
928 reporef = weakref.ref(self)
929 def txnclosehook(tr2):
930 """To be run if transaction is successful, will schedule a hook run
931 """
932 def hook():
933 reporef().hook('txnclose', throw=False, txnname=desc,
934 **tr2.hookargs)
935 reporef()._afterlock(hook)
936 tr.addfinalize('txnclose-hook', txnclosehook)
927 937 self._transref = weakref.ref(tr)
928 938 return tr
929 939
930 940 def _journalfiles(self):
931 941 return ((self.svfs, 'journal'),
932 942 (self.vfs, 'journal.dirstate'),
933 943 (self.vfs, 'journal.branch'),
934 944 (self.vfs, 'journal.desc'),
935 945 (self.vfs, 'journal.bookmarks'),
936 946 (self.svfs, 'journal.phaseroots'))
937 947
938 948 def undofiles(self):
939 949 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
940 950
941 951 def _writejournal(self, desc):
942 952 self.vfs.write("journal.dirstate",
943 953 self.vfs.tryread("dirstate"))
944 954 self.vfs.write("journal.branch",
945 955 encoding.fromlocal(self.dirstate.branch()))
946 956 self.vfs.write("journal.desc",
947 957 "%d\n%s\n" % (len(self), desc))
948 958 self.vfs.write("journal.bookmarks",
949 959 self.vfs.tryread("bookmarks"))
950 960 self.svfs.write("journal.phaseroots",
951 961 self.svfs.tryread("phaseroots"))
952 962
953 963 def recover(self):
954 964 lock = self.lock()
955 965 try:
956 966 if self.svfs.exists("journal"):
957 967 self.ui.status(_("rolling back interrupted transaction\n"))
958 968 vfsmap = {'': self.svfs,
959 969 'plain': self.vfs,}
960 970 transaction.rollback(self.svfs, vfsmap, "journal",
961 971 self.ui.warn)
962 972 self.invalidate()
963 973 return True
964 974 else:
965 975 self.ui.warn(_("no interrupted transaction available\n"))
966 976 return False
967 977 finally:
968 978 lock.release()
969 979
970 980 def rollback(self, dryrun=False, force=False):
971 981 wlock = lock = None
972 982 try:
973 983 wlock = self.wlock()
974 984 lock = self.lock()
975 985 if self.svfs.exists("undo"):
976 986 return self._rollback(dryrun, force)
977 987 else:
978 988 self.ui.warn(_("no rollback information available\n"))
979 989 return 1
980 990 finally:
981 991 release(lock, wlock)
982 992
983 993 @unfilteredmethod # Until we get smarter cache management
984 994 def _rollback(self, dryrun, force):
985 995 ui = self.ui
986 996 try:
987 997 args = self.vfs.read('undo.desc').splitlines()
988 998 (oldlen, desc, detail) = (int(args[0]), args[1], None)
989 999 if len(args) >= 3:
990 1000 detail = args[2]
991 1001 oldtip = oldlen - 1
992 1002
993 1003 if detail and ui.verbose:
994 1004 msg = (_('repository tip rolled back to revision %s'
995 1005 ' (undo %s: %s)\n')
996 1006 % (oldtip, desc, detail))
997 1007 else:
998 1008 msg = (_('repository tip rolled back to revision %s'
999 1009 ' (undo %s)\n')
1000 1010 % (oldtip, desc))
1001 1011 except IOError:
1002 1012 msg = _('rolling back unknown transaction\n')
1003 1013 desc = None
1004 1014
1005 1015 if not force and self['.'] != self['tip'] and desc == 'commit':
1006 1016 raise util.Abort(
1007 1017 _('rollback of last commit while not checked out '
1008 1018 'may lose data'), hint=_('use -f to force'))
1009 1019
1010 1020 ui.status(msg)
1011 1021 if dryrun:
1012 1022 return 0
1013 1023
1014 1024 parents = self.dirstate.parents()
1015 1025 self.destroying()
1016 1026 vfsmap = {'plain': self.vfs, '': self.svfs}
1017 1027 transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn)
1018 1028 if self.vfs.exists('undo.bookmarks'):
1019 1029 self.vfs.rename('undo.bookmarks', 'bookmarks')
1020 1030 if self.svfs.exists('undo.phaseroots'):
1021 1031 self.svfs.rename('undo.phaseroots', 'phaseroots')
1022 1032 self.invalidate()
1023 1033
1024 1034 parentgone = (parents[0] not in self.changelog.nodemap or
1025 1035 parents[1] not in self.changelog.nodemap)
1026 1036 if parentgone:
1027 1037 self.vfs.rename('undo.dirstate', 'dirstate')
1028 1038 try:
1029 1039 branch = self.vfs.read('undo.branch')
1030 1040 self.dirstate.setbranch(encoding.tolocal(branch))
1031 1041 except IOError:
1032 1042 ui.warn(_('named branch could not be reset: '
1033 1043 'current branch is still \'%s\'\n')
1034 1044 % self.dirstate.branch())
1035 1045
1036 1046 self.dirstate.invalidate()
1037 1047 parents = tuple([p.rev() for p in self.parents()])
1038 1048 if len(parents) > 1:
1039 1049 ui.status(_('working directory now based on '
1040 1050 'revisions %d and %d\n') % parents)
1041 1051 else:
1042 1052 ui.status(_('working directory now based on '
1043 1053 'revision %d\n') % parents)
1044 1054 # TODO: if we know which new heads may result from this rollback, pass
1045 1055 # them to destroy(), which will prevent the branchhead cache from being
1046 1056 # invalidated.
1047 1057 self.destroyed()
1048 1058 return 0
1049 1059
1050 1060 def invalidatecaches(self):
1051 1061
1052 1062 if '_tagscache' in vars(self):
1053 1063 # can't use delattr on proxy
1054 1064 del self.__dict__['_tagscache']
1055 1065
1056 1066 self.unfiltered()._branchcaches.clear()
1057 1067 self.invalidatevolatilesets()
1058 1068
1059 1069 def invalidatevolatilesets(self):
1060 1070 self.filteredrevcache.clear()
1061 1071 obsolete.clearobscaches(self)
1062 1072
1063 1073 def invalidatedirstate(self):
1064 1074 '''Invalidates the dirstate, causing the next call to dirstate
1065 1075 to check if it was modified since the last time it was read,
1066 1076 rereading it if it has.
1067 1077
1068 1078 This is different to dirstate.invalidate() that it doesn't always
1069 1079 rereads the dirstate. Use dirstate.invalidate() if you want to
1070 1080 explicitly read the dirstate again (i.e. restoring it to a previous
1071 1081 known good state).'''
1072 1082 if hasunfilteredcache(self, 'dirstate'):
1073 1083 for k in self.dirstate._filecache:
1074 1084 try:
1075 1085 delattr(self.dirstate, k)
1076 1086 except AttributeError:
1077 1087 pass
1078 1088 delattr(self.unfiltered(), 'dirstate')
1079 1089
1080 1090 def invalidate(self):
1081 1091 unfiltered = self.unfiltered() # all file caches are stored unfiltered
1082 1092 for k in self._filecache:
1083 1093 # dirstate is invalidated separately in invalidatedirstate()
1084 1094 if k == 'dirstate':
1085 1095 continue
1086 1096
1087 1097 try:
1088 1098 delattr(unfiltered, k)
1089 1099 except AttributeError:
1090 1100 pass
1091 1101 self.invalidatecaches()
1092 1102 self.store.invalidatecaches()
1093 1103
1094 1104 def invalidateall(self):
1095 1105 '''Fully invalidates both store and non-store parts, causing the
1096 1106 subsequent operation to reread any outside changes.'''
1097 1107 # extension should hook this to invalidate its caches
1098 1108 self.invalidate()
1099 1109 self.invalidatedirstate()
1100 1110
1101 1111 def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc):
1102 1112 try:
1103 1113 l = lockmod.lock(vfs, lockname, 0, releasefn, desc=desc)
1104 1114 except error.LockHeld, inst:
1105 1115 if not wait:
1106 1116 raise
1107 1117 self.ui.warn(_("waiting for lock on %s held by %r\n") %
1108 1118 (desc, inst.locker))
1109 1119 # default to 600 seconds timeout
1110 1120 l = lockmod.lock(vfs, lockname,
1111 1121 int(self.ui.config("ui", "timeout", "600")),
1112 1122 releasefn, desc=desc)
1113 1123 self.ui.warn(_("got lock after %s seconds\n") % l.delay)
1114 1124 if acquirefn:
1115 1125 acquirefn()
1116 1126 return l
1117 1127
1118 1128 def _afterlock(self, callback):
1119 1129 """add a callback to the current repository lock.
1120 1130
1121 1131 The callback will be executed on lock release."""
1122 1132 l = self._lockref and self._lockref()
1123 1133 if l:
1124 1134 l.postrelease.append(callback)
1125 1135 else:
1126 1136 callback()
1127 1137
1128 1138 def lock(self, wait=True):
1129 1139 '''Lock the repository store (.hg/store) and return a weak reference
1130 1140 to the lock. Use this before modifying the store (e.g. committing or
1131 1141 stripping). If you are opening a transaction, get a lock as well.)'''
1132 1142 l = self._lockref and self._lockref()
1133 1143 if l is not None and l.held:
1134 1144 l.lock()
1135 1145 return l
1136 1146
1137 1147 def unlock():
1138 1148 for k, ce in self._filecache.items():
1139 1149 if k == 'dirstate' or k not in self.__dict__:
1140 1150 continue
1141 1151 ce.refresh()
1142 1152
1143 1153 l = self._lock(self.svfs, "lock", wait, unlock,
1144 1154 self.invalidate, _('repository %s') % self.origroot)
1145 1155 self._lockref = weakref.ref(l)
1146 1156 return l
1147 1157
1148 1158 def wlock(self, wait=True):
1149 1159 '''Lock the non-store parts of the repository (everything under
1150 1160 .hg except .hg/store) and return a weak reference to the lock.
1151 1161 Use this before modifying files in .hg.'''
1152 1162 l = self._wlockref and self._wlockref()
1153 1163 if l is not None and l.held:
1154 1164 l.lock()
1155 1165 return l
1156 1166
1157 1167 def unlock():
1158 1168 if self.dirstate.pendingparentchange():
1159 1169 self.dirstate.invalidate()
1160 1170 else:
1161 1171 self.dirstate.write()
1162 1172
1163 1173 self._filecache['dirstate'].refresh()
1164 1174
1165 1175 l = self._lock(self.vfs, "wlock", wait, unlock,
1166 1176 self.invalidatedirstate, _('working directory of %s') %
1167 1177 self.origroot)
1168 1178 self._wlockref = weakref.ref(l)
1169 1179 return l
1170 1180
1171 1181 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
1172 1182 """
1173 1183 commit an individual file as part of a larger transaction
1174 1184 """
1175 1185
1176 1186 fname = fctx.path()
1177 1187 text = fctx.data()
1178 1188 flog = self.file(fname)
1179 1189 fparent1 = manifest1.get(fname, nullid)
1180 1190 fparent2 = manifest2.get(fname, nullid)
1181 1191
1182 1192 meta = {}
1183 1193 copy = fctx.renamed()
1184 1194 if copy and copy[0] != fname:
1185 1195 # Mark the new revision of this file as a copy of another
1186 1196 # file. This copy data will effectively act as a parent
1187 1197 # of this new revision. If this is a merge, the first
1188 1198 # parent will be the nullid (meaning "look up the copy data")
1189 1199 # and the second one will be the other parent. For example:
1190 1200 #
1191 1201 # 0 --- 1 --- 3 rev1 changes file foo
1192 1202 # \ / rev2 renames foo to bar and changes it
1193 1203 # \- 2 -/ rev3 should have bar with all changes and
1194 1204 # should record that bar descends from
1195 1205 # bar in rev2 and foo in rev1
1196 1206 #
1197 1207 # this allows this merge to succeed:
1198 1208 #
1199 1209 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
1200 1210 # \ / merging rev3 and rev4 should use bar@rev2
1201 1211 # \- 2 --- 4 as the merge base
1202 1212 #
1203 1213
1204 1214 cfname = copy[0]
1205 1215 crev = manifest1.get(cfname)
1206 1216 newfparent = fparent2
1207 1217
1208 1218 if manifest2: # branch merge
1209 1219 if fparent2 == nullid or crev is None: # copied on remote side
1210 1220 if cfname in manifest2:
1211 1221 crev = manifest2[cfname]
1212 1222 newfparent = fparent1
1213 1223
1214 1224 # Here, we used to search backwards through history to try to find
1215 1225 # where the file copy came from if the source of a copy was not in
1216 1226 # the parent directory. However, this doesn't actually make sense to
1217 1227 # do (what does a copy from something not in your working copy even
1218 1228 # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
1219 1229 # the user that copy information was dropped, so if they didn't
1220 1230 # expect this outcome it can be fixed, but this is the correct
1221 1231 # behavior in this circumstance.
1222 1232
1223 1233 if crev:
1224 1234 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
1225 1235 meta["copy"] = cfname
1226 1236 meta["copyrev"] = hex(crev)
1227 1237 fparent1, fparent2 = nullid, newfparent
1228 1238 else:
1229 1239 self.ui.warn(_("warning: can't find ancestor for '%s' "
1230 1240 "copied from '%s'!\n") % (fname, cfname))
1231 1241
1232 1242 elif fparent1 == nullid:
1233 1243 fparent1, fparent2 = fparent2, nullid
1234 1244 elif fparent2 != nullid:
1235 1245 # is one parent an ancestor of the other?
1236 1246 fparentancestors = flog.commonancestorsheads(fparent1, fparent2)
1237 1247 if fparent1 in fparentancestors:
1238 1248 fparent1, fparent2 = fparent2, nullid
1239 1249 elif fparent2 in fparentancestors:
1240 1250 fparent2 = nullid
1241 1251
1242 1252 # is the file changed?
1243 1253 if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
1244 1254 changelist.append(fname)
1245 1255 return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
1246 1256 # are just the flags changed during merge?
1247 1257 elif fname in manifest1 and manifest1.flags(fname) != fctx.flags():
1248 1258 changelist.append(fname)
1249 1259
1250 1260 return fparent1
1251 1261
1252 1262 @unfilteredmethod
1253 1263 def commit(self, text="", user=None, date=None, match=None, force=False,
1254 1264 editor=False, extra={}):
1255 1265 """Add a new revision to current repository.
1256 1266
1257 1267 Revision information is gathered from the working directory,
1258 1268 match can be used to filter the committed files. If editor is
1259 1269 supplied, it is called to get a commit message.
1260 1270 """
1261 1271
1262 1272 def fail(f, msg):
1263 1273 raise util.Abort('%s: %s' % (f, msg))
1264 1274
1265 1275 if not match:
1266 1276 match = matchmod.always(self.root, '')
1267 1277
1268 1278 if not force:
1269 1279 vdirs = []
1270 1280 match.explicitdir = vdirs.append
1271 1281 match.bad = fail
1272 1282
1273 1283 wlock = self.wlock()
1274 1284 try:
1275 1285 wctx = self[None]
1276 1286 merge = len(wctx.parents()) > 1
1277 1287
1278 1288 if (not force and merge and match and
1279 1289 (match.files() or match.anypats())):
1280 1290 raise util.Abort(_('cannot partially commit a merge '
1281 1291 '(do not specify files or patterns)'))
1282 1292
1283 1293 status = self.status(match=match, clean=force)
1284 1294 if force:
1285 1295 status.modified.extend(status.clean) # mq may commit clean files
1286 1296
1287 1297 # check subrepos
1288 1298 subs = []
1289 1299 commitsubs = set()
1290 1300 newstate = wctx.substate.copy()
1291 1301 # only manage subrepos and .hgsubstate if .hgsub is present
1292 1302 if '.hgsub' in wctx:
1293 1303 # we'll decide whether to track this ourselves, thanks
1294 1304 for c in status.modified, status.added, status.removed:
1295 1305 if '.hgsubstate' in c:
1296 1306 c.remove('.hgsubstate')
1297 1307
1298 1308 # compare current state to last committed state
1299 1309 # build new substate based on last committed state
1300 1310 oldstate = wctx.p1().substate
1301 1311 for s in sorted(newstate.keys()):
1302 1312 if not match(s):
1303 1313 # ignore working copy, use old state if present
1304 1314 if s in oldstate:
1305 1315 newstate[s] = oldstate[s]
1306 1316 continue
1307 1317 if not force:
1308 1318 raise util.Abort(
1309 1319 _("commit with new subrepo %s excluded") % s)
1310 1320 if wctx.sub(s).dirty(True):
1311 1321 if not self.ui.configbool('ui', 'commitsubrepos'):
1312 1322 raise util.Abort(
1313 1323 _("uncommitted changes in subrepo %s") % s,
1314 1324 hint=_("use --subrepos for recursive commit"))
1315 1325 subs.append(s)
1316 1326 commitsubs.add(s)
1317 1327 else:
1318 1328 bs = wctx.sub(s).basestate()
1319 1329 newstate[s] = (newstate[s][0], bs, newstate[s][2])
1320 1330 if oldstate.get(s, (None, None, None))[1] != bs:
1321 1331 subs.append(s)
1322 1332
1323 1333 # check for removed subrepos
1324 1334 for p in wctx.parents():
1325 1335 r = [s for s in p.substate if s not in newstate]
1326 1336 subs += [s for s in r if match(s)]
1327 1337 if subs:
1328 1338 if (not match('.hgsub') and
1329 1339 '.hgsub' in (wctx.modified() + wctx.added())):
1330 1340 raise util.Abort(
1331 1341 _("can't commit subrepos without .hgsub"))
1332 1342 status.modified.insert(0, '.hgsubstate')
1333 1343
1334 1344 elif '.hgsub' in status.removed:
1335 1345 # clean up .hgsubstate when .hgsub is removed
1336 1346 if ('.hgsubstate' in wctx and
1337 1347 '.hgsubstate' not in (status.modified + status.added +
1338 1348 status.removed)):
1339 1349 status.removed.insert(0, '.hgsubstate')
1340 1350
1341 1351 # make sure all explicit patterns are matched
1342 1352 if not force and match.files():
1343 1353 matched = set(status.modified + status.added + status.removed)
1344 1354
1345 1355 for f in match.files():
1346 1356 f = self.dirstate.normalize(f)
1347 1357 if f == '.' or f in matched or f in wctx.substate:
1348 1358 continue
1349 1359 if f in status.deleted:
1350 1360 fail(f, _('file not found!'))
1351 1361 if f in vdirs: # visited directory
1352 1362 d = f + '/'
1353 1363 for mf in matched:
1354 1364 if mf.startswith(d):
1355 1365 break
1356 1366 else:
1357 1367 fail(f, _("no match under directory!"))
1358 1368 elif f not in self.dirstate:
1359 1369 fail(f, _("file not tracked!"))
1360 1370
1361 1371 cctx = context.workingcommitctx(self, status,
1362 1372 text, user, date, extra)
1363 1373
1364 1374 if (not force and not extra.get("close") and not merge
1365 1375 and not cctx.files()
1366 1376 and wctx.branch() == wctx.p1().branch()):
1367 1377 return None
1368 1378
1369 1379 if merge and cctx.deleted():
1370 1380 raise util.Abort(_("cannot commit merge with missing files"))
1371 1381
1372 1382 ms = mergemod.mergestate(self)
1373 1383 for f in status.modified:
1374 1384 if f in ms and ms[f] == 'u':
1375 1385 raise util.Abort(_('unresolved merge conflicts '
1376 1386 '(see "hg help resolve")'))
1377 1387
1378 1388 if editor:
1379 1389 cctx._text = editor(self, cctx, subs)
1380 1390 edited = (text != cctx._text)
1381 1391
1382 1392 # Save commit message in case this transaction gets rolled back
1383 1393 # (e.g. by a pretxncommit hook). Leave the content alone on
1384 1394 # the assumption that the user will use the same editor again.
1385 1395 msgfn = self.savecommitmessage(cctx._text)
1386 1396
1387 1397 # commit subs and write new state
1388 1398 if subs:
1389 1399 for s in sorted(commitsubs):
1390 1400 sub = wctx.sub(s)
1391 1401 self.ui.status(_('committing subrepository %s\n') %
1392 1402 subrepo.subrelpath(sub))
1393 1403 sr = sub.commit(cctx._text, user, date)
1394 1404 newstate[s] = (newstate[s][0], sr)
1395 1405 subrepo.writestate(self, newstate)
1396 1406
1397 1407 p1, p2 = self.dirstate.parents()
1398 1408 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
1399 1409 try:
1400 1410 self.hook("precommit", throw=True, parent1=hookp1,
1401 1411 parent2=hookp2)
1402 1412 ret = self.commitctx(cctx, True)
1403 1413 except: # re-raises
1404 1414 if edited:
1405 1415 self.ui.write(
1406 1416 _('note: commit message saved in %s\n') % msgfn)
1407 1417 raise
1408 1418
1409 1419 # update bookmarks, dirstate and mergestate
1410 1420 bookmarks.update(self, [p1, p2], ret)
1411 1421 cctx.markcommitted(ret)
1412 1422 ms.reset()
1413 1423 finally:
1414 1424 wlock.release()
1415 1425
1416 1426 def commithook(node=hex(ret), parent1=hookp1, parent2=hookp2):
1417 1427 # hack for command that use a temporary commit (eg: histedit)
1418 1428 # temporary commit got stripped before hook release
1419 1429 if node in self:
1420 1430 self.hook("commit", node=node, parent1=parent1,
1421 1431 parent2=parent2)
1422 1432 self._afterlock(commithook)
1423 1433 return ret
1424 1434
1425 1435 @unfilteredmethod
1426 1436 def commitctx(self, ctx, error=False):
1427 1437 """Add a new revision to current repository.
1428 1438 Revision information is passed via the context argument.
1429 1439 """
1430 1440
1431 1441 tr = None
1432 1442 p1, p2 = ctx.p1(), ctx.p2()
1433 1443 user = ctx.user()
1434 1444
1435 1445 lock = self.lock()
1436 1446 try:
1437 1447 tr = self.transaction("commit")
1438 1448 trp = weakref.proxy(tr)
1439 1449
1440 1450 if ctx.files():
1441 1451 m1 = p1.manifest()
1442 1452 m2 = p2.manifest()
1443 1453 m = m1.copy()
1444 1454
1445 1455 # check in files
1446 1456 added = []
1447 1457 changed = []
1448 1458 removed = list(ctx.removed())
1449 1459 linkrev = len(self)
1450 1460 self.ui.note(_("committing files:\n"))
1451 1461 for f in sorted(ctx.modified() + ctx.added()):
1452 1462 self.ui.note(f + "\n")
1453 1463 try:
1454 1464 fctx = ctx[f]
1455 1465 if fctx is None:
1456 1466 removed.append(f)
1457 1467 else:
1458 1468 added.append(f)
1459 1469 m[f] = self._filecommit(fctx, m1, m2, linkrev,
1460 1470 trp, changed)
1461 1471 m.setflag(f, fctx.flags())
1462 1472 except OSError, inst:
1463 1473 self.ui.warn(_("trouble committing %s!\n") % f)
1464 1474 raise
1465 1475 except IOError, inst:
1466 1476 errcode = getattr(inst, 'errno', errno.ENOENT)
1467 1477 if error or errcode and errcode != errno.ENOENT:
1468 1478 self.ui.warn(_("trouble committing %s!\n") % f)
1469 1479 raise
1470 1480
1471 1481 # update manifest
1472 1482 self.ui.note(_("committing manifest\n"))
1473 1483 removed = [f for f in sorted(removed) if f in m1 or f in m2]
1474 1484 drop = [f for f in removed if f in m]
1475 1485 for f in drop:
1476 1486 del m[f]
1477 1487 mn = self.manifest.add(m, trp, linkrev,
1478 1488 p1.manifestnode(), p2.manifestnode(),
1479 1489 added, drop)
1480 1490 files = changed + removed
1481 1491 else:
1482 1492 mn = p1.manifestnode()
1483 1493 files = []
1484 1494
1485 1495 # update changelog
1486 1496 self.ui.note(_("committing changelog\n"))
1487 1497 self.changelog.delayupdate(tr)
1488 1498 n = self.changelog.add(mn, files, ctx.description(),
1489 1499 trp, p1.node(), p2.node(),
1490 1500 user, ctx.date(), ctx.extra().copy())
1491 1501 p = lambda: tr.writepending() and self.root or ""
1492 1502 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
1493 1503 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
1494 1504 parent2=xp2, pending=p)
1495 1505 # set the new commit is proper phase
1496 1506 targetphase = subrepo.newcommitphase(self.ui, ctx)
1497 1507 if targetphase:
1498 1508 # retract boundary do not alter parent changeset.
1499 1509 # if a parent have higher the resulting phase will
1500 1510 # be compliant anyway
1501 1511 #
1502 1512 # if minimal phase was 0 we don't need to retract anything
1503 1513 phases.retractboundary(self, tr, targetphase, [n])
1504 1514 tr.close()
1505 1515 branchmap.updatecache(self.filtered('served'))
1506 1516 return n
1507 1517 finally:
1508 1518 if tr:
1509 1519 tr.release()
1510 1520 lock.release()
1511 1521
1512 1522 @unfilteredmethod
1513 1523 def destroying(self):
1514 1524 '''Inform the repository that nodes are about to be destroyed.
1515 1525 Intended for use by strip and rollback, so there's a common
1516 1526 place for anything that has to be done before destroying history.
1517 1527
1518 1528 This is mostly useful for saving state that is in memory and waiting
1519 1529 to be flushed when the current lock is released. Because a call to
1520 1530 destroyed is imminent, the repo will be invalidated causing those
1521 1531 changes to stay in memory (waiting for the next unlock), or vanish
1522 1532 completely.
1523 1533 '''
1524 1534 # When using the same lock to commit and strip, the phasecache is left
1525 1535 # dirty after committing. Then when we strip, the repo is invalidated,
1526 1536 # causing those changes to disappear.
1527 1537 if '_phasecache' in vars(self):
1528 1538 self._phasecache.write()
1529 1539
1530 1540 @unfilteredmethod
1531 1541 def destroyed(self):
1532 1542 '''Inform the repository that nodes have been destroyed.
1533 1543 Intended for use by strip and rollback, so there's a common
1534 1544 place for anything that has to be done after destroying history.
1535 1545 '''
1536 1546 # When one tries to:
1537 1547 # 1) destroy nodes thus calling this method (e.g. strip)
1538 1548 # 2) use phasecache somewhere (e.g. commit)
1539 1549 #
1540 1550 # then 2) will fail because the phasecache contains nodes that were
1541 1551 # removed. We can either remove phasecache from the filecache,
1542 1552 # causing it to reload next time it is accessed, or simply filter
1543 1553 # the removed nodes now and write the updated cache.
1544 1554 self._phasecache.filterunknown(self)
1545 1555 self._phasecache.write()
1546 1556
1547 1557 # update the 'served' branch cache to help read only server process
1548 1558 # Thanks to branchcache collaboration this is done from the nearest
1549 1559 # filtered subset and it is expected to be fast.
1550 1560 branchmap.updatecache(self.filtered('served'))
1551 1561
1552 1562 # Ensure the persistent tag cache is updated. Doing it now
1553 1563 # means that the tag cache only has to worry about destroyed
1554 1564 # heads immediately after a strip/rollback. That in turn
1555 1565 # guarantees that "cachetip == currenttip" (comparing both rev
1556 1566 # and node) always means no nodes have been added or destroyed.
1557 1567
1558 1568 # XXX this is suboptimal when qrefresh'ing: we strip the current
1559 1569 # head, refresh the tag cache, then immediately add a new head.
1560 1570 # But I think doing it this way is necessary for the "instant
1561 1571 # tag cache retrieval" case to work.
1562 1572 self.invalidate()
1563 1573
1564 1574 def walk(self, match, node=None):
1565 1575 '''
1566 1576 walk recursively through the directory tree or a given
1567 1577 changeset, finding all files matched by the match
1568 1578 function
1569 1579 '''
1570 1580 return self[node].walk(match)
1571 1581
1572 1582 def status(self, node1='.', node2=None, match=None,
1573 1583 ignored=False, clean=False, unknown=False,
1574 1584 listsubrepos=False):
1575 1585 '''a convenience method that calls node1.status(node2)'''
1576 1586 return self[node1].status(node2, match, ignored, clean, unknown,
1577 1587 listsubrepos)
1578 1588
1579 1589 def heads(self, start=None):
1580 1590 heads = self.changelog.heads(start)
1581 1591 # sort the output in rev descending order
1582 1592 return sorted(heads, key=self.changelog.rev, reverse=True)
1583 1593
1584 1594 def branchheads(self, branch=None, start=None, closed=False):
1585 1595 '''return a (possibly filtered) list of heads for the given branch
1586 1596
1587 1597 Heads are returned in topological order, from newest to oldest.
1588 1598 If branch is None, use the dirstate branch.
1589 1599 If start is not None, return only heads reachable from start.
1590 1600 If closed is True, return heads that are marked as closed as well.
1591 1601 '''
1592 1602 if branch is None:
1593 1603 branch = self[None].branch()
1594 1604 branches = self.branchmap()
1595 1605 if branch not in branches:
1596 1606 return []
1597 1607 # the cache returns heads ordered lowest to highest
1598 1608 bheads = list(reversed(branches.branchheads(branch, closed=closed)))
1599 1609 if start is not None:
1600 1610 # filter out the heads that cannot be reached from startrev
1601 1611 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
1602 1612 bheads = [h for h in bheads if h in fbheads]
1603 1613 return bheads
1604 1614
1605 1615 def branches(self, nodes):
1606 1616 if not nodes:
1607 1617 nodes = [self.changelog.tip()]
1608 1618 b = []
1609 1619 for n in nodes:
1610 1620 t = n
1611 1621 while True:
1612 1622 p = self.changelog.parents(n)
1613 1623 if p[1] != nullid or p[0] == nullid:
1614 1624 b.append((t, n, p[0], p[1]))
1615 1625 break
1616 1626 n = p[0]
1617 1627 return b
1618 1628
1619 1629 def between(self, pairs):
1620 1630 r = []
1621 1631
1622 1632 for top, bottom in pairs:
1623 1633 n, l, i = top, [], 0
1624 1634 f = 1
1625 1635
1626 1636 while n != bottom and n != nullid:
1627 1637 p = self.changelog.parents(n)[0]
1628 1638 if i == f:
1629 1639 l.append(n)
1630 1640 f = f * 2
1631 1641 n = p
1632 1642 i += 1
1633 1643
1634 1644 r.append(l)
1635 1645
1636 1646 return r
1637 1647
1638 1648 def checkpush(self, pushop):
1639 1649 """Extensions can override this function if additional checks have
1640 1650 to be performed before pushing, or call it if they override push
1641 1651 command.
1642 1652 """
1643 1653 pass
1644 1654
1645 1655 @unfilteredpropertycache
1646 1656 def prepushoutgoinghooks(self):
1647 1657 """Return util.hooks consists of "(repo, remote, outgoing)"
1648 1658 functions, which are called before pushing changesets.
1649 1659 """
1650 1660 return util.hooks()
1651 1661
1652 1662 def stream_in(self, remote, requirements):
1653 1663 lock = self.lock()
1654 1664 try:
1655 1665 # Save remote branchmap. We will use it later
1656 1666 # to speed up branchcache creation
1657 1667 rbranchmap = None
1658 1668 if remote.capable("branchmap"):
1659 1669 rbranchmap = remote.branchmap()
1660 1670
1661 1671 fp = remote.stream_out()
1662 1672 l = fp.readline()
1663 1673 try:
1664 1674 resp = int(l)
1665 1675 except ValueError:
1666 1676 raise error.ResponseError(
1667 1677 _('unexpected response from remote server:'), l)
1668 1678 if resp == 1:
1669 1679 raise util.Abort(_('operation forbidden by server'))
1670 1680 elif resp == 2:
1671 1681 raise util.Abort(_('locking the remote repository failed'))
1672 1682 elif resp != 0:
1673 1683 raise util.Abort(_('the server sent an unknown error code'))
1674 1684 self.ui.status(_('streaming all changes\n'))
1675 1685 l = fp.readline()
1676 1686 try:
1677 1687 total_files, total_bytes = map(int, l.split(' ', 1))
1678 1688 except (ValueError, TypeError):
1679 1689 raise error.ResponseError(
1680 1690 _('unexpected response from remote server:'), l)
1681 1691 self.ui.status(_('%d files to transfer, %s of data\n') %
1682 1692 (total_files, util.bytecount(total_bytes)))
1683 1693 handled_bytes = 0
1684 1694 self.ui.progress(_('clone'), 0, total=total_bytes)
1685 1695 start = time.time()
1686 1696
1687 1697 tr = self.transaction(_('clone'))
1688 1698 try:
1689 1699 for i in xrange(total_files):
1690 1700 # XXX doesn't support '\n' or '\r' in filenames
1691 1701 l = fp.readline()
1692 1702 try:
1693 1703 name, size = l.split('\0', 1)
1694 1704 size = int(size)
1695 1705 except (ValueError, TypeError):
1696 1706 raise error.ResponseError(
1697 1707 _('unexpected response from remote server:'), l)
1698 1708 if self.ui.debugflag:
1699 1709 self.ui.debug('adding %s (%s)\n' %
1700 1710 (name, util.bytecount(size)))
1701 1711 # for backwards compat, name was partially encoded
1702 1712 ofp = self.svfs(store.decodedir(name), 'w')
1703 1713 for chunk in util.filechunkiter(fp, limit=size):
1704 1714 handled_bytes += len(chunk)
1705 1715 self.ui.progress(_('clone'), handled_bytes,
1706 1716 total=total_bytes)
1707 1717 ofp.write(chunk)
1708 1718 ofp.close()
1709 1719 tr.close()
1710 1720 finally:
1711 1721 tr.release()
1712 1722
1713 1723 # Writing straight to files circumvented the inmemory caches
1714 1724 self.invalidate()
1715 1725
1716 1726 elapsed = time.time() - start
1717 1727 if elapsed <= 0:
1718 1728 elapsed = 0.001
1719 1729 self.ui.progress(_('clone'), None)
1720 1730 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %
1721 1731 (util.bytecount(total_bytes), elapsed,
1722 1732 util.bytecount(total_bytes / elapsed)))
1723 1733
1724 1734 # new requirements = old non-format requirements +
1725 1735 # new format-related
1726 1736 # requirements from the streamed-in repository
1727 1737 requirements.update(set(self.requirements) - self.supportedformats)
1728 1738 self._applyrequirements(requirements)
1729 1739 self._writerequirements()
1730 1740
1731 1741 if rbranchmap:
1732 1742 rbheads = []
1733 1743 closed = []
1734 1744 for bheads in rbranchmap.itervalues():
1735 1745 rbheads.extend(bheads)
1736 1746 for h in bheads:
1737 1747 r = self.changelog.rev(h)
1738 1748 b, c = self.changelog.branchinfo(r)
1739 1749 if c:
1740 1750 closed.append(h)
1741 1751
1742 1752 if rbheads:
1743 1753 rtiprev = max((int(self.changelog.rev(node))
1744 1754 for node in rbheads))
1745 1755 cache = branchmap.branchcache(rbranchmap,
1746 1756 self[rtiprev].node(),
1747 1757 rtiprev,
1748 1758 closednodes=closed)
1749 1759 # Try to stick it as low as possible
1750 1760 # filter above served are unlikely to be fetch from a clone
1751 1761 for candidate in ('base', 'immutable', 'served'):
1752 1762 rview = self.filtered(candidate)
1753 1763 if cache.validfor(rview):
1754 1764 self._branchcaches[candidate] = cache
1755 1765 cache.write(rview)
1756 1766 break
1757 1767 self.invalidate()
1758 1768 return len(self.heads()) + 1
1759 1769 finally:
1760 1770 lock.release()
1761 1771
1762 1772 def clone(self, remote, heads=[], stream=None):
1763 1773 '''clone remote repository.
1764 1774
1765 1775 keyword arguments:
1766 1776 heads: list of revs to clone (forces use of pull)
1767 1777 stream: use streaming clone if possible'''
1768 1778
1769 1779 # now, all clients that can request uncompressed clones can
1770 1780 # read repo formats supported by all servers that can serve
1771 1781 # them.
1772 1782
1773 1783 # if revlog format changes, client will have to check version
1774 1784 # and format flags on "stream" capability, and use
1775 1785 # uncompressed only if compatible.
1776 1786
1777 1787 if stream is None:
1778 1788 # if the server explicitly prefers to stream (for fast LANs)
1779 1789 stream = remote.capable('stream-preferred')
1780 1790
1781 1791 if stream and not heads:
1782 1792 # 'stream' means remote revlog format is revlogv1 only
1783 1793 if remote.capable('stream'):
1784 1794 self.stream_in(remote, set(('revlogv1',)))
1785 1795 else:
1786 1796 # otherwise, 'streamreqs' contains the remote revlog format
1787 1797 streamreqs = remote.capable('streamreqs')
1788 1798 if streamreqs:
1789 1799 streamreqs = set(streamreqs.split(','))
1790 1800 # if we support it, stream in and adjust our requirements
1791 1801 if not streamreqs - self.supportedformats:
1792 1802 self.stream_in(remote, streamreqs)
1793 1803
1794 1804 quiet = self.ui.backupconfig('ui', 'quietbookmarkmove')
1795 1805 try:
1796 1806 self.ui.setconfig('ui', 'quietbookmarkmove', True, 'clone')
1797 1807 ret = exchange.pull(self, remote, heads).cgresult
1798 1808 finally:
1799 1809 self.ui.restoreconfig(quiet)
1800 1810 return ret
1801 1811
1802 1812 def pushkey(self, namespace, key, old, new):
1803 1813 try:
1804 1814 self.hook('prepushkey', throw=True, namespace=namespace, key=key,
1805 1815 old=old, new=new)
1806 1816 except error.HookAbort, exc:
1807 1817 self.ui.write_err(_("pushkey-abort: %s\n") % exc)
1808 1818 if exc.hint:
1809 1819 self.ui.write_err(_("(%s)\n") % exc.hint)
1810 1820 return False
1811 1821 self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
1812 1822 ret = pushkey.push(self, namespace, key, old, new)
1813 1823 def runhook():
1814 1824 self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
1815 1825 ret=ret)
1816 1826 self._afterlock(runhook)
1817 1827 return ret
1818 1828
1819 1829 def listkeys(self, namespace):
1820 1830 self.hook('prelistkeys', throw=True, namespace=namespace)
1821 1831 self.ui.debug('listing keys for "%s"\n' % namespace)
1822 1832 values = pushkey.list(self, namespace)
1823 1833 self.hook('listkeys', namespace=namespace, values=values)
1824 1834 return values
1825 1835
1826 1836 def debugwireargs(self, one, two, three=None, four=None, five=None):
1827 1837 '''used to test argument passing over the wire'''
1828 1838 return "%s %s %s %s %s" % (one, two, three, four, five)
1829 1839
1830 1840 def savecommitmessage(self, text):
1831 1841 fp = self.vfs('last-message.txt', 'wb')
1832 1842 try:
1833 1843 fp.write(text)
1834 1844 finally:
1835 1845 fp.close()
1836 1846 return self.pathto(fp.name[len(self.root) + 1:])
1837 1847
1838 1848 # used to avoid circular references so destructors work
1839 1849 def aftertrans(files):
1840 1850 renamefiles = [tuple(t) for t in files]
1841 1851 def a():
1842 1852 for vfs, src, dest in renamefiles:
1843 1853 try:
1844 1854 vfs.rename(src, dest)
1845 1855 except OSError: # journal file does not yet exist
1846 1856 pass
1847 1857 return a
1848 1858
1849 1859 def undoname(fn):
1850 1860 base, name = os.path.split(fn)
1851 1861 assert name.startswith('journal')
1852 1862 return os.path.join(base, name.replace('journal', 'undo', 1))
1853 1863
1854 1864 def instance(ui, path, create):
1855 1865 return localrepository(ui, util.urllocalpath(path), create)
1856 1866
1857 1867 def islocal(path):
1858 1868 return True
@@ -1,670 +1,677
1 1 commit hooks can see env vars
2 2
3 3 $ hg init a
4 4 $ cd a
5 5 $ cat > .hg/hgrc <<EOF
6 6 > [hooks]
7 7 > commit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit"
8 8 > commit.b = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit.b"
9 9 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= python \"$TESTDIR/printenv.py\" precommit"
10 10 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" pretxncommit"
11 11 > pretxncommit.tip = hg -q tip
12 12 > pre-identify = python "$TESTDIR/printenv.py" pre-identify 1
13 13 > pre-cat = python "$TESTDIR/printenv.py" pre-cat
14 14 > post-cat = python "$TESTDIR/printenv.py" post-cat
15 15 > pretxnopen = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" pretxnopen"
16 > txnclose = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" txnclose"
16 17 > EOF
17 18 $ echo a > a
18 19 $ hg add a
19 20 $ hg commit -m a
20 21 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000
21 22 pretxnopen hook: HG_TXNNAME=commit
22 23 pretxncommit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a
23 24 0:cb9a9f314b8b
25 txnclose hook: HG_PHASES_MOVED=1 HG_TXNNAME=commit
24 26 commit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
25 27 commit.b hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
26 28
27 29 $ hg clone . ../b
28 30 updating to branch default
29 31 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 32 $ cd ../b
31 33
32 34 changegroup hooks can see env vars
33 35
34 36 $ cat > .hg/hgrc <<EOF
35 37 > [hooks]
36 38 > prechangegroup = python "$TESTDIR/printenv.py" prechangegroup
37 39 > changegroup = python "$TESTDIR/printenv.py" changegroup
38 40 > incoming = python "$TESTDIR/printenv.py" incoming
39 41 > EOF
40 42
41 43 pretxncommit and commit hooks can see both parents of merge
42 44
43 45 $ cd ../a
44 46 $ echo b >> a
45 47 $ hg commit -m a1 -d "1 0"
46 48 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
47 49 pretxnopen hook: HG_TXNNAME=commit
48 50 pretxncommit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
49 51 1:ab228980c14d
52 txnclose hook: HG_TXNNAME=commit
50 53 commit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
51 54 commit.b hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
52 55 $ hg update -C 0
53 56 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
54 57 $ echo b > b
55 58 $ hg add b
56 59 $ hg commit -m b -d '1 0'
57 60 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
58 61 pretxnopen hook: HG_TXNNAME=commit
59 62 pretxncommit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
60 63 2:ee9deb46ab31
64 txnclose hook: HG_TXNNAME=commit
61 65 commit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
62 66 commit.b hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
63 67 created new head
64 68 $ hg merge 1
65 69 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 70 (branch merge, don't forget to commit)
67 71 $ hg commit -m merge -d '2 0'
68 72 precommit hook: HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
69 73 pretxnopen hook: HG_TXNNAME=commit
70 74 pretxncommit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a
71 75 3:07f3376c1e65
76 txnclose hook: HG_TXNNAME=commit
72 77 commit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
73 78 commit.b hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
74 79
75 80 test generic hooks
76 81
77 82 $ hg id
78 83 pre-identify hook: HG_ARGS=id HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None} HG_PATS=[]
79 84 abort: pre-identify hook exited with status 1
80 85 [255]
81 86 $ hg cat b
82 87 pre-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b']
83 88 b
84 89 post-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b'] HG_RESULT=0
85 90
86 91 $ cd ../b
87 92 $ hg pull ../a
88 93 pulling from ../a
89 94 searching for changes
90 95 prechangegroup hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
91 96 adding changesets
92 97 adding manifests
93 98 adding file changes
94 99 added 3 changesets with 2 changes to 2 files
95 100 changegroup hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
96 101 incoming hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
97 102 incoming hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
98 103 incoming hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
99 104 (run 'hg update' to get a working copy)
100 105
101 106 tag hooks can see env vars
102 107
103 108 $ cd ../a
104 109 $ cat >> .hg/hgrc <<EOF
105 110 > pretag = python "$TESTDIR/printenv.py" pretag
106 111 > tag = sh -c "HG_PARENT1= HG_PARENT2= python \"$TESTDIR/printenv.py\" tag"
107 112 > EOF
108 113 $ hg tag -d '3 0' a
109 114 pretag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
110 115 precommit hook: HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
111 116 pretxnopen hook: HG_TXNNAME=commit
112 117 pretxncommit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
113 118 4:539e4b31b6dc
114 119 tag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
120 txnclose hook: HG_TXNNAME=commit
115 121 commit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
116 122 commit.b hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
117 123 $ hg tag -l la
118 124 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
119 125 tag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
120 126
121 127 pretag hook can forbid tagging
122 128
123 129 $ echo "pretag.forbid = python \"$TESTDIR/printenv.py\" pretag.forbid 1" >> .hg/hgrc
124 130 $ hg tag -d '4 0' fa
125 131 pretag hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
126 132 pretag.forbid hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
127 133 abort: pretag.forbid hook exited with status 1
128 134 [255]
129 135 $ hg tag -l fla
130 136 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
131 137 pretag.forbid hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
132 138 abort: pretag.forbid hook exited with status 1
133 139 [255]
134 140
135 141 pretxncommit hook can see changeset, can roll back txn, changeset no
136 142 more there after
137 143
138 144 $ echo "pretxncommit.forbid0 = hg tip -q" >> .hg/hgrc
139 145 $ echo "pretxncommit.forbid1 = python \"$TESTDIR/printenv.py\" pretxncommit.forbid 1" >> .hg/hgrc
140 146 $ echo z > z
141 147 $ hg add z
142 148 $ hg -q tip
143 149 4:539e4b31b6dc
144 150 $ hg commit -m 'fail' -d '4 0'
145 151 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
146 152 pretxnopen hook: HG_TXNNAME=commit
147 153 pretxncommit hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
148 154 5:6f611f8018c1
149 155 5:6f611f8018c1
150 156 pretxncommit.forbid hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
151 157 transaction abort!
152 158 rollback completed
153 159 abort: pretxncommit.forbid1 hook exited with status 1
154 160 [255]
155 161 $ hg -q tip
156 162 4:539e4b31b6dc
157 163
158 164 (Check that no 'changelog.i.a' file were left behind)
159 165
160 166 $ ls -1 .hg/store/
161 167 00changelog.i
162 168 00manifest.i
163 169 data
164 170 fncache
165 171 journal.phaseroots
166 172 phaseroots
167 173 undo
168 174 undo.backup.fncache
169 175 undo.backupfiles
170 176 undo.phaseroots
171 177
172 178
173 179 precommit hook can prevent commit
174 180
175 181 $ echo "precommit.forbid = python \"$TESTDIR/printenv.py\" precommit.forbid 1" >> .hg/hgrc
176 182 $ hg commit -m 'fail' -d '4 0'
177 183 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
178 184 precommit.forbid hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
179 185 abort: precommit.forbid hook exited with status 1
180 186 [255]
181 187 $ hg -q tip
182 188 4:539e4b31b6dc
183 189
184 190 preupdate hook can prevent update
185 191
186 192 $ echo "preupdate = python \"$TESTDIR/printenv.py\" preupdate" >> .hg/hgrc
187 193 $ hg update 1
188 194 preupdate hook: HG_PARENT1=ab228980c14d
189 195 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
190 196
191 197 update hook
192 198
193 199 $ echo "update = python \"$TESTDIR/printenv.py\" update" >> .hg/hgrc
194 200 $ hg update
195 201 preupdate hook: HG_PARENT1=539e4b31b6dc
196 202 update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
197 203 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
198 204
199 205 pushkey hook
200 206
201 207 $ echo "pushkey = python \"$TESTDIR/printenv.py\" pushkey" >> .hg/hgrc
202 208 $ cd ../b
203 209 $ hg bookmark -r null foo
204 210 $ hg push -B foo ../a
205 211 pushing to ../a
206 212 searching for changes
207 213 no changes found
208 214 pretxnopen hook: HG_TXNNAME=bookmarks
215 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNNAME=bookmarks
209 216 pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1
210 217 exporting bookmark foo
211 218 [1]
212 219 $ cd ../a
213 220
214 221 listkeys hook
215 222
216 223 $ echo "listkeys = python \"$TESTDIR/printenv.py\" listkeys" >> .hg/hgrc
217 224 $ hg bookmark -r null bar
218 225 $ cd ../b
219 226 $ hg pull -B bar ../a
220 227 pulling from ../a
221 228 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
222 229 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
223 230 no changes found
224 231 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
225 232 adding remote bookmark bar
226 233 $ cd ../a
227 234
228 235 test that prepushkey can prevent incoming keys
229 236
230 237 $ echo "prepushkey = python \"$TESTDIR/printenv.py\" prepushkey.forbid 1" >> .hg/hgrc
231 238 $ cd ../b
232 239 $ hg bookmark -r null baz
233 240 $ hg push -B baz ../a
234 241 pushing to ../a
235 242 searching for changes
236 243 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
237 244 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
238 245 no changes found
239 246 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
240 247 prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
241 248 pushkey-abort: prepushkey hook exited with status 1
242 249 exporting bookmark baz failed!
243 250 [1]
244 251 $ cd ../a
245 252
246 253 test that prelistkeys can prevent listing keys
247 254
248 255 $ echo "prelistkeys = python \"$TESTDIR/printenv.py\" prelistkeys.forbid 1" >> .hg/hgrc
249 256 $ hg bookmark -r null quux
250 257 $ cd ../b
251 258 $ hg pull -B quux ../a
252 259 pulling from ../a
253 260 prelistkeys.forbid hook: HG_NAMESPACE=bookmarks
254 261 abort: prelistkeys hook exited with status 1
255 262 [255]
256 263 $ cd ../a
257 264 $ rm .hg/hgrc
258 265
259 266 prechangegroup hook can prevent incoming changes
260 267
261 268 $ cd ../b
262 269 $ hg -q tip
263 270 3:07f3376c1e65
264 271 $ cat > .hg/hgrc <<EOF
265 272 > [hooks]
266 273 > prechangegroup.forbid = python "$TESTDIR/printenv.py" prechangegroup.forbid 1
267 274 > EOF
268 275 $ hg pull ../a
269 276 pulling from ../a
270 277 searching for changes
271 278 prechangegroup.forbid hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
272 279 abort: prechangegroup.forbid hook exited with status 1
273 280 [255]
274 281
275 282 pretxnchangegroup hook can see incoming changes, can roll back txn,
276 283 incoming changes no longer there after
277 284
278 285 $ cat > .hg/hgrc <<EOF
279 286 > [hooks]
280 287 > pretxnchangegroup.forbid0 = hg tip -q
281 288 > pretxnchangegroup.forbid1 = python "$TESTDIR/printenv.py" pretxnchangegroup.forbid 1
282 289 > EOF
283 290 $ hg pull ../a
284 291 pulling from ../a
285 292 searching for changes
286 293 adding changesets
287 294 adding manifests
288 295 adding file changes
289 296 added 1 changesets with 1 changes to 1 files
290 297 4:539e4b31b6dc
291 298 pretxnchangegroup.forbid hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/b HG_SOURCE=pull HG_URL=file:$TESTTMP/a
292 299 transaction abort!
293 300 rollback completed
294 301 abort: pretxnchangegroup.forbid1 hook exited with status 1
295 302 [255]
296 303 $ hg -q tip
297 304 3:07f3376c1e65
298 305
299 306 outgoing hooks can see env vars
300 307
301 308 $ rm .hg/hgrc
302 309 $ cat > ../a/.hg/hgrc <<EOF
303 310 > [hooks]
304 311 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
305 312 > outgoing = python "$TESTDIR/printenv.py" outgoing
306 313 > EOF
307 314 $ hg pull ../a
308 315 pulling from ../a
309 316 searching for changes
310 317 preoutgoing hook: HG_SOURCE=pull
311 318 adding changesets
312 319 outgoing hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
313 320 adding manifests
314 321 adding file changes
315 322 added 1 changesets with 1 changes to 1 files
316 323 adding remote bookmark quux
317 324 (run 'hg update' to get a working copy)
318 325 $ hg rollback
319 326 repository tip rolled back to revision 3 (undo pull)
320 327
321 328 preoutgoing hook can prevent outgoing changes
322 329
323 330 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> ../a/.hg/hgrc
324 331 $ hg pull ../a
325 332 pulling from ../a
326 333 searching for changes
327 334 preoutgoing hook: HG_SOURCE=pull
328 335 preoutgoing.forbid hook: HG_SOURCE=pull
329 336 abort: preoutgoing.forbid hook exited with status 1
330 337 [255]
331 338
332 339 outgoing hooks work for local clones
333 340
334 341 $ cd ..
335 342 $ cat > a/.hg/hgrc <<EOF
336 343 > [hooks]
337 344 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
338 345 > outgoing = python "$TESTDIR/printenv.py" outgoing
339 346 > EOF
340 347 $ hg clone a c
341 348 preoutgoing hook: HG_SOURCE=clone
342 349 outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
343 350 updating to branch default
344 351 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
345 352 $ rm -rf c
346 353
347 354 preoutgoing hook can prevent outgoing changes for local clones
348 355
349 356 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> a/.hg/hgrc
350 357 $ hg clone a zzz
351 358 preoutgoing hook: HG_SOURCE=clone
352 359 preoutgoing.forbid hook: HG_SOURCE=clone
353 360 abort: preoutgoing.forbid hook exited with status 1
354 361 [255]
355 362
356 363 $ cd "$TESTTMP/b"
357 364
358 365 $ cat > hooktests.py <<EOF
359 366 > from mercurial import util
360 367 >
361 368 > uncallable = 0
362 369 >
363 370 > def printargs(args):
364 371 > args.pop('ui', None)
365 372 > args.pop('repo', None)
366 373 > a = list(args.items())
367 374 > a.sort()
368 375 > print 'hook args:'
369 376 > for k, v in a:
370 377 > print ' ', k, v
371 378 >
372 379 > def passhook(**args):
373 380 > printargs(args)
374 381 >
375 382 > def failhook(**args):
376 383 > printargs(args)
377 384 > return True
378 385 >
379 386 > class LocalException(Exception):
380 387 > pass
381 388 >
382 389 > def raisehook(**args):
383 390 > raise LocalException('exception from hook')
384 391 >
385 392 > def aborthook(**args):
386 393 > raise util.Abort('raise abort from hook')
387 394 >
388 395 > def brokenhook(**args):
389 396 > return 1 + {}
390 397 >
391 398 > def verbosehook(ui, **args):
392 399 > ui.note('verbose output from hook\n')
393 400 >
394 401 > def printtags(ui, repo, **args):
395 402 > print sorted(repo.tags())
396 403 >
397 404 > class container:
398 405 > unreachable = 1
399 406 > EOF
400 407
401 408 test python hooks
402 409
403 410 #if windows
404 411 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
405 412 #else
406 413 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
407 414 #endif
408 415 $ export PYTHONPATH
409 416
410 417 $ echo '[hooks]' > ../a/.hg/hgrc
411 418 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
412 419 $ hg pull ../a 2>&1 | grep 'raised an exception'
413 420 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
414 421
415 422 $ echo '[hooks]' > ../a/.hg/hgrc
416 423 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
417 424 $ hg pull ../a 2>&1 | grep 'raised an exception'
418 425 error: preoutgoing.raise hook raised an exception: exception from hook
419 426
420 427 $ echo '[hooks]' > ../a/.hg/hgrc
421 428 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
422 429 $ hg pull ../a
423 430 pulling from ../a
424 431 searching for changes
425 432 error: preoutgoing.abort hook failed: raise abort from hook
426 433 abort: raise abort from hook
427 434 [255]
428 435
429 436 $ echo '[hooks]' > ../a/.hg/hgrc
430 437 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
431 438 $ hg pull ../a
432 439 pulling from ../a
433 440 searching for changes
434 441 hook args:
435 442 hooktype preoutgoing
436 443 source pull
437 444 abort: preoutgoing.fail hook failed
438 445 [255]
439 446
440 447 $ echo '[hooks]' > ../a/.hg/hgrc
441 448 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
442 449 $ hg pull ../a
443 450 pulling from ../a
444 451 searching for changes
445 452 abort: preoutgoing.uncallable hook is invalid ("hooktests.uncallable" is not callable)
446 453 [255]
447 454
448 455 $ echo '[hooks]' > ../a/.hg/hgrc
449 456 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
450 457 $ hg pull ../a
451 458 pulling from ../a
452 459 searching for changes
453 460 abort: preoutgoing.nohook hook is invalid ("hooktests.nohook" is not defined)
454 461 [255]
455 462
456 463 $ echo '[hooks]' > ../a/.hg/hgrc
457 464 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
458 465 $ hg pull ../a
459 466 pulling from ../a
460 467 searching for changes
461 468 abort: preoutgoing.nomodule hook is invalid ("nomodule" not in a module)
462 469 [255]
463 470
464 471 $ echo '[hooks]' > ../a/.hg/hgrc
465 472 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
466 473 $ hg pull ../a
467 474 pulling from ../a
468 475 searching for changes
469 476 abort: preoutgoing.badmodule hook is invalid (import of "nomodule" failed)
470 477 [255]
471 478
472 479 $ echo '[hooks]' > ../a/.hg/hgrc
473 480 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
474 481 $ hg pull ../a
475 482 pulling from ../a
476 483 searching for changes
477 484 abort: preoutgoing.unreachable hook is invalid (import of "hooktests.container" failed)
478 485 [255]
479 486
480 487 $ echo '[hooks]' > ../a/.hg/hgrc
481 488 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
482 489 $ hg pull ../a
483 490 pulling from ../a
484 491 searching for changes
485 492 hook args:
486 493 hooktype preoutgoing
487 494 source pull
488 495 adding changesets
489 496 adding manifests
490 497 adding file changes
491 498 added 1 changesets with 1 changes to 1 files
492 499 adding remote bookmark quux
493 500 (run 'hg update' to get a working copy)
494 501
495 502 make sure --traceback works
496 503
497 504 $ echo '[hooks]' > .hg/hgrc
498 505 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
499 506
500 507 $ echo aa > a
501 508 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
502 509 Traceback (most recent call last):
503 510
504 511 $ cd ..
505 512 $ hg init c
506 513 $ cd c
507 514
508 515 $ cat > hookext.py <<EOF
509 516 > def autohook(**args):
510 517 > print "Automatically installed hook"
511 518 >
512 519 > def reposetup(ui, repo):
513 520 > repo.ui.setconfig("hooks", "commit.auto", autohook)
514 521 > EOF
515 522 $ echo '[extensions]' >> .hg/hgrc
516 523 $ echo 'hookext = hookext.py' >> .hg/hgrc
517 524
518 525 $ touch foo
519 526 $ hg add foo
520 527 $ hg ci -d '0 0' -m 'add foo'
521 528 Automatically installed hook
522 529 $ echo >> foo
523 530 $ hg ci --debug -d '0 0' -m 'change foo'
524 531 committing files:
525 532 foo
526 533 committing manifest
527 534 committing changelog
528 535 calling hook commit.auto: hgext_hookext.autohook
529 536 Automatically installed hook
530 537 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
531 538
532 539 $ hg showconfig hooks
533 540 hooks.commit.auto=<function autohook at *> (glob)
534 541
535 542 test python hook configured with python:[file]:[hook] syntax
536 543
537 544 $ cd ..
538 545 $ mkdir d
539 546 $ cd d
540 547 $ hg init repo
541 548 $ mkdir hooks
542 549
543 550 $ cd hooks
544 551 $ cat > testhooks.py <<EOF
545 552 > def testhook(**args):
546 553 > print 'hook works'
547 554 > EOF
548 555 $ echo '[hooks]' > ../repo/.hg/hgrc
549 556 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
550 557
551 558 $ cd ../repo
552 559 $ hg commit -d '0 0'
553 560 hook works
554 561 nothing changed
555 562 [1]
556 563
557 564 $ echo '[hooks]' > .hg/hgrc
558 565 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
559 566 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
560 567
561 568 $ hg up null
562 569 loading update.ne hook failed:
563 570 abort: No such file or directory: $TESTTMP/d/repo/nonexistent.py
564 571 [255]
565 572
566 573 $ hg id
567 574 loading pre-identify.npmd hook failed:
568 575 abort: No module named repo!
569 576 [255]
570 577
571 578 $ cd ../../b
572 579
573 580 make sure --traceback works on hook import failure
574 581
575 582 $ cat > importfail.py <<EOF
576 583 > import somebogusmodule
577 584 > # dereference something in the module to force demandimport to load it
578 585 > somebogusmodule.whatever
579 586 > EOF
580 587
581 588 $ echo '[hooks]' > .hg/hgrc
582 589 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
583 590
584 591 $ echo a >> a
585 592 $ hg --traceback commit -ma 2>&1 | egrep -v '^( +File| [a-zA-Z(])'
586 593 exception from first failed import attempt:
587 594 Traceback (most recent call last):
588 595 ImportError: No module named somebogusmodule
589 596 exception from second failed import attempt:
590 597 Traceback (most recent call last):
591 598 ImportError: No module named hgext_importfail
592 599 Traceback (most recent call last):
593 600 Abort: precommit.importfail hook is invalid (import of "importfail" failed)
594 601 abort: precommit.importfail hook is invalid (import of "importfail" failed)
595 602
596 603 Issue1827: Hooks Update & Commit not completely post operation
597 604
598 605 commit and update hooks should run after command completion
599 606
600 607 $ echo '[hooks]' > .hg/hgrc
601 608 $ echo 'commit = hg id' >> .hg/hgrc
602 609 $ echo 'update = hg id' >> .hg/hgrc
603 610 $ echo bb > a
604 611 $ hg ci -ma
605 612 223eafe2750c tip
606 613 $ hg up 0
607 614 cb9a9f314b8b
608 615 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
609 616
610 617 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
611 618 that is passed to pre/post hooks
612 619
613 620 $ echo '[hooks]' > .hg/hgrc
614 621 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
615 622 $ hg id
616 623 cb9a9f314b8b
617 624 $ hg id --verbose
618 625 calling hook pre-identify: hooktests.verbosehook
619 626 verbose output from hook
620 627 cb9a9f314b8b
621 628
622 629 Ensure hooks can be prioritized
623 630
624 631 $ echo '[hooks]' > .hg/hgrc
625 632 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
626 633 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
627 634 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
628 635 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
629 636 $ hg id --verbose
630 637 calling hook pre-identify.b: hooktests.verbosehook
631 638 verbose output from hook
632 639 calling hook pre-identify.a: hooktests.verbosehook
633 640 verbose output from hook
634 641 calling hook pre-identify.c: hooktests.verbosehook
635 642 verbose output from hook
636 643 cb9a9f314b8b
637 644
638 645 new tags must be visible in pretxncommit (issue3210)
639 646
640 647 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
641 648 $ hg tag -f foo
642 649 ['a', 'foo', 'tip']
643 650
644 651 new commits must be visible in pretxnchangegroup (issue3428)
645 652
646 653 $ cd ..
647 654 $ hg init to
648 655 $ echo '[hooks]' >> to/.hg/hgrc
649 656 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
650 657 $ echo a >> to/a
651 658 $ hg --cwd to ci -Ama
652 659 adding a
653 660 $ hg clone to from
654 661 updating to branch default
655 662 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
656 663 $ echo aa >> from/a
657 664 $ hg --cwd from ci -mb
658 665 $ hg --cwd from push
659 666 pushing to $TESTTMP/to (glob)
660 667 searching for changes
661 668 adding changesets
662 669 adding manifests
663 670 adding file changes
664 671 added 1 changesets with 1 changes to 1 files
665 672 changeset: 1:9836a07b9b9d
666 673 tag: tip
667 674 user: test
668 675 date: Thu Jan 01 00:00:00 1970 +0000
669 676 summary: b
670 677
General Comments 0
You need to be logged in to leave comments. Login now