##// END OF EJS Templates
hook: provide hook type information to external hook...
Pierre-Yves David -
r31746:0fa30fbc default
parent child Browse files
Show More
@@ -1,2365 +1,2368
1 1 The Mercurial system uses a set of configuration files to control
2 2 aspects of its behavior.
3 3
4 4 Troubleshooting
5 5 ===============
6 6
7 7 If you're having problems with your configuration,
8 8 :hg:`config --debug` can help you understand what is introducing
9 9 a setting into your environment.
10 10
11 11 See :hg:`help config.syntax` and :hg:`help config.files`
12 12 for information about how and where to override things.
13 13
14 14 Structure
15 15 =========
16 16
17 17 The configuration files use a simple ini-file format. A configuration
18 18 file consists of sections, led by a ``[section]`` header and followed
19 19 by ``name = value`` entries::
20 20
21 21 [ui]
22 22 username = Firstname Lastname <firstname.lastname@example.net>
23 23 verbose = True
24 24
25 25 The above entries will be referred to as ``ui.username`` and
26 26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
27 27
28 28 Files
29 29 =====
30 30
31 31 Mercurial reads configuration data from several files, if they exist.
32 32 These files do not exist by default and you will have to create the
33 33 appropriate configuration files yourself:
34 34
35 35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
36 36
37 37 Global configuration like the username setting is typically put into:
38 38
39 39 .. container:: windows
40 40
41 41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
42 42
43 43 .. container:: unix.plan9
44 44
45 45 - ``$HOME/.hgrc`` (on Unix, Plan9)
46 46
47 47 The names of these files depend on the system on which Mercurial is
48 48 installed. ``*.rc`` files from a single directory are read in
49 49 alphabetical order, later ones overriding earlier ones. Where multiple
50 50 paths are given below, settings from earlier paths override later
51 51 ones.
52 52
53 53 .. container:: verbose.unix
54 54
55 55 On Unix, the following files are consulted:
56 56
57 57 - ``<repo>/.hg/hgrc`` (per-repository)
58 58 - ``$HOME/.hgrc`` (per-user)
59 59 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
60 60 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
61 61 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
62 62 - ``/etc/mercurial/hgrc`` (per-system)
63 63 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
64 64 - ``<internal>/default.d/*.rc`` (defaults)
65 65
66 66 .. container:: verbose.windows
67 67
68 68 On Windows, the following files are consulted:
69 69
70 70 - ``<repo>/.hg/hgrc`` (per-repository)
71 71 - ``%USERPROFILE%\.hgrc`` (per-user)
72 72 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
73 73 - ``%HOME%\.hgrc`` (per-user)
74 74 - ``%HOME%\Mercurial.ini`` (per-user)
75 75 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-installation)
76 76 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
77 77 - ``<install-dir>\Mercurial.ini`` (per-installation)
78 78 - ``<internal>/default.d/*.rc`` (defaults)
79 79
80 80 .. note::
81 81
82 82 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
83 83 is used when running 32-bit Python on 64-bit Windows.
84 84
85 85 .. container:: windows
86 86
87 87 On Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``.
88 88
89 89 .. container:: verbose.plan9
90 90
91 91 On Plan9, the following files are consulted:
92 92
93 93 - ``<repo>/.hg/hgrc`` (per-repository)
94 94 - ``$home/lib/hgrc`` (per-user)
95 95 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
96 96 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
97 97 - ``/lib/mercurial/hgrc`` (per-system)
98 98 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
99 99 - ``<internal>/default.d/*.rc`` (defaults)
100 100
101 101 Per-repository configuration options only apply in a
102 102 particular repository. This file is not version-controlled, and
103 103 will not get transferred during a "clone" operation. Options in
104 104 this file override options in all other configuration files.
105 105
106 106 .. container:: unix.plan9
107 107
108 108 On Plan 9 and Unix, most of this file will be ignored if it doesn't
109 109 belong to a trusted user or to a trusted group. See
110 110 :hg:`help config.trusted` for more details.
111 111
112 112 Per-user configuration file(s) are for the user running Mercurial. Options
113 113 in these files apply to all Mercurial commands executed by this user in any
114 114 directory. Options in these files override per-system and per-installation
115 115 options.
116 116
117 117 Per-installation configuration files are searched for in the
118 118 directory where Mercurial is installed. ``<install-root>`` is the
119 119 parent directory of the **hg** executable (or symlink) being run.
120 120
121 121 .. container:: unix.plan9
122 122
123 123 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
124 124 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
125 125 files apply to all Mercurial commands executed by any user in any
126 126 directory.
127 127
128 128 Per-installation configuration files are for the system on
129 129 which Mercurial is running. Options in these files apply to all
130 130 Mercurial commands executed by any user in any directory. Registry
131 131 keys contain PATH-like strings, every part of which must reference
132 132 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
133 133 be read. Mercurial checks each of these locations in the specified
134 134 order until one or more configuration files are detected.
135 135
136 136 Per-system configuration files are for the system on which Mercurial
137 137 is running. Options in these files apply to all Mercurial commands
138 138 executed by any user in any directory. Options in these files
139 139 override per-installation options.
140 140
141 141 Mercurial comes with some default configuration. The default configuration
142 142 files are installed with Mercurial and will be overwritten on upgrades. Default
143 143 configuration files should never be edited by users or administrators but can
144 144 be overridden in other configuration files. So far the directory only contains
145 145 merge tool configuration but packagers can also put other default configuration
146 146 there.
147 147
148 148 Syntax
149 149 ======
150 150
151 151 A configuration file consists of sections, led by a ``[section]`` header
152 152 and followed by ``name = value`` entries (sometimes called
153 153 ``configuration keys``)::
154 154
155 155 [spam]
156 156 eggs=ham
157 157 green=
158 158 eggs
159 159
160 160 Each line contains one entry. If the lines that follow are indented,
161 161 they are treated as continuations of that entry. Leading whitespace is
162 162 removed from values. Empty lines are skipped. Lines beginning with
163 163 ``#`` or ``;`` are ignored and may be used to provide comments.
164 164
165 165 Configuration keys can be set multiple times, in which case Mercurial
166 166 will use the value that was configured last. As an example::
167 167
168 168 [spam]
169 169 eggs=large
170 170 ham=serrano
171 171 eggs=small
172 172
173 173 This would set the configuration key named ``eggs`` to ``small``.
174 174
175 175 It is also possible to define a section multiple times. A section can
176 176 be redefined on the same and/or on different configuration files. For
177 177 example::
178 178
179 179 [foo]
180 180 eggs=large
181 181 ham=serrano
182 182 eggs=small
183 183
184 184 [bar]
185 185 eggs=ham
186 186 green=
187 187 eggs
188 188
189 189 [foo]
190 190 ham=prosciutto
191 191 eggs=medium
192 192 bread=toasted
193 193
194 194 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
195 195 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
196 196 respectively. As you can see there only thing that matters is the last
197 197 value that was set for each of the configuration keys.
198 198
199 199 If a configuration key is set multiple times in different
200 200 configuration files the final value will depend on the order in which
201 201 the different configuration files are read, with settings from earlier
202 202 paths overriding later ones as described on the ``Files`` section
203 203 above.
204 204
205 205 A line of the form ``%include file`` will include ``file`` into the
206 206 current configuration file. The inclusion is recursive, which means
207 207 that included files can include other files. Filenames are relative to
208 208 the configuration file in which the ``%include`` directive is found.
209 209 Environment variables and ``~user`` constructs are expanded in
210 210 ``file``. This lets you do something like::
211 211
212 212 %include ~/.hgrc.d/$HOST.rc
213 213
214 214 to include a different configuration file on each computer you use.
215 215
216 216 A line with ``%unset name`` will remove ``name`` from the current
217 217 section, if it has been set previously.
218 218
219 219 The values are either free-form text strings, lists of text strings,
220 220 or Boolean values. Boolean values can be set to true using any of "1",
221 221 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
222 222 (all case insensitive).
223 223
224 224 List values are separated by whitespace or comma, except when values are
225 225 placed in double quotation marks::
226 226
227 227 allow_read = "John Doe, PhD", brian, betty
228 228
229 229 Quotation marks can be escaped by prefixing them with a backslash. Only
230 230 quotation marks at the beginning of a word is counted as a quotation
231 231 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
232 232
233 233 Sections
234 234 ========
235 235
236 236 This section describes the different sections that may appear in a
237 237 Mercurial configuration file, the purpose of each section, its possible
238 238 keys, and their possible values.
239 239
240 240 ``alias``
241 241 ---------
242 242
243 243 Defines command aliases.
244 244
245 245 Aliases allow you to define your own commands in terms of other
246 246 commands (or aliases), optionally including arguments. Positional
247 247 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
248 248 are expanded by Mercurial before execution. Positional arguments not
249 249 already used by ``$N`` in the definition are put at the end of the
250 250 command to be executed.
251 251
252 252 Alias definitions consist of lines of the form::
253 253
254 254 <alias> = <command> [<argument>]...
255 255
256 256 For example, this definition::
257 257
258 258 latest = log --limit 5
259 259
260 260 creates a new command ``latest`` that shows only the five most recent
261 261 changesets. You can define subsequent aliases using earlier ones::
262 262
263 263 stable5 = latest -b stable
264 264
265 265 .. note::
266 266
267 267 It is possible to create aliases with the same names as
268 268 existing commands, which will then override the original
269 269 definitions. This is almost always a bad idea!
270 270
271 271 An alias can start with an exclamation point (``!``) to make it a
272 272 shell alias. A shell alias is executed with the shell and will let you
273 273 run arbitrary commands. As an example, ::
274 274
275 275 echo = !echo $@
276 276
277 277 will let you do ``hg echo foo`` to have ``foo`` printed in your
278 278 terminal. A better example might be::
279 279
280 280 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
281 281
282 282 which will make ``hg purge`` delete all unknown files in the
283 283 repository in the same manner as the purge extension.
284 284
285 285 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
286 286 expand to the command arguments. Unmatched arguments are
287 287 removed. ``$0`` expands to the alias name and ``$@`` expands to all
288 288 arguments separated by a space. ``"$@"`` (with quotes) expands to all
289 289 arguments quoted individually and separated by a space. These expansions
290 290 happen before the command is passed to the shell.
291 291
292 292 Shell aliases are executed in an environment where ``$HG`` expands to
293 293 the path of the Mercurial that was used to execute the alias. This is
294 294 useful when you want to call further Mercurial commands in a shell
295 295 alias, as was done above for the purge alias. In addition,
296 296 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
297 297 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
298 298
299 299 .. note::
300 300
301 301 Some global configuration options such as ``-R`` are
302 302 processed before shell aliases and will thus not be passed to
303 303 aliases.
304 304
305 305
306 306 ``annotate``
307 307 ------------
308 308
309 309 Settings used when displaying file annotations. All values are
310 310 Booleans and default to False. See :hg:`help config.diff` for
311 311 related options for the diff command.
312 312
313 313 ``ignorews``
314 314 Ignore white space when comparing lines.
315 315
316 316 ``ignorewsamount``
317 317 Ignore changes in the amount of white space.
318 318
319 319 ``ignoreblanklines``
320 320 Ignore changes whose lines are all blank.
321 321
322 322
323 323 ``auth``
324 324 --------
325 325
326 326 Authentication credentials for HTTP authentication. This section
327 327 allows you to store usernames and passwords for use when logging
328 328 *into* HTTP servers. See :hg:`help config.web` if
329 329 you want to configure *who* can login to your HTTP server.
330 330
331 331 Each line has the following format::
332 332
333 333 <name>.<argument> = <value>
334 334
335 335 where ``<name>`` is used to group arguments into authentication
336 336 entries. Example::
337 337
338 338 foo.prefix = hg.intevation.de/mercurial
339 339 foo.username = foo
340 340 foo.password = bar
341 341 foo.schemes = http https
342 342
343 343 bar.prefix = secure.example.org
344 344 bar.key = path/to/file.key
345 345 bar.cert = path/to/file.cert
346 346 bar.schemes = https
347 347
348 348 Supported arguments:
349 349
350 350 ``prefix``
351 351 Either ``*`` or a URI prefix with or without the scheme part.
352 352 The authentication entry with the longest matching prefix is used
353 353 (where ``*`` matches everything and counts as a match of length
354 354 1). If the prefix doesn't include a scheme, the match is performed
355 355 against the URI with its scheme stripped as well, and the schemes
356 356 argument, q.v., is then subsequently consulted.
357 357
358 358 ``username``
359 359 Optional. Username to authenticate with. If not given, and the
360 360 remote site requires basic or digest authentication, the user will
361 361 be prompted for it. Environment variables are expanded in the
362 362 username letting you do ``foo.username = $USER``. If the URI
363 363 includes a username, only ``[auth]`` entries with a matching
364 364 username or without a username will be considered.
365 365
366 366 ``password``
367 367 Optional. Password to authenticate with. If not given, and the
368 368 remote site requires basic or digest authentication, the user
369 369 will be prompted for it.
370 370
371 371 ``key``
372 372 Optional. PEM encoded client certificate key file. Environment
373 373 variables are expanded in the filename.
374 374
375 375 ``cert``
376 376 Optional. PEM encoded client certificate chain file. Environment
377 377 variables are expanded in the filename.
378 378
379 379 ``schemes``
380 380 Optional. Space separated list of URI schemes to use this
381 381 authentication entry with. Only used if the prefix doesn't include
382 382 a scheme. Supported schemes are http and https. They will match
383 383 static-http and static-https respectively, as well.
384 384 (default: https)
385 385
386 386 If no suitable authentication entry is found, the user is prompted
387 387 for credentials as usual if required by the remote.
388 388
389 389 ``color``
390 390 ---------
391 391
392 392 Configure the Mercurial color mode. For details about how to define your custom
393 393 effect and style see :hg:`help color`.
394 394
395 395 ``mode``
396 396 String: control the method used to output color. One of ``auto``, ``ansi``,
397 397 ``win32``, ``terminfo`` or ``debug``. In auto mode the color extension will
398 398 use ANSI mode by default (or win32 mode on Windows) if it detects a
399 399 terminal. Any invalid value will disable color.
400 400
401 401 ``pagermode``
402 402 String: optinal override of ``color.mode`` used with pager (from the pager
403 403 extensions).
404 404
405 405 On some systems, terminfo mode may cause problems when using
406 406 color with the pager extension and less -R. less with the -R option
407 407 will only display ECMA-48 color codes, and terminfo mode may sometimes
408 408 emit codes that less doesn't understand. You can work around this by
409 409 either using ansi mode (or auto mode), or by using less -r (which will
410 410 pass through all terminal control codes, not just color control
411 411 codes).
412 412
413 413 On some systems (such as MSYS in Windows), the terminal may support
414 414 a different color mode than the pager (activated via the "pager"
415 415 extension).
416 416
417 417 ``commands``
418 418 ------------
419 419
420 420 ``status.relative``
421 421 Make paths in ``hg status`` output relative to the current directory.
422 422 (default: False)
423 423
424 424 ``update.requiredest``
425 425 Require that the user pass a destination when running ``hg update``.
426 426 For example, ``hg update .::`` will be allowed, but a plain ``hg update``
427 427 will be disallowed.
428 428 (default: False)
429 429
430 430 ``committemplate``
431 431 ------------------
432 432
433 433 ``changeset``
434 434 String: configuration in this section is used as the template to
435 435 customize the text shown in the editor when committing.
436 436
437 437 In addition to pre-defined template keywords, commit log specific one
438 438 below can be used for customization:
439 439
440 440 ``extramsg``
441 441 String: Extra message (typically 'Leave message empty to abort
442 442 commit.'). This may be changed by some commands or extensions.
443 443
444 444 For example, the template configuration below shows as same text as
445 445 one shown by default::
446 446
447 447 [committemplate]
448 448 changeset = {desc}\n\n
449 449 HG: Enter commit message. Lines beginning with 'HG:' are removed.
450 450 HG: {extramsg}
451 451 HG: --
452 452 HG: user: {author}\n{ifeq(p2rev, "-1", "",
453 453 "HG: branch merge\n")
454 454 }HG: branch '{branch}'\n{if(activebookmark,
455 455 "HG: bookmark '{activebookmark}'\n") }{subrepos %
456 456 "HG: subrepo {subrepo}\n" }{file_adds %
457 457 "HG: added {file}\n" }{file_mods %
458 458 "HG: changed {file}\n" }{file_dels %
459 459 "HG: removed {file}\n" }{if(files, "",
460 460 "HG: no files changed\n")}
461 461
462 462 ``diff()``
463 463 String: show the diff (see :hg:`help templates` for detail)
464 464
465 465 Sometimes it is helpful to show the diff of the changeset in the editor without
466 466 having to prefix 'HG: ' to each line so that highlighting works correctly. For
467 467 this, Mercurial provides a special string which will ignore everything below
468 468 it::
469 469
470 470 HG: ------------------------ >8 ------------------------
471 471
472 472 For example, the template configuration below will show the diff below the
473 473 extra message::
474 474
475 475 [committemplate]
476 476 changeset = {desc}\n\n
477 477 HG: Enter commit message. Lines beginning with 'HG:' are removed.
478 478 HG: {extramsg}
479 479 HG: ------------------------ >8 ------------------------
480 480 HG: Do not touch the line above.
481 481 HG: Everything below will be removed.
482 482 {diff()}
483 483
484 484 .. note::
485 485
486 486 For some problematic encodings (see :hg:`help win32mbcs` for
487 487 detail), this customization should be configured carefully, to
488 488 avoid showing broken characters.
489 489
490 490 For example, if a multibyte character ending with backslash (0x5c) is
491 491 followed by the ASCII character 'n' in the customized template,
492 492 the sequence of backslash and 'n' is treated as line-feed unexpectedly
493 493 (and the multibyte character is broken, too).
494 494
495 495 Customized template is used for commands below (``--edit`` may be
496 496 required):
497 497
498 498 - :hg:`backout`
499 499 - :hg:`commit`
500 500 - :hg:`fetch` (for merge commit only)
501 501 - :hg:`graft`
502 502 - :hg:`histedit`
503 503 - :hg:`import`
504 504 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
505 505 - :hg:`rebase`
506 506 - :hg:`shelve`
507 507 - :hg:`sign`
508 508 - :hg:`tag`
509 509 - :hg:`transplant`
510 510
511 511 Configuring items below instead of ``changeset`` allows showing
512 512 customized message only for specific actions, or showing different
513 513 messages for each action.
514 514
515 515 - ``changeset.backout`` for :hg:`backout`
516 516 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
517 517 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
518 518 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
519 519 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
520 520 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
521 521 - ``changeset.gpg.sign`` for :hg:`sign`
522 522 - ``changeset.graft`` for :hg:`graft`
523 523 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
524 524 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
525 525 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
526 526 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
527 527 - ``changeset.import.bypass`` for :hg:`import --bypass`
528 528 - ``changeset.import.normal.merge`` for :hg:`import` on merges
529 529 - ``changeset.import.normal.normal`` for :hg:`import` on other
530 530 - ``changeset.mq.qnew`` for :hg:`qnew`
531 531 - ``changeset.mq.qfold`` for :hg:`qfold`
532 532 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
533 533 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
534 534 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
535 535 - ``changeset.rebase.normal`` for :hg:`rebase` on other
536 536 - ``changeset.shelve.shelve`` for :hg:`shelve`
537 537 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
538 538 - ``changeset.tag.remove`` for :hg:`tag --remove`
539 539 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
540 540 - ``changeset.transplant.normal`` for :hg:`transplant` on other
541 541
542 542 These dot-separated lists of names are treated as hierarchical ones.
543 543 For example, ``changeset.tag.remove`` customizes the commit message
544 544 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
545 545 commit message for :hg:`tag` regardless of ``--remove`` option.
546 546
547 547 When the external editor is invoked for a commit, the corresponding
548 548 dot-separated list of names without the ``changeset.`` prefix
549 549 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
550 550 variable.
551 551
552 552 In this section, items other than ``changeset`` can be referred from
553 553 others. For example, the configuration to list committed files up
554 554 below can be referred as ``{listupfiles}``::
555 555
556 556 [committemplate]
557 557 listupfiles = {file_adds %
558 558 "HG: added {file}\n" }{file_mods %
559 559 "HG: changed {file}\n" }{file_dels %
560 560 "HG: removed {file}\n" }{if(files, "",
561 561 "HG: no files changed\n")}
562 562
563 563 ``decode/encode``
564 564 -----------------
565 565
566 566 Filters for transforming files on checkout/checkin. This would
567 567 typically be used for newline processing or other
568 568 localization/canonicalization of files.
569 569
570 570 Filters consist of a filter pattern followed by a filter command.
571 571 Filter patterns are globs by default, rooted at the repository root.
572 572 For example, to match any file ending in ``.txt`` in the root
573 573 directory only, use the pattern ``*.txt``. To match any file ending
574 574 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
575 575 For each file only the first matching filter applies.
576 576
577 577 The filter command can start with a specifier, either ``pipe:`` or
578 578 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
579 579
580 580 A ``pipe:`` command must accept data on stdin and return the transformed
581 581 data on stdout.
582 582
583 583 Pipe example::
584 584
585 585 [encode]
586 586 # uncompress gzip files on checkin to improve delta compression
587 587 # note: not necessarily a good idea, just an example
588 588 *.gz = pipe: gunzip
589 589
590 590 [decode]
591 591 # recompress gzip files when writing them to the working dir (we
592 592 # can safely omit "pipe:", because it's the default)
593 593 *.gz = gzip
594 594
595 595 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
596 596 with the name of a temporary file that contains the data to be
597 597 filtered by the command. The string ``OUTFILE`` is replaced with the name
598 598 of an empty temporary file, where the filtered data must be written by
599 599 the command.
600 600
601 601 .. container:: windows
602 602
603 603 .. note::
604 604
605 605 The tempfile mechanism is recommended for Windows systems,
606 606 where the standard shell I/O redirection operators often have
607 607 strange effects and may corrupt the contents of your files.
608 608
609 609 This filter mechanism is used internally by the ``eol`` extension to
610 610 translate line ending characters between Windows (CRLF) and Unix (LF)
611 611 format. We suggest you use the ``eol`` extension for convenience.
612 612
613 613
614 614 ``defaults``
615 615 ------------
616 616
617 617 (defaults are deprecated. Don't use them. Use aliases instead.)
618 618
619 619 Use the ``[defaults]`` section to define command defaults, i.e. the
620 620 default options/arguments to pass to the specified commands.
621 621
622 622 The following example makes :hg:`log` run in verbose mode, and
623 623 :hg:`status` show only the modified files, by default::
624 624
625 625 [defaults]
626 626 log = -v
627 627 status = -m
628 628
629 629 The actual commands, instead of their aliases, must be used when
630 630 defining command defaults. The command defaults will also be applied
631 631 to the aliases of the commands defined.
632 632
633 633
634 634 ``diff``
635 635 --------
636 636
637 637 Settings used when displaying diffs. Everything except for ``unified``
638 638 is a Boolean and defaults to False. See :hg:`help config.annotate`
639 639 for related options for the annotate command.
640 640
641 641 ``git``
642 642 Use git extended diff format.
643 643
644 644 ``nobinary``
645 645 Omit git binary patches.
646 646
647 647 ``nodates``
648 648 Don't include dates in diff headers.
649 649
650 650 ``noprefix``
651 651 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
652 652
653 653 ``showfunc``
654 654 Show which function each change is in.
655 655
656 656 ``ignorews``
657 657 Ignore white space when comparing lines.
658 658
659 659 ``ignorewsamount``
660 660 Ignore changes in the amount of white space.
661 661
662 662 ``ignoreblanklines``
663 663 Ignore changes whose lines are all blank.
664 664
665 665 ``unified``
666 666 Number of lines of context to show.
667 667
668 668 ``email``
669 669 ---------
670 670
671 671 Settings for extensions that send email messages.
672 672
673 673 ``from``
674 674 Optional. Email address to use in "From" header and SMTP envelope
675 675 of outgoing messages.
676 676
677 677 ``to``
678 678 Optional. Comma-separated list of recipients' email addresses.
679 679
680 680 ``cc``
681 681 Optional. Comma-separated list of carbon copy recipients'
682 682 email addresses.
683 683
684 684 ``bcc``
685 685 Optional. Comma-separated list of blind carbon copy recipients'
686 686 email addresses.
687 687
688 688 ``method``
689 689 Optional. Method to use to send email messages. If value is ``smtp``
690 690 (default), use SMTP (see the ``[smtp]`` section for configuration).
691 691 Otherwise, use as name of program to run that acts like sendmail
692 692 (takes ``-f`` option for sender, list of recipients on command line,
693 693 message on stdin). Normally, setting this to ``sendmail`` or
694 694 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
695 695
696 696 ``charsets``
697 697 Optional. Comma-separated list of character sets considered
698 698 convenient for recipients. Addresses, headers, and parts not
699 699 containing patches of outgoing messages will be encoded in the
700 700 first character set to which conversion from local encoding
701 701 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
702 702 conversion fails, the text in question is sent as is.
703 703 (default: '')
704 704
705 705 Order of outgoing email character sets:
706 706
707 707 1. ``us-ascii``: always first, regardless of settings
708 708 2. ``email.charsets``: in order given by user
709 709 3. ``ui.fallbackencoding``: if not in email.charsets
710 710 4. ``$HGENCODING``: if not in email.charsets
711 711 5. ``utf-8``: always last, regardless of settings
712 712
713 713 Email example::
714 714
715 715 [email]
716 716 from = Joseph User <joe.user@example.com>
717 717 method = /usr/sbin/sendmail
718 718 # charsets for western Europeans
719 719 # us-ascii, utf-8 omitted, as they are tried first and last
720 720 charsets = iso-8859-1, iso-8859-15, windows-1252
721 721
722 722
723 723 ``extensions``
724 724 --------------
725 725
726 726 Mercurial has an extension mechanism for adding new features. To
727 727 enable an extension, create an entry for it in this section.
728 728
729 729 If you know that the extension is already in Python's search path,
730 730 you can give the name of the module, followed by ``=``, with nothing
731 731 after the ``=``.
732 732
733 733 Otherwise, give a name that you choose, followed by ``=``, followed by
734 734 the path to the ``.py`` file (including the file name extension) that
735 735 defines the extension.
736 736
737 737 To explicitly disable an extension that is enabled in an hgrc of
738 738 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
739 739 or ``foo = !`` when path is not supplied.
740 740
741 741 Example for ``~/.hgrc``::
742 742
743 743 [extensions]
744 744 # (the churn extension will get loaded from Mercurial's path)
745 745 churn =
746 746 # (this extension will get loaded from the file specified)
747 747 myfeature = ~/.hgext/myfeature.py
748 748
749 749
750 750 ``format``
751 751 ----------
752 752
753 753 ``usegeneraldelta``
754 754 Enable or disable the "generaldelta" repository format which improves
755 755 repository compression by allowing "revlog" to store delta against arbitrary
756 756 revision instead of the previous stored one. This provides significant
757 757 improvement for repositories with branches.
758 758
759 759 Repositories with this on-disk format require Mercurial version 1.9.
760 760
761 761 Enabled by default.
762 762
763 763 ``dotencode``
764 764 Enable or disable the "dotencode" repository format which enhances
765 765 the "fncache" repository format (which has to be enabled to use
766 766 dotencode) to avoid issues with filenames starting with ._ on
767 767 Mac OS X and spaces on Windows.
768 768
769 769 Repositories with this on-disk format require Mercurial version 1.7.
770 770
771 771 Enabled by default.
772 772
773 773 ``usefncache``
774 774 Enable or disable the "fncache" repository format which enhances
775 775 the "store" repository format (which has to be enabled to use
776 776 fncache) to allow longer filenames and avoids using Windows
777 777 reserved names, e.g. "nul".
778 778
779 779 Repositories with this on-disk format require Mercurial version 1.1.
780 780
781 781 Enabled by default.
782 782
783 783 ``usestore``
784 784 Enable or disable the "store" repository format which improves
785 785 compatibility with systems that fold case or otherwise mangle
786 786 filenames. Disabling this option will allow you to store longer filenames
787 787 in some situations at the expense of compatibility.
788 788
789 789 Repositories with this on-disk format require Mercurial version 0.9.4.
790 790
791 791 Enabled by default.
792 792
793 793 ``graph``
794 794 ---------
795 795
796 796 Web graph view configuration. This section let you change graph
797 797 elements display properties by branches, for instance to make the
798 798 ``default`` branch stand out.
799 799
800 800 Each line has the following format::
801 801
802 802 <branch>.<argument> = <value>
803 803
804 804 where ``<branch>`` is the name of the branch being
805 805 customized. Example::
806 806
807 807 [graph]
808 808 # 2px width
809 809 default.width = 2
810 810 # red color
811 811 default.color = FF0000
812 812
813 813 Supported arguments:
814 814
815 815 ``width``
816 816 Set branch edges width in pixels.
817 817
818 818 ``color``
819 819 Set branch edges color in hexadecimal RGB notation.
820 820
821 821 ``hooks``
822 822 ---------
823 823
824 824 Commands or Python functions that get automatically executed by
825 825 various actions such as starting or finishing a commit. Multiple
826 826 hooks can be run for the same action by appending a suffix to the
827 827 action. Overriding a site-wide hook can be done by changing its
828 828 value or setting it to an empty string. Hooks can be prioritized
829 829 by adding a prefix of ``priority.`` to the hook name on a new line
830 830 and setting the priority. The default priority is 0.
831 831
832 832 Example ``.hg/hgrc``::
833 833
834 834 [hooks]
835 835 # update working directory after adding changesets
836 836 changegroup.update = hg update
837 837 # do not use the site-wide hook
838 838 incoming =
839 839 incoming.email = /my/email/hook
840 840 incoming.autobuild = /my/build/hook
841 841 # force autobuild hook to run before other incoming hooks
842 842 priority.incoming.autobuild = 1
843 843
844 844 Most hooks are run with environment variables set that give useful
845 additional information. For each hook below, the environment
846 variables it is passed are listed with names of the form ``$HG_foo``.
845 additional information. For each hook below, the environment variables
846 it is passed are listed with names of the form ``$HG_foo``. The
847 ``$HG_HOOKTYPE`` variable is set for all hooks. It contains the type of
848 hook which triggered the run. In the example about this will be
849 ``$HG_HOOKTYPE=incoming``.
847 850
848 851 ``changegroup``
849 852 Run after a changegroup has been added via push, pull or unbundle. ID of the
850 853 first new changeset is in ``$HG_NODE`` and last in ``$HG_NODE_LAST``. URL
851 854 from which changes came is in ``$HG_URL``.
852 855
853 856 ``commit``
854 857 Run after a changeset has been created in the local repository. ID
855 858 of the newly created changeset is in ``$HG_NODE``. Parent changeset
856 859 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
857 860
858 861 ``incoming``
859 862 Run after a changeset has been pulled, pushed, or unbundled into
860 863 the local repository. The ID of the newly arrived changeset is in
861 864 ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``.
862 865
863 866 ``outgoing``
864 867 Run after sending changes from local repository to another. ID of
865 868 first changeset sent is in ``$HG_NODE``. Source of operation is in
866 869 ``$HG_SOURCE``; Also see :hg:`help config.hooks.preoutgoing` hook.
867 870
868 871 ``post-<command>``
869 872 Run after successful invocations of the associated command. The
870 873 contents of the command line are passed as ``$HG_ARGS`` and the result
871 874 code in ``$HG_RESULT``. Parsed command line arguments are passed as
872 875 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
873 876 the python data internally passed to <command>. ``$HG_OPTS`` is a
874 877 dictionary of options (with unspecified options set to their defaults).
875 878 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
876 879
877 880 ``fail-<command>``
878 881 Run after a failed invocation of an associated command. The contents
879 882 of the command line are passed as ``$HG_ARGS``. Parsed command line
880 883 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
881 884 string representations of the python data internally passed to
882 885 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
883 886 options set to their defaults). ``$HG_PATS`` is a list of arguments.
884 887 Hook failure is ignored.
885 888
886 889 ``pre-<command>``
887 890 Run before executing the associated command. The contents of the
888 891 command line are passed as ``$HG_ARGS``. Parsed command line arguments
889 892 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
890 893 representations of the data internally passed to <command>. ``$HG_OPTS``
891 894 is a dictionary of options (with unspecified options set to their
892 895 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
893 896 failure, the command doesn't execute and Mercurial returns the failure
894 897 code.
895 898
896 899 ``prechangegroup``
897 900 Run before a changegroup is added via push, pull or unbundle. Exit
898 901 status 0 allows the changegroup to proceed. Non-zero status will
899 902 cause the push, pull or unbundle to fail. URL from which changes
900 903 will come is in ``$HG_URL``.
901 904
902 905 ``precommit``
903 906 Run before starting a local commit. Exit status 0 allows the
904 907 commit to proceed. Non-zero status will cause the commit to fail.
905 908 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
906 909
907 910 ``prelistkeys``
908 911 Run before listing pushkeys (like bookmarks) in the
909 912 repository. Non-zero status will cause failure. The key namespace is
910 913 in ``$HG_NAMESPACE``.
911 914
912 915 ``preoutgoing``
913 916 Run before collecting changes to send from the local repository to
914 917 another. Non-zero status will cause failure. This lets you prevent
915 918 pull over HTTP or SSH. Also prevents against local pull, push
916 919 (outbound) or bundle commands, but not effective, since you can
917 920 just copy files instead then. Source of operation is in
918 921 ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
919 922 SSH or HTTP repository. If "push", "pull" or "bundle", operation
920 923 is happening on behalf of repository on same system.
921 924
922 925 ``prepushkey``
923 926 Run before a pushkey (like a bookmark) is added to the
924 927 repository. Non-zero status will cause the key to be rejected. The
925 928 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
926 929 the old value (if any) is in ``$HG_OLD``, and the new value is in
927 930 ``$HG_NEW``.
928 931
929 932 ``pretag``
930 933 Run before creating a tag. Exit status 0 allows the tag to be
931 934 created. Non-zero status will cause the tag to fail. ID of
932 935 changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag is
933 936 local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``.
934 937
935 938 ``pretxnopen``
936 939 Run before any new repository transaction is open. The reason for the
937 940 transaction will be in ``$HG_TXNNAME`` and a unique identifier for the
938 941 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
939 942 transaction from being opened.
940 943
941 944 ``pretxnclose``
942 945 Run right before the transaction is actually finalized. Any repository change
943 946 will be visible to the hook program. This lets you validate the transaction
944 947 content or change it. Exit status 0 allows the commit to proceed. Non-zero
945 948 status will cause the transaction to be rolled back. The reason for the
946 949 transaction opening will be in ``$HG_TXNNAME`` and a unique identifier for
947 950 the transaction will be in ``HG_TXNID``. The rest of the available data will
948 951 vary according the transaction type. New changesets will add ``$HG_NODE`` (id
949 952 of the first added changeset), ``$HG_NODE_LAST`` (id of the last added
950 953 changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables, bookmarks and phases
951 954 changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``, etc.
952 955
953 956 ``txnclose``
954 957 Run after any repository transaction has been committed. At this
955 958 point, the transaction can no longer be rolled back. The hook will run
956 959 after the lock is released. See :hg:`help config.hooks.pretxnclose` docs for
957 960 details about available variables.
958 961
959 962 ``txnabort``
960 963 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
961 964 docs for details about available variables.
962 965
963 966 ``pretxnchangegroup``
964 967 Run after a changegroup has been added via push, pull or unbundle, but before
965 968 the transaction has been committed. Changegroup is visible to hook program.
966 969 This lets you validate incoming changes before accepting them. Passed the ID
967 970 of the first new changeset in ``$HG_NODE`` and last in ``$HG_NODE_LAST``.
968 971 Exit status 0 allows the transaction to commit. Non-zero status will cause
969 972 the transaction to be rolled back and the push, pull or unbundle will fail.
970 973 URL that was source of changes is in ``$HG_URL``.
971 974
972 975 ``pretxncommit``
973 976 Run after a changeset has been created but the transaction not yet
974 977 committed. Changeset is visible to hook program. This lets you
975 978 validate commit message and changes. Exit status 0 allows the
976 979 commit to proceed. Non-zero status will cause the transaction to
977 980 be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset
978 981 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
979 982
980 983 ``preupdate``
981 984 Run before updating the working directory. Exit status 0 allows
982 985 the update to proceed. Non-zero status will prevent the update.
983 986 Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
984 987 of second new parent is in ``$HG_PARENT2``.
985 988
986 989 ``listkeys``
987 990 Run after listing pushkeys (like bookmarks) in the repository. The
988 991 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
989 992 dictionary containing the keys and values.
990 993
991 994 ``pushkey``
992 995 Run after a pushkey (like a bookmark) is added to the
993 996 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
994 997 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
995 998 value is in ``$HG_NEW``.
996 999
997 1000 ``tag``
998 1001 Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
999 1002 Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
1000 1003 repository if ``$HG_LOCAL=0``.
1001 1004
1002 1005 ``update``
1003 1006 Run after updating the working directory. Changeset ID of first
1004 1007 new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is
1005 1008 in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1006 1009 update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``.
1007 1010
1008 1011 .. note::
1009 1012
1010 1013 It is generally better to use standard hooks rather than the
1011 1014 generic pre- and post- command hooks as they are guaranteed to be
1012 1015 called in the appropriate contexts for influencing transactions.
1013 1016 Also, hooks like "commit" will be called in all contexts that
1014 1017 generate a commit (e.g. tag) and not just the commit command.
1015 1018
1016 1019 .. note::
1017 1020
1018 1021 Environment variables with empty values may not be passed to
1019 1022 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1020 1023 will have an empty value under Unix-like platforms for non-merge
1021 1024 changesets, while it will not be available at all under Windows.
1022 1025
1023 1026 The syntax for Python hooks is as follows::
1024 1027
1025 1028 hookname = python:modulename.submodule.callable
1026 1029 hookname = python:/path/to/python/module.py:callable
1027 1030
1028 1031 Python hooks are run within the Mercurial process. Each hook is
1029 1032 called with at least three keyword arguments: a ui object (keyword
1030 1033 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1031 1034 keyword that tells what kind of hook is used. Arguments listed as
1032 1035 environment variables above are passed as keyword arguments, with no
1033 1036 ``HG_`` prefix, and names in lower case.
1034 1037
1035 1038 If a Python hook returns a "true" value or raises an exception, this
1036 1039 is treated as a failure.
1037 1040
1038 1041
1039 1042 ``hostfingerprints``
1040 1043 --------------------
1041 1044
1042 1045 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1043 1046
1044 1047 Fingerprints of the certificates of known HTTPS servers.
1045 1048
1046 1049 A HTTPS connection to a server with a fingerprint configured here will
1047 1050 only succeed if the servers certificate matches the fingerprint.
1048 1051 This is very similar to how ssh known hosts works.
1049 1052
1050 1053 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1051 1054 Multiple values can be specified (separated by spaces or commas). This can
1052 1055 be used to define both old and new fingerprints while a host transitions
1053 1056 to a new certificate.
1054 1057
1055 1058 The CA chain and web.cacerts is not used for servers with a fingerprint.
1056 1059
1057 1060 For example::
1058 1061
1059 1062 [hostfingerprints]
1060 1063 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1061 1064 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1062 1065
1063 1066 ``hostsecurity``
1064 1067 ----------------
1065 1068
1066 1069 Used to specify global and per-host security settings for connecting to
1067 1070 other machines.
1068 1071
1069 1072 The following options control default behavior for all hosts.
1070 1073
1071 1074 ``ciphers``
1072 1075 Defines the cryptographic ciphers to use for connections.
1073 1076
1074 1077 Value must be a valid OpenSSL Cipher List Format as documented at
1075 1078 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1076 1079
1077 1080 This setting is for advanced users only. Setting to incorrect values
1078 1081 can significantly lower connection security or decrease performance.
1079 1082 You have been warned.
1080 1083
1081 1084 This option requires Python 2.7.
1082 1085
1083 1086 ``minimumprotocol``
1084 1087 Defines the minimum channel encryption protocol to use.
1085 1088
1086 1089 By default, the highest version of TLS supported by both client and server
1087 1090 is used.
1088 1091
1089 1092 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1090 1093
1091 1094 When running on an old Python version, only ``tls1.0`` is allowed since
1092 1095 old versions of Python only support up to TLS 1.0.
1093 1096
1094 1097 When running a Python that supports modern TLS versions, the default is
1095 1098 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1096 1099 weakens security and should only be used as a feature of last resort if
1097 1100 a server does not support TLS 1.1+.
1098 1101
1099 1102 Options in the ``[hostsecurity]`` section can have the form
1100 1103 ``hostname``:``setting``. This allows multiple settings to be defined on a
1101 1104 per-host basis.
1102 1105
1103 1106 The following per-host settings can be defined.
1104 1107
1105 1108 ``ciphers``
1106 1109 This behaves like ``ciphers`` as described above except it only applies
1107 1110 to the host on which it is defined.
1108 1111
1109 1112 ``fingerprints``
1110 1113 A list of hashes of the DER encoded peer/remote certificate. Values have
1111 1114 the form ``algorithm``:``fingerprint``. e.g.
1112 1115 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1113 1116
1114 1117 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1115 1118 ``sha512``.
1116 1119
1117 1120 Use of ``sha256`` or ``sha512`` is preferred.
1118 1121
1119 1122 If a fingerprint is specified, the CA chain is not validated for this
1120 1123 host and Mercurial will require the remote certificate to match one
1121 1124 of the fingerprints specified. This means if the server updates its
1122 1125 certificate, Mercurial will abort until a new fingerprint is defined.
1123 1126 This can provide stronger security than traditional CA-based validation
1124 1127 at the expense of convenience.
1125 1128
1126 1129 This option takes precedence over ``verifycertsfile``.
1127 1130
1128 1131 ``minimumprotocol``
1129 1132 This behaves like ``minimumprotocol`` as described above except it
1130 1133 only applies to the host on which it is defined.
1131 1134
1132 1135 ``verifycertsfile``
1133 1136 Path to file a containing a list of PEM encoded certificates used to
1134 1137 verify the server certificate. Environment variables and ``~user``
1135 1138 constructs are expanded in the filename.
1136 1139
1137 1140 The server certificate or the certificate's certificate authority (CA)
1138 1141 must match a certificate from this file or certificate verification
1139 1142 will fail and connections to the server will be refused.
1140 1143
1141 1144 If defined, only certificates provided by this file will be used:
1142 1145 ``web.cacerts`` and any system/default certificates will not be
1143 1146 used.
1144 1147
1145 1148 This option has no effect if the per-host ``fingerprints`` option
1146 1149 is set.
1147 1150
1148 1151 The format of the file is as follows::
1149 1152
1150 1153 -----BEGIN CERTIFICATE-----
1151 1154 ... (certificate in base64 PEM encoding) ...
1152 1155 -----END CERTIFICATE-----
1153 1156 -----BEGIN CERTIFICATE-----
1154 1157 ... (certificate in base64 PEM encoding) ...
1155 1158 -----END CERTIFICATE-----
1156 1159
1157 1160 For example::
1158 1161
1159 1162 [hostsecurity]
1160 1163 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1161 1164 hg2.example.com:fingerprints = sha1:914f1aff87249c09b6859b88b1906d30756491ca, sha1:fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1162 1165 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1163 1166
1164 1167 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1165 1168 when connecting to ``hg.example.com``::
1166 1169
1167 1170 [hostsecurity]
1168 1171 minimumprotocol = tls1.2
1169 1172 hg.example.com:minimumprotocol = tls1.1
1170 1173
1171 1174 ``http_proxy``
1172 1175 --------------
1173 1176
1174 1177 Used to access web-based Mercurial repositories through a HTTP
1175 1178 proxy.
1176 1179
1177 1180 ``host``
1178 1181 Host name and (optional) port of the proxy server, for example
1179 1182 "myproxy:8000".
1180 1183
1181 1184 ``no``
1182 1185 Optional. Comma-separated list of host names that should bypass
1183 1186 the proxy.
1184 1187
1185 1188 ``passwd``
1186 1189 Optional. Password to authenticate with at the proxy server.
1187 1190
1188 1191 ``user``
1189 1192 Optional. User name to authenticate with at the proxy server.
1190 1193
1191 1194 ``always``
1192 1195 Optional. Always use the proxy, even for localhost and any entries
1193 1196 in ``http_proxy.no``. (default: False)
1194 1197
1195 1198 ``merge``
1196 1199 ---------
1197 1200
1198 1201 This section specifies behavior during merges and updates.
1199 1202
1200 1203 ``checkignored``
1201 1204 Controls behavior when an ignored file on disk has the same name as a tracked
1202 1205 file in the changeset being merged or updated to, and has different
1203 1206 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1204 1207 abort on such files. With ``warn``, warn on such files and back them up as
1205 1208 ``.orig``. With ``ignore``, don't print a warning and back them up as
1206 1209 ``.orig``. (default: ``abort``)
1207 1210
1208 1211 ``checkunknown``
1209 1212 Controls behavior when an unknown file that isn't ignored has the same name
1210 1213 as a tracked file in the changeset being merged or updated to, and has
1211 1214 different contents. Similar to ``merge.checkignored``, except for files that
1212 1215 are not ignored. (default: ``abort``)
1213 1216
1214 1217 ``merge-patterns``
1215 1218 ------------------
1216 1219
1217 1220 This section specifies merge tools to associate with particular file
1218 1221 patterns. Tools matched here will take precedence over the default
1219 1222 merge tool. Patterns are globs by default, rooted at the repository
1220 1223 root.
1221 1224
1222 1225 Example::
1223 1226
1224 1227 [merge-patterns]
1225 1228 **.c = kdiff3
1226 1229 **.jpg = myimgmerge
1227 1230
1228 1231 ``merge-tools``
1229 1232 ---------------
1230 1233
1231 1234 This section configures external merge tools to use for file-level
1232 1235 merges. This section has likely been preconfigured at install time.
1233 1236 Use :hg:`config merge-tools` to check the existing configuration.
1234 1237 Also see :hg:`help merge-tools` for more details.
1235 1238
1236 1239 Example ``~/.hgrc``::
1237 1240
1238 1241 [merge-tools]
1239 1242 # Override stock tool location
1240 1243 kdiff3.executable = ~/bin/kdiff3
1241 1244 # Specify command line
1242 1245 kdiff3.args = $base $local $other -o $output
1243 1246 # Give higher priority
1244 1247 kdiff3.priority = 1
1245 1248
1246 1249 # Changing the priority of preconfigured tool
1247 1250 meld.priority = 0
1248 1251
1249 1252 # Disable a preconfigured tool
1250 1253 vimdiff.disabled = yes
1251 1254
1252 1255 # Define new tool
1253 1256 myHtmlTool.args = -m $local $other $base $output
1254 1257 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1255 1258 myHtmlTool.priority = 1
1256 1259
1257 1260 Supported arguments:
1258 1261
1259 1262 ``priority``
1260 1263 The priority in which to evaluate this tool.
1261 1264 (default: 0)
1262 1265
1263 1266 ``executable``
1264 1267 Either just the name of the executable or its pathname.
1265 1268
1266 1269 .. container:: windows
1267 1270
1268 1271 On Windows, the path can use environment variables with ${ProgramFiles}
1269 1272 syntax.
1270 1273
1271 1274 (default: the tool name)
1272 1275
1273 1276 ``args``
1274 1277 The arguments to pass to the tool executable. You can refer to the
1275 1278 files being merged as well as the output file through these
1276 1279 variables: ``$base``, ``$local``, ``$other``, ``$output``. The meaning
1277 1280 of ``$local`` and ``$other`` can vary depending on which action is being
1278 1281 performed. During and update or merge, ``$local`` represents the original
1279 1282 state of the file, while ``$other`` represents the commit you are updating
1280 1283 to or the commit you are merging with. During a rebase ``$local``
1281 1284 represents the destination of the rebase, and ``$other`` represents the
1282 1285 commit being rebased.
1283 1286 (default: ``$local $base $other``)
1284 1287
1285 1288 ``premerge``
1286 1289 Attempt to run internal non-interactive 3-way merge tool before
1287 1290 launching external tool. Options are ``true``, ``false``, ``keep`` or
1288 1291 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1289 1292 premerge fails. The ``keep-merge3`` will do the same but include information
1290 1293 about the base of the merge in the marker (see internal :merge3 in
1291 1294 :hg:`help merge-tools`).
1292 1295 (default: True)
1293 1296
1294 1297 ``binary``
1295 1298 This tool can merge binary files. (default: False, unless tool
1296 1299 was selected by file pattern match)
1297 1300
1298 1301 ``symlink``
1299 1302 This tool can merge symlinks. (default: False)
1300 1303
1301 1304 ``check``
1302 1305 A list of merge success-checking options:
1303 1306
1304 1307 ``changed``
1305 1308 Ask whether merge was successful when the merged file shows no changes.
1306 1309 ``conflicts``
1307 1310 Check whether there are conflicts even though the tool reported success.
1308 1311 ``prompt``
1309 1312 Always prompt for merge success, regardless of success reported by tool.
1310 1313
1311 1314 ``fixeol``
1312 1315 Attempt to fix up EOL changes caused by the merge tool.
1313 1316 (default: False)
1314 1317
1315 1318 ``gui``
1316 1319 This tool requires a graphical interface to run. (default: False)
1317 1320
1318 1321 .. container:: windows
1319 1322
1320 1323 ``regkey``
1321 1324 Windows registry key which describes install location of this
1322 1325 tool. Mercurial will search for this key first under
1323 1326 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1324 1327 (default: None)
1325 1328
1326 1329 ``regkeyalt``
1327 1330 An alternate Windows registry key to try if the first key is not
1328 1331 found. The alternate key uses the same ``regname`` and ``regappend``
1329 1332 semantics of the primary key. The most common use for this key
1330 1333 is to search for 32bit applications on 64bit operating systems.
1331 1334 (default: None)
1332 1335
1333 1336 ``regname``
1334 1337 Name of value to read from specified registry key.
1335 1338 (default: the unnamed (default) value)
1336 1339
1337 1340 ``regappend``
1338 1341 String to append to the value read from the registry, typically
1339 1342 the executable name of the tool.
1340 1343 (default: None)
1341 1344
1342 1345
1343 1346 ``patch``
1344 1347 ---------
1345 1348
1346 1349 Settings used when applying patches, for instance through the 'import'
1347 1350 command or with Mercurial Queues extension.
1348 1351
1349 1352 ``eol``
1350 1353 When set to 'strict' patch content and patched files end of lines
1351 1354 are preserved. When set to ``lf`` or ``crlf``, both files end of
1352 1355 lines are ignored when patching and the result line endings are
1353 1356 normalized to either LF (Unix) or CRLF (Windows). When set to
1354 1357 ``auto``, end of lines are again ignored while patching but line
1355 1358 endings in patched files are normalized to their original setting
1356 1359 on a per-file basis. If target file does not exist or has no end
1357 1360 of line, patch line endings are preserved.
1358 1361 (default: strict)
1359 1362
1360 1363 ``fuzz``
1361 1364 The number of lines of 'fuzz' to allow when applying patches. This
1362 1365 controls how much context the patcher is allowed to ignore when
1363 1366 trying to apply a patch.
1364 1367 (default: 2)
1365 1368
1366 1369 ``paths``
1367 1370 ---------
1368 1371
1369 1372 Assigns symbolic names and behavior to repositories.
1370 1373
1371 1374 Options are symbolic names defining the URL or directory that is the
1372 1375 location of the repository. Example::
1373 1376
1374 1377 [paths]
1375 1378 my_server = https://example.com/my_repo
1376 1379 local_path = /home/me/repo
1377 1380
1378 1381 These symbolic names can be used from the command line. To pull
1379 1382 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1380 1383 :hg:`push local_path`.
1381 1384
1382 1385 Options containing colons (``:``) denote sub-options that can influence
1383 1386 behavior for that specific path. Example::
1384 1387
1385 1388 [paths]
1386 1389 my_server = https://example.com/my_path
1387 1390 my_server:pushurl = ssh://example.com/my_path
1388 1391
1389 1392 The following sub-options can be defined:
1390 1393
1391 1394 ``pushurl``
1392 1395 The URL to use for push operations. If not defined, the location
1393 1396 defined by the path's main entry is used.
1394 1397
1395 1398 ``pushrev``
1396 1399 A revset defining which revisions to push by default.
1397 1400
1398 1401 When :hg:`push` is executed without a ``-r`` argument, the revset
1399 1402 defined by this sub-option is evaluated to determine what to push.
1400 1403
1401 1404 For example, a value of ``.`` will push the working directory's
1402 1405 revision by default.
1403 1406
1404 1407 Revsets specifying bookmarks will not result in the bookmark being
1405 1408 pushed.
1406 1409
1407 1410 The following special named paths exist:
1408 1411
1409 1412 ``default``
1410 1413 The URL or directory to use when no source or remote is specified.
1411 1414
1412 1415 :hg:`clone` will automatically define this path to the location the
1413 1416 repository was cloned from.
1414 1417
1415 1418 ``default-push``
1416 1419 (deprecated) The URL or directory for the default :hg:`push` location.
1417 1420 ``default:pushurl`` should be used instead.
1418 1421
1419 1422 ``phases``
1420 1423 ----------
1421 1424
1422 1425 Specifies default handling of phases. See :hg:`help phases` for more
1423 1426 information about working with phases.
1424 1427
1425 1428 ``publish``
1426 1429 Controls draft phase behavior when working as a server. When true,
1427 1430 pushed changesets are set to public in both client and server and
1428 1431 pulled or cloned changesets are set to public in the client.
1429 1432 (default: True)
1430 1433
1431 1434 ``new-commit``
1432 1435 Phase of newly-created commits.
1433 1436 (default: draft)
1434 1437
1435 1438 ``checksubrepos``
1436 1439 Check the phase of the current revision of each subrepository. Allowed
1437 1440 values are "ignore", "follow" and "abort". For settings other than
1438 1441 "ignore", the phase of the current revision of each subrepository is
1439 1442 checked before committing the parent repository. If any of those phases is
1440 1443 greater than the phase of the parent repository (e.g. if a subrepo is in a
1441 1444 "secret" phase while the parent repo is in "draft" phase), the commit is
1442 1445 either aborted (if checksubrepos is set to "abort") or the higher phase is
1443 1446 used for the parent repository commit (if set to "follow").
1444 1447 (default: follow)
1445 1448
1446 1449
1447 1450 ``profiling``
1448 1451 -------------
1449 1452
1450 1453 Specifies profiling type, format, and file output. Two profilers are
1451 1454 supported: an instrumenting profiler (named ``ls``), and a sampling
1452 1455 profiler (named ``stat``).
1453 1456
1454 1457 In this section description, 'profiling data' stands for the raw data
1455 1458 collected during profiling, while 'profiling report' stands for a
1456 1459 statistical text report generated from the profiling data. The
1457 1460 profiling is done using lsprof.
1458 1461
1459 1462 ``enabled``
1460 1463 Enable the profiler.
1461 1464 (default: false)
1462 1465
1463 1466 This is equivalent to passing ``--profile`` on the command line.
1464 1467
1465 1468 ``type``
1466 1469 The type of profiler to use.
1467 1470 (default: stat)
1468 1471
1469 1472 ``ls``
1470 1473 Use Python's built-in instrumenting profiler. This profiler
1471 1474 works on all platforms, but each line number it reports is the
1472 1475 first line of a function. This restriction makes it difficult to
1473 1476 identify the expensive parts of a non-trivial function.
1474 1477 ``stat``
1475 1478 Use a statistical profiler, statprof. This profiler is most
1476 1479 useful for profiling commands that run for longer than about 0.1
1477 1480 seconds.
1478 1481
1479 1482 ``format``
1480 1483 Profiling format. Specific to the ``ls`` instrumenting profiler.
1481 1484 (default: text)
1482 1485
1483 1486 ``text``
1484 1487 Generate a profiling report. When saving to a file, it should be
1485 1488 noted that only the report is saved, and the profiling data is
1486 1489 not kept.
1487 1490 ``kcachegrind``
1488 1491 Format profiling data for kcachegrind use: when saving to a
1489 1492 file, the generated file can directly be loaded into
1490 1493 kcachegrind.
1491 1494
1492 1495 ``statformat``
1493 1496 Profiling format for the ``stat`` profiler.
1494 1497 (default: hotpath)
1495 1498
1496 1499 ``hotpath``
1497 1500 Show a tree-based display containing the hot path of execution (where
1498 1501 most time was spent).
1499 1502 ``bymethod``
1500 1503 Show a table of methods ordered by how frequently they are active.
1501 1504 ``byline``
1502 1505 Show a table of lines in files ordered by how frequently they are active.
1503 1506 ``json``
1504 1507 Render profiling data as JSON.
1505 1508
1506 1509 ``frequency``
1507 1510 Sampling frequency. Specific to the ``stat`` sampling profiler.
1508 1511 (default: 1000)
1509 1512
1510 1513 ``output``
1511 1514 File path where profiling data or report should be saved. If the
1512 1515 file exists, it is replaced. (default: None, data is printed on
1513 1516 stderr)
1514 1517
1515 1518 ``sort``
1516 1519 Sort field. Specific to the ``ls`` instrumenting profiler.
1517 1520 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1518 1521 ``inlinetime``.
1519 1522 (default: inlinetime)
1520 1523
1521 1524 ``limit``
1522 1525 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1523 1526 (default: 30)
1524 1527
1525 1528 ``nested``
1526 1529 Show at most this number of lines of drill-down info after each main entry.
1527 1530 This can help explain the difference between Total and Inline.
1528 1531 Specific to the ``ls`` instrumenting profiler.
1529 1532 (default: 5)
1530 1533
1531 1534 ``progress``
1532 1535 ------------
1533 1536
1534 1537 Mercurial commands can draw progress bars that are as informative as
1535 1538 possible. Some progress bars only offer indeterminate information, while others
1536 1539 have a definite end point.
1537 1540
1538 1541 ``delay``
1539 1542 Number of seconds (float) before showing the progress bar. (default: 3)
1540 1543
1541 1544 ``changedelay``
1542 1545 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1543 1546 that value will be used instead. (default: 1)
1544 1547
1545 1548 ``refresh``
1546 1549 Time in seconds between refreshes of the progress bar. (default: 0.1)
1547 1550
1548 1551 ``format``
1549 1552 Format of the progress bar.
1550 1553
1551 1554 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1552 1555 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1553 1556 last 20 characters of the item, but this can be changed by adding either
1554 1557 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1555 1558 first num characters.
1556 1559
1557 1560 (default: topic bar number estimate)
1558 1561
1559 1562 ``width``
1560 1563 If set, the maximum width of the progress information (that is, min(width,
1561 1564 term width) will be used).
1562 1565
1563 1566 ``clear-complete``
1564 1567 Clear the progress bar after it's done. (default: True)
1565 1568
1566 1569 ``disable``
1567 1570 If true, don't show a progress bar.
1568 1571
1569 1572 ``assume-tty``
1570 1573 If true, ALWAYS show a progress bar, unless disable is given.
1571 1574
1572 1575 ``rebase``
1573 1576 ----------
1574 1577
1575 1578 ``allowdivergence``
1576 1579 Default to False, when True allow creating divergence when performing
1577 1580 rebase of obsolete changesets.
1578 1581
1579 1582 ``revsetalias``
1580 1583 ---------------
1581 1584
1582 1585 Alias definitions for revsets. See :hg:`help revsets` for details.
1583 1586
1584 1587 ``server``
1585 1588 ----------
1586 1589
1587 1590 Controls generic server settings.
1588 1591
1589 1592 ``compressionengines``
1590 1593 List of compression engines and their relative priority to advertise
1591 1594 to clients.
1592 1595
1593 1596 The order of compression engines determines their priority, the first
1594 1597 having the highest priority. If a compression engine is not listed
1595 1598 here, it won't be advertised to clients.
1596 1599
1597 1600 If not set (the default), built-in defaults are used. Run
1598 1601 :hg:`debuginstall` to list available compression engines and their
1599 1602 default wire protocol priority.
1600 1603
1601 1604 Older Mercurial clients only support zlib compression and this setting
1602 1605 has no effect for legacy clients.
1603 1606
1604 1607 ``uncompressed``
1605 1608 Whether to allow clients to clone a repository using the
1606 1609 uncompressed streaming protocol. This transfers about 40% more
1607 1610 data than a regular clone, but uses less memory and CPU on both
1608 1611 server and client. Over a LAN (100 Mbps or better) or a very fast
1609 1612 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1610 1613 regular clone. Over most WAN connections (anything slower than
1611 1614 about 6 Mbps), uncompressed streaming is slower, because of the
1612 1615 extra data transfer overhead. This mode will also temporarily hold
1613 1616 the write lock while determining what data to transfer.
1614 1617 (default: True)
1615 1618
1616 1619 ``preferuncompressed``
1617 1620 When set, clients will try to use the uncompressed streaming
1618 1621 protocol. (default: False)
1619 1622
1620 1623 ``validate``
1621 1624 Whether to validate the completeness of pushed changesets by
1622 1625 checking that all new file revisions specified in manifests are
1623 1626 present. (default: False)
1624 1627
1625 1628 ``maxhttpheaderlen``
1626 1629 Instruct HTTP clients not to send request headers longer than this
1627 1630 many bytes. (default: 1024)
1628 1631
1629 1632 ``bundle1``
1630 1633 Whether to allow clients to push and pull using the legacy bundle1
1631 1634 exchange format. (default: True)
1632 1635
1633 1636 ``bundle1gd``
1634 1637 Like ``bundle1`` but only used if the repository is using the
1635 1638 *generaldelta* storage format. (default: True)
1636 1639
1637 1640 ``bundle1.push``
1638 1641 Whether to allow clients to push using the legacy bundle1 exchange
1639 1642 format. (default: True)
1640 1643
1641 1644 ``bundle1gd.push``
1642 1645 Like ``bundle1.push`` but only used if the repository is using the
1643 1646 *generaldelta* storage format. (default: True)
1644 1647
1645 1648 ``bundle1.pull``
1646 1649 Whether to allow clients to pull using the legacy bundle1 exchange
1647 1650 format. (default: True)
1648 1651
1649 1652 ``bundle1gd.pull``
1650 1653 Like ``bundle1.pull`` but only used if the repository is using the
1651 1654 *generaldelta* storage format. (default: True)
1652 1655
1653 1656 Large repositories using the *generaldelta* storage format should
1654 1657 consider setting this option because converting *generaldelta*
1655 1658 repositories to the exchange format required by the bundle1 data
1656 1659 format can consume a lot of CPU.
1657 1660
1658 1661 ``zliblevel``
1659 1662 Integer between ``-1`` and ``9`` that controls the zlib compression level
1660 1663 for wire protocol commands that send zlib compressed output (notably the
1661 1664 commands that send repository history data).
1662 1665
1663 1666 The default (``-1``) uses the default zlib compression level, which is
1664 1667 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
1665 1668 maximum compression.
1666 1669
1667 1670 Setting this option allows server operators to make trade-offs between
1668 1671 bandwidth and CPU used. Lowering the compression lowers CPU utilization
1669 1672 but sends more bytes to clients.
1670 1673
1671 1674 This option only impacts the HTTP server.
1672 1675
1673 1676 ``zstdlevel``
1674 1677 Integer between ``1`` and ``22`` that controls the zstd compression level
1675 1678 for wire protocol commands. ``1`` is the minimal amount of compression and
1676 1679 ``22`` is the highest amount of compression.
1677 1680
1678 1681 The default (``3``) should be significantly faster than zlib while likely
1679 1682 delivering better compression ratios.
1680 1683
1681 1684 This option only impacts the HTTP server.
1682 1685
1683 1686 See also ``server.zliblevel``.
1684 1687
1685 1688 ``smtp``
1686 1689 --------
1687 1690
1688 1691 Configuration for extensions that need to send email messages.
1689 1692
1690 1693 ``host``
1691 1694 Host name of mail server, e.g. "mail.example.com".
1692 1695
1693 1696 ``port``
1694 1697 Optional. Port to connect to on mail server. (default: 465 if
1695 1698 ``tls`` is smtps; 25 otherwise)
1696 1699
1697 1700 ``tls``
1698 1701 Optional. Method to enable TLS when connecting to mail server: starttls,
1699 1702 smtps or none. (default: none)
1700 1703
1701 1704 ``username``
1702 1705 Optional. User name for authenticating with the SMTP server.
1703 1706 (default: None)
1704 1707
1705 1708 ``password``
1706 1709 Optional. Password for authenticating with the SMTP server. If not
1707 1710 specified, interactive sessions will prompt the user for a
1708 1711 password; non-interactive sessions will fail. (default: None)
1709 1712
1710 1713 ``local_hostname``
1711 1714 Optional. The hostname that the sender can use to identify
1712 1715 itself to the MTA.
1713 1716
1714 1717
1715 1718 ``subpaths``
1716 1719 ------------
1717 1720
1718 1721 Subrepository source URLs can go stale if a remote server changes name
1719 1722 or becomes temporarily unavailable. This section lets you define
1720 1723 rewrite rules of the form::
1721 1724
1722 1725 <pattern> = <replacement>
1723 1726
1724 1727 where ``pattern`` is a regular expression matching a subrepository
1725 1728 source URL and ``replacement`` is the replacement string used to
1726 1729 rewrite it. Groups can be matched in ``pattern`` and referenced in
1727 1730 ``replacements``. For instance::
1728 1731
1729 1732 http://server/(.*)-hg/ = http://hg.server/\1/
1730 1733
1731 1734 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
1732 1735
1733 1736 Relative subrepository paths are first made absolute, and the
1734 1737 rewrite rules are then applied on the full (absolute) path. If ``pattern``
1735 1738 doesn't match the full path, an attempt is made to apply it on the
1736 1739 relative path alone. The rules are applied in definition order.
1737 1740
1738 1741 ``templatealias``
1739 1742 -----------------
1740 1743
1741 1744 Alias definitions for templates. See :hg:`help templates` for details.
1742 1745
1743 1746 ``templates``
1744 1747 -------------
1745 1748
1746 1749 Use the ``[templates]`` section to define template strings.
1747 1750 See :hg:`help templates` for details.
1748 1751
1749 1752 ``trusted``
1750 1753 -----------
1751 1754
1752 1755 Mercurial will not use the settings in the
1753 1756 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
1754 1757 user or to a trusted group, as various hgrc features allow arbitrary
1755 1758 commands to be run. This issue is often encountered when configuring
1756 1759 hooks or extensions for shared repositories or servers. However,
1757 1760 the web interface will use some safe settings from the ``[web]``
1758 1761 section.
1759 1762
1760 1763 This section specifies what users and groups are trusted. The
1761 1764 current user is always trusted. To trust everybody, list a user or a
1762 1765 group with name ``*``. These settings must be placed in an
1763 1766 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
1764 1767 user or service running Mercurial.
1765 1768
1766 1769 ``users``
1767 1770 Comma-separated list of trusted users.
1768 1771
1769 1772 ``groups``
1770 1773 Comma-separated list of trusted groups.
1771 1774
1772 1775
1773 1776 ``ui``
1774 1777 ------
1775 1778
1776 1779 User interface controls.
1777 1780
1778 1781 ``archivemeta``
1779 1782 Whether to include the .hg_archival.txt file containing meta data
1780 1783 (hashes for the repository base and for tip) in archives created
1781 1784 by the :hg:`archive` command or downloaded via hgweb.
1782 1785 (default: True)
1783 1786
1784 1787 ``askusername``
1785 1788 Whether to prompt for a username when committing. If True, and
1786 1789 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
1787 1790 be prompted to enter a username. If no username is entered, the
1788 1791 default ``USER@HOST`` is used instead.
1789 1792 (default: False)
1790 1793
1791 1794 ``clonebundles``
1792 1795 Whether the "clone bundles" feature is enabled.
1793 1796
1794 1797 When enabled, :hg:`clone` may download and apply a server-advertised
1795 1798 bundle file from a URL instead of using the normal exchange mechanism.
1796 1799
1797 1800 This can likely result in faster and more reliable clones.
1798 1801
1799 1802 (default: True)
1800 1803
1801 1804 ``clonebundlefallback``
1802 1805 Whether failure to apply an advertised "clone bundle" from a server
1803 1806 should result in fallback to a regular clone.
1804 1807
1805 1808 This is disabled by default because servers advertising "clone
1806 1809 bundles" often do so to reduce server load. If advertised bundles
1807 1810 start mass failing and clients automatically fall back to a regular
1808 1811 clone, this would add significant and unexpected load to the server
1809 1812 since the server is expecting clone operations to be offloaded to
1810 1813 pre-generated bundles. Failing fast (the default behavior) ensures
1811 1814 clients don't overwhelm the server when "clone bundle" application
1812 1815 fails.
1813 1816
1814 1817 (default: False)
1815 1818
1816 1819 ``clonebundleprefers``
1817 1820 Defines preferences for which "clone bundles" to use.
1818 1821
1819 1822 Servers advertising "clone bundles" may advertise multiple available
1820 1823 bundles. Each bundle may have different attributes, such as the bundle
1821 1824 type and compression format. This option is used to prefer a particular
1822 1825 bundle over another.
1823 1826
1824 1827 The following keys are defined by Mercurial:
1825 1828
1826 1829 BUNDLESPEC
1827 1830 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
1828 1831 e.g. ``gzip-v2`` or ``bzip2-v1``.
1829 1832
1830 1833 COMPRESSION
1831 1834 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
1832 1835
1833 1836 Server operators may define custom keys.
1834 1837
1835 1838 Example values: ``COMPRESSION=bzip2``,
1836 1839 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
1837 1840
1838 1841 By default, the first bundle advertised by the server is used.
1839 1842
1840 1843 ``color``
1841 1844 String: when to use to colorize output. possible value are auto, always,
1842 1845 never, or debug (default: never). 'auto' will use color whenever it seems
1843 1846 possible. See :hg:`help color` for details.
1844 1847
1845 1848 (in addition a boolean can be used in place always/never)
1846 1849
1847 1850 ``commitsubrepos``
1848 1851 Whether to commit modified subrepositories when committing the
1849 1852 parent repository. If False and one subrepository has uncommitted
1850 1853 changes, abort the commit.
1851 1854 (default: False)
1852 1855
1853 1856 ``debug``
1854 1857 Print debugging information. (default: False)
1855 1858
1856 1859 ``editor``
1857 1860 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
1858 1861
1859 1862 ``fallbackencoding``
1860 1863 Encoding to try if it's not possible to decode the changelog using
1861 1864 UTF-8. (default: ISO-8859-1)
1862 1865
1863 1866 ``graphnodetemplate``
1864 1867 The template used to print changeset nodes in an ASCII revision graph.
1865 1868 (default: ``{graphnode}``)
1866 1869
1867 1870 ``ignore``
1868 1871 A file to read per-user ignore patterns from. This file should be
1869 1872 in the same format as a repository-wide .hgignore file. Filenames
1870 1873 are relative to the repository root. This option supports hook syntax,
1871 1874 so if you want to specify multiple ignore files, you can do so by
1872 1875 setting something like ``ignore.other = ~/.hgignore2``. For details
1873 1876 of the ignore file format, see the ``hgignore(5)`` man page.
1874 1877
1875 1878 ``interactive``
1876 1879 Allow to prompt the user. (default: True)
1877 1880
1878 1881 ``interface``
1879 1882 Select the default interface for interactive features (default: text).
1880 1883 Possible values are 'text' and 'curses'.
1881 1884
1882 1885 ``interface.chunkselector``
1883 1886 Select the interface for change recording (e.g. :hg:`commit -i`).
1884 1887 Possible values are 'text' and 'curses'.
1885 1888 This config overrides the interface specified by ui.interface.
1886 1889
1887 1890 ``logtemplate``
1888 1891 Template string for commands that print changesets.
1889 1892
1890 1893 ``merge``
1891 1894 The conflict resolution program to use during a manual merge.
1892 1895 For more information on merge tools see :hg:`help merge-tools`.
1893 1896 For configuring merge tools see the ``[merge-tools]`` section.
1894 1897
1895 1898 ``mergemarkers``
1896 1899 Sets the merge conflict marker label styling. The ``detailed``
1897 1900 style uses the ``mergemarkertemplate`` setting to style the labels.
1898 1901 The ``basic`` style just uses 'local' and 'other' as the marker label.
1899 1902 One of ``basic`` or ``detailed``.
1900 1903 (default: ``basic``)
1901 1904
1902 1905 ``mergemarkertemplate``
1903 1906 The template used to print the commit description next to each conflict
1904 1907 marker during merge conflicts. See :hg:`help templates` for the template
1905 1908 format.
1906 1909
1907 1910 Defaults to showing the hash, tags, branches, bookmarks, author, and
1908 1911 the first line of the commit description.
1909 1912
1910 1913 If you use non-ASCII characters in names for tags, branches, bookmarks,
1911 1914 authors, and/or commit descriptions, you must pay attention to encodings of
1912 1915 managed files. At template expansion, non-ASCII characters use the encoding
1913 1916 specified by the ``--encoding`` global option, ``HGENCODING`` or other
1914 1917 environment variables that govern your locale. If the encoding of the merge
1915 1918 markers is different from the encoding of the merged files,
1916 1919 serious problems may occur.
1917 1920
1918 1921 ``origbackuppath``
1919 1922 The path to a directory used to store generated .orig files. If the path is
1920 1923 not a directory, one will be created.
1921 1924
1922 1925 ``patch``
1923 1926 An optional external tool that ``hg import`` and some extensions
1924 1927 will use for applying patches. By default Mercurial uses an
1925 1928 internal patch utility. The external tool must work as the common
1926 1929 Unix ``patch`` program. In particular, it must accept a ``-p``
1927 1930 argument to strip patch headers, a ``-d`` argument to specify the
1928 1931 current directory, a file name to patch, and a patch file to take
1929 1932 from stdin.
1930 1933
1931 1934 It is possible to specify a patch tool together with extra
1932 1935 arguments. For example, setting this option to ``patch --merge``
1933 1936 will use the ``patch`` program with its 2-way merge option.
1934 1937
1935 1938 ``portablefilenames``
1936 1939 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
1937 1940 (default: ``warn``)
1938 1941
1939 1942 ``warn``
1940 1943 Print a warning message on POSIX platforms, if a file with a non-portable
1941 1944 filename is added (e.g. a file with a name that can't be created on
1942 1945 Windows because it contains reserved parts like ``AUX``, reserved
1943 1946 characters like ``:``, or would cause a case collision with an existing
1944 1947 file).
1945 1948
1946 1949 ``ignore``
1947 1950 Don't print a warning.
1948 1951
1949 1952 ``abort``
1950 1953 The command is aborted.
1951 1954
1952 1955 ``true``
1953 1956 Alias for ``warn``.
1954 1957
1955 1958 ``false``
1956 1959 Alias for ``ignore``.
1957 1960
1958 1961 .. container:: windows
1959 1962
1960 1963 On Windows, this configuration option is ignored and the command aborted.
1961 1964
1962 1965 ``quiet``
1963 1966 Reduce the amount of output printed.
1964 1967 (default: False)
1965 1968
1966 1969 ``remotecmd``
1967 1970 Remote command to use for clone/push/pull operations.
1968 1971 (default: ``hg``)
1969 1972
1970 1973 ``report_untrusted``
1971 1974 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
1972 1975 trusted user or group.
1973 1976 (default: True)
1974 1977
1975 1978 ``slash``
1976 1979 Display paths using a slash (``/``) as the path separator. This
1977 1980 only makes a difference on systems where the default path
1978 1981 separator is not the slash character (e.g. Windows uses the
1979 1982 backslash character (``\``)).
1980 1983 (default: False)
1981 1984
1982 1985 ``statuscopies``
1983 1986 Display copies in the status command.
1984 1987
1985 1988 ``ssh``
1986 1989 Command to use for SSH connections. (default: ``ssh``)
1987 1990
1988 1991 ``strict``
1989 1992 Require exact command names, instead of allowing unambiguous
1990 1993 abbreviations. (default: False)
1991 1994
1992 1995 ``style``
1993 1996 Name of style to use for command output.
1994 1997
1995 1998 ``supportcontact``
1996 1999 A URL where users should report a Mercurial traceback. Use this if you are a
1997 2000 large organisation with its own Mercurial deployment process and crash
1998 2001 reports should be addressed to your internal support.
1999 2002
2000 2003 ``textwidth``
2001 2004 Maximum width of help text. A longer line generated by ``hg help`` or
2002 2005 ``hg subcommand --help`` will be broken after white space to get this
2003 2006 width or the terminal width, whichever comes first.
2004 2007 A non-positive value will disable this and the terminal width will be
2005 2008 used. (default: 78)
2006 2009
2007 2010 ``timeout``
2008 2011 The timeout used when a lock is held (in seconds), a negative value
2009 2012 means no timeout. (default: 600)
2010 2013
2011 2014 ``traceback``
2012 2015 Mercurial always prints a traceback when an unknown exception
2013 2016 occurs. Setting this to True will make Mercurial print a traceback
2014 2017 on all exceptions, even those recognized by Mercurial (such as
2015 2018 IOError or MemoryError). (default: False)
2016 2019
2017 2020 ``username``
2018 2021 The committer of a changeset created when running "commit".
2019 2022 Typically a person's name and email address, e.g. ``Fred Widget
2020 2023 <fred@example.com>``. Environment variables in the
2021 2024 username are expanded.
2022 2025
2023 2026 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2024 2027 hgrc is empty, e.g. if the system admin set ``username =`` in the
2025 2028 system hgrc, it has to be specified manually or in a different
2026 2029 hgrc file)
2027 2030
2028 2031 ``verbose``
2029 2032 Increase the amount of output printed. (default: False)
2030 2033
2031 2034
2032 2035 ``web``
2033 2036 -------
2034 2037
2035 2038 Web interface configuration. The settings in this section apply to
2036 2039 both the builtin webserver (started by :hg:`serve`) and the script you
2037 2040 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2038 2041 and WSGI).
2039 2042
2040 2043 The Mercurial webserver does no authentication (it does not prompt for
2041 2044 usernames and passwords to validate *who* users are), but it does do
2042 2045 authorization (it grants or denies access for *authenticated users*
2043 2046 based on settings in this section). You must either configure your
2044 2047 webserver to do authentication for you, or disable the authorization
2045 2048 checks.
2046 2049
2047 2050 For a quick setup in a trusted environment, e.g., a private LAN, where
2048 2051 you want it to accept pushes from anybody, you can use the following
2049 2052 command line::
2050 2053
2051 2054 $ hg --config web.allow_push=* --config web.push_ssl=False serve
2052 2055
2053 2056 Note that this will allow anybody to push anything to the server and
2054 2057 that this should not be used for public servers.
2055 2058
2056 2059 The full set of options is:
2057 2060
2058 2061 ``accesslog``
2059 2062 Where to output the access log. (default: stdout)
2060 2063
2061 2064 ``address``
2062 2065 Interface address to bind to. (default: all)
2063 2066
2064 2067 ``allow_archive``
2065 2068 List of archive format (bz2, gz, zip) allowed for downloading.
2066 2069 (default: empty)
2067 2070
2068 2071 ``allowbz2``
2069 2072 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2070 2073 revisions.
2071 2074 (default: False)
2072 2075
2073 2076 ``allowgz``
2074 2077 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2075 2078 revisions.
2076 2079 (default: False)
2077 2080
2078 2081 ``allowpull``
2079 2082 Whether to allow pulling from the repository. (default: True)
2080 2083
2081 2084 ``allow_push``
2082 2085 Whether to allow pushing to the repository. If empty or not set,
2083 2086 pushing is not allowed. If the special value ``*``, any remote
2084 2087 user can push, including unauthenticated users. Otherwise, the
2085 2088 remote user must have been authenticated, and the authenticated
2086 2089 user name must be present in this list. The contents of the
2087 2090 allow_push list are examined after the deny_push list.
2088 2091
2089 2092 ``allow_read``
2090 2093 If the user has not already been denied repository access due to
2091 2094 the contents of deny_read, this list determines whether to grant
2092 2095 repository access to the user. If this list is not empty, and the
2093 2096 user is unauthenticated or not present in the list, then access is
2094 2097 denied for the user. If the list is empty or not set, then access
2095 2098 is permitted to all users by default. Setting allow_read to the
2096 2099 special value ``*`` is equivalent to it not being set (i.e. access
2097 2100 is permitted to all users). The contents of the allow_read list are
2098 2101 examined after the deny_read list.
2099 2102
2100 2103 ``allowzip``
2101 2104 (DEPRECATED) Whether to allow .zip downloading of repository
2102 2105 revisions. This feature creates temporary files.
2103 2106 (default: False)
2104 2107
2105 2108 ``archivesubrepos``
2106 2109 Whether to recurse into subrepositories when archiving.
2107 2110 (default: False)
2108 2111
2109 2112 ``baseurl``
2110 2113 Base URL to use when publishing URLs in other locations, so
2111 2114 third-party tools like email notification hooks can construct
2112 2115 URLs. Example: ``http://hgserver/repos/``.
2113 2116
2114 2117 ``cacerts``
2115 2118 Path to file containing a list of PEM encoded certificate
2116 2119 authority certificates. Environment variables and ``~user``
2117 2120 constructs are expanded in the filename. If specified on the
2118 2121 client, then it will verify the identity of remote HTTPS servers
2119 2122 with these certificates.
2120 2123
2121 2124 To disable SSL verification temporarily, specify ``--insecure`` from
2122 2125 command line.
2123 2126
2124 2127 You can use OpenSSL's CA certificate file if your platform has
2125 2128 one. On most Linux systems this will be
2126 2129 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2127 2130 generate this file manually. The form must be as follows::
2128 2131
2129 2132 -----BEGIN CERTIFICATE-----
2130 2133 ... (certificate in base64 PEM encoding) ...
2131 2134 -----END CERTIFICATE-----
2132 2135 -----BEGIN CERTIFICATE-----
2133 2136 ... (certificate in base64 PEM encoding) ...
2134 2137 -----END CERTIFICATE-----
2135 2138
2136 2139 ``cache``
2137 2140 Whether to support caching in hgweb. (default: True)
2138 2141
2139 2142 ``certificate``
2140 2143 Certificate to use when running :hg:`serve`.
2141 2144
2142 2145 ``collapse``
2143 2146 With ``descend`` enabled, repositories in subdirectories are shown at
2144 2147 a single level alongside repositories in the current path. With
2145 2148 ``collapse`` also enabled, repositories residing at a deeper level than
2146 2149 the current path are grouped behind navigable directory entries that
2147 2150 lead to the locations of these repositories. In effect, this setting
2148 2151 collapses each collection of repositories found within a subdirectory
2149 2152 into a single entry for that subdirectory. (default: False)
2150 2153
2151 2154 ``comparisoncontext``
2152 2155 Number of lines of context to show in side-by-side file comparison. If
2153 2156 negative or the value ``full``, whole files are shown. (default: 5)
2154 2157
2155 2158 This setting can be overridden by a ``context`` request parameter to the
2156 2159 ``comparison`` command, taking the same values.
2157 2160
2158 2161 ``contact``
2159 2162 Name or email address of the person in charge of the repository.
2160 2163 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2161 2164
2162 2165 ``csp``
2163 2166 Send a ``Content-Security-Policy`` HTTP header with this value.
2164 2167
2165 2168 The value may contain a special string ``%nonce%``, which will be replaced
2166 2169 by a randomly-generated one-time use value. If the value contains
2167 2170 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2168 2171 one-time property of the nonce. This nonce will also be inserted into
2169 2172 ``<script>`` elements containing inline JavaScript.
2170 2173
2171 2174 Note: lots of HTML content sent by the server is derived from repository
2172 2175 data. Please consider the potential for malicious repository data to
2173 2176 "inject" itself into generated HTML content as part of your security
2174 2177 threat model.
2175 2178
2176 2179 ``deny_push``
2177 2180 Whether to deny pushing to the repository. If empty or not set,
2178 2181 push is not denied. If the special value ``*``, all remote users are
2179 2182 denied push. Otherwise, unauthenticated users are all denied, and
2180 2183 any authenticated user name present in this list is also denied. The
2181 2184 contents of the deny_push list are examined before the allow_push list.
2182 2185
2183 2186 ``deny_read``
2184 2187 Whether to deny reading/viewing of the repository. If this list is
2185 2188 not empty, unauthenticated users are all denied, and any
2186 2189 authenticated user name present in this list is also denied access to
2187 2190 the repository. If set to the special value ``*``, all remote users
2188 2191 are denied access (rarely needed ;). If deny_read is empty or not set,
2189 2192 the determination of repository access depends on the presence and
2190 2193 content of the allow_read list (see description). If both
2191 2194 deny_read and allow_read are empty or not set, then access is
2192 2195 permitted to all users by default. If the repository is being
2193 2196 served via hgwebdir, denied users will not be able to see it in
2194 2197 the list of repositories. The contents of the deny_read list have
2195 2198 priority over (are examined before) the contents of the allow_read
2196 2199 list.
2197 2200
2198 2201 ``descend``
2199 2202 hgwebdir indexes will not descend into subdirectories. Only repositories
2200 2203 directly in the current path will be shown (other repositories are still
2201 2204 available from the index corresponding to their containing path).
2202 2205
2203 2206 ``description``
2204 2207 Textual description of the repository's purpose or contents.
2205 2208 (default: "unknown")
2206 2209
2207 2210 ``encoding``
2208 2211 Character encoding name. (default: the current locale charset)
2209 2212 Example: "UTF-8".
2210 2213
2211 2214 ``errorlog``
2212 2215 Where to output the error log. (default: stderr)
2213 2216
2214 2217 ``guessmime``
2215 2218 Control MIME types for raw download of file content.
2216 2219 Set to True to let hgweb guess the content type from the file
2217 2220 extension. This will serve HTML files as ``text/html`` and might
2218 2221 allow cross-site scripting attacks when serving untrusted
2219 2222 repositories. (default: False)
2220 2223
2221 2224 ``hidden``
2222 2225 Whether to hide the repository in the hgwebdir index.
2223 2226 (default: False)
2224 2227
2225 2228 ``ipv6``
2226 2229 Whether to use IPv6. (default: False)
2227 2230
2228 2231 ``labels``
2229 2232 List of string *labels* associated with the repository.
2230 2233
2231 2234 Labels are exposed as a template keyword and can be used to customize
2232 2235 output. e.g. the ``index`` template can group or filter repositories
2233 2236 by labels and the ``summary`` template can display additional content
2234 2237 if a specific label is present.
2235 2238
2236 2239 ``logoimg``
2237 2240 File name of the logo image that some templates display on each page.
2238 2241 The file name is relative to ``staticurl``. That is, the full path to
2239 2242 the logo image is "staticurl/logoimg".
2240 2243 If unset, ``hglogo.png`` will be used.
2241 2244
2242 2245 ``logourl``
2243 2246 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2244 2247 will be used.
2245 2248
2246 2249 ``maxchanges``
2247 2250 Maximum number of changes to list on the changelog. (default: 10)
2248 2251
2249 2252 ``maxfiles``
2250 2253 Maximum number of files to list per changeset. (default: 10)
2251 2254
2252 2255 ``maxshortchanges``
2253 2256 Maximum number of changes to list on the shortlog, graph or filelog
2254 2257 pages. (default: 60)
2255 2258
2256 2259 ``name``
2257 2260 Repository name to use in the web interface.
2258 2261 (default: current working directory)
2259 2262
2260 2263 ``port``
2261 2264 Port to listen on. (default: 8000)
2262 2265
2263 2266 ``prefix``
2264 2267 Prefix path to serve from. (default: '' (server root))
2265 2268
2266 2269 ``push_ssl``
2267 2270 Whether to require that inbound pushes be transported over SSL to
2268 2271 prevent password sniffing. (default: True)
2269 2272
2270 2273 ``refreshinterval``
2271 2274 How frequently directory listings re-scan the filesystem for new
2272 2275 repositories, in seconds. This is relevant when wildcards are used
2273 2276 to define paths. Depending on how much filesystem traversal is
2274 2277 required, refreshing may negatively impact performance.
2275 2278
2276 2279 Values less than or equal to 0 always refresh.
2277 2280 (default: 20)
2278 2281
2279 2282 ``staticurl``
2280 2283 Base URL to use for static files. If unset, static files (e.g. the
2281 2284 hgicon.png favicon) will be served by the CGI script itself. Use
2282 2285 this setting to serve them directly with the HTTP server.
2283 2286 Example: ``http://hgserver/static/``.
2284 2287
2285 2288 ``stripes``
2286 2289 How many lines a "zebra stripe" should span in multi-line output.
2287 2290 Set to 0 to disable. (default: 1)
2288 2291
2289 2292 ``style``
2290 2293 Which template map style to use. The available options are the names of
2291 2294 subdirectories in the HTML templates path. (default: ``paper``)
2292 2295 Example: ``monoblue``.
2293 2296
2294 2297 ``templates``
2295 2298 Where to find the HTML templates. The default path to the HTML templates
2296 2299 can be obtained from ``hg debuginstall``.
2297 2300
2298 2301 ``websub``
2299 2302 ----------
2300 2303
2301 2304 Web substitution filter definition. You can use this section to
2302 2305 define a set of regular expression substitution patterns which
2303 2306 let you automatically modify the hgweb server output.
2304 2307
2305 2308 The default hgweb templates only apply these substitution patterns
2306 2309 on the revision description fields. You can apply them anywhere
2307 2310 you want when you create your own templates by adding calls to the
2308 2311 "websub" filter (usually after calling the "escape" filter).
2309 2312
2310 2313 This can be used, for example, to convert issue references to links
2311 2314 to your issue tracker, or to convert "markdown-like" syntax into
2312 2315 HTML (see the examples below).
2313 2316
2314 2317 Each entry in this section names a substitution filter.
2315 2318 The value of each entry defines the substitution expression itself.
2316 2319 The websub expressions follow the old interhg extension syntax,
2317 2320 which in turn imitates the Unix sed replacement syntax::
2318 2321
2319 2322 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2320 2323
2321 2324 You can use any separator other than "/". The final "i" is optional
2322 2325 and indicates that the search must be case insensitive.
2323 2326
2324 2327 Examples::
2325 2328
2326 2329 [websub]
2327 2330 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2328 2331 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2329 2332 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2330 2333
2331 2334 ``worker``
2332 2335 ----------
2333 2336
2334 2337 Parallel master/worker configuration. We currently perform working
2335 2338 directory updates in parallel on Unix-like systems, which greatly
2336 2339 helps performance.
2337 2340
2338 2341 ``numcpus``
2339 2342 Number of CPUs to use for parallel operations. A zero or
2340 2343 negative value is treated as ``use the default``.
2341 2344 (default: 4 or the number of CPUs on the system, whichever is larger)
2342 2345
2343 2346 ``backgroundclose``
2344 2347 Whether to enable closing file handles on background threads during certain
2345 2348 operations. Some platforms aren't very efficient at closing file
2346 2349 handles that have been written or appended to. By performing file closing
2347 2350 on background threads, file write rate can increase substantially.
2348 2351 (default: true on Windows, false elsewhere)
2349 2352
2350 2353 ``backgroundcloseminfilecount``
2351 2354 Minimum number of files required to trigger background file closing.
2352 2355 Operations not writing this many files won't start background close
2353 2356 threads.
2354 2357 (default: 2048)
2355 2358
2356 2359 ``backgroundclosemaxqueue``
2357 2360 The maximum number of opened file handles waiting to be closed in the
2358 2361 background. This option only has an effect if ``backgroundclose`` is
2359 2362 enabled.
2360 2363 (default: 384)
2361 2364
2362 2365 ``backgroundclosethreadcount``
2363 2366 Number of threads to process background file closes. Only relevant if
2364 2367 ``backgroundclose`` is enabled.
2365 2368 (default: 4)
@@ -1,266 +1,267
1 1 # hook.py - hook support for mercurial
2 2 #
3 3 # Copyright 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
8 8 from __future__ import absolute_import
9 9
10 10 import os
11 11 import sys
12 12
13 13 from .i18n import _
14 14 from . import (
15 15 demandimport,
16 16 error,
17 17 extensions,
18 18 pycompat,
19 19 util,
20 20 )
21 21
22 22 def _pythonhook(ui, repo, htype, hname, funcname, args, throw):
23 23 '''call python hook. hook is callable object, looked up as
24 24 name in python module. if callable returns "true", hook
25 25 fails, else passes. if hook raises exception, treated as
26 26 hook failure. exception propagates if throw is "true".
27 27
28 28 reason for "true" meaning "hook failed" is so that
29 29 unmodified commands (e.g. mercurial.commands.update) can
30 30 be run as hooks without wrappers to convert return values.'''
31 31
32 32 if callable(funcname):
33 33 obj = funcname
34 34 funcname = obj.__module__ + "." + obj.__name__
35 35 else:
36 36 d = funcname.rfind('.')
37 37 if d == -1:
38 38 raise error.HookLoadError(
39 39 _('%s hook is invalid: "%s" not in a module')
40 40 % (hname, funcname))
41 41 modname = funcname[:d]
42 42 oldpaths = sys.path
43 43 if util.mainfrozen():
44 44 # binary installs require sys.path manipulation
45 45 modpath, modfile = os.path.split(modname)
46 46 if modpath and modfile:
47 47 sys.path = sys.path[:] + [modpath]
48 48 modname = modfile
49 49 with demandimport.deactivated():
50 50 try:
51 51 obj = __import__(modname)
52 52 except (ImportError, SyntaxError):
53 53 e1 = sys.exc_info()
54 54 try:
55 55 # extensions are loaded with hgext_ prefix
56 56 obj = __import__("hgext_%s" % modname)
57 57 except (ImportError, SyntaxError):
58 58 e2 = sys.exc_info()
59 59 if ui.tracebackflag:
60 60 ui.warn(_('exception from first failed import '
61 61 'attempt:\n'))
62 62 ui.traceback(e1)
63 63 if ui.tracebackflag:
64 64 ui.warn(_('exception from second failed import '
65 65 'attempt:\n'))
66 66 ui.traceback(e2)
67 67
68 68 if not ui.tracebackflag:
69 69 tracebackhint = _(
70 70 'run with --traceback for stack trace')
71 71 else:
72 72 tracebackhint = None
73 73 raise error.HookLoadError(
74 74 _('%s hook is invalid: import of "%s" failed') %
75 75 (hname, modname), hint=tracebackhint)
76 76 sys.path = oldpaths
77 77 try:
78 78 for p in funcname.split('.')[1:]:
79 79 obj = getattr(obj, p)
80 80 except AttributeError:
81 81 raise error.HookLoadError(
82 82 _('%s hook is invalid: "%s" is not defined')
83 83 % (hname, funcname))
84 84 if not callable(obj):
85 85 raise error.HookLoadError(
86 86 _('%s hook is invalid: "%s" is not callable')
87 87 % (hname, funcname))
88 88
89 89 ui.note(_("calling hook %s: %s\n") % (hname, funcname))
90 90 starttime = util.timer()
91 91
92 92 try:
93 93 r = obj(ui=ui, repo=repo, hooktype=htype, **args)
94 94 except Exception as exc:
95 95 if isinstance(exc, error.Abort):
96 96 ui.warn(_('error: %s hook failed: %s\n') %
97 97 (hname, exc.args[0]))
98 98 else:
99 99 ui.warn(_('error: %s hook raised an exception: '
100 100 '%s\n') % (hname, exc))
101 101 if throw:
102 102 raise
103 103 if not ui.tracebackflag:
104 104 ui.warn(_('(run with --traceback for stack trace)\n'))
105 105 ui.traceback()
106 106 return True, True
107 107 finally:
108 108 duration = util.timer() - starttime
109 109 ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds\n',
110 110 htype, funcname, duration)
111 111 if r:
112 112 if throw:
113 113 raise error.HookAbort(_('%s hook failed') % hname)
114 114 ui.warn(_('warning: %s hook failed\n') % hname)
115 115 return r, False
116 116
117 def _exthook(ui, repo, name, cmd, args, throw):
117 def _exthook(ui, repo, htype, name, cmd, args, throw):
118 118 ui.note(_("running hook %s: %s\n") % (name, cmd))
119 119
120 120 starttime = util.timer()
121 121 env = {}
122 122
123 123 # make in-memory changes visible to external process
124 124 if repo is not None:
125 125 tr = repo.currenttransaction()
126 126 repo.dirstate.write(tr)
127 127 if tr and tr.writepending():
128 128 env['HG_PENDING'] = repo.root
129 env['HG_HOOKTYPE'] = htype
129 130
130 131 for k, v in args.iteritems():
131 132 if callable(v):
132 133 v = v()
133 134 if isinstance(v, dict):
134 135 # make the dictionary element order stable across Python
135 136 # implementations
136 137 v = ('{' +
137 138 ', '.join('%r: %r' % i for i in sorted(v.iteritems())) +
138 139 '}')
139 140 env['HG_' + k.upper()] = v
140 141
141 142 if repo:
142 143 cwd = repo.root
143 144 else:
144 145 cwd = pycompat.getcwd()
145 146 r = ui.system(cmd, environ=env, cwd=cwd, blockedtag='exthook-%s' % (name,))
146 147
147 148 duration = util.timer() - starttime
148 149 ui.log('exthook', 'exthook-%s: %s finished in %0.2f seconds\n',
149 150 name, cmd, duration)
150 151 if r:
151 152 desc, r = util.explainexit(r)
152 153 if throw:
153 154 raise error.HookAbort(_('%s hook %s') % (name, desc))
154 155 ui.warn(_('warning: %s hook %s\n') % (name, desc))
155 156 return r
156 157
157 158 # represent an untrusted hook command
158 159 _fromuntrusted = object()
159 160
160 161 def _allhooks(ui):
161 162 """return a list of (hook-id, cmd) pairs sorted by priority"""
162 163 hooks = _hookitems(ui)
163 164 # Be careful in this section, propagating the real commands from untrusted
164 165 # sources would create a security vulnerability, make sure anything altered
165 166 # in that section uses "_fromuntrusted" as its command.
166 167 untrustedhooks = _hookitems(ui, _untrusted=True)
167 168 for name, value in untrustedhooks.items():
168 169 trustedvalue = hooks.get(name, (None, None, name, _fromuntrusted))
169 170 if value != trustedvalue:
170 171 (lp, lo, lk, lv) = trustedvalue
171 172 hooks[name] = (lp, lo, lk, _fromuntrusted)
172 173 # (end of the security sensitive section)
173 174 return [(k, v) for p, o, k, v in sorted(hooks.values())]
174 175
175 176 def _hookitems(ui, _untrusted=False):
176 177 """return all hooks items ready to be sorted"""
177 178 hooks = {}
178 179 for name, cmd in ui.configitems('hooks', untrusted=_untrusted):
179 180 if not name.startswith('priority'):
180 181 priority = ui.configint('hooks', 'priority.%s' % name, 0)
181 182 hooks[name] = (-priority, len(hooks), name, cmd)
182 183 return hooks
183 184
184 185 _redirect = False
185 186 def redirect(state):
186 187 global _redirect
187 188 _redirect = state
188 189
189 190 def hook(ui, repo, htype, throw=False, **args):
190 191 if not ui.callhooks:
191 192 return False
192 193
193 194 hooks = []
194 195 for hname, cmd in _allhooks(ui):
195 196 if hname.split('.')[0] == htype and cmd:
196 197 hooks.append((hname, cmd))
197 198
198 199 res = runhooks(ui, repo, htype, hooks, throw=throw, **args)
199 200 r = False
200 201 for hname, cmd in hooks:
201 202 r = res[hname][0] or r
202 203 return r
203 204
204 205 def runhooks(ui, repo, htype, hooks, throw=False, **args):
205 206 res = {}
206 207 oldstdout = -1
207 208
208 209 try:
209 210 for hname, cmd in hooks:
210 211 if oldstdout == -1 and _redirect:
211 212 try:
212 213 stdoutno = util.stdout.fileno()
213 214 stderrno = util.stderr.fileno()
214 215 # temporarily redirect stdout to stderr, if possible
215 216 if stdoutno >= 0 and stderrno >= 0:
216 217 util.stdout.flush()
217 218 oldstdout = os.dup(stdoutno)
218 219 os.dup2(stderrno, stdoutno)
219 220 except (OSError, AttributeError):
220 221 # files seem to be bogus, give up on redirecting (WSGI, etc)
221 222 pass
222 223
223 224 if cmd is _fromuntrusted:
224 225 if throw:
225 226 raise error.HookAbort(
226 227 _('untrusted hook %s not executed') % hname,
227 228 hint = _("see 'hg help config.trusted'"))
228 229 ui.warn(_('warning: untrusted hook %s not executed\n') % hname)
229 230 r = 1
230 231 raised = False
231 232 elif callable(cmd):
232 233 r, raised = _pythonhook(ui, repo, htype, hname, cmd, args,
233 234 throw)
234 235 elif cmd.startswith('python:'):
235 236 if cmd.count(':') >= 2:
236 237 path, cmd = cmd[7:].rsplit(':', 1)
237 238 path = util.expandpath(path)
238 239 if repo:
239 240 path = os.path.join(repo.root, path)
240 241 try:
241 242 mod = extensions.loadpath(path, 'hghook.%s' % hname)
242 243 except Exception:
243 244 ui.write(_("loading %s hook failed:\n") % hname)
244 245 raise
245 246 hookfn = getattr(mod, cmd)
246 247 else:
247 248 hookfn = cmd[7:].strip()
248 249 r, raised = _pythonhook(ui, repo, htype, hname, hookfn, args,
249 250 throw)
250 251 else:
251 r = _exthook(ui, repo, hname, cmd, args, throw)
252 r = _exthook(ui, repo, htype, hname, cmd, args, throw)
252 253 raised = False
253 254
254 255 res[hname] = r, raised
255 256
256 257 # The stderr is fully buffered on Windows when connected to a pipe.
257 258 # A forcible flush is required to make small stderr data in the
258 259 # remote side available to the client immediately.
259 260 util.stderr.flush()
260 261 finally:
261 262 if _redirect and oldstdout >= 0:
262 263 util.stdout.flush() # write hook output to stderr fd
263 264 os.dup2(oldstdout, stdoutno)
264 265 os.close(oldstdout)
265 266
266 267 return res
@@ -1,853 +1,853
1 1
2 2 $ cat << EOF >> $HGRCPATH
3 3 > [format]
4 4 > usegeneraldelta=yes
5 5 > EOF
6 6
7 7 Setting up test
8 8
9 9 $ hg init test
10 10 $ cd test
11 11 $ echo 0 > afile
12 12 $ hg add afile
13 13 $ hg commit -m "0.0"
14 14 $ echo 1 >> afile
15 15 $ hg commit -m "0.1"
16 16 $ echo 2 >> afile
17 17 $ hg commit -m "0.2"
18 18 $ echo 3 >> afile
19 19 $ hg commit -m "0.3"
20 20 $ hg update -C 0
21 21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 22 $ echo 1 >> afile
23 23 $ hg commit -m "1.1"
24 24 created new head
25 25 $ echo 2 >> afile
26 26 $ hg commit -m "1.2"
27 27 $ echo "a line" > fred
28 28 $ echo 3 >> afile
29 29 $ hg add fred
30 30 $ hg commit -m "1.3"
31 31 $ hg mv afile adifferentfile
32 32 $ hg commit -m "1.3m"
33 33 $ hg update -C 3
34 34 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
35 35 $ hg mv afile anotherfile
36 36 $ hg commit -m "0.3m"
37 37 $ hg verify
38 38 checking changesets
39 39 checking manifests
40 40 crosschecking files in changesets and manifests
41 41 checking files
42 42 4 files, 9 changesets, 7 total revisions
43 43 $ cd ..
44 44 $ hg init empty
45 45
46 46 Bundle and phase
47 47
48 48 $ hg -R test phase --force --secret 0
49 49 $ hg -R test bundle phase.hg empty
50 50 searching for changes
51 51 no changes found (ignored 9 secret changesets)
52 52 [1]
53 53 $ hg -R test phase --draft -r 'head()'
54 54
55 55 Bundle --all
56 56
57 57 $ hg -R test bundle --all all.hg
58 58 9 changesets found
59 59
60 60 Bundle test to full.hg
61 61
62 62 $ hg -R test bundle full.hg empty
63 63 searching for changes
64 64 9 changesets found
65 65
66 66 Unbundle full.hg in test
67 67
68 68 $ hg -R test unbundle full.hg
69 69 adding changesets
70 70 adding manifests
71 71 adding file changes
72 72 added 0 changesets with 0 changes to 4 files
73 73 (run 'hg update' to get a working copy)
74 74
75 75 Verify empty
76 76
77 77 $ hg -R empty heads
78 78 [1]
79 79 $ hg -R empty verify
80 80 checking changesets
81 81 checking manifests
82 82 crosschecking files in changesets and manifests
83 83 checking files
84 84 0 files, 0 changesets, 0 total revisions
85 85
86 86 Pull full.hg into test (using --cwd)
87 87
88 88 $ hg --cwd test pull ../full.hg
89 89 pulling from ../full.hg
90 90 searching for changes
91 91 no changes found
92 92
93 93 Verify that there are no leaked temporary files after pull (issue2797)
94 94
95 95 $ ls test/.hg | grep .hg10un
96 96 [1]
97 97
98 98 Pull full.hg into empty (using --cwd)
99 99
100 100 $ hg --cwd empty pull ../full.hg
101 101 pulling from ../full.hg
102 102 requesting all changes
103 103 adding changesets
104 104 adding manifests
105 105 adding file changes
106 106 added 9 changesets with 7 changes to 4 files (+1 heads)
107 107 (run 'hg heads' to see heads, 'hg merge' to merge)
108 108
109 109 Rollback empty
110 110
111 111 $ hg -R empty rollback
112 112 repository tip rolled back to revision -1 (undo pull)
113 113
114 114 Pull full.hg into empty again (using --cwd)
115 115
116 116 $ hg --cwd empty pull ../full.hg
117 117 pulling from ../full.hg
118 118 requesting all changes
119 119 adding changesets
120 120 adding manifests
121 121 adding file changes
122 122 added 9 changesets with 7 changes to 4 files (+1 heads)
123 123 (run 'hg heads' to see heads, 'hg merge' to merge)
124 124
125 125 Pull full.hg into test (using -R)
126 126
127 127 $ hg -R test pull full.hg
128 128 pulling from full.hg
129 129 searching for changes
130 130 no changes found
131 131
132 132 Pull full.hg into empty (using -R)
133 133
134 134 $ hg -R empty pull full.hg
135 135 pulling from full.hg
136 136 searching for changes
137 137 no changes found
138 138
139 139 Rollback empty
140 140
141 141 $ hg -R empty rollback
142 142 repository tip rolled back to revision -1 (undo pull)
143 143
144 144 Pull full.hg into empty again (using -R)
145 145
146 146 $ hg -R empty pull full.hg
147 147 pulling from full.hg
148 148 requesting all changes
149 149 adding changesets
150 150 adding manifests
151 151 adding file changes
152 152 added 9 changesets with 7 changes to 4 files (+1 heads)
153 153 (run 'hg heads' to see heads, 'hg merge' to merge)
154 154
155 155 Log -R full.hg in fresh empty
156 156
157 157 $ rm -r empty
158 158 $ hg init empty
159 159 $ cd empty
160 160 $ hg -R bundle://../full.hg log
161 161 changeset: 8:aa35859c02ea
162 162 tag: tip
163 163 parent: 3:eebf5a27f8ca
164 164 user: test
165 165 date: Thu Jan 01 00:00:00 1970 +0000
166 166 summary: 0.3m
167 167
168 168 changeset: 7:a6a34bfa0076
169 169 user: test
170 170 date: Thu Jan 01 00:00:00 1970 +0000
171 171 summary: 1.3m
172 172
173 173 changeset: 6:7373c1169842
174 174 user: test
175 175 date: Thu Jan 01 00:00:00 1970 +0000
176 176 summary: 1.3
177 177
178 178 changeset: 5:1bb50a9436a7
179 179 user: test
180 180 date: Thu Jan 01 00:00:00 1970 +0000
181 181 summary: 1.2
182 182
183 183 changeset: 4:095197eb4973
184 184 parent: 0:f9ee2f85a263
185 185 user: test
186 186 date: Thu Jan 01 00:00:00 1970 +0000
187 187 summary: 1.1
188 188
189 189 changeset: 3:eebf5a27f8ca
190 190 user: test
191 191 date: Thu Jan 01 00:00:00 1970 +0000
192 192 summary: 0.3
193 193
194 194 changeset: 2:e38ba6f5b7e0
195 195 user: test
196 196 date: Thu Jan 01 00:00:00 1970 +0000
197 197 summary: 0.2
198 198
199 199 changeset: 1:34c2bf6b0626
200 200 user: test
201 201 date: Thu Jan 01 00:00:00 1970 +0000
202 202 summary: 0.1
203 203
204 204 changeset: 0:f9ee2f85a263
205 205 user: test
206 206 date: Thu Jan 01 00:00:00 1970 +0000
207 207 summary: 0.0
208 208
209 209 Make sure bundlerepo doesn't leak tempfiles (issue2491)
210 210
211 211 $ ls .hg
212 212 00changelog.i
213 213 cache
214 214 requires
215 215 store
216 216
217 217 Pull ../full.hg into empty (with hook)
218 218
219 219 $ cat >> .hg/hgrc <<EOF
220 220 > [hooks]
221 221 > changegroup = sh -c "printenv.py changegroup"
222 222 > EOF
223 223
224 224 doesn't work (yet ?)
225 225
226 226 hg -R bundle://../full.hg verify
227 227
228 228 $ hg pull bundle://../full.hg
229 229 pulling from bundle:../full.hg
230 230 requesting all changes
231 231 adding changesets
232 232 adding manifests
233 233 adding file changes
234 234 added 9 changesets with 7 changes to 4 files (+1 heads)
235 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=bundle:../full.hg
235 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=bundle:../full.hg
236 236 (run 'hg heads' to see heads, 'hg merge' to merge)
237 237
238 238 Rollback empty
239 239
240 240 $ hg rollback
241 241 repository tip rolled back to revision -1 (undo pull)
242 242 $ cd ..
243 243
244 244 Log -R bundle:empty+full.hg
245 245
246 246 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
247 247 8 7 6 5 4 3 2 1 0
248 248
249 249 Pull full.hg into empty again (using -R; with hook)
250 250
251 251 $ hg -R empty pull full.hg
252 252 pulling from full.hg
253 253 requesting all changes
254 254 adding changesets
255 255 adding manifests
256 256 adding file changes
257 257 added 9 changesets with 7 changes to 4 files (+1 heads)
258 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=bundle:empty+full.hg
258 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=bundle:empty+full.hg
259 259 (run 'hg heads' to see heads, 'hg merge' to merge)
260 260
261 261 Cannot produce streaming clone bundles with "hg bundle"
262 262
263 263 $ hg -R test bundle -t packed1 packed.hg
264 264 abort: packed bundles cannot be produced by "hg bundle"
265 265 (use 'hg debugcreatestreamclonebundle')
266 266 [255]
267 267
268 268 packed1 is produced properly
269 269
270 270 $ hg -R test debugcreatestreamclonebundle packed.hg
271 271 writing 2664 bytes for 6 files
272 272 bundle requirements: generaldelta, revlogv1
273 273
274 274 $ f -B 64 --size --sha1 --hexdump packed.hg
275 275 packed.hg: size=2827, sha1=9d14cb90c66a21462d915ab33656f38b9deed686
276 276 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
277 277 0010: 00 00 00 00 0a 68 00 16 67 65 6e 65 72 61 6c 64 |.....h..generald|
278 278 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
279 279 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
280 280
281 281 $ hg debugbundle --spec packed.hg
282 282 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
283 283
284 284 generaldelta requirement is not listed in stream clone bundles unless used
285 285
286 286 $ hg --config format.usegeneraldelta=false init testnongd
287 287 $ cd testnongd
288 288 $ touch foo
289 289 $ hg -q commit -A -m initial
290 290 $ cd ..
291 291 $ hg -R testnongd debugcreatestreamclonebundle packednongd.hg
292 292 writing 301 bytes for 3 files
293 293 bundle requirements: revlogv1
294 294
295 295 $ f -B 64 --size --sha1 --hexdump packednongd.hg
296 296 packednongd.hg: size=383, sha1=1d9c230238edd5d38907100b729ba72b1831fe6f
297 297 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
298 298 0010: 00 00 00 00 01 2d 00 09 72 65 76 6c 6f 67 76 31 |.....-..revlogv1|
299 299 0020: 00 64 61 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 |.data/foo.i.64..|
300 300 0030: 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
301 301
302 302 $ hg debugbundle --spec packednongd.hg
303 303 none-packed1;requirements%3Drevlogv1
304 304
305 305 Unpacking packed1 bundles with "hg unbundle" isn't allowed
306 306
307 307 $ hg init packed
308 308 $ hg -R packed unbundle packed.hg
309 309 abort: packed bundles cannot be applied with "hg unbundle"
310 310 (use "hg debugapplystreamclonebundle")
311 311 [255]
312 312
313 313 packed1 can be consumed from debug command
314 314
315 315 (this also confirms that streamclone-ed changes are visible via
316 316 @filecache properties to in-process procedures before closing
317 317 transaction)
318 318
319 319 $ cat > $TESTTMP/showtip.py <<EOF
320 320 > from __future__ import absolute_import
321 321 >
322 322 > def showtip(ui, repo, hooktype, **kwargs):
323 323 > ui.warn('%s: %s\n' % (hooktype, repo['tip'].hex()[:12]))
324 324 >
325 325 > def reposetup(ui, repo):
326 326 > # this confirms (and ensures) that (empty) 00changelog.i
327 327 > # before streamclone is already cached as repo.changelog
328 328 > ui.setconfig('hooks', 'pretxnopen.showtip', showtip)
329 329 >
330 330 > # this confirms that streamclone-ed changes are visible to
331 331 > # in-process procedures before closing transaction
332 332 > ui.setconfig('hooks', 'pretxnclose.showtip', showtip)
333 333 >
334 334 > # this confirms that streamclone-ed changes are still visible
335 335 > # after closing transaction
336 336 > ui.setconfig('hooks', 'txnclose.showtip', showtip)
337 337 > EOF
338 338 $ cat >> $HGRCPATH <<EOF
339 339 > [extensions]
340 340 > showtip = $TESTTMP/showtip.py
341 341 > EOF
342 342
343 343 $ hg -R packed debugapplystreamclonebundle packed.hg
344 344 6 files to transfer, 2.60 KB of data
345 345 pretxnopen: 000000000000
346 346 pretxnclose: aa35859c02ea
347 347 transferred 2.60 KB in *.* seconds (* */sec) (glob)
348 348 txnclose: aa35859c02ea
349 349
350 350 (for safety, confirm visibility of streamclone-ed changes by another
351 351 process, too)
352 352
353 353 $ hg -R packed tip -T "{node|short}\n"
354 354 aa35859c02ea
355 355
356 356 $ cat >> $HGRCPATH <<EOF
357 357 > [extensions]
358 358 > showtip = !
359 359 > EOF
360 360
361 361 Does not work on non-empty repo
362 362
363 363 $ hg -R packed debugapplystreamclonebundle packed.hg
364 364 abort: cannot apply stream clone bundle on non-empty repo
365 365 [255]
366 366
367 367 Create partial clones
368 368
369 369 $ rm -r empty
370 370 $ hg init empty
371 371 $ hg clone -r 3 test partial
372 372 adding changesets
373 373 adding manifests
374 374 adding file changes
375 375 added 4 changesets with 4 changes to 1 files
376 376 updating to branch default
377 377 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 378 $ hg clone partial partial2
379 379 updating to branch default
380 380 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 381 $ cd partial
382 382
383 383 Log -R full.hg in partial
384 384
385 385 $ hg -R bundle://../full.hg log -T phases
386 386 changeset: 8:aa35859c02ea
387 387 tag: tip
388 388 phase: draft
389 389 parent: 3:eebf5a27f8ca
390 390 user: test
391 391 date: Thu Jan 01 00:00:00 1970 +0000
392 392 summary: 0.3m
393 393
394 394 changeset: 7:a6a34bfa0076
395 395 phase: draft
396 396 user: test
397 397 date: Thu Jan 01 00:00:00 1970 +0000
398 398 summary: 1.3m
399 399
400 400 changeset: 6:7373c1169842
401 401 phase: draft
402 402 user: test
403 403 date: Thu Jan 01 00:00:00 1970 +0000
404 404 summary: 1.3
405 405
406 406 changeset: 5:1bb50a9436a7
407 407 phase: draft
408 408 user: test
409 409 date: Thu Jan 01 00:00:00 1970 +0000
410 410 summary: 1.2
411 411
412 412 changeset: 4:095197eb4973
413 413 phase: draft
414 414 parent: 0:f9ee2f85a263
415 415 user: test
416 416 date: Thu Jan 01 00:00:00 1970 +0000
417 417 summary: 1.1
418 418
419 419 changeset: 3:eebf5a27f8ca
420 420 phase: public
421 421 user: test
422 422 date: Thu Jan 01 00:00:00 1970 +0000
423 423 summary: 0.3
424 424
425 425 changeset: 2:e38ba6f5b7e0
426 426 phase: public
427 427 user: test
428 428 date: Thu Jan 01 00:00:00 1970 +0000
429 429 summary: 0.2
430 430
431 431 changeset: 1:34c2bf6b0626
432 432 phase: public
433 433 user: test
434 434 date: Thu Jan 01 00:00:00 1970 +0000
435 435 summary: 0.1
436 436
437 437 changeset: 0:f9ee2f85a263
438 438 phase: public
439 439 user: test
440 440 date: Thu Jan 01 00:00:00 1970 +0000
441 441 summary: 0.0
442 442
443 443
444 444 Incoming full.hg in partial
445 445
446 446 $ hg incoming bundle://../full.hg
447 447 comparing with bundle:../full.hg
448 448 searching for changes
449 449 changeset: 4:095197eb4973
450 450 parent: 0:f9ee2f85a263
451 451 user: test
452 452 date: Thu Jan 01 00:00:00 1970 +0000
453 453 summary: 1.1
454 454
455 455 changeset: 5:1bb50a9436a7
456 456 user: test
457 457 date: Thu Jan 01 00:00:00 1970 +0000
458 458 summary: 1.2
459 459
460 460 changeset: 6:7373c1169842
461 461 user: test
462 462 date: Thu Jan 01 00:00:00 1970 +0000
463 463 summary: 1.3
464 464
465 465 changeset: 7:a6a34bfa0076
466 466 user: test
467 467 date: Thu Jan 01 00:00:00 1970 +0000
468 468 summary: 1.3m
469 469
470 470 changeset: 8:aa35859c02ea
471 471 tag: tip
472 472 parent: 3:eebf5a27f8ca
473 473 user: test
474 474 date: Thu Jan 01 00:00:00 1970 +0000
475 475 summary: 0.3m
476 476
477 477
478 478 Outgoing -R full.hg vs partial2 in partial
479 479
480 480 $ hg -R bundle://../full.hg outgoing ../partial2
481 481 comparing with ../partial2
482 482 searching for changes
483 483 changeset: 4:095197eb4973
484 484 parent: 0:f9ee2f85a263
485 485 user: test
486 486 date: Thu Jan 01 00:00:00 1970 +0000
487 487 summary: 1.1
488 488
489 489 changeset: 5:1bb50a9436a7
490 490 user: test
491 491 date: Thu Jan 01 00:00:00 1970 +0000
492 492 summary: 1.2
493 493
494 494 changeset: 6:7373c1169842
495 495 user: test
496 496 date: Thu Jan 01 00:00:00 1970 +0000
497 497 summary: 1.3
498 498
499 499 changeset: 7:a6a34bfa0076
500 500 user: test
501 501 date: Thu Jan 01 00:00:00 1970 +0000
502 502 summary: 1.3m
503 503
504 504 changeset: 8:aa35859c02ea
505 505 tag: tip
506 506 parent: 3:eebf5a27f8ca
507 507 user: test
508 508 date: Thu Jan 01 00:00:00 1970 +0000
509 509 summary: 0.3m
510 510
511 511
512 512 Outgoing -R does-not-exist.hg vs partial2 in partial
513 513
514 514 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
515 515 abort: *../does-not-exist.hg* (glob)
516 516 [255]
517 517 $ cd ..
518 518
519 519 hide outer repo
520 520 $ hg init
521 521
522 522 Direct clone from bundle (all-history)
523 523
524 524 $ hg clone full.hg full-clone
525 525 requesting all changes
526 526 adding changesets
527 527 adding manifests
528 528 adding file changes
529 529 added 9 changesets with 7 changes to 4 files (+1 heads)
530 530 updating to branch default
531 531 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
532 532 $ hg -R full-clone heads
533 533 changeset: 8:aa35859c02ea
534 534 tag: tip
535 535 parent: 3:eebf5a27f8ca
536 536 user: test
537 537 date: Thu Jan 01 00:00:00 1970 +0000
538 538 summary: 0.3m
539 539
540 540 changeset: 7:a6a34bfa0076
541 541 user: test
542 542 date: Thu Jan 01 00:00:00 1970 +0000
543 543 summary: 1.3m
544 544
545 545 $ rm -r full-clone
546 546
547 547 When cloning from a non-copiable repository into '', do not
548 548 recurse infinitely (issue2528)
549 549
550 550 $ hg clone full.hg ''
551 551 abort: empty destination path is not valid
552 552 [255]
553 553
554 554 test for https://bz.mercurial-scm.org/216
555 555
556 556 Unbundle incremental bundles into fresh empty in one go
557 557
558 558 $ rm -r empty
559 559 $ hg init empty
560 560 $ hg -R test bundle --base null -r 0 ../0.hg
561 561 1 changesets found
562 562 $ hg -R test bundle --base 0 -r 1 ../1.hg
563 563 1 changesets found
564 564 $ hg -R empty unbundle -u ../0.hg ../1.hg
565 565 adding changesets
566 566 adding manifests
567 567 adding file changes
568 568 added 1 changesets with 1 changes to 1 files
569 569 adding changesets
570 570 adding manifests
571 571 adding file changes
572 572 added 1 changesets with 1 changes to 1 files
573 573 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
574 574
575 575 View full contents of the bundle
576 576 $ hg -R test bundle --base null -r 3 ../partial.hg
577 577 4 changesets found
578 578 $ cd test
579 579 $ hg -R ../../partial.hg log -r "bundle()"
580 580 changeset: 0:f9ee2f85a263
581 581 user: test
582 582 date: Thu Jan 01 00:00:00 1970 +0000
583 583 summary: 0.0
584 584
585 585 changeset: 1:34c2bf6b0626
586 586 user: test
587 587 date: Thu Jan 01 00:00:00 1970 +0000
588 588 summary: 0.1
589 589
590 590 changeset: 2:e38ba6f5b7e0
591 591 user: test
592 592 date: Thu Jan 01 00:00:00 1970 +0000
593 593 summary: 0.2
594 594
595 595 changeset: 3:eebf5a27f8ca
596 596 user: test
597 597 date: Thu Jan 01 00:00:00 1970 +0000
598 598 summary: 0.3
599 599
600 600 $ cd ..
601 601
602 602 test for 540d1059c802
603 603
604 604 test for 540d1059c802
605 605
606 606 $ hg init orig
607 607 $ cd orig
608 608 $ echo foo > foo
609 609 $ hg add foo
610 610 $ hg ci -m 'add foo'
611 611
612 612 $ hg clone . ../copy
613 613 updating to branch default
614 614 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
615 615 $ hg tag foo
616 616
617 617 $ cd ../copy
618 618 $ echo >> foo
619 619 $ hg ci -m 'change foo'
620 620 $ hg bundle ../bundle.hg ../orig
621 621 searching for changes
622 622 1 changesets found
623 623
624 624 $ cd ../orig
625 625 $ hg incoming ../bundle.hg
626 626 comparing with ../bundle.hg
627 627 searching for changes
628 628 changeset: 2:ed1b79f46b9a
629 629 tag: tip
630 630 parent: 0:bbd179dfa0a7
631 631 user: test
632 632 date: Thu Jan 01 00:00:00 1970 +0000
633 633 summary: change foo
634 634
635 635 $ cd ..
636 636
637 637 test bundle with # in the filename (issue2154):
638 638
639 639 $ cp bundle.hg 'test#bundle.hg'
640 640 $ cd orig
641 641 $ hg incoming '../test#bundle.hg'
642 642 comparing with ../test
643 643 abort: unknown revision 'bundle.hg'!
644 644 [255]
645 645
646 646 note that percent encoding is not handled:
647 647
648 648 $ hg incoming ../test%23bundle.hg
649 649 abort: repository ../test%23bundle.hg not found!
650 650 [255]
651 651 $ cd ..
652 652
653 653 test to bundle revisions on the newly created branch (issue3828):
654 654
655 655 $ hg -q clone -U test test-clone
656 656 $ cd test
657 657
658 658 $ hg -q branch foo
659 659 $ hg commit -m "create foo branch"
660 660 $ hg -q outgoing ../test-clone
661 661 9:b4f5acb1ee27
662 662 $ hg -q bundle --branch foo foo.hg ../test-clone
663 663 $ hg -R foo.hg -q log -r "bundle()"
664 664 9:b4f5acb1ee27
665 665
666 666 $ cd ..
667 667
668 668 test for https://bz.mercurial-scm.org/1144
669 669
670 670 test that verify bundle does not traceback
671 671
672 672 partial history bundle, fails w/ unknown parent
673 673
674 674 $ hg -R bundle.hg verify
675 675 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
676 676 [255]
677 677
678 678 full history bundle, refuses to verify non-local repo
679 679
680 680 $ hg -R all.hg verify
681 681 abort: cannot verify bundle or remote repos
682 682 [255]
683 683
684 684 but, regular verify must continue to work
685 685
686 686 $ hg -R orig verify
687 687 checking changesets
688 688 checking manifests
689 689 crosschecking files in changesets and manifests
690 690 checking files
691 691 2 files, 2 changesets, 2 total revisions
692 692
693 693 diff against bundle
694 694
695 695 $ hg init b
696 696 $ cd b
697 697 $ hg -R ../all.hg diff -r tip
698 698 diff -r aa35859c02ea anotherfile
699 699 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
700 700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
701 701 @@ -1,4 +0,0 @@
702 702 -0
703 703 -1
704 704 -2
705 705 -3
706 706 $ cd ..
707 707
708 708 bundle single branch
709 709
710 710 $ hg init branchy
711 711 $ cd branchy
712 712 $ echo a >a
713 713 $ echo x >x
714 714 $ hg ci -Ama
715 715 adding a
716 716 adding x
717 717 $ echo c >c
718 718 $ echo xx >x
719 719 $ hg ci -Amc
720 720 adding c
721 721 $ echo c1 >c1
722 722 $ hg ci -Amc1
723 723 adding c1
724 724 $ hg up 0
725 725 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
726 726 $ echo b >b
727 727 $ hg ci -Amb
728 728 adding b
729 729 created new head
730 730 $ echo b1 >b1
731 731 $ echo xx >x
732 732 $ hg ci -Amb1
733 733 adding b1
734 734 $ hg clone -q -r2 . part
735 735
736 736 == bundling via incoming
737 737
738 738 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
739 739 comparing with .
740 740 searching for changes
741 741 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
742 742 057f4db07f61970e1c11e83be79e9d08adc4dc31
743 743
744 744 == bundling
745 745
746 746 $ hg bundle bundle.hg part --debug --config progress.debug=true
747 747 query 1; heads
748 748 searching for changes
749 749 all remote heads known locally
750 750 2 changesets found
751 751 list of changesets:
752 752 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
753 753 057f4db07f61970e1c11e83be79e9d08adc4dc31
754 754 bundle2-output-bundle: "HG20", (1 params) 1 parts total
755 755 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
756 756 bundling: 1/2 changesets (50.00%)
757 757 bundling: 2/2 changesets (100.00%)
758 758 bundling: 1/2 manifests (50.00%)
759 759 bundling: 2/2 manifests (100.00%)
760 760 bundling: b 1/3 files (33.33%)
761 761 bundling: b1 2/3 files (66.67%)
762 762 bundling: x 3/3 files (100.00%)
763 763
764 764 == Test for issue3441
765 765
766 766 $ hg clone -q -r0 . part2
767 767 $ hg -q -R part2 pull bundle.hg
768 768 $ hg -R part2 verify
769 769 checking changesets
770 770 checking manifests
771 771 crosschecking files in changesets and manifests
772 772 checking files
773 773 4 files, 3 changesets, 5 total revisions
774 774
775 775 == Test bundling no commits
776 776
777 777 $ hg bundle -r 'public()' no-output.hg
778 778 abort: no commits to bundle
779 779 [255]
780 780
781 781 $ cd ..
782 782
783 783 When user merges to the revision existing only in the bundle,
784 784 it should show warning that second parent of the working
785 785 directory does not exist
786 786
787 787 $ hg init update2bundled
788 788 $ cd update2bundled
789 789 $ cat <<EOF >> .hg/hgrc
790 790 > [extensions]
791 791 > strip =
792 792 > EOF
793 793 $ echo "aaa" >> a
794 794 $ hg commit -A -m 0
795 795 adding a
796 796 $ echo "bbb" >> b
797 797 $ hg commit -A -m 1
798 798 adding b
799 799 $ echo "ccc" >> c
800 800 $ hg commit -A -m 2
801 801 adding c
802 802 $ hg update -r 1
803 803 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
804 804 $ echo "ddd" >> d
805 805 $ hg commit -A -m 3
806 806 adding d
807 807 created new head
808 808 $ hg update -r 2
809 809 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
810 810 $ hg log -G
811 811 o changeset: 3:8bd3e1f196af
812 812 | tag: tip
813 813 | parent: 1:a01eca7af26d
814 814 | user: test
815 815 | date: Thu Jan 01 00:00:00 1970 +0000
816 816 | summary: 3
817 817 |
818 818 | @ changeset: 2:4652c276ac4f
819 819 |/ user: test
820 820 | date: Thu Jan 01 00:00:00 1970 +0000
821 821 | summary: 2
822 822 |
823 823 o changeset: 1:a01eca7af26d
824 824 | user: test
825 825 | date: Thu Jan 01 00:00:00 1970 +0000
826 826 | summary: 1
827 827 |
828 828 o changeset: 0:4fe08cd4693e
829 829 user: test
830 830 date: Thu Jan 01 00:00:00 1970 +0000
831 831 summary: 0
832 832
833 833 $ hg bundle --base 1 -r 3 ../update2bundled.hg
834 834 1 changesets found
835 835 $ hg strip -r 3
836 836 saved backup bundle to $TESTTMP/update2bundled/.hg/strip-backup/8bd3e1f196af-017e56d8-backup.hg (glob)
837 837 $ hg merge -R ../update2bundled.hg -r 3
838 838 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
839 839 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
840 840 (branch merge, don't forget to commit)
841 841
842 842 When user updates to the revision existing only in the bundle,
843 843 it should show warning
844 844
845 845 $ hg update -R ../update2bundled.hg --clean -r 3
846 846 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
847 847 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
848 848
849 849 When user updates to the revision existing in the local repository
850 850 the warning shouldn't be emitted
851 851
852 852 $ hg update -R ../update2bundled.hg -r 0
853 853 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
@@ -1,1136 +1,1136
1 1 Test exchange of common information using bundle2
2 2
3 3
4 4 $ getmainid() {
5 5 > hg -R main log --template '{node}\n' --rev "$1"
6 6 > }
7 7
8 8 enable obsolescence
9 9
10 10 $ cp $HGRCPATH $TESTTMP/hgrc.orig
11 11 $ cat > $TESTTMP/bundle2-pushkey-hook.sh << EOF
12 12 > echo pushkey: lock state after \"\$HG_NAMESPACE\"
13 13 > hg debuglock
14 14 > EOF
15 15
16 16 $ cat >> $HGRCPATH << EOF
17 17 > [experimental]
18 18 > evolution=createmarkers,exchange
19 19 > bundle2-output-capture=True
20 20 > [ui]
21 21 > ssh=python "$TESTDIR/dummyssh"
22 22 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
23 23 > [web]
24 24 > push_ssl = false
25 25 > allow_push = *
26 26 > [phases]
27 27 > publish=False
28 28 > [hooks]
29 29 > pretxnclose.tip = hg log -r tip -T "pre-close-tip:{node|short} {phase} {bookmarks}\n"
30 30 > txnclose.tip = hg log -r tip -T "postclose-tip:{node|short} {phase} {bookmarks}\n"
31 31 > txnclose.env = sh -c "HG_LOCAL= printenv.py txnclose"
32 32 > pushkey= sh "$TESTTMP/bundle2-pushkey-hook.sh"
33 33 > EOF
34 34
35 35 The extension requires a repo (currently unused)
36 36
37 37 $ hg init main
38 38 $ cd main
39 39 $ touch a
40 40 $ hg add a
41 41 $ hg commit -m 'a'
42 42 pre-close-tip:3903775176ed draft
43 43 postclose-tip:3903775176ed draft
44 txnclose hook: HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
44 txnclose hook: HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
45 45
46 46 $ hg unbundle $TESTDIR/bundles/rebase.hg
47 47 adding changesets
48 48 adding manifests
49 49 adding file changes
50 50 added 8 changesets with 7 changes to 7 files (+3 heads)
51 51 pre-close-tip:02de42196ebe draft
52 52 postclose-tip:02de42196ebe draft
53 txnclose hook: HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=unbundle HG_TXNID=TXN:$ID$ HG_TXNNAME=unbundle
53 txnclose hook: HG_HOOKTYPE=txnclose HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=unbundle HG_TXNID=TXN:$ID$ HG_TXNNAME=unbundle
54 54 bundle:*/tests/bundles/rebase.hg HG_URL=bundle:*/tests/bundles/rebase.hg (glob)
55 55 (run 'hg heads' to see heads, 'hg merge' to merge)
56 56
57 57 $ cd ..
58 58
59 59 Real world exchange
60 60 =====================
61 61
62 62 Add more obsolescence information
63 63
64 64 $ hg -R main debugobsolete -d '0 0' 1111111111111111111111111111111111111111 `getmainid 9520eea781bc`
65 65 pre-close-tip:02de42196ebe draft
66 66 postclose-tip:02de42196ebe draft
67 txnclose hook: HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
67 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
68 68 $ hg -R main debugobsolete -d '0 0' 2222222222222222222222222222222222222222 `getmainid 24b6387c8c8c`
69 69 pre-close-tip:02de42196ebe draft
70 70 postclose-tip:02de42196ebe draft
71 txnclose hook: HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
71 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
72 72
73 73 clone --pull
74 74
75 75 $ hg -R main phase --public cd010b8cd998
76 76 pre-close-tip:02de42196ebe draft
77 77 postclose-tip:02de42196ebe draft
78 txnclose hook: HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
78 txnclose hook: HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
79 79 $ hg clone main other --pull --rev 9520eea781bc
80 80 adding changesets
81 81 adding manifests
82 82 adding file changes
83 83 added 2 changesets with 2 changes to 2 files
84 84 1 new obsolescence markers
85 85 pre-close-tip:9520eea781bc draft
86 86 postclose-tip:9520eea781bc draft
87 txnclose hook: HG_NEW_OBSMARKERS=1 HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=9520eea781bcca16c1e15acc0ba14335a0e8e5ba HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
87 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=9520eea781bcca16c1e15acc0ba14335a0e8e5ba HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
88 88 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
89 89 updating to branch default
90 90 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 91 $ hg -R other log -G
92 92 @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
93 93 |
94 94 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
95 95
96 96 $ hg -R other debugobsolete
97 97 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
98 98
99 99 pull
100 100
101 101 $ hg -R main phase --public 9520eea781bc
102 102 pre-close-tip:02de42196ebe draft
103 103 postclose-tip:02de42196ebe draft
104 txnclose hook: HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
104 txnclose hook: HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
105 105 $ hg -R other pull -r 24b6387c8c8c
106 106 pulling from $TESTTMP/main (glob)
107 107 searching for changes
108 108 adding changesets
109 109 adding manifests
110 110 adding file changes
111 111 added 1 changesets with 1 changes to 1 files (+1 heads)
112 112 1 new obsolescence markers
113 113 pre-close-tip:24b6387c8c8c draft
114 114 postclose-tip:24b6387c8c8c draft
115 txnclose hook: HG_NEW_OBSMARKERS=1 HG_NODE=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_NODE_LAST=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
115 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_NODE_LAST=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
116 116 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
117 117 (run 'hg heads' to see heads, 'hg merge' to merge)
118 118 $ hg -R other log -G
119 119 o 2:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
120 120 |
121 121 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
122 122 |/
123 123 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
124 124
125 125 $ hg -R other debugobsolete
126 126 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
127 127 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
128 128
129 129 pull empty (with phase movement)
130 130
131 131 $ hg -R main phase --public 24b6387c8c8c
132 132 pre-close-tip:02de42196ebe draft
133 133 postclose-tip:02de42196ebe draft
134 txnclose hook: HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
134 txnclose hook: HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
135 135 $ hg -R other pull -r 24b6387c8c8c
136 136 pulling from $TESTTMP/main (glob)
137 137 no changes found
138 138 pre-close-tip:24b6387c8c8c public
139 139 postclose-tip:24b6387c8c8c public
140 txnclose hook: HG_NEW_OBSMARKERS=0 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
140 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
141 141 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
142 142 $ hg -R other log -G
143 143 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
144 144 |
145 145 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
146 146 |/
147 147 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
148 148
149 149 $ hg -R other debugobsolete
150 150 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
151 151 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
152 152
153 153 pull empty
154 154
155 155 $ hg -R other pull -r 24b6387c8c8c
156 156 pulling from $TESTTMP/main (glob)
157 157 no changes found
158 158 pre-close-tip:24b6387c8c8c public
159 159 postclose-tip:24b6387c8c8c public
160 txnclose hook: HG_NEW_OBSMARKERS=0 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
160 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
161 161 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
162 162 $ hg -R other log -G
163 163 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
164 164 |
165 165 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
166 166 |/
167 167 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
168 168
169 169 $ hg -R other debugobsolete
170 170 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
171 171 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
172 172
173 173 add extra data to test their exchange during push
174 174
175 175 $ hg -R main bookmark --rev eea13746799a book_eea1
176 176 pre-close-tip:02de42196ebe draft
177 177 postclose-tip:02de42196ebe draft
178 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
178 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
179 179 $ hg -R main debugobsolete -d '0 0' 3333333333333333333333333333333333333333 `getmainid eea13746799a`
180 180 pre-close-tip:02de42196ebe draft
181 181 postclose-tip:02de42196ebe draft
182 txnclose hook: HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
182 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
183 183 $ hg -R main bookmark --rev 02de42196ebe book_02de
184 184 pre-close-tip:02de42196ebe draft book_02de
185 185 postclose-tip:02de42196ebe draft book_02de
186 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
186 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
187 187 $ hg -R main debugobsolete -d '0 0' 4444444444444444444444444444444444444444 `getmainid 02de42196ebe`
188 188 pre-close-tip:02de42196ebe draft book_02de
189 189 postclose-tip:02de42196ebe draft book_02de
190 txnclose hook: HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
190 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
191 191 $ hg -R main bookmark --rev 42ccdea3bb16 book_42cc
192 192 pre-close-tip:02de42196ebe draft book_02de
193 193 postclose-tip:02de42196ebe draft book_02de
194 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
194 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
195 195 $ hg -R main debugobsolete -d '0 0' 5555555555555555555555555555555555555555 `getmainid 42ccdea3bb16`
196 196 pre-close-tip:02de42196ebe draft book_02de
197 197 postclose-tip:02de42196ebe draft book_02de
198 txnclose hook: HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
198 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
199 199 $ hg -R main bookmark --rev 5fddd98957c8 book_5fdd
200 200 pre-close-tip:02de42196ebe draft book_02de
201 201 postclose-tip:02de42196ebe draft book_02de
202 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
202 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
203 203 $ hg -R main debugobsolete -d '0 0' 6666666666666666666666666666666666666666 `getmainid 5fddd98957c8`
204 204 pre-close-tip:02de42196ebe draft book_02de
205 205 postclose-tip:02de42196ebe draft book_02de
206 txnclose hook: HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
206 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
207 207 $ hg -R main bookmark --rev 32af7686d403 book_32af
208 208 pre-close-tip:02de42196ebe draft book_02de
209 209 postclose-tip:02de42196ebe draft book_02de
210 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
210 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
211 211 $ hg -R main debugobsolete -d '0 0' 7777777777777777777777777777777777777777 `getmainid 32af7686d403`
212 212 pre-close-tip:02de42196ebe draft book_02de
213 213 postclose-tip:02de42196ebe draft book_02de
214 txnclose hook: HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
214 txnclose hook: HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
215 215
216 216 $ hg -R other bookmark --rev cd010b8cd998 book_eea1
217 217 pre-close-tip:24b6387c8c8c public
218 218 postclose-tip:24b6387c8c8c public
219 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
219 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
220 220 $ hg -R other bookmark --rev cd010b8cd998 book_02de
221 221 pre-close-tip:24b6387c8c8c public
222 222 postclose-tip:24b6387c8c8c public
223 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
223 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
224 224 $ hg -R other bookmark --rev cd010b8cd998 book_42cc
225 225 pre-close-tip:24b6387c8c8c public
226 226 postclose-tip:24b6387c8c8c public
227 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
227 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
228 228 $ hg -R other bookmark --rev cd010b8cd998 book_5fdd
229 229 pre-close-tip:24b6387c8c8c public
230 230 postclose-tip:24b6387c8c8c public
231 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
231 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
232 232 $ hg -R other bookmark --rev cd010b8cd998 book_32af
233 233 pre-close-tip:24b6387c8c8c public
234 234 postclose-tip:24b6387c8c8c public
235 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
235 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
236 236
237 237 $ hg -R main phase --public eea13746799a
238 238 pre-close-tip:02de42196ebe draft book_02de
239 239 postclose-tip:02de42196ebe draft book_02de
240 txnclose hook: HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
240 txnclose hook: HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
241 241
242 242 push
243 243 $ hg -R main push other --rev eea13746799a --bookmark book_eea1
244 244 pushing to other
245 245 searching for changes
246 246 remote: adding changesets
247 247 remote: adding manifests
248 248 remote: adding file changes
249 249 remote: added 1 changesets with 0 changes to 0 files (-1 heads)
250 250 remote: 1 new obsolescence markers
251 251 remote: pre-close-tip:eea13746799a public book_eea1
252 252 remote: pushkey: lock state after "phases"
253 253 remote: lock: free
254 254 remote: wlock: free
255 255 remote: pushkey: lock state after "bookmarks"
256 256 remote: lock: free
257 257 remote: wlock: free
258 258 remote: postclose-tip:eea13746799a public book_eea1
259 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_NEW_OBSMARKERS=1 HG_NODE=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_NODE_LAST=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_PHASES_MOVED=1 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/other
259 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_NODE_LAST=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_PHASES_MOVED=1 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/other
260 260 updating bookmark book_eea1
261 261 pre-close-tip:02de42196ebe draft book_02de
262 262 postclose-tip:02de42196ebe draft book_02de
263 txnclose hook: HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
263 txnclose hook: HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
264 264 file:/*/$TESTTMP/other HG_URL=file:$TESTTMP/other (glob)
265 265 $ hg -R other log -G
266 266 o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
267 267 |\
268 268 | o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
269 269 | |
270 270 @ | 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
271 271 |/
272 272 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de book_32af book_42cc book_5fdd A
273 273
274 274 $ hg -R other debugobsolete
275 275 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
276 276 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
277 277 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
278 278
279 279 pull over ssh
280 280
281 281 $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --bookmark book_02de
282 282 pulling from ssh://user@dummy/main
283 283 searching for changes
284 284 adding changesets
285 285 adding manifests
286 286 adding file changes
287 287 added 1 changesets with 1 changes to 1 files (+1 heads)
288 288 1 new obsolescence markers
289 289 updating bookmark book_02de
290 290 pre-close-tip:02de42196ebe draft book_02de
291 291 postclose-tip:02de42196ebe draft book_02de
292 txnclose hook: HG_BOOKMARK_MOVED=1 HG_NEW_OBSMARKERS=1 HG_NODE=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
292 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
293 293 ssh://user@dummy/main HG_URL=ssh://user@dummy/main
294 294 (run 'hg heads' to see heads, 'hg merge' to merge)
295 295 $ hg -R other debugobsolete
296 296 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
297 297 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
298 298 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
299 299 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
300 300
301 301 pull over http
302 302
303 303 $ hg serve -R main -p $HGPORT -d --pid-file=main.pid -E main-error.log
304 304 $ cat main.pid >> $DAEMON_PIDS
305 305
306 306 $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16 --bookmark book_42cc
307 307 pulling from http://localhost:$HGPORT/
308 308 searching for changes
309 309 adding changesets
310 310 adding manifests
311 311 adding file changes
312 312 added 1 changesets with 1 changes to 1 files (+1 heads)
313 313 1 new obsolescence markers
314 314 updating bookmark book_42cc
315 315 pre-close-tip:42ccdea3bb16 draft book_42cc
316 316 postclose-tip:42ccdea3bb16 draft book_42cc
317 txnclose hook: HG_BOOKMARK_MOVED=1 HG_NEW_OBSMARKERS=1 HG_NODE=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_NODE_LAST=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
317 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_NODE_LAST=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
318 318 http://localhost:$HGPORT/ HG_URL=http://localhost:$HGPORT/
319 319 (run 'hg heads .' to see heads, 'hg merge' to merge)
320 320 $ cat main-error.log
321 321 $ hg -R other debugobsolete
322 322 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
323 323 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
324 324 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
325 325 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
326 326 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
327 327
328 328 push over ssh
329 329
330 330 $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8 --bookmark book_5fdd
331 331 pushing to ssh://user@dummy/other
332 332 searching for changes
333 333 remote: adding changesets
334 334 remote: adding manifests
335 335 remote: adding file changes
336 336 remote: added 1 changesets with 1 changes to 1 files
337 337 remote: 1 new obsolescence markers
338 338 remote: pre-close-tip:5fddd98957c8 draft book_5fdd
339 339 remote: pushkey: lock state after "bookmarks"
340 340 remote: lock: free
341 341 remote: wlock: free
342 342 remote: postclose-tip:5fddd98957c8 draft book_5fdd
343 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_NEW_OBSMARKERS=1 HG_NODE=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_NODE_LAST=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:ssh:$LOCALIP
343 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_NODE_LAST=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:ssh:$LOCALIP
344 344 updating bookmark book_5fdd
345 345 pre-close-tip:02de42196ebe draft book_02de
346 346 postclose-tip:02de42196ebe draft book_02de
347 txnclose hook: HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
347 txnclose hook: HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
348 348 ssh://user@dummy/other HG_URL=ssh://user@dummy/other
349 349 $ hg -R other log -G
350 350 o 6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
351 351 |
352 352 o 5:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
353 353 |
354 354 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
355 355 | |
356 356 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
357 357 | |/|
358 358 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
359 359 |/ /
360 360 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
361 361 |/
362 362 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af A
363 363
364 364 $ hg -R other debugobsolete
365 365 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
366 366 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
367 367 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
368 368 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
369 369 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
370 370 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
371 371
372 372 push over http
373 373
374 374 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
375 375 $ cat other.pid >> $DAEMON_PIDS
376 376
377 377 $ hg -R main phase --public 32af7686d403
378 378 pre-close-tip:02de42196ebe draft book_02de
379 379 postclose-tip:02de42196ebe draft book_02de
380 txnclose hook: HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
380 txnclose hook: HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
381 381 $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403 --bookmark book_32af
382 382 pushing to http://localhost:$HGPORT2/
383 383 searching for changes
384 384 remote: adding changesets
385 385 remote: adding manifests
386 386 remote: adding file changes
387 387 remote: added 1 changesets with 1 changes to 1 files
388 388 remote: 1 new obsolescence markers
389 389 remote: pre-close-tip:32af7686d403 public book_32af
390 390 remote: pushkey: lock state after "phases"
391 391 remote: lock: free
392 392 remote: wlock: free
393 393 remote: pushkey: lock state after "bookmarks"
394 394 remote: lock: free
395 395 remote: wlock: free
396 396 remote: postclose-tip:32af7686d403 public book_32af
397 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_NEW_OBSMARKERS=1 HG_NODE=32af7686d403cf45b5d95f2d70cebea587ac806a HG_NODE_LAST=32af7686d403cf45b5d95f2d70cebea587ac806a HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:http:$LOCALIP:
397 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=32af7686d403cf45b5d95f2d70cebea587ac806a HG_NODE_LAST=32af7686d403cf45b5d95f2d70cebea587ac806a HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:http:$LOCALIP:
398 398 updating bookmark book_32af
399 399 pre-close-tip:02de42196ebe draft book_02de
400 400 postclose-tip:02de42196ebe draft book_02de
401 txnclose hook: HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
401 txnclose hook: HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
402 402 http://localhost:$HGPORT2/ HG_URL=http://localhost:$HGPORT2/
403 403 $ cat other-error.log
404 404
405 405 Check final content.
406 406
407 407 $ hg -R other log -G
408 408 o 7:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af D
409 409 |
410 410 o 6:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
411 411 |
412 412 o 5:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
413 413 |
414 414 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
415 415 | |
416 416 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
417 417 | |/|
418 418 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
419 419 |/ /
420 420 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
421 421 |/
422 422 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
423 423
424 424 $ hg -R other debugobsolete
425 425 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
426 426 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
427 427 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
428 428 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
429 429 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
430 430 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
431 431 7777777777777777777777777777777777777777 32af7686d403cf45b5d95f2d70cebea587ac806a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
432 432
433 433 (check that no 'pending' files remain)
434 434
435 435 $ ls -1 other/.hg/bookmarks*
436 436 other/.hg/bookmarks
437 437 $ ls -1 other/.hg/store/phaseroots*
438 438 other/.hg/store/phaseroots
439 439 $ ls -1 other/.hg/store/00changelog.i*
440 440 other/.hg/store/00changelog.i
441 441
442 442 Error Handling
443 443 ==============
444 444
445 445 Check that errors are properly returned to the client during push.
446 446
447 447 Setting up
448 448
449 449 $ cat > failpush.py << EOF
450 450 > """A small extension that makes push fails when using bundle2
451 451 >
452 452 > used to test error handling in bundle2
453 453 > """
454 454 >
455 455 > from mercurial import error
456 456 > from mercurial import bundle2
457 457 > from mercurial import exchange
458 458 > from mercurial import extensions
459 459 >
460 460 > def _pushbundle2failpart(pushop, bundler):
461 461 > reason = pushop.ui.config('failpush', 'reason', None)
462 462 > part = None
463 463 > if reason == 'abort':
464 464 > bundler.newpart('test:abort')
465 465 > if reason == 'unknown':
466 466 > bundler.newpart('test:unknown')
467 467 > if reason == 'race':
468 468 > # 20 Bytes of crap
469 469 > bundler.newpart('check:heads', data='01234567890123456789')
470 470 >
471 471 > @bundle2.parthandler("test:abort")
472 472 > def handleabort(op, part):
473 473 > raise error.Abort('Abandon ship!', hint="don't panic")
474 474 >
475 475 > def uisetup(ui):
476 476 > exchange.b2partsgenmapping['failpart'] = _pushbundle2failpart
477 477 > exchange.b2partsgenorder.insert(0, 'failpart')
478 478 >
479 479 > EOF
480 480
481 481 $ cd main
482 482 $ hg up tip
483 483 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
484 484 $ echo 'I' > I
485 485 $ hg add I
486 486 $ hg ci -m 'I'
487 487 pre-close-tip:e7ec4e813ba6 draft
488 488 postclose-tip:e7ec4e813ba6 draft
489 txnclose hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
489 txnclose hook: HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
490 490 $ hg id
491 491 e7ec4e813ba6 tip
492 492 $ cd ..
493 493
494 494 $ cat << EOF >> $HGRCPATH
495 495 > [extensions]
496 496 > failpush=$TESTTMP/failpush.py
497 497 > EOF
498 498
499 499 $ killdaemons.py
500 500 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
501 501 $ cat other.pid >> $DAEMON_PIDS
502 502
503 503 Doing the actual push: Abort error
504 504
505 505 $ cat << EOF >> $HGRCPATH
506 506 > [failpush]
507 507 > reason = abort
508 508 > EOF
509 509
510 510 $ hg -R main push other -r e7ec4e813ba6
511 511 pushing to other
512 512 searching for changes
513 513 abort: Abandon ship!
514 514 (don't panic)
515 515 [255]
516 516
517 517 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
518 518 pushing to ssh://user@dummy/other
519 519 searching for changes
520 520 remote: Abandon ship!
521 521 remote: (don't panic)
522 522 abort: push failed on remote
523 523 [255]
524 524
525 525 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
526 526 pushing to http://localhost:$HGPORT2/
527 527 searching for changes
528 528 remote: Abandon ship!
529 529 remote: (don't panic)
530 530 abort: push failed on remote
531 531 [255]
532 532
533 533
534 534 Doing the actual push: unknown mandatory parts
535 535
536 536 $ cat << EOF >> $HGRCPATH
537 537 > [failpush]
538 538 > reason = unknown
539 539 > EOF
540 540
541 541 $ hg -R main push other -r e7ec4e813ba6
542 542 pushing to other
543 543 searching for changes
544 544 abort: missing support for test:unknown
545 545 [255]
546 546
547 547 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
548 548 pushing to ssh://user@dummy/other
549 549 searching for changes
550 550 abort: missing support for test:unknown
551 551 [255]
552 552
553 553 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
554 554 pushing to http://localhost:$HGPORT2/
555 555 searching for changes
556 556 abort: missing support for test:unknown
557 557 [255]
558 558
559 559 Doing the actual push: race
560 560
561 561 $ cat << EOF >> $HGRCPATH
562 562 > [failpush]
563 563 > reason = race
564 564 > EOF
565 565
566 566 $ hg -R main push other -r e7ec4e813ba6
567 567 pushing to other
568 568 searching for changes
569 569 abort: push failed:
570 570 'repository changed while pushing - please try again'
571 571 [255]
572 572
573 573 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
574 574 pushing to ssh://user@dummy/other
575 575 searching for changes
576 576 abort: push failed:
577 577 'repository changed while pushing - please try again'
578 578 [255]
579 579
580 580 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
581 581 pushing to http://localhost:$HGPORT2/
582 582 searching for changes
583 583 abort: push failed:
584 584 'repository changed while pushing - please try again'
585 585 [255]
586 586
587 587 Doing the actual push: hook abort
588 588
589 589 $ cat << EOF >> $HGRCPATH
590 590 > [failpush]
591 591 > reason =
592 592 > [hooks]
593 593 > pretxnclose.failpush = sh -c "echo 'You shall not pass!'; false"
594 594 > txnabort.failpush = sh -c "echo 'Cleaning up the mess...'"
595 595 > EOF
596 596
597 597 $ killdaemons.py
598 598 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
599 599 $ cat other.pid >> $DAEMON_PIDS
600 600
601 601 $ hg -R main push other -r e7ec4e813ba6
602 602 pushing to other
603 603 searching for changes
604 604 remote: adding changesets
605 605 remote: adding manifests
606 606 remote: adding file changes
607 607 remote: added 1 changesets with 1 changes to 1 files
608 608 remote: pre-close-tip:e7ec4e813ba6 draft
609 609 remote: You shall not pass!
610 610 remote: transaction abort!
611 611 remote: Cleaning up the mess...
612 612 remote: rollback completed
613 613 abort: pretxnclose.failpush hook exited with status 1
614 614 [255]
615 615
616 616 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
617 617 pushing to ssh://user@dummy/other
618 618 searching for changes
619 619 remote: adding changesets
620 620 remote: adding manifests
621 621 remote: adding file changes
622 622 remote: added 1 changesets with 1 changes to 1 files
623 623 remote: pre-close-tip:e7ec4e813ba6 draft
624 624 remote: You shall not pass!
625 625 remote: transaction abort!
626 626 remote: Cleaning up the mess...
627 627 remote: rollback completed
628 628 remote: pretxnclose.failpush hook exited with status 1
629 629 abort: push failed on remote
630 630 [255]
631 631
632 632 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
633 633 pushing to http://localhost:$HGPORT2/
634 634 searching for changes
635 635 remote: adding changesets
636 636 remote: adding manifests
637 637 remote: adding file changes
638 638 remote: added 1 changesets with 1 changes to 1 files
639 639 remote: pre-close-tip:e7ec4e813ba6 draft
640 640 remote: You shall not pass!
641 641 remote: transaction abort!
642 642 remote: Cleaning up the mess...
643 643 remote: rollback completed
644 644 remote: pretxnclose.failpush hook exited with status 1
645 645 abort: push failed on remote
646 646 [255]
647 647
648 648 (check that no 'pending' files remain)
649 649
650 650 $ ls -1 other/.hg/bookmarks*
651 651 other/.hg/bookmarks
652 652 $ ls -1 other/.hg/store/phaseroots*
653 653 other/.hg/store/phaseroots
654 654 $ ls -1 other/.hg/store/00changelog.i*
655 655 other/.hg/store/00changelog.i
656 656
657 657 Check error from hook during the unbundling process itself
658 658
659 659 $ cat << EOF >> $HGRCPATH
660 660 > pretxnchangegroup = sh -c "echo 'Fail early!'; false"
661 661 > EOF
662 662 $ killdaemons.py # reload http config
663 663 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
664 664 $ cat other.pid >> $DAEMON_PIDS
665 665
666 666 $ hg -R main push other -r e7ec4e813ba6
667 667 pushing to other
668 668 searching for changes
669 669 remote: adding changesets
670 670 remote: adding manifests
671 671 remote: adding file changes
672 672 remote: added 1 changesets with 1 changes to 1 files
673 673 remote: Fail early!
674 674 remote: transaction abort!
675 675 remote: Cleaning up the mess...
676 676 remote: rollback completed
677 677 abort: pretxnchangegroup hook exited with status 1
678 678 [255]
679 679 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
680 680 pushing to ssh://user@dummy/other
681 681 searching for changes
682 682 remote: adding changesets
683 683 remote: adding manifests
684 684 remote: adding file changes
685 685 remote: added 1 changesets with 1 changes to 1 files
686 686 remote: Fail early!
687 687 remote: transaction abort!
688 688 remote: Cleaning up the mess...
689 689 remote: rollback completed
690 690 remote: pretxnchangegroup hook exited with status 1
691 691 abort: push failed on remote
692 692 [255]
693 693 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
694 694 pushing to http://localhost:$HGPORT2/
695 695 searching for changes
696 696 remote: adding changesets
697 697 remote: adding manifests
698 698 remote: adding file changes
699 699 remote: added 1 changesets with 1 changes to 1 files
700 700 remote: Fail early!
701 701 remote: transaction abort!
702 702 remote: Cleaning up the mess...
703 703 remote: rollback completed
704 704 remote: pretxnchangegroup hook exited with status 1
705 705 abort: push failed on remote
706 706 [255]
707 707
708 708 Check output capture control.
709 709
710 710 (should be still forced for http, disabled for local and ssh)
711 711
712 712 $ cat >> $HGRCPATH << EOF
713 713 > [experimental]
714 714 > bundle2-output-capture=False
715 715 > EOF
716 716
717 717 $ hg -R main push other -r e7ec4e813ba6
718 718 pushing to other
719 719 searching for changes
720 720 adding changesets
721 721 adding manifests
722 722 adding file changes
723 723 added 1 changesets with 1 changes to 1 files
724 724 Fail early!
725 725 transaction abort!
726 726 Cleaning up the mess...
727 727 rollback completed
728 728 abort: pretxnchangegroup hook exited with status 1
729 729 [255]
730 730 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
731 731 pushing to ssh://user@dummy/other
732 732 searching for changes
733 733 remote: adding changesets
734 734 remote: adding manifests
735 735 remote: adding file changes
736 736 remote: added 1 changesets with 1 changes to 1 files
737 737 remote: Fail early!
738 738 remote: transaction abort!
739 739 remote: Cleaning up the mess...
740 740 remote: rollback completed
741 741 remote: pretxnchangegroup hook exited with status 1
742 742 abort: push failed on remote
743 743 [255]
744 744 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
745 745 pushing to http://localhost:$HGPORT2/
746 746 searching for changes
747 747 remote: adding changesets
748 748 remote: adding manifests
749 749 remote: adding file changes
750 750 remote: added 1 changesets with 1 changes to 1 files
751 751 remote: Fail early!
752 752 remote: transaction abort!
753 753 remote: Cleaning up the mess...
754 754 remote: rollback completed
755 755 remote: pretxnchangegroup hook exited with status 1
756 756 abort: push failed on remote
757 757 [255]
758 758
759 759 Check abort from mandatory pushkey
760 760
761 761 $ cat > mandatorypart.py << EOF
762 762 > from mercurial import exchange
763 763 > from mercurial import pushkey
764 764 > from mercurial import node
765 765 > from mercurial import error
766 766 > @exchange.b2partsgenerator('failingpuskey')
767 767 > def addfailingpushey(pushop, bundler):
768 768 > enc = pushkey.encode
769 769 > part = bundler.newpart('pushkey')
770 770 > part.addparam('namespace', enc('phases'))
771 771 > part.addparam('key', enc(pushop.repo['cd010b8cd998'].hex()))
772 772 > part.addparam('old', enc(str(0))) # successful update
773 773 > part.addparam('new', enc(str(0)))
774 774 > def fail(pushop, exc):
775 775 > raise error.Abort('Correct phase push failed (because hooks)')
776 776 > pushop.pkfailcb[part.id] = fail
777 777 > EOF
778 778 $ cat >> $HGRCPATH << EOF
779 779 > [hooks]
780 780 > pretxnchangegroup=
781 781 > pretxnclose.failpush=
782 782 > prepushkey.failpush = sh -c "echo 'do not push the key !'; false"
783 783 > [extensions]
784 784 > mandatorypart=$TESTTMP/mandatorypart.py
785 785 > EOF
786 786 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS # reload http config
787 787 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
788 788 $ cat other.pid >> $DAEMON_PIDS
789 789
790 790 (Failure from a hook)
791 791
792 792 $ hg -R main push other -r e7ec4e813ba6
793 793 pushing to other
794 794 searching for changes
795 795 adding changesets
796 796 adding manifests
797 797 adding file changes
798 798 added 1 changesets with 1 changes to 1 files
799 799 do not push the key !
800 800 pushkey-abort: prepushkey.failpush hook exited with status 1
801 801 transaction abort!
802 802 Cleaning up the mess...
803 803 rollback completed
804 804 abort: Correct phase push failed (because hooks)
805 805 [255]
806 806 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
807 807 pushing to ssh://user@dummy/other
808 808 searching for changes
809 809 remote: adding changesets
810 810 remote: adding manifests
811 811 remote: adding file changes
812 812 remote: added 1 changesets with 1 changes to 1 files
813 813 remote: do not push the key !
814 814 remote: pushkey-abort: prepushkey.failpush hook exited with status 1
815 815 remote: transaction abort!
816 816 remote: Cleaning up the mess...
817 817 remote: rollback completed
818 818 abort: Correct phase push failed (because hooks)
819 819 [255]
820 820 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
821 821 pushing to http://localhost:$HGPORT2/
822 822 searching for changes
823 823 remote: adding changesets
824 824 remote: adding manifests
825 825 remote: adding file changes
826 826 remote: added 1 changesets with 1 changes to 1 files
827 827 remote: do not push the key !
828 828 remote: pushkey-abort: prepushkey.failpush hook exited with status 1
829 829 remote: transaction abort!
830 830 remote: Cleaning up the mess...
831 831 remote: rollback completed
832 832 abort: Correct phase push failed (because hooks)
833 833 [255]
834 834
835 835 (Failure from a the pushkey)
836 836
837 837 $ cat > mandatorypart.py << EOF
838 838 > from mercurial import exchange
839 839 > from mercurial import pushkey
840 840 > from mercurial import node
841 841 > from mercurial import error
842 842 > @exchange.b2partsgenerator('failingpuskey')
843 843 > def addfailingpushey(pushop, bundler):
844 844 > enc = pushkey.encode
845 845 > part = bundler.newpart('pushkey')
846 846 > part.addparam('namespace', enc('phases'))
847 847 > part.addparam('key', enc(pushop.repo['cd010b8cd998'].hex()))
848 848 > part.addparam('old', enc(str(4))) # will fail
849 849 > part.addparam('new', enc(str(3)))
850 850 > def fail(pushop, exc):
851 851 > raise error.Abort('Clown phase push failed')
852 852 > pushop.pkfailcb[part.id] = fail
853 853 > EOF
854 854 $ cat >> $HGRCPATH << EOF
855 855 > [hooks]
856 856 > prepushkey.failpush =
857 857 > EOF
858 858 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS # reload http config
859 859 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
860 860 $ cat other.pid >> $DAEMON_PIDS
861 861
862 862 $ hg -R main push other -r e7ec4e813ba6
863 863 pushing to other
864 864 searching for changes
865 865 adding changesets
866 866 adding manifests
867 867 adding file changes
868 868 added 1 changesets with 1 changes to 1 files
869 869 transaction abort!
870 870 Cleaning up the mess...
871 871 rollback completed
872 872 pushkey: lock state after "phases"
873 873 lock: free
874 874 wlock: free
875 875 abort: Clown phase push failed
876 876 [255]
877 877 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
878 878 pushing to ssh://user@dummy/other
879 879 searching for changes
880 880 remote: adding changesets
881 881 remote: adding manifests
882 882 remote: adding file changes
883 883 remote: added 1 changesets with 1 changes to 1 files
884 884 remote: transaction abort!
885 885 remote: Cleaning up the mess...
886 886 remote: rollback completed
887 887 remote: pushkey: lock state after "phases"
888 888 remote: lock: free
889 889 remote: wlock: free
890 890 abort: Clown phase push failed
891 891 [255]
892 892 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
893 893 pushing to http://localhost:$HGPORT2/
894 894 searching for changes
895 895 remote: adding changesets
896 896 remote: adding manifests
897 897 remote: adding file changes
898 898 remote: added 1 changesets with 1 changes to 1 files
899 899 remote: transaction abort!
900 900 remote: Cleaning up the mess...
901 901 remote: rollback completed
902 902 remote: pushkey: lock state after "phases"
903 903 remote: lock: free
904 904 remote: wlock: free
905 905 abort: Clown phase push failed
906 906 [255]
907 907
908 908 Test lazily acquiring the lock during unbundle
909 909 $ cp $TESTTMP/hgrc.orig $HGRCPATH
910 910 $ cat >> $HGRCPATH <<EOF
911 911 > [ui]
912 912 > ssh=python "$TESTDIR/dummyssh"
913 913 > EOF
914 914
915 915 $ cat >> $TESTTMP/locktester.py <<EOF
916 916 > import os
917 917 > from mercurial import extensions, bundle2, util
918 918 > def checklock(orig, repo, *args, **kwargs):
919 919 > if repo.svfs.lexists("lock"):
920 920 > raise util.Abort("Lock should not be taken")
921 921 > return orig(repo, *args, **kwargs)
922 922 > def extsetup(ui):
923 923 > extensions.wrapfunction(bundle2, 'processbundle', checklock)
924 924 > EOF
925 925
926 926 $ hg init lazylock
927 927 $ cat >> lazylock/.hg/hgrc <<EOF
928 928 > [extensions]
929 929 > locktester=$TESTTMP/locktester.py
930 930 > EOF
931 931
932 932 $ hg clone -q ssh://user@dummy/lazylock lazylockclient
933 933 $ cd lazylockclient
934 934 $ touch a && hg ci -Aqm a
935 935 $ hg push
936 936 pushing to ssh://user@dummy/lazylock
937 937 searching for changes
938 938 remote: Lock should not be taken
939 939 abort: push failed on remote
940 940 [255]
941 941
942 942 $ cat >> ../lazylock/.hg/hgrc <<EOF
943 943 > [experimental]
944 944 > bundle2lazylocking=True
945 945 > EOF
946 946 $ hg push
947 947 pushing to ssh://user@dummy/lazylock
948 948 searching for changes
949 949 remote: adding changesets
950 950 remote: adding manifests
951 951 remote: adding file changes
952 952 remote: added 1 changesets with 1 changes to 1 files
953 953
954 954 $ cd ..
955 955
956 956 Servers can disable bundle1 for clone/pull operations
957 957
958 958 $ killdaemons.py
959 959 $ hg init bundle2onlyserver
960 960 $ cd bundle2onlyserver
961 961 $ cat > .hg/hgrc << EOF
962 962 > [server]
963 963 > bundle1.pull = false
964 964 > EOF
965 965
966 966 $ touch foo
967 967 $ hg -q commit -A -m initial
968 968
969 969 $ hg serve -p $HGPORT -d --pid-file=hg.pid
970 970 $ cat hg.pid >> $DAEMON_PIDS
971 971
972 972 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2
973 973 requesting all changes
974 974 abort: remote error:
975 975 incompatible Mercurial client; bundle2 required
976 976 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
977 977 [255]
978 978 $ killdaemons.py
979 979 $ cd ..
980 980
981 981 bundle1 can still pull non-generaldelta repos when generaldelta bundle1 disabled
982 982
983 983 $ hg --config format.usegeneraldelta=false init notgdserver
984 984 $ cd notgdserver
985 985 $ cat > .hg/hgrc << EOF
986 986 > [server]
987 987 > bundle1gd.pull = false
988 988 > EOF
989 989
990 990 $ touch foo
991 991 $ hg -q commit -A -m initial
992 992 $ hg serve -p $HGPORT -d --pid-file=hg.pid
993 993 $ cat hg.pid >> $DAEMON_PIDS
994 994
995 995 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2-1
996 996 requesting all changes
997 997 adding changesets
998 998 adding manifests
999 999 adding file changes
1000 1000 added 1 changesets with 1 changes to 1 files
1001 1001 updating to branch default
1002 1002 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1003 1003
1004 1004 $ killdaemons.py
1005 1005 $ cd ../bundle2onlyserver
1006 1006
1007 1007 bundle1 pull can be disabled for generaldelta repos only
1008 1008
1009 1009 $ cat > .hg/hgrc << EOF
1010 1010 > [server]
1011 1011 > bundle1gd.pull = false
1012 1012 > EOF
1013 1013
1014 1014 $ hg serve -p $HGPORT -d --pid-file=hg.pid
1015 1015 $ cat hg.pid >> $DAEMON_PIDS
1016 1016 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2
1017 1017 requesting all changes
1018 1018 abort: remote error:
1019 1019 incompatible Mercurial client; bundle2 required
1020 1020 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1021 1021 [255]
1022 1022
1023 1023 $ killdaemons.py
1024 1024
1025 1025 Verify the global server.bundle1 option works
1026 1026
1027 1027 $ cd ..
1028 1028 $ cat > bundle2onlyserver/.hg/hgrc << EOF
1029 1029 > [server]
1030 1030 > bundle1 = false
1031 1031 > EOF
1032 1032 $ hg -R bundle2onlyserver serve -p $HGPORT -d --pid-file=hg.pid
1033 1033 $ cat hg.pid >> $DAEMON_PIDS
1034 1034 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT not-bundle2
1035 1035 requesting all changes
1036 1036 abort: remote error:
1037 1037 incompatible Mercurial client; bundle2 required
1038 1038 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1039 1039 [255]
1040 1040 $ killdaemons.py
1041 1041
1042 1042 $ hg --config devel.legacy.exchange=bundle1 clone ssh://user@dummy/bundle2onlyserver not-bundle2-ssh
1043 1043 requesting all changes
1044 1044 adding changesets
1045 1045 remote: abort: incompatible Mercurial client; bundle2 required
1046 1046 remote: (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1047 1047 transaction abort!
1048 1048 rollback completed
1049 1049 abort: stream ended unexpectedly (got 0 bytes, expected 4)
1050 1050 [255]
1051 1051
1052 1052 $ cat > bundle2onlyserver/.hg/hgrc << EOF
1053 1053 > [server]
1054 1054 > bundle1gd = false
1055 1055 > EOF
1056 1056 $ hg -R bundle2onlyserver serve -p $HGPORT -d --pid-file=hg.pid
1057 1057 $ cat hg.pid >> $DAEMON_PIDS
1058 1058
1059 1059 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2
1060 1060 requesting all changes
1061 1061 abort: remote error:
1062 1062 incompatible Mercurial client; bundle2 required
1063 1063 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1064 1064 [255]
1065 1065
1066 1066 $ killdaemons.py
1067 1067
1068 1068 $ cd notgdserver
1069 1069 $ cat > .hg/hgrc << EOF
1070 1070 > [server]
1071 1071 > bundle1gd = false
1072 1072 > EOF
1073 1073 $ hg serve -p $HGPORT -d --pid-file=hg.pid
1074 1074 $ cat hg.pid >> $DAEMON_PIDS
1075 1075
1076 1076 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2-2
1077 1077 requesting all changes
1078 1078 adding changesets
1079 1079 adding manifests
1080 1080 adding file changes
1081 1081 added 1 changesets with 1 changes to 1 files
1082 1082 updating to branch default
1083 1083 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1084 1084
1085 1085 $ killdaemons.py
1086 1086 $ cd ../bundle2onlyserver
1087 1087
1088 1088 Verify bundle1 pushes can be disabled
1089 1089
1090 1090 $ cat > .hg/hgrc << EOF
1091 1091 > [server]
1092 1092 > bundle1.push = false
1093 1093 > [web]
1094 1094 > allow_push = *
1095 1095 > push_ssl = false
1096 1096 > EOF
1097 1097
1098 1098 $ hg serve -p $HGPORT -d --pid-file=hg.pid -E error.log
1099 1099 $ cat hg.pid >> $DAEMON_PIDS
1100 1100 $ cd ..
1101 1101
1102 1102 $ hg clone http://localhost:$HGPORT bundle2-only
1103 1103 requesting all changes
1104 1104 adding changesets
1105 1105 adding manifests
1106 1106 adding file changes
1107 1107 added 1 changesets with 1 changes to 1 files
1108 1108 updating to branch default
1109 1109 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1110 1110 $ cd bundle2-only
1111 1111 $ echo commit > foo
1112 1112 $ hg commit -m commit
1113 1113 $ hg --config devel.legacy.exchange=bundle1 push
1114 1114 pushing to http://localhost:$HGPORT/
1115 1115 searching for changes
1116 1116 abort: remote error:
1117 1117 incompatible Mercurial client; bundle2 required
1118 1118 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1119 1119 [255]
1120 1120
1121 1121 (also check with ssh)
1122 1122
1123 1123 $ hg --config devel.legacy.exchange=bundle1 push ssh://user@dummy/bundle2onlyserver
1124 1124 pushing to ssh://user@dummy/bundle2onlyserver
1125 1125 searching for changes
1126 1126 remote: abort: incompatible Mercurial client; bundle2 required
1127 1127 remote: (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1128 1128 [1]
1129 1129
1130 1130 $ hg push
1131 1131 pushing to http://localhost:$HGPORT/
1132 1132 searching for changes
1133 1133 remote: adding changesets
1134 1134 remote: adding manifests
1135 1135 remote: adding file changes
1136 1136 remote: added 1 changesets with 1 changes to 1 files
@@ -1,260 +1,260
1 1 Create an extension to test bundle2 with multiple changegroups
2 2
3 3 $ cat > bundle2.py <<EOF
4 4 > """
5 5 > """
6 6 > from mercurial import changegroup, discovery, exchange
7 7 >
8 8 > def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None,
9 9 > b2caps=None, heads=None, common=None,
10 10 > **kwargs):
11 11 > # Create two changegroups given the common changesets and heads for the
12 12 > # changegroup part we are being requested. Use the parent of each head
13 13 > # in 'heads' as intermediate heads for the first changegroup.
14 14 > intermediates = [repo[r].p1().node() for r in heads]
15 15 > outgoing = discovery.outgoing(repo, common, intermediates)
16 16 > cg = changegroup.getchangegroup(repo, source, outgoing,
17 17 > bundlecaps=bundlecaps)
18 18 > bundler.newpart('output', data='changegroup1')
19 19 > bundler.newpart('changegroup', data=cg.getchunks())
20 20 > outgoing = discovery.outgoing(repo, common + intermediates, heads)
21 21 > cg = changegroup.getchangegroup(repo, source, outgoing,
22 22 > bundlecaps=bundlecaps)
23 23 > bundler.newpart('output', data='changegroup2')
24 24 > bundler.newpart('changegroup', data=cg.getchunks())
25 25 >
26 26 > def _pull(repo, *args, **kwargs):
27 27 > pullop = _orig_pull(repo, *args, **kwargs)
28 28 > repo.ui.write('pullop.cgresult is %d\n' % pullop.cgresult)
29 29 > return pullop
30 30 >
31 31 > _orig_pull = exchange.pull
32 32 > exchange.pull = _pull
33 33 > exchange.getbundle2partsmapping['changegroup'] = _getbundlechangegrouppart
34 34 > EOF
35 35
36 36 $ cat >> $HGRCPATH << EOF
37 37 > [ui]
38 38 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
39 39 > EOF
40 40
41 41 Start with a simple repository with a single commit
42 42
43 43 $ hg init repo
44 44 $ cd repo
45 45 $ cat > .hg/hgrc << EOF
46 46 > [extensions]
47 47 > bundle2=$TESTTMP/bundle2.py
48 48 > EOF
49 49
50 50 $ echo A > A
51 51 $ hg commit -A -m A -q
52 52 $ cd ..
53 53
54 54 Clone
55 55
56 56 $ hg clone -q repo clone
57 57
58 58 Add two linear commits
59 59
60 60 $ cd repo
61 61 $ echo B > B
62 62 $ hg commit -A -m B -q
63 63 $ echo C > C
64 64 $ hg commit -A -m C -q
65 65
66 66 $ cd ../clone
67 67 $ cat >> .hg/hgrc <<EOF
68 68 > [hooks]
69 69 > pretxnchangegroup = sh -c "printenv.py pretxnchangegroup"
70 70 > changegroup = sh -c "printenv.py changegroup"
71 71 > incoming = sh -c "printenv.py incoming"
72 72 > EOF
73 73
74 74 Pull the new commits in the clone
75 75
76 76 $ hg pull
77 77 pulling from $TESTTMP/repo (glob)
78 78 searching for changes
79 79 remote: changegroup1
80 80 adding changesets
81 81 adding manifests
82 82 adding file changes
83 83 added 1 changesets with 1 changes to 1 files
84 pretxnchangegroup hook: HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_PENDING=$TESTTMP/clone HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
84 pretxnchangegroup hook: HG_HOOKTYPE=pretxnchangegroup HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_PENDING=$TESTTMP/clone HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
85 85 remote: changegroup2
86 86 adding changesets
87 87 adding manifests
88 88 adding file changes
89 89 added 1 changesets with 1 changes to 1 files
90 pretxnchangegroup hook: HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_PENDING=$TESTTMP/clone HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
91 changegroup hook: HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
92 incoming hook: HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
93 changegroup hook: HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
94 incoming hook: HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
90 pretxnchangegroup hook: HG_HOOKTYPE=pretxnchangegroup HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_PENDING=$TESTTMP/clone HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
91 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
92 incoming hook: HG_HOOKTYPE=incoming HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
93 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
94 incoming hook: HG_HOOKTYPE=incoming HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
95 95 pullop.cgresult is 1
96 96 (run 'hg update' to get a working copy)
97 97 $ hg update
98 98 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 99 $ hg log -G
100 100 @ 2:f838bfaca5c7 public test C
101 101 |
102 102 o 1:27547f69f254 public test B
103 103 |
104 104 o 0:4a2df7238c3b public test A
105 105
106 106 Add more changesets with multiple heads to the original repository
107 107
108 108 $ cd ../repo
109 109 $ echo D > D
110 110 $ hg commit -A -m D -q
111 111 $ hg up -r 1
112 112 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
113 113 $ echo E > E
114 114 $ hg commit -A -m E -q
115 115 $ echo F > F
116 116 $ hg commit -A -m F -q
117 117 $ hg up -r 1
118 118 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
119 119 $ echo G > G
120 120 $ hg commit -A -m G -q
121 121 $ hg up -r 3
122 122 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
123 123 $ echo H > H
124 124 $ hg commit -A -m H -q
125 125 $ hg log -G
126 126 @ 7:5cd59d311f65 draft test H
127 127 |
128 128 | o 6:1d14c3ce6ac0 draft test G
129 129 | |
130 130 | | o 5:7f219660301f draft test F
131 131 | | |
132 132 | | o 4:8a5212ebc852 draft test E
133 133 | |/
134 134 o | 3:b3325c91a4d9 draft test D
135 135 | |
136 136 o | 2:f838bfaca5c7 draft test C
137 137 |/
138 138 o 1:27547f69f254 draft test B
139 139 |
140 140 o 0:4a2df7238c3b draft test A
141 141
142 142 New heads are reported during transfer and properly accounted for in
143 143 pullop.cgresult
144 144
145 145 $ cd ../clone
146 146 $ hg pull
147 147 pulling from $TESTTMP/repo (glob)
148 148 searching for changes
149 149 remote: changegroup1
150 150 adding changesets
151 151 adding manifests
152 152 adding file changes
153 153 added 2 changesets with 2 changes to 2 files (+1 heads)
154 pretxnchangegroup hook: HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3 HG_PENDING=$TESTTMP/clone HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
154 pretxnchangegroup hook: HG_HOOKTYPE=pretxnchangegroup HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3 HG_PENDING=$TESTTMP/clone HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
155 155 remote: changegroup2
156 156 adding changesets
157 157 adding manifests
158 158 adding file changes
159 159 added 3 changesets with 3 changes to 3 files (+1 heads)
160 pretxnchangegroup hook: HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46 HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1 HG_PENDING=$TESTTMP/clone HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
161 changegroup hook: HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
162 incoming hook: HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
163 incoming hook: HG_NODE=8a5212ebc8527f9fb821601504794e3eb11a1ed3 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
164 changegroup hook: HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46 HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
165 incoming hook: HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
166 incoming hook: HG_NODE=1d14c3ce6ac0582d2809220d33e8cd7a696e0156 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
167 incoming hook: HG_NODE=5cd59d311f6508b8e0ed28a266756c859419c9f1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
160 pretxnchangegroup hook: HG_HOOKTYPE=pretxnchangegroup HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46 HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1 HG_PENDING=$TESTTMP/clone HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
161 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
162 incoming hook: HG_HOOKTYPE=incoming HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
163 incoming hook: HG_HOOKTYPE=incoming HG_NODE=8a5212ebc8527f9fb821601504794e3eb11a1ed3 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
164 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46 HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
165 incoming hook: HG_HOOKTYPE=incoming HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
166 incoming hook: HG_HOOKTYPE=incoming HG_NODE=1d14c3ce6ac0582d2809220d33e8cd7a696e0156 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
167 incoming hook: HG_HOOKTYPE=incoming HG_NODE=5cd59d311f6508b8e0ed28a266756c859419c9f1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
168 168 pullop.cgresult is 3
169 169 (run 'hg heads' to see heads, 'hg merge' to merge)
170 170 $ hg log -G
171 171 o 7:5cd59d311f65 public test H
172 172 |
173 173 | o 6:1d14c3ce6ac0 public test G
174 174 | |
175 175 | | o 5:7f219660301f public test F
176 176 | | |
177 177 | | o 4:8a5212ebc852 public test E
178 178 | |/
179 179 o | 3:b3325c91a4d9 public test D
180 180 | |
181 181 @ | 2:f838bfaca5c7 public test C
182 182 |/
183 183 o 1:27547f69f254 public test B
184 184 |
185 185 o 0:4a2df7238c3b public test A
186 186
187 187 Removing a head from the original repository by merging it
188 188
189 189 $ cd ../repo
190 190 $ hg merge -r 6 -q
191 191 $ hg commit -m Merge
192 192 $ echo I > I
193 193 $ hg commit -A -m H -q
194 194 $ hg log -G
195 195 @ 9:9d18e5bd9ab0 draft test H
196 196 |
197 197 o 8:71bd7b46de72 draft test Merge
198 198 |\
199 199 | o 7:5cd59d311f65 draft test H
200 200 | |
201 201 o | 6:1d14c3ce6ac0 draft test G
202 202 | |
203 203 | | o 5:7f219660301f draft test F
204 204 | | |
205 205 +---o 4:8a5212ebc852 draft test E
206 206 | |
207 207 | o 3:b3325c91a4d9 draft test D
208 208 | |
209 209 | o 2:f838bfaca5c7 draft test C
210 210 |/
211 211 o 1:27547f69f254 draft test B
212 212 |
213 213 o 0:4a2df7238c3b draft test A
214 214
215 215 Removed heads are reported during transfer and properly accounted for in
216 216 pullop.cgresult
217 217
218 218 $ cd ../clone
219 219 $ hg pull
220 220 pulling from $TESTTMP/repo (glob)
221 221 searching for changes
222 222 remote: changegroup1
223 223 adding changesets
224 224 adding manifests
225 225 adding file changes
226 226 added 1 changesets with 0 changes to 0 files (-1 heads)
227 pretxnchangegroup hook: HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_PENDING=$TESTTMP/clone HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
227 pretxnchangegroup hook: HG_HOOKTYPE=pretxnchangegroup HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_PENDING=$TESTTMP/clone HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
228 228 remote: changegroup2
229 229 adding changesets
230 230 adding manifests
231 231 adding file changes
232 232 added 1 changesets with 1 changes to 1 files
233 pretxnchangegroup hook: HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_PENDING=$TESTTMP/clone HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
234 changegroup hook: HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
235 incoming hook: HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
236 changegroup hook: HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
237 incoming hook: HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
233 pretxnchangegroup hook: HG_HOOKTYPE=pretxnchangegroup HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_PENDING=$TESTTMP/clone HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
234 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
235 incoming hook: HG_HOOKTYPE=incoming HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
236 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
237 incoming hook: HG_HOOKTYPE=incoming HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/repo
238 238 pullop.cgresult is -2
239 239 (run 'hg update' to get a working copy)
240 240 $ hg log -G
241 241 o 9:9d18e5bd9ab0 public test H
242 242 |
243 243 o 8:71bd7b46de72 public test Merge
244 244 |\
245 245 | o 7:5cd59d311f65 public test H
246 246 | |
247 247 o | 6:1d14c3ce6ac0 public test G
248 248 | |
249 249 | | o 5:7f219660301f public test F
250 250 | | |
251 251 +---o 4:8a5212ebc852 public test E
252 252 | |
253 253 | o 3:b3325c91a4d9 public test D
254 254 | |
255 255 | @ 2:f838bfaca5c7 public test C
256 256 |/
257 257 o 1:27547f69f254 public test B
258 258 |
259 259 o 0:4a2df7238c3b public test A
260 260
@@ -1,935 +1,935
1 1 commit hooks can see env vars
2 2 (and post-transaction one are run unlocked)
3 3
4 4
5 5 $ cat > $TESTTMP/txnabort.checkargs.py <<EOF
6 6 > def showargs(ui, repo, hooktype, **kwargs):
7 7 > ui.write('%s python hook: %s\n' % (hooktype, ','.join(sorted(kwargs))))
8 8 > EOF
9 9
10 10 $ hg init a
11 11 $ cd a
12 12 $ cat > .hg/hgrc <<EOF
13 13 > [hooks]
14 14 > commit = sh -c "HG_LOCAL= HG_TAG= printenv.py commit"
15 15 > commit.b = sh -c "HG_LOCAL= HG_TAG= printenv.py commit.b"
16 16 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= printenv.py precommit"
17 17 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxncommit"
18 18 > pretxncommit.tip = hg -q tip
19 19 > pre-identify = sh -c "printenv.py pre-identify 1"
20 20 > pre-cat = sh -c "printenv.py pre-cat"
21 21 > post-cat = sh -c "printenv.py post-cat"
22 22 > pretxnopen = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxnopen"
23 23 > pretxnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxnclose"
24 24 > txnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py txnclose"
25 25 > txnabort.0 = python:$TESTTMP/txnabort.checkargs.py:showargs
26 26 > txnabort.1 = sh -c "HG_LOCAL= HG_TAG= printenv.py txnabort"
27 27 > txnclose.checklock = sh -c "hg debuglock > /dev/null"
28 28 > EOF
29 29 $ echo a > a
30 30 $ hg add a
31 31 $ hg commit -m a
32 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000
33 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
34 pretxncommit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a
32 precommit hook: HG_HOOKTYPE=precommit HG_PARENT1=0000000000000000000000000000000000000000
33 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
34 pretxncommit hook: HG_HOOKTYPE=pretxncommit HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a
35 35 0:cb9a9f314b8b
36 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
37 txnclose hook: HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
38 commit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
39 commit.b hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
36 pretxnclose hook: HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
37 txnclose hook: HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
38 commit hook: HG_HOOKTYPE=commit HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
39 commit.b hook: HG_HOOKTYPE=commit HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
40 40
41 41 $ hg clone . ../b
42 42 updating to branch default
43 43 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 44 $ cd ../b
45 45
46 46 changegroup hooks can see env vars
47 47
48 48 $ cat > .hg/hgrc <<EOF
49 49 > [hooks]
50 50 > prechangegroup = sh -c "printenv.py prechangegroup"
51 51 > changegroup = sh -c "printenv.py changegroup"
52 52 > incoming = sh -c "printenv.py incoming"
53 53 > EOF
54 54
55 55 pretxncommit and commit hooks can see both parents of merge
56 56
57 57 $ cd ../a
58 58 $ echo b >> a
59 59 $ hg commit -m a1 -d "1 0"
60 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
61 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
62 pretxncommit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
60 precommit hook: HG_HOOKTYPE=precommit HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
61 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
62 pretxncommit hook: HG_HOOKTYPE=pretxncommit HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
63 63 1:ab228980c14d
64 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
65 txnclose hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
66 commit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
67 commit.b hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
64 pretxnclose hook: HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
65 txnclose hook: HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
66 commit hook: HG_HOOKTYPE=commit HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
67 commit.b hook: HG_HOOKTYPE=commit HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
68 68 $ hg update -C 0
69 69 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 70 $ echo b > b
71 71 $ hg add b
72 72 $ hg commit -m b -d '1 0'
73 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
74 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
75 pretxncommit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
73 precommit hook: HG_HOOKTYPE=precommit HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
74 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
75 pretxncommit hook: HG_HOOKTYPE=pretxncommit HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
76 76 2:ee9deb46ab31
77 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
77 pretxnclose hook: HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
78 78 created new head
79 txnclose hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
80 commit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
81 commit.b hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
79 txnclose hook: HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
80 commit hook: HG_HOOKTYPE=commit HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
81 commit.b hook: HG_HOOKTYPE=commit HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
82 82 $ hg merge 1
83 83 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 84 (branch merge, don't forget to commit)
85 85 $ hg commit -m merge -d '2 0'
86 precommit hook: HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
87 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
88 pretxncommit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a
86 precommit hook: HG_HOOKTYPE=precommit HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
87 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
88 pretxncommit hook: HG_HOOKTYPE=pretxncommit HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a
89 89 3:07f3376c1e65
90 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
91 txnclose hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
92 commit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
93 commit.b hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
90 pretxnclose hook: HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
91 txnclose hook: HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
92 commit hook: HG_HOOKTYPE=commit HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
93 commit.b hook: HG_HOOKTYPE=commit HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
94 94
95 95 test generic hooks
96 96
97 97 $ hg id
98 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=[]
98 pre-identify hook: HG_ARGS=id HG_HOOKTYPE=pre-identify HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None} HG_PATS=[]
99 99 abort: pre-identify hook exited with status 1
100 100 [255]
101 101 $ hg cat b
102 pre-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b']
102 pre-cat hook: HG_ARGS=cat b HG_HOOKTYPE=pre-cat HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b']
103 103 b
104 post-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b'] HG_RESULT=0
104 post-cat hook: HG_ARGS=cat b HG_HOOKTYPE=post-cat HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b'] HG_RESULT=0
105 105
106 106 $ cd ../b
107 107 $ hg pull ../a
108 108 pulling from ../a
109 109 searching for changes
110 prechangegroup hook: HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
110 prechangegroup hook: HG_HOOKTYPE=prechangegroup HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
111 111 adding changesets
112 112 adding manifests
113 113 adding file changes
114 114 added 3 changesets with 2 changes to 2 files
115 changegroup hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_NODE_LAST=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
116 incoming hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
117 incoming hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
118 incoming hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
115 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_NODE_LAST=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
116 incoming hook: HG_HOOKTYPE=incoming HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
117 incoming hook: HG_HOOKTYPE=incoming HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
118 incoming hook: HG_HOOKTYPE=incoming HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
119 119 (run 'hg update' to get a working copy)
120 120
121 121 tag hooks can see env vars
122 122
123 123 $ cd ../a
124 124 $ cat >> .hg/hgrc <<EOF
125 125 > pretag = sh -c "printenv.py pretag"
126 126 > tag = sh -c "HG_PARENT1= HG_PARENT2= printenv.py tag"
127 127 > EOF
128 128 $ hg tag -d '3 0' a
129 pretag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
130 precommit hook: HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
131 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
132 pretxncommit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
129 pretag hook: HG_HOOKTYPE=pretag HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
130 precommit hook: HG_HOOKTYPE=precommit HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
131 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
132 pretxncommit hook: HG_HOOKTYPE=pretxncommit HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
133 133 4:539e4b31b6dc
134 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
135 tag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
136 txnclose hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
137 commit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
138 commit.b hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
134 pretxnclose hook: HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
135 tag hook: HG_HOOKTYPE=tag HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
136 txnclose hook: HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
137 commit hook: HG_HOOKTYPE=commit HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
138 commit.b hook: HG_HOOKTYPE=commit HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
139 139 $ hg tag -l la
140 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
141 tag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
140 pretag hook: HG_HOOKTYPE=pretag HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
141 tag hook: HG_HOOKTYPE=tag HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
142 142
143 143 pretag hook can forbid tagging
144 144
145 145 $ cat >> .hg/hgrc <<EOF
146 146 > pretag.forbid = sh -c "printenv.py pretag.forbid 1"
147 147 > EOF
148 148 $ hg tag -d '4 0' fa
149 pretag hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
150 pretag.forbid hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
149 pretag hook: HG_HOOKTYPE=pretag HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
150 pretag.forbid hook: HG_HOOKTYPE=pretag HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
151 151 abort: pretag.forbid hook exited with status 1
152 152 [255]
153 153 $ hg tag -l fla
154 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
155 pretag.forbid hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
154 pretag hook: HG_HOOKTYPE=pretag HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
155 pretag.forbid hook: HG_HOOKTYPE=pretag HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
156 156 abort: pretag.forbid hook exited with status 1
157 157 [255]
158 158
159 159 pretxncommit hook can see changeset, can roll back txn, changeset no
160 160 more there after
161 161
162 162 $ cat >> .hg/hgrc <<EOF
163 163 > pretxncommit.forbid0 = sh -c "hg tip -q"
164 164 > pretxncommit.forbid1 = sh -c "printenv.py pretxncommit.forbid 1"
165 165 > EOF
166 166 $ echo z > z
167 167 $ hg add z
168 168 $ hg -q tip
169 169 4:539e4b31b6dc
170 170 $ hg commit -m 'fail' -d '4 0'
171 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
172 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
173 pretxncommit hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
171 precommit hook: HG_HOOKTYPE=precommit HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
172 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
173 pretxncommit hook: HG_HOOKTYPE=pretxncommit HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
174 174 5:6f611f8018c1
175 175 5:6f611f8018c1
176 pretxncommit.forbid hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
176 pretxncommit.forbid hook: HG_HOOKTYPE=pretxncommit HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
177 177 transaction abort!
178 178 txnabort python hook: txnid,txnname
179 txnabort hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
179 txnabort hook: HG_HOOKTYPE=txnabort HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
180 180 rollback completed
181 181 abort: pretxncommit.forbid1 hook exited with status 1
182 182 [255]
183 183 $ hg -q tip
184 184 4:539e4b31b6dc
185 185
186 186 (Check that no 'changelog.i.a' file were left behind)
187 187
188 188 $ ls -1 .hg/store/
189 189 00changelog.i
190 190 00manifest.i
191 191 data
192 192 fncache
193 193 journal.phaseroots
194 194 phaseroots
195 195 undo
196 196 undo.backup.fncache
197 197 undo.backupfiles
198 198 undo.phaseroots
199 199
200 200
201 201 precommit hook can prevent commit
202 202
203 203 $ cat >> .hg/hgrc <<EOF
204 204 > precommit.forbid = sh -c "printenv.py precommit.forbid 1"
205 205 > EOF
206 206 $ hg commit -m 'fail' -d '4 0'
207 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
208 precommit.forbid hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
207 precommit hook: HG_HOOKTYPE=precommit HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
208 precommit.forbid hook: HG_HOOKTYPE=precommit HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
209 209 abort: precommit.forbid hook exited with status 1
210 210 [255]
211 211 $ hg -q tip
212 212 4:539e4b31b6dc
213 213
214 214 preupdate hook can prevent update
215 215
216 216 $ cat >> .hg/hgrc <<EOF
217 217 > preupdate = sh -c "printenv.py preupdate"
218 218 > EOF
219 219 $ hg update 1
220 preupdate hook: HG_PARENT1=ab228980c14d
220 preupdate hook: HG_HOOKTYPE=preupdate HG_PARENT1=ab228980c14d
221 221 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
222 222
223 223 update hook
224 224
225 225 $ cat >> .hg/hgrc <<EOF
226 226 > update = sh -c "printenv.py update"
227 227 > EOF
228 228 $ hg update
229 preupdate hook: HG_PARENT1=539e4b31b6dc
230 update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
229 preupdate hook: HG_HOOKTYPE=preupdate HG_PARENT1=539e4b31b6dc
230 update hook: HG_ERROR=0 HG_HOOKTYPE=update HG_PARENT1=539e4b31b6dc
231 231 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
232 232
233 233 pushkey hook
234 234
235 235 $ cat >> .hg/hgrc <<EOF
236 236 > pushkey = sh -c "printenv.py pushkey"
237 237 > EOF
238 238 $ cd ../b
239 239 $ hg bookmark -r null foo
240 240 $ hg push -B foo ../a
241 241 pushing to ../a
242 242 searching for changes
243 243 no changes found
244 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=push
245 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_PENDING=$TESTTMP/a HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/a
246 pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1
247 txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/a
244 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=push
245 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/a
246 pushkey hook: HG_HOOKTYPE=pushkey HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1
247 txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKTYPE=txnclose HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/a
248 248 exporting bookmark foo
249 249 [1]
250 250 $ cd ../a
251 251
252 252 listkeys hook
253 253
254 254 $ cat >> .hg/hgrc <<EOF
255 255 > listkeys = sh -c "printenv.py listkeys"
256 256 > EOF
257 257 $ hg bookmark -r null bar
258 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
259 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
260 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
258 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
259 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
260 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
261 261 $ cd ../b
262 262 $ hg pull -B bar ../a
263 263 pulling from ../a
264 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
264 listkeys hook: HG_HOOKTYPE=listkeys HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
265 265 no changes found
266 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
266 listkeys hook: HG_HOOKTYPE=listkeys HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
267 267 adding remote bookmark bar
268 268 $ cd ../a
269 269
270 270 test that prepushkey can prevent incoming keys
271 271
272 272 $ cat >> .hg/hgrc <<EOF
273 273 > prepushkey = sh -c "printenv.py prepushkey.forbid 1"
274 274 > EOF
275 275 $ cd ../b
276 276 $ hg bookmark -r null baz
277 277 $ hg push -B baz ../a
278 278 pushing to ../a
279 279 searching for changes
280 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
281 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
280 listkeys hook: HG_HOOKTYPE=listkeys HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
281 listkeys hook: HG_HOOKTYPE=listkeys HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
282 282 no changes found
283 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=push
284 prepushkey.forbid hook: HG_BUNDLE2=1 HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
283 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=push
284 prepushkey.forbid hook: HG_BUNDLE2=1 HG_HOOKTYPE=prepushkey HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
285 285 pushkey-abort: prepushkey hook exited with status 1
286 286 abort: exporting bookmark baz failed!
287 287 [255]
288 288 $ cd ../a
289 289
290 290 test that prelistkeys can prevent listing keys
291 291
292 292 $ cat >> .hg/hgrc <<EOF
293 293 > prelistkeys = sh -c "printenv.py prelistkeys.forbid 1"
294 294 > EOF
295 295 $ hg bookmark -r null quux
296 pretxnopen hook: HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
297 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
298 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
296 pretxnopen hook: HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
297 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
298 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
299 299 $ cd ../b
300 300 $ hg pull -B quux ../a
301 301 pulling from ../a
302 prelistkeys.forbid hook: HG_NAMESPACE=bookmarks
302 prelistkeys.forbid hook: HG_HOOKTYPE=prelistkeys HG_NAMESPACE=bookmarks
303 303 abort: prelistkeys hook exited with status 1
304 304 [255]
305 305 $ cd ../a
306 306 $ rm .hg/hgrc
307 307
308 308 prechangegroup hook can prevent incoming changes
309 309
310 310 $ cd ../b
311 311 $ hg -q tip
312 312 3:07f3376c1e65
313 313 $ cat > .hg/hgrc <<EOF
314 314 > [hooks]
315 315 > prechangegroup.forbid = sh -c "printenv.py prechangegroup.forbid 1"
316 316 > EOF
317 317 $ hg pull ../a
318 318 pulling from ../a
319 319 searching for changes
320 prechangegroup.forbid hook: HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
320 prechangegroup.forbid hook: HG_HOOKTYPE=prechangegroup HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
321 321 abort: prechangegroup.forbid hook exited with status 1
322 322 [255]
323 323
324 324 pretxnchangegroup hook can see incoming changes, can roll back txn,
325 325 incoming changes no longer there after
326 326
327 327 $ cat > .hg/hgrc <<EOF
328 328 > [hooks]
329 329 > pretxnchangegroup.forbid0 = hg tip -q
330 330 > pretxnchangegroup.forbid1 = sh -c "printenv.py pretxnchangegroup.forbid 1"
331 331 > EOF
332 332 $ hg pull ../a
333 333 pulling from ../a
334 334 searching for changes
335 335 adding changesets
336 336 adding manifests
337 337 adding file changes
338 338 added 1 changesets with 1 changes to 1 files
339 339 4:539e4b31b6dc
340 pretxnchangegroup.forbid hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_NODE_LAST=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/b HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
340 pretxnchangegroup.forbid hook: HG_HOOKTYPE=pretxnchangegroup HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_NODE_LAST=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/b HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
341 341 transaction abort!
342 342 rollback completed
343 343 abort: pretxnchangegroup.forbid1 hook exited with status 1
344 344 [255]
345 345 $ hg -q tip
346 346 3:07f3376c1e65
347 347
348 348 outgoing hooks can see env vars
349 349
350 350 $ rm .hg/hgrc
351 351 $ cat > ../a/.hg/hgrc <<EOF
352 352 > [hooks]
353 353 > preoutgoing = sh -c "printenv.py preoutgoing"
354 354 > outgoing = sh -c "printenv.py outgoing"
355 355 > EOF
356 356 $ hg pull ../a
357 357 pulling from ../a
358 358 searching for changes
359 preoutgoing hook: HG_SOURCE=pull
360 outgoing hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
359 preoutgoing hook: HG_HOOKTYPE=preoutgoing HG_SOURCE=pull
360 outgoing hook: HG_HOOKTYPE=outgoing HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
361 361 adding changesets
362 362 adding manifests
363 363 adding file changes
364 364 added 1 changesets with 1 changes to 1 files
365 365 adding remote bookmark quux
366 366 (run 'hg update' to get a working copy)
367 367 $ hg rollback
368 368 repository tip rolled back to revision 3 (undo pull)
369 369
370 370 preoutgoing hook can prevent outgoing changes
371 371
372 372 $ cat >> ../a/.hg/hgrc <<EOF
373 373 > preoutgoing.forbid = sh -c "printenv.py preoutgoing.forbid 1"
374 374 > EOF
375 375 $ hg pull ../a
376 376 pulling from ../a
377 377 searching for changes
378 preoutgoing hook: HG_SOURCE=pull
379 preoutgoing.forbid hook: HG_SOURCE=pull
378 preoutgoing hook: HG_HOOKTYPE=preoutgoing HG_SOURCE=pull
379 preoutgoing.forbid hook: HG_HOOKTYPE=preoutgoing HG_SOURCE=pull
380 380 abort: preoutgoing.forbid hook exited with status 1
381 381 [255]
382 382
383 383 outgoing hooks work for local clones
384 384
385 385 $ cd ..
386 386 $ cat > a/.hg/hgrc <<EOF
387 387 > [hooks]
388 388 > preoutgoing = sh -c "printenv.py preoutgoing"
389 389 > outgoing = sh -c "printenv.py outgoing"
390 390 > EOF
391 391 $ hg clone a c
392 preoutgoing hook: HG_SOURCE=clone
393 outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
392 preoutgoing hook: HG_HOOKTYPE=preoutgoing HG_SOURCE=clone
393 outgoing hook: HG_HOOKTYPE=outgoing HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
394 394 updating to branch default
395 395 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
396 396 $ rm -rf c
397 397
398 398 preoutgoing hook can prevent outgoing changes for local clones
399 399
400 400 $ cat >> a/.hg/hgrc <<EOF
401 401 > preoutgoing.forbid = sh -c "printenv.py preoutgoing.forbid 1"
402 402 > EOF
403 403 $ hg clone a zzz
404 preoutgoing hook: HG_SOURCE=clone
405 preoutgoing.forbid hook: HG_SOURCE=clone
404 preoutgoing hook: HG_HOOKTYPE=preoutgoing HG_SOURCE=clone
405 preoutgoing.forbid hook: HG_HOOKTYPE=preoutgoing HG_SOURCE=clone
406 406 abort: preoutgoing.forbid hook exited with status 1
407 407 [255]
408 408
409 409 $ cd "$TESTTMP/b"
410 410
411 411 $ cat > hooktests.py <<EOF
412 412 > from mercurial import error
413 413 >
414 414 > uncallable = 0
415 415 >
416 416 > def printargs(args):
417 417 > args.pop('ui', None)
418 418 > args.pop('repo', None)
419 419 > a = list(args.items())
420 420 > a.sort()
421 421 > print 'hook args:'
422 422 > for k, v in a:
423 423 > print ' ', k, v
424 424 >
425 425 > def passhook(**args):
426 426 > printargs(args)
427 427 >
428 428 > def failhook(**args):
429 429 > printargs(args)
430 430 > return True
431 431 >
432 432 > class LocalException(Exception):
433 433 > pass
434 434 >
435 435 > def raisehook(**args):
436 436 > raise LocalException('exception from hook')
437 437 >
438 438 > def aborthook(**args):
439 439 > raise error.Abort('raise abort from hook')
440 440 >
441 441 > def brokenhook(**args):
442 442 > return 1 + {}
443 443 >
444 444 > def verbosehook(ui, **args):
445 445 > ui.note('verbose output from hook\n')
446 446 >
447 447 > def printtags(ui, repo, **args):
448 448 > print sorted(repo.tags())
449 449 >
450 450 > class container:
451 451 > unreachable = 1
452 452 > EOF
453 453
454 454 $ cat > syntaxerror.py << EOF
455 455 > (foo
456 456 > EOF
457 457
458 458 test python hooks
459 459
460 460 #if windows
461 461 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
462 462 #else
463 463 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
464 464 #endif
465 465 $ export PYTHONPATH
466 466
467 467 $ echo '[hooks]' > ../a/.hg/hgrc
468 468 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
469 469 $ hg pull ../a 2>&1 | grep 'raised an exception'
470 470 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
471 471
472 472 $ echo '[hooks]' > ../a/.hg/hgrc
473 473 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
474 474 $ hg pull ../a 2>&1 | grep 'raised an exception'
475 475 error: preoutgoing.raise hook raised an exception: exception from hook
476 476
477 477 $ echo '[hooks]' > ../a/.hg/hgrc
478 478 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
479 479 $ hg pull ../a
480 480 pulling from ../a
481 481 searching for changes
482 482 error: preoutgoing.abort hook failed: raise abort from hook
483 483 abort: raise abort from hook
484 484 [255]
485 485
486 486 $ echo '[hooks]' > ../a/.hg/hgrc
487 487 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
488 488 $ hg pull ../a
489 489 pulling from ../a
490 490 searching for changes
491 491 hook args:
492 492 hooktype preoutgoing
493 493 source pull
494 494 abort: preoutgoing.fail hook failed
495 495 [255]
496 496
497 497 $ echo '[hooks]' > ../a/.hg/hgrc
498 498 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
499 499 $ hg pull ../a
500 500 pulling from ../a
501 501 searching for changes
502 502 abort: preoutgoing.uncallable hook is invalid: "hooktests.uncallable" is not callable
503 503 [255]
504 504
505 505 $ echo '[hooks]' > ../a/.hg/hgrc
506 506 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
507 507 $ hg pull ../a
508 508 pulling from ../a
509 509 searching for changes
510 510 abort: preoutgoing.nohook hook is invalid: "hooktests.nohook" is not defined
511 511 [255]
512 512
513 513 $ echo '[hooks]' > ../a/.hg/hgrc
514 514 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
515 515 $ hg pull ../a
516 516 pulling from ../a
517 517 searching for changes
518 518 abort: preoutgoing.nomodule hook is invalid: "nomodule" not in a module
519 519 [255]
520 520
521 521 $ echo '[hooks]' > ../a/.hg/hgrc
522 522 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
523 523 $ hg pull ../a
524 524 pulling from ../a
525 525 searching for changes
526 526 abort: preoutgoing.badmodule hook is invalid: import of "nomodule" failed
527 527 (run with --traceback for stack trace)
528 528 [255]
529 529
530 530 $ echo '[hooks]' > ../a/.hg/hgrc
531 531 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
532 532 $ hg pull ../a
533 533 pulling from ../a
534 534 searching for changes
535 535 abort: preoutgoing.unreachable hook is invalid: import of "hooktests.container" failed
536 536 (run with --traceback for stack trace)
537 537 [255]
538 538
539 539 $ echo '[hooks]' > ../a/.hg/hgrc
540 540 $ echo 'preoutgoing.syntaxerror = python:syntaxerror.syntaxerror' >> ../a/.hg/hgrc
541 541 $ hg pull ../a
542 542 pulling from ../a
543 543 searching for changes
544 544 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
545 545 (run with --traceback for stack trace)
546 546 [255]
547 547
548 548 The second egrep is to filter out lines like ' ^', which are slightly
549 549 different between Python 2.6 and Python 2.7.
550 550 $ hg pull ../a --traceback 2>&1 | egrep -v '^( +File| [_a-zA-Z*(])' | egrep -v '^( )+(\^)?$'
551 551 pulling from ../a
552 552 searching for changes
553 553 exception from first failed import attempt:
554 554 Traceback (most recent call last):
555 555 SyntaxError: * (glob)
556 556 exception from second failed import attempt:
557 557 Traceback (most recent call last):
558 558 ImportError: No module named hgext_syntaxerror
559 559 Traceback (most recent call last):
560 560 HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
561 561 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
562 562
563 563 $ echo '[hooks]' > ../a/.hg/hgrc
564 564 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
565 565 $ hg pull ../a
566 566 pulling from ../a
567 567 searching for changes
568 568 hook args:
569 569 hooktype preoutgoing
570 570 source pull
571 571 adding changesets
572 572 adding manifests
573 573 adding file changes
574 574 added 1 changesets with 1 changes to 1 files
575 575 adding remote bookmark quux
576 576 (run 'hg update' to get a working copy)
577 577
578 578 post- python hooks that fail to *run* don't cause an abort
579 579 $ rm ../a/.hg/hgrc
580 580 $ echo '[hooks]' > .hg/hgrc
581 581 $ echo 'post-pull.broken = python:hooktests.brokenhook' >> .hg/hgrc
582 582 $ hg pull ../a
583 583 pulling from ../a
584 584 searching for changes
585 585 no changes found
586 586 error: post-pull.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
587 587 (run with --traceback for stack trace)
588 588
589 589 but post- python hooks that fail to *load* do
590 590 $ echo '[hooks]' > .hg/hgrc
591 591 $ echo 'post-pull.nomodule = python:nomodule' >> .hg/hgrc
592 592 $ hg pull ../a
593 593 pulling from ../a
594 594 searching for changes
595 595 no changes found
596 596 abort: post-pull.nomodule hook is invalid: "nomodule" not in a module
597 597 [255]
598 598
599 599 $ echo '[hooks]' > .hg/hgrc
600 600 $ echo 'post-pull.badmodule = python:nomodule.nowhere' >> .hg/hgrc
601 601 $ hg pull ../a
602 602 pulling from ../a
603 603 searching for changes
604 604 no changes found
605 605 abort: post-pull.badmodule hook is invalid: import of "nomodule" failed
606 606 (run with --traceback for stack trace)
607 607 [255]
608 608
609 609 $ echo '[hooks]' > .hg/hgrc
610 610 $ echo 'post-pull.nohook = python:hooktests.nohook' >> .hg/hgrc
611 611 $ hg pull ../a
612 612 pulling from ../a
613 613 searching for changes
614 614 no changes found
615 615 abort: post-pull.nohook hook is invalid: "hooktests.nohook" is not defined
616 616 [255]
617 617
618 618 make sure --traceback works
619 619
620 620 $ echo '[hooks]' > .hg/hgrc
621 621 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
622 622
623 623 $ echo aa > a
624 624 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
625 625 Traceback (most recent call last):
626 626
627 627 $ cd ..
628 628 $ hg init c
629 629 $ cd c
630 630
631 631 $ cat > hookext.py <<EOF
632 632 > def autohook(**args):
633 633 > print "Automatically installed hook"
634 634 >
635 635 > def reposetup(ui, repo):
636 636 > repo.ui.setconfig("hooks", "commit.auto", autohook)
637 637 > EOF
638 638 $ echo '[extensions]' >> .hg/hgrc
639 639 $ echo 'hookext = hookext.py' >> .hg/hgrc
640 640
641 641 $ touch foo
642 642 $ hg add foo
643 643 $ hg ci -d '0 0' -m 'add foo'
644 644 Automatically installed hook
645 645 $ echo >> foo
646 646 $ hg ci --debug -d '0 0' -m 'change foo'
647 647 committing files:
648 648 foo
649 649 committing manifest
650 650 committing changelog
651 651 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
652 652 calling hook commit.auto: hgext_hookext.autohook
653 653 Automatically installed hook
654 654
655 655 $ hg showconfig hooks
656 656 hooks.commit.auto=<function autohook at *> (glob)
657 657
658 658 test python hook configured with python:[file]:[hook] syntax
659 659
660 660 $ cd ..
661 661 $ mkdir d
662 662 $ cd d
663 663 $ hg init repo
664 664 $ mkdir hooks
665 665
666 666 $ cd hooks
667 667 $ cat > testhooks.py <<EOF
668 668 > def testhook(**args):
669 669 > print 'hook works'
670 670 > EOF
671 671 $ echo '[hooks]' > ../repo/.hg/hgrc
672 672 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
673 673
674 674 $ cd ../repo
675 675 $ hg commit -d '0 0'
676 676 hook works
677 677 nothing changed
678 678 [1]
679 679
680 680 $ echo '[hooks]' > .hg/hgrc
681 681 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
682 682 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
683 683
684 684 $ hg up null
685 685 loading update.ne hook failed:
686 686 abort: No such file or directory: $TESTTMP/d/repo/nonexistent.py
687 687 [255]
688 688
689 689 $ hg id
690 690 loading pre-identify.npmd hook failed:
691 691 abort: No module named repo!
692 692 [255]
693 693
694 694 $ cd ../../b
695 695
696 696 make sure --traceback works on hook import failure
697 697
698 698 $ cat > importfail.py <<EOF
699 699 > import somebogusmodule
700 700 > # dereference something in the module to force demandimport to load it
701 701 > somebogusmodule.whatever
702 702 > EOF
703 703
704 704 $ echo '[hooks]' > .hg/hgrc
705 705 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
706 706
707 707 $ echo a >> a
708 708 $ hg --traceback commit -ma 2>&1 | egrep -v '^( +File| [a-zA-Z(])'
709 709 exception from first failed import attempt:
710 710 Traceback (most recent call last):
711 711 ImportError: No module named somebogusmodule
712 712 exception from second failed import attempt:
713 713 Traceback (most recent call last):
714 714 ImportError: No module named hgext_importfail
715 715 Traceback (most recent call last):
716 716 HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed
717 717 abort: precommit.importfail hook is invalid: import of "importfail" failed
718 718
719 719 Issue1827: Hooks Update & Commit not completely post operation
720 720
721 721 commit and update hooks should run after command completion. The largefiles
722 722 use demonstrates a recursive wlock, showing the hook doesn't run until the
723 723 final release (and dirstate flush).
724 724
725 725 $ echo '[hooks]' > .hg/hgrc
726 726 $ echo 'commit = hg id' >> .hg/hgrc
727 727 $ echo 'update = hg id' >> .hg/hgrc
728 728 $ echo bb > a
729 729 $ hg ci -ma
730 730 223eafe2750c tip
731 731 $ hg up 0 --config extensions.largefiles=
732 732 cb9a9f314b8b
733 733 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
734 734
735 735 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
736 736 that is passed to pre/post hooks
737 737
738 738 $ echo '[hooks]' > .hg/hgrc
739 739 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
740 740 $ hg id
741 741 cb9a9f314b8b
742 742 $ hg id --verbose
743 743 calling hook pre-identify: hooktests.verbosehook
744 744 verbose output from hook
745 745 cb9a9f314b8b
746 746
747 747 Ensure hooks can be prioritized
748 748
749 749 $ echo '[hooks]' > .hg/hgrc
750 750 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
751 751 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
752 752 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
753 753 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
754 754 $ hg id --verbose
755 755 calling hook pre-identify.b: hooktests.verbosehook
756 756 verbose output from hook
757 757 calling hook pre-identify.a: hooktests.verbosehook
758 758 verbose output from hook
759 759 calling hook pre-identify.c: hooktests.verbosehook
760 760 verbose output from hook
761 761 cb9a9f314b8b
762 762
763 763 new tags must be visible in pretxncommit (issue3210)
764 764
765 765 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
766 766 $ hg tag -f foo
767 767 ['a', 'foo', 'tip']
768 768
769 769 post-init hooks must not crash (issue4983)
770 770 This also creates the `to` repo for the next test block.
771 771
772 772 $ cd ..
773 773 $ cat << EOF >> hgrc-with-post-init-hook
774 774 > [hooks]
775 775 > post-init = sh -c "printenv.py post-init"
776 776 > EOF
777 777 $ HGRCPATH=hgrc-with-post-init-hook hg init to
778 post-init hook: HG_ARGS=init to HG_OPTS={'insecure': None, 'remotecmd': '', 'ssh': ''} HG_PATS=['to'] HG_RESULT=0
778 post-init hook: HG_ARGS=init to HG_HOOKTYPE=post-init HG_OPTS={'insecure': None, 'remotecmd': '', 'ssh': ''} HG_PATS=['to'] HG_RESULT=0
779 779
780 780 new commits must be visible in pretxnchangegroup (issue3428)
781 781
782 782 $ echo '[hooks]' >> to/.hg/hgrc
783 783 $ echo 'prechangegroup = hg --traceback tip' >> to/.hg/hgrc
784 784 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
785 785 $ echo a >> to/a
786 786 $ hg --cwd to ci -Ama
787 787 adding a
788 788 $ hg clone to from
789 789 updating to branch default
790 790 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
791 791 $ echo aa >> from/a
792 792 $ hg --cwd from ci -mb
793 793 $ hg --cwd from push
794 794 pushing to $TESTTMP/to (glob)
795 795 searching for changes
796 796 changeset: 0:cb9a9f314b8b
797 797 tag: tip
798 798 user: test
799 799 date: Thu Jan 01 00:00:00 1970 +0000
800 800 summary: a
801 801
802 802 adding changesets
803 803 adding manifests
804 804 adding file changes
805 805 added 1 changesets with 1 changes to 1 files
806 806 changeset: 1:9836a07b9b9d
807 807 tag: tip
808 808 user: test
809 809 date: Thu Jan 01 00:00:00 1970 +0000
810 810 summary: b
811 811
812 812
813 813 pretxnclose hook failure should abort the transaction
814 814
815 815 $ hg init txnfailure
816 816 $ cd txnfailure
817 817 $ touch a && hg commit -Aqm a
818 818 $ cat >> .hg/hgrc <<EOF
819 819 > [hooks]
820 820 > pretxnclose.error = exit 1
821 821 > EOF
822 822 $ hg strip -r 0 --config extensions.strip=
823 823 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
824 824 saved backup bundle to * (glob)
825 825 transaction abort!
826 826 rollback completed
827 827 strip failed, backup bundle stored in * (glob)
828 828 abort: pretxnclose.error hook exited with status 1
829 829 [255]
830 830 $ hg recover
831 831 no interrupted transaction available
832 832 [1]
833 833 $ cd ..
834 834
835 835 check whether HG_PENDING makes pending changes only in related
836 836 repositories visible to an external hook.
837 837
838 838 (emulate a transaction running concurrently by copied
839 839 .hg/store/00changelog.i.a in subsequent test)
840 840
841 841 $ cat > $TESTTMP/savepending.sh <<EOF
842 842 > cp .hg/store/00changelog.i.a .hg/store/00changelog.i.a.saved
843 843 > exit 1 # to avoid adding new revision for subsequent tests
844 844 > EOF
845 845 $ cd a
846 846 $ hg tip -q
847 847 4:539e4b31b6dc
848 848 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" commit -m "invisible"
849 849 transaction abort!
850 850 rollback completed
851 851 abort: pretxnclose hook exited with status 1
852 852 [255]
853 853 $ cp .hg/store/00changelog.i.a.saved .hg/store/00changelog.i.a
854 854
855 855 (check (in)visibility of new changeset while transaction running in
856 856 repo)
857 857
858 858 $ cat > $TESTTMP/checkpending.sh <<EOF
859 859 > echo '@a'
860 860 > hg -R $TESTTMP/a tip -q
861 861 > echo '@a/nested'
862 862 > hg -R $TESTTMP/a/nested tip -q
863 863 > exit 1 # to avoid adding new revision for subsequent tests
864 864 > EOF
865 865 $ hg init nested
866 866 $ cd nested
867 867 $ echo a > a
868 868 $ hg add a
869 869 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" commit -m '#0'
870 870 @a
871 871 4:539e4b31b6dc
872 872 @a/nested
873 873 0:bf5e395ced2c
874 874 transaction abort!
875 875 rollback completed
876 876 abort: pretxnclose hook exited with status 1
877 877 [255]
878 878
879 879 Hook from untrusted hgrc are reported as failure
880 880 ================================================
881 881
882 882 $ cat << EOF > $TESTTMP/untrusted.py
883 883 > from mercurial import scmutil, util
884 884 > def uisetup(ui):
885 885 > class untrustedui(ui.__class__):
886 886 > def _trusted(self, fp, f):
887 887 > if util.normpath(fp.name).endswith('untrusted/.hg/hgrc'):
888 888 > return False
889 889 > return super(untrustedui, self)._trusted(fp, f)
890 890 > ui.__class__ = untrustedui
891 891 > EOF
892 892 $ cat << EOF >> $HGRCPATH
893 893 > [extensions]
894 894 > untrusted=$TESTTMP/untrusted.py
895 895 > EOF
896 896 $ hg init untrusted
897 897 $ cd untrusted
898 898
899 899 Non-blocking hook
900 900 -----------------
901 901
902 902 $ cat << EOF >> .hg/hgrc
903 903 > [hooks]
904 904 > txnclose.testing=echo txnclose hook called
905 905 > EOF
906 906 $ touch a && hg commit -Aqm a
907 907 warning: untrusted hook txnclose.testing not executed
908 908 $ hg log
909 909 changeset: 0:3903775176ed
910 910 tag: tip
911 911 user: test
912 912 date: Thu Jan 01 00:00:00 1970 +0000
913 913 summary: a
914 914
915 915
916 916 Non-blocking hook
917 917 -----------------
918 918
919 919 $ cat << EOF >> .hg/hgrc
920 920 > [hooks]
921 921 > pretxnclose.testing=echo pre-txnclose hook called
922 922 > EOF
923 923 $ touch b && hg commit -Aqm a
924 924 transaction abort!
925 925 rollback completed
926 926 abort: untrusted hook pretxnclose.testing not executed
927 927 (see 'hg help config.trusted')
928 928 [255]
929 929 $ hg log
930 930 changeset: 0:3903775176ed
931 931 tag: tip
932 932 user: test
933 933 date: Thu Jan 01 00:00:00 1970 +0000
934 934 summary: a
935 935
@@ -1,347 +1,347
1 1 #require serve
2 2
3 3 This test is a duplicate of 'test-http.t', feel free to factor out
4 4 parts that are not bundle1/bundle2 specific.
5 5
6 6 $ cat << EOF >> $HGRCPATH
7 7 > [devel]
8 8 > # This test is dedicated to interaction through old bundle
9 9 > legacy.exchange = bundle1
10 10 > EOF
11 11
12 12 $ hg init test
13 13 $ cd test
14 14 $ echo foo>foo
15 15 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
16 16 $ echo foo>foo.d/foo
17 17 $ echo bar>foo.d/bAr.hg.d/BaR
18 18 $ echo bar>foo.d/baR.d.hg/bAR
19 19 $ hg commit -A -m 1
20 20 adding foo
21 21 adding foo.d/bAr.hg.d/BaR
22 22 adding foo.d/baR.d.hg/bAR
23 23 adding foo.d/foo
24 24 $ hg serve -p $HGPORT -d --pid-file=../hg1.pid -E ../error.log
25 25 $ hg serve --config server.uncompressed=False -p $HGPORT1 -d --pid-file=../hg2.pid
26 26
27 27 Test server address cannot be reused
28 28
29 29 #if windows
30 30 $ hg serve -p $HGPORT1 2>&1
31 31 abort: cannot start server at 'localhost:$HGPORT1': * (glob)
32 32 [255]
33 33 #else
34 34 $ hg serve -p $HGPORT1 2>&1
35 35 abort: cannot start server at 'localhost:$HGPORT1': Address already in use
36 36 [255]
37 37 #endif
38 38 $ cd ..
39 39 $ cat hg1.pid hg2.pid >> $DAEMON_PIDS
40 40
41 41 clone via stream
42 42
43 43 $ hg clone --uncompressed http://localhost:$HGPORT/ copy 2>&1
44 44 streaming all changes
45 45 6 files to transfer, 606 bytes of data
46 46 transferred * bytes in * seconds (*/sec) (glob)
47 47 searching for changes
48 48 no changes found
49 49 updating to branch default
50 50 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 51 $ hg verify -R copy
52 52 checking changesets
53 53 checking manifests
54 54 crosschecking files in changesets and manifests
55 55 checking files
56 56 4 files, 1 changesets, 4 total revisions
57 57
58 58 try to clone via stream, should use pull instead
59 59
60 60 $ hg clone --uncompressed http://localhost:$HGPORT1/ copy2
61 61 requesting all changes
62 62 adding changesets
63 63 adding manifests
64 64 adding file changes
65 65 added 1 changesets with 4 changes to 4 files
66 66 updating to branch default
67 67 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
68 68
69 69 clone via pull
70 70
71 71 $ hg clone http://localhost:$HGPORT1/ copy-pull
72 72 requesting all changes
73 73 adding changesets
74 74 adding manifests
75 75 adding file changes
76 76 added 1 changesets with 4 changes to 4 files
77 77 updating to branch default
78 78 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 79 $ hg verify -R copy-pull
80 80 checking changesets
81 81 checking manifests
82 82 crosschecking files in changesets and manifests
83 83 checking files
84 84 4 files, 1 changesets, 4 total revisions
85 85 $ cd test
86 86 $ echo bar > bar
87 87 $ hg commit -A -d '1 0' -m 2
88 88 adding bar
89 89 $ cd ..
90 90
91 91 clone over http with --update
92 92
93 93 $ hg clone http://localhost:$HGPORT1/ updated --update 0
94 94 requesting all changes
95 95 adding changesets
96 96 adding manifests
97 97 adding file changes
98 98 added 2 changesets with 5 changes to 5 files
99 99 updating to branch default
100 100 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
101 101 $ hg log -r . -R updated
102 102 changeset: 0:8b6053c928fe
103 103 user: test
104 104 date: Thu Jan 01 00:00:00 1970 +0000
105 105 summary: 1
106 106
107 107 $ rm -rf updated
108 108
109 109 incoming via HTTP
110 110
111 111 $ hg clone http://localhost:$HGPORT1/ --rev 0 partial
112 112 adding changesets
113 113 adding manifests
114 114 adding file changes
115 115 added 1 changesets with 4 changes to 4 files
116 116 updating to branch default
117 117 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 118 $ cd partial
119 119 $ touch LOCAL
120 120 $ hg ci -qAm LOCAL
121 121 $ hg incoming http://localhost:$HGPORT1/ --template '{desc}\n'
122 122 comparing with http://localhost:$HGPORT1/
123 123 searching for changes
124 124 2
125 125 $ cd ..
126 126
127 127 pull
128 128
129 129 $ cd copy-pull
130 130 $ cat >> .hg/hgrc <<EOF
131 131 > [hooks]
132 132 > changegroup = sh -c "printenv.py changegroup"
133 133 > EOF
134 134 $ hg pull
135 135 pulling from http://localhost:$HGPORT1/
136 136 searching for changes
137 137 adding changesets
138 138 adding manifests
139 139 adding file changes
140 140 added 1 changesets with 1 changes to 1 files
141 changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=http://localhost:$HGPORT1/
141 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=http://localhost:$HGPORT1/
142 142 (run 'hg update' to get a working copy)
143 143 $ cd ..
144 144
145 145 clone from invalid URL
146 146
147 147 $ hg clone http://localhost:$HGPORT/bad
148 148 abort: HTTP Error 404: Not Found
149 149 [255]
150 150
151 151 test http authentication
152 152 + use the same server to test server side streaming preference
153 153
154 154 $ cd test
155 155 $ cat << EOT > userpass.py
156 156 > import base64
157 157 > from mercurial.hgweb import common
158 158 > def perform_authentication(hgweb, req, op):
159 159 > auth = req.env.get('HTTP_AUTHORIZATION')
160 160 > if not auth:
161 161 > raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, 'who',
162 162 > [('WWW-Authenticate', 'Basic Realm="mercurial"')])
163 163 > if base64.b64decode(auth.split()[1]).split(':', 1) != ['user', 'pass']:
164 164 > raise common.ErrorResponse(common.HTTP_FORBIDDEN, 'no')
165 165 > def extsetup():
166 166 > common.permhooks.insert(0, perform_authentication)
167 167 > EOT
168 168 $ hg serve --config extensions.x=userpass.py -p $HGPORT2 -d --pid-file=pid \
169 169 > --config server.preferuncompressed=True \
170 170 > --config web.push_ssl=False --config web.allow_push=* -A ../access.log
171 171 $ cat pid >> $DAEMON_PIDS
172 172
173 173 $ cat << EOF > get_pass.py
174 174 > import getpass
175 175 > def newgetpass(arg):
176 176 > return "pass"
177 177 > getpass.getpass = newgetpass
178 178 > EOF
179 179
180 180 $ hg id http://localhost:$HGPORT2/
181 181 abort: http authorization required for http://localhost:$HGPORT2/
182 182 [255]
183 183 $ hg id http://localhost:$HGPORT2/
184 184 abort: http authorization required for http://localhost:$HGPORT2/
185 185 [255]
186 186 $ hg id --config ui.interactive=true --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
187 187 http authorization required for http://localhost:$HGPORT2/
188 188 realm: mercurial
189 189 user: user
190 190 password: 5fed3813f7f5
191 191 $ hg id http://user:pass@localhost:$HGPORT2/
192 192 5fed3813f7f5
193 193 $ echo '[auth]' >> .hg/hgrc
194 194 $ echo 'l.schemes=http' >> .hg/hgrc
195 195 $ echo 'l.prefix=lo' >> .hg/hgrc
196 196 $ echo 'l.username=user' >> .hg/hgrc
197 197 $ echo 'l.password=pass' >> .hg/hgrc
198 198 $ hg id http://localhost:$HGPORT2/
199 199 5fed3813f7f5
200 200 $ hg id http://localhost:$HGPORT2/
201 201 5fed3813f7f5
202 202 $ hg id http://user@localhost:$HGPORT2/
203 203 5fed3813f7f5
204 204 $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
205 205 streaming all changes
206 206 7 files to transfer, 916 bytes of data
207 207 transferred * bytes in * seconds (*/sec) (glob)
208 208 searching for changes
209 209 no changes found
210 210 updating to branch default
211 211 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 212 --pull should override server's preferuncompressed
213 213 $ hg clone --pull http://user:pass@localhost:$HGPORT2/ dest-pull 2>&1
214 214 requesting all changes
215 215 adding changesets
216 216 adding manifests
217 217 adding file changes
218 218 added 2 changesets with 5 changes to 5 files
219 219 updating to branch default
220 220 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 221
222 222 $ hg id http://user2@localhost:$HGPORT2/
223 223 abort: http authorization required for http://localhost:$HGPORT2/
224 224 [255]
225 225 $ hg id http://user:pass2@localhost:$HGPORT2/
226 226 abort: HTTP Error 403: no
227 227 [255]
228 228
229 229 $ hg -R dest tag -r tip top
230 230 $ hg -R dest push http://user:pass@localhost:$HGPORT2/
231 231 pushing to http://user:***@localhost:$HGPORT2/
232 232 searching for changes
233 233 remote: adding changesets
234 234 remote: adding manifests
235 235 remote: adding file changes
236 236 remote: added 1 changesets with 1 changes to 1 files
237 237 $ hg rollback -q
238 238
239 239 $ sed 's/.*] "/"/' < ../access.log
240 240 "GET /?cmd=capabilities HTTP/1.1" 200 -
241 241 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
242 242 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
243 243 "GET /?cmd=capabilities HTTP/1.1" 200 -
244 244 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
245 245 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
246 246 "GET /?cmd=capabilities HTTP/1.1" 200 -
247 247 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
248 248 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
249 249 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
250 250 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
251 251 "GET /?cmd=capabilities HTTP/1.1" 200 -
252 252 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
253 253 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
254 254 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
255 255 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
256 256 "GET /?cmd=capabilities HTTP/1.1" 200 -
257 257 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
258 258 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
259 259 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
260 260 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
261 261 "GET /?cmd=capabilities HTTP/1.1" 200 -
262 262 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
263 263 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
264 264 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
265 265 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
266 266 "GET /?cmd=capabilities HTTP/1.1" 200 -
267 267 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
268 268 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
269 269 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
270 270 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
271 271 "GET /?cmd=capabilities HTTP/1.1" 200 -
272 272 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
273 273 "GET /?cmd=stream_out HTTP/1.1" 401 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
274 274 "GET /?cmd=stream_out HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
275 275 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
276 276 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D5fed3813f7f5e1824344fdc9cf8f63bb662c292d x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
277 277 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
278 278 "GET /?cmd=capabilities HTTP/1.1" 200 -
279 279 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
280 280 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
281 281 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
282 282 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
283 283 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
284 284 "GET /?cmd=capabilities HTTP/1.1" 200 -
285 285 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
286 286 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
287 287 "GET /?cmd=capabilities HTTP/1.1" 200 -
288 288 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
289 289 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
290 290 "GET /?cmd=listkeys HTTP/1.1" 403 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
291 291 "GET /?cmd=capabilities HTTP/1.1" 200 -
292 292 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872 x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
293 293 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
294 294 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
295 295 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
296 296 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
297 297 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
298 298 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
299 299 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=686173686564+5eb5abfefeea63c80dd7553bcc3783f37e0c5524* (glob)
300 300 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
301 301
302 302 $ cd ..
303 303
304 304 clone of serve with repo in root and unserved subrepo (issue2970)
305 305
306 306 $ hg --cwd test init sub
307 307 $ echo empty > test/sub/empty
308 308 $ hg --cwd test/sub add empty
309 309 $ hg --cwd test/sub commit -qm 'add empty'
310 310 $ hg --cwd test/sub tag -r 0 something
311 311 $ echo sub = sub > test/.hgsub
312 312 $ hg --cwd test add .hgsub
313 313 $ hg --cwd test commit -qm 'add subrepo'
314 314 $ hg clone http://localhost:$HGPORT noslash-clone
315 315 requesting all changes
316 316 adding changesets
317 317 adding manifests
318 318 adding file changes
319 319 added 3 changesets with 7 changes to 7 files
320 320 updating to branch default
321 321 abort: HTTP Error 404: Not Found
322 322 [255]
323 323 $ hg clone http://localhost:$HGPORT/ slash-clone
324 324 requesting all changes
325 325 adding changesets
326 326 adding manifests
327 327 adding file changes
328 328 added 3 changesets with 7 changes to 7 files
329 329 updating to branch default
330 330 abort: HTTP Error 404: Not Found
331 331 [255]
332 332
333 333 check error log
334 334
335 335 $ cat error.log
336 336
337 337 Check error reporting while pulling/cloning
338 338
339 339 $ $RUNTESTDIR/killdaemons.py
340 340 $ hg -R test serve -p $HGPORT -d --pid-file=hg3.pid -E error.log --config extensions.crash=${TESTDIR}/crashgetbundler.py
341 341 $ cat hg3.pid >> $DAEMON_PIDS
342 342 $ hg clone http://localhost:$HGPORT/ abort-clone
343 343 requesting all changes
344 344 abort: remote error:
345 345 this is an exercise
346 346 [255]
347 347 $ cat error.log
@@ -1,335 +1,335
1 1 #require serve
2 2
3 3 $ hg init test
4 4 $ cd test
5 5 $ echo foo>foo
6 6 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
7 7 $ echo foo>foo.d/foo
8 8 $ echo bar>foo.d/bAr.hg.d/BaR
9 9 $ echo bar>foo.d/baR.d.hg/bAR
10 10 $ hg commit -A -m 1
11 11 adding foo
12 12 adding foo.d/bAr.hg.d/BaR
13 13 adding foo.d/baR.d.hg/bAR
14 14 adding foo.d/foo
15 15 $ hg serve -p $HGPORT -d --pid-file=../hg1.pid -E ../error.log
16 16 $ hg serve --config server.uncompressed=False -p $HGPORT1 -d --pid-file=../hg2.pid
17 17
18 18 Test server address cannot be reused
19 19
20 20 #if windows
21 21 $ hg serve -p $HGPORT1 2>&1
22 22 abort: cannot start server at ':$HGPORT1': * (glob)
23 23 [255]
24 24 #else
25 25 $ hg serve -p $HGPORT1 2>&1
26 26 abort: cannot start server at 'localhost:$HGPORT1': Address already in use
27 27 [255]
28 28 #endif
29 29 $ cd ..
30 30 $ cat hg1.pid hg2.pid >> $DAEMON_PIDS
31 31
32 32 clone via stream
33 33
34 34 $ hg clone --uncompressed http://localhost:$HGPORT/ copy 2>&1
35 35 streaming all changes
36 36 6 files to transfer, 606 bytes of data
37 37 transferred * bytes in * seconds (*/sec) (glob)
38 38 searching for changes
39 39 no changes found
40 40 updating to branch default
41 41 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 42 $ hg verify -R copy
43 43 checking changesets
44 44 checking manifests
45 45 crosschecking files in changesets and manifests
46 46 checking files
47 47 4 files, 1 changesets, 4 total revisions
48 48
49 49 try to clone via stream, should use pull instead
50 50
51 51 $ hg clone --uncompressed http://localhost:$HGPORT1/ copy2
52 52 requesting all changes
53 53 adding changesets
54 54 adding manifests
55 55 adding file changes
56 56 added 1 changesets with 4 changes to 4 files
57 57 updating to branch default
58 58 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 59
60 60 clone via pull
61 61
62 62 $ hg clone http://localhost:$HGPORT1/ copy-pull
63 63 requesting all changes
64 64 adding changesets
65 65 adding manifests
66 66 adding file changes
67 67 added 1 changesets with 4 changes to 4 files
68 68 updating to branch default
69 69 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 70 $ hg verify -R copy-pull
71 71 checking changesets
72 72 checking manifests
73 73 crosschecking files in changesets and manifests
74 74 checking files
75 75 4 files, 1 changesets, 4 total revisions
76 76 $ cd test
77 77 $ echo bar > bar
78 78 $ hg commit -A -d '1 0' -m 2
79 79 adding bar
80 80 $ cd ..
81 81
82 82 clone over http with --update
83 83
84 84 $ hg clone http://localhost:$HGPORT1/ updated --update 0
85 85 requesting all changes
86 86 adding changesets
87 87 adding manifests
88 88 adding file changes
89 89 added 2 changesets with 5 changes to 5 files
90 90 updating to branch default
91 91 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 92 $ hg log -r . -R updated
93 93 changeset: 0:8b6053c928fe
94 94 user: test
95 95 date: Thu Jan 01 00:00:00 1970 +0000
96 96 summary: 1
97 97
98 98 $ rm -rf updated
99 99
100 100 incoming via HTTP
101 101
102 102 $ hg clone http://localhost:$HGPORT1/ --rev 0 partial
103 103 adding changesets
104 104 adding manifests
105 105 adding file changes
106 106 added 1 changesets with 4 changes to 4 files
107 107 updating to branch default
108 108 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 109 $ cd partial
110 110 $ touch LOCAL
111 111 $ hg ci -qAm LOCAL
112 112 $ hg incoming http://localhost:$HGPORT1/ --template '{desc}\n'
113 113 comparing with http://localhost:$HGPORT1/
114 114 searching for changes
115 115 2
116 116 $ cd ..
117 117
118 118 pull
119 119
120 120 $ cd copy-pull
121 121 $ cat >> .hg/hgrc <<EOF
122 122 > [hooks]
123 123 > changegroup = sh -c "printenv.py changegroup"
124 124 > EOF
125 125 $ hg pull
126 126 pulling from http://localhost:$HGPORT1/
127 127 searching for changes
128 128 adding changesets
129 129 adding manifests
130 130 adding file changes
131 131 added 1 changesets with 1 changes to 1 files
132 changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=http://localhost:$HGPORT1/
132 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=http://localhost:$HGPORT1/
133 133 (run 'hg update' to get a working copy)
134 134 $ cd ..
135 135
136 136 clone from invalid URL
137 137
138 138 $ hg clone http://localhost:$HGPORT/bad
139 139 abort: HTTP Error 404: Not Found
140 140 [255]
141 141
142 142 test http authentication
143 143 + use the same server to test server side streaming preference
144 144
145 145 $ cd test
146 146 $ cat << EOT > userpass.py
147 147 > import base64
148 148 > from mercurial.hgweb import common
149 149 > def perform_authentication(hgweb, req, op):
150 150 > auth = req.env.get('HTTP_AUTHORIZATION')
151 151 > if not auth:
152 152 > raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, 'who',
153 153 > [('WWW-Authenticate', 'Basic Realm="mercurial"')])
154 154 > if base64.b64decode(auth.split()[1]).split(':', 1) != ['user', 'pass']:
155 155 > raise common.ErrorResponse(common.HTTP_FORBIDDEN, 'no')
156 156 > def extsetup():
157 157 > common.permhooks.insert(0, perform_authentication)
158 158 > EOT
159 159 $ hg serve --config extensions.x=userpass.py -p $HGPORT2 -d --pid-file=pid \
160 160 > --config server.preferuncompressed=True \
161 161 > --config web.push_ssl=False --config web.allow_push=* -A ../access.log
162 162 $ cat pid >> $DAEMON_PIDS
163 163
164 164 $ cat << EOF > get_pass.py
165 165 > import getpass
166 166 > def newgetpass(arg):
167 167 > return "pass"
168 168 > getpass.getpass = newgetpass
169 169 > EOF
170 170
171 171 $ hg id http://localhost:$HGPORT2/
172 172 abort: http authorization required for http://localhost:$HGPORT2/
173 173 [255]
174 174 $ hg id http://localhost:$HGPORT2/
175 175 abort: http authorization required for http://localhost:$HGPORT2/
176 176 [255]
177 177 $ hg id --config ui.interactive=true --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
178 178 http authorization required for http://localhost:$HGPORT2/
179 179 realm: mercurial
180 180 user: user
181 181 password: 5fed3813f7f5
182 182 $ hg id http://user:pass@localhost:$HGPORT2/
183 183 5fed3813f7f5
184 184 $ echo '[auth]' >> .hg/hgrc
185 185 $ echo 'l.schemes=http' >> .hg/hgrc
186 186 $ echo 'l.prefix=lo' >> .hg/hgrc
187 187 $ echo 'l.username=user' >> .hg/hgrc
188 188 $ echo 'l.password=pass' >> .hg/hgrc
189 189 $ hg id http://localhost:$HGPORT2/
190 190 5fed3813f7f5
191 191 $ hg id http://localhost:$HGPORT2/
192 192 5fed3813f7f5
193 193 $ hg id http://user@localhost:$HGPORT2/
194 194 5fed3813f7f5
195 195 $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
196 196 streaming all changes
197 197 7 files to transfer, 916 bytes of data
198 198 transferred * bytes in * seconds (*/sec) (glob)
199 199 searching for changes
200 200 no changes found
201 201 updating to branch default
202 202 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
203 203 --pull should override server's preferuncompressed
204 204 $ hg clone --pull http://user:pass@localhost:$HGPORT2/ dest-pull 2>&1
205 205 requesting all changes
206 206 adding changesets
207 207 adding manifests
208 208 adding file changes
209 209 added 2 changesets with 5 changes to 5 files
210 210 updating to branch default
211 211 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 212
213 213 $ hg id http://user2@localhost:$HGPORT2/
214 214 abort: http authorization required for http://localhost:$HGPORT2/
215 215 [255]
216 216 $ hg id http://user:pass2@localhost:$HGPORT2/
217 217 abort: HTTP Error 403: no
218 218 [255]
219 219
220 220 $ hg -R dest tag -r tip top
221 221 $ hg -R dest push http://user:pass@localhost:$HGPORT2/
222 222 pushing to http://user:***@localhost:$HGPORT2/
223 223 searching for changes
224 224 remote: adding changesets
225 225 remote: adding manifests
226 226 remote: adding file changes
227 227 remote: added 1 changesets with 1 changes to 1 files
228 228 $ hg rollback -q
229 229
230 230 $ sed 's/.*] "/"/' < ../access.log
231 231 "GET /?cmd=capabilities HTTP/1.1" 200 -
232 232 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
233 233 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
234 234 "GET /?cmd=capabilities HTTP/1.1" 200 -
235 235 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
236 236 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
237 237 "GET /?cmd=capabilities HTTP/1.1" 200 -
238 238 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
239 239 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
240 240 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
241 241 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
242 242 "GET /?cmd=capabilities HTTP/1.1" 200 -
243 243 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
244 244 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
245 245 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
246 246 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
247 247 "GET /?cmd=capabilities HTTP/1.1" 200 -
248 248 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
249 249 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
250 250 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
251 251 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
252 252 "GET /?cmd=capabilities HTTP/1.1" 200 -
253 253 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
254 254 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
255 255 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
256 256 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
257 257 "GET /?cmd=capabilities HTTP/1.1" 200 -
258 258 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
259 259 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
260 260 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
261 261 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
262 262 "GET /?cmd=capabilities HTTP/1.1" 200 -
263 263 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
264 264 "GET /?cmd=stream_out HTTP/1.1" 401 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
265 265 "GET /?cmd=stream_out HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
266 266 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D5fed3813f7f5e1824344fdc9cf8f63bb662c292d x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
267 267 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=phases%2Cbookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
268 268 "GET /?cmd=capabilities HTTP/1.1" 200 -
269 269 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
270 270 "GET /?cmd=getbundle HTTP/1.1" 401 - x-hgarg-1:bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=phases%2Cbookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
271 271 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=phases%2Cbookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
272 272 "GET /?cmd=capabilities HTTP/1.1" 200 -
273 273 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
274 274 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
275 275 "GET /?cmd=capabilities HTTP/1.1" 200 -
276 276 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
277 277 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
278 278 "GET /?cmd=listkeys HTTP/1.1" 403 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
279 279 "GET /?cmd=capabilities HTTP/1.1" 200 -
280 280 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872 x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
281 281 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
282 282 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
283 283 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
284 284 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
285 285 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
286 286 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
287 287 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365* (glob)
288 288 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=*zlib,none,bzip2 (glob)
289 289
290 290 $ cd ..
291 291
292 292 clone of serve with repo in root and unserved subrepo (issue2970)
293 293
294 294 $ hg --cwd test init sub
295 295 $ echo empty > test/sub/empty
296 296 $ hg --cwd test/sub add empty
297 297 $ hg --cwd test/sub commit -qm 'add empty'
298 298 $ hg --cwd test/sub tag -r 0 something
299 299 $ echo sub = sub > test/.hgsub
300 300 $ hg --cwd test add .hgsub
301 301 $ hg --cwd test commit -qm 'add subrepo'
302 302 $ hg clone http://localhost:$HGPORT noslash-clone
303 303 requesting all changes
304 304 adding changesets
305 305 adding manifests
306 306 adding file changes
307 307 added 3 changesets with 7 changes to 7 files
308 308 updating to branch default
309 309 abort: HTTP Error 404: Not Found
310 310 [255]
311 311 $ hg clone http://localhost:$HGPORT/ slash-clone
312 312 requesting all changes
313 313 adding changesets
314 314 adding manifests
315 315 adding file changes
316 316 added 3 changesets with 7 changes to 7 files
317 317 updating to branch default
318 318 abort: HTTP Error 404: Not Found
319 319 [255]
320 320
321 321 check error log
322 322
323 323 $ cat error.log
324 324
325 325 check abort error reporting while pulling/cloning
326 326
327 327 $ $RUNTESTDIR/killdaemons.py
328 328 $ hg -R test serve -p $HGPORT -d --pid-file=hg3.pid -E error.log --config extensions.crash=${TESTDIR}/crashgetbundler.py
329 329 $ cat hg3.pid >> $DAEMON_PIDS
330 330 $ hg clone http://localhost:$HGPORT/ abort-clone
331 331 requesting all changes
332 332 remote: abort: this is an exercise
333 333 abort: pull failed on remote
334 334 [255]
335 335 $ cat error.log
@@ -1,644 +1,644
1 1 #require serve ssl
2 2
3 3 Proper https client requires the built-in ssl from Python 2.6.
4 4
5 5 Make server certificates:
6 6
7 7 $ CERTSDIR="$TESTDIR/sslcerts"
8 8 $ cat "$CERTSDIR/priv.pem" "$CERTSDIR/pub.pem" >> server.pem
9 9 $ PRIV=`pwd`/server.pem
10 10 $ cat "$CERTSDIR/priv.pem" "$CERTSDIR/pub-not-yet.pem" > server-not-yet.pem
11 11 $ cat "$CERTSDIR/priv.pem" "$CERTSDIR/pub-expired.pem" > server-expired.pem
12 12
13 13 $ hg init test
14 14 $ cd test
15 15 $ echo foo>foo
16 16 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
17 17 $ echo foo>foo.d/foo
18 18 $ echo bar>foo.d/bAr.hg.d/BaR
19 19 $ echo bar>foo.d/baR.d.hg/bAR
20 20 $ hg commit -A -m 1
21 21 adding foo
22 22 adding foo.d/bAr.hg.d/BaR
23 23 adding foo.d/baR.d.hg/bAR
24 24 adding foo.d/foo
25 25 $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV
26 26 $ cat ../hg0.pid >> $DAEMON_PIDS
27 27
28 28 cacert not found
29 29
30 30 $ hg in --config web.cacerts=no-such.pem https://localhost:$HGPORT/
31 31 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
32 32 abort: could not find web.cacerts: no-such.pem
33 33 [255]
34 34
35 35 Test server address cannot be reused
36 36
37 37 #if windows
38 38 $ hg serve -p $HGPORT --certificate=$PRIV 2>&1
39 39 abort: cannot start server at 'localhost:$HGPORT':
40 40 [255]
41 41 #else
42 42 $ hg serve -p $HGPORT --certificate=$PRIV 2>&1
43 43 abort: cannot start server at 'localhost:$HGPORT': Address already in use
44 44 [255]
45 45 #endif
46 46 $ cd ..
47 47
48 48 Our test cert is not signed by a trusted CA. It should fail to verify if
49 49 we are able to load CA certs.
50 50
51 51 #if sslcontext defaultcacerts no-defaultcacertsloaded
52 52 $ hg clone https://localhost:$HGPORT/ copy-pull
53 53 (an attempt was made to load CA certificates but none were loaded; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error)
54 54 abort: error: *certificate verify failed* (glob)
55 55 [255]
56 56 #endif
57 57
58 58 #if no-sslcontext defaultcacerts
59 59 $ hg clone https://localhost:$HGPORT/ copy-pull
60 60 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
61 61 (using CA certificates from *; if you see this message, your Mercurial install is not properly configured; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message) (glob) (?)
62 62 abort: error: *certificate verify failed* (glob)
63 63 [255]
64 64 #endif
65 65
66 66 #if no-sslcontext windows
67 67 $ hg clone https://localhost:$HGPORT/ copy-pull
68 68 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
69 69 (unable to load Windows CA certificates; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message)
70 70 abort: error: *certificate verify failed* (glob)
71 71 [255]
72 72 #endif
73 73
74 74 #if no-sslcontext osx
75 75 $ hg clone https://localhost:$HGPORT/ copy-pull
76 76 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
77 77 (unable to load CA certificates; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message)
78 78 abort: localhost certificate error: no certificate received
79 79 (set hostsecurity.localhost:certfingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e config setting or use --insecure to connect insecurely)
80 80 [255]
81 81 #endif
82 82
83 83 #if defaultcacertsloaded
84 84 $ hg clone https://localhost:$HGPORT/ copy-pull
85 85 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
86 86 (using CA certificates from *; if you see this message, your Mercurial install is not properly configured; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message) (glob) (?)
87 87 abort: error: *certificate verify failed* (glob)
88 88 [255]
89 89 #endif
90 90
91 91 #if no-defaultcacerts
92 92 $ hg clone https://localhost:$HGPORT/ copy-pull
93 93 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
94 94 (unable to load * certificates; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message) (glob) (?)
95 95 abort: localhost certificate error: no certificate received
96 96 (set hostsecurity.localhost:certfingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e config setting or use --insecure to connect insecurely)
97 97 [255]
98 98 #endif
99 99
100 100 Specifying a per-host certificate file that doesn't exist will abort
101 101
102 102 $ hg --config hostsecurity.localhost:verifycertsfile=/does/not/exist clone https://localhost:$HGPORT/
103 103 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
104 104 abort: path specified by hostsecurity.localhost:verifycertsfile does not exist: /does/not/exist
105 105 [255]
106 106
107 107 A malformed per-host certificate file will raise an error
108 108
109 109 $ echo baddata > badca.pem
110 110 #if sslcontext
111 111 $ hg --config hostsecurity.localhost:verifycertsfile=badca.pem clone https://localhost:$HGPORT/
112 112 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
113 113 abort: error loading CA file badca.pem: * (glob)
114 114 (file is empty or malformed?)
115 115 [255]
116 116 #else
117 117 $ hg --config hostsecurity.localhost:verifycertsfile=badca.pem clone https://localhost:$HGPORT/
118 118 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
119 119 abort: error: * (glob)
120 120 [255]
121 121 #endif
122 122
123 123 A per-host certificate mismatching the server will fail verification
124 124
125 125 (modern ssl is able to discern whether the loaded cert is a CA cert)
126 126 #if sslcontext
127 127 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/client-cert.pem" clone https://localhost:$HGPORT/
128 128 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
129 129 (an attempt was made to load CA certificates but none were loaded; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error)
130 130 abort: error: *certificate verify failed* (glob)
131 131 [255]
132 132 #else
133 133 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/client-cert.pem" clone https://localhost:$HGPORT/
134 134 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
135 135 abort: error: *certificate verify failed* (glob)
136 136 [255]
137 137 #endif
138 138
139 139 A per-host certificate matching the server's cert will be accepted
140 140
141 141 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/pub.pem" clone -U https://localhost:$HGPORT/ perhostgood1
142 142 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
143 143 requesting all changes
144 144 adding changesets
145 145 adding manifests
146 146 adding file changes
147 147 added 1 changesets with 4 changes to 4 files
148 148
149 149 A per-host certificate with multiple certs and one matching will be accepted
150 150
151 151 $ cat "$CERTSDIR/client-cert.pem" "$CERTSDIR/pub.pem" > perhost.pem
152 152 $ hg --config hostsecurity.localhost:verifycertsfile=perhost.pem clone -U https://localhost:$HGPORT/ perhostgood2
153 153 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
154 154 requesting all changes
155 155 adding changesets
156 156 adding manifests
157 157 adding file changes
158 158 added 1 changesets with 4 changes to 4 files
159 159
160 160 Defining both per-host certificate and a fingerprint will print a warning
161 161
162 162 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/pub.pem" --config hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03 clone -U https://localhost:$HGPORT/ caandfingerwarning
163 163 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
164 164 (hostsecurity.localhost:verifycertsfile ignored when host fingerprints defined; using host fingerprints for verification)
165 165 requesting all changes
166 166 adding changesets
167 167 adding manifests
168 168 adding file changes
169 169 added 1 changesets with 4 changes to 4 files
170 170
171 171 $ DISABLECACERTS="--config devel.disableloaddefaultcerts=true"
172 172
173 173 Inability to verify peer certificate will result in abort
174 174
175 175 $ hg clone https://localhost:$HGPORT/ copy-pull $DISABLECACERTS
176 176 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
177 177 abort: unable to verify security of localhost (no loaded CA certificates); refusing to connect
178 178 (see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error or set hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e to trust this server)
179 179 [255]
180 180
181 181 $ hg clone --insecure https://localhost:$HGPORT/ copy-pull
182 182 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
183 183 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
184 184 requesting all changes
185 185 adding changesets
186 186 adding manifests
187 187 adding file changes
188 188 added 1 changesets with 4 changes to 4 files
189 189 updating to branch default
190 190 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 191 $ hg verify -R copy-pull
192 192 checking changesets
193 193 checking manifests
194 194 crosschecking files in changesets and manifests
195 195 checking files
196 196 4 files, 1 changesets, 4 total revisions
197 197 $ cd test
198 198 $ echo bar > bar
199 199 $ hg commit -A -d '1 0' -m 2
200 200 adding bar
201 201 $ cd ..
202 202
203 203 pull without cacert
204 204
205 205 $ cd copy-pull
206 206 $ cat >> .hg/hgrc <<EOF
207 207 > [hooks]
208 208 > changegroup = sh -c "printenv.py changegroup"
209 209 > EOF
210 210 $ hg pull $DISABLECACERTS
211 211 pulling from https://localhost:$HGPORT/
212 212 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
213 213 abort: unable to verify security of localhost (no loaded CA certificates); refusing to connect
214 214 (see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error or set hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e to trust this server)
215 215 [255]
216 216
217 217 $ hg pull --insecure
218 218 pulling from https://localhost:$HGPORT/
219 219 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
220 220 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
221 221 searching for changes
222 222 adding changesets
223 223 adding manifests
224 224 adding file changes
225 225 added 1 changesets with 1 changes to 1 files
226 changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=https://localhost:$HGPORT/
226 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=https://localhost:$HGPORT/
227 227 (run 'hg update' to get a working copy)
228 228 $ cd ..
229 229
230 230 cacert configured in local repo
231 231
232 232 $ cp copy-pull/.hg/hgrc copy-pull/.hg/hgrc.bu
233 233 $ echo "[web]" >> copy-pull/.hg/hgrc
234 234 $ echo "cacerts=$CERTSDIR/pub.pem" >> copy-pull/.hg/hgrc
235 235 $ hg -R copy-pull pull
236 236 pulling from https://localhost:$HGPORT/
237 237 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
238 238 searching for changes
239 239 no changes found
240 240 $ mv copy-pull/.hg/hgrc.bu copy-pull/.hg/hgrc
241 241
242 242 cacert configured globally, also testing expansion of environment
243 243 variables in the filename
244 244
245 245 $ echo "[web]" >> $HGRCPATH
246 246 $ echo 'cacerts=$P/pub.pem' >> $HGRCPATH
247 247 $ P="$CERTSDIR" hg -R copy-pull pull
248 248 pulling from https://localhost:$HGPORT/
249 249 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
250 250 searching for changes
251 251 no changes found
252 252 $ P="$CERTSDIR" hg -R copy-pull pull --insecure
253 253 pulling from https://localhost:$HGPORT/
254 254 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
255 255 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
256 256 searching for changes
257 257 no changes found
258 258
259 259 empty cacert file
260 260
261 261 $ touch emptycafile
262 262
263 263 #if sslcontext
264 264 $ hg --config web.cacerts=emptycafile -R copy-pull pull
265 265 pulling from https://localhost:$HGPORT/
266 266 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
267 267 abort: error loading CA file emptycafile: * (glob)
268 268 (file is empty or malformed?)
269 269 [255]
270 270 #else
271 271 $ hg --config web.cacerts=emptycafile -R copy-pull pull
272 272 pulling from https://localhost:$HGPORT/
273 273 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
274 274 abort: error: * (glob)
275 275 [255]
276 276 #endif
277 277
278 278 cacert mismatch
279 279
280 280 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub.pem" \
281 281 > https://$LOCALIP:$HGPORT/
282 282 pulling from https://*:$HGPORT/ (glob)
283 283 warning: connecting to $LOCALIP using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
284 284 abort: $LOCALIP certificate error: certificate is for localhost
285 285 (set hostsecurity.$LOCALIP:certfingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e config setting or use --insecure to connect insecurely)
286 286 [255]
287 287 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub.pem" \
288 288 > https://$LOCALIP:$HGPORT/ --insecure
289 289 pulling from https://*:$HGPORT/ (glob)
290 290 warning: connecting to $LOCALIP using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
291 291 warning: connection security to $LOCALIP is disabled per current settings; communication is susceptible to eavesdropping and tampering
292 292 searching for changes
293 293 no changes found
294 294 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-other.pem"
295 295 pulling from https://localhost:$HGPORT/
296 296 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
297 297 abort: error: *certificate verify failed* (glob)
298 298 [255]
299 299 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-other.pem" \
300 300 > --insecure
301 301 pulling from https://localhost:$HGPORT/
302 302 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
303 303 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
304 304 searching for changes
305 305 no changes found
306 306
307 307 Test server cert which isn't valid yet
308 308
309 309 $ hg serve -R test -p $HGPORT1 -d --pid-file=hg1.pid --certificate=server-not-yet.pem
310 310 $ cat hg1.pid >> $DAEMON_PIDS
311 311 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-not-yet.pem" \
312 312 > https://localhost:$HGPORT1/
313 313 pulling from https://localhost:$HGPORT1/
314 314 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
315 315 abort: error: *certificate verify failed* (glob)
316 316 [255]
317 317
318 318 Test server cert which no longer is valid
319 319
320 320 $ hg serve -R test -p $HGPORT2 -d --pid-file=hg2.pid --certificate=server-expired.pem
321 321 $ cat hg2.pid >> $DAEMON_PIDS
322 322 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-expired.pem" \
323 323 > https://localhost:$HGPORT2/
324 324 pulling from https://localhost:$HGPORT2/
325 325 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
326 326 abort: error: *certificate verify failed* (glob)
327 327 [255]
328 328
329 329 Disabling the TLS 1.0 warning works
330 330 $ hg -R copy-pull id https://localhost:$HGPORT/ \
331 331 > --config hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03 \
332 332 > --config hostsecurity.disabletls10warning=true
333 333 5fed3813f7f5
334 334
335 335 #if no-sslcontext no-py27+
336 336 Setting ciphers doesn't work in Python 2.6
337 337 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=HIGH -R copy-pull id https://localhost:$HGPORT/
338 338 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
339 339 abort: setting ciphers in [hostsecurity] is not supported by this version of Python
340 340 (remove the config option or run Mercurial with a modern Python version (preferred))
341 341 [255]
342 342 #endif
343 343
344 344 Setting ciphers works in Python 2.7+ but the error message is different on
345 345 legacy ssl. We test legacy once and do more feature checking on modern
346 346 configs.
347 347
348 348 #if py27+ no-sslcontext
349 349 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=invalid -R copy-pull id https://localhost:$HGPORT/
350 350 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
351 351 abort: *No cipher can be selected. (glob)
352 352 [255]
353 353
354 354 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=HIGH -R copy-pull id https://localhost:$HGPORT/
355 355 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
356 356 5fed3813f7f5
357 357 #endif
358 358
359 359 #if sslcontext
360 360 Setting ciphers to an invalid value aborts
361 361 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=invalid -R copy-pull id https://localhost:$HGPORT/
362 362 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
363 363 abort: could not set ciphers: No cipher can be selected.
364 364 (change cipher string (invalid) in config)
365 365 [255]
366 366
367 367 $ P="$CERTSDIR" hg --config hostsecurity.localhost:ciphers=invalid -R copy-pull id https://localhost:$HGPORT/
368 368 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
369 369 abort: could not set ciphers: No cipher can be selected.
370 370 (change cipher string (invalid) in config)
371 371 [255]
372 372
373 373 Changing the cipher string works
374 374
375 375 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=HIGH -R copy-pull id https://localhost:$HGPORT/
376 376 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
377 377 5fed3813f7f5
378 378 #endif
379 379
380 380 Fingerprints
381 381
382 382 - works without cacerts (hostfingerprints)
383 383 $ hg -R copy-pull id https://localhost:$HGPORT/ --insecure --config hostfingerprints.localhost=ec:d8:7c:d6:b3:86:d0:4f:c1:b8:b4:1c:9d:8f:5e:16:8e:ef:1c:03
384 384 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
385 385 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, set the following config value in [hostsecurity] and remove the old one from [hostfingerprints] to upgrade to a more secure SHA-256 fingerprint: localhost.fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
386 386 5fed3813f7f5
387 387
388 388 - works without cacerts (hostsecurity)
389 389 $ hg -R copy-pull id https://localhost:$HGPORT/ --config hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03
390 390 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
391 391 5fed3813f7f5
392 392
393 393 $ hg -R copy-pull id https://localhost:$HGPORT/ --config hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e
394 394 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
395 395 5fed3813f7f5
396 396
397 397 - multiple fingerprints specified and first matches
398 398 $ hg --config 'hostfingerprints.localhost=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03, deadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/ --insecure
399 399 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
400 400 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, set the following config value in [hostsecurity] and remove the old one from [hostfingerprints] to upgrade to a more secure SHA-256 fingerprint: localhost.fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
401 401 5fed3813f7f5
402 402
403 403 $ hg --config 'hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03, sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/
404 404 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
405 405 5fed3813f7f5
406 406
407 407 - multiple fingerprints specified and last matches
408 408 $ hg --config 'hostfingerprints.localhost=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03' -R copy-pull id https://localhost:$HGPORT/ --insecure
409 409 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
410 410 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, set the following config value in [hostsecurity] and remove the old one from [hostfingerprints] to upgrade to a more secure SHA-256 fingerprint: localhost.fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
411 411 5fed3813f7f5
412 412
413 413 $ hg --config 'hostsecurity.localhost:fingerprints=sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03' -R copy-pull id https://localhost:$HGPORT/
414 414 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
415 415 5fed3813f7f5
416 416
417 417 - multiple fingerprints specified and none match
418 418
419 419 $ hg --config 'hostfingerprints.localhost=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, aeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/ --insecure
420 420 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
421 421 abort: certificate for localhost has unexpected fingerprint ec:d8:7c:d6:b3:86:d0:4f:c1:b8:b4:1c:9d:8f:5e:16:8e:ef:1c:03
422 422 (check hostfingerprint configuration)
423 423 [255]
424 424
425 425 $ hg --config 'hostsecurity.localhost:fingerprints=sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, sha1:aeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/
426 426 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
427 427 abort: certificate for localhost has unexpected fingerprint sha1:ec:d8:7c:d6:b3:86:d0:4f:c1:b8:b4:1c:9d:8f:5e:16:8e:ef:1c:03
428 428 (check hostsecurity configuration)
429 429 [255]
430 430
431 431 - fails when cert doesn't match hostname (port is ignored)
432 432 $ hg -R copy-pull id https://localhost:$HGPORT1/ --config hostfingerprints.localhost=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03
433 433 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
434 434 abort: certificate for localhost has unexpected fingerprint f4:2f:5a:0c:3e:52:5b:db:e7:24:a8:32:1d:18:97:6d:69:b5:87:84
435 435 (check hostfingerprint configuration)
436 436 [255]
437 437
438 438
439 439 - ignores that certificate doesn't match hostname
440 440 $ hg -R copy-pull id https://$LOCALIP:$HGPORT/ --config hostfingerprints.$LOCALIP=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03
441 441 warning: connecting to $LOCALIP using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
442 442 (SHA-1 fingerprint for $LOCALIP found in legacy [hostfingerprints] section; if you trust this fingerprint, set the following config value in [hostsecurity] and remove the old one from [hostfingerprints] to upgrade to a more secure SHA-256 fingerprint: $LOCALIP.fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
443 443 5fed3813f7f5
444 444
445 445 Ports used by next test. Kill servers.
446 446
447 447 $ killdaemons.py hg0.pid
448 448 $ killdaemons.py hg1.pid
449 449 $ killdaemons.py hg2.pid
450 450
451 451 #if sslcontext tls1.2
452 452 Start servers running supported TLS versions
453 453
454 454 $ cd test
455 455 $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV \
456 456 > --config devel.serverexactprotocol=tls1.0
457 457 $ cat ../hg0.pid >> $DAEMON_PIDS
458 458 $ hg serve -p $HGPORT1 -d --pid-file=../hg1.pid --certificate=$PRIV \
459 459 > --config devel.serverexactprotocol=tls1.1
460 460 $ cat ../hg1.pid >> $DAEMON_PIDS
461 461 $ hg serve -p $HGPORT2 -d --pid-file=../hg2.pid --certificate=$PRIV \
462 462 > --config devel.serverexactprotocol=tls1.2
463 463 $ cat ../hg2.pid >> $DAEMON_PIDS
464 464 $ cd ..
465 465
466 466 Clients talking same TLS versions work
467 467
468 468 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.0 id https://localhost:$HGPORT/
469 469 5fed3813f7f5
470 470 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.1 id https://localhost:$HGPORT1/
471 471 5fed3813f7f5
472 472 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.2 id https://localhost:$HGPORT2/
473 473 5fed3813f7f5
474 474
475 475 Clients requiring newer TLS version than what server supports fail
476 476
477 477 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/
478 478 (could not negotiate a common security protocol (tls1.1+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
479 479 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
480 480 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
481 481 abort: error: *unsupported protocol* (glob)
482 482 [255]
483 483
484 484 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.1 id https://localhost:$HGPORT/
485 485 (could not negotiate a common security protocol (tls1.1+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
486 486 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
487 487 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
488 488 abort: error: *unsupported protocol* (glob)
489 489 [255]
490 490 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.2 id https://localhost:$HGPORT/
491 491 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
492 492 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
493 493 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
494 494 abort: error: *unsupported protocol* (glob)
495 495 [255]
496 496 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.2 id https://localhost:$HGPORT1/
497 497 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
498 498 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
499 499 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
500 500 abort: error: *unsupported protocol* (glob)
501 501 [255]
502 502
503 503 --insecure will allow TLS 1.0 connections and override configs
504 504
505 505 $ hg --config hostsecurity.minimumprotocol=tls1.2 id --insecure https://localhost:$HGPORT1/
506 506 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
507 507 5fed3813f7f5
508 508
509 509 The per-host config option overrides the default
510 510
511 511 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
512 512 > --config hostsecurity.minimumprotocol=tls1.2 \
513 513 > --config hostsecurity.localhost:minimumprotocol=tls1.0
514 514 5fed3813f7f5
515 515
516 516 The per-host config option by itself works
517 517
518 518 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
519 519 > --config hostsecurity.localhost:minimumprotocol=tls1.2
520 520 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
521 521 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
522 522 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
523 523 abort: error: *unsupported protocol* (glob)
524 524 [255]
525 525
526 526 .hg/hgrc file [hostsecurity] settings are applied to remote ui instances (issue5305)
527 527
528 528 $ cat >> copy-pull/.hg/hgrc << EOF
529 529 > [hostsecurity]
530 530 > localhost:minimumprotocol=tls1.2
531 531 > EOF
532 532 $ P="$CERTSDIR" hg -R copy-pull id https://localhost:$HGPORT/
533 533 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
534 534 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
535 535 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
536 536 abort: error: *unsupported protocol* (glob)
537 537 [255]
538 538
539 539 $ killdaemons.py hg0.pid
540 540 $ killdaemons.py hg1.pid
541 541 $ killdaemons.py hg2.pid
542 542 #endif
543 543
544 544 Prepare for connecting through proxy
545 545
546 546 $ hg serve -R test -p $HGPORT -d --pid-file=hg0.pid --certificate=$PRIV
547 547 $ cat hg0.pid >> $DAEMON_PIDS
548 548 $ hg serve -R test -p $HGPORT2 -d --pid-file=hg2.pid --certificate=server-expired.pem
549 549 $ cat hg2.pid >> $DAEMON_PIDS
550 550 tinyproxy.py doesn't fully detach, so killing it may result in extra output
551 551 from the shell. So don't kill it.
552 552 $ tinyproxy.py $HGPORT1 localhost >proxy.log </dev/null 2>&1 &
553 553 $ while [ ! -f proxy.pid ]; do sleep 0; done
554 554 $ cat proxy.pid >> $DAEMON_PIDS
555 555
556 556 $ echo "[http_proxy]" >> copy-pull/.hg/hgrc
557 557 $ echo "always=True" >> copy-pull/.hg/hgrc
558 558 $ echo "[hostfingerprints]" >> copy-pull/.hg/hgrc
559 559 $ echo "localhost =" >> copy-pull/.hg/hgrc
560 560
561 561 Test unvalidated https through proxy
562 562
563 563 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull --insecure
564 564 pulling from https://localhost:$HGPORT/
565 565 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
566 566 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
567 567 searching for changes
568 568 no changes found
569 569
570 570 Test https with cacert and fingerprint through proxy
571 571
572 572 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull \
573 573 > --config web.cacerts="$CERTSDIR/pub.pem"
574 574 pulling from https://localhost:$HGPORT/
575 575 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
576 576 searching for changes
577 577 no changes found
578 578 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull https://localhost:$HGPORT/ --config hostfingerprints.localhost=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03 --trace
579 579 pulling from https://*:$HGPORT/ (glob)
580 580 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
581 581 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, set the following config value in [hostsecurity] and remove the old one from [hostfingerprints] to upgrade to a more secure SHA-256 fingerprint: localhost.fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
582 582 searching for changes
583 583 no changes found
584 584
585 585 Test https with cert problems through proxy
586 586
587 587 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull \
588 588 > --config web.cacerts="$CERTSDIR/pub-other.pem"
589 589 pulling from https://localhost:$HGPORT/
590 590 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
591 591 abort: error: *certificate verify failed* (glob)
592 592 [255]
593 593 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull \
594 594 > --config web.cacerts="$CERTSDIR/pub-expired.pem" https://localhost:$HGPORT2/
595 595 pulling from https://localhost:$HGPORT2/
596 596 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
597 597 abort: error: *certificate verify failed* (glob)
598 598 [255]
599 599
600 600
601 601 $ killdaemons.py hg0.pid
602 602
603 603 #if sslcontext
604 604
605 605 Start hgweb that requires client certificates:
606 606
607 607 $ cd test
608 608 $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV \
609 609 > --config devel.servercafile=$PRIV --config devel.serverrequirecert=true
610 610 $ cat ../hg0.pid >> $DAEMON_PIDS
611 611 $ cd ..
612 612
613 613 without client certificate:
614 614
615 615 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/
616 616 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
617 617 abort: error: *handshake failure* (glob)
618 618 [255]
619 619
620 620 with client certificate:
621 621
622 622 $ cat << EOT >> $HGRCPATH
623 623 > [auth]
624 624 > l.prefix = localhost
625 625 > l.cert = $CERTSDIR/client-cert.pem
626 626 > l.key = $CERTSDIR/client-key.pem
627 627 > EOT
628 628
629 629 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
630 630 > --config auth.l.key="$CERTSDIR/client-key-decrypted.pem"
631 631 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
632 632 5fed3813f7f5
633 633
634 634 $ printf '1234\n' | env P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
635 635 > --config ui.interactive=True --config ui.nontty=True
636 636 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
637 637 passphrase for */client-key.pem: 5fed3813f7f5 (glob)
638 638
639 639 $ env P="$CERTSDIR" hg id https://localhost:$HGPORT/
640 640 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
641 641 abort: error: * (glob)
642 642 [255]
643 643
644 644 #endif
@@ -1,203 +1,203
1 1 #require killdaemons
2 2
3 3 This test checks behavior related to bundle1 that changed or is likely
4 4 to change with bundle2. Feel free to factor out any part of the test
5 5 which does not need to exist to keep bundle1 working.
6 6
7 7 $ cat << EOF >> $HGRCPATH
8 8 > [devel]
9 9 > # This test is dedicated to interaction through old bundle
10 10 > legacy.exchange = bundle1
11 11 > EOF
12 12
13 13 $ hg init test
14 14 $ cd test
15 15 $ echo a > a
16 16 $ hg ci -Ama
17 17 adding a
18 18 $ cd ..
19 19 $ hg clone test test2
20 20 updating to branch default
21 21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 22 $ cd test2
23 23 $ echo a >> a
24 24 $ hg ci -mb
25 25 $ req() {
26 26 > hg serve -p $HGPORT -d --pid-file=hg.pid -E errors.log
27 27 > cat hg.pid >> $DAEMON_PIDS
28 28 > hg --cwd ../test2 push http://localhost:$HGPORT/
29 29 > exitstatus=$?
30 30 > killdaemons.py
31 31 > echo % serve errors
32 32 > cat errors.log
33 33 > return $exitstatus
34 34 > }
35 35 $ cd ../test
36 36
37 37 expect ssl error
38 38
39 39 $ req
40 40 pushing to http://localhost:$HGPORT/
41 41 searching for changes
42 42 abort: HTTP Error 403: ssl required
43 43 % serve errors
44 44 [255]
45 45
46 46 expect authorization error
47 47
48 48 $ echo '[web]' > .hg/hgrc
49 49 $ echo 'push_ssl = false' >> .hg/hgrc
50 50 $ req
51 51 pushing to http://localhost:$HGPORT/
52 52 searching for changes
53 53 abort: authorization failed
54 54 % serve errors
55 55 [255]
56 56
57 57 expect authorization error: must have authorized user
58 58
59 59 $ echo 'allow_push = unperson' >> .hg/hgrc
60 60 $ req
61 61 pushing to http://localhost:$HGPORT/
62 62 searching for changes
63 63 abort: authorization failed
64 64 % serve errors
65 65 [255]
66 66
67 67 expect success
68 68
69 69 $ cat >> .hg/hgrc <<EOF
70 70 > allow_push = *
71 71 > [hooks]
72 72 > changegroup = sh -c "printenv.py changegroup 0"
73 73 > pushkey = sh -c "printenv.py pushkey 0"
74 74 > EOF
75 75 $ req
76 76 pushing to http://localhost:$HGPORT/
77 77 searching for changes
78 78 remote: adding changesets
79 79 remote: adding manifests
80 80 remote: adding file changes
81 81 remote: added 1 changesets with 1 changes to 1 files
82 remote: changegroup hook: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
82 remote: changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
83 83 % serve errors
84 84 $ hg rollback
85 85 repository tip rolled back to revision 0 (undo serve)
86 86
87 87 expect success, server lacks the httpheader capability
88 88
89 89 $ CAP=httpheader
90 90 $ . "$TESTDIR/notcapable"
91 91 $ req
92 92 pushing to http://localhost:$HGPORT/
93 93 searching for changes
94 94 remote: adding changesets
95 95 remote: adding manifests
96 96 remote: adding file changes
97 97 remote: added 1 changesets with 1 changes to 1 files
98 remote: changegroup hook: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
98 remote: changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
99 99 % serve errors
100 100 $ hg rollback
101 101 repository tip rolled back to revision 0 (undo serve)
102 102
103 103 expect success, server lacks the unbundlehash capability
104 104
105 105 $ CAP=unbundlehash
106 106 $ . "$TESTDIR/notcapable"
107 107 $ req
108 108 pushing to http://localhost:$HGPORT/
109 109 searching for changes
110 110 remote: adding changesets
111 111 remote: adding manifests
112 112 remote: adding file changes
113 113 remote: added 1 changesets with 1 changes to 1 files
114 remote: changegroup hook: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
114 remote: changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
115 115 % serve errors
116 116 $ hg rollback
117 117 repository tip rolled back to revision 0 (undo serve)
118 118
119 119 expect success, pre-d1b16a746db6 server supports the unbundle capability, but
120 120 has no parameter
121 121
122 122 $ cat <<EOF > notcapable-unbundleparam.py
123 123 > from mercurial import extensions, httppeer
124 124 > def capable(orig, self, name):
125 125 > if name == 'unbundle':
126 126 > return True
127 127 > return orig(self, name)
128 128 > def uisetup(ui):
129 129 > extensions.wrapfunction(httppeer.httppeer, 'capable', capable)
130 130 > EOF
131 131 $ cp $HGRCPATH $HGRCPATH.orig
132 132 $ cat <<EOF >> $HGRCPATH
133 133 > [extensions]
134 134 > notcapable-unbundleparam = `pwd`/notcapable-unbundleparam.py
135 135 > EOF
136 136 $ req
137 137 pushing to http://localhost:$HGPORT/
138 138 searching for changes
139 139 remote: adding changesets
140 140 remote: adding manifests
141 141 remote: adding file changes
142 142 remote: added 1 changesets with 1 changes to 1 files
143 143 remote: changegroup hook: * (glob)
144 144 % serve errors
145 145 $ hg rollback
146 146 repository tip rolled back to revision 0 (undo serve)
147 147 $ mv $HGRCPATH.orig $HGRCPATH
148 148
149 149 expect push success, phase change failure
150 150
151 151 $ cat > .hg/hgrc <<EOF
152 152 > [web]
153 153 > push_ssl = false
154 154 > allow_push = *
155 155 > [hooks]
156 156 > prepushkey = sh -c "printenv.py prepushkey 1"
157 157 > EOF
158 158 $ req
159 159 pushing to http://localhost:$HGPORT/
160 160 searching for changes
161 161 remote: adding changesets
162 162 remote: adding manifests
163 163 remote: adding file changes
164 164 remote: added 1 changesets with 1 changes to 1 files
165 165 % serve errors
166 166
167 167 expect phase change success
168 168
169 169 $ cat >> .hg/hgrc <<EOF
170 170 > prepushkey = sh -c "printenv.py prepushkey 0"
171 171 > EOF
172 172 $ req
173 173 pushing to http://localhost:$HGPORT/
174 174 searching for changes
175 175 no changes found
176 176 % serve errors
177 177 [1]
178 178 $ hg rollback
179 179 repository tip rolled back to revision 0 (undo serve)
180 180
181 181 expect authorization error: all users denied
182 182
183 183 $ echo '[web]' > .hg/hgrc
184 184 $ echo 'push_ssl = false' >> .hg/hgrc
185 185 $ echo 'deny_push = *' >> .hg/hgrc
186 186 $ req
187 187 pushing to http://localhost:$HGPORT/
188 188 searching for changes
189 189 abort: authorization failed
190 190 % serve errors
191 191 [255]
192 192
193 193 expect authorization error: some users denied, users must be authenticated
194 194
195 195 $ echo 'deny_push = unperson' >> .hg/hgrc
196 196 $ req
197 197 pushing to http://localhost:$HGPORT/
198 198 searching for changes
199 199 abort: authorization failed
200 200 % serve errors
201 201 [255]
202 202
203 203 $ cd ..
@@ -1,175 +1,175
1 1 #require killdaemons
2 2
3 3 $ hg init test
4 4 $ cd test
5 5 $ echo a > a
6 6 $ hg ci -Ama
7 7 adding a
8 8 $ cd ..
9 9 $ hg clone test test2
10 10 updating to branch default
11 11 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 12 $ cd test2
13 13 $ echo a >> a
14 14 $ hg ci -mb
15 15 $ req() {
16 16 > hg serve -p $HGPORT -d --pid-file=hg.pid -E errors.log
17 17 > cat hg.pid >> $DAEMON_PIDS
18 18 > hg --cwd ../test2 push http://localhost:$HGPORT/
19 19 > exitstatus=$?
20 20 > killdaemons.py
21 21 > echo % serve errors
22 22 > cat errors.log
23 23 > return $exitstatus
24 24 > }
25 25 $ cd ../test
26 26
27 27 expect ssl error
28 28
29 29 $ req
30 30 pushing to http://localhost:$HGPORT/
31 31 searching for changes
32 32 abort: HTTP Error 403: ssl required
33 33 % serve errors
34 34 [255]
35 35
36 36 expect authorization error
37 37
38 38 $ echo '[web]' > .hg/hgrc
39 39 $ echo 'push_ssl = false' >> .hg/hgrc
40 40 $ req
41 41 pushing to http://localhost:$HGPORT/
42 42 searching for changes
43 43 abort: authorization failed
44 44 % serve errors
45 45 [255]
46 46
47 47 expect authorization error: must have authorized user
48 48
49 49 $ echo 'allow_push = unperson' >> .hg/hgrc
50 50 $ req
51 51 pushing to http://localhost:$HGPORT/
52 52 searching for changes
53 53 abort: authorization failed
54 54 % serve errors
55 55 [255]
56 56
57 57 expect success
58 58
59 59 $ cat >> .hg/hgrc <<EOF
60 60 > allow_push = *
61 61 > [hooks]
62 62 > changegroup = sh -c "printenv.py changegroup 0"
63 63 > pushkey = sh -c "printenv.py pushkey 0"
64 64 > EOF
65 65 $ req
66 66 pushing to http://localhost:$HGPORT/
67 67 searching for changes
68 68 remote: adding changesets
69 69 remote: adding manifests
70 70 remote: adding file changes
71 71 remote: added 1 changesets with 1 changes to 1 files
72 remote: pushkey hook: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_OLD=1 HG_RET=1
73 remote: changegroup hook: HG_BUNDLE2=1 HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
72 remote: pushkey hook: HG_HOOKTYPE=pushkey HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_OLD=1 HG_RET=1
73 remote: changegroup hook: HG_BUNDLE2=1 HG_HOOKTYPE=changegroup HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
74 74 % serve errors
75 75 $ hg rollback
76 76 repository tip rolled back to revision 0 (undo serve)
77 77
78 78 expect success, server lacks the httpheader capability
79 79
80 80 $ CAP=httpheader
81 81 $ . "$TESTDIR/notcapable"
82 82 $ req
83 83 pushing to http://localhost:$HGPORT/
84 84 searching for changes
85 85 remote: adding changesets
86 86 remote: adding manifests
87 87 remote: adding file changes
88 88 remote: added 1 changesets with 1 changes to 1 files
89 remote: pushkey hook: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_OLD=1 HG_RET=1
90 remote: changegroup hook: HG_BUNDLE2=1 HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
89 remote: pushkey hook: HG_HOOKTYPE=pushkey HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_OLD=1 HG_RET=1
90 remote: changegroup hook: HG_BUNDLE2=1 HG_HOOKTYPE=changegroup HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
91 91 % serve errors
92 92 $ hg rollback
93 93 repository tip rolled back to revision 0 (undo serve)
94 94
95 95 expect success, server lacks the unbundlehash capability
96 96
97 97 $ CAP=unbundlehash
98 98 $ . "$TESTDIR/notcapable"
99 99 $ req
100 100 pushing to http://localhost:$HGPORT/
101 101 searching for changes
102 102 remote: adding changesets
103 103 remote: adding manifests
104 104 remote: adding file changes
105 105 remote: added 1 changesets with 1 changes to 1 files
106 remote: pushkey hook: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_OLD=1 HG_RET=1
107 remote: changegroup hook: HG_BUNDLE2=1 HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
106 remote: pushkey hook: HG_HOOKTYPE=pushkey HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_OLD=1 HG_RET=1
107 remote: changegroup hook: HG_BUNDLE2=1 HG_HOOKTYPE=changegroup HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
108 108 % serve errors
109 109 $ hg rollback
110 110 repository tip rolled back to revision 0 (undo serve)
111 111
112 112 expect push success, phase change failure
113 113
114 114 $ cat > .hg/hgrc <<EOF
115 115 > [web]
116 116 > push_ssl = false
117 117 > allow_push = *
118 118 > [hooks]
119 119 > prepushkey = sh -c "printenv.py prepushkey 1"
120 120 > EOF
121 121 $ req
122 122 pushing to http://localhost:$HGPORT/
123 123 searching for changes
124 124 remote: adding changesets
125 125 remote: adding manifests
126 126 remote: adding file changes
127 127 remote: added 1 changesets with 1 changes to 1 files
128 remote: prepushkey hook: HG_BUNDLE2=1 HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_OLD=1 HG_PENDING=$TESTTMP/test HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
128 remote: prepushkey hook: HG_BUNDLE2=1 HG_HOOKTYPE=prepushkey HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_OLD=1 HG_PENDING=$TESTTMP/test HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
129 129 remote: pushkey-abort: prepushkey hook exited with status 1
130 130 remote: transaction abort!
131 131 remote: rollback completed
132 132 abort: updating ba677d0156c1 to public failed
133 133 % serve errors
134 134 [255]
135 135
136 136 expect phase change success
137 137
138 138 $ cat >> .hg/hgrc <<EOF
139 139 > prepushkey = sh -c "printenv.py prepushkey 0"
140 140 > EOF
141 141 $ req
142 142 pushing to http://localhost:$HGPORT/
143 143 searching for changes
144 144 remote: adding changesets
145 145 remote: adding manifests
146 146 remote: adding file changes
147 147 remote: added 1 changesets with 1 changes to 1 files
148 remote: prepushkey hook: HG_BUNDLE2=1 HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_OLD=1 HG_PENDING=$TESTTMP/test HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
148 remote: prepushkey hook: HG_BUNDLE2=1 HG_HOOKTYPE=prepushkey HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_OLD=1 HG_PENDING=$TESTTMP/test HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP:
149 149 % serve errors
150 150 $ hg rollback
151 151 repository tip rolled back to revision 0 (undo serve)
152 152
153 153 expect authorization error: all users denied
154 154
155 155 $ echo '[web]' > .hg/hgrc
156 156 $ echo 'push_ssl = false' >> .hg/hgrc
157 157 $ echo 'deny_push = *' >> .hg/hgrc
158 158 $ req
159 159 pushing to http://localhost:$HGPORT/
160 160 searching for changes
161 161 abort: authorization failed
162 162 % serve errors
163 163 [255]
164 164
165 165 expect authorization error: some users denied, users must be authenticated
166 166
167 167 $ echo 'deny_push = unperson' >> .hg/hgrc
168 168 $ req
169 169 pushing to http://localhost:$HGPORT/
170 170 searching for changes
171 171 abort: authorization failed
172 172 % serve errors
173 173 [255]
174 174
175 175 $ cd ..
@@ -1,562 +1,562
1 1 This test is a duplicate of 'test-http.t' feel free to factor out
2 2 parts that are not bundle1/bundle2 specific.
3 3
4 4 $ cat << EOF >> $HGRCPATH
5 5 > [devel]
6 6 > # This test is dedicated to interaction through old bundle
7 7 > legacy.exchange = bundle1
8 8 > [format] # temporary settings
9 9 > usegeneraldelta=yes
10 10 > EOF
11 11
12 12
13 13 This test tries to exercise the ssh functionality with a dummy script
14 14
15 15 creating 'remote' repo
16 16
17 17 $ hg init remote
18 18 $ cd remote
19 19 $ echo this > foo
20 20 $ echo this > fooO
21 21 $ hg ci -A -m "init" foo fooO
22 22
23 23 insert a closed branch (issue4428)
24 24
25 25 $ hg up null
26 26 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
27 27 $ hg branch closed
28 28 marked working directory as branch closed
29 29 (branches are permanent and global, did you want a bookmark?)
30 30 $ hg ci -mc0
31 31 $ hg ci --close-branch -mc1
32 32 $ hg up -q default
33 33
34 34 configure for serving
35 35
36 36 $ cat <<EOF > .hg/hgrc
37 37 > [server]
38 38 > uncompressed = True
39 39 >
40 40 > [hooks]
41 41 > changegroup = sh -c "printenv.py changegroup-in-remote 0 ../dummylog"
42 42 > EOF
43 43 $ cd ..
44 44
45 45 repo not found error
46 46
47 47 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
48 48 remote: abort: repository nonexistent not found!
49 49 abort: no suitable response from remote hg!
50 50 [255]
51 51
52 52 non-existent absolute path
53 53
54 54 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
55 55 remote: abort: repository /$TESTTMP/nonexistent not found!
56 56 abort: no suitable response from remote hg!
57 57 [255]
58 58
59 59 clone remote via stream
60 60
61 61 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
62 62 streaming all changes
63 63 4 files to transfer, 602 bytes of data
64 64 transferred 602 bytes in * seconds (*) (glob)
65 65 searching for changes
66 66 no changes found
67 67 updating to branch default
68 68 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
69 69 $ cd local-stream
70 70 $ hg verify
71 71 checking changesets
72 72 checking manifests
73 73 crosschecking files in changesets and manifests
74 74 checking files
75 75 2 files, 3 changesets, 2 total revisions
76 76 $ hg branches
77 77 default 0:1160648e36ce
78 78 $ cd ..
79 79
80 80 clone bookmarks via stream
81 81
82 82 $ hg -R local-stream book mybook
83 83 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/local-stream stream2
84 84 streaming all changes
85 85 4 files to transfer, 602 bytes of data
86 86 transferred 602 bytes in * seconds (*) (glob)
87 87 searching for changes
88 88 no changes found
89 89 updating to branch default
90 90 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 91 $ cd stream2
92 92 $ hg book
93 93 mybook 0:1160648e36ce
94 94 $ cd ..
95 95 $ rm -rf local-stream stream2
96 96
97 97 clone remote via pull
98 98
99 99 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
100 100 requesting all changes
101 101 adding changesets
102 102 adding manifests
103 103 adding file changes
104 104 added 3 changesets with 2 changes to 2 files
105 105 updating to branch default
106 106 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 107
108 108 verify
109 109
110 110 $ cd local
111 111 $ hg verify
112 112 checking changesets
113 113 checking manifests
114 114 crosschecking files in changesets and manifests
115 115 checking files
116 116 2 files, 3 changesets, 2 total revisions
117 117 $ cat >> .hg/hgrc <<EOF
118 118 > [hooks]
119 119 > changegroup = sh -c "printenv.py changegroup-in-local 0 ../dummylog"
120 120 > EOF
121 121
122 122 empty default pull
123 123
124 124 $ hg paths
125 125 default = ssh://user@dummy/remote
126 126 $ hg pull -e "python \"$TESTDIR/dummyssh\""
127 127 pulling from ssh://user@dummy/remote
128 128 searching for changes
129 129 no changes found
130 130
131 131 pull from wrong ssh URL
132 132
133 133 $ hg pull -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
134 134 pulling from ssh://user@dummy/doesnotexist
135 135 remote: abort: repository doesnotexist not found!
136 136 abort: no suitable response from remote hg!
137 137 [255]
138 138
139 139 local change
140 140
141 141 $ echo bleah > foo
142 142 $ hg ci -m "add"
143 143
144 144 updating rc
145 145
146 146 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
147 147 $ echo "[ui]" >> .hg/hgrc
148 148 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
149 149
150 150 find outgoing
151 151
152 152 $ hg out ssh://user@dummy/remote
153 153 comparing with ssh://user@dummy/remote
154 154 searching for changes
155 155 changeset: 3:a28a9d1a809c
156 156 tag: tip
157 157 parent: 0:1160648e36ce
158 158 user: test
159 159 date: Thu Jan 01 00:00:00 1970 +0000
160 160 summary: add
161 161
162 162
163 163 find incoming on the remote side
164 164
165 165 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
166 166 comparing with ssh://user@dummy/local
167 167 searching for changes
168 168 changeset: 3:a28a9d1a809c
169 169 tag: tip
170 170 parent: 0:1160648e36ce
171 171 user: test
172 172 date: Thu Jan 01 00:00:00 1970 +0000
173 173 summary: add
174 174
175 175
176 176 find incoming on the remote side (using absolute path)
177 177
178 178 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
179 179 comparing with ssh://user@dummy/$TESTTMP/local
180 180 searching for changes
181 181 changeset: 3:a28a9d1a809c
182 182 tag: tip
183 183 parent: 0:1160648e36ce
184 184 user: test
185 185 date: Thu Jan 01 00:00:00 1970 +0000
186 186 summary: add
187 187
188 188
189 189 push
190 190
191 191 $ hg push
192 192 pushing to ssh://user@dummy/remote
193 193 searching for changes
194 194 remote: adding changesets
195 195 remote: adding manifests
196 196 remote: adding file changes
197 197 remote: added 1 changesets with 1 changes to 1 files
198 198 $ cd ../remote
199 199
200 200 check remote tip
201 201
202 202 $ hg tip
203 203 changeset: 3:a28a9d1a809c
204 204 tag: tip
205 205 parent: 0:1160648e36ce
206 206 user: test
207 207 date: Thu Jan 01 00:00:00 1970 +0000
208 208 summary: add
209 209
210 210 $ hg verify
211 211 checking changesets
212 212 checking manifests
213 213 crosschecking files in changesets and manifests
214 214 checking files
215 215 2 files, 4 changesets, 3 total revisions
216 216 $ hg cat -r tip foo
217 217 bleah
218 218 $ echo z > z
219 219 $ hg ci -A -m z z
220 220 created new head
221 221
222 222 test pushkeys and bookmarks
223 223
224 224 $ cd ../local
225 225 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
226 226 bookmarks
227 227 namespaces
228 228 phases
229 229 $ hg book foo -r 0
230 230 $ hg out -B
231 231 comparing with ssh://user@dummy/remote
232 232 searching for changed bookmarks
233 233 foo 1160648e36ce
234 234 $ hg push -B foo
235 235 pushing to ssh://user@dummy/remote
236 236 searching for changes
237 237 no changes found
238 238 exporting bookmark foo
239 239 [1]
240 240 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
241 241 foo 1160648e36cec0054048a7edc4110c6f84fde594
242 242 $ hg book -f foo
243 243 $ hg push --traceback
244 244 pushing to ssh://user@dummy/remote
245 245 searching for changes
246 246 no changes found
247 247 updating bookmark foo
248 248 [1]
249 249 $ hg book -d foo
250 250 $ hg in -B
251 251 comparing with ssh://user@dummy/remote
252 252 searching for changed bookmarks
253 253 foo a28a9d1a809c
254 254 $ hg book -f -r 0 foo
255 255 $ hg pull -B foo
256 256 pulling from ssh://user@dummy/remote
257 257 no changes found
258 258 updating bookmark foo
259 259 $ hg book -d foo
260 260 $ hg push -B foo
261 261 pushing to ssh://user@dummy/remote
262 262 searching for changes
263 263 no changes found
264 264 deleting remote bookmark foo
265 265 [1]
266 266
267 267 a bad, evil hook that prints to stdout
268 268
269 269 $ cat <<EOF > $TESTTMP/badhook
270 270 > import sys
271 271 > sys.stdout.write("KABOOM\n")
272 272 > EOF
273 273
274 274 $ echo '[hooks]' >> ../remote/.hg/hgrc
275 275 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
276 276 $ echo r > r
277 277 $ hg ci -A -m z r
278 278
279 279 push should succeed even though it has an unexpected response
280 280
281 281 $ hg push
282 282 pushing to ssh://user@dummy/remote
283 283 searching for changes
284 284 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
285 285 remote: adding changesets
286 286 remote: adding manifests
287 287 remote: adding file changes
288 288 remote: added 1 changesets with 1 changes to 1 files
289 289 remote: KABOOM
290 290 $ hg -R ../remote heads
291 291 changeset: 5:1383141674ec
292 292 tag: tip
293 293 parent: 3:a28a9d1a809c
294 294 user: test
295 295 date: Thu Jan 01 00:00:00 1970 +0000
296 296 summary: z
297 297
298 298 changeset: 4:6c0482d977a3
299 299 parent: 0:1160648e36ce
300 300 user: test
301 301 date: Thu Jan 01 00:00:00 1970 +0000
302 302 summary: z
303 303
304 304
305 305 clone bookmarks
306 306
307 307 $ hg -R ../remote bookmark test
308 308 $ hg -R ../remote bookmarks
309 309 * test 4:6c0482d977a3
310 310 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
311 311 requesting all changes
312 312 adding changesets
313 313 adding manifests
314 314 adding file changes
315 315 added 6 changesets with 5 changes to 4 files (+1 heads)
316 316 updating to branch default
317 317 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
318 318 $ hg -R local-bookmarks bookmarks
319 319 test 4:6c0482d977a3
320 320
321 321 passwords in ssh urls are not supported
322 322 (we use a glob here because different Python versions give different
323 323 results here)
324 324
325 325 $ hg push ssh://user:erroneouspwd@dummy/remote
326 326 pushing to ssh://user:*@dummy/remote (glob)
327 327 abort: password in URL not supported!
328 328 [255]
329 329
330 330 $ cd ..
331 331
332 332 hide outer repo
333 333 $ hg init
334 334
335 335 Test remote paths with spaces (issue2983):
336 336
337 337 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
338 338 $ touch "$TESTTMP/a repo/test"
339 339 $ hg -R 'a repo' commit -A -m "test"
340 340 adding test
341 341 $ hg -R 'a repo' tag tag
342 342 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
343 343 73649e48688a
344 344
345 345 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
346 346 abort: unknown revision 'noNoNO'!
347 347 [255]
348 348
349 349 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
350 350
351 351 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
352 352 destination directory: a repo
353 353 abort: destination 'a repo' is not empty
354 354 [255]
355 355
356 356 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
357 357 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
358 358 parameters:
359 359
360 360 $ cat > ssh.sh << EOF
361 361 > userhost="\$1"
362 362 > SSH_ORIGINAL_COMMAND="\$2"
363 363 > export SSH_ORIGINAL_COMMAND
364 364 > PYTHONPATH="$PYTHONPATH"
365 365 > export PYTHONPATH
366 366 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
367 367 > EOF
368 368
369 369 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
370 370 73649e48688a
371 371
372 372 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
373 373 remote: Illegal repository "$TESTTMP/a'repo" (glob)
374 374 abort: no suitable response from remote hg!
375 375 [255]
376 376
377 377 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
378 378 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
379 379 abort: no suitable response from remote hg!
380 380 [255]
381 381
382 382 $ SSH_ORIGINAL_COMMAND="'hg' serve -R 'a'repo' --stdio" python "$TESTDIR/../contrib/hg-ssh"
383 383 Illegal command "'hg' serve -R 'a'repo' --stdio": No closing quotation
384 384 [255]
385 385
386 386 Test hg-ssh in read-only mode:
387 387
388 388 $ cat > ssh.sh << EOF
389 389 > userhost="\$1"
390 390 > SSH_ORIGINAL_COMMAND="\$2"
391 391 > export SSH_ORIGINAL_COMMAND
392 392 > PYTHONPATH="$PYTHONPATH"
393 393 > export PYTHONPATH
394 394 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
395 395 > EOF
396 396
397 397 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
398 398 requesting all changes
399 399 adding changesets
400 400 adding manifests
401 401 adding file changes
402 402 added 6 changesets with 5 changes to 4 files (+1 heads)
403 403 updating to branch default
404 404 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
405 405
406 406 $ cd read-only-local
407 407 $ echo "baz" > bar
408 408 $ hg ci -A -m "unpushable commit" bar
409 409 $ hg push --ssh "sh ../ssh.sh"
410 410 pushing to ssh://user@dummy/*/remote (glob)
411 411 searching for changes
412 412 remote: Permission denied
413 413 remote: abort: pretxnopen.hg-ssh hook failed
414 414 remote: Permission denied
415 415 remote: pushkey-abort: prepushkey.hg-ssh hook failed
416 416 updating 6c0482d977a3 to public failed!
417 417 [1]
418 418
419 419 $ cd ..
420 420
421 421 stderr from remote commands should be printed before stdout from local code (issue4336)
422 422
423 423 $ hg clone remote stderr-ordering
424 424 updating to branch default
425 425 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
426 426 $ cd stderr-ordering
427 427 $ cat >> localwrite.py << EOF
428 428 > from mercurial import exchange, extensions
429 429 >
430 430 > def wrappedpush(orig, repo, *args, **kwargs):
431 431 > res = orig(repo, *args, **kwargs)
432 432 > repo.ui.write('local stdout\n')
433 433 > return res
434 434 >
435 435 > def extsetup(ui):
436 436 > extensions.wrapfunction(exchange, 'push', wrappedpush)
437 437 > EOF
438 438
439 439 $ cat >> .hg/hgrc << EOF
440 440 > [paths]
441 441 > default-push = ssh://user@dummy/remote
442 442 > [ui]
443 443 > ssh = python "$TESTDIR/dummyssh"
444 444 > [extensions]
445 445 > localwrite = localwrite.py
446 446 > EOF
447 447
448 448 $ echo localwrite > foo
449 449 $ hg commit -m 'testing localwrite'
450 450 $ hg push
451 451 pushing to ssh://user@dummy/remote
452 452 searching for changes
453 453 remote: adding changesets
454 454 remote: adding manifests
455 455 remote: adding file changes
456 456 remote: added 1 changesets with 1 changes to 1 files
457 457 remote: KABOOM
458 458 local stdout
459 459
460 460 debug output
461 461
462 462 $ hg pull --debug ssh://user@dummy/remote
463 463 pulling from ssh://user@dummy/remote
464 464 running python ".*/dummyssh" user@dummy ('|")hg -R remote serve --stdio('|") (re)
465 465 sending hello command
466 466 sending between command
467 467 remote: 355
468 468 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN
469 469 remote: 1
470 470 preparing listkeys for "bookmarks"
471 471 sending listkeys command
472 472 received listkey for "bookmarks": 45 bytes
473 473 query 1; heads
474 474 sending batch command
475 475 searching for changes
476 476 all remote heads known locally
477 477 no changes found
478 478 preparing listkeys for "phases"
479 479 sending listkeys command
480 480 received listkey for "phases": 15 bytes
481 481 checking for updated bookmarks
482 482
483 483 $ cd ..
484 484
485 485 $ cat dummylog
486 486 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
487 487 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
488 488 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
489 489 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio
490 490 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
491 491 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
492 492 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
493 493 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
494 494 Got arguments 1:user@dummy 2:hg -R local serve --stdio
495 495 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
496 496 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
497 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_NODE_LAST=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
497 changegroup-in-remote hook: HG_HOOKTYPE=changegroup HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_NODE_LAST=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
498 498 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
499 499 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
500 500 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
501 501 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
502 502 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
503 503 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
504 504 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
505 505 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
506 506 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
507 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
507 changegroup-in-remote hook: HG_HOOKTYPE=changegroup HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
508 508 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
509 509 Got arguments 1:user@dummy 2:hg init 'a repo'
510 510 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
511 511 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
512 512 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
513 513 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
514 514 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
515 changegroup-in-remote hook: HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_NODE_LAST=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
515 changegroup-in-remote hook: HG_HOOKTYPE=changegroup HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_NODE_LAST=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
516 516 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
517 517
518 518 remote hook failure is attributed to remote
519 519
520 520 $ cat > $TESTTMP/failhook << EOF
521 521 > def hook(ui, repo, **kwargs):
522 522 > ui.write('hook failure!\n')
523 523 > ui.flush()
524 524 > return 1
525 525 > EOF
526 526
527 527 $ echo "pretxnchangegroup.fail = python:$TESTTMP/failhook:hook" >> remote/.hg/hgrc
528 528
529 529 $ hg -q --config ui.ssh="python $TESTDIR/dummyssh" clone ssh://user@dummy/remote hookout
530 530 $ cd hookout
531 531 $ touch hookfailure
532 532 $ hg -q commit -A -m 'remote hook failure'
533 533 $ hg --config ui.ssh="python $TESTDIR/dummyssh" push
534 534 pushing to ssh://user@dummy/remote
535 535 searching for changes
536 536 remote: adding changesets
537 537 remote: adding manifests
538 538 remote: adding file changes
539 539 remote: added 1 changesets with 1 changes to 1 files
540 540 remote: hook failure!
541 541 remote: transaction abort!
542 542 remote: rollback completed
543 543 remote: abort: pretxnchangegroup.fail hook failed
544 544 [1]
545 545
546 546 abort during pull is properly reported as such
547 547
548 548 $ echo morefoo >> ../remote/foo
549 549 $ hg -R ../remote commit --message "more foo to be pulled"
550 550 $ cat >> ../remote/.hg/hgrc << EOF
551 551 > [extensions]
552 552 > crash = ${TESTDIR}/crashgetbundler.py
553 553 > EOF
554 554 $ hg --config ui.ssh="python $TESTDIR/dummyssh" pull
555 555 pulling from ssh://user@dummy/remote
556 556 searching for changes
557 557 adding changesets
558 558 remote: abort: this is an exercise
559 559 transaction abort!
560 560 rollback completed
561 561 abort: stream ended unexpectedly (got 0 bytes, expected 4)
562 562 [255]
@@ -1,564 +1,564
1 1
2 2 This test tries to exercise the ssh functionality with a dummy script
3 3
4 4 $ cat <<EOF >> $HGRCPATH
5 5 > [format]
6 6 > usegeneraldelta=yes
7 7 > EOF
8 8
9 9 creating 'remote' repo
10 10
11 11 $ hg init remote
12 12 $ cd remote
13 13 $ echo this > foo
14 14 $ echo this > fooO
15 15 $ hg ci -A -m "init" foo fooO
16 16
17 17 insert a closed branch (issue4428)
18 18
19 19 $ hg up null
20 20 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
21 21 $ hg branch closed
22 22 marked working directory as branch closed
23 23 (branches are permanent and global, did you want a bookmark?)
24 24 $ hg ci -mc0
25 25 $ hg ci --close-branch -mc1
26 26 $ hg up -q default
27 27
28 28 configure for serving
29 29
30 30 $ cat <<EOF > .hg/hgrc
31 31 > [server]
32 32 > uncompressed = True
33 33 >
34 34 > [hooks]
35 35 > changegroup = sh -c "printenv.py changegroup-in-remote 0 ../dummylog"
36 36 > EOF
37 37 $ cd ..
38 38
39 39 repo not found error
40 40
41 41 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
42 42 remote: abort: repository nonexistent not found!
43 43 abort: no suitable response from remote hg!
44 44 [255]
45 45
46 46 non-existent absolute path
47 47
48 48 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/`pwd`/nonexistent local
49 49 remote: abort: repository $TESTTMP/nonexistent not found!
50 50 abort: no suitable response from remote hg!
51 51 [255]
52 52
53 53 clone remote via stream
54 54
55 55 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
56 56 streaming all changes
57 57 4 files to transfer, 602 bytes of data
58 58 transferred 602 bytes in * seconds (*) (glob)
59 59 searching for changes
60 60 no changes found
61 61 updating to branch default
62 62 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 63 $ cd local-stream
64 64 $ hg verify
65 65 checking changesets
66 66 checking manifests
67 67 crosschecking files in changesets and manifests
68 68 checking files
69 69 2 files, 3 changesets, 2 total revisions
70 70 $ hg branches
71 71 default 0:1160648e36ce
72 72 $ cd ..
73 73
74 74 clone bookmarks via stream
75 75
76 76 $ hg -R local-stream book mybook
77 77 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/local-stream stream2
78 78 streaming all changes
79 79 4 files to transfer, 602 bytes of data
80 80 transferred 602 bytes in * seconds (*) (glob)
81 81 searching for changes
82 82 no changes found
83 83 updating to branch default
84 84 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
85 85 $ cd stream2
86 86 $ hg book
87 87 mybook 0:1160648e36ce
88 88 $ cd ..
89 89 $ rm -rf local-stream stream2
90 90
91 91 clone remote via pull
92 92
93 93 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
94 94 requesting all changes
95 95 adding changesets
96 96 adding manifests
97 97 adding file changes
98 98 added 3 changesets with 2 changes to 2 files
99 99 updating to branch default
100 100 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
101 101
102 102 verify
103 103
104 104 $ cd local
105 105 $ hg verify
106 106 checking changesets
107 107 checking manifests
108 108 crosschecking files in changesets and manifests
109 109 checking files
110 110 2 files, 3 changesets, 2 total revisions
111 111 $ cat >> .hg/hgrc <<EOF
112 112 > [hooks]
113 113 > changegroup = sh -c "printenv.py changegroup-in-local 0 ../dummylog"
114 114 > EOF
115 115
116 116 empty default pull
117 117
118 118 $ hg paths
119 119 default = ssh://user@dummy/remote
120 120 $ hg pull -e "python \"$TESTDIR/dummyssh\""
121 121 pulling from ssh://user@dummy/remote
122 122 searching for changes
123 123 no changes found
124 124
125 125 pull from wrong ssh URL
126 126
127 127 $ hg pull -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
128 128 pulling from ssh://user@dummy/doesnotexist
129 129 remote: abort: repository doesnotexist not found!
130 130 abort: no suitable response from remote hg!
131 131 [255]
132 132
133 133 local change
134 134
135 135 $ echo bleah > foo
136 136 $ hg ci -m "add"
137 137
138 138 updating rc
139 139
140 140 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
141 141 $ echo "[ui]" >> .hg/hgrc
142 142 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
143 143
144 144 find outgoing
145 145
146 146 $ hg out ssh://user@dummy/remote
147 147 comparing with ssh://user@dummy/remote
148 148 searching for changes
149 149 changeset: 3:a28a9d1a809c
150 150 tag: tip
151 151 parent: 0:1160648e36ce
152 152 user: test
153 153 date: Thu Jan 01 00:00:00 1970 +0000
154 154 summary: add
155 155
156 156
157 157 find incoming on the remote side
158 158
159 159 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
160 160 comparing with ssh://user@dummy/local
161 161 searching for changes
162 162 changeset: 3:a28a9d1a809c
163 163 tag: tip
164 164 parent: 0:1160648e36ce
165 165 user: test
166 166 date: Thu Jan 01 00:00:00 1970 +0000
167 167 summary: add
168 168
169 169
170 170 find incoming on the remote side (using absolute path)
171 171
172 172 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
173 173 comparing with ssh://user@dummy/$TESTTMP/local
174 174 searching for changes
175 175 changeset: 3:a28a9d1a809c
176 176 tag: tip
177 177 parent: 0:1160648e36ce
178 178 user: test
179 179 date: Thu Jan 01 00:00:00 1970 +0000
180 180 summary: add
181 181
182 182
183 183 push
184 184
185 185 $ hg push
186 186 pushing to ssh://user@dummy/remote
187 187 searching for changes
188 188 remote: adding changesets
189 189 remote: adding manifests
190 190 remote: adding file changes
191 191 remote: added 1 changesets with 1 changes to 1 files
192 192 $ cd ../remote
193 193
194 194 check remote tip
195 195
196 196 $ hg tip
197 197 changeset: 3:a28a9d1a809c
198 198 tag: tip
199 199 parent: 0:1160648e36ce
200 200 user: test
201 201 date: Thu Jan 01 00:00:00 1970 +0000
202 202 summary: add
203 203
204 204 $ hg verify
205 205 checking changesets
206 206 checking manifests
207 207 crosschecking files in changesets and manifests
208 208 checking files
209 209 2 files, 4 changesets, 3 total revisions
210 210 $ hg cat -r tip foo
211 211 bleah
212 212 $ echo z > z
213 213 $ hg ci -A -m z z
214 214 created new head
215 215
216 216 test pushkeys and bookmarks
217 217
218 218 $ cd ../local
219 219 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
220 220 bookmarks
221 221 namespaces
222 222 phases
223 223 $ hg book foo -r 0
224 224 $ hg out -B
225 225 comparing with ssh://user@dummy/remote
226 226 searching for changed bookmarks
227 227 foo 1160648e36ce
228 228 $ hg push -B foo
229 229 pushing to ssh://user@dummy/remote
230 230 searching for changes
231 231 no changes found
232 232 exporting bookmark foo
233 233 [1]
234 234 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
235 235 foo 1160648e36cec0054048a7edc4110c6f84fde594
236 236 $ hg book -f foo
237 237 $ hg push --traceback
238 238 pushing to ssh://user@dummy/remote
239 239 searching for changes
240 240 no changes found
241 241 updating bookmark foo
242 242 [1]
243 243 $ hg book -d foo
244 244 $ hg in -B
245 245 comparing with ssh://user@dummy/remote
246 246 searching for changed bookmarks
247 247 foo a28a9d1a809c
248 248 $ hg book -f -r 0 foo
249 249 $ hg pull -B foo
250 250 pulling from ssh://user@dummy/remote
251 251 no changes found
252 252 updating bookmark foo
253 253 $ hg book -d foo
254 254 $ hg push -B foo
255 255 pushing to ssh://user@dummy/remote
256 256 searching for changes
257 257 no changes found
258 258 deleting remote bookmark foo
259 259 [1]
260 260
261 261 a bad, evil hook that prints to stdout
262 262
263 263 $ cat <<EOF > $TESTTMP/badhook
264 264 > import sys
265 265 > sys.stdout.write("KABOOM\n")
266 266 > EOF
267 267
268 268 $ cat <<EOF > $TESTTMP/badpyhook.py
269 269 > import sys
270 270 > def hook(ui, repo, hooktype, **kwargs):
271 271 > sys.stdout.write("KABOOM IN PROCESS\n")
272 272 > EOF
273 273
274 274 $ cat <<EOF >> ../remote/.hg/hgrc
275 275 > [hooks]
276 276 > changegroup.stdout = python $TESTTMP/badhook
277 277 > changegroup.pystdout = python:$TESTTMP/badpyhook.py:hook
278 278 > EOF
279 279 $ echo r > r
280 280 $ hg ci -A -m z r
281 281
282 282 push should succeed even though it has an unexpected response
283 283
284 284 $ hg push
285 285 pushing to ssh://user@dummy/remote
286 286 searching for changes
287 287 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
288 288 remote: adding changesets
289 289 remote: adding manifests
290 290 remote: adding file changes
291 291 remote: added 1 changesets with 1 changes to 1 files
292 292 remote: KABOOM
293 293 remote: KABOOM IN PROCESS
294 294 $ hg -R ../remote heads
295 295 changeset: 5:1383141674ec
296 296 tag: tip
297 297 parent: 3:a28a9d1a809c
298 298 user: test
299 299 date: Thu Jan 01 00:00:00 1970 +0000
300 300 summary: z
301 301
302 302 changeset: 4:6c0482d977a3
303 303 parent: 0:1160648e36ce
304 304 user: test
305 305 date: Thu Jan 01 00:00:00 1970 +0000
306 306 summary: z
307 307
308 308
309 309 clone bookmarks
310 310
311 311 $ hg -R ../remote bookmark test
312 312 $ hg -R ../remote bookmarks
313 313 * test 4:6c0482d977a3
314 314 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
315 315 requesting all changes
316 316 adding changesets
317 317 adding manifests
318 318 adding file changes
319 319 added 6 changesets with 5 changes to 4 files (+1 heads)
320 320 updating to branch default
321 321 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
322 322 $ hg -R local-bookmarks bookmarks
323 323 test 4:6c0482d977a3
324 324
325 325 passwords in ssh urls are not supported
326 326 (we use a glob here because different Python versions give different
327 327 results here)
328 328
329 329 $ hg push ssh://user:erroneouspwd@dummy/remote
330 330 pushing to ssh://user:*@dummy/remote (glob)
331 331 abort: password in URL not supported!
332 332 [255]
333 333
334 334 $ cd ..
335 335
336 336 hide outer repo
337 337 $ hg init
338 338
339 339 Test remote paths with spaces (issue2983):
340 340
341 341 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
342 342 $ touch "$TESTTMP/a repo/test"
343 343 $ hg -R 'a repo' commit -A -m "test"
344 344 adding test
345 345 $ hg -R 'a repo' tag tag
346 346 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
347 347 73649e48688a
348 348
349 349 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
350 350 abort: unknown revision 'noNoNO'!
351 351 [255]
352 352
353 353 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
354 354
355 355 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
356 356 destination directory: a repo
357 357 abort: destination 'a repo' is not empty
358 358 [255]
359 359
360 360 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
361 361 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
362 362 parameters:
363 363
364 364 $ cat > ssh.sh << EOF
365 365 > userhost="\$1"
366 366 > SSH_ORIGINAL_COMMAND="\$2"
367 367 > export SSH_ORIGINAL_COMMAND
368 368 > PYTHONPATH="$PYTHONPATH"
369 369 > export PYTHONPATH
370 370 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
371 371 > EOF
372 372
373 373 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
374 374 73649e48688a
375 375
376 376 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
377 377 remote: Illegal repository "$TESTTMP/a'repo" (glob)
378 378 abort: no suitable response from remote hg!
379 379 [255]
380 380
381 381 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
382 382 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
383 383 abort: no suitable response from remote hg!
384 384 [255]
385 385
386 386 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
387 387 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
388 388 [255]
389 389
390 390 Test hg-ssh in read-only mode:
391 391
392 392 $ cat > ssh.sh << EOF
393 393 > userhost="\$1"
394 394 > SSH_ORIGINAL_COMMAND="\$2"
395 395 > export SSH_ORIGINAL_COMMAND
396 396 > PYTHONPATH="$PYTHONPATH"
397 397 > export PYTHONPATH
398 398 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
399 399 > EOF
400 400
401 401 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
402 402 requesting all changes
403 403 adding changesets
404 404 adding manifests
405 405 adding file changes
406 406 added 6 changesets with 5 changes to 4 files (+1 heads)
407 407 updating to branch default
408 408 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
409 409
410 410 $ cd read-only-local
411 411 $ echo "baz" > bar
412 412 $ hg ci -A -m "unpushable commit" bar
413 413 $ hg push --ssh "sh ../ssh.sh"
414 414 pushing to ssh://user@dummy/*/remote (glob)
415 415 searching for changes
416 416 remote: Permission denied
417 417 remote: pretxnopen.hg-ssh hook failed
418 418 abort: push failed on remote
419 419 [255]
420 420
421 421 $ cd ..
422 422
423 423 stderr from remote commands should be printed before stdout from local code (issue4336)
424 424
425 425 $ hg clone remote stderr-ordering
426 426 updating to branch default
427 427 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
428 428 $ cd stderr-ordering
429 429 $ cat >> localwrite.py << EOF
430 430 > from mercurial import exchange, extensions
431 431 >
432 432 > def wrappedpush(orig, repo, *args, **kwargs):
433 433 > res = orig(repo, *args, **kwargs)
434 434 > repo.ui.write('local stdout\n')
435 435 > return res
436 436 >
437 437 > def extsetup(ui):
438 438 > extensions.wrapfunction(exchange, 'push', wrappedpush)
439 439 > EOF
440 440
441 441 $ cat >> .hg/hgrc << EOF
442 442 > [paths]
443 443 > default-push = ssh://user@dummy/remote
444 444 > [ui]
445 445 > ssh = python "$TESTDIR/dummyssh"
446 446 > [extensions]
447 447 > localwrite = localwrite.py
448 448 > EOF
449 449
450 450 $ echo localwrite > foo
451 451 $ hg commit -m 'testing localwrite'
452 452 $ hg push
453 453 pushing to ssh://user@dummy/remote
454 454 searching for changes
455 455 remote: adding changesets
456 456 remote: adding manifests
457 457 remote: adding file changes
458 458 remote: added 1 changesets with 1 changes to 1 files
459 459 remote: KABOOM
460 460 remote: KABOOM IN PROCESS
461 461 local stdout
462 462
463 463 debug output
464 464
465 465 $ hg pull --debug ssh://user@dummy/remote
466 466 pulling from ssh://user@dummy/remote
467 467 running python ".*/dummyssh" user@dummy ('|")hg -R remote serve --stdio('|") (re)
468 468 sending hello command
469 469 sending between command
470 470 remote: 355
471 471 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN
472 472 remote: 1
473 473 query 1; heads
474 474 sending batch command
475 475 searching for changes
476 476 all remote heads known locally
477 477 no changes found
478 478 sending getbundle command
479 479 bundle2-input-bundle: with-transaction
480 480 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
481 481 bundle2-input-part: total payload size 15
482 482 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
483 483 bundle2-input-part: total payload size 45
484 484 bundle2-input-bundle: 1 parts total
485 485 checking for updated bookmarks
486 486
487 487 $ cd ..
488 488
489 489 $ cat dummylog
490 490 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
491 491 Got arguments 1:user@dummy 2:hg -R $TESTTMP/nonexistent serve --stdio
492 492 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
493 493 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio
494 494 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
495 495 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
496 496 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
497 497 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
498 498 Got arguments 1:user@dummy 2:hg -R local serve --stdio
499 499 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
500 500 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
501 changegroup-in-remote hook: HG_BUNDLE2=1 HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_NODE_LAST=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
501 changegroup-in-remote hook: HG_BUNDLE2=1 HG_HOOKTYPE=changegroup HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_NODE_LAST=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
502 502 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
503 503 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
504 504 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
505 505 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
506 506 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
507 507 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
508 508 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
509 509 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
510 510 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
511 changegroup-in-remote hook: HG_BUNDLE2=1 HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
511 changegroup-in-remote hook: HG_BUNDLE2=1 HG_HOOKTYPE=changegroup HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
512 512 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
513 513 Got arguments 1:user@dummy 2:hg init 'a repo'
514 514 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
515 515 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
516 516 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
517 517 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
518 518 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
519 changegroup-in-remote hook: HG_BUNDLE2=1 HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_NODE_LAST=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
519 changegroup-in-remote hook: HG_BUNDLE2=1 HG_HOOKTYPE=changegroup HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_NODE_LAST=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
520 520 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
521 521
522 522 remote hook failure is attributed to remote
523 523
524 524 $ cat > $TESTTMP/failhook << EOF
525 525 > def hook(ui, repo, **kwargs):
526 526 > ui.write('hook failure!\n')
527 527 > ui.flush()
528 528 > return 1
529 529 > EOF
530 530
531 531 $ echo "pretxnchangegroup.fail = python:$TESTTMP/failhook:hook" >> remote/.hg/hgrc
532 532
533 533 $ hg -q --config ui.ssh="python $TESTDIR/dummyssh" clone ssh://user@dummy/remote hookout
534 534 $ cd hookout
535 535 $ touch hookfailure
536 536 $ hg -q commit -A -m 'remote hook failure'
537 537 $ hg --config ui.ssh="python $TESTDIR/dummyssh" push
538 538 pushing to ssh://user@dummy/remote
539 539 searching for changes
540 540 remote: adding changesets
541 541 remote: adding manifests
542 542 remote: adding file changes
543 543 remote: added 1 changesets with 1 changes to 1 files
544 544 remote: hook failure!
545 545 remote: transaction abort!
546 546 remote: rollback completed
547 547 remote: pretxnchangegroup.fail hook failed
548 548 abort: push failed on remote
549 549 [255]
550 550
551 551 abort during pull is properly reported as such
552 552
553 553 $ echo morefoo >> ../remote/foo
554 554 $ hg -R ../remote commit --message "more foo to be pulled"
555 555 $ cat >> ../remote/.hg/hgrc << EOF
556 556 > [extensions]
557 557 > crash = ${TESTDIR}/crashgetbundler.py
558 558 > EOF
559 559 $ hg --config ui.ssh="python $TESTDIR/dummyssh" pull
560 560 pulling from ssh://user@dummy/remote
561 561 searching for changes
562 562 remote: abort: this is an exercise
563 563 abort: pull failed on remote
564 564 [255]
@@ -1,159 +1,159
1 1 #require killdaemons
2 2
3 3 $ hg clone http://localhost:$HGPORT/ copy
4 4 abort: * (glob)
5 5 [255]
6 6 $ test -d copy
7 7 [1]
8 8
9 9 This server doesn't do range requests so it's basically only good for
10 10 one pull
11 11
12 12 $ python "$TESTDIR/dumbhttp.py" -p $HGPORT --pid dumb.pid
13 13 $ cat dumb.pid >> $DAEMON_PIDS
14 14 $ hg init remote
15 15 $ cd remote
16 16 $ echo foo > bar
17 17 $ echo c2 > '.dotfile with spaces'
18 18 $ hg add
19 19 adding .dotfile with spaces
20 20 adding bar
21 21 $ hg commit -m"test"
22 22 $ hg tip
23 23 changeset: 0:02770d679fb8
24 24 tag: tip
25 25 user: test
26 26 date: Thu Jan 01 00:00:00 1970 +0000
27 27 summary: test
28 28
29 29 $ cd ..
30 30 $ hg clone static-http://localhost:$HGPORT/remote local
31 31 requesting all changes
32 32 adding changesets
33 33 adding manifests
34 34 adding file changes
35 35 added 1 changesets with 2 changes to 2 files
36 36 updating to branch default
37 37 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 38 $ cd local
39 39 $ hg verify
40 40 checking changesets
41 41 checking manifests
42 42 crosschecking files in changesets and manifests
43 43 checking files
44 44 2 files, 1 changesets, 2 total revisions
45 45 $ cat bar
46 46 foo
47 47 $ cd ../remote
48 48 $ echo baz > quux
49 49 $ hg commit -A -mtest2
50 50 adding quux
51 51
52 52 check for HTTP opener failures when cachefile does not exist
53 53
54 54 $ rm .hg/cache/*
55 55 $ cd ../local
56 56 $ cat >> .hg/hgrc <<EOF
57 57 > [hooks]
58 58 > changegroup = sh -c "printenv.py changegroup"
59 59 > EOF
60 60 $ hg pull
61 61 pulling from static-http://localhost:$HGPORT/remote
62 62 searching for changes
63 63 adding changesets
64 64 adding manifests
65 65 adding file changes
66 66 added 1 changesets with 1 changes to 1 files
67 changegroup hook: HG_NODE=4ac2e3648604439c580c69b09ec9d93a88d93432 HG_NODE_LAST=4ac2e3648604439c580c69b09ec9d93a88d93432 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=http://localhost:$HGPORT/remote
67 changegroup hook: HG_HOOKTYPE=changegroup HG_NODE=4ac2e3648604439c580c69b09ec9d93a88d93432 HG_NODE_LAST=4ac2e3648604439c580c69b09ec9d93a88d93432 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=http://localhost:$HGPORT/remote
68 68 (run 'hg update' to get a working copy)
69 69
70 70 trying to push
71 71
72 72 $ hg update
73 73 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
74 74 $ echo more foo >> bar
75 75 $ hg commit -m"test"
76 76 $ hg push
77 77 pushing to static-http://localhost:$HGPORT/remote
78 78 abort: destination does not support push
79 79 [255]
80 80
81 81 trying clone -r
82 82
83 83 $ cd ..
84 84 $ hg clone -r doesnotexist static-http://localhost:$HGPORT/remote local0
85 85 abort: unknown revision 'doesnotexist'!
86 86 [255]
87 87 $ hg clone -r 0 static-http://localhost:$HGPORT/remote local0
88 88 adding changesets
89 89 adding manifests
90 90 adding file changes
91 91 added 1 changesets with 2 changes to 2 files
92 92 updating to branch default
93 93 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
94 94
95 95 test with "/" URI (issue747) and subrepo
96 96
97 97 $ hg init
98 98 $ hg init sub
99 99 $ touch sub/test
100 100 $ hg -R sub commit -A -m "test"
101 101 adding test
102 102 $ hg -R sub tag not-empty
103 103 $ echo sub=sub > .hgsub
104 104 $ echo a > a
105 105 $ hg add a .hgsub
106 106 $ hg -q ci -ma
107 107 $ hg clone static-http://localhost:$HGPORT/ local2
108 108 requesting all changes
109 109 adding changesets
110 110 adding manifests
111 111 adding file changes
112 112 added 1 changesets with 3 changes to 3 files
113 113 updating to branch default
114 114 cloning subrepo sub from static-http://localhost:$HGPORT/sub
115 115 requesting all changes
116 116 adding changesets
117 117 adding manifests
118 118 adding file changes
119 119 added 2 changesets with 2 changes to 2 files
120 120 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 121 $ cd local2
122 122 $ hg verify
123 123 checking changesets
124 124 checking manifests
125 125 crosschecking files in changesets and manifests
126 126 checking files
127 127 3 files, 1 changesets, 3 total revisions
128 128 checking subrepo links
129 129 $ cat a
130 130 a
131 131 $ hg paths
132 132 default = static-http://localhost:$HGPORT/
133 133
134 134 test with empty repo (issue965)
135 135
136 136 $ cd ..
137 137 $ hg init remotempty
138 138 $ hg clone static-http://localhost:$HGPORT/remotempty local3
139 139 no changes found
140 140 updating to branch default
141 141 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 142 $ cd local3
143 143 $ hg verify
144 144 checking changesets
145 145 checking manifests
146 146 crosschecking files in changesets and manifests
147 147 checking files
148 148 0 files, 0 changesets, 0 total revisions
149 149 $ hg paths
150 150 default = static-http://localhost:$HGPORT/remotempty
151 151
152 152 test with non-repo
153 153
154 154 $ cd ..
155 155 $ mkdir notarepo
156 156 $ hg clone static-http://localhost:$HGPORT/notarepo local3
157 157 abort: 'http://localhost:$HGPORT/notarepo' does not appear to be an hg repository!
158 158 [255]
159 159 $ killdaemons.py
General Comments 0
You need to be logged in to leave comments. Login now