##// END OF EJS Templates
clone-bundles: add a command to clear all bundles
marmoute -
r51306:10318b88 default
parent child Browse files
Show More
@@ -1,979 +1,996 b''
1 1 # This software may be used and distributed according to the terms of the
2 2 # GNU General Public License version 2 or any later version.
3 3
4 4 """advertise pre-generated bundles to seed clones
5 5
6 6 "clonebundles" is a server-side extension used to advertise the existence
7 7 of pre-generated, externally hosted bundle files to clients that are
8 8 cloning so that cloning can be faster, more reliable, and require less
9 9 resources on the server. "pullbundles" is a related feature for sending
10 10 pre-generated bundle files to clients as part of pull operations.
11 11
12 12 Cloning can be a CPU and I/O intensive operation on servers. Traditionally,
13 13 the server, in response to a client's request to clone, dynamically generates
14 14 a bundle containing the entire repository content and sends it to the client.
15 15 There is no caching on the server and the server will have to redundantly
16 16 generate the same outgoing bundle in response to each clone request. For
17 17 servers with large repositories or with high clone volume, the load from
18 18 clones can make scaling the server challenging and costly.
19 19
20 20 This extension provides server operators the ability to offload
21 21 potentially expensive clone load to an external service. Pre-generated
22 22 bundles also allow using more CPU intensive compression, reducing the
23 23 effective bandwidth requirements.
24 24
25 25 Here's how clone bundles work:
26 26
27 27 1. A server operator establishes a mechanism for making bundle files available
28 28 on a hosting service where Mercurial clients can fetch them.
29 29 2. A manifest file listing available bundle URLs and some optional metadata
30 30 is added to the Mercurial repository on the server.
31 31 3. A client initiates a clone against a clone bundles aware server.
32 32 4. The client sees the server is advertising clone bundles and fetches the
33 33 manifest listing available bundles.
34 34 5. The client filters and sorts the available bundles based on what it
35 35 supports and prefers.
36 36 6. The client downloads and applies an available bundle from the
37 37 server-specified URL.
38 38 7. The client reconnects to the original server and performs the equivalent
39 39 of :hg:`pull` to retrieve all repository data not in the bundle. (The
40 40 repository could have been updated between when the bundle was created
41 41 and when the client started the clone.) This may use "pullbundles".
42 42
43 43 Instead of the server generating full repository bundles for every clone
44 44 request, it generates full bundles once and they are subsequently reused to
45 45 bootstrap new clones. The server may still transfer data at clone time.
46 46 However, this is only data that has been added/changed since the bundle was
47 47 created. For large, established repositories, this can reduce server load for
48 48 clones to less than 1% of original.
49 49
50 50 Here's how pullbundles work:
51 51
52 52 1. A manifest file listing available bundles and describing the revisions
53 53 is added to the Mercurial repository on the server.
54 54 2. A new-enough client informs the server that it supports partial pulls
55 55 and initiates a pull.
56 56 3. If the server has pull bundles enabled and sees the client advertising
57 57 partial pulls, it checks for a matching pull bundle in the manifest.
58 58 A bundle matches if the format is supported by the client, the client
59 59 has the required revisions already and needs something from the bundle.
60 60 4. If there is at least one matching bundle, the server sends it to the client.
61 61 5. The client applies the bundle and notices that the server reply was
62 62 incomplete. It initiates another pull.
63 63
64 64 To work, this extension requires the following of server operators:
65 65
66 66 * Generating bundle files of repository content (typically periodically,
67 67 such as once per day).
68 68 * Clone bundles: A file server that clients have network access to and that
69 69 Python knows how to talk to through its normal URL handling facility
70 70 (typically an HTTP/HTTPS server).
71 71 * A process for keeping the bundles manifest in sync with available bundle
72 72 files.
73 73
74 74 Strictly speaking, using a static file hosting server isn't required: a server
75 75 operator could use a dynamic service for retrieving bundle data. However,
76 76 static file hosting services are simple and scalable and should be sufficient
77 77 for most needs.
78 78
79 79 Bundle files can be generated with the :hg:`bundle` command. Typically
80 80 :hg:`bundle --all` is used to produce a bundle of the entire repository.
81 81
82 82 :hg:`debugcreatestreamclonebundle` can be used to produce a special
83 83 *streaming clonebundle*. These are bundle files that are extremely efficient
84 84 to produce and consume (read: fast). However, they are larger than
85 85 traditional bundle formats and require that clients support the exact set
86 86 of repository data store formats in use by the repository that created them.
87 87 Typically, a newer server can serve data that is compatible with older clients.
88 88 However, *streaming clone bundles* don't have this guarantee. **Server
89 89 operators need to be aware that newer versions of Mercurial may produce
90 90 streaming clone bundles incompatible with older Mercurial versions.**
91 91
92 92 A server operator is responsible for creating a ``.hg/clonebundles.manifest``
93 93 file containing the list of available bundle files suitable for seeding
94 94 clones. If this file does not exist, the repository will not advertise the
95 95 existence of clone bundles when clients connect. For pull bundles,
96 96 ``.hg/pullbundles.manifest`` is used.
97 97
98 98 The manifest file contains a newline (\\n) delimited list of entries.
99 99
100 100 Each line in this file defines an available bundle. Lines have the format:
101 101
102 102 <URL> [<key>=<value>[ <key>=<value>]]
103 103
104 104 That is, a URL followed by an optional, space-delimited list of key=value
105 105 pairs describing additional properties of this bundle. Both keys and values
106 106 are URI encoded.
107 107
108 108 For pull bundles, the URL is a path under the ``.hg`` directory of the
109 109 repository.
110 110
111 111 Keys in UPPERCASE are reserved for use by Mercurial and are defined below.
112 112 All non-uppercase keys can be used by site installations. An example use
113 113 for custom properties is to use the *datacenter* attribute to define which
114 114 data center a file is hosted in. Clients could then prefer a server in the
115 115 data center closest to them.
116 116
117 117 The following reserved keys are currently defined:
118 118
119 119 BUNDLESPEC
120 120 A "bundle specification" string that describes the type of the bundle.
121 121
122 122 These are string values that are accepted by the "--type" argument of
123 123 :hg:`bundle`.
124 124
125 125 The values are parsed in strict mode, which means they must be of the
126 126 "<compression>-<type>" form. See
127 127 mercurial.exchange.parsebundlespec() for more details.
128 128
129 129 :hg:`debugbundle --spec` can be used to print the bundle specification
130 130 string for a bundle file. The output of this command can be used verbatim
131 131 for the value of ``BUNDLESPEC`` (it is already escaped).
132 132
133 133 Clients will automatically filter out specifications that are unknown or
134 134 unsupported so they won't attempt to download something that likely won't
135 135 apply.
136 136
137 137 The actual value doesn't impact client behavior beyond filtering:
138 138 clients will still sniff the bundle type from the header of downloaded
139 139 files.
140 140
141 141 **Use of this key is highly recommended**, as it allows clients to
142 142 easily skip unsupported bundles. If this key is not defined, an old
143 143 client may attempt to apply a bundle that it is incapable of reading.
144 144
145 145 REQUIRESNI
146 146 Whether Server Name Indication (SNI) is required to connect to the URL.
147 147 SNI allows servers to use multiple certificates on the same IP. It is
148 148 somewhat common in CDNs and other hosting providers. Older Python
149 149 versions do not support SNI. Defining this attribute enables clients
150 150 with older Python versions to filter this entry without experiencing
151 151 an opaque SSL failure at connection time.
152 152
153 153 If this is defined, it is important to advertise a non-SNI fallback
154 154 URL or clients running old Python releases may not be able to clone
155 155 with the clonebundles facility.
156 156
157 157 Value should be "true".
158 158
159 159 REQUIREDRAM
160 160 Value specifies expected memory requirements to decode the payload.
161 161 Values can have suffixes for common bytes sizes. e.g. "64MB".
162 162
163 163 This key is often used with zstd-compressed bundles using a high
164 164 compression level / window size, which can require 100+ MB of memory
165 165 to decode.
166 166
167 167 heads
168 168 Used for pull bundles. This contains the ``;`` separated changeset
169 169 hashes of the heads of the bundle content.
170 170
171 171 bases
172 172 Used for pull bundles. This contains the ``;`` separated changeset
173 173 hashes of the roots of the bundle content. This can be skipped if
174 174 the bundle was created without ``--base``.
175 175
176 176 Manifests can contain multiple entries. Assuming metadata is defined, clients
177 177 will filter entries from the manifest that they don't support. The remaining
178 178 entries are optionally sorted by client preferences
179 179 (``ui.clonebundleprefers`` config option). The client then attempts
180 180 to fetch the bundle at the first URL in the remaining list.
181 181
182 182 **Errors when downloading a bundle will fail the entire clone operation:
183 183 clients do not automatically fall back to a traditional clone.** The reason
184 184 for this is that if a server is using clone bundles, it is probably doing so
185 185 because the feature is necessary to help it scale. In other words, there
186 186 is an assumption that clone load will be offloaded to another service and
187 187 that the Mercurial server isn't responsible for serving this clone load.
188 188 If that other service experiences issues and clients start mass falling back to
189 189 the original Mercurial server, the added clone load could overwhelm the server
190 190 due to unexpected load and effectively take it offline. Not having clients
191 191 automatically fall back to cloning from the original server mitigates this
192 192 scenario.
193 193
194 194 Because there is no automatic Mercurial server fallback on failure of the
195 195 bundle hosting service, it is important for server operators to view the bundle
196 196 hosting service as an extension of the Mercurial server in terms of
197 197 availability and service level agreements: if the bundle hosting service goes
198 198 down, so does the ability for clients to clone. Note: clients will see a
199 199 message informing them how to bypass the clone bundles facility when a failure
200 200 occurs. So server operators should prepare for some people to follow these
201 201 instructions when a failure occurs, thus driving more load to the original
202 202 Mercurial server when the bundle hosting service fails.
203 203
204 204
205 205 auto-generation of clone bundles
206 206 --------------------------------
207 207
208 208 It is possible to set Mercurial to automatically re-generate clone bundles when
209 209 enough new content is available.
210 210
211 211 Mercurial will take care of the process asynchronously. The defined list of
212 212 bundle-type will be generated, uploaded, and advertised. Older bundles will get
213 213 decommissioned as newer ones replace them.
214 214
215 215 Bundles Generation:
216 216 ...................
217 217
218 218 The extension can generate multiple variants of the clone bundle. Each
219 219 different variant will be defined by the "bundle-spec" they use::
220 220
221 221 [clone-bundles]
222 222 auto-generate.formats= zstd-v2, gzip-v2
223 223
224 224 See `hg help bundlespec` for details about available options.
225 225
226 226 By default, new bundles are generated when 5% of the repository contents or at
227 227 least 1000 revisions are not contained in the cached bundles. This option can
228 228 be controlled by the `clone-bundles.trigger.below-bundled-ratio` option
229 229 (default 0.95) and the `clone-bundles.trigger.revs` option (default 1000)::
230 230
231 231 [clone-bundles]
232 232 trigger.below-bundled-ratio=0.95
233 233 trigger.revs=1000
234 234
235 235 This logic can be manually triggered using the `admin::clone-bundles-refresh`
236 236 command, or automatically on each repository change if
237 237 `clone-bundles.auto-generate.on-change` is set to `yes`.
238 238
239 239 [clone-bundles]
240 240 auto-generate.on-change=yes
241 241 auto-generate.formats= zstd-v2, gzip-v2
242 242
243 243 Bundles Upload and Serving:
244 244 ...........................
245 245
246 246 The generated bundles need to be made available to users through a "public" URL.
247 247 This should be donne through `clone-bundles.upload-command` configuration. The
248 248 value of this command should be a shell command. It will have access to the
249 249 bundle file path through the `$HGCB_BUNDLE_PATH` variable. And the expected
250 250 basename in the "public" URL is accessible at::
251 251
252 252 [clone-bundles]
253 253 upload-command=sftp put $HGCB_BUNDLE_PATH \
254 254 sftp://bundles.host/clone-bundles/$HGCB_BUNDLE_BASENAME
255 255
256 256 If the file was already uploaded, the command must still succeed.
257 257
258 258 After upload, the file should be available at an url defined by
259 259 `clone-bundles.url-template`.
260 260
261 261 [clone-bundles]
262 262 url-template=https://bundles.host/cache/clone-bundles/{basename}
263 263
264 264 Old bundles cleanup:
265 265 ....................
266 266
267 267 When new bundles are generated, the older ones are no longer necessary and can
268 268 be removed from storage. This is done through the `clone-bundles.delete-command`
269 269 configuration. The command is given the url of the artifact to delete through
270 270 the `$HGCB_BUNDLE_URL` environment variable.
271 271
272 272 [clone-bundles]
273 273 delete-command=sftp rm sftp://bundles.host/clone-bundles/$HGCB_BUNDLE_BASENAME
274 274
275 275 If the file was already deleted, the command must still succeed.
276 276 """
277 277
278 278
279 279 import os
280 280 import weakref
281 281
282 282 from mercurial.i18n import _
283 283
284 284 from mercurial import (
285 285 bundlecaches,
286 286 commands,
287 287 error,
288 288 extensions,
289 289 localrepo,
290 290 lock,
291 291 node,
292 292 registrar,
293 293 util,
294 294 wireprotov1server,
295 295 )
296 296
297 297
298 298 from mercurial.utils import (
299 299 procutil,
300 300 )
301 301
302 302 testedwith = b'ships-with-hg-core'
303 303
304 304
305 305 def capabilities(orig, repo, proto):
306 306 caps = orig(repo, proto)
307 307
308 308 # Only advertise if a manifest exists. This does add some I/O to requests.
309 309 # But this should be cheaper than a wasted network round trip due to
310 310 # missing file.
311 311 if repo.vfs.exists(bundlecaches.CB_MANIFEST_FILE):
312 312 caps.append(b'clonebundles')
313 313
314 314 return caps
315 315
316 316
317 317 def extsetup(ui):
318 318 extensions.wrapfunction(wireprotov1server, b'_capabilities', capabilities)
319 319
320 320
321 321 # logic for bundle auto-generation
322 322
323 323
324 324 configtable = {}
325 325 configitem = registrar.configitem(configtable)
326 326
327 327 cmdtable = {}
328 328 command = registrar.command(cmdtable)
329 329
330 330 configitem(b'clone-bundles', b'auto-generate.on-change', default=False)
331 331 configitem(b'clone-bundles', b'auto-generate.formats', default=list)
332 332 configitem(b'clone-bundles', b'trigger.below-bundled-ratio', default=0.95)
333 333 configitem(b'clone-bundles', b'trigger.revs', default=1000)
334 334
335 335 configitem(b'clone-bundles', b'upload-command', default=None)
336 336
337 337 configitem(b'clone-bundles', b'delete-command', default=None)
338 338
339 339 configitem(b'clone-bundles', b'url-template', default=None)
340 340
341 341 configitem(b'devel', b'debug.clonebundles', default=False)
342 342
343 343
344 344 # category for the post-close transaction hooks
345 345 CAT_POSTCLOSE = b"clonebundles-autobundles"
346 346
347 347 # template for bundle file names
348 348 BUNDLE_MASK = (
349 349 b"full-%(bundle_type)s-%(revs)d_revs-%(tip_short)s_tip-%(op_id)s.hg"
350 350 )
351 351
352 352
353 353 # file in .hg/ use to track clonebundles being auto-generated
354 354 AUTO_GEN_FILE = b'clonebundles.auto-gen'
355 355
356 356
357 357 class BundleBase(object):
358 358 """represents the core of properties that matters for us in a bundle
359 359
360 360 :bundle_type: the bundlespec (see hg help bundlespec)
361 361 :revs: the number of revisions in the repo at bundle creation time
362 362 :tip_rev: the rev-num of the tip revision
363 363 :tip_node: the node id of the tip-most revision in the bundle
364 364
365 365 :ready: True if the bundle is ready to be served
366 366 """
367 367
368 368 ready = False
369 369
370 370 def __init__(self, bundle_type, revs, tip_rev, tip_node):
371 371 self.bundle_type = bundle_type
372 372 self.revs = revs
373 373 self.tip_rev = tip_rev
374 374 self.tip_node = tip_node
375 375
376 376 def valid_for(self, repo):
377 377 """is this bundle applicable to the current repository
378 378
379 379 This is useful for detecting bundles made irrelevant by stripping.
380 380 """
381 381 tip_node = node.bin(self.tip_node)
382 382 return repo.changelog.index.get_rev(tip_node) == self.tip_rev
383 383
384 384 def __eq__(self, other):
385 385 left = (self.ready, self.bundle_type, self.tip_rev, self.tip_node)
386 386 right = (other.ready, other.bundle_type, other.tip_rev, other.tip_node)
387 387 return left == right
388 388
389 389 def __neq__(self, other):
390 390 return not self == other
391 391
392 392 def __cmp__(self, other):
393 393 if self == other:
394 394 return 0
395 395 return -1
396 396
397 397
398 398 class RequestedBundle(BundleBase):
399 399 """A bundle that should be generated.
400 400
401 401 Additional attributes compared to BundleBase
402 402 :heads: list of head revisions (as rev-num)
403 403 :op_id: a "unique" identifier for the operation triggering the change
404 404 """
405 405
406 406 def __init__(self, bundle_type, revs, tip_rev, tip_node, head_revs, op_id):
407 407 self.head_revs = head_revs
408 408 self.op_id = op_id
409 409 super(RequestedBundle, self).__init__(
410 410 bundle_type,
411 411 revs,
412 412 tip_rev,
413 413 tip_node,
414 414 )
415 415
416 416 @property
417 417 def suggested_filename(self):
418 418 """A filename that can be used for the generated bundle"""
419 419 data = {
420 420 b'bundle_type': self.bundle_type,
421 421 b'revs': self.revs,
422 422 b'heads': self.head_revs,
423 423 b'tip_rev': self.tip_rev,
424 424 b'tip_node': self.tip_node,
425 425 b'tip_short': self.tip_node[:12],
426 426 b'op_id': self.op_id,
427 427 }
428 428 return BUNDLE_MASK % data
429 429
430 430 def generate_bundle(self, repo, file_path):
431 431 """generate the bundle at `filepath`"""
432 432 commands.bundle(
433 433 repo.ui,
434 434 repo,
435 435 file_path,
436 436 base=[b"null"],
437 437 rev=self.head_revs,
438 438 type=self.bundle_type,
439 439 quiet=True,
440 440 )
441 441
442 442 def generating(self, file_path, hostname=None, pid=None):
443 443 """return a GeneratingBundle object from this object"""
444 444 if pid is None:
445 445 pid = os.getpid()
446 446 if hostname is None:
447 447 hostname = lock._getlockprefix()
448 448 return GeneratingBundle(
449 449 self.bundle_type,
450 450 self.revs,
451 451 self.tip_rev,
452 452 self.tip_node,
453 453 hostname,
454 454 pid,
455 455 file_path,
456 456 )
457 457
458 458
459 459 class GeneratingBundle(BundleBase):
460 460 """A bundle being generated
461 461
462 462 extra attributes compared to BundleBase:
463 463
464 464 :hostname: the hostname of the machine generating the bundle
465 465 :pid: the pid of the process generating the bundle
466 466 :filepath: the target filename of the bundle
467 467
468 468 These attributes exist to help detect stalled generation processes.
469 469 """
470 470
471 471 ready = False
472 472
473 473 def __init__(
474 474 self, bundle_type, revs, tip_rev, tip_node, hostname, pid, filepath
475 475 ):
476 476 self.hostname = hostname
477 477 self.pid = pid
478 478 self.filepath = filepath
479 479 super(GeneratingBundle, self).__init__(
480 480 bundle_type, revs, tip_rev, tip_node
481 481 )
482 482
483 483 @classmethod
484 484 def from_line(cls, line):
485 485 """create an object by deserializing a line from AUTO_GEN_FILE"""
486 486 assert line.startswith(b'PENDING-v1 ')
487 487 (
488 488 __,
489 489 bundle_type,
490 490 revs,
491 491 tip_rev,
492 492 tip_node,
493 493 hostname,
494 494 pid,
495 495 filepath,
496 496 ) = line.split()
497 497 hostname = util.urlreq.unquote(hostname)
498 498 filepath = util.urlreq.unquote(filepath)
499 499 revs = int(revs)
500 500 tip_rev = int(tip_rev)
501 501 pid = int(pid)
502 502 return cls(
503 503 bundle_type, revs, tip_rev, tip_node, hostname, pid, filepath
504 504 )
505 505
506 506 def to_line(self):
507 507 """serialize the object to include as a line in AUTO_GEN_FILE"""
508 508 templ = b"PENDING-v1 %s %d %d %s %s %d %s"
509 509 data = (
510 510 self.bundle_type,
511 511 self.revs,
512 512 self.tip_rev,
513 513 self.tip_node,
514 514 util.urlreq.quote(self.hostname),
515 515 self.pid,
516 516 util.urlreq.quote(self.filepath),
517 517 )
518 518 return templ % data
519 519
520 520 def __eq__(self, other):
521 521 if not super(GeneratingBundle, self).__eq__(other):
522 522 return False
523 523 left = (self.hostname, self.pid, self.filepath)
524 524 right = (other.hostname, other.pid, other.filepath)
525 525 return left == right
526 526
527 527 def uploaded(self, url, basename):
528 528 """return a GeneratedBundle from this object"""
529 529 return GeneratedBundle(
530 530 self.bundle_type,
531 531 self.revs,
532 532 self.tip_rev,
533 533 self.tip_node,
534 534 url,
535 535 basename,
536 536 )
537 537
538 538
539 539 class GeneratedBundle(BundleBase):
540 540 """A bundle that is done being generated and can be served
541 541
542 542 extra attributes compared to BundleBase:
543 543
544 544 :file_url: the url where the bundle is available.
545 545 :basename: the "basename" used to upload (useful for deletion)
546 546
547 547 These attributes exist to generate a bundle manifest
548 548 (.hg/pullbundles.manifest)
549 549 """
550 550
551 551 ready = True
552 552
553 553 def __init__(
554 554 self, bundle_type, revs, tip_rev, tip_node, file_url, basename
555 555 ):
556 556 self.file_url = file_url
557 557 self.basename = basename
558 558 super(GeneratedBundle, self).__init__(
559 559 bundle_type, revs, tip_rev, tip_node
560 560 )
561 561
562 562 @classmethod
563 563 def from_line(cls, line):
564 564 """create an object by deserializing a line from AUTO_GEN_FILE"""
565 565 assert line.startswith(b'DONE-v1 ')
566 566 (
567 567 __,
568 568 bundle_type,
569 569 revs,
570 570 tip_rev,
571 571 tip_node,
572 572 file_url,
573 573 basename,
574 574 ) = line.split()
575 575 revs = int(revs)
576 576 tip_rev = int(tip_rev)
577 577 file_url = util.urlreq.unquote(file_url)
578 578 return cls(bundle_type, revs, tip_rev, tip_node, file_url, basename)
579 579
580 580 def to_line(self):
581 581 """serialize the object to include as a line in AUTO_GEN_FILE"""
582 582 templ = b"DONE-v1 %s %d %d %s %s %s"
583 583 data = (
584 584 self.bundle_type,
585 585 self.revs,
586 586 self.tip_rev,
587 587 self.tip_node,
588 588 util.urlreq.quote(self.file_url),
589 589 self.basename,
590 590 )
591 591 return templ % data
592 592
593 593 def manifest_line(self):
594 594 """serialize the object to include as a line in pullbundles.manifest"""
595 595 templ = b"%s BUNDLESPEC=%s REQUIRESNI=true"
596 596 return templ % (self.file_url, self.bundle_type)
597 597
598 598 def __eq__(self, other):
599 599 if not super(GeneratedBundle, self).__eq__(other):
600 600 return False
601 601 return self.file_url == other.file_url
602 602
603 603
604 604 def parse_auto_gen(content):
605 605 """parse the AUTO_GEN_FILE to return a list of Bundle object"""
606 606 bundles = []
607 607 for line in content.splitlines():
608 608 if line.startswith(b'PENDING-v1 '):
609 609 bundles.append(GeneratingBundle.from_line(line))
610 610 elif line.startswith(b'DONE-v1 '):
611 611 bundles.append(GeneratedBundle.from_line(line))
612 612 return bundles
613 613
614 614
615 615 def dumps_auto_gen(bundles):
616 616 """serialize a list of Bundle as a AUTO_GEN_FILE content"""
617 617 lines = []
618 618 for b in bundles:
619 619 lines.append(b"%s\n" % b.to_line())
620 620 lines.sort()
621 621 return b"".join(lines)
622 622
623 623
624 624 def read_auto_gen(repo):
625 625 """read the AUTO_GEN_FILE for the <repo> a list of Bundle object"""
626 626 data = repo.vfs.tryread(AUTO_GEN_FILE)
627 627 if not data:
628 628 return []
629 629 return parse_auto_gen(data)
630 630
631 631
632 632 def write_auto_gen(repo, bundles):
633 633 """write a list of Bundle objects into the repo's AUTO_GEN_FILE"""
634 634 assert repo._cb_lock_ref is not None
635 635 data = dumps_auto_gen(bundles)
636 636 with repo.vfs(AUTO_GEN_FILE, mode=b'wb', atomictemp=True) as f:
637 637 f.write(data)
638 638
639 639
640 640 def generate_manifest(bundles):
641 641 """write a list of Bundle objects into the repo's AUTO_GEN_FILE"""
642 642 bundles = list(bundles)
643 643 bundles.sort(key=lambda b: b.bundle_type)
644 644 lines = []
645 645 for b in bundles:
646 646 lines.append(b"%s\n" % b.manifest_line())
647 647 return b"".join(lines)
648 648
649 649
650 650 def update_ondisk_manifest(repo):
651 651 """update the clonebundle manifest with latest url"""
652 652 with repo.clonebundles_lock():
653 653 bundles = read_auto_gen(repo)
654 654
655 655 per_types = {}
656 656 for b in bundles:
657 657 if not (b.ready and b.valid_for(repo)):
658 658 continue
659 659 current = per_types.get(b.bundle_type)
660 660 if current is not None and current.revs >= b.revs:
661 661 continue
662 662 per_types[b.bundle_type] = b
663 663 manifest = generate_manifest(per_types.values())
664 664 with repo.vfs(
665 665 bundlecaches.CB_MANIFEST_FILE, mode=b"wb", atomictemp=True
666 666 ) as f:
667 667 f.write(manifest)
668 668
669 669
670 670 def update_bundle_list(repo, new_bundles=(), del_bundles=()):
671 671 """modify the repo's AUTO_GEN_FILE
672 672
673 673 This method also regenerates the clone bundle manifest when needed"""
674 674 with repo.clonebundles_lock():
675 675 bundles = read_auto_gen(repo)
676 676 if del_bundles:
677 677 bundles = [b for b in bundles if b not in del_bundles]
678 678 new_bundles = [b for b in new_bundles if b not in bundles]
679 679 bundles.extend(new_bundles)
680 680 write_auto_gen(repo, bundles)
681 681 all_changed = []
682 682 all_changed.extend(new_bundles)
683 683 all_changed.extend(del_bundles)
684 684 if any(b.ready for b in all_changed):
685 685 update_ondisk_manifest(repo)
686 686
687 687
688 688 def cleanup_tmp_bundle(repo, target):
689 689 """remove a GeneratingBundle file and entry"""
690 690 assert not target.ready
691 691 with repo.clonebundles_lock():
692 692 repo.vfs.tryunlink(target.filepath)
693 693 update_bundle_list(repo, del_bundles=[target])
694 694
695 695
696 696 def finalize_one_bundle(repo, target):
697 697 """upload a generated bundle and advertise it in the clonebundles.manifest"""
698 698 with repo.clonebundles_lock():
699 699 bundles = read_auto_gen(repo)
700 700 if target in bundles and target.valid_for(repo):
701 701 result = upload_bundle(repo, target)
702 702 update_bundle_list(repo, new_bundles=[result])
703 703 cleanup_tmp_bundle(repo, target)
704 704
705 705
706 706 def find_outdated_bundles(repo, bundles):
707 707 """finds outdated bundles"""
708 708 olds = []
709 709 per_types = {}
710 710 for b in bundles:
711 711 if not b.valid_for(repo):
712 712 olds.append(b)
713 713 continue
714 714 l = per_types.setdefault(b.bundle_type, [])
715 715 l.append(b)
716 716 for key in sorted(per_types):
717 717 all = per_types[key]
718 718 if len(all) > 1:
719 719 all.sort(key=lambda b: b.revs, reverse=True)
720 720 olds.extend(all[1:])
721 721 return olds
722 722
723 723
724 724 def collect_garbage(repo):
725 725 """finds outdated bundles and get them deleted"""
726 726 with repo.clonebundles_lock():
727 727 bundles = read_auto_gen(repo)
728 728 olds = find_outdated_bundles(repo, bundles)
729 729 for o in olds:
730 730 delete_bundle(repo, o)
731 731 update_bundle_list(repo, del_bundles=olds)
732 732
733 733
734 734 def upload_bundle(repo, bundle):
735 735 """upload the result of a GeneratingBundle and return a GeneratedBundle
736 736
737 737 The upload is done using the `clone-bundles.upload-command`
738 738 """
739 739 cmd = repo.ui.config(b'clone-bundles', b'upload-command')
740 740 url = repo.ui.config(b'clone-bundles', b'url-template')
741 741 basename = repo.vfs.basename(bundle.filepath)
742 742 filepath = procutil.shellquote(bundle.filepath)
743 743 variables = {
744 744 b'HGCB_BUNDLE_PATH': filepath,
745 745 b'HGCB_BUNDLE_BASENAME': basename,
746 746 }
747 747 env = procutil.shellenviron(environ=variables)
748 748 ret = repo.ui.system(cmd, environ=env)
749 749 if ret:
750 750 raise error.Abort(b"command returned status %d: %s" % (ret, cmd))
751 751 url = (
752 752 url.decode('utf8')
753 753 .format(basename=basename.decode('utf8'))
754 754 .encode('utf8')
755 755 )
756 756 return bundle.uploaded(url, basename)
757 757
758 758
759 759 def delete_bundle(repo, bundle):
760 760 """delete a bundle from storage"""
761 761 assert bundle.ready
762 762 msg = b'clone-bundles: deleting bundle %s\n'
763 763 msg %= bundle.basename
764 764 if repo.ui.configbool(b'devel', b'debug.clonebundles'):
765 765 repo.ui.write(msg)
766 766 else:
767 767 repo.ui.debug(msg)
768 768
769 769 cmd = repo.ui.config(b'clone-bundles', b'delete-command')
770 770 variables = {
771 771 b'HGCB_BUNDLE_URL': bundle.file_url,
772 772 b'HGCB_BASENAME': bundle.basename,
773 773 }
774 774 env = procutil.shellenviron(environ=variables)
775 775 ret = repo.ui.system(cmd, environ=env)
776 776 if ret:
777 777 raise error.Abort(b"command returned status %d: %s" % (ret, cmd))
778 778
779 779
780 780 def auto_bundle_needed_actions(repo, bundles, op_id):
781 781 """find the list of bundles that need action
782 782
783 783 returns a list of RequestedBundle objects that need to be generated and
784 784 uploaded."""
785 785 create_bundles = []
786 786 delete_bundles = []
787 787 repo = repo.filtered(b"immutable")
788 788 targets = repo.ui.configlist(b'clone-bundles', b'auto-generate.formats')
789 789 ratio = float(
790 790 repo.ui.config(b'clone-bundles', b'trigger.below-bundled-ratio')
791 791 )
792 792 abs_revs = repo.ui.configint(b'clone-bundles', b'trigger.revs')
793 793 revs = len(repo.changelog)
794 794 generic_data = {
795 795 'revs': revs,
796 796 'head_revs': repo.changelog.headrevs(),
797 797 'tip_rev': repo.changelog.tiprev(),
798 798 'tip_node': node.hex(repo.changelog.tip()),
799 799 'op_id': op_id,
800 800 }
801 801 for t in targets:
802 802 if new_bundle_needed(repo, bundles, ratio, abs_revs, t, revs):
803 803 data = generic_data.copy()
804 804 data['bundle_type'] = t
805 805 b = RequestedBundle(**data)
806 806 create_bundles.append(b)
807 807 delete_bundles.extend(find_outdated_bundles(repo, bundles))
808 808 return create_bundles, delete_bundles
809 809
810 810
811 811 def new_bundle_needed(repo, bundles, ratio, abs_revs, bundle_type, revs):
812 812 """consider the current cached content and trigger new bundles if needed"""
813 813 threshold = max((revs * ratio), (revs - abs_revs))
814 814 for b in bundles:
815 815 if not b.valid_for(repo) or b.bundle_type != bundle_type:
816 816 continue
817 817 if b.revs > threshold:
818 818 return False
819 819 return True
820 820
821 821
822 822 def start_one_bundle(repo, bundle):
823 823 """start the generation of a single bundle file
824 824
825 825 the `bundle` argument should be a RequestedBundle object.
826 826
827 827 This data is passed to the `debugmakeclonebundles` "as is".
828 828 """
829 829 data = util.pickle.dumps(bundle)
830 830 cmd = [procutil.hgexecutable(), b'--cwd', repo.path, INTERNAL_CMD]
831 831 env = procutil.shellenviron()
832 832 msg = b'clone-bundles: starting bundle generation: %s\n'
833 833 stdout = None
834 834 stderr = None
835 835 waits = []
836 836 record_wait = None
837 837 if repo.ui.configbool(b'devel', b'debug.clonebundles'):
838 838 stdout = procutil.stdout
839 839 stderr = procutil.stderr
840 840 repo.ui.write(msg % bundle.bundle_type)
841 841 record_wait = waits.append
842 842 else:
843 843 repo.ui.debug(msg % bundle.bundle_type)
844 844 bg = procutil.runbgcommand
845 845 bg(
846 846 cmd,
847 847 env,
848 848 stdin_bytes=data,
849 849 stdout=stdout,
850 850 stderr=stderr,
851 851 record_wait=record_wait,
852 852 )
853 853 for f in waits:
854 854 f()
855 855
856 856
857 857 INTERNAL_CMD = b'debug::internal-make-clone-bundles'
858 858
859 859
860 860 @command(INTERNAL_CMD, [], b'')
861 861 def debugmakeclonebundles(ui, repo):
862 862 """Internal command to auto-generate debug bundles"""
863 863 requested_bundle = util.pickle.load(procutil.stdin)
864 864 procutil.stdin.close()
865 865
866 866 collect_garbage(repo)
867 867
868 868 fname = requested_bundle.suggested_filename
869 869 fpath = repo.vfs.makedirs(b'tmp-bundles')
870 870 fpath = repo.vfs.join(b'tmp-bundles', fname)
871 871 bundle = requested_bundle.generating(fpath)
872 872 update_bundle_list(repo, new_bundles=[bundle])
873 873
874 874 requested_bundle.generate_bundle(repo, fpath)
875 875
876 876 repo.invalidate()
877 877 finalize_one_bundle(repo, bundle)
878 878
879 879
880 880 def make_auto_bundler(source_repo):
881 881 reporef = weakref.ref(source_repo)
882 882
883 883 def autobundle(tr):
884 884 repo = reporef()
885 885 assert repo is not None
886 886 bundles = read_auto_gen(repo)
887 887 new, __ = auto_bundle_needed_actions(repo, bundles, b"%d_txn" % id(tr))
888 888 for data in new:
889 889 start_one_bundle(repo, data)
890 890 return None
891 891
892 892 return autobundle
893 893
894 894
895 895 def reposetup(ui, repo):
896 896 """install the two pieces needed for automatic clonebundle generation
897 897
898 898 - add a "post-close" hook that fires bundling when needed
899 899 - introduce a clone-bundle lock to let multiple processes meddle with the
900 900 state files.
901 901 """
902 902 if not repo.local():
903 903 return
904 904
905 905 class autobundlesrepo(repo.__class__):
906 906 def transaction(self, *args, **kwargs):
907 907 tr = super(autobundlesrepo, self).transaction(*args, **kwargs)
908 908 enabled = repo.ui.configbool(
909 909 b'clone-bundles',
910 910 b'auto-generate.on-change',
911 911 )
912 912 targets = repo.ui.configlist(
913 913 b'clone-bundles', b'auto-generate.formats'
914 914 )
915 915 if enabled and targets:
916 916 tr.addpostclose(CAT_POSTCLOSE, make_auto_bundler(self))
917 917 return tr
918 918
919 919 @localrepo.unfilteredmethod
920 920 def clonebundles_lock(self, wait=True):
921 921 '''Lock the repository file related to clone bundles'''
922 922 if not util.safehasattr(self, '_cb_lock_ref'):
923 923 self._cb_lock_ref = None
924 924 l = self._currentlock(self._cb_lock_ref)
925 925 if l is not None:
926 926 l.lock()
927 927 return l
928 928
929 929 l = self._lock(
930 930 vfs=self.vfs,
931 931 lockname=b"clonebundleslock",
932 932 wait=wait,
933 933 releasefn=None,
934 934 acquirefn=None,
935 935 desc=_(b'repository %s') % self.origroot,
936 936 )
937 937 self._cb_lock_ref = weakref.ref(l)
938 938 return l
939 939
940 940 repo._wlockfreeprefix.add(AUTO_GEN_FILE)
941 941 repo._wlockfreeprefix.add(bundlecaches.CB_MANIFEST_FILE)
942 942 repo.__class__ = autobundlesrepo
943 943
944 944
945 945 @command(b'admin::clone-bundles-refresh', [], b'')
946 946 def cmd_admin_clone_bundles_refresh(ui, repo: localrepo.localrepository):
947 947 """generate clone bundles according to the configuration
948 948
949 949 This runs the logic for automatic generation, removing outdated bundles and
950 950 generating new ones if necessary. See :hg:`help -e clone-bundles` for
951 951 details about how to configure this feature.
952 952 """
953 953 debug = repo.ui.configbool(b'devel', b'debug.clonebundles')
954 954 bundles = read_auto_gen(repo)
955 955 op_id = b"%d_acbr" % os.getpid()
956 956 create, delete = auto_bundle_needed_actions(repo, bundles, op_id)
957 957
958 958 # we clean up outdated bundle before generating new one to keep the last
959 959 # two version of the bundle around for a while and avoid having to deal
960 960 # client that just got served a manifest.
961 961 for o in delete:
962 962 delete_bundle(repo, o)
963 963 update_bundle_list(repo, del_bundles=delete)
964 964
965 965 if create:
966 966 fpath = repo.vfs.makedirs(b'tmp-bundles')
967 967 for requested_bundle in create:
968 968 if debug:
969 969 msg = b'clone-bundles: starting bundle generation: %s\n'
970 970 repo.ui.write(msg % requested_bundle.bundle_type)
971 971 fname = requested_bundle.suggested_filename
972 972 fpath = repo.vfs.join(b'tmp-bundles', fname)
973 973 generating_bundle = requested_bundle.generating(fpath)
974 974 update_bundle_list(repo, new_bundles=[generating_bundle])
975 975 requested_bundle.generate_bundle(repo, fpath)
976 976 result = upload_bundle(repo, generating_bundle)
977 977 update_bundle_list(repo, new_bundles=[result])
978 978 update_ondisk_manifest(repo)
979 979 cleanup_tmp_bundle(repo, generating_bundle)
980
981
982 @command(b'admin::clone-bundles-clear', [], b'')
983 def cmd_admin_clone_bundles_clear(ui, repo: localrepo.localrepository):
984 """remove existing clone bundle caches
985
986 See `hg help admin::clone-bundles-refresh` for details on how to regenerate
987 them.
988
989 This command will only affect bundles currently available, it will not
990 affect bundles being asynchronously generated.
991 """
992 bundles = read_auto_gen(repo)
993 delete = [b for b in bundles if b.ready]
994 for o in delete:
995 delete_bundle(repo, o)
996 update_bundle_list(repo, del_bundles=delete)
@@ -1,320 +1,337 b''
1 1
2 2 #require no-reposimplestore no-chg
3 3
4 4 initial setup
5 5
6 6 $ hg init server
7 7 $ cat >> server/.hg/hgrc << EOF
8 8 > [extensions]
9 9 > clonebundles =
10 10 >
11 11 > [clone-bundles]
12 12 > auto-generate.on-change = yes
13 13 > auto-generate.formats = v2
14 14 > upload-command = cp "\$HGCB_BUNDLE_PATH" "$TESTTMP"/final-upload/
15 15 > delete-command = rm -f "$TESTTMP/final-upload/\$HGCB_BASENAME"
16 16 > url-template = file://$TESTTMP/final-upload/{basename}
17 17 >
18 18 > [devel]
19 19 > debug.clonebundles=yes
20 20 > EOF
21 21
22 22 $ mkdir final-upload
23 23 $ hg clone server client
24 24 updating to branch default
25 25 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
26 26 $ cd client
27 27
28 28 Test bundles are generated on push
29 29 ==================================
30 30
31 31 $ touch foo
32 32 $ hg -q commit -A -m 'add foo'
33 33 $ touch bar
34 34 $ hg -q commit -A -m 'add bar'
35 35 $ hg push
36 36 pushing to $TESTTMP/server
37 37 searching for changes
38 38 adding changesets
39 39 adding manifests
40 40 adding file changes
41 41 2 changesets found
42 42 added 2 changesets with 2 changes to 2 files
43 43 clone-bundles: starting bundle generation: v2
44 44 $ cat ../server/.hg/clonebundles.manifest
45 45 file:/*/$TESTTMP/final-upload/full-v2-2_revs-aaff8d2ffbbf_tip-*_txn.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
46 46 $ ls -1 ../final-upload
47 47 full-v2-2_revs-aaff8d2ffbbf_tip-*_txn.hg (glob)
48 48 $ ls -1 ../server/.hg/tmp-bundles
49 49
50 50 Newer bundles are generated with more pushes
51 51 --------------------------------------------
52 52
53 53 $ touch baz
54 54 $ hg -q commit -A -m 'add baz'
55 55 $ touch buz
56 56 $ hg -q commit -A -m 'add buz'
57 57 $ hg push
58 58 pushing to $TESTTMP/server
59 59 searching for changes
60 60 adding changesets
61 61 adding manifests
62 62 adding file changes
63 63 4 changesets found
64 64 added 2 changesets with 2 changes to 2 files
65 65 clone-bundles: starting bundle generation: v2
66 66
67 67 $ cat ../server/.hg/clonebundles.manifest
68 68 file:/*/$TESTTMP/final-upload/full-v2-4_revs-6427147b985a_tip-*_txn.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
69 69 $ ls -1 ../final-upload
70 70 full-v2-2_revs-aaff8d2ffbbf_tip-*_txn.hg (glob)
71 71 full-v2-4_revs-6427147b985a_tip-*_txn.hg (glob)
72 72 $ ls -1 ../server/.hg/tmp-bundles
73 73
74 74 Older bundles are cleaned up with more pushes
75 75 ---------------------------------------------
76 76
77 77 $ touch faz
78 78 $ hg -q commit -A -m 'add faz'
79 79 $ touch fuz
80 80 $ hg -q commit -A -m 'add fuz'
81 81 $ hg push
82 82 pushing to $TESTTMP/server
83 83 searching for changes
84 84 adding changesets
85 85 adding manifests
86 86 adding file changes
87 87 clone-bundles: deleting bundle full-v2-2_revs-aaff8d2ffbbf_tip-*_txn.hg (glob)
88 88 6 changesets found
89 89 added 2 changesets with 2 changes to 2 files
90 90 clone-bundles: starting bundle generation: v2
91 91
92 92 $ cat ../server/.hg/clonebundles.manifest
93 93 file:/*/$TESTTMP/final-upload/full-v2-6_revs-b1010e95ea00_tip-*_txn.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
94 94 $ ls -1 ../final-upload
95 95 full-v2-4_revs-6427147b985a_tip-*_txn.hg (glob)
96 96 full-v2-6_revs-b1010e95ea00_tip-*_txn.hg (glob)
97 97 $ ls -1 ../server/.hg/tmp-bundles
98 98
99 99 Test conditions to get them generated
100 100 =====================================
101 101
102 102 Check ratio
103 103
104 104 $ cat >> ../server/.hg/hgrc << EOF
105 105 > [clone-bundles]
106 106 > trigger.below-bundled-ratio = 0.5
107 107 > EOF
108 108 $ touch far
109 109 $ hg -q commit -A -m 'add far'
110 110 $ hg push
111 111 pushing to $TESTTMP/server
112 112 searching for changes
113 113 adding changesets
114 114 adding manifests
115 115 adding file changes
116 116 added 1 changesets with 1 changes to 1 files
117 117 $ cat ../server/.hg/clonebundles.manifest
118 118 file:/*/$TESTTMP/final-upload/full-v2-6_revs-b1010e95ea00_tip-*_txn.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
119 119 $ ls -1 ../final-upload
120 120 full-v2-4_revs-6427147b985a_tip-*_txn.hg (glob)
121 121 full-v2-6_revs-b1010e95ea00_tip-*_txn.hg (glob)
122 122 $ ls -1 ../server/.hg/tmp-bundles
123 123
124 124 Check absolute number of revisions
125 125
126 126 $ cat >> ../server/.hg/hgrc << EOF
127 127 > [clone-bundles]
128 128 > trigger.revs = 2
129 129 > EOF
130 130 $ touch bur
131 131 $ hg -q commit -A -m 'add bur'
132 132 $ hg push
133 133 pushing to $TESTTMP/server
134 134 searching for changes
135 135 adding changesets
136 136 adding manifests
137 137 adding file changes
138 138 clone-bundles: deleting bundle full-v2-4_revs-6427147b985a_tip-*_txn.hg (glob)
139 139 8 changesets found
140 140 added 1 changesets with 1 changes to 1 files
141 141 clone-bundles: starting bundle generation: v2
142 142 $ cat ../server/.hg/clonebundles.manifest
143 143 file:/*/$TESTTMP/final-upload/full-v2-8_revs-8353e8af1306_tip-*_txn.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
144 144 $ ls -1 ../final-upload
145 145 full-v2-6_revs-b1010e95ea00_tip-*_txn.hg (glob)
146 146 full-v2-8_revs-8353e8af1306_tip-*_txn.hg (glob)
147 147 $ ls -1 ../server/.hg/tmp-bundles
148 148
149 149 (that one would not generate new bundles)
150 150
151 151 $ touch tur
152 152 $ hg -q commit -A -m 'add tur'
153 153 $ hg push
154 154 pushing to $TESTTMP/server
155 155 searching for changes
156 156 adding changesets
157 157 adding manifests
158 158 adding file changes
159 159 added 1 changesets with 1 changes to 1 files
160 160 $ cat ../server/.hg/clonebundles.manifest
161 161 file:/*/$TESTTMP/final-upload/full-v2-8_revs-8353e8af1306_tip-*_txn.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
162 162 $ ls -1 ../final-upload
163 163 full-v2-6_revs-b1010e95ea00_tip-*_txn.hg (glob)
164 164 full-v2-8_revs-8353e8af1306_tip-*_txn.hg (glob)
165 165 $ ls -1 ../server/.hg/tmp-bundles
166 166
167 167 Test generation through the dedicated command
168 168 =============================================
169 169
170 170 $ cat >> ../server/.hg/hgrc << EOF
171 171 > [clone-bundles]
172 172 > auto-generate.on-change = no
173 173 > EOF
174 174
175 175 Check the command can generate content when needed
176 176 --------------------------------------------------
177 177
178 178 Do a push that makes the condition fulfilled,
179 179 Yet it should not automatically generate a bundle with
180 180 "auto-generate.on-change" not set.
181 181
182 182 $ touch quoi
183 183 $ hg -q commit -A -m 'add quoi'
184 184
185 185 $ pre_push_manifest=`cat ../server/.hg/clonebundles.manifest|f --sha256 | sed 's/.*=//' | cat`
186 186 $ pre_push_upload=`ls -1 ../final-upload|f --sha256 | sed 's/.*=//' | cat`
187 187 $ ls -1 ../server/.hg/tmp-bundles
188 188
189 189 $ hg push
190 190 pushing to $TESTTMP/server
191 191 searching for changes
192 192 adding changesets
193 193 adding manifests
194 194 adding file changes
195 195 added 1 changesets with 1 changes to 1 files
196 196
197 197 $ post_push_manifest=`cat ../server/.hg/clonebundles.manifest|f --sha256 | sed 's/.*=//' | cat`
198 198 $ post_push_upload=`ls -1 ../final-upload|f --sha256 | sed 's/.*=//' | cat`
199 199 $ ls -1 ../server/.hg/tmp-bundles
200 200 $ test "$pre_push_manifest" = "$post_push_manifest"
201 201 $ test "$pre_push_upload" = "$post_push_upload"
202 202
203 203 Running the command should detect the stale bundles, and do the full automatic
204 204 generation logic.
205 205
206 206 $ hg -R ../server/ admin::clone-bundles-refresh
207 207 clone-bundles: deleting bundle full-v2-6_revs-b1010e95ea00_tip-*_txn.hg (glob)
208 208 clone-bundles: starting bundle generation: v2
209 209 10 changesets found
210 210 $ cat ../server/.hg/clonebundles.manifest
211 211 file:/*/$TESTTMP/final-upload/full-v2-10_revs-3b6f57f17d70_tip-*_acbr.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
212 212 $ ls -1 ../final-upload
213 213 full-v2-10_revs-3b6f57f17d70_tip-*_acbr.hg (glob)
214 214 full-v2-8_revs-8353e8af1306_tip-*_txn.hg (glob)
215 215 $ ls -1 ../server/.hg/tmp-bundles
216 216
217 217 Check the command cleans up older bundles when possible
218 218 -------------------------------------------------------
219 219
220 220 $ hg -R ../server/ admin::clone-bundles-refresh
221 221 clone-bundles: deleting bundle full-v2-8_revs-8353e8af1306_tip-*_txn.hg (glob)
222 222 $ cat ../server/.hg/clonebundles.manifest
223 223 file:/*/$TESTTMP/final-upload/full-v2-10_revs-3b6f57f17d70_tip-*_acbr.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
224 224 $ ls -1 ../final-upload
225 225 full-v2-10_revs-3b6f57f17d70_tip-*_acbr.hg (glob)
226 226 $ ls -1 ../server/.hg/tmp-bundles
227 227
228 228 Nothing is generated when the bundles are sufficiently up to date
229 229 -----------------------------------------------------------------
230 230
231 231 $ touch feur
232 232 $ hg -q commit -A -m 'add feur'
233 233
234 234 $ pre_push_manifest=`cat ../server/.hg/clonebundles.manifest|f --sha256 | sed 's/.*=//' | cat`
235 235 $ pre_push_upload=`ls -1 ../final-upload|f --sha256 | sed 's/.*=//' | cat`
236 236 $ ls -1 ../server/.hg/tmp-bundles
237 237
238 238 $ hg push
239 239 pushing to $TESTTMP/server
240 240 searching for changes
241 241 adding changesets
242 242 adding manifests
243 243 adding file changes
244 244 added 1 changesets with 1 changes to 1 files
245 245
246 246 $ post_push_manifest=`cat ../server/.hg/clonebundles.manifest|f --sha256 | sed 's/.*=//' | cat`
247 247 $ post_push_upload=`ls -1 ../final-upload|f --sha256 | sed 's/.*=//' | cat`
248 248 $ ls -1 ../server/.hg/tmp-bundles
249 249 $ test "$pre_push_manifest" = "$post_push_manifest"
250 250 $ test "$pre_push_upload" = "$post_push_upload"
251 251
252 252 $ hg -R ../server/ admin::clone-bundles-refresh
253 253
254 254 $ post_refresh_manifest=`cat ../server/.hg/clonebundles.manifest|f --sha256 | sed 's/.*=//' | cat`
255 255 $ post_refresh_upload=`ls -1 ../final-upload|f --sha256 | sed 's/.*=//' | cat`
256 256 $ ls -1 ../server/.hg/tmp-bundles
257 257 $ test "$pre_push_manifest" = "$post_refresh_manifest"
258 258 $ test "$pre_push_upload" = "$post_refresh_upload"
259 259
260 260 Test modification of configuration
261 261 ==================================
262 262
263 263 Testing that later runs adapt to configuration changes even if the repository is
264 264 unchanged.
265 265
266 266 adding more formats
267 267 -------------------
268 268
269 269 bundle for added formats should be generated
270 270
271 271 change configuration
272 272
273 273 $ cat >> ../server/.hg/hgrc << EOF
274 274 > [clone-bundles]
275 275 > auto-generate.formats = v1, v2
276 276 > EOF
277 277
278 278 refresh the bundles
279 279
280 280 $ hg -R ../server/ admin::clone-bundles-refresh
281 281 clone-bundles: starting bundle generation: v1
282 282 11 changesets found
283 283
284 284 the bundle for the "new" format should have been added
285 285
286 286 $ cat ../server/.hg/clonebundles.manifest
287 287 file:/*/$TESTTMP/final-upload/full-v1-11_revs-4226b1cd5fda_tip-*_acbr.hg BUNDLESPEC=v1 REQUIRESNI=true (glob)
288 288 file:/*/$TESTTMP/final-upload/full-v2-10_revs-3b6f57f17d70_tip-*_acbr.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
289 289 $ ls -1 ../final-upload
290 290 full-v1-11_revs-4226b1cd5fda_tip-*_acbr.hg (glob)
291 291 full-v2-10_revs-3b6f57f17d70_tip-*_acbr.hg (glob)
292 292 $ ls -1 ../server/.hg/tmp-bundles
293 293
294 294 Changing the ratio
295 295 ------------------
296 296
297 297 Changing the ratio to something that would have triggered a bundle during the last push.
298 298
299 299 $ cat >> ../server/.hg/hgrc << EOF
300 300 > [clone-bundles]
301 301 > trigger.below-bundled-ratio = 0.95
302 302 > EOF
303 303
304 304 refresh the bundles
305 305
306 306 $ hg -R ../server/ admin::clone-bundles-refresh
307 307 clone-bundles: starting bundle generation: v2
308 308 11 changesets found
309 309
310 310
311 311 the "outdated' bundle should be refreshed
312 312
313 313 $ cat ../server/.hg/clonebundles.manifest
314 314 file:/*/$TESTTMP/final-upload/full-v1-11_revs-4226b1cd5fda_tip-*_acbr.hg BUNDLESPEC=v1 REQUIRESNI=true (glob)
315 315 file:/*/$TESTTMP/final-upload/full-v2-11_revs-4226b1cd5fda_tip-*_acbr.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
316 316 $ ls -1 ../final-upload
317 317 full-v1-11_revs-4226b1cd5fda_tip-*_acbr.hg (glob)
318 318 full-v2-10_revs-3b6f57f17d70_tip-*_acbr.hg (glob)
319 319 full-v2-11_revs-4226b1cd5fda_tip-*_acbr.hg (glob)
320 320 $ ls -1 ../server/.hg/tmp-bundles
321
322 Test more command options
323 =========================
324
325 bundle clearing
326 ---------------
327
328 $ hg -R ../server/ admin::clone-bundles-clear
329 clone-bundles: deleting bundle full-v1-11_revs-4226b1cd5fda_tip-*_acbr.hg (glob)
330 clone-bundles: deleting bundle full-v2-10_revs-3b6f57f17d70_tip-*_acbr.hg (glob)
331 clone-bundles: deleting bundle full-v2-11_revs-4226b1cd5fda_tip-*_acbr.hg (glob)
332
333 Nothing should remain
334
335 $ cat ../server/.hg/clonebundles.manifest
336 $ ls -1 ../final-upload
337 $ ls -1 ../server/.hg/tmp-bundles
@@ -1,4081 +1,4082 b''
1 1 Short help:
2 2
3 3 $ hg
4 4 Mercurial Distributed SCM
5 5
6 6 basic commands:
7 7
8 8 add add the specified files on the next commit
9 9 annotate show changeset information by line for each file
10 10 clone make a copy of an existing repository
11 11 commit commit the specified files or all outstanding changes
12 12 diff diff repository (or selected files)
13 13 export dump the header and diffs for one or more changesets
14 14 forget forget the specified files on the next commit
15 15 init create a new repository in the given directory
16 16 log show revision history of entire repository or files
17 17 merge merge another revision into working directory
18 18 pull pull changes from the specified source
19 19 push push changes to the specified destination
20 20 remove remove the specified files on the next commit
21 21 serve start stand-alone webserver
22 22 status show changed files in the working directory
23 23 summary summarize working directory state
24 24 update update working directory (or switch revisions)
25 25
26 26 (use 'hg help' for the full list of commands or 'hg -v' for details)
27 27
28 28 $ hg -q
29 29 add add the specified files on the next commit
30 30 annotate show changeset information by line for each file
31 31 clone make a copy of an existing repository
32 32 commit commit the specified files or all outstanding changes
33 33 diff diff repository (or selected files)
34 34 export dump the header and diffs for one or more changesets
35 35 forget forget the specified files on the next commit
36 36 init create a new repository in the given directory
37 37 log show revision history of entire repository or files
38 38 merge merge another revision into working directory
39 39 pull pull changes from the specified source
40 40 push push changes to the specified destination
41 41 remove remove the specified files on the next commit
42 42 serve start stand-alone webserver
43 43 status show changed files in the working directory
44 44 summary summarize working directory state
45 45 update update working directory (or switch revisions)
46 46
47 47 Extra extensions will be printed in help output in a non-reliable order since
48 48 the extension is unknown.
49 49 #if no-extraextensions
50 50
51 51 $ hg help
52 52 Mercurial Distributed SCM
53 53
54 54 list of commands:
55 55
56 56 Repository creation:
57 57
58 58 clone make a copy of an existing repository
59 59 init create a new repository in the given directory
60 60
61 61 Remote repository management:
62 62
63 63 incoming show new changesets found in source
64 64 outgoing show changesets not found in the destination
65 65 paths show aliases for remote repositories
66 66 pull pull changes from the specified source
67 67 push push changes to the specified destination
68 68 serve start stand-alone webserver
69 69
70 70 Change creation:
71 71
72 72 commit commit the specified files or all outstanding changes
73 73
74 74 Change manipulation:
75 75
76 76 backout reverse effect of earlier changeset
77 77 graft copy changes from other branches onto the current branch
78 78 merge merge another revision into working directory
79 79
80 80 Change organization:
81 81
82 82 bookmarks create a new bookmark or list existing bookmarks
83 83 branch set or show the current branch name
84 84 branches list repository named branches
85 85 phase set or show the current phase name
86 86 tag add one or more tags for the current or given revision
87 87 tags list repository tags
88 88
89 89 File content management:
90 90
91 91 annotate show changeset information by line for each file
92 92 cat output the current or given revision of files
93 93 copy mark files as copied for the next commit
94 94 diff diff repository (or selected files)
95 95 grep search for a pattern in specified files
96 96
97 97 Change navigation:
98 98
99 99 bisect subdivision search of changesets
100 100 heads show branch heads
101 101 identify identify the working directory or specified revision
102 102 log show revision history of entire repository or files
103 103
104 104 Working directory management:
105 105
106 106 add add the specified files on the next commit
107 107 addremove add all new files, delete all missing files
108 108 files list tracked files
109 109 forget forget the specified files on the next commit
110 110 purge removes files not tracked by Mercurial
111 111 remove remove the specified files on the next commit
112 112 rename rename files; equivalent of copy + remove
113 113 resolve redo merges or set/view the merge status of files
114 114 revert restore files to their checkout state
115 115 root print the root (top) of the current working directory
116 116 shelve save and set aside changes from the working directory
117 117 status show changed files in the working directory
118 118 summary summarize working directory state
119 119 unshelve restore a shelved change to the working directory
120 120 update update working directory (or switch revisions)
121 121
122 122 Change import/export:
123 123
124 124 archive create an unversioned archive of a repository revision
125 125 bundle create a bundle file
126 126 export dump the header and diffs for one or more changesets
127 127 import import an ordered set of patches
128 128 unbundle apply one or more bundle files
129 129
130 130 Repository maintenance:
131 131
132 132 manifest output the current or given revision of the project manifest
133 133 recover roll back an interrupted transaction
134 134 verify verify the integrity of the repository
135 135
136 136 Help:
137 137
138 138 config show combined config settings from all hgrc files
139 139 help show help for a given topic or a help overview
140 140 version output version and copyright information
141 141
142 142 additional help topics:
143 143
144 144 Mercurial identifiers:
145 145
146 146 filesets Specifying File Sets
147 147 hgignore Syntax for Mercurial Ignore Files
148 148 patterns File Name Patterns
149 149 revisions Specifying Revisions
150 150 urls URL Paths
151 151
152 152 Mercurial output:
153 153
154 154 color Colorizing Outputs
155 155 dates Date Formats
156 156 diffs Diff Formats
157 157 templating Template Usage
158 158
159 159 Mercurial configuration:
160 160
161 161 config Configuration Files
162 162 environment Environment Variables
163 163 extensions Using Additional Features
164 164 flags Command-line flags
165 165 hgweb Configuring hgweb
166 166 merge-tools Merge Tools
167 167 pager Pager Support
168 168 rust Rust in Mercurial
169 169
170 170 Concepts:
171 171
172 172 bundlespec Bundle File Formats
173 173 evolution Safely rewriting history (EXPERIMENTAL)
174 174 glossary Glossary
175 175 phases Working with Phases
176 176 subrepos Subrepositories
177 177
178 178 Miscellaneous:
179 179
180 180 deprecated Deprecated Features
181 181 internals Technical implementation topics
182 182 scripting Using Mercurial from scripts and automation
183 183
184 184 (use 'hg help -v' to show built-in aliases and global options)
185 185
186 186 $ hg -q help
187 187 Repository creation:
188 188
189 189 clone make a copy of an existing repository
190 190 init create a new repository in the given directory
191 191
192 192 Remote repository management:
193 193
194 194 incoming show new changesets found in source
195 195 outgoing show changesets not found in the destination
196 196 paths show aliases for remote repositories
197 197 pull pull changes from the specified source
198 198 push push changes to the specified destination
199 199 serve start stand-alone webserver
200 200
201 201 Change creation:
202 202
203 203 commit commit the specified files or all outstanding changes
204 204
205 205 Change manipulation:
206 206
207 207 backout reverse effect of earlier changeset
208 208 graft copy changes from other branches onto the current branch
209 209 merge merge another revision into working directory
210 210
211 211 Change organization:
212 212
213 213 bookmarks create a new bookmark or list existing bookmarks
214 214 branch set or show the current branch name
215 215 branches list repository named branches
216 216 phase set or show the current phase name
217 217 tag add one or more tags for the current or given revision
218 218 tags list repository tags
219 219
220 220 File content management:
221 221
222 222 annotate show changeset information by line for each file
223 223 cat output the current or given revision of files
224 224 copy mark files as copied for the next commit
225 225 diff diff repository (or selected files)
226 226 grep search for a pattern in specified files
227 227
228 228 Change navigation:
229 229
230 230 bisect subdivision search of changesets
231 231 heads show branch heads
232 232 identify identify the working directory or specified revision
233 233 log show revision history of entire repository or files
234 234
235 235 Working directory management:
236 236
237 237 add add the specified files on the next commit
238 238 addremove add all new files, delete all missing files
239 239 files list tracked files
240 240 forget forget the specified files on the next commit
241 241 purge removes files not tracked by Mercurial
242 242 remove remove the specified files on the next commit
243 243 rename rename files; equivalent of copy + remove
244 244 resolve redo merges or set/view the merge status of files
245 245 revert restore files to their checkout state
246 246 root print the root (top) of the current working directory
247 247 shelve save and set aside changes from the working directory
248 248 status show changed files in the working directory
249 249 summary summarize working directory state
250 250 unshelve restore a shelved change to the working directory
251 251 update update working directory (or switch revisions)
252 252
253 253 Change import/export:
254 254
255 255 archive create an unversioned archive of a repository revision
256 256 bundle create a bundle file
257 257 export dump the header and diffs for one or more changesets
258 258 import import an ordered set of patches
259 259 unbundle apply one or more bundle files
260 260
261 261 Repository maintenance:
262 262
263 263 manifest output the current or given revision of the project manifest
264 264 recover roll back an interrupted transaction
265 265 verify verify the integrity of the repository
266 266
267 267 Help:
268 268
269 269 config show combined config settings from all hgrc files
270 270 help show help for a given topic or a help overview
271 271 version output version and copyright information
272 272
273 273 additional help topics:
274 274
275 275 Mercurial identifiers:
276 276
277 277 filesets Specifying File Sets
278 278 hgignore Syntax for Mercurial Ignore Files
279 279 patterns File Name Patterns
280 280 revisions Specifying Revisions
281 281 urls URL Paths
282 282
283 283 Mercurial output:
284 284
285 285 color Colorizing Outputs
286 286 dates Date Formats
287 287 diffs Diff Formats
288 288 templating Template Usage
289 289
290 290 Mercurial configuration:
291 291
292 292 config Configuration Files
293 293 environment Environment Variables
294 294 extensions Using Additional Features
295 295 flags Command-line flags
296 296 hgweb Configuring hgweb
297 297 merge-tools Merge Tools
298 298 pager Pager Support
299 299 rust Rust in Mercurial
300 300
301 301 Concepts:
302 302
303 303 bundlespec Bundle File Formats
304 304 evolution Safely rewriting history (EXPERIMENTAL)
305 305 glossary Glossary
306 306 phases Working with Phases
307 307 subrepos Subrepositories
308 308
309 309 Miscellaneous:
310 310
311 311 deprecated Deprecated Features
312 312 internals Technical implementation topics
313 313 scripting Using Mercurial from scripts and automation
314 314
315 315 Test extension help:
316 316 $ hg help extensions --config extensions.rebase= --config extensions.children=
317 317 Using Additional Features
318 318 """""""""""""""""""""""""
319 319
320 320 Mercurial has the ability to add new features through the use of
321 321 extensions. Extensions may add new commands, add options to existing
322 322 commands, change the default behavior of commands, or implement hooks.
323 323
324 324 To enable the "foo" extension, either shipped with Mercurial or in the
325 325 Python search path, create an entry for it in your configuration file,
326 326 like this:
327 327
328 328 [extensions]
329 329 foo =
330 330
331 331 You may also specify the full path to an extension:
332 332
333 333 [extensions]
334 334 myfeature = ~/.hgext/myfeature.py
335 335
336 336 See 'hg help config' for more information on configuration files.
337 337
338 338 Extensions are not loaded by default for a variety of reasons: they can
339 339 increase startup overhead; they may be meant for advanced usage only; they
340 340 may provide potentially dangerous abilities (such as letting you destroy
341 341 or modify history); they might not be ready for prime time; or they may
342 342 alter some usual behaviors of stock Mercurial. It is thus up to the user
343 343 to activate extensions as needed.
344 344
345 345 To explicitly disable an extension enabled in a configuration file of
346 346 broader scope, prepend its path with !:
347 347
348 348 [extensions]
349 349 # disabling extension bar residing in /path/to/extension/bar.py
350 350 bar = !/path/to/extension/bar.py
351 351 # ditto, but no path was supplied for extension baz
352 352 baz = !
353 353
354 354 enabled extensions:
355 355
356 356 children command to display child changesets (DEPRECATED)
357 357 rebase command to move sets of revisions to a different ancestor
358 358
359 359 disabled extensions:
360 360
361 361 acl hooks for controlling repository access
362 362 blackbox log repository events to a blackbox for debugging
363 363 bugzilla hooks for integrating with the Bugzilla bug tracker
364 364 censor erase file content at a given revision
365 365 churn command to display statistics about repository history
366 366 clonebundles advertise pre-generated bundles to seed clones
367 367 closehead close arbitrary heads without checking them out first
368 368 convert import revisions from foreign VCS repositories into
369 369 Mercurial
370 370 eol automatically manage newlines in repository files
371 371 extdiff command to allow external programs to compare revisions
372 372 factotum http authentication with factotum
373 373 fastexport export repositories as git fast-import stream
374 374 githelp try mapping git commands to Mercurial commands
375 375 gpg commands to sign and verify changesets
376 376 hgk browse the repository in a graphical way
377 377 highlight syntax highlighting for hgweb (requires Pygments)
378 378 histedit interactive history editing
379 379 keyword expand keywords in tracked files
380 380 largefiles track large binary files
381 381 mq manage a stack of patches
382 382 notify hooks for sending email push notifications
383 383 patchbomb command to send changesets as (a series of) patch emails
384 384 relink recreates hardlinks between repository clones
385 385 schemes extend schemes with shortcuts to repository swarms
386 386 share share a common history between several working directories
387 387 transplant command to transplant changesets from another branch
388 388 win32mbcs allow the use of MBCS paths with problematic encodings
389 389 zeroconf discover and advertise repositories on the local network
390 390
391 391 #endif
392 392
393 393 Verify that deprecated extensions are included if --verbose:
394 394
395 395 $ hg -v help extensions | grep children
396 396 children command to display child changesets (DEPRECATED)
397 397
398 398 Verify that extension keywords appear in help templates
399 399
400 400 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
401 401
402 402 Test short command list with verbose option
403 403
404 404 $ hg -v help shortlist
405 405 Mercurial Distributed SCM
406 406
407 407 basic commands:
408 408
409 409 abort abort an unfinished operation (EXPERIMENTAL)
410 410 add add the specified files on the next commit
411 411 annotate, blame
412 412 show changeset information by line for each file
413 413 clone make a copy of an existing repository
414 414 commit, ci commit the specified files or all outstanding changes
415 415 continue resumes an interrupted operation (EXPERIMENTAL)
416 416 diff diff repository (or selected files)
417 417 export dump the header and diffs for one or more changesets
418 418 forget forget the specified files on the next commit
419 419 init create a new repository in the given directory
420 420 log, history show revision history of entire repository or files
421 421 merge merge another revision into working directory
422 422 pull pull changes from the specified source
423 423 push push changes to the specified destination
424 424 remove, rm remove the specified files on the next commit
425 425 serve start stand-alone webserver
426 426 status, st show changed files in the working directory
427 427 summary, sum summarize working directory state
428 428 update, up, checkout, co
429 429 update working directory (or switch revisions)
430 430
431 431 global options ([+] can be repeated):
432 432
433 433 -R --repository REPO repository root directory or name of overlay bundle
434 434 file
435 435 --cwd DIR change working directory
436 436 -y --noninteractive do not prompt, automatically pick the first choice for
437 437 all prompts
438 438 -q --quiet suppress output
439 439 -v --verbose enable additional output
440 440 --color TYPE when to colorize (boolean, always, auto, never, or
441 441 debug)
442 442 --config CONFIG [+] set/override config option (use 'section.name=value')
443 443 --debug enable debugging output
444 444 --debugger start debugger
445 445 --encoding ENCODE set the charset encoding (default: ascii)
446 446 --encodingmode MODE set the charset encoding mode (default: strict)
447 447 --traceback always print a traceback on exception
448 448 --time time how long the command takes
449 449 --profile print command execution profile
450 450 --version output version information and exit
451 451 -h --help display help and exit
452 452 --hidden consider hidden changesets
453 453 --pager TYPE when to paginate (boolean, always, auto, or never)
454 454 (default: auto)
455 455
456 456 (use 'hg help' for the full list of commands)
457 457
458 458 $ hg add -h
459 459 hg add [OPTION]... [FILE]...
460 460
461 461 add the specified files on the next commit
462 462
463 463 Schedule files to be version controlled and added to the repository.
464 464
465 465 The files will be added to the repository at the next commit. To undo an
466 466 add before that, see 'hg forget'.
467 467
468 468 If no names are given, add all files to the repository (except files
469 469 matching ".hgignore").
470 470
471 471 Returns 0 if all files are successfully added.
472 472
473 473 options ([+] can be repeated):
474 474
475 475 -I --include PATTERN [+] include names matching the given patterns
476 476 -X --exclude PATTERN [+] exclude names matching the given patterns
477 477 -S --subrepos recurse into subrepositories
478 478 -n --dry-run do not perform actions, just print output
479 479
480 480 (some details hidden, use --verbose to show complete help)
481 481
482 482 Verbose help for add
483 483
484 484 $ hg add -hv
485 485 hg add [OPTION]... [FILE]...
486 486
487 487 add the specified files on the next commit
488 488
489 489 Schedule files to be version controlled and added to the repository.
490 490
491 491 The files will be added to the repository at the next commit. To undo an
492 492 add before that, see 'hg forget'.
493 493
494 494 If no names are given, add all files to the repository (except files
495 495 matching ".hgignore").
496 496
497 497 Examples:
498 498
499 499 - New (unknown) files are added automatically by 'hg add':
500 500
501 501 $ ls
502 502 foo.c
503 503 $ hg status
504 504 ? foo.c
505 505 $ hg add
506 506 adding foo.c
507 507 $ hg status
508 508 A foo.c
509 509
510 510 - Specific files to be added can be specified:
511 511
512 512 $ ls
513 513 bar.c foo.c
514 514 $ hg status
515 515 ? bar.c
516 516 ? foo.c
517 517 $ hg add bar.c
518 518 $ hg status
519 519 A bar.c
520 520 ? foo.c
521 521
522 522 Returns 0 if all files are successfully added.
523 523
524 524 options ([+] can be repeated):
525 525
526 526 -I --include PATTERN [+] include names matching the given patterns
527 527 -X --exclude PATTERN [+] exclude names matching the given patterns
528 528 -S --subrepos recurse into subrepositories
529 529 -n --dry-run do not perform actions, just print output
530 530
531 531 global options ([+] can be repeated):
532 532
533 533 -R --repository REPO repository root directory or name of overlay bundle
534 534 file
535 535 --cwd DIR change working directory
536 536 -y --noninteractive do not prompt, automatically pick the first choice for
537 537 all prompts
538 538 -q --quiet suppress output
539 539 -v --verbose enable additional output
540 540 --color TYPE when to colorize (boolean, always, auto, never, or
541 541 debug)
542 542 --config CONFIG [+] set/override config option (use 'section.name=value')
543 543 --debug enable debugging output
544 544 --debugger start debugger
545 545 --encoding ENCODE set the charset encoding (default: ascii)
546 546 --encodingmode MODE set the charset encoding mode (default: strict)
547 547 --traceback always print a traceback on exception
548 548 --time time how long the command takes
549 549 --profile print command execution profile
550 550 --version output version information and exit
551 551 -h --help display help and exit
552 552 --hidden consider hidden changesets
553 553 --pager TYPE when to paginate (boolean, always, auto, or never)
554 554 (default: auto)
555 555
556 556 Test the textwidth config option
557 557
558 558 $ hg root -h --config ui.textwidth=50
559 559 hg root
560 560
561 561 print the root (top) of the current working
562 562 directory
563 563
564 564 Print the root directory of the current
565 565 repository.
566 566
567 567 Returns 0 on success.
568 568
569 569 options:
570 570
571 571 -T --template TEMPLATE display with template
572 572
573 573 (some details hidden, use --verbose to show
574 574 complete help)
575 575
576 576 Test help option with version option
577 577
578 578 $ hg add -h --version
579 579 Mercurial Distributed SCM (version *) (glob)
580 580 (see https://mercurial-scm.org for more information)
581 581
582 582 Copyright (C) 2005-* Olivia Mackall and others (glob)
583 583 This is free software; see the source for copying conditions. There is NO
584 584 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
585 585
586 586 $ hg add --skjdfks
587 587 hg add: option --skjdfks not recognized
588 588 hg add [OPTION]... [FILE]...
589 589
590 590 add the specified files on the next commit
591 591
592 592 options ([+] can be repeated):
593 593
594 594 -I --include PATTERN [+] include names matching the given patterns
595 595 -X --exclude PATTERN [+] exclude names matching the given patterns
596 596 -S --subrepos recurse into subrepositories
597 597 -n --dry-run do not perform actions, just print output
598 598
599 599 (use 'hg add -h' to show more help)
600 600 [10]
601 601
602 602 Test ambiguous command help
603 603
604 604 $ hg help ad
605 605 list of commands:
606 606
607 607 add add the specified files on the next commit
608 608 addremove add all new files, delete all missing files
609 609
610 610 (use 'hg help -v ad' to show built-in aliases and global options)
611 611
612 612 Test command without options
613 613
614 614 $ hg help verify
615 615 hg verify
616 616
617 617 verify the integrity of the repository
618 618
619 619 Verify the integrity of the current repository.
620 620
621 621 This will perform an extensive check of the repository's integrity,
622 622 validating the hashes and checksums of each entry in the changelog,
623 623 manifest, and tracked files, as well as the integrity of their crosslinks
624 624 and indices.
625 625
626 626 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
627 627 information about recovery from corruption of the repository.
628 628
629 629 Returns 0 on success, 1 if errors are encountered.
630 630
631 631 options:
632 632
633 633 (some details hidden, use --verbose to show complete help)
634 634
635 635 $ hg help diff
636 636 hg diff [OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...
637 637
638 638 diff repository (or selected files)
639 639
640 640 Show differences between revisions for the specified files.
641 641
642 642 Differences between files are shown using the unified diff format.
643 643
644 644 Note:
645 645 'hg diff' may generate unexpected results for merges, as it will
646 646 default to comparing against the working directory's first parent
647 647 changeset if no revisions are specified. To diff against the conflict
648 648 regions, you can use '--config diff.merge=yes'.
649 649
650 650 By default, the working directory files are compared to its first parent.
651 651 To see the differences from another revision, use --from. To see the
652 652 difference to another revision, use --to. For example, 'hg diff --from .^'
653 653 will show the differences from the working copy's grandparent to the
654 654 working copy, 'hg diff --to .' will show the diff from the working copy to
655 655 its parent (i.e. the reverse of the default), and 'hg diff --from 1.0 --to
656 656 1.2' will show the diff between those two revisions.
657 657
658 658 Alternatively you can specify -c/--change with a revision to see the
659 659 changes in that changeset relative to its first parent (i.e. 'hg diff -c
660 660 42' is equivalent to 'hg diff --from 42^ --to 42')
661 661
662 662 Without the -a/--text option, diff will avoid generating diffs of files it
663 663 detects as binary. With -a, diff will generate a diff anyway, probably
664 664 with undesirable results.
665 665
666 666 Use the -g/--git option to generate diffs in the git extended diff format.
667 667 For more information, read 'hg help diffs'.
668 668
669 669 Returns 0 on success.
670 670
671 671 options ([+] can be repeated):
672 672
673 673 --from REV1 revision to diff from
674 674 --to REV2 revision to diff to
675 675 -c --change REV change made by revision
676 676 -a --text treat all files as text
677 677 -g --git use git extended diff format
678 678 --binary generate binary diffs in git mode (default)
679 679 --nodates omit dates from diff headers
680 680 --noprefix omit a/ and b/ prefixes from filenames
681 681 -p --show-function show which function each change is in
682 682 --reverse produce a diff that undoes the changes
683 683 -w --ignore-all-space ignore white space when comparing lines
684 684 -b --ignore-space-change ignore changes in the amount of white space
685 685 -B --ignore-blank-lines ignore changes whose lines are all blank
686 686 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
687 687 -U --unified NUM number of lines of context to show
688 688 --stat output diffstat-style summary of changes
689 689 --root DIR produce diffs relative to subdirectory
690 690 -I --include PATTERN [+] include names matching the given patterns
691 691 -X --exclude PATTERN [+] exclude names matching the given patterns
692 692 -S --subrepos recurse into subrepositories
693 693
694 694 (some details hidden, use --verbose to show complete help)
695 695
696 696 $ hg help status
697 697 hg status [OPTION]... [FILE]...
698 698
699 699 aliases: st
700 700
701 701 show changed files in the working directory
702 702
703 703 Show status of files in the repository. If names are given, only files
704 704 that match are shown. Files that are clean or ignored or the source of a
705 705 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
706 706 -C/--copies or -A/--all are given. Unless options described with "show
707 707 only ..." are given, the options -mardu are used.
708 708
709 709 Option -q/--quiet hides untracked (unknown and ignored) files unless
710 710 explicitly requested with -u/--unknown or -i/--ignored.
711 711
712 712 Note:
713 713 'hg status' may appear to disagree with diff if permissions have
714 714 changed or a merge has occurred. The standard diff format does not
715 715 report permission changes and diff only reports changes relative to one
716 716 merge parent.
717 717
718 718 If one revision is given, it is used as the base revision. If two
719 719 revisions are given, the differences between them are shown. The --change
720 720 option can also be used as a shortcut to list the changed files of a
721 721 revision from its first parent.
722 722
723 723 The codes used to show the status of files are:
724 724
725 725 M = modified
726 726 A = added
727 727 R = removed
728 728 C = clean
729 729 ! = missing (deleted by non-hg command, but still tracked)
730 730 ? = not tracked
731 731 I = ignored
732 732 = origin of the previous file (with --copies)
733 733
734 734 Returns 0 on success.
735 735
736 736 options ([+] can be repeated):
737 737
738 738 -A --all show status of all files
739 739 -m --modified show only modified files
740 740 -a --added show only added files
741 741 -r --removed show only removed files
742 742 -d --deleted show only missing files
743 743 -c --clean show only files without changes
744 744 -u --unknown show only unknown (not tracked) files
745 745 -i --ignored show only ignored files
746 746 -n --no-status hide status prefix
747 747 -C --copies show source of copied files
748 748 -0 --print0 end filenames with NUL, for use with xargs
749 749 --rev REV [+] show difference from revision
750 750 --change REV list the changed files of a revision
751 751 -I --include PATTERN [+] include names matching the given patterns
752 752 -X --exclude PATTERN [+] exclude names matching the given patterns
753 753 -S --subrepos recurse into subrepositories
754 754 -T --template TEMPLATE display with template
755 755
756 756 (some details hidden, use --verbose to show complete help)
757 757
758 758 $ hg -q help status
759 759 hg status [OPTION]... [FILE]...
760 760
761 761 show changed files in the working directory
762 762
763 763 $ hg help foo
764 764 abort: no such help topic: foo
765 765 (try 'hg help --keyword foo')
766 766 [10]
767 767
768 768 $ hg skjdfks
769 769 hg: unknown command 'skjdfks'
770 770 (use 'hg help' for a list of commands)
771 771 [10]
772 772
773 773 Typoed command gives suggestion
774 774 $ hg puls
775 775 hg: unknown command 'puls'
776 776 (did you mean one of pull, push?)
777 777 [10]
778 778
779 779 Not enabled extension gets suggested
780 780
781 781 $ hg rebase
782 782 hg: unknown command 'rebase'
783 783 'rebase' is provided by the following extension:
784 784
785 785 rebase command to move sets of revisions to a different ancestor
786 786
787 787 (use 'hg help extensions' for information on enabling extensions)
788 788 [10]
789 789
790 790 Disabled extension gets suggested
791 791 $ hg --config extensions.rebase=! rebase
792 792 hg: unknown command 'rebase'
793 793 'rebase' is provided by the following extension:
794 794
795 795 rebase command to move sets of revisions to a different ancestor
796 796
797 797 (use 'hg help extensions' for information on enabling extensions)
798 798 [10]
799 799
800 800 Checking that help adapts based on the config:
801 801
802 802 $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
803 803 -g --[no-]git use git extended diff format (default: on from
804 804 config)
805 805
806 806 Make sure that we don't run afoul of the help system thinking that
807 807 this is a section and erroring out weirdly.
808 808
809 809 $ hg .log
810 810 hg: unknown command '.log'
811 811 (did you mean log?)
812 812 [10]
813 813
814 814 $ hg log.
815 815 hg: unknown command 'log.'
816 816 (did you mean log?)
817 817 [10]
818 818 $ hg pu.lh
819 819 hg: unknown command 'pu.lh'
820 820 (did you mean one of pull, push?)
821 821 [10]
822 822
823 823 $ cat > helpext.py <<EOF
824 824 > import os
825 825 > from mercurial import commands, fancyopts, registrar
826 826 >
827 827 > def func(arg):
828 828 > return '%sfoo' % arg
829 829 > class customopt(fancyopts.customopt):
830 830 > def newstate(self, oldstate, newparam, abort):
831 831 > return '%sbar' % oldstate
832 832 > cmdtable = {}
833 833 > command = registrar.command(cmdtable)
834 834 >
835 835 > @command(b'nohelp',
836 836 > [(b'', b'longdesc', 3, b'x'*67),
837 837 > (b'n', b'', None, b'normal desc'),
838 838 > (b'', b'newline', b'', b'line1\nline2'),
839 839 > (b'', b'default-off', False, b'enable X'),
840 840 > (b'', b'default-on', True, b'enable Y'),
841 841 > (b'', b'callableopt', func, b'adds foo'),
842 842 > (b'', b'customopt', customopt(''), b'adds bar'),
843 843 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
844 844 > b'hg nohelp',
845 845 > norepo=True)
846 846 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
847 847 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
848 848 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
849 849 > def nohelp(ui, *args, **kwargs):
850 850 > pass
851 851 >
852 852 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
853 853 > def hashelp(ui, *args, **kwargs):
854 854 > """Extension command's help"""
855 855 >
856 856 > def uisetup(ui):
857 857 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
858 858 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
859 859 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
860 860 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
861 861 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
862 862 >
863 863 > EOF
864 864 $ echo '[extensions]' >> $HGRCPATH
865 865 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
866 866
867 867 Test for aliases
868 868
869 869 $ hg help | grep hgalias
870 870 hgalias My doc
871 871
872 872 $ hg help hgalias
873 873 hg hgalias [--remote]
874 874
875 875 alias for: hg summary
876 876
877 877 My doc
878 878
879 879 defined by: helpext
880 880
881 881 options:
882 882
883 883 --remote check for push and pull
884 884
885 885 (some details hidden, use --verbose to show complete help)
886 886 $ hg help hgaliasnodoc
887 887 hg hgaliasnodoc [--remote]
888 888
889 889 alias for: hg summary
890 890
891 891 summarize working directory state
892 892
893 893 This generates a brief summary of the working directory state, including
894 894 parents, branch, commit status, phase and available updates.
895 895
896 896 With the --remote option, this will check the default paths for incoming
897 897 and outgoing changes. This can be time-consuming.
898 898
899 899 Returns 0 on success.
900 900
901 901 defined by: helpext
902 902
903 903 options:
904 904
905 905 --remote check for push and pull
906 906
907 907 (some details hidden, use --verbose to show complete help)
908 908
909 909 $ hg help shellalias
910 910 hg shellalias
911 911
912 912 shell alias for: echo hi
913 913
914 914 (no help text available)
915 915
916 916 defined by: helpext
917 917
918 918 (some details hidden, use --verbose to show complete help)
919 919
920 920 Test command with no help text
921 921
922 922 $ hg help nohelp
923 923 hg nohelp
924 924
925 925 (no help text available)
926 926
927 927 options:
928 928
929 929 --longdesc VALUE
930 930 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
931 931 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
932 932 -n -- normal desc
933 933 --newline VALUE line1 line2
934 934 --default-off enable X
935 935 --[no-]default-on enable Y (default: on)
936 936 --callableopt VALUE adds foo
937 937 --customopt VALUE adds bar
938 938 --customopt-withdefault VALUE adds bar (default: foo)
939 939
940 940 (some details hidden, use --verbose to show complete help)
941 941
942 942 Test that default list of commands includes extension commands that have help,
943 943 but not those that don't, except in verbose mode, when a keyword is passed, or
944 944 when help about the extension is requested.
945 945
946 946 #if no-extraextensions
947 947
948 948 $ hg help | grep hashelp
949 949 hashelp Extension command's help
950 950 $ hg help | grep nohelp
951 951 [1]
952 952 $ hg help -v | grep nohelp
953 953 nohelp (no help text available)
954 954
955 955 $ hg help -k nohelp
956 956 Commands:
957 957
958 958 nohelp hg nohelp
959 959
960 960 Extension Commands:
961 961
962 962 nohelp (no help text available)
963 963
964 964 $ hg help helpext
965 965 helpext extension - no help text available
966 966
967 967 list of commands:
968 968
969 969 hashelp Extension command's help
970 970 nohelp (no help text available)
971 971
972 972 (use 'hg help -v helpext' to show built-in aliases and global options)
973 973
974 974 #endif
975 975
976 976 Test list of internal help commands
977 977
978 978 $ hg help debug
979 979 debug commands (internal and unsupported):
980 980
981 981 debug-delta-find
982 982 display the computation to get to a valid delta for storing REV
983 983 debug-repair-issue6528
984 984 find affected revisions and repair them. See issue6528 for more
985 985 details.
986 986 debug-revlog-index
987 987 dump index data for a revlog
988 988 debug-revlog-stats
989 989 display statistics about revlogs in the store
990 990 debug::stable-tail-sort
991 991 display the stable-tail sort of the ancestors of a given node
992 992 debugancestor
993 993 find the ancestor revision of two revisions in a given index
994 994 debugantivirusrunning
995 995 attempt to trigger an antivirus scanner to see if one is active
996 996 debugapplystreamclonebundle
997 997 apply a stream clone bundle file
998 998 debugbackupbundle
999 999 lists the changesets available in backup bundles
1000 1000 debugbuilddag
1001 1001 builds a repo with a given DAG from scratch in the current
1002 1002 empty repo
1003 1003 debugbundle lists the contents of a bundle
1004 1004 debugcapabilities
1005 1005 lists the capabilities of a remote peer
1006 1006 debugchangedfiles
1007 1007 list the stored files changes for a revision
1008 1008 debugcheckstate
1009 1009 validate the correctness of the current dirstate
1010 1010 debugcolor show available color, effects or style
1011 1011 debugcommands
1012 1012 list all available commands and options
1013 1013 debugcomplete
1014 1014 returns the completion list associated with the given command
1015 1015 debugcreatestreamclonebundle
1016 1016 create a stream clone bundle file
1017 1017 debugdag format the changelog or an index DAG as a concise textual
1018 1018 description
1019 1019 debugdata dump the contents of a data file revision
1020 1020 debugdate parse and display a date
1021 1021 debugdeltachain
1022 1022 dump information about delta chains in a revlog
1023 1023 debugdirstate
1024 1024 show the contents of the current dirstate
1025 1025 debugdirstateignorepatternshash
1026 1026 show the hash of ignore patterns stored in dirstate if v2,
1027 1027 debugdiscovery
1028 1028 runs the changeset discovery protocol in isolation
1029 1029 debugdownload
1030 1030 download a resource using Mercurial logic and config
1031 1031 debugextensions
1032 1032 show information about active extensions
1033 1033 debugfileset parse and apply a fileset specification
1034 1034 debugformat display format information about the current repository
1035 1035 debugfsinfo show information detected about current filesystem
1036 1036 debuggetbundle
1037 1037 retrieves a bundle from a repo
1038 1038 debugignore display the combined ignore pattern and information about
1039 1039 ignored files
1040 1040 debugindexdot
1041 1041 dump an index DAG as a graphviz dot file
1042 1042 debugindexstats
1043 1043 show stats related to the changelog index
1044 1044 debuginstall test Mercurial installation
1045 1045 debugknown test whether node ids are known to a repo
1046 1046 debuglocks show or modify state of locks
1047 1047 debugmanifestfulltextcache
1048 1048 show, clear or amend the contents of the manifest fulltext
1049 1049 cache
1050 1050 debugmergestate
1051 1051 print merge state
1052 1052 debugnamecomplete
1053 1053 complete "names" - tags, open branch names, bookmark names
1054 1054 debugnodemap write and inspect on disk nodemap
1055 1055 debugobsolete
1056 1056 create arbitrary obsolete marker
1057 1057 debugoptADV (no help text available)
1058 1058 debugoptDEP (no help text available)
1059 1059 debugoptEXP (no help text available)
1060 1060 debugp1copies
1061 1061 dump copy information compared to p1
1062 1062 debugp2copies
1063 1063 dump copy information compared to p2
1064 1064 debugpathcomplete
1065 1065 complete part or all of a tracked path
1066 1066 debugpathcopies
1067 1067 show copies between two revisions
1068 1068 debugpeer establish a connection to a peer repository
1069 1069 debugpickmergetool
1070 1070 examine which merge tool is chosen for specified file
1071 1071 debugpushkey access the pushkey key/value protocol
1072 1072 debugpvec (no help text available)
1073 1073 debugrebuilddirstate
1074 1074 rebuild the dirstate as it would look like for the given
1075 1075 revision
1076 1076 debugrebuildfncache
1077 1077 rebuild the fncache file
1078 1078 debugrename dump rename information
1079 1079 debugrequires
1080 1080 print the current repo requirements
1081 1081 debugrevlog show data and statistics about a revlog
1082 1082 debugrevlogindex
1083 1083 dump the contents of a revlog index
1084 1084 debugrevspec parse and apply a revision specification
1085 1085 debugserve run a server with advanced settings
1086 1086 debugsetparents
1087 1087 manually set the parents of the current working directory
1088 1088 (DANGEROUS)
1089 1089 debugshell run an interactive Python interpreter
1090 1090 debugsidedata
1091 1091 dump the side data for a cl/manifest/file revision
1092 1092 debugssl test a secure connection to a server
1093 1093 debugstrip strip changesets and all their descendants from the repository
1094 1094 debugsub (no help text available)
1095 1095 debugsuccessorssets
1096 1096 show set of successors for revision
1097 1097 debugtagscache
1098 1098 display the contents of .hg/cache/hgtagsfnodes1
1099 1099 debugtemplate
1100 1100 parse and apply a template
1101 1101 debuguigetpass
1102 1102 show prompt to type password
1103 1103 debuguiprompt
1104 1104 show plain prompt
1105 1105 debugupdatecaches
1106 1106 warm all known caches in the repository
1107 1107 debugupgraderepo
1108 1108 upgrade a repository to use different features
1109 1109 debugwalk show how files match on given patterns
1110 1110 debugwhyunstable
1111 1111 explain instabilities of a changeset
1112 1112 debugwireargs
1113 1113 (no help text available)
1114 1114 debugwireproto
1115 1115 send wire protocol commands to a server
1116 1116
1117 1117 (use 'hg help -v debug' to show built-in aliases and global options)
1118 1118
1119 1119 internals topic renders index of available sub-topics
1120 1120
1121 1121 $ hg help internals
1122 1122 Technical implementation topics
1123 1123 """""""""""""""""""""""""""""""
1124 1124
1125 1125 To access a subtopic, use "hg help internals.{subtopic-name}"
1126 1126
1127 1127 bid-merge Bid Merge Algorithm
1128 1128 bundle2 Bundle2
1129 1129 bundles Bundles
1130 1130 cbor CBOR
1131 1131 censor Censor
1132 1132 changegroups Changegroups
1133 1133 config Config Registrar
1134 1134 dirstate-v2 dirstate-v2 file format
1135 1135 extensions Extension API
1136 1136 mergestate Mergestate
1137 1137 requirements Repository Requirements
1138 1138 revlogs Revision Logs
1139 1139 wireprotocol Wire Protocol
1140 1140 wireprotocolrpc
1141 1141 Wire Protocol RPC
1142 1142 wireprotocolv2
1143 1143 Wire Protocol Version 2
1144 1144
1145 1145 sub-topics can be accessed
1146 1146
1147 1147 $ hg help internals.changegroups
1148 1148 Changegroups
1149 1149 """"""""""""
1150 1150
1151 1151 Changegroups are representations of repository revlog data, specifically
1152 1152 the changelog data, root/flat manifest data, treemanifest data, and
1153 1153 filelogs.
1154 1154
1155 1155 There are 4 versions of changegroups: "1", "2", "3" and "4". From a high-
1156 1156 level, versions "1" and "2" are almost exactly the same, with the only
1157 1157 difference being an additional item in the *delta header*. Version "3"
1158 1158 adds support for storage flags in the *delta header* and optionally
1159 1159 exchanging treemanifests (enabled by setting an option on the
1160 1160 "changegroup" part in the bundle2). Version "4" adds support for
1161 1161 exchanging sidedata (additional revision metadata not part of the digest).
1162 1162
1163 1163 Changegroups when not exchanging treemanifests consist of 3 logical
1164 1164 segments:
1165 1165
1166 1166 +---------------------------------+
1167 1167 | | | |
1168 1168 | changeset | manifest | filelogs |
1169 1169 | | | |
1170 1170 | | | |
1171 1171 +---------------------------------+
1172 1172
1173 1173 When exchanging treemanifests, there are 4 logical segments:
1174 1174
1175 1175 +-------------------------------------------------+
1176 1176 | | | | |
1177 1177 | changeset | root | treemanifests | filelogs |
1178 1178 | | manifest | | |
1179 1179 | | | | |
1180 1180 +-------------------------------------------------+
1181 1181
1182 1182 The principle building block of each segment is a *chunk*. A *chunk* is a
1183 1183 framed piece of data:
1184 1184
1185 1185 +---------------------------------------+
1186 1186 | | |
1187 1187 | length | data |
1188 1188 | (4 bytes) | (<length - 4> bytes) |
1189 1189 | | |
1190 1190 +---------------------------------------+
1191 1191
1192 1192 All integers are big-endian signed integers. Each chunk starts with a
1193 1193 32-bit integer indicating the length of the entire chunk (including the
1194 1194 length field itself).
1195 1195
1196 1196 There is a special case chunk that has a value of 0 for the length
1197 1197 ("0x00000000"). We call this an *empty chunk*.
1198 1198
1199 1199 Delta Groups
1200 1200 ============
1201 1201
1202 1202 A *delta group* expresses the content of a revlog as a series of deltas,
1203 1203 or patches against previous revisions.
1204 1204
1205 1205 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1206 1206 to signal the end of the delta group:
1207 1207
1208 1208 +------------------------------------------------------------------------+
1209 1209 | | | | | |
1210 1210 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1211 1211 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1212 1212 | | | | | |
1213 1213 +------------------------------------------------------------------------+
1214 1214
1215 1215 Each *chunk*'s data consists of the following:
1216 1216
1217 1217 +---------------------------------------+
1218 1218 | | |
1219 1219 | delta header | delta data |
1220 1220 | (various by version) | (various) |
1221 1221 | | |
1222 1222 +---------------------------------------+
1223 1223
1224 1224 The *delta data* is a series of *delta*s that describe a diff from an
1225 1225 existing entry (either that the recipient already has, or previously
1226 1226 specified in the bundle/changegroup).
1227 1227
1228 1228 The *delta header* is different between versions "1", "2", "3" and "4" of
1229 1229 the changegroup format.
1230 1230
1231 1231 Version 1 (headerlen=80):
1232 1232
1233 1233 +------------------------------------------------------+
1234 1234 | | | | |
1235 1235 | node | p1 node | p2 node | link node |
1236 1236 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1237 1237 | | | | |
1238 1238 +------------------------------------------------------+
1239 1239
1240 1240 Version 2 (headerlen=100):
1241 1241
1242 1242 +------------------------------------------------------------------+
1243 1243 | | | | | |
1244 1244 | node | p1 node | p2 node | base node | link node |
1245 1245 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1246 1246 | | | | | |
1247 1247 +------------------------------------------------------------------+
1248 1248
1249 1249 Version 3 (headerlen=102):
1250 1250
1251 1251 +------------------------------------------------------------------------------+
1252 1252 | | | | | | |
1253 1253 | node | p1 node | p2 node | base node | link node | flags |
1254 1254 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1255 1255 | | | | | | |
1256 1256 +------------------------------------------------------------------------------+
1257 1257
1258 1258 Version 4 (headerlen=103):
1259 1259
1260 1260 +------------------------------------------------------------------------------+----------+
1261 1261 | | | | | | | |
1262 1262 | node | p1 node | p2 node | base node | link node | flags | pflags |
1263 1263 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
1264 1264 | | | | | | | |
1265 1265 +------------------------------------------------------------------------------+----------+
1266 1266
1267 1267 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1268 1268 contain a series of *delta*s, densely packed (no separators). These deltas
1269 1269 describe a diff from an existing entry (either that the recipient already
1270 1270 has, or previously specified in the bundle/changegroup). The format is
1271 1271 described more fully in "hg help internals.bdiff", but briefly:
1272 1272
1273 1273 +---------------------------------------------------------------+
1274 1274 | | | | |
1275 1275 | start offset | end offset | new length | content |
1276 1276 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1277 1277 | | | | |
1278 1278 +---------------------------------------------------------------+
1279 1279
1280 1280 Please note that the length field in the delta data does *not* include
1281 1281 itself.
1282 1282
1283 1283 In version 1, the delta is always applied against the previous node from
1284 1284 the changegroup or the first parent if this is the first entry in the
1285 1285 changegroup.
1286 1286
1287 1287 In version 2 and up, the delta base node is encoded in the entry in the
1288 1288 changegroup. This allows the delta to be expressed against any parent,
1289 1289 which can result in smaller deltas and more efficient encoding of data.
1290 1290
1291 1291 The *flags* field holds bitwise flags affecting the processing of revision
1292 1292 data. The following flags are defined:
1293 1293
1294 1294 32768
1295 1295 Censored revision. The revision's fulltext has been replaced by censor
1296 1296 metadata. May only occur on file revisions.
1297 1297
1298 1298 16384
1299 1299 Ellipsis revision. Revision hash does not match data (likely due to
1300 1300 rewritten parents).
1301 1301
1302 1302 8192
1303 1303 Externally stored. The revision fulltext contains "key:value" "\n"
1304 1304 delimited metadata defining an object stored elsewhere. Used by the LFS
1305 1305 extension.
1306 1306
1307 1307 4096
1308 1308 Contains copy information. This revision changes files in a way that
1309 1309 could affect copy tracing. This does *not* affect changegroup handling,
1310 1310 but is relevant for other parts of Mercurial.
1311 1311
1312 1312 For historical reasons, the integer values are identical to revlog version
1313 1313 1 per-revision storage flags and correspond to bits being set in this
1314 1314 2-byte field. Bits were allocated starting from the most-significant bit,
1315 1315 hence the reverse ordering and allocation of these flags.
1316 1316
1317 1317 The *pflags* (protocol flags) field holds bitwise flags affecting the
1318 1318 protocol itself. They are first in the header since they may affect the
1319 1319 handling of the rest of the fields in a future version. They are defined
1320 1320 as such:
1321 1321
1322 1322 1 indicates whether to read a chunk of sidedata (of variable length) right
1323 1323 after the revision flags.
1324 1324
1325 1325 Changeset Segment
1326 1326 =================
1327 1327
1328 1328 The *changeset segment* consists of a single *delta group* holding
1329 1329 changelog data. The *empty chunk* at the end of the *delta group* denotes
1330 1330 the boundary to the *manifest segment*.
1331 1331
1332 1332 Manifest Segment
1333 1333 ================
1334 1334
1335 1335 The *manifest segment* consists of a single *delta group* holding manifest
1336 1336 data. If treemanifests are in use, it contains only the manifest for the
1337 1337 root directory of the repository. Otherwise, it contains the entire
1338 1338 manifest data. The *empty chunk* at the end of the *delta group* denotes
1339 1339 the boundary to the next segment (either the *treemanifests segment* or
1340 1340 the *filelogs segment*, depending on version and the request options).
1341 1341
1342 1342 Treemanifests Segment
1343 1343 ---------------------
1344 1344
1345 1345 The *treemanifests segment* only exists in changegroup version "3" and
1346 1346 "4", and only if the 'treemanifest' param is part of the bundle2
1347 1347 changegroup part (it is not possible to use changegroup version 3 or 4
1348 1348 outside of bundle2). Aside from the filenames in the *treemanifests
1349 1349 segment* containing a trailing "/" character, it behaves identically to
1350 1350 the *filelogs segment* (see below). The final sub-segment is followed by
1351 1351 an *empty chunk* (logically, a sub-segment with filename size 0). This
1352 1352 denotes the boundary to the *filelogs segment*.
1353 1353
1354 1354 Filelogs Segment
1355 1355 ================
1356 1356
1357 1357 The *filelogs segment* consists of multiple sub-segments, each
1358 1358 corresponding to an individual file whose data is being described:
1359 1359
1360 1360 +--------------------------------------------------+
1361 1361 | | | | | |
1362 1362 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1363 1363 | | | | | (4 bytes) |
1364 1364 | | | | | |
1365 1365 +--------------------------------------------------+
1366 1366
1367 1367 The final filelog sub-segment is followed by an *empty chunk* (logically,
1368 1368 a sub-segment with filename size 0). This denotes the end of the segment
1369 1369 and of the overall changegroup.
1370 1370
1371 1371 Each filelog sub-segment consists of the following:
1372 1372
1373 1373 +------------------------------------------------------+
1374 1374 | | | |
1375 1375 | filename length | filename | delta group |
1376 1376 | (4 bytes) | (<length - 4> bytes) | (various) |
1377 1377 | | | |
1378 1378 +------------------------------------------------------+
1379 1379
1380 1380 That is, a *chunk* consisting of the filename (not terminated or padded)
1381 1381 followed by N chunks constituting the *delta group* for this file. The
1382 1382 *empty chunk* at the end of each *delta group* denotes the boundary to the
1383 1383 next filelog sub-segment.
1384 1384
1385 1385 non-existent subtopics print an error
1386 1386
1387 1387 $ hg help internals.foo
1388 1388 abort: no such help topic: internals.foo
1389 1389 (try 'hg help --keyword foo')
1390 1390 [10]
1391 1391
1392 1392 test advanced, deprecated and experimental options are hidden in command help
1393 1393 $ hg help debugoptADV
1394 1394 hg debugoptADV
1395 1395
1396 1396 (no help text available)
1397 1397
1398 1398 options:
1399 1399
1400 1400 (some details hidden, use --verbose to show complete help)
1401 1401 $ hg help debugoptDEP
1402 1402 hg debugoptDEP
1403 1403
1404 1404 (no help text available)
1405 1405
1406 1406 options:
1407 1407
1408 1408 (some details hidden, use --verbose to show complete help)
1409 1409
1410 1410 $ hg help debugoptEXP
1411 1411 hg debugoptEXP
1412 1412
1413 1413 (no help text available)
1414 1414
1415 1415 options:
1416 1416
1417 1417 (some details hidden, use --verbose to show complete help)
1418 1418
1419 1419 test advanced, deprecated and experimental options are shown with -v
1420 1420 $ hg help -v debugoptADV | grep aopt
1421 1421 --aopt option is (ADVANCED)
1422 1422 $ hg help -v debugoptDEP | grep dopt
1423 1423 --dopt option is (DEPRECATED)
1424 1424 $ hg help -v debugoptEXP | grep eopt
1425 1425 --eopt option is (EXPERIMENTAL)
1426 1426
1427 1427 #if gettext
1428 1428 test deprecated option is hidden with translation with untranslated description
1429 1429 (use many globy for not failing on changed transaction)
1430 1430 $ LANGUAGE=sv hg help debugoptDEP
1431 1431 hg debugoptDEP
1432 1432
1433 1433 (*) (glob)
1434 1434
1435 1435 options:
1436 1436
1437 1437 (some details hidden, use --verbose to show complete help)
1438 1438 #endif
1439 1439
1440 1440 Test commands that collide with topics (issue4240)
1441 1441
1442 1442 $ hg config -hq
1443 1443 hg config [-u] [NAME]...
1444 1444
1445 1445 show combined config settings from all hgrc files
1446 1446 $ hg showconfig -hq
1447 1447 hg config [-u] [NAME]...
1448 1448
1449 1449 show combined config settings from all hgrc files
1450 1450
1451 1451 Test a help topic
1452 1452
1453 1453 $ hg help dates
1454 1454 Date Formats
1455 1455 """"""""""""
1456 1456
1457 1457 Some commands allow the user to specify a date, e.g.:
1458 1458
1459 1459 - backout, commit, import, tag: Specify the commit date.
1460 1460 - log, revert, update: Select revision(s) by date.
1461 1461
1462 1462 Many date formats are valid. Here are some examples:
1463 1463
1464 1464 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1465 1465 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1466 1466 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1467 1467 - "Dec 6" (midnight)
1468 1468 - "13:18" (today assumed)
1469 1469 - "3:39" (3:39AM assumed)
1470 1470 - "3:39pm" (15:39)
1471 1471 - "2006-12-06 13:18:29" (ISO 8601 format)
1472 1472 - "2006-12-6 13:18"
1473 1473 - "2006-12-6"
1474 1474 - "12-6"
1475 1475 - "12/6"
1476 1476 - "12/6/6" (Dec 6 2006)
1477 1477 - "today" (midnight)
1478 1478 - "yesterday" (midnight)
1479 1479 - "now" - right now
1480 1480
1481 1481 Lastly, there is Mercurial's internal format:
1482 1482
1483 1483 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1484 1484
1485 1485 This is the internal representation format for dates. The first number is
1486 1486 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1487 1487 is the offset of the local timezone, in seconds west of UTC (negative if
1488 1488 the timezone is east of UTC).
1489 1489
1490 1490 The log command also accepts date ranges:
1491 1491
1492 1492 - "<DATE" - at or before a given date/time
1493 1493 - ">DATE" - on or after a given date/time
1494 1494 - "DATE to DATE" - a date range, inclusive
1495 1495 - "-DAYS" - within a given number of days from today
1496 1496
1497 1497 Test repeated config section name
1498 1498
1499 1499 $ hg help config.host
1500 1500 "http_proxy.host"
1501 1501 Host name and (optional) port of the proxy server, for example
1502 1502 "myproxy:8000".
1503 1503
1504 1504 "smtp.host"
1505 1505 Host name of mail server, e.g. "mail.example.com".
1506 1506
1507 1507
1508 1508 Test section name with dot
1509 1509
1510 1510 $ hg help config.ui.username
1511 1511 "ui.username"
1512 1512 The committer of a changeset created when running "commit". Typically
1513 1513 a person's name and email address, e.g. "Fred Widget
1514 1514 <fred@example.com>". Environment variables in the username are
1515 1515 expanded.
1516 1516
1517 1517 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1518 1518 empty, e.g. if the system admin set "username =" in the system hgrc,
1519 1519 it has to be specified manually or in a different hgrc file)
1520 1520
1521 1521
1522 1522 $ hg help config.annotate.git
1523 1523 abort: help section not found: config.annotate.git
1524 1524 [10]
1525 1525
1526 1526 $ hg help config.update.check
1527 1527 "commands.update.check"
1528 1528 Determines what level of checking 'hg update' will perform before
1529 1529 moving to a destination revision. Valid values are "abort", "none",
1530 1530 "linear", and "noconflict".
1531 1531
1532 1532 - "abort" always fails if the working directory has uncommitted
1533 1533 changes.
1534 1534 - "none" performs no checking, and may result in a merge with
1535 1535 uncommitted changes.
1536 1536 - "linear" allows any update as long as it follows a straight line in
1537 1537 the revision history, and may trigger a merge with uncommitted
1538 1538 changes.
1539 1539 - "noconflict" will allow any update which would not trigger a merge
1540 1540 with uncommitted changes, if any are present.
1541 1541
1542 1542 (default: "linear")
1543 1543
1544 1544
1545 1545 $ hg help config.commands.update.check
1546 1546 "commands.update.check"
1547 1547 Determines what level of checking 'hg update' will perform before
1548 1548 moving to a destination revision. Valid values are "abort", "none",
1549 1549 "linear", and "noconflict".
1550 1550
1551 1551 - "abort" always fails if the working directory has uncommitted
1552 1552 changes.
1553 1553 - "none" performs no checking, and may result in a merge with
1554 1554 uncommitted changes.
1555 1555 - "linear" allows any update as long as it follows a straight line in
1556 1556 the revision history, and may trigger a merge with uncommitted
1557 1557 changes.
1558 1558 - "noconflict" will allow any update which would not trigger a merge
1559 1559 with uncommitted changes, if any are present.
1560 1560
1561 1561 (default: "linear")
1562 1562
1563 1563
1564 1564 $ hg help config.ommands.update.check
1565 1565 abort: help section not found: config.ommands.update.check
1566 1566 [10]
1567 1567
1568 1568 Unrelated trailing paragraphs shouldn't be included
1569 1569
1570 1570 $ hg help config.extramsg | grep '^$'
1571 1571
1572 1572
1573 1573 Test capitalized section name
1574 1574
1575 1575 $ hg help scripting.HGPLAIN > /dev/null
1576 1576
1577 1577 Help subsection:
1578 1578
1579 1579 $ hg help config.charsets |grep "Email example:" > /dev/null
1580 1580 [1]
1581 1581
1582 1582 Show nested definitions
1583 1583 ("profiling.type"[break]"ls"[break]"stat"[break])
1584 1584
1585 1585 $ hg help config.type | egrep '^$'|wc -l
1586 1586 \s*3 (re)
1587 1587
1588 1588 $ hg help config.profiling.type.ls
1589 1589 "profiling.type.ls"
1590 1590 Use Python's built-in instrumenting profiler. This profiler works on
1591 1591 all platforms, but each line number it reports is the first line of
1592 1592 a function. This restriction makes it difficult to identify the
1593 1593 expensive parts of a non-trivial function.
1594 1594
1595 1595
1596 1596 Separate sections from subsections
1597 1597
1598 1598 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1599 1599 "format"
1600 1600 --------
1601 1601
1602 1602 "usegeneraldelta"
1603 1603
1604 1604 "dotencode"
1605 1605
1606 1606 "usefncache"
1607 1607
1608 1608 "use-dirstate-v2"
1609 1609
1610 1610 "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories"
1611 1611
1612 1612 "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet"
1613 1613
1614 1614 "use-dirstate-tracked-hint"
1615 1615
1616 1616 "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories"
1617 1617
1618 1618 "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet"
1619 1619
1620 1620 "use-persistent-nodemap"
1621 1621
1622 1622 "use-share-safe"
1623 1623
1624 1624 "use-share-safe.automatic-upgrade-of-mismatching-repositories"
1625 1625
1626 1626 "use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet"
1627 1627
1628 1628 "usestore"
1629 1629
1630 1630 "sparse-revlog"
1631 1631
1632 1632 "revlog-compression"
1633 1633
1634 1634 "bookmarks-in-store"
1635 1635
1636 1636 "profiling"
1637 1637 -----------
1638 1638
1639 1639 "format"
1640 1640
1641 1641 "progress"
1642 1642 ----------
1643 1643
1644 1644 "format"
1645 1645
1646 1646
1647 1647 Last item in help config.*:
1648 1648
1649 1649 $ hg help config.`hg help config|grep '^ "'| \
1650 1650 > tail -1|sed 's![ "]*!!g'`| \
1651 1651 > grep 'hg help -c config' > /dev/null
1652 1652 [1]
1653 1653
1654 1654 note to use help -c for general hg help config:
1655 1655
1656 1656 $ hg help config |grep 'hg help -c config' > /dev/null
1657 1657
1658 1658 Test templating help
1659 1659
1660 1660 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1661 1661 desc String. The text of the changeset description.
1662 1662 diffstat String. Statistics of changes with the following format:
1663 1663 firstline Any text. Returns the first line of text.
1664 1664 nonempty Any text. Returns '(none)' if the string is empty.
1665 1665
1666 1666 Test deprecated items
1667 1667
1668 1668 $ hg help -v templating | grep currentbookmark
1669 1669 currentbookmark
1670 1670 $ hg help templating | (grep currentbookmark || true)
1671 1671
1672 1672 Test help hooks
1673 1673
1674 1674 $ cat > helphook1.py <<EOF
1675 1675 > from mercurial import help
1676 1676 >
1677 1677 > def rewrite(ui, topic, doc):
1678 1678 > return doc + b'\nhelphook1\n'
1679 1679 >
1680 1680 > def extsetup(ui):
1681 1681 > help.addtopichook(b'revisions', rewrite)
1682 1682 > EOF
1683 1683 $ cat > helphook2.py <<EOF
1684 1684 > from mercurial import help
1685 1685 >
1686 1686 > def rewrite(ui, topic, doc):
1687 1687 > return doc + b'\nhelphook2\n'
1688 1688 >
1689 1689 > def extsetup(ui):
1690 1690 > help.addtopichook(b'revisions', rewrite)
1691 1691 > EOF
1692 1692 $ echo '[extensions]' >> $HGRCPATH
1693 1693 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1694 1694 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1695 1695 $ hg help revsets | grep helphook
1696 1696 helphook1
1697 1697 helphook2
1698 1698
1699 1699 help -c should only show debug --debug
1700 1700
1701 1701 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1702 1702 [1]
1703 1703
1704 1704 help -c should only show deprecated for -v
1705 1705
1706 1706 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1707 1707 [1]
1708 1708
1709 1709 Test -s / --system
1710 1710
1711 1711 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1712 1712 > wc -l | sed -e 's/ //g'
1713 1713 0
1714 1714 $ hg help config.files --system unix | grep 'USER' | \
1715 1715 > wc -l | sed -e 's/ //g'
1716 1716 0
1717 1717
1718 1718 Test -e / -c / -k combinations
1719 1719
1720 1720 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1721 1721 Commands:
1722 1722 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1723 1723 Extensions:
1724 1724 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1725 1725 Topics:
1726 1726 Commands:
1727 1727 Extensions:
1728 1728 Extension Commands:
1729 1729 $ hg help -c schemes
1730 1730 abort: no such help topic: schemes
1731 1731 (try 'hg help --keyword schemes')
1732 1732 [10]
1733 1733 $ hg help -e schemes |head -1
1734 1734 schemes extension - extend schemes with shortcuts to repository swarms
1735 1735 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1736 1736 Commands:
1737 1737 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1738 1738 Extensions:
1739 1739 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1740 1740 Extensions:
1741 1741 Commands:
1742 1742 $ hg help -c commit > /dev/null
1743 1743 $ hg help -e -c commit > /dev/null
1744 1744 $ hg help -e commit
1745 1745 abort: no such help topic: commit
1746 1746 (try 'hg help --keyword commit')
1747 1747 [10]
1748 1748
1749 1749 Test keyword search help
1750 1750
1751 1751 $ cat > prefixedname.py <<EOF
1752 1752 > '''matched against word "clone"
1753 1753 > '''
1754 1754 > EOF
1755 1755 $ echo '[extensions]' >> $HGRCPATH
1756 1756 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1757 1757 $ hg help -k clone
1758 1758 Topics:
1759 1759
1760 1760 config Configuration Files
1761 1761 extensions Using Additional Features
1762 1762 glossary Glossary
1763 1763 phases Working with Phases
1764 1764 subrepos Subrepositories
1765 1765 urls URL Paths
1766 1766
1767 1767 Commands:
1768 1768
1769 1769 bookmarks create a new bookmark or list existing bookmarks
1770 1770 clone make a copy of an existing repository
1771 1771 paths show aliases for remote repositories
1772 1772 pull pull changes from the specified source
1773 1773 update update working directory (or switch revisions)
1774 1774
1775 1775 Extensions:
1776 1776
1777 1777 clonebundles advertise pre-generated bundles to seed clones
1778 1778 narrow create clones which fetch history data for subset of files
1779 1779 (EXPERIMENTAL)
1780 1780 prefixedname matched against word "clone"
1781 1781 relink recreates hardlinks between repository clones
1782 1782
1783 1783 Extension Commands:
1784 1784
1785 admin::clone-bundles-clear remove existing clone bundle caches
1785 1786 admin::clone-bundles-refresh generate clone bundles according to the
1786 1787 configuration
1787 1788 qclone clone main and patch repository at same time
1788 1789
1789 1790 Test unfound topic
1790 1791
1791 1792 $ hg help nonexistingtopicthatwillneverexisteverever
1792 1793 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1793 1794 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1794 1795 [10]
1795 1796
1796 1797 Test unfound keyword
1797 1798
1798 1799 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1799 1800 abort: no matches
1800 1801 (try 'hg help' for a list of topics)
1801 1802 [10]
1802 1803
1803 1804 Test omit indicating for help
1804 1805
1805 1806 $ cat > addverboseitems.py <<EOF
1806 1807 > r'''extension to test omit indicating.
1807 1808 >
1808 1809 > This paragraph is never omitted (for extension)
1809 1810 >
1810 1811 > .. container:: verbose
1811 1812 >
1812 1813 > This paragraph is omitted,
1813 1814 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1814 1815 >
1815 1816 > This paragraph is never omitted, too (for extension)
1816 1817 > '''
1817 1818 > from mercurial import commands, help
1818 1819 > testtopic = br"""This paragraph is never omitted (for topic).
1819 1820 >
1820 1821 > .. container:: verbose
1821 1822 >
1822 1823 > This paragraph is omitted,
1823 1824 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1824 1825 >
1825 1826 > This paragraph is never omitted, too (for topic)
1826 1827 > """
1827 1828 > def extsetup(ui):
1828 1829 > help.helptable.append(([b"topic-containing-verbose"],
1829 1830 > b"This is the topic to test omit indicating.",
1830 1831 > lambda ui: testtopic))
1831 1832 > EOF
1832 1833 $ echo '[extensions]' >> $HGRCPATH
1833 1834 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1834 1835 $ hg help addverboseitems
1835 1836 addverboseitems extension - extension to test omit indicating.
1836 1837
1837 1838 This paragraph is never omitted (for extension)
1838 1839
1839 1840 This paragraph is never omitted, too (for extension)
1840 1841
1841 1842 (some details hidden, use --verbose to show complete help)
1842 1843
1843 1844 no commands defined
1844 1845 $ hg help -v addverboseitems
1845 1846 addverboseitems extension - extension to test omit indicating.
1846 1847
1847 1848 This paragraph is never omitted (for extension)
1848 1849
1849 1850 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1850 1851 extension)
1851 1852
1852 1853 This paragraph is never omitted, too (for extension)
1853 1854
1854 1855 no commands defined
1855 1856 $ hg help topic-containing-verbose
1856 1857 This is the topic to test omit indicating.
1857 1858 """"""""""""""""""""""""""""""""""""""""""
1858 1859
1859 1860 This paragraph is never omitted (for topic).
1860 1861
1861 1862 This paragraph is never omitted, too (for topic)
1862 1863
1863 1864 (some details hidden, use --verbose to show complete help)
1864 1865 $ hg help -v topic-containing-verbose
1865 1866 This is the topic to test omit indicating.
1866 1867 """"""""""""""""""""""""""""""""""""""""""
1867 1868
1868 1869 This paragraph is never omitted (for topic).
1869 1870
1870 1871 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1871 1872 topic)
1872 1873
1873 1874 This paragraph is never omitted, too (for topic)
1874 1875
1875 1876 Test section lookup
1876 1877
1877 1878 $ hg help revset.merge
1878 1879 "merge()"
1879 1880 Changeset is a merge changeset.
1880 1881
1881 1882 $ hg help glossary.dag
1882 1883 DAG
1883 1884 The repository of changesets of a distributed version control system
1884 1885 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1885 1886 of nodes and edges, where nodes correspond to changesets and edges
1886 1887 imply a parent -> child relation. This graph can be visualized by
1887 1888 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1888 1889 limited by the requirement for children to have at most two parents.
1889 1890
1890 1891
1891 1892 $ hg help hgrc.paths
1892 1893 "paths"
1893 1894 -------
1894 1895
1895 1896 Assigns symbolic names and behavior to repositories.
1896 1897
1897 1898 Options are symbolic names defining the URL or directory that is the
1898 1899 location of the repository. Example:
1899 1900
1900 1901 [paths]
1901 1902 my_server = https://example.com/my_repo
1902 1903 local_path = /home/me/repo
1903 1904
1904 1905 These symbolic names can be used from the command line. To pull from
1905 1906 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1906 1907 local_path'. You can check 'hg help urls' for details about valid URLs.
1907 1908
1908 1909 Options containing colons (":") denote sub-options that can influence
1909 1910 behavior for that specific path. Example:
1910 1911
1911 1912 [paths]
1912 1913 my_server = https://example.com/my_path
1913 1914 my_server:pushurl = ssh://example.com/my_path
1914 1915
1915 1916 Paths using the 'path://otherpath' scheme will inherit the sub-options
1916 1917 value from the path they point to.
1917 1918
1918 1919 The following sub-options can be defined:
1919 1920
1920 1921 "multi-urls"
1921 1922 A boolean option. When enabled the value of the '[paths]' entry will be
1922 1923 parsed as a list and the alias will resolve to multiple destination. If
1923 1924 some of the list entry use the 'path://' syntax, the suboption will be
1924 1925 inherited individually.
1925 1926
1926 1927 "pushurl"
1927 1928 The URL to use for push operations. If not defined, the location
1928 1929 defined by the path's main entry is used.
1929 1930
1930 1931 "pushrev"
1931 1932 A revset defining which revisions to push by default.
1932 1933
1933 1934 When 'hg push' is executed without a "-r" argument, the revset defined
1934 1935 by this sub-option is evaluated to determine what to push.
1935 1936
1936 1937 For example, a value of "." will push the working directory's revision
1937 1938 by default.
1938 1939
1939 1940 Revsets specifying bookmarks will not result in the bookmark being
1940 1941 pushed.
1941 1942
1942 1943 "bookmarks.mode"
1943 1944 How bookmark will be dealt during the exchange. It support the following
1944 1945 value
1945 1946
1946 1947 - "default": the default behavior, local and remote bookmarks are
1947 1948 "merged" on push/pull.
1948 1949 - "mirror": when pulling, replace local bookmarks by remote bookmarks.
1949 1950 This is useful to replicate a repository, or as an optimization.
1950 1951 - "ignore": ignore bookmarks during exchange. (This currently only
1951 1952 affect pulling)
1952 1953
1953 1954 The following special named paths exist:
1954 1955
1955 1956 "default"
1956 1957 The URL or directory to use when no source or remote is specified.
1957 1958
1958 1959 'hg clone' will automatically define this path to the location the
1959 1960 repository was cloned from.
1960 1961
1961 1962 "default-push"
1962 1963 (deprecated) The URL or directory for the default 'hg push' location.
1963 1964 "default:pushurl" should be used instead.
1964 1965
1965 1966 $ hg help glossary.mcguffin
1966 1967 abort: help section not found: glossary.mcguffin
1967 1968 [10]
1968 1969
1969 1970 $ hg help glossary.mc.guffin
1970 1971 abort: help section not found: glossary.mc.guffin
1971 1972 [10]
1972 1973
1973 1974 $ hg help template.files
1974 1975 files List of strings. All files modified, added, or removed by
1975 1976 this changeset.
1976 1977 files(pattern)
1977 1978 All files of the current changeset matching the pattern. See
1978 1979 'hg help patterns'.
1979 1980
1980 1981 Test section lookup by translated message
1981 1982
1982 1983 str.lower() instead of encoding.lower(str) on translated message might
1983 1984 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1984 1985 as the second or later byte of multi-byte character.
1985 1986
1986 1987 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1987 1988 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1988 1989 replacement makes message meaningless.
1989 1990
1990 1991 This tests that section lookup by translated string isn't broken by
1991 1992 such str.lower().
1992 1993
1993 1994 $ "$PYTHON" <<EOF
1994 1995 > def escape(s):
1995 1996 > return b''.join(br'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1996 1997 > # translation of "record" in ja_JP.cp932
1997 1998 > upper = b"\x8bL\x98^"
1998 1999 > # str.lower()-ed section name should be treated as different one
1999 2000 > lower = b"\x8bl\x98^"
2000 2001 > with open('ambiguous.py', 'wb') as fp:
2001 2002 > fp.write(b"""# ambiguous section names in ja_JP.cp932
2002 2003 > u'''summary of extension
2003 2004 >
2004 2005 > %s
2005 2006 > ----
2006 2007 >
2007 2008 > Upper name should show only this message
2008 2009 >
2009 2010 > %s
2010 2011 > ----
2011 2012 >
2012 2013 > Lower name should show only this message
2013 2014 >
2014 2015 > subsequent section
2015 2016 > ------------------
2016 2017 >
2017 2018 > This should be hidden at 'hg help ambiguous' with section name.
2018 2019 > '''
2019 2020 > """ % (escape(upper), escape(lower)))
2020 2021 > EOF
2021 2022
2022 2023 $ cat >> $HGRCPATH <<EOF
2023 2024 > [extensions]
2024 2025 > ambiguous = ./ambiguous.py
2025 2026 > EOF
2026 2027
2027 2028 $ "$PYTHON" <<EOF | sh
2028 2029 > from mercurial.utils import procutil
2029 2030 > upper = b"\x8bL\x98^"
2030 2031 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
2031 2032 > EOF
2032 2033 \x8bL\x98^ (esc)
2033 2034 ----
2034 2035
2035 2036 Upper name should show only this message
2036 2037
2037 2038
2038 2039 $ "$PYTHON" <<EOF | sh
2039 2040 > from mercurial.utils import procutil
2040 2041 > lower = b"\x8bl\x98^"
2041 2042 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
2042 2043 > EOF
2043 2044 \x8bl\x98^ (esc)
2044 2045 ----
2045 2046
2046 2047 Lower name should show only this message
2047 2048
2048 2049
2049 2050 $ cat >> $HGRCPATH <<EOF
2050 2051 > [extensions]
2051 2052 > ambiguous = !
2052 2053 > EOF
2053 2054
2054 2055 Show help content of disabled extensions
2055 2056
2056 2057 $ cat >> $HGRCPATH <<EOF
2057 2058 > [extensions]
2058 2059 > ambiguous = !./ambiguous.py
2059 2060 > EOF
2060 2061 $ hg help -e ambiguous
2061 2062 ambiguous extension - (no help text available)
2062 2063
2063 2064 (use 'hg help extensions' for information on enabling extensions)
2064 2065
2065 2066 Test dynamic list of merge tools only shows up once
2066 2067 $ hg help merge-tools
2067 2068 Merge Tools
2068 2069 """""""""""
2069 2070
2070 2071 To merge files Mercurial uses merge tools.
2071 2072
2072 2073 A merge tool combines two different versions of a file into a merged file.
2073 2074 Merge tools are given the two files and the greatest common ancestor of
2074 2075 the two file versions, so they can determine the changes made on both
2075 2076 branches.
2076 2077
2077 2078 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
2078 2079 backout' and in several extensions.
2079 2080
2080 2081 Usually, the merge tool tries to automatically reconcile the files by
2081 2082 combining all non-overlapping changes that occurred separately in the two
2082 2083 different evolutions of the same initial base file. Furthermore, some
2083 2084 interactive merge programs make it easier to manually resolve conflicting
2084 2085 merges, either in a graphical way, or by inserting some conflict markers.
2085 2086 Mercurial does not include any interactive merge programs but relies on
2086 2087 external tools for that.
2087 2088
2088 2089 Available merge tools
2089 2090 =====================
2090 2091
2091 2092 External merge tools and their properties are configured in the merge-
2092 2093 tools configuration section - see hgrc(5) - but they can often just be
2093 2094 named by their executable.
2094 2095
2095 2096 A merge tool is generally usable if its executable can be found on the
2096 2097 system and if it can handle the merge. The executable is found if it is an
2097 2098 absolute or relative executable path or the name of an application in the
2098 2099 executable search path. The tool is assumed to be able to handle the merge
2099 2100 if it can handle symlinks if the file is a symlink, if it can handle
2100 2101 binary files if the file is binary, and if a GUI is available if the tool
2101 2102 requires a GUI.
2102 2103
2103 2104 There are some internal merge tools which can be used. The internal merge
2104 2105 tools are:
2105 2106
2106 2107 ":dump"
2107 2108 Creates three versions of the files to merge, containing the contents of
2108 2109 local, other and base. These files can then be used to perform a merge
2109 2110 manually. If the file to be merged is named "a.txt", these files will
2110 2111 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2111 2112 they will be placed in the same directory as "a.txt".
2112 2113
2113 2114 This implies premerge. Therefore, files aren't dumped, if premerge runs
2114 2115 successfully. Use :forcedump to forcibly write files out.
2115 2116
2116 2117 (actual capabilities: binary, symlink)
2117 2118
2118 2119 ":fail"
2119 2120 Rather than attempting to merge files that were modified on both
2120 2121 branches, it marks them as unresolved. The resolve command must be used
2121 2122 to resolve these conflicts.
2122 2123
2123 2124 (actual capabilities: binary, symlink)
2124 2125
2125 2126 ":forcedump"
2126 2127 Creates three versions of the files as same as :dump, but omits
2127 2128 premerge.
2128 2129
2129 2130 (actual capabilities: binary, symlink)
2130 2131
2131 2132 ":local"
2132 2133 Uses the local 'p1()' version of files as the merged version.
2133 2134
2134 2135 (actual capabilities: binary, symlink)
2135 2136
2136 2137 ":merge"
2137 2138 Uses the internal non-interactive simple merge algorithm for merging
2138 2139 files. It will fail if there are any conflicts and leave markers in the
2139 2140 partially merged file. Markers will have two sections, one for each side
2140 2141 of merge.
2141 2142
2142 2143 ":merge-local"
2143 2144 Like :merge, but resolve all conflicts non-interactively in favor of the
2144 2145 local 'p1()' changes.
2145 2146
2146 2147 ":merge-other"
2147 2148 Like :merge, but resolve all conflicts non-interactively in favor of the
2148 2149 other 'p2()' changes.
2149 2150
2150 2151 ":merge3"
2151 2152 Uses the internal non-interactive simple merge algorithm for merging
2152 2153 files. It will fail if there are any conflicts and leave markers in the
2153 2154 partially merged file. Marker will have three sections, one from each
2154 2155 side of the merge and one for the base content.
2155 2156
2156 2157 ":mergediff"
2157 2158 Uses the internal non-interactive simple merge algorithm for merging
2158 2159 files. It will fail if there are any conflicts and leave markers in the
2159 2160 partially merged file. The marker will have two sections, one with the
2160 2161 content from one side of the merge, and one with a diff from the base
2161 2162 content to the content on the other side. (experimental)
2162 2163
2163 2164 ":other"
2164 2165 Uses the other 'p2()' version of files as the merged version.
2165 2166
2166 2167 (actual capabilities: binary, symlink)
2167 2168
2168 2169 ":prompt"
2169 2170 Asks the user which of the local 'p1()' or the other 'p2()' version to
2170 2171 keep as the merged version.
2171 2172
2172 2173 (actual capabilities: binary, symlink)
2173 2174
2174 2175 ":tagmerge"
2175 2176 Uses the internal tag merge algorithm (experimental).
2176 2177
2177 2178 ":union"
2178 2179 Uses the internal non-interactive simple merge algorithm for merging
2179 2180 files. It will use both local and other sides for conflict regions by
2180 2181 adding local on top of other. No markers are inserted.
2181 2182
2182 2183 ":union-other-first"
2183 2184 Like :union, but add other on top of local.
2184 2185
2185 2186 Internal tools are always available and do not require a GUI but will by
2186 2187 default not handle symlinks or binary files. See next section for detail
2187 2188 about "actual capabilities" described above.
2188 2189
2189 2190 Choosing a merge tool
2190 2191 =====================
2191 2192
2192 2193 Mercurial uses these rules when deciding which merge tool to use:
2193 2194
2194 2195 1. If a tool has been specified with the --tool option to merge or
2195 2196 resolve, it is used. If it is the name of a tool in the merge-tools
2196 2197 configuration, its configuration is used. Otherwise the specified tool
2197 2198 must be executable by the shell.
2198 2199 2. If the "HGMERGE" environment variable is present, its value is used and
2199 2200 must be executable by the shell.
2200 2201 3. If the filename of the file to be merged matches any of the patterns in
2201 2202 the merge-patterns configuration section, the first usable merge tool
2202 2203 corresponding to a matching pattern is used.
2203 2204 4. If ui.merge is set it will be considered next. If the value is not the
2204 2205 name of a configured tool, the specified value is used and must be
2205 2206 executable by the shell. Otherwise the named tool is used if it is
2206 2207 usable.
2207 2208 5. If any usable merge tools are present in the merge-tools configuration
2208 2209 section, the one with the highest priority is used.
2209 2210 6. If a program named "hgmerge" can be found on the system, it is used -
2210 2211 but it will by default not be used for symlinks and binary files.
2211 2212 7. If the file to be merged is not binary and is not a symlink, then
2212 2213 internal ":merge" is used.
2213 2214 8. Otherwise, ":prompt" is used.
2214 2215
2215 2216 For historical reason, Mercurial treats merge tools as below while
2216 2217 examining rules above.
2217 2218
2218 2219 step specified via binary symlink
2219 2220 ----------------------------------
2220 2221 1. --tool o/o o/o
2221 2222 2. HGMERGE o/o o/o
2222 2223 3. merge-patterns o/o(*) x/?(*)
2223 2224 4. ui.merge x/?(*) x/?(*)
2224 2225
2225 2226 Each capability column indicates Mercurial behavior for internal/external
2226 2227 merge tools at examining each rule.
2227 2228
2228 2229 - "o": "assume that a tool has capability"
2229 2230 - "x": "assume that a tool does not have capability"
2230 2231 - "?": "check actual capability of a tool"
2231 2232
2232 2233 If "merge.strict-capability-check" configuration is true, Mercurial checks
2233 2234 capabilities of merge tools strictly in (*) cases above (= each capability
2234 2235 column becomes "?/?"). It is false by default for backward compatibility.
2235 2236
2236 2237 Note:
2237 2238 After selecting a merge program, Mercurial will by default attempt to
2238 2239 merge the files using a simple merge algorithm first. Only if it
2239 2240 doesn't succeed because of conflicting changes will Mercurial actually
2240 2241 execute the merge program. Whether to use the simple merge algorithm
2241 2242 first can be controlled by the premerge setting of the merge tool.
2242 2243 Premerge is enabled by default unless the file is binary or a symlink.
2243 2244
2244 2245 See the merge-tools and ui sections of hgrc(5) for details on the
2245 2246 configuration of merge tools.
2246 2247
2247 2248 Compression engines listed in `hg help bundlespec`
2248 2249
2249 2250 $ hg help bundlespec | grep gzip
2250 2251 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2251 2252 An algorithm that produces smaller bundles than "gzip".
2252 2253 This engine will likely produce smaller bundles than "gzip" but will be
2253 2254 "gzip"
2254 2255 better compression than "gzip". It also frequently yields better (?)
2255 2256
2256 2257 Test usage of section marks in help documents
2257 2258
2258 2259 $ cd "$TESTDIR"/../doc
2259 2260 $ "$PYTHON" check-seclevel.py
2260 2261 $ cd $TESTTMP
2261 2262
2262 2263 #if serve
2263 2264
2264 2265 Test the help pages in hgweb.
2265 2266
2266 2267 Dish up an empty repo; serve it cold.
2267 2268
2268 2269 $ hg init "$TESTTMP/test"
2269 2270 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2270 2271 $ cat hg.pid >> $DAEMON_PIDS
2271 2272
2272 2273 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2273 2274 200 Script output follows
2274 2275
2275 2276 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2276 2277 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2277 2278 <head>
2278 2279 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2279 2280 <meta name="robots" content="index, nofollow" />
2280 2281 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2281 2282 <script type="text/javascript" src="/static/mercurial.js"></script>
2282 2283
2283 2284 <title>Help: Index</title>
2284 2285 </head>
2285 2286 <body>
2286 2287
2287 2288 <div class="container">
2288 2289 <div class="menu">
2289 2290 <div class="logo">
2290 2291 <a href="https://mercurial-scm.org/">
2291 2292 <img src="/static/hglogo.png" alt="mercurial" /></a>
2292 2293 </div>
2293 2294 <ul>
2294 2295 <li><a href="/shortlog">log</a></li>
2295 2296 <li><a href="/graph">graph</a></li>
2296 2297 <li><a href="/tags">tags</a></li>
2297 2298 <li><a href="/bookmarks">bookmarks</a></li>
2298 2299 <li><a href="/branches">branches</a></li>
2299 2300 </ul>
2300 2301 <ul>
2301 2302 <li class="active">help</li>
2302 2303 </ul>
2303 2304 </div>
2304 2305
2305 2306 <div class="main">
2306 2307 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2307 2308
2308 2309 <form class="search" action="/log">
2309 2310
2310 2311 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2311 2312 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2312 2313 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2313 2314 </form>
2314 2315 <table class="bigtable">
2315 2316 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2316 2317
2317 2318 <tr><td>
2318 2319 <a href="/help/bundlespec">
2319 2320 bundlespec
2320 2321 </a>
2321 2322 </td><td>
2322 2323 Bundle File Formats
2323 2324 </td></tr>
2324 2325 <tr><td>
2325 2326 <a href="/help/color">
2326 2327 color
2327 2328 </a>
2328 2329 </td><td>
2329 2330 Colorizing Outputs
2330 2331 </td></tr>
2331 2332 <tr><td>
2332 2333 <a href="/help/config">
2333 2334 config
2334 2335 </a>
2335 2336 </td><td>
2336 2337 Configuration Files
2337 2338 </td></tr>
2338 2339 <tr><td>
2339 2340 <a href="/help/dates">
2340 2341 dates
2341 2342 </a>
2342 2343 </td><td>
2343 2344 Date Formats
2344 2345 </td></tr>
2345 2346 <tr><td>
2346 2347 <a href="/help/deprecated">
2347 2348 deprecated
2348 2349 </a>
2349 2350 </td><td>
2350 2351 Deprecated Features
2351 2352 </td></tr>
2352 2353 <tr><td>
2353 2354 <a href="/help/diffs">
2354 2355 diffs
2355 2356 </a>
2356 2357 </td><td>
2357 2358 Diff Formats
2358 2359 </td></tr>
2359 2360 <tr><td>
2360 2361 <a href="/help/environment">
2361 2362 environment
2362 2363 </a>
2363 2364 </td><td>
2364 2365 Environment Variables
2365 2366 </td></tr>
2366 2367 <tr><td>
2367 2368 <a href="/help/evolution">
2368 2369 evolution
2369 2370 </a>
2370 2371 </td><td>
2371 2372 Safely rewriting history (EXPERIMENTAL)
2372 2373 </td></tr>
2373 2374 <tr><td>
2374 2375 <a href="/help/extensions">
2375 2376 extensions
2376 2377 </a>
2377 2378 </td><td>
2378 2379 Using Additional Features
2379 2380 </td></tr>
2380 2381 <tr><td>
2381 2382 <a href="/help/filesets">
2382 2383 filesets
2383 2384 </a>
2384 2385 </td><td>
2385 2386 Specifying File Sets
2386 2387 </td></tr>
2387 2388 <tr><td>
2388 2389 <a href="/help/flags">
2389 2390 flags
2390 2391 </a>
2391 2392 </td><td>
2392 2393 Command-line flags
2393 2394 </td></tr>
2394 2395 <tr><td>
2395 2396 <a href="/help/glossary">
2396 2397 glossary
2397 2398 </a>
2398 2399 </td><td>
2399 2400 Glossary
2400 2401 </td></tr>
2401 2402 <tr><td>
2402 2403 <a href="/help/hgignore">
2403 2404 hgignore
2404 2405 </a>
2405 2406 </td><td>
2406 2407 Syntax for Mercurial Ignore Files
2407 2408 </td></tr>
2408 2409 <tr><td>
2409 2410 <a href="/help/hgweb">
2410 2411 hgweb
2411 2412 </a>
2412 2413 </td><td>
2413 2414 Configuring hgweb
2414 2415 </td></tr>
2415 2416 <tr><td>
2416 2417 <a href="/help/internals">
2417 2418 internals
2418 2419 </a>
2419 2420 </td><td>
2420 2421 Technical implementation topics
2421 2422 </td></tr>
2422 2423 <tr><td>
2423 2424 <a href="/help/merge-tools">
2424 2425 merge-tools
2425 2426 </a>
2426 2427 </td><td>
2427 2428 Merge Tools
2428 2429 </td></tr>
2429 2430 <tr><td>
2430 2431 <a href="/help/pager">
2431 2432 pager
2432 2433 </a>
2433 2434 </td><td>
2434 2435 Pager Support
2435 2436 </td></tr>
2436 2437 <tr><td>
2437 2438 <a href="/help/patterns">
2438 2439 patterns
2439 2440 </a>
2440 2441 </td><td>
2441 2442 File Name Patterns
2442 2443 </td></tr>
2443 2444 <tr><td>
2444 2445 <a href="/help/phases">
2445 2446 phases
2446 2447 </a>
2447 2448 </td><td>
2448 2449 Working with Phases
2449 2450 </td></tr>
2450 2451 <tr><td>
2451 2452 <a href="/help/revisions">
2452 2453 revisions
2453 2454 </a>
2454 2455 </td><td>
2455 2456 Specifying Revisions
2456 2457 </td></tr>
2457 2458 <tr><td>
2458 2459 <a href="/help/rust">
2459 2460 rust
2460 2461 </a>
2461 2462 </td><td>
2462 2463 Rust in Mercurial
2463 2464 </td></tr>
2464 2465 <tr><td>
2465 2466 <a href="/help/scripting">
2466 2467 scripting
2467 2468 </a>
2468 2469 </td><td>
2469 2470 Using Mercurial from scripts and automation
2470 2471 </td></tr>
2471 2472 <tr><td>
2472 2473 <a href="/help/subrepos">
2473 2474 subrepos
2474 2475 </a>
2475 2476 </td><td>
2476 2477 Subrepositories
2477 2478 </td></tr>
2478 2479 <tr><td>
2479 2480 <a href="/help/templating">
2480 2481 templating
2481 2482 </a>
2482 2483 </td><td>
2483 2484 Template Usage
2484 2485 </td></tr>
2485 2486 <tr><td>
2486 2487 <a href="/help/urls">
2487 2488 urls
2488 2489 </a>
2489 2490 </td><td>
2490 2491 URL Paths
2491 2492 </td></tr>
2492 2493 <tr><td>
2493 2494 <a href="/help/topic-containing-verbose">
2494 2495 topic-containing-verbose
2495 2496 </a>
2496 2497 </td><td>
2497 2498 This is the topic to test omit indicating.
2498 2499 </td></tr>
2499 2500
2500 2501
2501 2502 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2502 2503
2503 2504 <tr><td>
2504 2505 <a href="/help/abort">
2505 2506 abort
2506 2507 </a>
2507 2508 </td><td>
2508 2509 abort an unfinished operation (EXPERIMENTAL)
2509 2510 </td></tr>
2510 2511 <tr><td>
2511 2512 <a href="/help/add">
2512 2513 add
2513 2514 </a>
2514 2515 </td><td>
2515 2516 add the specified files on the next commit
2516 2517 </td></tr>
2517 2518 <tr><td>
2518 2519 <a href="/help/annotate">
2519 2520 annotate
2520 2521 </a>
2521 2522 </td><td>
2522 2523 show changeset information by line for each file
2523 2524 </td></tr>
2524 2525 <tr><td>
2525 2526 <a href="/help/clone">
2526 2527 clone
2527 2528 </a>
2528 2529 </td><td>
2529 2530 make a copy of an existing repository
2530 2531 </td></tr>
2531 2532 <tr><td>
2532 2533 <a href="/help/commit">
2533 2534 commit
2534 2535 </a>
2535 2536 </td><td>
2536 2537 commit the specified files or all outstanding changes
2537 2538 </td></tr>
2538 2539 <tr><td>
2539 2540 <a href="/help/continue">
2540 2541 continue
2541 2542 </a>
2542 2543 </td><td>
2543 2544 resumes an interrupted operation (EXPERIMENTAL)
2544 2545 </td></tr>
2545 2546 <tr><td>
2546 2547 <a href="/help/diff">
2547 2548 diff
2548 2549 </a>
2549 2550 </td><td>
2550 2551 diff repository (or selected files)
2551 2552 </td></tr>
2552 2553 <tr><td>
2553 2554 <a href="/help/export">
2554 2555 export
2555 2556 </a>
2556 2557 </td><td>
2557 2558 dump the header and diffs for one or more changesets
2558 2559 </td></tr>
2559 2560 <tr><td>
2560 2561 <a href="/help/forget">
2561 2562 forget
2562 2563 </a>
2563 2564 </td><td>
2564 2565 forget the specified files on the next commit
2565 2566 </td></tr>
2566 2567 <tr><td>
2567 2568 <a href="/help/init">
2568 2569 init
2569 2570 </a>
2570 2571 </td><td>
2571 2572 create a new repository in the given directory
2572 2573 </td></tr>
2573 2574 <tr><td>
2574 2575 <a href="/help/log">
2575 2576 log
2576 2577 </a>
2577 2578 </td><td>
2578 2579 show revision history of entire repository or files
2579 2580 </td></tr>
2580 2581 <tr><td>
2581 2582 <a href="/help/merge">
2582 2583 merge
2583 2584 </a>
2584 2585 </td><td>
2585 2586 merge another revision into working directory
2586 2587 </td></tr>
2587 2588 <tr><td>
2588 2589 <a href="/help/pull">
2589 2590 pull
2590 2591 </a>
2591 2592 </td><td>
2592 2593 pull changes from the specified source
2593 2594 </td></tr>
2594 2595 <tr><td>
2595 2596 <a href="/help/push">
2596 2597 push
2597 2598 </a>
2598 2599 </td><td>
2599 2600 push changes to the specified destination
2600 2601 </td></tr>
2601 2602 <tr><td>
2602 2603 <a href="/help/remove">
2603 2604 remove
2604 2605 </a>
2605 2606 </td><td>
2606 2607 remove the specified files on the next commit
2607 2608 </td></tr>
2608 2609 <tr><td>
2609 2610 <a href="/help/serve">
2610 2611 serve
2611 2612 </a>
2612 2613 </td><td>
2613 2614 start stand-alone webserver
2614 2615 </td></tr>
2615 2616 <tr><td>
2616 2617 <a href="/help/status">
2617 2618 status
2618 2619 </a>
2619 2620 </td><td>
2620 2621 show changed files in the working directory
2621 2622 </td></tr>
2622 2623 <tr><td>
2623 2624 <a href="/help/summary">
2624 2625 summary
2625 2626 </a>
2626 2627 </td><td>
2627 2628 summarize working directory state
2628 2629 </td></tr>
2629 2630 <tr><td>
2630 2631 <a href="/help/update">
2631 2632 update
2632 2633 </a>
2633 2634 </td><td>
2634 2635 update working directory (or switch revisions)
2635 2636 </td></tr>
2636 2637
2637 2638
2638 2639
2639 2640 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2640 2641
2641 2642 <tr><td>
2642 2643 <a href="/help/addremove">
2643 2644 addremove
2644 2645 </a>
2645 2646 </td><td>
2646 2647 add all new files, delete all missing files
2647 2648 </td></tr>
2648 2649 <tr><td>
2649 2650 <a href="/help/archive">
2650 2651 archive
2651 2652 </a>
2652 2653 </td><td>
2653 2654 create an unversioned archive of a repository revision
2654 2655 </td></tr>
2655 2656 <tr><td>
2656 2657 <a href="/help/backout">
2657 2658 backout
2658 2659 </a>
2659 2660 </td><td>
2660 2661 reverse effect of earlier changeset
2661 2662 </td></tr>
2662 2663 <tr><td>
2663 2664 <a href="/help/bisect">
2664 2665 bisect
2665 2666 </a>
2666 2667 </td><td>
2667 2668 subdivision search of changesets
2668 2669 </td></tr>
2669 2670 <tr><td>
2670 2671 <a href="/help/bookmarks">
2671 2672 bookmarks
2672 2673 </a>
2673 2674 </td><td>
2674 2675 create a new bookmark or list existing bookmarks
2675 2676 </td></tr>
2676 2677 <tr><td>
2677 2678 <a href="/help/branch">
2678 2679 branch
2679 2680 </a>
2680 2681 </td><td>
2681 2682 set or show the current branch name
2682 2683 </td></tr>
2683 2684 <tr><td>
2684 2685 <a href="/help/branches">
2685 2686 branches
2686 2687 </a>
2687 2688 </td><td>
2688 2689 list repository named branches
2689 2690 </td></tr>
2690 2691 <tr><td>
2691 2692 <a href="/help/bundle">
2692 2693 bundle
2693 2694 </a>
2694 2695 </td><td>
2695 2696 create a bundle file
2696 2697 </td></tr>
2697 2698 <tr><td>
2698 2699 <a href="/help/cat">
2699 2700 cat
2700 2701 </a>
2701 2702 </td><td>
2702 2703 output the current or given revision of files
2703 2704 </td></tr>
2704 2705 <tr><td>
2705 2706 <a href="/help/config">
2706 2707 config
2707 2708 </a>
2708 2709 </td><td>
2709 2710 show combined config settings from all hgrc files
2710 2711 </td></tr>
2711 2712 <tr><td>
2712 2713 <a href="/help/copy">
2713 2714 copy
2714 2715 </a>
2715 2716 </td><td>
2716 2717 mark files as copied for the next commit
2717 2718 </td></tr>
2718 2719 <tr><td>
2719 2720 <a href="/help/files">
2720 2721 files
2721 2722 </a>
2722 2723 </td><td>
2723 2724 list tracked files
2724 2725 </td></tr>
2725 2726 <tr><td>
2726 2727 <a href="/help/graft">
2727 2728 graft
2728 2729 </a>
2729 2730 </td><td>
2730 2731 copy changes from other branches onto the current branch
2731 2732 </td></tr>
2732 2733 <tr><td>
2733 2734 <a href="/help/grep">
2734 2735 grep
2735 2736 </a>
2736 2737 </td><td>
2737 2738 search for a pattern in specified files
2738 2739 </td></tr>
2739 2740 <tr><td>
2740 2741 <a href="/help/hashelp">
2741 2742 hashelp
2742 2743 </a>
2743 2744 </td><td>
2744 2745 Extension command's help
2745 2746 </td></tr>
2746 2747 <tr><td>
2747 2748 <a href="/help/heads">
2748 2749 heads
2749 2750 </a>
2750 2751 </td><td>
2751 2752 show branch heads
2752 2753 </td></tr>
2753 2754 <tr><td>
2754 2755 <a href="/help/help">
2755 2756 help
2756 2757 </a>
2757 2758 </td><td>
2758 2759 show help for a given topic or a help overview
2759 2760 </td></tr>
2760 2761 <tr><td>
2761 2762 <a href="/help/hgalias">
2762 2763 hgalias
2763 2764 </a>
2764 2765 </td><td>
2765 2766 My doc
2766 2767 </td></tr>
2767 2768 <tr><td>
2768 2769 <a href="/help/hgaliasnodoc">
2769 2770 hgaliasnodoc
2770 2771 </a>
2771 2772 </td><td>
2772 2773 summarize working directory state
2773 2774 </td></tr>
2774 2775 <tr><td>
2775 2776 <a href="/help/identify">
2776 2777 identify
2777 2778 </a>
2778 2779 </td><td>
2779 2780 identify the working directory or specified revision
2780 2781 </td></tr>
2781 2782 <tr><td>
2782 2783 <a href="/help/import">
2783 2784 import
2784 2785 </a>
2785 2786 </td><td>
2786 2787 import an ordered set of patches
2787 2788 </td></tr>
2788 2789 <tr><td>
2789 2790 <a href="/help/incoming">
2790 2791 incoming
2791 2792 </a>
2792 2793 </td><td>
2793 2794 show new changesets found in source
2794 2795 </td></tr>
2795 2796 <tr><td>
2796 2797 <a href="/help/manifest">
2797 2798 manifest
2798 2799 </a>
2799 2800 </td><td>
2800 2801 output the current or given revision of the project manifest
2801 2802 </td></tr>
2802 2803 <tr><td>
2803 2804 <a href="/help/nohelp">
2804 2805 nohelp
2805 2806 </a>
2806 2807 </td><td>
2807 2808 (no help text available)
2808 2809 </td></tr>
2809 2810 <tr><td>
2810 2811 <a href="/help/outgoing">
2811 2812 outgoing
2812 2813 </a>
2813 2814 </td><td>
2814 2815 show changesets not found in the destination
2815 2816 </td></tr>
2816 2817 <tr><td>
2817 2818 <a href="/help/paths">
2818 2819 paths
2819 2820 </a>
2820 2821 </td><td>
2821 2822 show aliases for remote repositories
2822 2823 </td></tr>
2823 2824 <tr><td>
2824 2825 <a href="/help/phase">
2825 2826 phase
2826 2827 </a>
2827 2828 </td><td>
2828 2829 set or show the current phase name
2829 2830 </td></tr>
2830 2831 <tr><td>
2831 2832 <a href="/help/purge">
2832 2833 purge
2833 2834 </a>
2834 2835 </td><td>
2835 2836 removes files not tracked by Mercurial
2836 2837 </td></tr>
2837 2838 <tr><td>
2838 2839 <a href="/help/recover">
2839 2840 recover
2840 2841 </a>
2841 2842 </td><td>
2842 2843 roll back an interrupted transaction
2843 2844 </td></tr>
2844 2845 <tr><td>
2845 2846 <a href="/help/rename">
2846 2847 rename
2847 2848 </a>
2848 2849 </td><td>
2849 2850 rename files; equivalent of copy + remove
2850 2851 </td></tr>
2851 2852 <tr><td>
2852 2853 <a href="/help/resolve">
2853 2854 resolve
2854 2855 </a>
2855 2856 </td><td>
2856 2857 redo merges or set/view the merge status of files
2857 2858 </td></tr>
2858 2859 <tr><td>
2859 2860 <a href="/help/revert">
2860 2861 revert
2861 2862 </a>
2862 2863 </td><td>
2863 2864 restore files to their checkout state
2864 2865 </td></tr>
2865 2866 <tr><td>
2866 2867 <a href="/help/root">
2867 2868 root
2868 2869 </a>
2869 2870 </td><td>
2870 2871 print the root (top) of the current working directory
2871 2872 </td></tr>
2872 2873 <tr><td>
2873 2874 <a href="/help/shellalias">
2874 2875 shellalias
2875 2876 </a>
2876 2877 </td><td>
2877 2878 (no help text available)
2878 2879 </td></tr>
2879 2880 <tr><td>
2880 2881 <a href="/help/shelve">
2881 2882 shelve
2882 2883 </a>
2883 2884 </td><td>
2884 2885 save and set aside changes from the working directory
2885 2886 </td></tr>
2886 2887 <tr><td>
2887 2888 <a href="/help/tag">
2888 2889 tag
2889 2890 </a>
2890 2891 </td><td>
2891 2892 add one or more tags for the current or given revision
2892 2893 </td></tr>
2893 2894 <tr><td>
2894 2895 <a href="/help/tags">
2895 2896 tags
2896 2897 </a>
2897 2898 </td><td>
2898 2899 list repository tags
2899 2900 </td></tr>
2900 2901 <tr><td>
2901 2902 <a href="/help/unbundle">
2902 2903 unbundle
2903 2904 </a>
2904 2905 </td><td>
2905 2906 apply one or more bundle files
2906 2907 </td></tr>
2907 2908 <tr><td>
2908 2909 <a href="/help/unshelve">
2909 2910 unshelve
2910 2911 </a>
2911 2912 </td><td>
2912 2913 restore a shelved change to the working directory
2913 2914 </td></tr>
2914 2915 <tr><td>
2915 2916 <a href="/help/verify">
2916 2917 verify
2917 2918 </a>
2918 2919 </td><td>
2919 2920 verify the integrity of the repository
2920 2921 </td></tr>
2921 2922 <tr><td>
2922 2923 <a href="/help/version">
2923 2924 version
2924 2925 </a>
2925 2926 </td><td>
2926 2927 output version and copyright information
2927 2928 </td></tr>
2928 2929
2929 2930
2930 2931 </table>
2931 2932 </div>
2932 2933 </div>
2933 2934
2934 2935
2935 2936
2936 2937 </body>
2937 2938 </html>
2938 2939
2939 2940
2940 2941 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2941 2942 200 Script output follows
2942 2943
2943 2944 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2944 2945 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2945 2946 <head>
2946 2947 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2947 2948 <meta name="robots" content="index, nofollow" />
2948 2949 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2949 2950 <script type="text/javascript" src="/static/mercurial.js"></script>
2950 2951
2951 2952 <title>Help: add</title>
2952 2953 </head>
2953 2954 <body>
2954 2955
2955 2956 <div class="container">
2956 2957 <div class="menu">
2957 2958 <div class="logo">
2958 2959 <a href="https://mercurial-scm.org/">
2959 2960 <img src="/static/hglogo.png" alt="mercurial" /></a>
2960 2961 </div>
2961 2962 <ul>
2962 2963 <li><a href="/shortlog">log</a></li>
2963 2964 <li><a href="/graph">graph</a></li>
2964 2965 <li><a href="/tags">tags</a></li>
2965 2966 <li><a href="/bookmarks">bookmarks</a></li>
2966 2967 <li><a href="/branches">branches</a></li>
2967 2968 </ul>
2968 2969 <ul>
2969 2970 <li class="active"><a href="/help">help</a></li>
2970 2971 </ul>
2971 2972 </div>
2972 2973
2973 2974 <div class="main">
2974 2975 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2975 2976 <h3>Help: add</h3>
2976 2977
2977 2978 <form class="search" action="/log">
2978 2979
2979 2980 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2980 2981 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2981 2982 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2982 2983 </form>
2983 2984 <div id="doc">
2984 2985 <p>
2985 2986 hg add [OPTION]... [FILE]...
2986 2987 </p>
2987 2988 <p>
2988 2989 add the specified files on the next commit
2989 2990 </p>
2990 2991 <p>
2991 2992 Schedule files to be version controlled and added to the
2992 2993 repository.
2993 2994 </p>
2994 2995 <p>
2995 2996 The files will be added to the repository at the next commit. To
2996 2997 undo an add before that, see 'hg forget'.
2997 2998 </p>
2998 2999 <p>
2999 3000 If no names are given, add all files to the repository (except
3000 3001 files matching &quot;.hgignore&quot;).
3001 3002 </p>
3002 3003 <p>
3003 3004 Examples:
3004 3005 </p>
3005 3006 <ul>
3006 3007 <li> New (unknown) files are added automatically by 'hg add':
3007 3008 <pre>
3008 3009 \$ ls (re)
3009 3010 foo.c
3010 3011 \$ hg status (re)
3011 3012 ? foo.c
3012 3013 \$ hg add (re)
3013 3014 adding foo.c
3014 3015 \$ hg status (re)
3015 3016 A foo.c
3016 3017 </pre>
3017 3018 <li> Specific files to be added can be specified:
3018 3019 <pre>
3019 3020 \$ ls (re)
3020 3021 bar.c foo.c
3021 3022 \$ hg status (re)
3022 3023 ? bar.c
3023 3024 ? foo.c
3024 3025 \$ hg add bar.c (re)
3025 3026 \$ hg status (re)
3026 3027 A bar.c
3027 3028 ? foo.c
3028 3029 </pre>
3029 3030 </ul>
3030 3031 <p>
3031 3032 Returns 0 if all files are successfully added.
3032 3033 </p>
3033 3034 <p>
3034 3035 options ([+] can be repeated):
3035 3036 </p>
3036 3037 <table>
3037 3038 <tr><td>-I</td>
3038 3039 <td>--include PATTERN [+]</td>
3039 3040 <td>include names matching the given patterns</td></tr>
3040 3041 <tr><td>-X</td>
3041 3042 <td>--exclude PATTERN [+]</td>
3042 3043 <td>exclude names matching the given patterns</td></tr>
3043 3044 <tr><td>-S</td>
3044 3045 <td>--subrepos</td>
3045 3046 <td>recurse into subrepositories</td></tr>
3046 3047 <tr><td>-n</td>
3047 3048 <td>--dry-run</td>
3048 3049 <td>do not perform actions, just print output</td></tr>
3049 3050 </table>
3050 3051 <p>
3051 3052 global options ([+] can be repeated):
3052 3053 </p>
3053 3054 <table>
3054 3055 <tr><td>-R</td>
3055 3056 <td>--repository REPO</td>
3056 3057 <td>repository root directory or name of overlay bundle file</td></tr>
3057 3058 <tr><td></td>
3058 3059 <td>--cwd DIR</td>
3059 3060 <td>change working directory</td></tr>
3060 3061 <tr><td>-y</td>
3061 3062 <td>--noninteractive</td>
3062 3063 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3063 3064 <tr><td>-q</td>
3064 3065 <td>--quiet</td>
3065 3066 <td>suppress output</td></tr>
3066 3067 <tr><td>-v</td>
3067 3068 <td>--verbose</td>
3068 3069 <td>enable additional output</td></tr>
3069 3070 <tr><td></td>
3070 3071 <td>--color TYPE</td>
3071 3072 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3072 3073 <tr><td></td>
3073 3074 <td>--config CONFIG [+]</td>
3074 3075 <td>set/override config option (use 'section.name=value')</td></tr>
3075 3076 <tr><td></td>
3076 3077 <td>--debug</td>
3077 3078 <td>enable debugging output</td></tr>
3078 3079 <tr><td></td>
3079 3080 <td>--debugger</td>
3080 3081 <td>start debugger</td></tr>
3081 3082 <tr><td></td>
3082 3083 <td>--encoding ENCODE</td>
3083 3084 <td>set the charset encoding (default: ascii)</td></tr>
3084 3085 <tr><td></td>
3085 3086 <td>--encodingmode MODE</td>
3086 3087 <td>set the charset encoding mode (default: strict)</td></tr>
3087 3088 <tr><td></td>
3088 3089 <td>--traceback</td>
3089 3090 <td>always print a traceback on exception</td></tr>
3090 3091 <tr><td></td>
3091 3092 <td>--time</td>
3092 3093 <td>time how long the command takes</td></tr>
3093 3094 <tr><td></td>
3094 3095 <td>--profile</td>
3095 3096 <td>print command execution profile</td></tr>
3096 3097 <tr><td></td>
3097 3098 <td>--version</td>
3098 3099 <td>output version information and exit</td></tr>
3099 3100 <tr><td>-h</td>
3100 3101 <td>--help</td>
3101 3102 <td>display help and exit</td></tr>
3102 3103 <tr><td></td>
3103 3104 <td>--hidden</td>
3104 3105 <td>consider hidden changesets</td></tr>
3105 3106 <tr><td></td>
3106 3107 <td>--pager TYPE</td>
3107 3108 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3108 3109 </table>
3109 3110
3110 3111 </div>
3111 3112 </div>
3112 3113 </div>
3113 3114
3114 3115
3115 3116
3116 3117 </body>
3117 3118 </html>
3118 3119
3119 3120
3120 3121 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
3121 3122 200 Script output follows
3122 3123
3123 3124 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3124 3125 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3125 3126 <head>
3126 3127 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3127 3128 <meta name="robots" content="index, nofollow" />
3128 3129 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3129 3130 <script type="text/javascript" src="/static/mercurial.js"></script>
3130 3131
3131 3132 <title>Help: remove</title>
3132 3133 </head>
3133 3134 <body>
3134 3135
3135 3136 <div class="container">
3136 3137 <div class="menu">
3137 3138 <div class="logo">
3138 3139 <a href="https://mercurial-scm.org/">
3139 3140 <img src="/static/hglogo.png" alt="mercurial" /></a>
3140 3141 </div>
3141 3142 <ul>
3142 3143 <li><a href="/shortlog">log</a></li>
3143 3144 <li><a href="/graph">graph</a></li>
3144 3145 <li><a href="/tags">tags</a></li>
3145 3146 <li><a href="/bookmarks">bookmarks</a></li>
3146 3147 <li><a href="/branches">branches</a></li>
3147 3148 </ul>
3148 3149 <ul>
3149 3150 <li class="active"><a href="/help">help</a></li>
3150 3151 </ul>
3151 3152 </div>
3152 3153
3153 3154 <div class="main">
3154 3155 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3155 3156 <h3>Help: remove</h3>
3156 3157
3157 3158 <form class="search" action="/log">
3158 3159
3159 3160 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3160 3161 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3161 3162 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3162 3163 </form>
3163 3164 <div id="doc">
3164 3165 <p>
3165 3166 hg remove [OPTION]... FILE...
3166 3167 </p>
3167 3168 <p>
3168 3169 aliases: rm
3169 3170 </p>
3170 3171 <p>
3171 3172 remove the specified files on the next commit
3172 3173 </p>
3173 3174 <p>
3174 3175 Schedule the indicated files for removal from the current branch.
3175 3176 </p>
3176 3177 <p>
3177 3178 This command schedules the files to be removed at the next commit.
3178 3179 To undo a remove before that, see 'hg revert'. To undo added
3179 3180 files, see 'hg forget'.
3180 3181 </p>
3181 3182 <p>
3182 3183 -A/--after can be used to remove only files that have already
3183 3184 been deleted, -f/--force can be used to force deletion, and -Af
3184 3185 can be used to remove files from the next revision without
3185 3186 deleting them from the working directory.
3186 3187 </p>
3187 3188 <p>
3188 3189 The following table details the behavior of remove for different
3189 3190 file states (columns) and option combinations (rows). The file
3190 3191 states are Added [A], Clean [C], Modified [M] and Missing [!]
3191 3192 (as reported by 'hg status'). The actions are Warn, Remove
3192 3193 (from branch) and Delete (from disk):
3193 3194 </p>
3194 3195 <table>
3195 3196 <tr><td>opt/state</td>
3196 3197 <td>A</td>
3197 3198 <td>C</td>
3198 3199 <td>M</td>
3199 3200 <td>!</td></tr>
3200 3201 <tr><td>none</td>
3201 3202 <td>W</td>
3202 3203 <td>RD</td>
3203 3204 <td>W</td>
3204 3205 <td>R</td></tr>
3205 3206 <tr><td>-f</td>
3206 3207 <td>R</td>
3207 3208 <td>RD</td>
3208 3209 <td>RD</td>
3209 3210 <td>R</td></tr>
3210 3211 <tr><td>-A</td>
3211 3212 <td>W</td>
3212 3213 <td>W</td>
3213 3214 <td>W</td>
3214 3215 <td>R</td></tr>
3215 3216 <tr><td>-Af</td>
3216 3217 <td>R</td>
3217 3218 <td>R</td>
3218 3219 <td>R</td>
3219 3220 <td>R</td></tr>
3220 3221 </table>
3221 3222 <p>
3222 3223 <b>Note:</b>
3223 3224 </p>
3224 3225 <p>
3225 3226 'hg remove' never deletes files in Added [A] state from the
3226 3227 working directory, not even if &quot;--force&quot; is specified.
3227 3228 </p>
3228 3229 <p>
3229 3230 Returns 0 on success, 1 if any warnings encountered.
3230 3231 </p>
3231 3232 <p>
3232 3233 options ([+] can be repeated):
3233 3234 </p>
3234 3235 <table>
3235 3236 <tr><td>-A</td>
3236 3237 <td>--after</td>
3237 3238 <td>record delete for missing files</td></tr>
3238 3239 <tr><td>-f</td>
3239 3240 <td>--force</td>
3240 3241 <td>forget added files, delete modified files</td></tr>
3241 3242 <tr><td>-S</td>
3242 3243 <td>--subrepos</td>
3243 3244 <td>recurse into subrepositories</td></tr>
3244 3245 <tr><td>-I</td>
3245 3246 <td>--include PATTERN [+]</td>
3246 3247 <td>include names matching the given patterns</td></tr>
3247 3248 <tr><td>-X</td>
3248 3249 <td>--exclude PATTERN [+]</td>
3249 3250 <td>exclude names matching the given patterns</td></tr>
3250 3251 <tr><td>-n</td>
3251 3252 <td>--dry-run</td>
3252 3253 <td>do not perform actions, just print output</td></tr>
3253 3254 </table>
3254 3255 <p>
3255 3256 global options ([+] can be repeated):
3256 3257 </p>
3257 3258 <table>
3258 3259 <tr><td>-R</td>
3259 3260 <td>--repository REPO</td>
3260 3261 <td>repository root directory or name of overlay bundle file</td></tr>
3261 3262 <tr><td></td>
3262 3263 <td>--cwd DIR</td>
3263 3264 <td>change working directory</td></tr>
3264 3265 <tr><td>-y</td>
3265 3266 <td>--noninteractive</td>
3266 3267 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3267 3268 <tr><td>-q</td>
3268 3269 <td>--quiet</td>
3269 3270 <td>suppress output</td></tr>
3270 3271 <tr><td>-v</td>
3271 3272 <td>--verbose</td>
3272 3273 <td>enable additional output</td></tr>
3273 3274 <tr><td></td>
3274 3275 <td>--color TYPE</td>
3275 3276 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3276 3277 <tr><td></td>
3277 3278 <td>--config CONFIG [+]</td>
3278 3279 <td>set/override config option (use 'section.name=value')</td></tr>
3279 3280 <tr><td></td>
3280 3281 <td>--debug</td>
3281 3282 <td>enable debugging output</td></tr>
3282 3283 <tr><td></td>
3283 3284 <td>--debugger</td>
3284 3285 <td>start debugger</td></tr>
3285 3286 <tr><td></td>
3286 3287 <td>--encoding ENCODE</td>
3287 3288 <td>set the charset encoding (default: ascii)</td></tr>
3288 3289 <tr><td></td>
3289 3290 <td>--encodingmode MODE</td>
3290 3291 <td>set the charset encoding mode (default: strict)</td></tr>
3291 3292 <tr><td></td>
3292 3293 <td>--traceback</td>
3293 3294 <td>always print a traceback on exception</td></tr>
3294 3295 <tr><td></td>
3295 3296 <td>--time</td>
3296 3297 <td>time how long the command takes</td></tr>
3297 3298 <tr><td></td>
3298 3299 <td>--profile</td>
3299 3300 <td>print command execution profile</td></tr>
3300 3301 <tr><td></td>
3301 3302 <td>--version</td>
3302 3303 <td>output version information and exit</td></tr>
3303 3304 <tr><td>-h</td>
3304 3305 <td>--help</td>
3305 3306 <td>display help and exit</td></tr>
3306 3307 <tr><td></td>
3307 3308 <td>--hidden</td>
3308 3309 <td>consider hidden changesets</td></tr>
3309 3310 <tr><td></td>
3310 3311 <td>--pager TYPE</td>
3311 3312 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3312 3313 </table>
3313 3314
3314 3315 </div>
3315 3316 </div>
3316 3317 </div>
3317 3318
3318 3319
3319 3320
3320 3321 </body>
3321 3322 </html>
3322 3323
3323 3324
3324 3325 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3325 3326 200 Script output follows
3326 3327
3327 3328 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3328 3329 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3329 3330 <head>
3330 3331 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3331 3332 <meta name="robots" content="index, nofollow" />
3332 3333 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3333 3334 <script type="text/javascript" src="/static/mercurial.js"></script>
3334 3335
3335 3336 <title>Help: dates</title>
3336 3337 </head>
3337 3338 <body>
3338 3339
3339 3340 <div class="container">
3340 3341 <div class="menu">
3341 3342 <div class="logo">
3342 3343 <a href="https://mercurial-scm.org/">
3343 3344 <img src="/static/hglogo.png" alt="mercurial" /></a>
3344 3345 </div>
3345 3346 <ul>
3346 3347 <li><a href="/shortlog">log</a></li>
3347 3348 <li><a href="/graph">graph</a></li>
3348 3349 <li><a href="/tags">tags</a></li>
3349 3350 <li><a href="/bookmarks">bookmarks</a></li>
3350 3351 <li><a href="/branches">branches</a></li>
3351 3352 </ul>
3352 3353 <ul>
3353 3354 <li class="active"><a href="/help">help</a></li>
3354 3355 </ul>
3355 3356 </div>
3356 3357
3357 3358 <div class="main">
3358 3359 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3359 3360 <h3>Help: dates</h3>
3360 3361
3361 3362 <form class="search" action="/log">
3362 3363
3363 3364 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3364 3365 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3365 3366 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3366 3367 </form>
3367 3368 <div id="doc">
3368 3369 <h1>Date Formats</h1>
3369 3370 <p>
3370 3371 Some commands allow the user to specify a date, e.g.:
3371 3372 </p>
3372 3373 <ul>
3373 3374 <li> backout, commit, import, tag: Specify the commit date.
3374 3375 <li> log, revert, update: Select revision(s) by date.
3375 3376 </ul>
3376 3377 <p>
3377 3378 Many date formats are valid. Here are some examples:
3378 3379 </p>
3379 3380 <ul>
3380 3381 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3381 3382 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3382 3383 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3383 3384 <li> &quot;Dec 6&quot; (midnight)
3384 3385 <li> &quot;13:18&quot; (today assumed)
3385 3386 <li> &quot;3:39&quot; (3:39AM assumed)
3386 3387 <li> &quot;3:39pm&quot; (15:39)
3387 3388 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3388 3389 <li> &quot;2006-12-6 13:18&quot;
3389 3390 <li> &quot;2006-12-6&quot;
3390 3391 <li> &quot;12-6&quot;
3391 3392 <li> &quot;12/6&quot;
3392 3393 <li> &quot;12/6/6&quot; (Dec 6 2006)
3393 3394 <li> &quot;today&quot; (midnight)
3394 3395 <li> &quot;yesterday&quot; (midnight)
3395 3396 <li> &quot;now&quot; - right now
3396 3397 </ul>
3397 3398 <p>
3398 3399 Lastly, there is Mercurial's internal format:
3399 3400 </p>
3400 3401 <ul>
3401 3402 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3402 3403 </ul>
3403 3404 <p>
3404 3405 This is the internal representation format for dates. The first number
3405 3406 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3406 3407 second is the offset of the local timezone, in seconds west of UTC
3407 3408 (negative if the timezone is east of UTC).
3408 3409 </p>
3409 3410 <p>
3410 3411 The log command also accepts date ranges:
3411 3412 </p>
3412 3413 <ul>
3413 3414 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3414 3415 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3415 3416 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3416 3417 <li> &quot;-DAYS&quot; - within a given number of days from today
3417 3418 </ul>
3418 3419
3419 3420 </div>
3420 3421 </div>
3421 3422 </div>
3422 3423
3423 3424
3424 3425
3425 3426 </body>
3426 3427 </html>
3427 3428
3428 3429
3429 3430 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3430 3431 200 Script output follows
3431 3432
3432 3433 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3433 3434 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3434 3435 <head>
3435 3436 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3436 3437 <meta name="robots" content="index, nofollow" />
3437 3438 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3438 3439 <script type="text/javascript" src="/static/mercurial.js"></script>
3439 3440
3440 3441 <title>Help: pager</title>
3441 3442 </head>
3442 3443 <body>
3443 3444
3444 3445 <div class="container">
3445 3446 <div class="menu">
3446 3447 <div class="logo">
3447 3448 <a href="https://mercurial-scm.org/">
3448 3449 <img src="/static/hglogo.png" alt="mercurial" /></a>
3449 3450 </div>
3450 3451 <ul>
3451 3452 <li><a href="/shortlog">log</a></li>
3452 3453 <li><a href="/graph">graph</a></li>
3453 3454 <li><a href="/tags">tags</a></li>
3454 3455 <li><a href="/bookmarks">bookmarks</a></li>
3455 3456 <li><a href="/branches">branches</a></li>
3456 3457 </ul>
3457 3458 <ul>
3458 3459 <li class="active"><a href="/help">help</a></li>
3459 3460 </ul>
3460 3461 </div>
3461 3462
3462 3463 <div class="main">
3463 3464 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3464 3465 <h3>Help: pager</h3>
3465 3466
3466 3467 <form class="search" action="/log">
3467 3468
3468 3469 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3469 3470 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3470 3471 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3471 3472 </form>
3472 3473 <div id="doc">
3473 3474 <h1>Pager Support</h1>
3474 3475 <p>
3475 3476 Some Mercurial commands can produce a lot of output, and Mercurial will
3476 3477 attempt to use a pager to make those commands more pleasant.
3477 3478 </p>
3478 3479 <p>
3479 3480 To set the pager that should be used, set the application variable:
3480 3481 </p>
3481 3482 <pre>
3482 3483 [pager]
3483 3484 pager = less -FRX
3484 3485 </pre>
3485 3486 <p>
3486 3487 If no pager is set in the user or repository configuration, Mercurial uses the
3487 3488 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3488 3489 or system configuration is used. If none of these are set, a default pager will
3489 3490 be used, typically 'less' on Unix and 'more' on Windows.
3490 3491 </p>
3491 3492 <p>
3492 3493 You can disable the pager for certain commands by adding them to the
3493 3494 pager.ignore list:
3494 3495 </p>
3495 3496 <pre>
3496 3497 [pager]
3497 3498 ignore = version, help, update
3498 3499 </pre>
3499 3500 <p>
3500 3501 To ignore global commands like 'hg version' or 'hg help', you have
3501 3502 to specify them in your user configuration file.
3502 3503 </p>
3503 3504 <p>
3504 3505 To control whether the pager is used at all for an individual command,
3505 3506 you can use --pager=&lt;value&gt;:
3506 3507 </p>
3507 3508 <ul>
3508 3509 <li> use as needed: 'auto'.
3509 3510 <li> require the pager: 'yes' or 'on'.
3510 3511 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3511 3512 </ul>
3512 3513 <p>
3513 3514 To globally turn off all attempts to use a pager, set:
3514 3515 </p>
3515 3516 <pre>
3516 3517 [ui]
3517 3518 paginate = never
3518 3519 </pre>
3519 3520 <p>
3520 3521 which will prevent the pager from running.
3521 3522 </p>
3522 3523
3523 3524 </div>
3524 3525 </div>
3525 3526 </div>
3526 3527
3527 3528
3528 3529
3529 3530 </body>
3530 3531 </html>
3531 3532
3532 3533
3533 3534 Sub-topic indexes rendered properly
3534 3535
3535 3536 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3536 3537 200 Script output follows
3537 3538
3538 3539 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3539 3540 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3540 3541 <head>
3541 3542 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3542 3543 <meta name="robots" content="index, nofollow" />
3543 3544 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3544 3545 <script type="text/javascript" src="/static/mercurial.js"></script>
3545 3546
3546 3547 <title>Help: internals</title>
3547 3548 </head>
3548 3549 <body>
3549 3550
3550 3551 <div class="container">
3551 3552 <div class="menu">
3552 3553 <div class="logo">
3553 3554 <a href="https://mercurial-scm.org/">
3554 3555 <img src="/static/hglogo.png" alt="mercurial" /></a>
3555 3556 </div>
3556 3557 <ul>
3557 3558 <li><a href="/shortlog">log</a></li>
3558 3559 <li><a href="/graph">graph</a></li>
3559 3560 <li><a href="/tags">tags</a></li>
3560 3561 <li><a href="/bookmarks">bookmarks</a></li>
3561 3562 <li><a href="/branches">branches</a></li>
3562 3563 </ul>
3563 3564 <ul>
3564 3565 <li><a href="/help">help</a></li>
3565 3566 </ul>
3566 3567 </div>
3567 3568
3568 3569 <div class="main">
3569 3570 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3570 3571
3571 3572 <form class="search" action="/log">
3572 3573
3573 3574 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3574 3575 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3575 3576 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3576 3577 </form>
3577 3578 <table class="bigtable">
3578 3579 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3579 3580
3580 3581 <tr><td>
3581 3582 <a href="/help/internals.bid-merge">
3582 3583 bid-merge
3583 3584 </a>
3584 3585 </td><td>
3585 3586 Bid Merge Algorithm
3586 3587 </td></tr>
3587 3588 <tr><td>
3588 3589 <a href="/help/internals.bundle2">
3589 3590 bundle2
3590 3591 </a>
3591 3592 </td><td>
3592 3593 Bundle2
3593 3594 </td></tr>
3594 3595 <tr><td>
3595 3596 <a href="/help/internals.bundles">
3596 3597 bundles
3597 3598 </a>
3598 3599 </td><td>
3599 3600 Bundles
3600 3601 </td></tr>
3601 3602 <tr><td>
3602 3603 <a href="/help/internals.cbor">
3603 3604 cbor
3604 3605 </a>
3605 3606 </td><td>
3606 3607 CBOR
3607 3608 </td></tr>
3608 3609 <tr><td>
3609 3610 <a href="/help/internals.censor">
3610 3611 censor
3611 3612 </a>
3612 3613 </td><td>
3613 3614 Censor
3614 3615 </td></tr>
3615 3616 <tr><td>
3616 3617 <a href="/help/internals.changegroups">
3617 3618 changegroups
3618 3619 </a>
3619 3620 </td><td>
3620 3621 Changegroups
3621 3622 </td></tr>
3622 3623 <tr><td>
3623 3624 <a href="/help/internals.config">
3624 3625 config
3625 3626 </a>
3626 3627 </td><td>
3627 3628 Config Registrar
3628 3629 </td></tr>
3629 3630 <tr><td>
3630 3631 <a href="/help/internals.dirstate-v2">
3631 3632 dirstate-v2
3632 3633 </a>
3633 3634 </td><td>
3634 3635 dirstate-v2 file format
3635 3636 </td></tr>
3636 3637 <tr><td>
3637 3638 <a href="/help/internals.extensions">
3638 3639 extensions
3639 3640 </a>
3640 3641 </td><td>
3641 3642 Extension API
3642 3643 </td></tr>
3643 3644 <tr><td>
3644 3645 <a href="/help/internals.mergestate">
3645 3646 mergestate
3646 3647 </a>
3647 3648 </td><td>
3648 3649 Mergestate
3649 3650 </td></tr>
3650 3651 <tr><td>
3651 3652 <a href="/help/internals.requirements">
3652 3653 requirements
3653 3654 </a>
3654 3655 </td><td>
3655 3656 Repository Requirements
3656 3657 </td></tr>
3657 3658 <tr><td>
3658 3659 <a href="/help/internals.revlogs">
3659 3660 revlogs
3660 3661 </a>
3661 3662 </td><td>
3662 3663 Revision Logs
3663 3664 </td></tr>
3664 3665 <tr><td>
3665 3666 <a href="/help/internals.wireprotocol">
3666 3667 wireprotocol
3667 3668 </a>
3668 3669 </td><td>
3669 3670 Wire Protocol
3670 3671 </td></tr>
3671 3672 <tr><td>
3672 3673 <a href="/help/internals.wireprotocolrpc">
3673 3674 wireprotocolrpc
3674 3675 </a>
3675 3676 </td><td>
3676 3677 Wire Protocol RPC
3677 3678 </td></tr>
3678 3679 <tr><td>
3679 3680 <a href="/help/internals.wireprotocolv2">
3680 3681 wireprotocolv2
3681 3682 </a>
3682 3683 </td><td>
3683 3684 Wire Protocol Version 2
3684 3685 </td></tr>
3685 3686
3686 3687
3687 3688
3688 3689
3689 3690
3690 3691 </table>
3691 3692 </div>
3692 3693 </div>
3693 3694
3694 3695
3695 3696
3696 3697 </body>
3697 3698 </html>
3698 3699
3699 3700
3700 3701 Sub-topic topics rendered properly
3701 3702
3702 3703 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3703 3704 200 Script output follows
3704 3705
3705 3706 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3706 3707 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3707 3708 <head>
3708 3709 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3709 3710 <meta name="robots" content="index, nofollow" />
3710 3711 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3711 3712 <script type="text/javascript" src="/static/mercurial.js"></script>
3712 3713
3713 3714 <title>Help: internals.changegroups</title>
3714 3715 </head>
3715 3716 <body>
3716 3717
3717 3718 <div class="container">
3718 3719 <div class="menu">
3719 3720 <div class="logo">
3720 3721 <a href="https://mercurial-scm.org/">
3721 3722 <img src="/static/hglogo.png" alt="mercurial" /></a>
3722 3723 </div>
3723 3724 <ul>
3724 3725 <li><a href="/shortlog">log</a></li>
3725 3726 <li><a href="/graph">graph</a></li>
3726 3727 <li><a href="/tags">tags</a></li>
3727 3728 <li><a href="/bookmarks">bookmarks</a></li>
3728 3729 <li><a href="/branches">branches</a></li>
3729 3730 </ul>
3730 3731 <ul>
3731 3732 <li class="active"><a href="/help">help</a></li>
3732 3733 </ul>
3733 3734 </div>
3734 3735
3735 3736 <div class="main">
3736 3737 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3737 3738 <h3>Help: internals.changegroups</h3>
3738 3739
3739 3740 <form class="search" action="/log">
3740 3741
3741 3742 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3742 3743 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3743 3744 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3744 3745 </form>
3745 3746 <div id="doc">
3746 3747 <h1>Changegroups</h1>
3747 3748 <p>
3748 3749 Changegroups are representations of repository revlog data, specifically
3749 3750 the changelog data, root/flat manifest data, treemanifest data, and
3750 3751 filelogs.
3751 3752 </p>
3752 3753 <p>
3753 3754 There are 4 versions of changegroups: &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;. From a
3754 3755 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3755 3756 only difference being an additional item in the *delta header*. Version
3756 3757 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3757 3758 exchanging treemanifests (enabled by setting an option on the
3758 3759 &quot;changegroup&quot; part in the bundle2). Version &quot;4&quot; adds support for exchanging
3759 3760 sidedata (additional revision metadata not part of the digest).
3760 3761 </p>
3761 3762 <p>
3762 3763 Changegroups when not exchanging treemanifests consist of 3 logical
3763 3764 segments:
3764 3765 </p>
3765 3766 <pre>
3766 3767 +---------------------------------+
3767 3768 | | | |
3768 3769 | changeset | manifest | filelogs |
3769 3770 | | | |
3770 3771 | | | |
3771 3772 +---------------------------------+
3772 3773 </pre>
3773 3774 <p>
3774 3775 When exchanging treemanifests, there are 4 logical segments:
3775 3776 </p>
3776 3777 <pre>
3777 3778 +-------------------------------------------------+
3778 3779 | | | | |
3779 3780 | changeset | root | treemanifests | filelogs |
3780 3781 | | manifest | | |
3781 3782 | | | | |
3782 3783 +-------------------------------------------------+
3783 3784 </pre>
3784 3785 <p>
3785 3786 The principle building block of each segment is a *chunk*. A *chunk*
3786 3787 is a framed piece of data:
3787 3788 </p>
3788 3789 <pre>
3789 3790 +---------------------------------------+
3790 3791 | | |
3791 3792 | length | data |
3792 3793 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3793 3794 | | |
3794 3795 +---------------------------------------+
3795 3796 </pre>
3796 3797 <p>
3797 3798 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3798 3799 integer indicating the length of the entire chunk (including the length field
3799 3800 itself).
3800 3801 </p>
3801 3802 <p>
3802 3803 There is a special case chunk that has a value of 0 for the length
3803 3804 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3804 3805 </p>
3805 3806 <h2>Delta Groups</h2>
3806 3807 <p>
3807 3808 A *delta group* expresses the content of a revlog as a series of deltas,
3808 3809 or patches against previous revisions.
3809 3810 </p>
3810 3811 <p>
3811 3812 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3812 3813 to signal the end of the delta group:
3813 3814 </p>
3814 3815 <pre>
3815 3816 +------------------------------------------------------------------------+
3816 3817 | | | | | |
3817 3818 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3818 3819 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3819 3820 | | | | | |
3820 3821 +------------------------------------------------------------------------+
3821 3822 </pre>
3822 3823 <p>
3823 3824 Each *chunk*'s data consists of the following:
3824 3825 </p>
3825 3826 <pre>
3826 3827 +---------------------------------------+
3827 3828 | | |
3828 3829 | delta header | delta data |
3829 3830 | (various by version) | (various) |
3830 3831 | | |
3831 3832 +---------------------------------------+
3832 3833 </pre>
3833 3834 <p>
3834 3835 The *delta data* is a series of *delta*s that describe a diff from an existing
3835 3836 entry (either that the recipient already has, or previously specified in the
3836 3837 bundle/changegroup).
3837 3838 </p>
3838 3839 <p>
3839 3840 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;
3840 3841 of the changegroup format.
3841 3842 </p>
3842 3843 <p>
3843 3844 Version 1 (headerlen=80):
3844 3845 </p>
3845 3846 <pre>
3846 3847 +------------------------------------------------------+
3847 3848 | | | | |
3848 3849 | node | p1 node | p2 node | link node |
3849 3850 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3850 3851 | | | | |
3851 3852 +------------------------------------------------------+
3852 3853 </pre>
3853 3854 <p>
3854 3855 Version 2 (headerlen=100):
3855 3856 </p>
3856 3857 <pre>
3857 3858 +------------------------------------------------------------------+
3858 3859 | | | | | |
3859 3860 | node | p1 node | p2 node | base node | link node |
3860 3861 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3861 3862 | | | | | |
3862 3863 +------------------------------------------------------------------+
3863 3864 </pre>
3864 3865 <p>
3865 3866 Version 3 (headerlen=102):
3866 3867 </p>
3867 3868 <pre>
3868 3869 +------------------------------------------------------------------------------+
3869 3870 | | | | | | |
3870 3871 | node | p1 node | p2 node | base node | link node | flags |
3871 3872 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3872 3873 | | | | | | |
3873 3874 +------------------------------------------------------------------------------+
3874 3875 </pre>
3875 3876 <p>
3876 3877 Version 4 (headerlen=103):
3877 3878 </p>
3878 3879 <pre>
3879 3880 +------------------------------------------------------------------------------+----------+
3880 3881 | | | | | | | |
3881 3882 | node | p1 node | p2 node | base node | link node | flags | pflags |
3882 3883 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
3883 3884 | | | | | | | |
3884 3885 +------------------------------------------------------------------------------+----------+
3885 3886 </pre>
3886 3887 <p>
3887 3888 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3888 3889 series of *delta*s, densely packed (no separators). These deltas describe a diff
3889 3890 from an existing entry (either that the recipient already has, or previously
3890 3891 specified in the bundle/changegroup). The format is described more fully in
3891 3892 &quot;hg help internals.bdiff&quot;, but briefly:
3892 3893 </p>
3893 3894 <pre>
3894 3895 +---------------------------------------------------------------+
3895 3896 | | | | |
3896 3897 | start offset | end offset | new length | content |
3897 3898 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3898 3899 | | | | |
3899 3900 +---------------------------------------------------------------+
3900 3901 </pre>
3901 3902 <p>
3902 3903 Please note that the length field in the delta data does *not* include itself.
3903 3904 </p>
3904 3905 <p>
3905 3906 In version 1, the delta is always applied against the previous node from
3906 3907 the changegroup or the first parent if this is the first entry in the
3907 3908 changegroup.
3908 3909 </p>
3909 3910 <p>
3910 3911 In version 2 and up, the delta base node is encoded in the entry in the
3911 3912 changegroup. This allows the delta to be expressed against any parent,
3912 3913 which can result in smaller deltas and more efficient encoding of data.
3913 3914 </p>
3914 3915 <p>
3915 3916 The *flags* field holds bitwise flags affecting the processing of revision
3916 3917 data. The following flags are defined:
3917 3918 </p>
3918 3919 <dl>
3919 3920 <dt>32768
3920 3921 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3921 3922 <dt>16384
3922 3923 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3923 3924 <dt>8192
3924 3925 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3925 3926 <dt>4096
3926 3927 <dd>Contains copy information. This revision changes files in a way that could affect copy tracing. This does *not* affect changegroup handling, but is relevant for other parts of Mercurial.
3927 3928 </dl>
3928 3929 <p>
3929 3930 For historical reasons, the integer values are identical to revlog version 1
3930 3931 per-revision storage flags and correspond to bits being set in this 2-byte
3931 3932 field. Bits were allocated starting from the most-significant bit, hence the
3932 3933 reverse ordering and allocation of these flags.
3933 3934 </p>
3934 3935 <p>
3935 3936 The *pflags* (protocol flags) field holds bitwise flags affecting the protocol
3936 3937 itself. They are first in the header since they may affect the handling of the
3937 3938 rest of the fields in a future version. They are defined as such:
3938 3939 </p>
3939 3940 <dl>
3940 3941 <dt>1 indicates whether to read a chunk of sidedata (of variable length) right
3941 3942 <dd>after the revision flags.
3942 3943 </dl>
3943 3944 <h2>Changeset Segment</h2>
3944 3945 <p>
3945 3946 The *changeset segment* consists of a single *delta group* holding
3946 3947 changelog data. The *empty chunk* at the end of the *delta group* denotes
3947 3948 the boundary to the *manifest segment*.
3948 3949 </p>
3949 3950 <h2>Manifest Segment</h2>
3950 3951 <p>
3951 3952 The *manifest segment* consists of a single *delta group* holding manifest
3952 3953 data. If treemanifests are in use, it contains only the manifest for the
3953 3954 root directory of the repository. Otherwise, it contains the entire
3954 3955 manifest data. The *empty chunk* at the end of the *delta group* denotes
3955 3956 the boundary to the next segment (either the *treemanifests segment* or the
3956 3957 *filelogs segment*, depending on version and the request options).
3957 3958 </p>
3958 3959 <h3>Treemanifests Segment</h3>
3959 3960 <p>
3960 3961 The *treemanifests segment* only exists in changegroup version &quot;3&quot; and &quot;4&quot;,
3961 3962 and only if the 'treemanifest' param is part of the bundle2 changegroup part
3962 3963 (it is not possible to use changegroup version 3 or 4 outside of bundle2).
3963 3964 Aside from the filenames in the *treemanifests segment* containing a
3964 3965 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3965 3966 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3966 3967 a sub-segment with filename size 0). This denotes the boundary to the
3967 3968 *filelogs segment*.
3968 3969 </p>
3969 3970 <h2>Filelogs Segment</h2>
3970 3971 <p>
3971 3972 The *filelogs segment* consists of multiple sub-segments, each
3972 3973 corresponding to an individual file whose data is being described:
3973 3974 </p>
3974 3975 <pre>
3975 3976 +--------------------------------------------------+
3976 3977 | | | | | |
3977 3978 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3978 3979 | | | | | (4 bytes) |
3979 3980 | | | | | |
3980 3981 +--------------------------------------------------+
3981 3982 </pre>
3982 3983 <p>
3983 3984 The final filelog sub-segment is followed by an *empty chunk* (logically,
3984 3985 a sub-segment with filename size 0). This denotes the end of the segment
3985 3986 and of the overall changegroup.
3986 3987 </p>
3987 3988 <p>
3988 3989 Each filelog sub-segment consists of the following:
3989 3990 </p>
3990 3991 <pre>
3991 3992 +------------------------------------------------------+
3992 3993 | | | |
3993 3994 | filename length | filename | delta group |
3994 3995 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3995 3996 | | | |
3996 3997 +------------------------------------------------------+
3997 3998 </pre>
3998 3999 <p>
3999 4000 That is, a *chunk* consisting of the filename (not terminated or padded)
4000 4001 followed by N chunks constituting the *delta group* for this file. The
4001 4002 *empty chunk* at the end of each *delta group* denotes the boundary to the
4002 4003 next filelog sub-segment.
4003 4004 </p>
4004 4005
4005 4006 </div>
4006 4007 </div>
4007 4008 </div>
4008 4009
4009 4010
4010 4011
4011 4012 </body>
4012 4013 </html>
4013 4014
4014 4015
4015 4016 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
4016 4017 404 Not Found
4017 4018
4018 4019 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4019 4020 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
4020 4021 <head>
4021 4022 <link rel="icon" href="/static/hgicon.png" type="image/png" />
4022 4023 <meta name="robots" content="index, nofollow" />
4023 4024 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
4024 4025 <script type="text/javascript" src="/static/mercurial.js"></script>
4025 4026
4026 4027 <title>test: error</title>
4027 4028 </head>
4028 4029 <body>
4029 4030
4030 4031 <div class="container">
4031 4032 <div class="menu">
4032 4033 <div class="logo">
4033 4034 <a href="https://mercurial-scm.org/">
4034 4035 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
4035 4036 </div>
4036 4037 <ul>
4037 4038 <li><a href="/shortlog">log</a></li>
4038 4039 <li><a href="/graph">graph</a></li>
4039 4040 <li><a href="/tags">tags</a></li>
4040 4041 <li><a href="/bookmarks">bookmarks</a></li>
4041 4042 <li><a href="/branches">branches</a></li>
4042 4043 </ul>
4043 4044 <ul>
4044 4045 <li><a href="/help">help</a></li>
4045 4046 </ul>
4046 4047 </div>
4047 4048
4048 4049 <div class="main">
4049 4050
4050 4051 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
4051 4052 <h3>error</h3>
4052 4053
4053 4054
4054 4055 <form class="search" action="/log">
4055 4056
4056 4057 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
4057 4058 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
4058 4059 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
4059 4060 </form>
4060 4061
4061 4062 <div class="description">
4062 4063 <p>
4063 4064 An error occurred while processing your request:
4064 4065 </p>
4065 4066 <p>
4066 4067 Not Found
4067 4068 </p>
4068 4069 </div>
4069 4070 </div>
4070 4071 </div>
4071 4072
4072 4073
4073 4074
4074 4075 </body>
4075 4076 </html>
4076 4077
4077 4078 [1]
4078 4079
4079 4080 $ killdaemons.py
4080 4081
4081 4082 #endif
General Comments 0
You need to be logged in to leave comments. Login now