##// END OF EJS Templates
color: add the definition of '--color' in core...
Pierre-Yves David -
r31104:8346b2f0 default
parent child Browse files
Show More
@@ -1,251 +1,252 b''
1 1 # color.py color output for Mercurial commands
2 2 #
3 3 # Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 '''colorize output from some commands
9 9
10 10 The color extension colorizes output from several Mercurial commands.
11 11 For example, the diff command shows additions in green and deletions
12 12 in red, while the status command shows modified files in magenta. Many
13 13 other commands have analogous colors. It is possible to customize
14 14 these colors.
15 15
16 16 Effects
17 17 -------
18 18
19 19 Other effects in addition to color, like bold and underlined text, are
20 20 also available. By default, the terminfo database is used to find the
21 21 terminal codes used to change color and effect. If terminfo is not
22 22 available, then effects are rendered with the ECMA-48 SGR control
23 23 function (aka ANSI escape codes).
24 24
25 25 The available effects in terminfo mode are 'blink', 'bold', 'dim',
26 26 'inverse', 'invisible', 'italic', 'standout', and 'underline'; in
27 27 ECMA-48 mode, the options are 'bold', 'inverse', 'italic', and
28 28 'underline'. How each is rendered depends on the terminal emulator.
29 29 Some may not be available for a given terminal type, and will be
30 30 silently ignored.
31 31
32 32 If the terminfo entry for your terminal is missing codes for an effect
33 33 or has the wrong codes, you can add or override those codes in your
34 34 configuration::
35 35
36 36 [color]
37 37 terminfo.dim = \E[2m
38 38
39 39 where '\E' is substituted with an escape character.
40 40
41 41 Labels
42 42 ------
43 43
44 44 Text receives color effects depending on the labels that it has. Many
45 45 default Mercurial commands emit labelled text. You can also define
46 46 your own labels in templates using the label function, see :hg:`help
47 47 templates`. A single portion of text may have more than one label. In
48 48 that case, effects given to the last label will override any other
49 49 effects. This includes the special "none" effect, which nullifies
50 50 other effects.
51 51
52 52 Labels are normally invisible. In order to see these labels and their
53 53 position in the text, use the global --color=debug option. The same
54 54 anchor text may be associated to multiple labels, e.g.
55 55
56 56 [log.changeset changeset.secret|changeset: 22611:6f0a53c8f587]
57 57
58 58 The following are the default effects for some default labels. Default
59 59 effects may be overridden from your configuration file::
60 60
61 61 [color]
62 62 status.modified = blue bold underline red_background
63 63 status.added = green bold
64 64 status.removed = red bold blue_background
65 65 status.deleted = cyan bold underline
66 66 status.unknown = magenta bold underline
67 67 status.ignored = black bold
68 68
69 69 # 'none' turns off all effects
70 70 status.clean = none
71 71 status.copied = none
72 72
73 73 qseries.applied = blue bold underline
74 74 qseries.unapplied = black bold
75 75 qseries.missing = red bold
76 76
77 77 diff.diffline = bold
78 78 diff.extended = cyan bold
79 79 diff.file_a = red bold
80 80 diff.file_b = green bold
81 81 diff.hunk = magenta
82 82 diff.deleted = red
83 83 diff.inserted = green
84 84 diff.changed = white
85 85 diff.tab =
86 86 diff.trailingwhitespace = bold red_background
87 87
88 88 # Blank so it inherits the style of the surrounding label
89 89 changeset.public =
90 90 changeset.draft =
91 91 changeset.secret =
92 92
93 93 resolve.unresolved = red bold
94 94 resolve.resolved = green bold
95 95
96 96 bookmarks.active = green
97 97
98 98 branches.active = none
99 99 branches.closed = black bold
100 100 branches.current = green
101 101 branches.inactive = none
102 102
103 103 tags.normal = green
104 104 tags.local = black bold
105 105
106 106 rebase.rebased = blue
107 107 rebase.remaining = red bold
108 108
109 109 shelve.age = cyan
110 110 shelve.newest = green bold
111 111 shelve.name = blue bold
112 112
113 113 histedit.remaining = red bold
114 114
115 115 Custom colors
116 116 -------------
117 117
118 118 Because there are only eight standard colors, this module allows you
119 119 to define color names for other color slots which might be available
120 120 for your terminal type, assuming terminfo mode. For instance::
121 121
122 122 color.brightblue = 12
123 123 color.pink = 207
124 124 color.orange = 202
125 125
126 126 to set 'brightblue' to color slot 12 (useful for 16 color terminals
127 127 that have brighter colors defined in the upper eight) and, 'pink' and
128 128 'orange' to colors in 256-color xterm's default color cube. These
129 129 defined colors may then be used as any of the pre-defined eight,
130 130 including appending '_background' to set the background to that color.
131 131
132 132 Modes
133 133 -----
134 134
135 135 By default, the color extension will use ANSI mode (or win32 mode on
136 136 Windows) if it detects a terminal. To override auto mode (to enable
137 137 terminfo mode, for example), set the following configuration option::
138 138
139 139 [color]
140 140 mode = terminfo
141 141
142 142 Any value other than 'ansi', 'win32', 'terminfo', or 'auto' will
143 143 disable color.
144 144
145 145 Note that on some systems, terminfo mode may cause problems when using
146 146 color with the pager extension and less -R. less with the -R option
147 147 will only display ECMA-48 color codes, and terminfo mode may sometimes
148 148 emit codes that less doesn't understand. You can work around this by
149 149 either using ansi mode (or auto mode), or by using less -r (which will
150 150 pass through all terminal control codes, not just color control
151 151 codes).
152 152
153 153 On some systems (such as MSYS in Windows), the terminal may support
154 154 a different color mode than the pager (activated via the "pager"
155 155 extension). It is possible to define separate modes depending on whether
156 156 the pager is active::
157 157
158 158 [color]
159 159 mode = auto
160 160 pagermode = ansi
161 161
162 162 If ``pagermode`` is not defined, the ``mode`` will be used.
163 163 '''
164 164
165 165 from __future__ import absolute_import
166 166
167 167 try:
168 168 import curses
169 169 curses.COLOR_BLACK # force import
170 170 except ImportError:
171 171 curses = None
172 172
173 173 from mercurial.i18n import _
174 174 from mercurial import (
175 175 cmdutil,
176 176 color,
177 177 commands,
178 178 dispatch,
179 179 extensions,
180 180 ui as uimod,
181 181 )
182 182
183 183 cmdtable = {}
184 184 command = cmdutil.command(cmdtable)
185 185 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
186 186 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
187 187 # be specifying the version(s) of Mercurial they are tested with, or
188 188 # leave the attribute unspecified.
189 189 testedwith = 'ships-with-hg-core'
190 190
191 191 def uisetup(ui):
192 192 def colorcmd(orig, ui_, opts, cmd, cmdfunc):
193 193 mode = color._modesetup(ui_, opts['color'])
194 194 uimod.ui._colormode = mode
195 195 if mode and mode != 'debug':
196 196 color.configstyles(ui_)
197 197 return orig(ui_, opts, cmd, cmdfunc)
198 198 extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
199 199
200 200 def extsetup(ui):
201 commands.globalopts.append(
202 ('', 'color', 'auto',
203 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
204 # and should not be translated
205 _("when to colorize (boolean, always, auto, never, or debug)"),
206 _('TYPE')))
201 # change default color config
202 for idx, entry in enumerate(commands.globalopts):
203 if entry[1] == 'color':
204 patch = ('auto', entry[3].replace(' (EXPERIMENTAL)', ''))
205 new = entry[:2] + patch + entry[4:]
206 commands.globalopts[idx] = new
207 break
207 208
208 209 @command('debugcolor',
209 210 [('', 'style', None, _('show all configured styles'))],
210 211 'hg debugcolor')
211 212 def debugcolor(ui, repo, **opts):
212 213 """show available color, effects or style"""
213 214 ui.write(('color mode: %s\n') % ui._colormode)
214 215 if opts.get('style'):
215 216 return _debugdisplaystyle(ui)
216 217 else:
217 218 return _debugdisplaycolor(ui)
218 219
219 220 def _debugdisplaycolor(ui):
220 221 oldstyle = color._styles.copy()
221 222 try:
222 223 color._styles.clear()
223 224 for effect in color._effects.keys():
224 225 color._styles[effect] = effect
225 226 if color._terminfo_params:
226 227 for k, v in ui.configitems('color'):
227 228 if k.startswith('color.'):
228 229 color._styles[k] = k[6:]
229 230 elif k.startswith('terminfo.'):
230 231 color._styles[k] = k[9:]
231 232 ui.write(_('available colors:\n'))
232 233 # sort label with a '_' after the other to group '_background' entry.
233 234 items = sorted(color._styles.items(),
234 235 key=lambda i: ('_' in i[0], i[0], i[1]))
235 236 for colorname, label in items:
236 237 ui.write(('%s\n') % colorname, label=label)
237 238 finally:
238 239 color._styles.clear()
239 240 color._styles.update(oldstyle)
240 241
241 242 def _debugdisplaystyle(ui):
242 243 ui.write(_('available style:\n'))
243 244 width = max(len(s) for s in color._styles)
244 245 for label, effects in sorted(color._styles.items()):
245 246 ui.write('%s' % label, label=label)
246 247 if effects:
247 248 # 50
248 249 ui.write(': ')
249 250 ui.write(' ' * (max(0, width - len(label))))
250 251 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
251 252 ui.write('\n')
@@ -1,5429 +1,5435 b''
1 1 # commands.py - command processing for mercurial
2 2 #
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import difflib
11 11 import errno
12 12 import os
13 13 import re
14 14
15 15 from .i18n import _
16 16 from .node import (
17 17 hex,
18 18 nullid,
19 19 nullrev,
20 20 short,
21 21 )
22 22 from . import (
23 23 archival,
24 24 bookmarks,
25 25 bundle2,
26 26 changegroup,
27 27 cmdutil,
28 28 copies,
29 29 destutil,
30 30 dirstateguard,
31 31 discovery,
32 32 encoding,
33 33 error,
34 34 exchange,
35 35 extensions,
36 36 graphmod,
37 37 hbisect,
38 38 help,
39 39 hg,
40 40 lock as lockmod,
41 41 merge as mergemod,
42 42 obsolete,
43 43 patch,
44 44 phases,
45 45 pycompat,
46 46 revsetlang,
47 47 scmutil,
48 48 server,
49 49 sshserver,
50 50 streamclone,
51 51 templatekw,
52 52 ui as uimod,
53 53 util,
54 54 )
55 55
56 56 release = lockmod.release
57 57
58 58 table = {}
59 59
60 60 command = cmdutil.command(table)
61 61
62 62 # label constants
63 63 # until 3.5, bookmarks.current was the advertised name, not
64 64 # bookmarks.active, so we must use both to avoid breaking old
65 65 # custom styles
66 66 activebookmarklabel = 'bookmarks.active bookmarks.current'
67 67
68 68 # common command options
69 69
70 70 globalopts = [
71 71 ('R', 'repository', '',
72 72 _('repository root directory or name of overlay bundle file'),
73 73 _('REPO')),
74 74 ('', 'cwd', '',
75 75 _('change working directory'), _('DIR')),
76 76 ('y', 'noninteractive', None,
77 77 _('do not prompt, automatically pick the first choice for all prompts')),
78 78 ('q', 'quiet', None, _('suppress output')),
79 79 ('v', 'verbose', None, _('enable additional output')),
80 ('', 'color', 'never',
81 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
82 # and should not be translated
83 _("when to colorize (boolean, always, auto, never, or debug)"
84 " (EXPERIMENTAL)"),
85 _('TYPE')),
80 86 ('', 'config', [],
81 87 _('set/override config option (use \'section.name=value\')'),
82 88 _('CONFIG')),
83 89 ('', 'debug', None, _('enable debugging output')),
84 90 ('', 'debugger', None, _('start debugger')),
85 91 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
86 92 _('ENCODE')),
87 93 ('', 'encodingmode', encoding.encodingmode,
88 94 _('set the charset encoding mode'), _('MODE')),
89 95 ('', 'traceback', None, _('always print a traceback on exception')),
90 96 ('', 'time', None, _('time how long the command takes')),
91 97 ('', 'profile', None, _('print command execution profile')),
92 98 ('', 'version', None, _('output version information and exit')),
93 99 ('h', 'help', None, _('display help and exit')),
94 100 ('', 'hidden', False, _('consider hidden changesets')),
95 101 ('', 'pager', 'auto',
96 102 _("when to paginate (boolean, always, auto, or never)"), _('TYPE')),
97 103 ]
98 104
99 105 dryrunopts = [('n', 'dry-run', None,
100 106 _('do not perform actions, just print output'))]
101 107
102 108 remoteopts = [
103 109 ('e', 'ssh', '',
104 110 _('specify ssh command to use'), _('CMD')),
105 111 ('', 'remotecmd', '',
106 112 _('specify hg command to run on the remote side'), _('CMD')),
107 113 ('', 'insecure', None,
108 114 _('do not verify server certificate (ignoring web.cacerts config)')),
109 115 ]
110 116
111 117 walkopts = [
112 118 ('I', 'include', [],
113 119 _('include names matching the given patterns'), _('PATTERN')),
114 120 ('X', 'exclude', [],
115 121 _('exclude names matching the given patterns'), _('PATTERN')),
116 122 ]
117 123
118 124 commitopts = [
119 125 ('m', 'message', '',
120 126 _('use text as commit message'), _('TEXT')),
121 127 ('l', 'logfile', '',
122 128 _('read commit message from file'), _('FILE')),
123 129 ]
124 130
125 131 commitopts2 = [
126 132 ('d', 'date', '',
127 133 _('record the specified date as commit date'), _('DATE')),
128 134 ('u', 'user', '',
129 135 _('record the specified user as committer'), _('USER')),
130 136 ]
131 137
132 138 # hidden for now
133 139 formatteropts = [
134 140 ('T', 'template', '',
135 141 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
136 142 ]
137 143
138 144 templateopts = [
139 145 ('', 'style', '',
140 146 _('display using template map file (DEPRECATED)'), _('STYLE')),
141 147 ('T', 'template', '',
142 148 _('display with template'), _('TEMPLATE')),
143 149 ]
144 150
145 151 logopts = [
146 152 ('p', 'patch', None, _('show patch')),
147 153 ('g', 'git', None, _('use git extended diff format')),
148 154 ('l', 'limit', '',
149 155 _('limit number of changes displayed'), _('NUM')),
150 156 ('M', 'no-merges', None, _('do not show merges')),
151 157 ('', 'stat', None, _('output diffstat-style summary of changes')),
152 158 ('G', 'graph', None, _("show the revision DAG")),
153 159 ] + templateopts
154 160
155 161 diffopts = [
156 162 ('a', 'text', None, _('treat all files as text')),
157 163 ('g', 'git', None, _('use git extended diff format')),
158 164 ('', 'nodates', None, _('omit dates from diff headers'))
159 165 ]
160 166
161 167 diffwsopts = [
162 168 ('w', 'ignore-all-space', None,
163 169 _('ignore white space when comparing lines')),
164 170 ('b', 'ignore-space-change', None,
165 171 _('ignore changes in the amount of white space')),
166 172 ('B', 'ignore-blank-lines', None,
167 173 _('ignore changes whose lines are all blank')),
168 174 ]
169 175
170 176 diffopts2 = [
171 177 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
172 178 ('p', 'show-function', None, _('show which function each change is in')),
173 179 ('', 'reverse', None, _('produce a diff that undoes the changes')),
174 180 ] + diffwsopts + [
175 181 ('U', 'unified', '',
176 182 _('number of lines of context to show'), _('NUM')),
177 183 ('', 'stat', None, _('output diffstat-style summary of changes')),
178 184 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
179 185 ]
180 186
181 187 mergetoolopts = [
182 188 ('t', 'tool', '', _('specify merge tool')),
183 189 ]
184 190
185 191 similarityopts = [
186 192 ('s', 'similarity', '',
187 193 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
188 194 ]
189 195
190 196 subrepoopts = [
191 197 ('S', 'subrepos', None,
192 198 _('recurse into subrepositories'))
193 199 ]
194 200
195 201 debugrevlogopts = [
196 202 ('c', 'changelog', False, _('open changelog')),
197 203 ('m', 'manifest', False, _('open manifest')),
198 204 ('', 'dir', '', _('open directory manifest')),
199 205 ]
200 206
201 207 # Commands start here, listed alphabetically
202 208
203 209 @command('^add',
204 210 walkopts + subrepoopts + dryrunopts,
205 211 _('[OPTION]... [FILE]...'),
206 212 inferrepo=True)
207 213 def add(ui, repo, *pats, **opts):
208 214 """add the specified files on the next commit
209 215
210 216 Schedule files to be version controlled and added to the
211 217 repository.
212 218
213 219 The files will be added to the repository at the next commit. To
214 220 undo an add before that, see :hg:`forget`.
215 221
216 222 If no names are given, add all files to the repository (except
217 223 files matching ``.hgignore``).
218 224
219 225 .. container:: verbose
220 226
221 227 Examples:
222 228
223 229 - New (unknown) files are added
224 230 automatically by :hg:`add`::
225 231
226 232 $ ls
227 233 foo.c
228 234 $ hg status
229 235 ? foo.c
230 236 $ hg add
231 237 adding foo.c
232 238 $ hg status
233 239 A foo.c
234 240
235 241 - Specific files to be added can be specified::
236 242
237 243 $ ls
238 244 bar.c foo.c
239 245 $ hg status
240 246 ? bar.c
241 247 ? foo.c
242 248 $ hg add bar.c
243 249 $ hg status
244 250 A bar.c
245 251 ? foo.c
246 252
247 253 Returns 0 if all files are successfully added.
248 254 """
249 255
250 256 m = scmutil.match(repo[None], pats, opts)
251 257 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
252 258 return rejected and 1 or 0
253 259
254 260 @command('addremove',
255 261 similarityopts + subrepoopts + walkopts + dryrunopts,
256 262 _('[OPTION]... [FILE]...'),
257 263 inferrepo=True)
258 264 def addremove(ui, repo, *pats, **opts):
259 265 """add all new files, delete all missing files
260 266
261 267 Add all new files and remove all missing files from the
262 268 repository.
263 269
264 270 Unless names are given, new files are ignored if they match any of
265 271 the patterns in ``.hgignore``. As with add, these changes take
266 272 effect at the next commit.
267 273
268 274 Use the -s/--similarity option to detect renamed files. This
269 275 option takes a percentage between 0 (disabled) and 100 (files must
270 276 be identical) as its parameter. With a parameter greater than 0,
271 277 this compares every removed file with every added file and records
272 278 those similar enough as renames. Detecting renamed files this way
273 279 can be expensive. After using this option, :hg:`status -C` can be
274 280 used to check which files were identified as moved or renamed. If
275 281 not specified, -s/--similarity defaults to 100 and only renames of
276 282 identical files are detected.
277 283
278 284 .. container:: verbose
279 285
280 286 Examples:
281 287
282 288 - A number of files (bar.c and foo.c) are new,
283 289 while foobar.c has been removed (without using :hg:`remove`)
284 290 from the repository::
285 291
286 292 $ ls
287 293 bar.c foo.c
288 294 $ hg status
289 295 ! foobar.c
290 296 ? bar.c
291 297 ? foo.c
292 298 $ hg addremove
293 299 adding bar.c
294 300 adding foo.c
295 301 removing foobar.c
296 302 $ hg status
297 303 A bar.c
298 304 A foo.c
299 305 R foobar.c
300 306
301 307 - A file foobar.c was moved to foo.c without using :hg:`rename`.
302 308 Afterwards, it was edited slightly::
303 309
304 310 $ ls
305 311 foo.c
306 312 $ hg status
307 313 ! foobar.c
308 314 ? foo.c
309 315 $ hg addremove --similarity 90
310 316 removing foobar.c
311 317 adding foo.c
312 318 recording removal of foobar.c as rename to foo.c (94% similar)
313 319 $ hg status -C
314 320 A foo.c
315 321 foobar.c
316 322 R foobar.c
317 323
318 324 Returns 0 if all files are successfully added.
319 325 """
320 326 try:
321 327 sim = float(opts.get('similarity') or 100)
322 328 except ValueError:
323 329 raise error.Abort(_('similarity must be a number'))
324 330 if sim < 0 or sim > 100:
325 331 raise error.Abort(_('similarity must be between 0 and 100'))
326 332 matcher = scmutil.match(repo[None], pats, opts)
327 333 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
328 334
329 335 @command('^annotate|blame',
330 336 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
331 337 ('', 'follow', None,
332 338 _('follow copies/renames and list the filename (DEPRECATED)')),
333 339 ('', 'no-follow', None, _("don't follow copies and renames")),
334 340 ('a', 'text', None, _('treat all files as text')),
335 341 ('u', 'user', None, _('list the author (long with -v)')),
336 342 ('f', 'file', None, _('list the filename')),
337 343 ('d', 'date', None, _('list the date (short with -q)')),
338 344 ('n', 'number', None, _('list the revision number (default)')),
339 345 ('c', 'changeset', None, _('list the changeset')),
340 346 ('l', 'line-number', None, _('show line number at the first appearance'))
341 347 ] + diffwsopts + walkopts + formatteropts,
342 348 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
343 349 inferrepo=True)
344 350 def annotate(ui, repo, *pats, **opts):
345 351 """show changeset information by line for each file
346 352
347 353 List changes in files, showing the revision id responsible for
348 354 each line.
349 355
350 356 This command is useful for discovering when a change was made and
351 357 by whom.
352 358
353 359 If you include --file, --user, or --date, the revision number is
354 360 suppressed unless you also include --number.
355 361
356 362 Without the -a/--text option, annotate will avoid processing files
357 363 it detects as binary. With -a, annotate will annotate the file
358 364 anyway, although the results will probably be neither useful
359 365 nor desirable.
360 366
361 367 Returns 0 on success.
362 368 """
363 369 if not pats:
364 370 raise error.Abort(_('at least one filename or pattern is required'))
365 371
366 372 if opts.get('follow'):
367 373 # --follow is deprecated and now just an alias for -f/--file
368 374 # to mimic the behavior of Mercurial before version 1.5
369 375 opts['file'] = True
370 376
371 377 ctx = scmutil.revsingle(repo, opts.get('rev'))
372 378
373 379 fm = ui.formatter('annotate', opts)
374 380 if ui.quiet:
375 381 datefunc = util.shortdate
376 382 else:
377 383 datefunc = util.datestr
378 384 if ctx.rev() is None:
379 385 def hexfn(node):
380 386 if node is None:
381 387 return None
382 388 else:
383 389 return fm.hexfunc(node)
384 390 if opts.get('changeset'):
385 391 # omit "+" suffix which is appended to node hex
386 392 def formatrev(rev):
387 393 if rev is None:
388 394 return '%d' % ctx.p1().rev()
389 395 else:
390 396 return '%d' % rev
391 397 else:
392 398 def formatrev(rev):
393 399 if rev is None:
394 400 return '%d+' % ctx.p1().rev()
395 401 else:
396 402 return '%d ' % rev
397 403 def formathex(hex):
398 404 if hex is None:
399 405 return '%s+' % fm.hexfunc(ctx.p1().node())
400 406 else:
401 407 return '%s ' % hex
402 408 else:
403 409 hexfn = fm.hexfunc
404 410 formatrev = formathex = str
405 411
406 412 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
407 413 ('number', ' ', lambda x: x[0].rev(), formatrev),
408 414 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
409 415 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
410 416 ('file', ' ', lambda x: x[0].path(), str),
411 417 ('line_number', ':', lambda x: x[1], str),
412 418 ]
413 419 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
414 420
415 421 if (not opts.get('user') and not opts.get('changeset')
416 422 and not opts.get('date') and not opts.get('file')):
417 423 opts['number'] = True
418 424
419 425 linenumber = opts.get('line_number') is not None
420 426 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
421 427 raise error.Abort(_('at least one of -n/-c is required for -l'))
422 428
423 429 ui.pager('annotate')
424 430
425 431 if fm.isplain():
426 432 def makefunc(get, fmt):
427 433 return lambda x: fmt(get(x))
428 434 else:
429 435 def makefunc(get, fmt):
430 436 return get
431 437 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
432 438 if opts.get(op)]
433 439 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
434 440 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
435 441 if opts.get(op))
436 442
437 443 def bad(x, y):
438 444 raise error.Abort("%s: %s" % (x, y))
439 445
440 446 m = scmutil.match(ctx, pats, opts, badfn=bad)
441 447
442 448 follow = not opts.get('no_follow')
443 449 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
444 450 whitespace=True)
445 451 for abs in ctx.walk(m):
446 452 fctx = ctx[abs]
447 453 if not opts.get('text') and util.binary(fctx.data()):
448 454 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
449 455 continue
450 456
451 457 lines = fctx.annotate(follow=follow, linenumber=linenumber,
452 458 diffopts=diffopts)
453 459 if not lines:
454 460 continue
455 461 formats = []
456 462 pieces = []
457 463
458 464 for f, sep in funcmap:
459 465 l = [f(n) for n, dummy in lines]
460 466 if fm.isplain():
461 467 sizes = [encoding.colwidth(x) for x in l]
462 468 ml = max(sizes)
463 469 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
464 470 else:
465 471 formats.append(['%s' for x in l])
466 472 pieces.append(l)
467 473
468 474 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
469 475 fm.startitem()
470 476 fm.write(fields, "".join(f), *p)
471 477 fm.write('line', ": %s", l[1])
472 478
473 479 if not lines[-1][1].endswith('\n'):
474 480 fm.plain('\n')
475 481
476 482 fm.end()
477 483
478 484 @command('archive',
479 485 [('', 'no-decode', None, _('do not pass files through decoders')),
480 486 ('p', 'prefix', '', _('directory prefix for files in archive'),
481 487 _('PREFIX')),
482 488 ('r', 'rev', '', _('revision to distribute'), _('REV')),
483 489 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
484 490 ] + subrepoopts + walkopts,
485 491 _('[OPTION]... DEST'))
486 492 def archive(ui, repo, dest, **opts):
487 493 '''create an unversioned archive of a repository revision
488 494
489 495 By default, the revision used is the parent of the working
490 496 directory; use -r/--rev to specify a different revision.
491 497
492 498 The archive type is automatically detected based on file
493 499 extension (to override, use -t/--type).
494 500
495 501 .. container:: verbose
496 502
497 503 Examples:
498 504
499 505 - create a zip file containing the 1.0 release::
500 506
501 507 hg archive -r 1.0 project-1.0.zip
502 508
503 509 - create a tarball excluding .hg files::
504 510
505 511 hg archive project.tar.gz -X ".hg*"
506 512
507 513 Valid types are:
508 514
509 515 :``files``: a directory full of files (default)
510 516 :``tar``: tar archive, uncompressed
511 517 :``tbz2``: tar archive, compressed using bzip2
512 518 :``tgz``: tar archive, compressed using gzip
513 519 :``uzip``: zip archive, uncompressed
514 520 :``zip``: zip archive, compressed using deflate
515 521
516 522 The exact name of the destination archive or directory is given
517 523 using a format string; see :hg:`help export` for details.
518 524
519 525 Each member added to an archive file has a directory prefix
520 526 prepended. Use -p/--prefix to specify a format string for the
521 527 prefix. The default is the basename of the archive, with suffixes
522 528 removed.
523 529
524 530 Returns 0 on success.
525 531 '''
526 532
527 533 ctx = scmutil.revsingle(repo, opts.get('rev'))
528 534 if not ctx:
529 535 raise error.Abort(_('no working directory: please specify a revision'))
530 536 node = ctx.node()
531 537 dest = cmdutil.makefilename(repo, dest, node)
532 538 if os.path.realpath(dest) == repo.root:
533 539 raise error.Abort(_('repository root cannot be destination'))
534 540
535 541 kind = opts.get('type') or archival.guesskind(dest) or 'files'
536 542 prefix = opts.get('prefix')
537 543
538 544 if dest == '-':
539 545 if kind == 'files':
540 546 raise error.Abort(_('cannot archive plain files to stdout'))
541 547 dest = cmdutil.makefileobj(repo, dest)
542 548 if not prefix:
543 549 prefix = os.path.basename(repo.root) + '-%h'
544 550
545 551 prefix = cmdutil.makefilename(repo, prefix, node)
546 552 matchfn = scmutil.match(ctx, [], opts)
547 553 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
548 554 matchfn, prefix, subrepos=opts.get('subrepos'))
549 555
550 556 @command('backout',
551 557 [('', 'merge', None, _('merge with old dirstate parent after backout')),
552 558 ('', 'commit', None,
553 559 _('commit if no conflicts were encountered (DEPRECATED)')),
554 560 ('', 'no-commit', None, _('do not commit')),
555 561 ('', 'parent', '',
556 562 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
557 563 ('r', 'rev', '', _('revision to backout'), _('REV')),
558 564 ('e', 'edit', False, _('invoke editor on commit messages')),
559 565 ] + mergetoolopts + walkopts + commitopts + commitopts2,
560 566 _('[OPTION]... [-r] REV'))
561 567 def backout(ui, repo, node=None, rev=None, **opts):
562 568 '''reverse effect of earlier changeset
563 569
564 570 Prepare a new changeset with the effect of REV undone in the
565 571 current working directory. If no conflicts were encountered,
566 572 it will be committed immediately.
567 573
568 574 If REV is the parent of the working directory, then this new changeset
569 575 is committed automatically (unless --no-commit is specified).
570 576
571 577 .. note::
572 578
573 579 :hg:`backout` cannot be used to fix either an unwanted or
574 580 incorrect merge.
575 581
576 582 .. container:: verbose
577 583
578 584 Examples:
579 585
580 586 - Reverse the effect of the parent of the working directory.
581 587 This backout will be committed immediately::
582 588
583 589 hg backout -r .
584 590
585 591 - Reverse the effect of previous bad revision 23::
586 592
587 593 hg backout -r 23
588 594
589 595 - Reverse the effect of previous bad revision 23 and
590 596 leave changes uncommitted::
591 597
592 598 hg backout -r 23 --no-commit
593 599 hg commit -m "Backout revision 23"
594 600
595 601 By default, the pending changeset will have one parent,
596 602 maintaining a linear history. With --merge, the pending
597 603 changeset will instead have two parents: the old parent of the
598 604 working directory and a new child of REV that simply undoes REV.
599 605
600 606 Before version 1.7, the behavior without --merge was equivalent
601 607 to specifying --merge followed by :hg:`update --clean .` to
602 608 cancel the merge and leave the child of REV as a head to be
603 609 merged separately.
604 610
605 611 See :hg:`help dates` for a list of formats valid for -d/--date.
606 612
607 613 See :hg:`help revert` for a way to restore files to the state
608 614 of another revision.
609 615
610 616 Returns 0 on success, 1 if nothing to backout or there are unresolved
611 617 files.
612 618 '''
613 619 wlock = lock = None
614 620 try:
615 621 wlock = repo.wlock()
616 622 lock = repo.lock()
617 623 return _dobackout(ui, repo, node, rev, **opts)
618 624 finally:
619 625 release(lock, wlock)
620 626
621 627 def _dobackout(ui, repo, node=None, rev=None, **opts):
622 628 if opts.get('commit') and opts.get('no_commit'):
623 629 raise error.Abort(_("cannot use --commit with --no-commit"))
624 630 if opts.get('merge') and opts.get('no_commit'):
625 631 raise error.Abort(_("cannot use --merge with --no-commit"))
626 632
627 633 if rev and node:
628 634 raise error.Abort(_("please specify just one revision"))
629 635
630 636 if not rev:
631 637 rev = node
632 638
633 639 if not rev:
634 640 raise error.Abort(_("please specify a revision to backout"))
635 641
636 642 date = opts.get('date')
637 643 if date:
638 644 opts['date'] = util.parsedate(date)
639 645
640 646 cmdutil.checkunfinished(repo)
641 647 cmdutil.bailifchanged(repo)
642 648 node = scmutil.revsingle(repo, rev).node()
643 649
644 650 op1, op2 = repo.dirstate.parents()
645 651 if not repo.changelog.isancestor(node, op1):
646 652 raise error.Abort(_('cannot backout change that is not an ancestor'))
647 653
648 654 p1, p2 = repo.changelog.parents(node)
649 655 if p1 == nullid:
650 656 raise error.Abort(_('cannot backout a change with no parents'))
651 657 if p2 != nullid:
652 658 if not opts.get('parent'):
653 659 raise error.Abort(_('cannot backout a merge changeset'))
654 660 p = repo.lookup(opts['parent'])
655 661 if p not in (p1, p2):
656 662 raise error.Abort(_('%s is not a parent of %s') %
657 663 (short(p), short(node)))
658 664 parent = p
659 665 else:
660 666 if opts.get('parent'):
661 667 raise error.Abort(_('cannot use --parent on non-merge changeset'))
662 668 parent = p1
663 669
664 670 # the backout should appear on the same branch
665 671 branch = repo.dirstate.branch()
666 672 bheads = repo.branchheads(branch)
667 673 rctx = scmutil.revsingle(repo, hex(parent))
668 674 if not opts.get('merge') and op1 != node:
669 675 dsguard = dirstateguard.dirstateguard(repo, 'backout')
670 676 try:
671 677 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
672 678 'backout')
673 679 stats = mergemod.update(repo, parent, True, True, node, False)
674 680 repo.setparents(op1, op2)
675 681 dsguard.close()
676 682 hg._showstats(repo, stats)
677 683 if stats[3]:
678 684 repo.ui.status(_("use 'hg resolve' to retry unresolved "
679 685 "file merges\n"))
680 686 return 1
681 687 finally:
682 688 ui.setconfig('ui', 'forcemerge', '', '')
683 689 lockmod.release(dsguard)
684 690 else:
685 691 hg.clean(repo, node, show_stats=False)
686 692 repo.dirstate.setbranch(branch)
687 693 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
688 694
689 695 if opts.get('no_commit'):
690 696 msg = _("changeset %s backed out, "
691 697 "don't forget to commit.\n")
692 698 ui.status(msg % short(node))
693 699 return 0
694 700
695 701 def commitfunc(ui, repo, message, match, opts):
696 702 editform = 'backout'
697 703 e = cmdutil.getcommiteditor(editform=editform, **opts)
698 704 if not message:
699 705 # we don't translate commit messages
700 706 message = "Backed out changeset %s" % short(node)
701 707 e = cmdutil.getcommiteditor(edit=True, editform=editform)
702 708 return repo.commit(message, opts.get('user'), opts.get('date'),
703 709 match, editor=e)
704 710 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
705 711 if not newnode:
706 712 ui.status(_("nothing changed\n"))
707 713 return 1
708 714 cmdutil.commitstatus(repo, newnode, branch, bheads)
709 715
710 716 def nice(node):
711 717 return '%d:%s' % (repo.changelog.rev(node), short(node))
712 718 ui.status(_('changeset %s backs out changeset %s\n') %
713 719 (nice(repo.changelog.tip()), nice(node)))
714 720 if opts.get('merge') and op1 != node:
715 721 hg.clean(repo, op1, show_stats=False)
716 722 ui.status(_('merging with changeset %s\n')
717 723 % nice(repo.changelog.tip()))
718 724 try:
719 725 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
720 726 'backout')
721 727 return hg.merge(repo, hex(repo.changelog.tip()))
722 728 finally:
723 729 ui.setconfig('ui', 'forcemerge', '', '')
724 730 return 0
725 731
726 732 @command('bisect',
727 733 [('r', 'reset', False, _('reset bisect state')),
728 734 ('g', 'good', False, _('mark changeset good')),
729 735 ('b', 'bad', False, _('mark changeset bad')),
730 736 ('s', 'skip', False, _('skip testing changeset')),
731 737 ('e', 'extend', False, _('extend the bisect range')),
732 738 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
733 739 ('U', 'noupdate', False, _('do not update to target'))],
734 740 _("[-gbsr] [-U] [-c CMD] [REV]"))
735 741 def bisect(ui, repo, rev=None, extra=None, command=None,
736 742 reset=None, good=None, bad=None, skip=None, extend=None,
737 743 noupdate=None):
738 744 """subdivision search of changesets
739 745
740 746 This command helps to find changesets which introduce problems. To
741 747 use, mark the earliest changeset you know exhibits the problem as
742 748 bad, then mark the latest changeset which is free from the problem
743 749 as good. Bisect will update your working directory to a revision
744 750 for testing (unless the -U/--noupdate option is specified). Once
745 751 you have performed tests, mark the working directory as good or
746 752 bad, and bisect will either update to another candidate changeset
747 753 or announce that it has found the bad revision.
748 754
749 755 As a shortcut, you can also use the revision argument to mark a
750 756 revision as good or bad without checking it out first.
751 757
752 758 If you supply a command, it will be used for automatic bisection.
753 759 The environment variable HG_NODE will contain the ID of the
754 760 changeset being tested. The exit status of the command will be
755 761 used to mark revisions as good or bad: status 0 means good, 125
756 762 means to skip the revision, 127 (command not found) will abort the
757 763 bisection, and any other non-zero exit status means the revision
758 764 is bad.
759 765
760 766 .. container:: verbose
761 767
762 768 Some examples:
763 769
764 770 - start a bisection with known bad revision 34, and good revision 12::
765 771
766 772 hg bisect --bad 34
767 773 hg bisect --good 12
768 774
769 775 - advance the current bisection by marking current revision as good or
770 776 bad::
771 777
772 778 hg bisect --good
773 779 hg bisect --bad
774 780
775 781 - mark the current revision, or a known revision, to be skipped (e.g. if
776 782 that revision is not usable because of another issue)::
777 783
778 784 hg bisect --skip
779 785 hg bisect --skip 23
780 786
781 787 - skip all revisions that do not touch directories ``foo`` or ``bar``::
782 788
783 789 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
784 790
785 791 - forget the current bisection::
786 792
787 793 hg bisect --reset
788 794
789 795 - use 'make && make tests' to automatically find the first broken
790 796 revision::
791 797
792 798 hg bisect --reset
793 799 hg bisect --bad 34
794 800 hg bisect --good 12
795 801 hg bisect --command "make && make tests"
796 802
797 803 - see all changesets whose states are already known in the current
798 804 bisection::
799 805
800 806 hg log -r "bisect(pruned)"
801 807
802 808 - see the changeset currently being bisected (especially useful
803 809 if running with -U/--noupdate)::
804 810
805 811 hg log -r "bisect(current)"
806 812
807 813 - see all changesets that took part in the current bisection::
808 814
809 815 hg log -r "bisect(range)"
810 816
811 817 - you can even get a nice graph::
812 818
813 819 hg log --graph -r "bisect(range)"
814 820
815 821 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
816 822
817 823 Returns 0 on success.
818 824 """
819 825 # backward compatibility
820 826 if rev in "good bad reset init".split():
821 827 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
822 828 cmd, rev, extra = rev, extra, None
823 829 if cmd == "good":
824 830 good = True
825 831 elif cmd == "bad":
826 832 bad = True
827 833 else:
828 834 reset = True
829 835 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
830 836 raise error.Abort(_('incompatible arguments'))
831 837
832 838 cmdutil.checkunfinished(repo)
833 839
834 840 if reset:
835 841 hbisect.resetstate(repo)
836 842 return
837 843
838 844 state = hbisect.load_state(repo)
839 845
840 846 # update state
841 847 if good or bad or skip:
842 848 if rev:
843 849 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
844 850 else:
845 851 nodes = [repo.lookup('.')]
846 852 if good:
847 853 state['good'] += nodes
848 854 elif bad:
849 855 state['bad'] += nodes
850 856 elif skip:
851 857 state['skip'] += nodes
852 858 hbisect.save_state(repo, state)
853 859 if not (state['good'] and state['bad']):
854 860 return
855 861
856 862 def mayupdate(repo, node, show_stats=True):
857 863 """common used update sequence"""
858 864 if noupdate:
859 865 return
860 866 cmdutil.bailifchanged(repo)
861 867 return hg.clean(repo, node, show_stats=show_stats)
862 868
863 869 displayer = cmdutil.show_changeset(ui, repo, {})
864 870
865 871 if command:
866 872 changesets = 1
867 873 if noupdate:
868 874 try:
869 875 node = state['current'][0]
870 876 except LookupError:
871 877 raise error.Abort(_('current bisect revision is unknown - '
872 878 'start a new bisect to fix'))
873 879 else:
874 880 node, p2 = repo.dirstate.parents()
875 881 if p2 != nullid:
876 882 raise error.Abort(_('current bisect revision is a merge'))
877 883 if rev:
878 884 node = repo[scmutil.revsingle(repo, rev, node)].node()
879 885 try:
880 886 while changesets:
881 887 # update state
882 888 state['current'] = [node]
883 889 hbisect.save_state(repo, state)
884 890 status = ui.system(command, environ={'HG_NODE': hex(node)})
885 891 if status == 125:
886 892 transition = "skip"
887 893 elif status == 0:
888 894 transition = "good"
889 895 # status < 0 means process was killed
890 896 elif status == 127:
891 897 raise error.Abort(_("failed to execute %s") % command)
892 898 elif status < 0:
893 899 raise error.Abort(_("%s killed") % command)
894 900 else:
895 901 transition = "bad"
896 902 state[transition].append(node)
897 903 ctx = repo[node]
898 904 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
899 905 hbisect.checkstate(state)
900 906 # bisect
901 907 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
902 908 # update to next check
903 909 node = nodes[0]
904 910 mayupdate(repo, node, show_stats=False)
905 911 finally:
906 912 state['current'] = [node]
907 913 hbisect.save_state(repo, state)
908 914 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
909 915 return
910 916
911 917 hbisect.checkstate(state)
912 918
913 919 # actually bisect
914 920 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
915 921 if extend:
916 922 if not changesets:
917 923 extendnode = hbisect.extendrange(repo, state, nodes, good)
918 924 if extendnode is not None:
919 925 ui.write(_("Extending search to changeset %d:%s\n")
920 926 % (extendnode.rev(), extendnode))
921 927 state['current'] = [extendnode.node()]
922 928 hbisect.save_state(repo, state)
923 929 return mayupdate(repo, extendnode.node())
924 930 raise error.Abort(_("nothing to extend"))
925 931
926 932 if changesets == 0:
927 933 hbisect.printresult(ui, repo, state, displayer, nodes, good)
928 934 else:
929 935 assert len(nodes) == 1 # only a single node can be tested next
930 936 node = nodes[0]
931 937 # compute the approximate number of remaining tests
932 938 tests, size = 0, 2
933 939 while size <= changesets:
934 940 tests, size = tests + 1, size * 2
935 941 rev = repo.changelog.rev(node)
936 942 ui.write(_("Testing changeset %d:%s "
937 943 "(%d changesets remaining, ~%d tests)\n")
938 944 % (rev, short(node), changesets, tests))
939 945 state['current'] = [node]
940 946 hbisect.save_state(repo, state)
941 947 return mayupdate(repo, node)
942 948
943 949 @command('bookmarks|bookmark',
944 950 [('f', 'force', False, _('force')),
945 951 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
946 952 ('d', 'delete', False, _('delete a given bookmark')),
947 953 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
948 954 ('i', 'inactive', False, _('mark a bookmark inactive')),
949 955 ] + formatteropts,
950 956 _('hg bookmarks [OPTIONS]... [NAME]...'))
951 957 def bookmark(ui, repo, *names, **opts):
952 958 '''create a new bookmark or list existing bookmarks
953 959
954 960 Bookmarks are labels on changesets to help track lines of development.
955 961 Bookmarks are unversioned and can be moved, renamed and deleted.
956 962 Deleting or moving a bookmark has no effect on the associated changesets.
957 963
958 964 Creating or updating to a bookmark causes it to be marked as 'active'.
959 965 The active bookmark is indicated with a '*'.
960 966 When a commit is made, the active bookmark will advance to the new commit.
961 967 A plain :hg:`update` will also advance an active bookmark, if possible.
962 968 Updating away from a bookmark will cause it to be deactivated.
963 969
964 970 Bookmarks can be pushed and pulled between repositories (see
965 971 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
966 972 diverged, a new 'divergent bookmark' of the form 'name@path' will
967 973 be created. Using :hg:`merge` will resolve the divergence.
968 974
969 975 A bookmark named '@' has the special property that :hg:`clone` will
970 976 check it out by default if it exists.
971 977
972 978 .. container:: verbose
973 979
974 980 Examples:
975 981
976 982 - create an active bookmark for a new line of development::
977 983
978 984 hg book new-feature
979 985
980 986 - create an inactive bookmark as a place marker::
981 987
982 988 hg book -i reviewed
983 989
984 990 - create an inactive bookmark on another changeset::
985 991
986 992 hg book -r .^ tested
987 993
988 994 - rename bookmark turkey to dinner::
989 995
990 996 hg book -m turkey dinner
991 997
992 998 - move the '@' bookmark from another branch::
993 999
994 1000 hg book -f @
995 1001 '''
996 1002 force = opts.get('force')
997 1003 rev = opts.get('rev')
998 1004 delete = opts.get('delete')
999 1005 rename = opts.get('rename')
1000 1006 inactive = opts.get('inactive')
1001 1007
1002 1008 def checkformat(mark):
1003 1009 mark = mark.strip()
1004 1010 if not mark:
1005 1011 raise error.Abort(_("bookmark names cannot consist entirely of "
1006 1012 "whitespace"))
1007 1013 scmutil.checknewlabel(repo, mark, 'bookmark')
1008 1014 return mark
1009 1015
1010 1016 def checkconflict(repo, mark, cur, force=False, target=None):
1011 1017 if mark in marks and not force:
1012 1018 if target:
1013 1019 if marks[mark] == target and target == cur:
1014 1020 # re-activating a bookmark
1015 1021 return
1016 1022 anc = repo.changelog.ancestors([repo[target].rev()])
1017 1023 bmctx = repo[marks[mark]]
1018 1024 divs = [repo[b].node() for b in marks
1019 1025 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
1020 1026
1021 1027 # allow resolving a single divergent bookmark even if moving
1022 1028 # the bookmark across branches when a revision is specified
1023 1029 # that contains a divergent bookmark
1024 1030 if bmctx.rev() not in anc and target in divs:
1025 1031 bookmarks.deletedivergent(repo, [target], mark)
1026 1032 return
1027 1033
1028 1034 deletefrom = [b for b in divs
1029 1035 if repo[b].rev() in anc or b == target]
1030 1036 bookmarks.deletedivergent(repo, deletefrom, mark)
1031 1037 if bookmarks.validdest(repo, bmctx, repo[target]):
1032 1038 ui.status(_("moving bookmark '%s' forward from %s\n") %
1033 1039 (mark, short(bmctx.node())))
1034 1040 return
1035 1041 raise error.Abort(_("bookmark '%s' already exists "
1036 1042 "(use -f to force)") % mark)
1037 1043 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
1038 1044 and not force):
1039 1045 raise error.Abort(
1040 1046 _("a bookmark cannot have the name of an existing branch"))
1041 1047
1042 1048 if delete and rename:
1043 1049 raise error.Abort(_("--delete and --rename are incompatible"))
1044 1050 if delete and rev:
1045 1051 raise error.Abort(_("--rev is incompatible with --delete"))
1046 1052 if rename and rev:
1047 1053 raise error.Abort(_("--rev is incompatible with --rename"))
1048 1054 if not names and (delete or rev):
1049 1055 raise error.Abort(_("bookmark name required"))
1050 1056
1051 1057 if delete or rename or names or inactive:
1052 1058 wlock = lock = tr = None
1053 1059 try:
1054 1060 wlock = repo.wlock()
1055 1061 lock = repo.lock()
1056 1062 cur = repo.changectx('.').node()
1057 1063 marks = repo._bookmarks
1058 1064 if delete:
1059 1065 tr = repo.transaction('bookmark')
1060 1066 for mark in names:
1061 1067 if mark not in marks:
1062 1068 raise error.Abort(_("bookmark '%s' does not exist") %
1063 1069 mark)
1064 1070 if mark == repo._activebookmark:
1065 1071 bookmarks.deactivate(repo)
1066 1072 del marks[mark]
1067 1073
1068 1074 elif rename:
1069 1075 tr = repo.transaction('bookmark')
1070 1076 if not names:
1071 1077 raise error.Abort(_("new bookmark name required"))
1072 1078 elif len(names) > 1:
1073 1079 raise error.Abort(_("only one new bookmark name allowed"))
1074 1080 mark = checkformat(names[0])
1075 1081 if rename not in marks:
1076 1082 raise error.Abort(_("bookmark '%s' does not exist")
1077 1083 % rename)
1078 1084 checkconflict(repo, mark, cur, force)
1079 1085 marks[mark] = marks[rename]
1080 1086 if repo._activebookmark == rename and not inactive:
1081 1087 bookmarks.activate(repo, mark)
1082 1088 del marks[rename]
1083 1089 elif names:
1084 1090 tr = repo.transaction('bookmark')
1085 1091 newact = None
1086 1092 for mark in names:
1087 1093 mark = checkformat(mark)
1088 1094 if newact is None:
1089 1095 newact = mark
1090 1096 if inactive and mark == repo._activebookmark:
1091 1097 bookmarks.deactivate(repo)
1092 1098 return
1093 1099 tgt = cur
1094 1100 if rev:
1095 1101 tgt = scmutil.revsingle(repo, rev).node()
1096 1102 checkconflict(repo, mark, cur, force, tgt)
1097 1103 marks[mark] = tgt
1098 1104 if not inactive and cur == marks[newact] and not rev:
1099 1105 bookmarks.activate(repo, newact)
1100 1106 elif cur != tgt and newact == repo._activebookmark:
1101 1107 bookmarks.deactivate(repo)
1102 1108 elif inactive:
1103 1109 if len(marks) == 0:
1104 1110 ui.status(_("no bookmarks set\n"))
1105 1111 elif not repo._activebookmark:
1106 1112 ui.status(_("no active bookmark\n"))
1107 1113 else:
1108 1114 bookmarks.deactivate(repo)
1109 1115 if tr is not None:
1110 1116 marks.recordchange(tr)
1111 1117 tr.close()
1112 1118 finally:
1113 1119 lockmod.release(tr, lock, wlock)
1114 1120 else: # show bookmarks
1115 1121 fm = ui.formatter('bookmarks', opts)
1116 1122 hexfn = fm.hexfunc
1117 1123 marks = repo._bookmarks
1118 1124 if len(marks) == 0 and fm.isplain():
1119 1125 ui.status(_("no bookmarks set\n"))
1120 1126 for bmark, n in sorted(marks.iteritems()):
1121 1127 active = repo._activebookmark
1122 1128 if bmark == active:
1123 1129 prefix, label = '*', activebookmarklabel
1124 1130 else:
1125 1131 prefix, label = ' ', ''
1126 1132
1127 1133 fm.startitem()
1128 1134 if not ui.quiet:
1129 1135 fm.plain(' %s ' % prefix, label=label)
1130 1136 fm.write('bookmark', '%s', bmark, label=label)
1131 1137 pad = " " * (25 - encoding.colwidth(bmark))
1132 1138 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1133 1139 repo.changelog.rev(n), hexfn(n), label=label)
1134 1140 fm.data(active=(bmark == active))
1135 1141 fm.plain('\n')
1136 1142 fm.end()
1137 1143
1138 1144 @command('branch',
1139 1145 [('f', 'force', None,
1140 1146 _('set branch name even if it shadows an existing branch')),
1141 1147 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1142 1148 _('[-fC] [NAME]'))
1143 1149 def branch(ui, repo, label=None, **opts):
1144 1150 """set or show the current branch name
1145 1151
1146 1152 .. note::
1147 1153
1148 1154 Branch names are permanent and global. Use :hg:`bookmark` to create a
1149 1155 light-weight bookmark instead. See :hg:`help glossary` for more
1150 1156 information about named branches and bookmarks.
1151 1157
1152 1158 With no argument, show the current branch name. With one argument,
1153 1159 set the working directory branch name (the branch will not exist
1154 1160 in the repository until the next commit). Standard practice
1155 1161 recommends that primary development take place on the 'default'
1156 1162 branch.
1157 1163
1158 1164 Unless -f/--force is specified, branch will not let you set a
1159 1165 branch name that already exists.
1160 1166
1161 1167 Use -C/--clean to reset the working directory branch to that of
1162 1168 the parent of the working directory, negating a previous branch
1163 1169 change.
1164 1170
1165 1171 Use the command :hg:`update` to switch to an existing branch. Use
1166 1172 :hg:`commit --close-branch` to mark this branch head as closed.
1167 1173 When all heads of a branch are closed, the branch will be
1168 1174 considered closed.
1169 1175
1170 1176 Returns 0 on success.
1171 1177 """
1172 1178 if label:
1173 1179 label = label.strip()
1174 1180
1175 1181 if not opts.get('clean') and not label:
1176 1182 ui.write("%s\n" % repo.dirstate.branch())
1177 1183 return
1178 1184
1179 1185 with repo.wlock():
1180 1186 if opts.get('clean'):
1181 1187 label = repo[None].p1().branch()
1182 1188 repo.dirstate.setbranch(label)
1183 1189 ui.status(_('reset working directory to branch %s\n') % label)
1184 1190 elif label:
1185 1191 if not opts.get('force') and label in repo.branchmap():
1186 1192 if label not in [p.branch() for p in repo[None].parents()]:
1187 1193 raise error.Abort(_('a branch of the same name already'
1188 1194 ' exists'),
1189 1195 # i18n: "it" refers to an existing branch
1190 1196 hint=_("use 'hg update' to switch to it"))
1191 1197 scmutil.checknewlabel(repo, label, 'branch')
1192 1198 repo.dirstate.setbranch(label)
1193 1199 ui.status(_('marked working directory as branch %s\n') % label)
1194 1200
1195 1201 # find any open named branches aside from default
1196 1202 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1197 1203 if n != "default" and not c]
1198 1204 if not others:
1199 1205 ui.status(_('(branches are permanent and global, '
1200 1206 'did you want a bookmark?)\n'))
1201 1207
1202 1208 @command('branches',
1203 1209 [('a', 'active', False,
1204 1210 _('show only branches that have unmerged heads (DEPRECATED)')),
1205 1211 ('c', 'closed', False, _('show normal and closed branches')),
1206 1212 ] + formatteropts,
1207 1213 _('[-c]'))
1208 1214 def branches(ui, repo, active=False, closed=False, **opts):
1209 1215 """list repository named branches
1210 1216
1211 1217 List the repository's named branches, indicating which ones are
1212 1218 inactive. If -c/--closed is specified, also list branches which have
1213 1219 been marked closed (see :hg:`commit --close-branch`).
1214 1220
1215 1221 Use the command :hg:`update` to switch to an existing branch.
1216 1222
1217 1223 Returns 0.
1218 1224 """
1219 1225
1220 1226 fm = ui.formatter('branches', opts)
1221 1227 hexfunc = fm.hexfunc
1222 1228
1223 1229 allheads = set(repo.heads())
1224 1230 branches = []
1225 1231 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1226 1232 isactive = not isclosed and bool(set(heads) & allheads)
1227 1233 branches.append((tag, repo[tip], isactive, not isclosed))
1228 1234 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1229 1235 reverse=True)
1230 1236
1231 1237 for tag, ctx, isactive, isopen in branches:
1232 1238 if active and not isactive:
1233 1239 continue
1234 1240 if isactive:
1235 1241 label = 'branches.active'
1236 1242 notice = ''
1237 1243 elif not isopen:
1238 1244 if not closed:
1239 1245 continue
1240 1246 label = 'branches.closed'
1241 1247 notice = _(' (closed)')
1242 1248 else:
1243 1249 label = 'branches.inactive'
1244 1250 notice = _(' (inactive)')
1245 1251 current = (tag == repo.dirstate.branch())
1246 1252 if current:
1247 1253 label = 'branches.current'
1248 1254
1249 1255 fm.startitem()
1250 1256 fm.write('branch', '%s', tag, label=label)
1251 1257 rev = ctx.rev()
1252 1258 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1253 1259 fmt = ' ' * padsize + ' %d:%s'
1254 1260 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1255 1261 label='log.changeset changeset.%s' % ctx.phasestr())
1256 1262 fm.data(active=isactive, closed=not isopen, current=current)
1257 1263 if not ui.quiet:
1258 1264 fm.plain(notice)
1259 1265 fm.plain('\n')
1260 1266 fm.end()
1261 1267
1262 1268 @command('bundle',
1263 1269 [('f', 'force', None, _('run even when the destination is unrelated')),
1264 1270 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1265 1271 _('REV')),
1266 1272 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1267 1273 _('BRANCH')),
1268 1274 ('', 'base', [],
1269 1275 _('a base changeset assumed to be available at the destination'),
1270 1276 _('REV')),
1271 1277 ('a', 'all', None, _('bundle all changesets in the repository')),
1272 1278 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1273 1279 ] + remoteopts,
1274 1280 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1275 1281 def bundle(ui, repo, fname, dest=None, **opts):
1276 1282 """create a changegroup file
1277 1283
1278 1284 Generate a changegroup file collecting changesets to be added
1279 1285 to a repository.
1280 1286
1281 1287 To create a bundle containing all changesets, use -a/--all
1282 1288 (or --base null). Otherwise, hg assumes the destination will have
1283 1289 all the nodes you specify with --base parameters. Otherwise, hg
1284 1290 will assume the repository has all the nodes in destination, or
1285 1291 default-push/default if no destination is specified.
1286 1292
1287 1293 You can change bundle format with the -t/--type option. You can
1288 1294 specify a compression, a bundle version or both using a dash
1289 1295 (comp-version). The available compression methods are: none, bzip2,
1290 1296 and gzip (by default, bundles are compressed using bzip2). The
1291 1297 available formats are: v1, v2 (default to most suitable).
1292 1298
1293 1299 The bundle file can then be transferred using conventional means
1294 1300 and applied to another repository with the unbundle or pull
1295 1301 command. This is useful when direct push and pull are not
1296 1302 available or when exporting an entire repository is undesirable.
1297 1303
1298 1304 Applying bundles preserves all changeset contents including
1299 1305 permissions, copy/rename information, and revision history.
1300 1306
1301 1307 Returns 0 on success, 1 if no changes found.
1302 1308 """
1303 1309 revs = None
1304 1310 if 'rev' in opts:
1305 1311 revstrings = opts['rev']
1306 1312 revs = scmutil.revrange(repo, revstrings)
1307 1313 if revstrings and not revs:
1308 1314 raise error.Abort(_('no commits to bundle'))
1309 1315
1310 1316 bundletype = opts.get('type', 'bzip2').lower()
1311 1317 try:
1312 1318 bcompression, cgversion, params = exchange.parsebundlespec(
1313 1319 repo, bundletype, strict=False)
1314 1320 except error.UnsupportedBundleSpecification as e:
1315 1321 raise error.Abort(str(e),
1316 1322 hint=_("see 'hg help bundle' for supported "
1317 1323 "values for --type"))
1318 1324
1319 1325 # Packed bundles are a pseudo bundle format for now.
1320 1326 if cgversion == 's1':
1321 1327 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1322 1328 hint=_("use 'hg debugcreatestreamclonebundle'"))
1323 1329
1324 1330 if opts.get('all'):
1325 1331 if dest:
1326 1332 raise error.Abort(_("--all is incompatible with specifying "
1327 1333 "a destination"))
1328 1334 if opts.get('base'):
1329 1335 ui.warn(_("ignoring --base because --all was specified\n"))
1330 1336 base = ['null']
1331 1337 else:
1332 1338 base = scmutil.revrange(repo, opts.get('base'))
1333 1339 # TODO: get desired bundlecaps from command line.
1334 1340 bundlecaps = None
1335 1341 if cgversion not in changegroup.supportedoutgoingversions(repo):
1336 1342 raise error.Abort(_("repository does not support bundle version %s") %
1337 1343 cgversion)
1338 1344
1339 1345 if base:
1340 1346 if dest:
1341 1347 raise error.Abort(_("--base is incompatible with specifying "
1342 1348 "a destination"))
1343 1349 common = [repo.lookup(rev) for rev in base]
1344 1350 heads = revs and map(repo.lookup, revs) or None
1345 1351 outgoing = discovery.outgoing(repo, common, heads)
1346 1352 cg = changegroup.getchangegroup(repo, 'bundle', outgoing,
1347 1353 bundlecaps=bundlecaps,
1348 1354 version=cgversion)
1349 1355 outgoing = None
1350 1356 else:
1351 1357 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1352 1358 dest, branches = hg.parseurl(dest, opts.get('branch'))
1353 1359 other = hg.peer(repo, opts, dest)
1354 1360 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1355 1361 heads = revs and map(repo.lookup, revs) or revs
1356 1362 outgoing = discovery.findcommonoutgoing(repo, other,
1357 1363 onlyheads=heads,
1358 1364 force=opts.get('force'),
1359 1365 portable=True)
1360 1366 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1361 1367 bundlecaps, version=cgversion)
1362 1368 if not cg:
1363 1369 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1364 1370 return 1
1365 1371
1366 1372 if cgversion == '01': #bundle1
1367 1373 if bcompression is None:
1368 1374 bcompression = 'UN'
1369 1375 bversion = 'HG10' + bcompression
1370 1376 bcompression = None
1371 1377 else:
1372 1378 assert cgversion == '02'
1373 1379 bversion = 'HG20'
1374 1380
1375 1381 # TODO compression options should be derived from bundlespec parsing.
1376 1382 # This is a temporary hack to allow adjusting bundle compression
1377 1383 # level without a) formalizing the bundlespec changes to declare it
1378 1384 # b) introducing a command flag.
1379 1385 compopts = {}
1380 1386 complevel = ui.configint('experimental', 'bundlecomplevel')
1381 1387 if complevel is not None:
1382 1388 compopts['level'] = complevel
1383 1389
1384 1390 bundle2.writebundle(ui, cg, fname, bversion, compression=bcompression,
1385 1391 compopts=compopts)
1386 1392
1387 1393 @command('cat',
1388 1394 [('o', 'output', '',
1389 1395 _('print output to file with formatted name'), _('FORMAT')),
1390 1396 ('r', 'rev', '', _('print the given revision'), _('REV')),
1391 1397 ('', 'decode', None, _('apply any matching decode filter')),
1392 1398 ] + walkopts,
1393 1399 _('[OPTION]... FILE...'),
1394 1400 inferrepo=True)
1395 1401 def cat(ui, repo, file1, *pats, **opts):
1396 1402 """output the current or given revision of files
1397 1403
1398 1404 Print the specified files as they were at the given revision. If
1399 1405 no revision is given, the parent of the working directory is used.
1400 1406
1401 1407 Output may be to a file, in which case the name of the file is
1402 1408 given using a format string. The formatting rules as follows:
1403 1409
1404 1410 :``%%``: literal "%" character
1405 1411 :``%s``: basename of file being printed
1406 1412 :``%d``: dirname of file being printed, or '.' if in repository root
1407 1413 :``%p``: root-relative path name of file being printed
1408 1414 :``%H``: changeset hash (40 hexadecimal digits)
1409 1415 :``%R``: changeset revision number
1410 1416 :``%h``: short-form changeset hash (12 hexadecimal digits)
1411 1417 :``%r``: zero-padded changeset revision number
1412 1418 :``%b``: basename of the exporting repository
1413 1419
1414 1420 Returns 0 on success.
1415 1421 """
1416 1422 ctx = scmutil.revsingle(repo, opts.get('rev'))
1417 1423 m = scmutil.match(ctx, (file1,) + pats, opts)
1418 1424
1419 1425 ui.pager('cat')
1420 1426 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1421 1427
1422 1428 @command('^clone',
1423 1429 [('U', 'noupdate', None, _('the clone will include an empty working '
1424 1430 'directory (only a repository)')),
1425 1431 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1426 1432 _('REV')),
1427 1433 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1428 1434 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1429 1435 ('', 'pull', None, _('use pull protocol to copy metadata')),
1430 1436 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1431 1437 ] + remoteopts,
1432 1438 _('[OPTION]... SOURCE [DEST]'),
1433 1439 norepo=True)
1434 1440 def clone(ui, source, dest=None, **opts):
1435 1441 """make a copy of an existing repository
1436 1442
1437 1443 Create a copy of an existing repository in a new directory.
1438 1444
1439 1445 If no destination directory name is specified, it defaults to the
1440 1446 basename of the source.
1441 1447
1442 1448 The location of the source is added to the new repository's
1443 1449 ``.hg/hgrc`` file, as the default to be used for future pulls.
1444 1450
1445 1451 Only local paths and ``ssh://`` URLs are supported as
1446 1452 destinations. For ``ssh://`` destinations, no working directory or
1447 1453 ``.hg/hgrc`` will be created on the remote side.
1448 1454
1449 1455 If the source repository has a bookmark called '@' set, that
1450 1456 revision will be checked out in the new repository by default.
1451 1457
1452 1458 To check out a particular version, use -u/--update, or
1453 1459 -U/--noupdate to create a clone with no working directory.
1454 1460
1455 1461 To pull only a subset of changesets, specify one or more revisions
1456 1462 identifiers with -r/--rev or branches with -b/--branch. The
1457 1463 resulting clone will contain only the specified changesets and
1458 1464 their ancestors. These options (or 'clone src#rev dest') imply
1459 1465 --pull, even for local source repositories.
1460 1466
1461 1467 .. note::
1462 1468
1463 1469 Specifying a tag will include the tagged changeset but not the
1464 1470 changeset containing the tag.
1465 1471
1466 1472 .. container:: verbose
1467 1473
1468 1474 For efficiency, hardlinks are used for cloning whenever the
1469 1475 source and destination are on the same filesystem (note this
1470 1476 applies only to the repository data, not to the working
1471 1477 directory). Some filesystems, such as AFS, implement hardlinking
1472 1478 incorrectly, but do not report errors. In these cases, use the
1473 1479 --pull option to avoid hardlinking.
1474 1480
1475 1481 In some cases, you can clone repositories and the working
1476 1482 directory using full hardlinks with ::
1477 1483
1478 1484 $ cp -al REPO REPOCLONE
1479 1485
1480 1486 This is the fastest way to clone, but it is not always safe. The
1481 1487 operation is not atomic (making sure REPO is not modified during
1482 1488 the operation is up to you) and you have to make sure your
1483 1489 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1484 1490 so). Also, this is not compatible with certain extensions that
1485 1491 place their metadata under the .hg directory, such as mq.
1486 1492
1487 1493 Mercurial will update the working directory to the first applicable
1488 1494 revision from this list:
1489 1495
1490 1496 a) null if -U or the source repository has no changesets
1491 1497 b) if -u . and the source repository is local, the first parent of
1492 1498 the source repository's working directory
1493 1499 c) the changeset specified with -u (if a branch name, this means the
1494 1500 latest head of that branch)
1495 1501 d) the changeset specified with -r
1496 1502 e) the tipmost head specified with -b
1497 1503 f) the tipmost head specified with the url#branch source syntax
1498 1504 g) the revision marked with the '@' bookmark, if present
1499 1505 h) the tipmost head of the default branch
1500 1506 i) tip
1501 1507
1502 1508 When cloning from servers that support it, Mercurial may fetch
1503 1509 pre-generated data from a server-advertised URL. When this is done,
1504 1510 hooks operating on incoming changesets and changegroups may fire twice,
1505 1511 once for the bundle fetched from the URL and another for any additional
1506 1512 data not fetched from this URL. In addition, if an error occurs, the
1507 1513 repository may be rolled back to a partial clone. This behavior may
1508 1514 change in future releases. See :hg:`help -e clonebundles` for more.
1509 1515
1510 1516 Examples:
1511 1517
1512 1518 - clone a remote repository to a new directory named hg/::
1513 1519
1514 1520 hg clone https://www.mercurial-scm.org/repo/hg/
1515 1521
1516 1522 - create a lightweight local clone::
1517 1523
1518 1524 hg clone project/ project-feature/
1519 1525
1520 1526 - clone from an absolute path on an ssh server (note double-slash)::
1521 1527
1522 1528 hg clone ssh://user@server//home/projects/alpha/
1523 1529
1524 1530 - do a high-speed clone over a LAN while checking out a
1525 1531 specified version::
1526 1532
1527 1533 hg clone --uncompressed http://server/repo -u 1.5
1528 1534
1529 1535 - create a repository without changesets after a particular revision::
1530 1536
1531 1537 hg clone -r 04e544 experimental/ good/
1532 1538
1533 1539 - clone (and track) a particular named branch::
1534 1540
1535 1541 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1536 1542
1537 1543 See :hg:`help urls` for details on specifying URLs.
1538 1544
1539 1545 Returns 0 on success.
1540 1546 """
1541 1547 if opts.get('noupdate') and opts.get('updaterev'):
1542 1548 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1543 1549
1544 1550 r = hg.clone(ui, opts, source, dest,
1545 1551 pull=opts.get('pull'),
1546 1552 stream=opts.get('uncompressed'),
1547 1553 rev=opts.get('rev'),
1548 1554 update=opts.get('updaterev') or not opts.get('noupdate'),
1549 1555 branch=opts.get('branch'),
1550 1556 shareopts=opts.get('shareopts'))
1551 1557
1552 1558 return r is None
1553 1559
1554 1560 @command('^commit|ci',
1555 1561 [('A', 'addremove', None,
1556 1562 _('mark new/missing files as added/removed before committing')),
1557 1563 ('', 'close-branch', None,
1558 1564 _('mark a branch head as closed')),
1559 1565 ('', 'amend', None, _('amend the parent of the working directory')),
1560 1566 ('s', 'secret', None, _('use the secret phase for committing')),
1561 1567 ('e', 'edit', None, _('invoke editor on commit messages')),
1562 1568 ('i', 'interactive', None, _('use interactive mode')),
1563 1569 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1564 1570 _('[OPTION]... [FILE]...'),
1565 1571 inferrepo=True)
1566 1572 def commit(ui, repo, *pats, **opts):
1567 1573 """commit the specified files or all outstanding changes
1568 1574
1569 1575 Commit changes to the given files into the repository. Unlike a
1570 1576 centralized SCM, this operation is a local operation. See
1571 1577 :hg:`push` for a way to actively distribute your changes.
1572 1578
1573 1579 If a list of files is omitted, all changes reported by :hg:`status`
1574 1580 will be committed.
1575 1581
1576 1582 If you are committing the result of a merge, do not provide any
1577 1583 filenames or -I/-X filters.
1578 1584
1579 1585 If no commit message is specified, Mercurial starts your
1580 1586 configured editor where you can enter a message. In case your
1581 1587 commit fails, you will find a backup of your message in
1582 1588 ``.hg/last-message.txt``.
1583 1589
1584 1590 The --close-branch flag can be used to mark the current branch
1585 1591 head closed. When all heads of a branch are closed, the branch
1586 1592 will be considered closed and no longer listed.
1587 1593
1588 1594 The --amend flag can be used to amend the parent of the
1589 1595 working directory with a new commit that contains the changes
1590 1596 in the parent in addition to those currently reported by :hg:`status`,
1591 1597 if there are any. The old commit is stored in a backup bundle in
1592 1598 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1593 1599 on how to restore it).
1594 1600
1595 1601 Message, user and date are taken from the amended commit unless
1596 1602 specified. When a message isn't specified on the command line,
1597 1603 the editor will open with the message of the amended commit.
1598 1604
1599 1605 It is not possible to amend public changesets (see :hg:`help phases`)
1600 1606 or changesets that have children.
1601 1607
1602 1608 See :hg:`help dates` for a list of formats valid for -d/--date.
1603 1609
1604 1610 Returns 0 on success, 1 if nothing changed.
1605 1611
1606 1612 .. container:: verbose
1607 1613
1608 1614 Examples:
1609 1615
1610 1616 - commit all files ending in .py::
1611 1617
1612 1618 hg commit --include "set:**.py"
1613 1619
1614 1620 - commit all non-binary files::
1615 1621
1616 1622 hg commit --exclude "set:binary()"
1617 1623
1618 1624 - amend the current commit and set the date to now::
1619 1625
1620 1626 hg commit --amend --date now
1621 1627 """
1622 1628 wlock = lock = None
1623 1629 try:
1624 1630 wlock = repo.wlock()
1625 1631 lock = repo.lock()
1626 1632 return _docommit(ui, repo, *pats, **opts)
1627 1633 finally:
1628 1634 release(lock, wlock)
1629 1635
1630 1636 def _docommit(ui, repo, *pats, **opts):
1631 1637 if opts.get('interactive'):
1632 1638 opts.pop('interactive')
1633 1639 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1634 1640 cmdutil.recordfilter, *pats, **opts)
1635 1641 # ret can be 0 (no changes to record) or the value returned by
1636 1642 # commit(), 1 if nothing changed or None on success.
1637 1643 return 1 if ret == 0 else ret
1638 1644
1639 1645 if opts.get('subrepos'):
1640 1646 if opts.get('amend'):
1641 1647 raise error.Abort(_('cannot amend with --subrepos'))
1642 1648 # Let --subrepos on the command line override config setting.
1643 1649 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1644 1650
1645 1651 cmdutil.checkunfinished(repo, commit=True)
1646 1652
1647 1653 branch = repo[None].branch()
1648 1654 bheads = repo.branchheads(branch)
1649 1655
1650 1656 extra = {}
1651 1657 if opts.get('close_branch'):
1652 1658 extra['close'] = 1
1653 1659
1654 1660 if not bheads:
1655 1661 raise error.Abort(_('can only close branch heads'))
1656 1662 elif opts.get('amend'):
1657 1663 if repo[None].parents()[0].p1().branch() != branch and \
1658 1664 repo[None].parents()[0].p2().branch() != branch:
1659 1665 raise error.Abort(_('can only close branch heads'))
1660 1666
1661 1667 if opts.get('amend'):
1662 1668 if ui.configbool('ui', 'commitsubrepos'):
1663 1669 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1664 1670
1665 1671 old = repo['.']
1666 1672 if not old.mutable():
1667 1673 raise error.Abort(_('cannot amend public changesets'))
1668 1674 if len(repo[None].parents()) > 1:
1669 1675 raise error.Abort(_('cannot amend while merging'))
1670 1676 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1671 1677 if not allowunstable and old.children():
1672 1678 raise error.Abort(_('cannot amend changeset with children'))
1673 1679
1674 1680 # Currently histedit gets confused if an amend happens while histedit
1675 1681 # is in progress. Since we have a checkunfinished command, we are
1676 1682 # temporarily honoring it.
1677 1683 #
1678 1684 # Note: eventually this guard will be removed. Please do not expect
1679 1685 # this behavior to remain.
1680 1686 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1681 1687 cmdutil.checkunfinished(repo)
1682 1688
1683 1689 # commitfunc is used only for temporary amend commit by cmdutil.amend
1684 1690 def commitfunc(ui, repo, message, match, opts):
1685 1691 return repo.commit(message,
1686 1692 opts.get('user') or old.user(),
1687 1693 opts.get('date') or old.date(),
1688 1694 match,
1689 1695 extra=extra)
1690 1696
1691 1697 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1692 1698 if node == old.node():
1693 1699 ui.status(_("nothing changed\n"))
1694 1700 return 1
1695 1701 else:
1696 1702 def commitfunc(ui, repo, message, match, opts):
1697 1703 backup = ui.backupconfig('phases', 'new-commit')
1698 1704 baseui = repo.baseui
1699 1705 basebackup = baseui.backupconfig('phases', 'new-commit')
1700 1706 try:
1701 1707 if opts.get('secret'):
1702 1708 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1703 1709 # Propagate to subrepos
1704 1710 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1705 1711
1706 1712 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1707 1713 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1708 1714 return repo.commit(message, opts.get('user'), opts.get('date'),
1709 1715 match,
1710 1716 editor=editor,
1711 1717 extra=extra)
1712 1718 finally:
1713 1719 ui.restoreconfig(backup)
1714 1720 repo.baseui.restoreconfig(basebackup)
1715 1721
1716 1722
1717 1723 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1718 1724
1719 1725 if not node:
1720 1726 stat = cmdutil.postcommitstatus(repo, pats, opts)
1721 1727 if stat[3]:
1722 1728 ui.status(_("nothing changed (%d missing files, see "
1723 1729 "'hg status')\n") % len(stat[3]))
1724 1730 else:
1725 1731 ui.status(_("nothing changed\n"))
1726 1732 return 1
1727 1733
1728 1734 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1729 1735
1730 1736 @command('config|showconfig|debugconfig',
1731 1737 [('u', 'untrusted', None, _('show untrusted configuration options')),
1732 1738 ('e', 'edit', None, _('edit user config')),
1733 1739 ('l', 'local', None, _('edit repository config')),
1734 1740 ('g', 'global', None, _('edit global config'))] + formatteropts,
1735 1741 _('[-u] [NAME]...'),
1736 1742 optionalrepo=True)
1737 1743 def config(ui, repo, *values, **opts):
1738 1744 """show combined config settings from all hgrc files
1739 1745
1740 1746 With no arguments, print names and values of all config items.
1741 1747
1742 1748 With one argument of the form section.name, print just the value
1743 1749 of that config item.
1744 1750
1745 1751 With multiple arguments, print names and values of all config
1746 1752 items with matching section names.
1747 1753
1748 1754 With --edit, start an editor on the user-level config file. With
1749 1755 --global, edit the system-wide config file. With --local, edit the
1750 1756 repository-level config file.
1751 1757
1752 1758 With --debug, the source (filename and line number) is printed
1753 1759 for each config item.
1754 1760
1755 1761 See :hg:`help config` for more information about config files.
1756 1762
1757 1763 Returns 0 on success, 1 if NAME does not exist.
1758 1764
1759 1765 """
1760 1766
1761 1767 if opts.get('edit') or opts.get('local') or opts.get('global'):
1762 1768 if opts.get('local') and opts.get('global'):
1763 1769 raise error.Abort(_("can't use --local and --global together"))
1764 1770
1765 1771 if opts.get('local'):
1766 1772 if not repo:
1767 1773 raise error.Abort(_("can't use --local outside a repository"))
1768 1774 paths = [repo.join('hgrc')]
1769 1775 elif opts.get('global'):
1770 1776 paths = scmutil.systemrcpath()
1771 1777 else:
1772 1778 paths = scmutil.userrcpath()
1773 1779
1774 1780 for f in paths:
1775 1781 if os.path.exists(f):
1776 1782 break
1777 1783 else:
1778 1784 if opts.get('global'):
1779 1785 samplehgrc = uimod.samplehgrcs['global']
1780 1786 elif opts.get('local'):
1781 1787 samplehgrc = uimod.samplehgrcs['local']
1782 1788 else:
1783 1789 samplehgrc = uimod.samplehgrcs['user']
1784 1790
1785 1791 f = paths[0]
1786 1792 fp = open(f, "w")
1787 1793 fp.write(samplehgrc)
1788 1794 fp.close()
1789 1795
1790 1796 editor = ui.geteditor()
1791 1797 ui.system("%s \"%s\"" % (editor, f),
1792 1798 onerr=error.Abort, errprefix=_("edit failed"))
1793 1799 return
1794 1800 ui.pager('config')
1795 1801 fm = ui.formatter('config', opts)
1796 1802 for f in scmutil.rcpath():
1797 1803 ui.debug('read config from: %s\n' % f)
1798 1804 untrusted = bool(opts.get('untrusted'))
1799 1805 if values:
1800 1806 sections = [v for v in values if '.' not in v]
1801 1807 items = [v for v in values if '.' in v]
1802 1808 if len(items) > 1 or items and sections:
1803 1809 raise error.Abort(_('only one config item permitted'))
1804 1810 matched = False
1805 1811 for section, name, value in ui.walkconfig(untrusted=untrusted):
1806 1812 source = ui.configsource(section, name, untrusted)
1807 1813 value = str(value)
1808 1814 if fm.isplain():
1809 1815 source = source or 'none'
1810 1816 value = value.replace('\n', '\\n')
1811 1817 entryname = section + '.' + name
1812 1818 if values:
1813 1819 for v in values:
1814 1820 if v == section:
1815 1821 fm.startitem()
1816 1822 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1817 1823 fm.write('name value', '%s=%s\n', entryname, value)
1818 1824 matched = True
1819 1825 elif v == entryname:
1820 1826 fm.startitem()
1821 1827 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1822 1828 fm.write('value', '%s\n', value)
1823 1829 fm.data(name=entryname)
1824 1830 matched = True
1825 1831 else:
1826 1832 fm.startitem()
1827 1833 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1828 1834 fm.write('name value', '%s=%s\n', entryname, value)
1829 1835 matched = True
1830 1836 fm.end()
1831 1837 if matched:
1832 1838 return 0
1833 1839 return 1
1834 1840
1835 1841 @command('copy|cp',
1836 1842 [('A', 'after', None, _('record a copy that has already occurred')),
1837 1843 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1838 1844 ] + walkopts + dryrunopts,
1839 1845 _('[OPTION]... [SOURCE]... DEST'))
1840 1846 def copy(ui, repo, *pats, **opts):
1841 1847 """mark files as copied for the next commit
1842 1848
1843 1849 Mark dest as having copies of source files. If dest is a
1844 1850 directory, copies are put in that directory. If dest is a file,
1845 1851 the source must be a single file.
1846 1852
1847 1853 By default, this command copies the contents of files as they
1848 1854 exist in the working directory. If invoked with -A/--after, the
1849 1855 operation is recorded, but no copying is performed.
1850 1856
1851 1857 This command takes effect with the next commit. To undo a copy
1852 1858 before that, see :hg:`revert`.
1853 1859
1854 1860 Returns 0 on success, 1 if errors are encountered.
1855 1861 """
1856 1862 with repo.wlock(False):
1857 1863 return cmdutil.copy(ui, repo, pats, opts)
1858 1864
1859 1865 @command('^diff',
1860 1866 [('r', 'rev', [], _('revision'), _('REV')),
1861 1867 ('c', 'change', '', _('change made by revision'), _('REV'))
1862 1868 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1863 1869 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1864 1870 inferrepo=True)
1865 1871 def diff(ui, repo, *pats, **opts):
1866 1872 """diff repository (or selected files)
1867 1873
1868 1874 Show differences between revisions for the specified files.
1869 1875
1870 1876 Differences between files are shown using the unified diff format.
1871 1877
1872 1878 .. note::
1873 1879
1874 1880 :hg:`diff` may generate unexpected results for merges, as it will
1875 1881 default to comparing against the working directory's first
1876 1882 parent changeset if no revisions are specified.
1877 1883
1878 1884 When two revision arguments are given, then changes are shown
1879 1885 between those revisions. If only one revision is specified then
1880 1886 that revision is compared to the working directory, and, when no
1881 1887 revisions are specified, the working directory files are compared
1882 1888 to its first parent.
1883 1889
1884 1890 Alternatively you can specify -c/--change with a revision to see
1885 1891 the changes in that changeset relative to its first parent.
1886 1892
1887 1893 Without the -a/--text option, diff will avoid generating diffs of
1888 1894 files it detects as binary. With -a, diff will generate a diff
1889 1895 anyway, probably with undesirable results.
1890 1896
1891 1897 Use the -g/--git option to generate diffs in the git extended diff
1892 1898 format. For more information, read :hg:`help diffs`.
1893 1899
1894 1900 .. container:: verbose
1895 1901
1896 1902 Examples:
1897 1903
1898 1904 - compare a file in the current working directory to its parent::
1899 1905
1900 1906 hg diff foo.c
1901 1907
1902 1908 - compare two historical versions of a directory, with rename info::
1903 1909
1904 1910 hg diff --git -r 1.0:1.2 lib/
1905 1911
1906 1912 - get change stats relative to the last change on some date::
1907 1913
1908 1914 hg diff --stat -r "date('may 2')"
1909 1915
1910 1916 - diff all newly-added files that contain a keyword::
1911 1917
1912 1918 hg diff "set:added() and grep(GNU)"
1913 1919
1914 1920 - compare a revision and its parents::
1915 1921
1916 1922 hg diff -c 9353 # compare against first parent
1917 1923 hg diff -r 9353^:9353 # same using revset syntax
1918 1924 hg diff -r 9353^2:9353 # compare against the second parent
1919 1925
1920 1926 Returns 0 on success.
1921 1927 """
1922 1928
1923 1929 revs = opts.get('rev')
1924 1930 change = opts.get('change')
1925 1931 stat = opts.get('stat')
1926 1932 reverse = opts.get('reverse')
1927 1933
1928 1934 if revs and change:
1929 1935 msg = _('cannot specify --rev and --change at the same time')
1930 1936 raise error.Abort(msg)
1931 1937 elif change:
1932 1938 node2 = scmutil.revsingle(repo, change, None).node()
1933 1939 node1 = repo[node2].p1().node()
1934 1940 else:
1935 1941 node1, node2 = scmutil.revpair(repo, revs)
1936 1942
1937 1943 if reverse:
1938 1944 node1, node2 = node2, node1
1939 1945
1940 1946 diffopts = patch.diffallopts(ui, opts)
1941 1947 m = scmutil.match(repo[node2], pats, opts)
1942 1948 ui.pager('diff')
1943 1949 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1944 1950 listsubrepos=opts.get('subrepos'),
1945 1951 root=opts.get('root'))
1946 1952
1947 1953 @command('^export',
1948 1954 [('o', 'output', '',
1949 1955 _('print output to file with formatted name'), _('FORMAT')),
1950 1956 ('', 'switch-parent', None, _('diff against the second parent')),
1951 1957 ('r', 'rev', [], _('revisions to export'), _('REV')),
1952 1958 ] + diffopts,
1953 1959 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
1954 1960 def export(ui, repo, *changesets, **opts):
1955 1961 """dump the header and diffs for one or more changesets
1956 1962
1957 1963 Print the changeset header and diffs for one or more revisions.
1958 1964 If no revision is given, the parent of the working directory is used.
1959 1965
1960 1966 The information shown in the changeset header is: author, date,
1961 1967 branch name (if non-default), changeset hash, parent(s) and commit
1962 1968 comment.
1963 1969
1964 1970 .. note::
1965 1971
1966 1972 :hg:`export` may generate unexpected diff output for merge
1967 1973 changesets, as it will compare the merge changeset against its
1968 1974 first parent only.
1969 1975
1970 1976 Output may be to a file, in which case the name of the file is
1971 1977 given using a format string. The formatting rules are as follows:
1972 1978
1973 1979 :``%%``: literal "%" character
1974 1980 :``%H``: changeset hash (40 hexadecimal digits)
1975 1981 :``%N``: number of patches being generated
1976 1982 :``%R``: changeset revision number
1977 1983 :``%b``: basename of the exporting repository
1978 1984 :``%h``: short-form changeset hash (12 hexadecimal digits)
1979 1985 :``%m``: first line of the commit message (only alphanumeric characters)
1980 1986 :``%n``: zero-padded sequence number, starting at 1
1981 1987 :``%r``: zero-padded changeset revision number
1982 1988
1983 1989 Without the -a/--text option, export will avoid generating diffs
1984 1990 of files it detects as binary. With -a, export will generate a
1985 1991 diff anyway, probably with undesirable results.
1986 1992
1987 1993 Use the -g/--git option to generate diffs in the git extended diff
1988 1994 format. See :hg:`help diffs` for more information.
1989 1995
1990 1996 With the --switch-parent option, the diff will be against the
1991 1997 second parent. It can be useful to review a merge.
1992 1998
1993 1999 .. container:: verbose
1994 2000
1995 2001 Examples:
1996 2002
1997 2003 - use export and import to transplant a bugfix to the current
1998 2004 branch::
1999 2005
2000 2006 hg export -r 9353 | hg import -
2001 2007
2002 2008 - export all the changesets between two revisions to a file with
2003 2009 rename information::
2004 2010
2005 2011 hg export --git -r 123:150 > changes.txt
2006 2012
2007 2013 - split outgoing changes into a series of patches with
2008 2014 descriptive names::
2009 2015
2010 2016 hg export -r "outgoing()" -o "%n-%m.patch"
2011 2017
2012 2018 Returns 0 on success.
2013 2019 """
2014 2020 changesets += tuple(opts.get('rev', []))
2015 2021 if not changesets:
2016 2022 changesets = ['.']
2017 2023 revs = scmutil.revrange(repo, changesets)
2018 2024 if not revs:
2019 2025 raise error.Abort(_("export requires at least one changeset"))
2020 2026 if len(revs) > 1:
2021 2027 ui.note(_('exporting patches:\n'))
2022 2028 else:
2023 2029 ui.note(_('exporting patch:\n'))
2024 2030 ui.pager('export')
2025 2031 cmdutil.export(repo, revs, template=opts.get('output'),
2026 2032 switch_parent=opts.get('switch_parent'),
2027 2033 opts=patch.diffallopts(ui, opts))
2028 2034
2029 2035 @command('files',
2030 2036 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2031 2037 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2032 2038 ] + walkopts + formatteropts + subrepoopts,
2033 2039 _('[OPTION]... [FILE]...'))
2034 2040 def files(ui, repo, *pats, **opts):
2035 2041 """list tracked files
2036 2042
2037 2043 Print files under Mercurial control in the working directory or
2038 2044 specified revision for given files (excluding removed files).
2039 2045 Files can be specified as filenames or filesets.
2040 2046
2041 2047 If no files are given to match, this command prints the names
2042 2048 of all files under Mercurial control.
2043 2049
2044 2050 .. container:: verbose
2045 2051
2046 2052 Examples:
2047 2053
2048 2054 - list all files under the current directory::
2049 2055
2050 2056 hg files .
2051 2057
2052 2058 - shows sizes and flags for current revision::
2053 2059
2054 2060 hg files -vr .
2055 2061
2056 2062 - list all files named README::
2057 2063
2058 2064 hg files -I "**/README"
2059 2065
2060 2066 - list all binary files::
2061 2067
2062 2068 hg files "set:binary()"
2063 2069
2064 2070 - find files containing a regular expression::
2065 2071
2066 2072 hg files "set:grep('bob')"
2067 2073
2068 2074 - search tracked file contents with xargs and grep::
2069 2075
2070 2076 hg files -0 | xargs -0 grep foo
2071 2077
2072 2078 See :hg:`help patterns` and :hg:`help filesets` for more information
2073 2079 on specifying file patterns.
2074 2080
2075 2081 Returns 0 if a match is found, 1 otherwise.
2076 2082
2077 2083 """
2078 2084 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2079 2085
2080 2086 end = '\n'
2081 2087 if opts.get('print0'):
2082 2088 end = '\0'
2083 2089 fmt = '%s' + end
2084 2090
2085 2091 m = scmutil.match(ctx, pats, opts)
2086 2092 ui.pager('files')
2087 2093 with ui.formatter('files', opts) as fm:
2088 2094 return cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
2089 2095
2090 2096 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
2091 2097 def forget(ui, repo, *pats, **opts):
2092 2098 """forget the specified files on the next commit
2093 2099
2094 2100 Mark the specified files so they will no longer be tracked
2095 2101 after the next commit.
2096 2102
2097 2103 This only removes files from the current branch, not from the
2098 2104 entire project history, and it does not delete them from the
2099 2105 working directory.
2100 2106
2101 2107 To delete the file from the working directory, see :hg:`remove`.
2102 2108
2103 2109 To undo a forget before the next commit, see :hg:`add`.
2104 2110
2105 2111 .. container:: verbose
2106 2112
2107 2113 Examples:
2108 2114
2109 2115 - forget newly-added binary files::
2110 2116
2111 2117 hg forget "set:added() and binary()"
2112 2118
2113 2119 - forget files that would be excluded by .hgignore::
2114 2120
2115 2121 hg forget "set:hgignore()"
2116 2122
2117 2123 Returns 0 on success.
2118 2124 """
2119 2125
2120 2126 if not pats:
2121 2127 raise error.Abort(_('no files specified'))
2122 2128
2123 2129 m = scmutil.match(repo[None], pats, opts)
2124 2130 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
2125 2131 return rejected and 1 or 0
2126 2132
2127 2133 @command(
2128 2134 'graft',
2129 2135 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2130 2136 ('c', 'continue', False, _('resume interrupted graft')),
2131 2137 ('e', 'edit', False, _('invoke editor on commit messages')),
2132 2138 ('', 'log', None, _('append graft info to log message')),
2133 2139 ('f', 'force', False, _('force graft')),
2134 2140 ('D', 'currentdate', False,
2135 2141 _('record the current date as commit date')),
2136 2142 ('U', 'currentuser', False,
2137 2143 _('record the current user as committer'), _('DATE'))]
2138 2144 + commitopts2 + mergetoolopts + dryrunopts,
2139 2145 _('[OPTION]... [-r REV]... REV...'))
2140 2146 def graft(ui, repo, *revs, **opts):
2141 2147 '''copy changes from other branches onto the current branch
2142 2148
2143 2149 This command uses Mercurial's merge logic to copy individual
2144 2150 changes from other branches without merging branches in the
2145 2151 history graph. This is sometimes known as 'backporting' or
2146 2152 'cherry-picking'. By default, graft will copy user, date, and
2147 2153 description from the source changesets.
2148 2154
2149 2155 Changesets that are ancestors of the current revision, that have
2150 2156 already been grafted, or that are merges will be skipped.
2151 2157
2152 2158 If --log is specified, log messages will have a comment appended
2153 2159 of the form::
2154 2160
2155 2161 (grafted from CHANGESETHASH)
2156 2162
2157 2163 If --force is specified, revisions will be grafted even if they
2158 2164 are already ancestors of or have been grafted to the destination.
2159 2165 This is useful when the revisions have since been backed out.
2160 2166
2161 2167 If a graft merge results in conflicts, the graft process is
2162 2168 interrupted so that the current merge can be manually resolved.
2163 2169 Once all conflicts are addressed, the graft process can be
2164 2170 continued with the -c/--continue option.
2165 2171
2166 2172 .. note::
2167 2173
2168 2174 The -c/--continue option does not reapply earlier options, except
2169 2175 for --force.
2170 2176
2171 2177 .. container:: verbose
2172 2178
2173 2179 Examples:
2174 2180
2175 2181 - copy a single change to the stable branch and edit its description::
2176 2182
2177 2183 hg update stable
2178 2184 hg graft --edit 9393
2179 2185
2180 2186 - graft a range of changesets with one exception, updating dates::
2181 2187
2182 2188 hg graft -D "2085::2093 and not 2091"
2183 2189
2184 2190 - continue a graft after resolving conflicts::
2185 2191
2186 2192 hg graft -c
2187 2193
2188 2194 - show the source of a grafted changeset::
2189 2195
2190 2196 hg log --debug -r .
2191 2197
2192 2198 - show revisions sorted by date::
2193 2199
2194 2200 hg log -r "sort(all(), date)"
2195 2201
2196 2202 See :hg:`help revisions` for more about specifying revisions.
2197 2203
2198 2204 Returns 0 on successful completion.
2199 2205 '''
2200 2206 with repo.wlock():
2201 2207 return _dograft(ui, repo, *revs, **opts)
2202 2208
2203 2209 def _dograft(ui, repo, *revs, **opts):
2204 2210 if revs and opts.get('rev'):
2205 2211 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2206 2212 'revision ordering!\n'))
2207 2213
2208 2214 revs = list(revs)
2209 2215 revs.extend(opts.get('rev'))
2210 2216
2211 2217 if not opts.get('user') and opts.get('currentuser'):
2212 2218 opts['user'] = ui.username()
2213 2219 if not opts.get('date') and opts.get('currentdate'):
2214 2220 opts['date'] = "%d %d" % util.makedate()
2215 2221
2216 2222 editor = cmdutil.getcommiteditor(editform='graft', **opts)
2217 2223
2218 2224 cont = False
2219 2225 if opts.get('continue'):
2220 2226 cont = True
2221 2227 if revs:
2222 2228 raise error.Abort(_("can't specify --continue and revisions"))
2223 2229 # read in unfinished revisions
2224 2230 try:
2225 2231 nodes = repo.vfs.read('graftstate').splitlines()
2226 2232 revs = [repo[node].rev() for node in nodes]
2227 2233 except IOError as inst:
2228 2234 if inst.errno != errno.ENOENT:
2229 2235 raise
2230 2236 cmdutil.wrongtooltocontinue(repo, _('graft'))
2231 2237 else:
2232 2238 cmdutil.checkunfinished(repo)
2233 2239 cmdutil.bailifchanged(repo)
2234 2240 if not revs:
2235 2241 raise error.Abort(_('no revisions specified'))
2236 2242 revs = scmutil.revrange(repo, revs)
2237 2243
2238 2244 skipped = set()
2239 2245 # check for merges
2240 2246 for rev in repo.revs('%ld and merge()', revs):
2241 2247 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
2242 2248 skipped.add(rev)
2243 2249 revs = [r for r in revs if r not in skipped]
2244 2250 if not revs:
2245 2251 return -1
2246 2252
2247 2253 # Don't check in the --continue case, in effect retaining --force across
2248 2254 # --continues. That's because without --force, any revisions we decided to
2249 2255 # skip would have been filtered out here, so they wouldn't have made their
2250 2256 # way to the graftstate. With --force, any revisions we would have otherwise
2251 2257 # skipped would not have been filtered out, and if they hadn't been applied
2252 2258 # already, they'd have been in the graftstate.
2253 2259 if not (cont or opts.get('force')):
2254 2260 # check for ancestors of dest branch
2255 2261 crev = repo['.'].rev()
2256 2262 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2257 2263 # XXX make this lazy in the future
2258 2264 # don't mutate while iterating, create a copy
2259 2265 for rev in list(revs):
2260 2266 if rev in ancestors:
2261 2267 ui.warn(_('skipping ancestor revision %d:%s\n') %
2262 2268 (rev, repo[rev]))
2263 2269 # XXX remove on list is slow
2264 2270 revs.remove(rev)
2265 2271 if not revs:
2266 2272 return -1
2267 2273
2268 2274 # analyze revs for earlier grafts
2269 2275 ids = {}
2270 2276 for ctx in repo.set("%ld", revs):
2271 2277 ids[ctx.hex()] = ctx.rev()
2272 2278 n = ctx.extra().get('source')
2273 2279 if n:
2274 2280 ids[n] = ctx.rev()
2275 2281
2276 2282 # check ancestors for earlier grafts
2277 2283 ui.debug('scanning for duplicate grafts\n')
2278 2284
2279 2285 for rev in repo.changelog.findmissingrevs(revs, [crev]):
2280 2286 ctx = repo[rev]
2281 2287 n = ctx.extra().get('source')
2282 2288 if n in ids:
2283 2289 try:
2284 2290 r = repo[n].rev()
2285 2291 except error.RepoLookupError:
2286 2292 r = None
2287 2293 if r in revs:
2288 2294 ui.warn(_('skipping revision %d:%s '
2289 2295 '(already grafted to %d:%s)\n')
2290 2296 % (r, repo[r], rev, ctx))
2291 2297 revs.remove(r)
2292 2298 elif ids[n] in revs:
2293 2299 if r is None:
2294 2300 ui.warn(_('skipping already grafted revision %d:%s '
2295 2301 '(%d:%s also has unknown origin %s)\n')
2296 2302 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2297 2303 else:
2298 2304 ui.warn(_('skipping already grafted revision %d:%s '
2299 2305 '(%d:%s also has origin %d:%s)\n')
2300 2306 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2301 2307 revs.remove(ids[n])
2302 2308 elif ctx.hex() in ids:
2303 2309 r = ids[ctx.hex()]
2304 2310 ui.warn(_('skipping already grafted revision %d:%s '
2305 2311 '(was grafted from %d:%s)\n') %
2306 2312 (r, repo[r], rev, ctx))
2307 2313 revs.remove(r)
2308 2314 if not revs:
2309 2315 return -1
2310 2316
2311 2317 for pos, ctx in enumerate(repo.set("%ld", revs)):
2312 2318 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2313 2319 ctx.description().split('\n', 1)[0])
2314 2320 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2315 2321 if names:
2316 2322 desc += ' (%s)' % ' '.join(names)
2317 2323 ui.status(_('grafting %s\n') % desc)
2318 2324 if opts.get('dry_run'):
2319 2325 continue
2320 2326
2321 2327 source = ctx.extra().get('source')
2322 2328 extra = {}
2323 2329 if source:
2324 2330 extra['source'] = source
2325 2331 extra['intermediate-source'] = ctx.hex()
2326 2332 else:
2327 2333 extra['source'] = ctx.hex()
2328 2334 user = ctx.user()
2329 2335 if opts.get('user'):
2330 2336 user = opts['user']
2331 2337 date = ctx.date()
2332 2338 if opts.get('date'):
2333 2339 date = opts['date']
2334 2340 message = ctx.description()
2335 2341 if opts.get('log'):
2336 2342 message += '\n(grafted from %s)' % ctx.hex()
2337 2343
2338 2344 # we don't merge the first commit when continuing
2339 2345 if not cont:
2340 2346 # perform the graft merge with p1(rev) as 'ancestor'
2341 2347 try:
2342 2348 # ui.forcemerge is an internal variable, do not document
2343 2349 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
2344 2350 'graft')
2345 2351 stats = mergemod.graft(repo, ctx, ctx.p1(),
2346 2352 ['local', 'graft'])
2347 2353 finally:
2348 2354 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
2349 2355 # report any conflicts
2350 2356 if stats and stats[3] > 0:
2351 2357 # write out state for --continue
2352 2358 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
2353 2359 repo.vfs.write('graftstate', ''.join(nodelines))
2354 2360 extra = ''
2355 2361 if opts.get('user'):
2356 2362 extra += ' --user %s' % util.shellquote(opts['user'])
2357 2363 if opts.get('date'):
2358 2364 extra += ' --date %s' % util.shellquote(opts['date'])
2359 2365 if opts.get('log'):
2360 2366 extra += ' --log'
2361 2367 hint=_("use 'hg resolve' and 'hg graft --continue%s'") % extra
2362 2368 raise error.Abort(
2363 2369 _("unresolved conflicts, can't continue"),
2364 2370 hint=hint)
2365 2371 else:
2366 2372 cont = False
2367 2373
2368 2374 # commit
2369 2375 node = repo.commit(text=message, user=user,
2370 2376 date=date, extra=extra, editor=editor)
2371 2377 if node is None:
2372 2378 ui.warn(
2373 2379 _('note: graft of %d:%s created no changes to commit\n') %
2374 2380 (ctx.rev(), ctx))
2375 2381
2376 2382 # remove state when we complete successfully
2377 2383 if not opts.get('dry_run'):
2378 2384 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
2379 2385
2380 2386 return 0
2381 2387
2382 2388 @command('grep',
2383 2389 [('0', 'print0', None, _('end fields with NUL')),
2384 2390 ('', 'all', None, _('print all revisions that match')),
2385 2391 ('a', 'text', None, _('treat all files as text')),
2386 2392 ('f', 'follow', None,
2387 2393 _('follow changeset history,'
2388 2394 ' or file history across copies and renames')),
2389 2395 ('i', 'ignore-case', None, _('ignore case when matching')),
2390 2396 ('l', 'files-with-matches', None,
2391 2397 _('print only filenames and revisions that match')),
2392 2398 ('n', 'line-number', None, _('print matching line numbers')),
2393 2399 ('r', 'rev', [],
2394 2400 _('only search files changed within revision range'), _('REV')),
2395 2401 ('u', 'user', None, _('list the author (long with -v)')),
2396 2402 ('d', 'date', None, _('list the date (short with -q)')),
2397 2403 ] + formatteropts + walkopts,
2398 2404 _('[OPTION]... PATTERN [FILE]...'),
2399 2405 inferrepo=True)
2400 2406 def grep(ui, repo, pattern, *pats, **opts):
2401 2407 """search revision history for a pattern in specified files
2402 2408
2403 2409 Search revision history for a regular expression in the specified
2404 2410 files or the entire project.
2405 2411
2406 2412 By default, grep prints the most recent revision number for each
2407 2413 file in which it finds a match. To get it to print every revision
2408 2414 that contains a change in match status ("-" for a match that becomes
2409 2415 a non-match, or "+" for a non-match that becomes a match), use the
2410 2416 --all flag.
2411 2417
2412 2418 PATTERN can be any Python (roughly Perl-compatible) regular
2413 2419 expression.
2414 2420
2415 2421 If no FILEs are specified (and -f/--follow isn't set), all files in
2416 2422 the repository are searched, including those that don't exist in the
2417 2423 current branch or have been deleted in a prior changeset.
2418 2424
2419 2425 Returns 0 if a match is found, 1 otherwise.
2420 2426 """
2421 2427 reflags = re.M
2422 2428 if opts.get('ignore_case'):
2423 2429 reflags |= re.I
2424 2430 try:
2425 2431 regexp = util.re.compile(pattern, reflags)
2426 2432 except re.error as inst:
2427 2433 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
2428 2434 return 1
2429 2435 sep, eol = ':', '\n'
2430 2436 if opts.get('print0'):
2431 2437 sep = eol = '\0'
2432 2438
2433 2439 getfile = util.lrucachefunc(repo.file)
2434 2440
2435 2441 def matchlines(body):
2436 2442 begin = 0
2437 2443 linenum = 0
2438 2444 while begin < len(body):
2439 2445 match = regexp.search(body, begin)
2440 2446 if not match:
2441 2447 break
2442 2448 mstart, mend = match.span()
2443 2449 linenum += body.count('\n', begin, mstart) + 1
2444 2450 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2445 2451 begin = body.find('\n', mend) + 1 or len(body) + 1
2446 2452 lend = begin - 1
2447 2453 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2448 2454
2449 2455 class linestate(object):
2450 2456 def __init__(self, line, linenum, colstart, colend):
2451 2457 self.line = line
2452 2458 self.linenum = linenum
2453 2459 self.colstart = colstart
2454 2460 self.colend = colend
2455 2461
2456 2462 def __hash__(self):
2457 2463 return hash((self.linenum, self.line))
2458 2464
2459 2465 def __eq__(self, other):
2460 2466 return self.line == other.line
2461 2467
2462 2468 def findpos(self):
2463 2469 """Iterate all (start, end) indices of matches"""
2464 2470 yield self.colstart, self.colend
2465 2471 p = self.colend
2466 2472 while p < len(self.line):
2467 2473 m = regexp.search(self.line, p)
2468 2474 if not m:
2469 2475 break
2470 2476 yield m.span()
2471 2477 p = m.end()
2472 2478
2473 2479 matches = {}
2474 2480 copies = {}
2475 2481 def grepbody(fn, rev, body):
2476 2482 matches[rev].setdefault(fn, [])
2477 2483 m = matches[rev][fn]
2478 2484 for lnum, cstart, cend, line in matchlines(body):
2479 2485 s = linestate(line, lnum, cstart, cend)
2480 2486 m.append(s)
2481 2487
2482 2488 def difflinestates(a, b):
2483 2489 sm = difflib.SequenceMatcher(None, a, b)
2484 2490 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2485 2491 if tag == 'insert':
2486 2492 for i in xrange(blo, bhi):
2487 2493 yield ('+', b[i])
2488 2494 elif tag == 'delete':
2489 2495 for i in xrange(alo, ahi):
2490 2496 yield ('-', a[i])
2491 2497 elif tag == 'replace':
2492 2498 for i in xrange(alo, ahi):
2493 2499 yield ('-', a[i])
2494 2500 for i in xrange(blo, bhi):
2495 2501 yield ('+', b[i])
2496 2502
2497 2503 def display(fm, fn, ctx, pstates, states):
2498 2504 rev = ctx.rev()
2499 2505 if fm.isplain():
2500 2506 formatuser = ui.shortuser
2501 2507 else:
2502 2508 formatuser = str
2503 2509 if ui.quiet:
2504 2510 datefmt = '%Y-%m-%d'
2505 2511 else:
2506 2512 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2507 2513 found = False
2508 2514 @util.cachefunc
2509 2515 def binary():
2510 2516 flog = getfile(fn)
2511 2517 return util.binary(flog.read(ctx.filenode(fn)))
2512 2518
2513 2519 fieldnamemap = {'filename': 'file', 'linenumber': 'line_number'}
2514 2520 if opts.get('all'):
2515 2521 iter = difflinestates(pstates, states)
2516 2522 else:
2517 2523 iter = [('', l) for l in states]
2518 2524 for change, l in iter:
2519 2525 fm.startitem()
2520 2526 fm.data(node=fm.hexfunc(ctx.node()))
2521 2527 cols = [
2522 2528 ('filename', fn, True),
2523 2529 ('rev', rev, True),
2524 2530 ('linenumber', l.linenum, opts.get('line_number')),
2525 2531 ]
2526 2532 if opts.get('all'):
2527 2533 cols.append(('change', change, True))
2528 2534 cols.extend([
2529 2535 ('user', formatuser(ctx.user()), opts.get('user')),
2530 2536 ('date', fm.formatdate(ctx.date(), datefmt), opts.get('date')),
2531 2537 ])
2532 2538 lastcol = next(name for name, data, cond in reversed(cols) if cond)
2533 2539 for name, data, cond in cols:
2534 2540 field = fieldnamemap.get(name, name)
2535 2541 fm.condwrite(cond, field, '%s', data, label='grep.%s' % name)
2536 2542 if cond and name != lastcol:
2537 2543 fm.plain(sep, label='grep.sep')
2538 2544 if not opts.get('files_with_matches'):
2539 2545 fm.plain(sep, label='grep.sep')
2540 2546 if not opts.get('text') and binary():
2541 2547 fm.plain(_(" Binary file matches"))
2542 2548 else:
2543 2549 displaymatches(fm.nested('texts'), l)
2544 2550 fm.plain(eol)
2545 2551 found = True
2546 2552 if opts.get('files_with_matches'):
2547 2553 break
2548 2554 return found
2549 2555
2550 2556 def displaymatches(fm, l):
2551 2557 p = 0
2552 2558 for s, e in l.findpos():
2553 2559 if p < s:
2554 2560 fm.startitem()
2555 2561 fm.write('text', '%s', l.line[p:s])
2556 2562 fm.data(matched=False)
2557 2563 fm.startitem()
2558 2564 fm.write('text', '%s', l.line[s:e], label='grep.match')
2559 2565 fm.data(matched=True)
2560 2566 p = e
2561 2567 if p < len(l.line):
2562 2568 fm.startitem()
2563 2569 fm.write('text', '%s', l.line[p:])
2564 2570 fm.data(matched=False)
2565 2571 fm.end()
2566 2572
2567 2573 skip = {}
2568 2574 revfiles = {}
2569 2575 matchfn = scmutil.match(repo[None], pats, opts)
2570 2576 found = False
2571 2577 follow = opts.get('follow')
2572 2578
2573 2579 def prep(ctx, fns):
2574 2580 rev = ctx.rev()
2575 2581 pctx = ctx.p1()
2576 2582 parent = pctx.rev()
2577 2583 matches.setdefault(rev, {})
2578 2584 matches.setdefault(parent, {})
2579 2585 files = revfiles.setdefault(rev, [])
2580 2586 for fn in fns:
2581 2587 flog = getfile(fn)
2582 2588 try:
2583 2589 fnode = ctx.filenode(fn)
2584 2590 except error.LookupError:
2585 2591 continue
2586 2592
2587 2593 copied = flog.renamed(fnode)
2588 2594 copy = follow and copied and copied[0]
2589 2595 if copy:
2590 2596 copies.setdefault(rev, {})[fn] = copy
2591 2597 if fn in skip:
2592 2598 if copy:
2593 2599 skip[copy] = True
2594 2600 continue
2595 2601 files.append(fn)
2596 2602
2597 2603 if fn not in matches[rev]:
2598 2604 grepbody(fn, rev, flog.read(fnode))
2599 2605
2600 2606 pfn = copy or fn
2601 2607 if pfn not in matches[parent]:
2602 2608 try:
2603 2609 fnode = pctx.filenode(pfn)
2604 2610 grepbody(pfn, parent, flog.read(fnode))
2605 2611 except error.LookupError:
2606 2612 pass
2607 2613
2608 2614 ui.pager('grep')
2609 2615 fm = ui.formatter('grep', opts)
2610 2616 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2611 2617 rev = ctx.rev()
2612 2618 parent = ctx.p1().rev()
2613 2619 for fn in sorted(revfiles.get(rev, [])):
2614 2620 states = matches[rev][fn]
2615 2621 copy = copies.get(rev, {}).get(fn)
2616 2622 if fn in skip:
2617 2623 if copy:
2618 2624 skip[copy] = True
2619 2625 continue
2620 2626 pstates = matches.get(parent, {}).get(copy or fn, [])
2621 2627 if pstates or states:
2622 2628 r = display(fm, fn, ctx, pstates, states)
2623 2629 found = found or r
2624 2630 if r and not opts.get('all'):
2625 2631 skip[fn] = True
2626 2632 if copy:
2627 2633 skip[copy] = True
2628 2634 del matches[rev]
2629 2635 del revfiles[rev]
2630 2636 fm.end()
2631 2637
2632 2638 return not found
2633 2639
2634 2640 @command('heads',
2635 2641 [('r', 'rev', '',
2636 2642 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2637 2643 ('t', 'topo', False, _('show topological heads only')),
2638 2644 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2639 2645 ('c', 'closed', False, _('show normal and closed branch heads')),
2640 2646 ] + templateopts,
2641 2647 _('[-ct] [-r STARTREV] [REV]...'))
2642 2648 def heads(ui, repo, *branchrevs, **opts):
2643 2649 """show branch heads
2644 2650
2645 2651 With no arguments, show all open branch heads in the repository.
2646 2652 Branch heads are changesets that have no descendants on the
2647 2653 same branch. They are where development generally takes place and
2648 2654 are the usual targets for update and merge operations.
2649 2655
2650 2656 If one or more REVs are given, only open branch heads on the
2651 2657 branches associated with the specified changesets are shown. This
2652 2658 means that you can use :hg:`heads .` to see the heads on the
2653 2659 currently checked-out branch.
2654 2660
2655 2661 If -c/--closed is specified, also show branch heads marked closed
2656 2662 (see :hg:`commit --close-branch`).
2657 2663
2658 2664 If STARTREV is specified, only those heads that are descendants of
2659 2665 STARTREV will be displayed.
2660 2666
2661 2667 If -t/--topo is specified, named branch mechanics will be ignored and only
2662 2668 topological heads (changesets with no children) will be shown.
2663 2669
2664 2670 Returns 0 if matching heads are found, 1 if not.
2665 2671 """
2666 2672
2667 2673 start = None
2668 2674 if 'rev' in opts:
2669 2675 start = scmutil.revsingle(repo, opts['rev'], None).node()
2670 2676
2671 2677 if opts.get('topo'):
2672 2678 heads = [repo[h] for h in repo.heads(start)]
2673 2679 else:
2674 2680 heads = []
2675 2681 for branch in repo.branchmap():
2676 2682 heads += repo.branchheads(branch, start, opts.get('closed'))
2677 2683 heads = [repo[h] for h in heads]
2678 2684
2679 2685 if branchrevs:
2680 2686 branches = set(repo[br].branch() for br in branchrevs)
2681 2687 heads = [h for h in heads if h.branch() in branches]
2682 2688
2683 2689 if opts.get('active') and branchrevs:
2684 2690 dagheads = repo.heads(start)
2685 2691 heads = [h for h in heads if h.node() in dagheads]
2686 2692
2687 2693 if branchrevs:
2688 2694 haveheads = set(h.branch() for h in heads)
2689 2695 if branches - haveheads:
2690 2696 headless = ', '.join(b for b in branches - haveheads)
2691 2697 msg = _('no open branch heads found on branches %s')
2692 2698 if opts.get('rev'):
2693 2699 msg += _(' (started at %s)') % opts['rev']
2694 2700 ui.warn((msg + '\n') % headless)
2695 2701
2696 2702 if not heads:
2697 2703 return 1
2698 2704
2699 2705 heads = sorted(heads, key=lambda x: -x.rev())
2700 2706 displayer = cmdutil.show_changeset(ui, repo, opts)
2701 2707 for ctx in heads:
2702 2708 displayer.show(ctx)
2703 2709 displayer.close()
2704 2710
2705 2711 @command('help',
2706 2712 [('e', 'extension', None, _('show only help for extensions')),
2707 2713 ('c', 'command', None, _('show only help for commands')),
2708 2714 ('k', 'keyword', None, _('show topics matching keyword')),
2709 2715 ('s', 'system', [], _('show help for specific platform(s)')),
2710 2716 ],
2711 2717 _('[-ecks] [TOPIC]'),
2712 2718 norepo=True)
2713 2719 def help_(ui, name=None, **opts):
2714 2720 """show help for a given topic or a help overview
2715 2721
2716 2722 With no arguments, print a list of commands with short help messages.
2717 2723
2718 2724 Given a topic, extension, or command name, print help for that
2719 2725 topic.
2720 2726
2721 2727 Returns 0 if successful.
2722 2728 """
2723 2729
2724 2730 keep = opts.get('system') or []
2725 2731 if len(keep) == 0:
2726 2732 if pycompat.sysplatform.startswith('win'):
2727 2733 keep.append('windows')
2728 2734 elif pycompat.sysplatform == 'OpenVMS':
2729 2735 keep.append('vms')
2730 2736 elif pycompat.sysplatform == 'plan9':
2731 2737 keep.append('plan9')
2732 2738 else:
2733 2739 keep.append('unix')
2734 2740 keep.append(pycompat.sysplatform.lower())
2735 2741 if ui.verbose:
2736 2742 keep.append('verbose')
2737 2743
2738 2744 formatted = help.formattedhelp(ui, name, keep=keep, **opts)
2739 2745 ui.pager('help')
2740 2746 ui.write(formatted)
2741 2747
2742 2748
2743 2749 @command('identify|id',
2744 2750 [('r', 'rev', '',
2745 2751 _('identify the specified revision'), _('REV')),
2746 2752 ('n', 'num', None, _('show local revision number')),
2747 2753 ('i', 'id', None, _('show global revision id')),
2748 2754 ('b', 'branch', None, _('show branch')),
2749 2755 ('t', 'tags', None, _('show tags')),
2750 2756 ('B', 'bookmarks', None, _('show bookmarks')),
2751 2757 ] + remoteopts,
2752 2758 _('[-nibtB] [-r REV] [SOURCE]'),
2753 2759 optionalrepo=True)
2754 2760 def identify(ui, repo, source=None, rev=None,
2755 2761 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
2756 2762 """identify the working directory or specified revision
2757 2763
2758 2764 Print a summary identifying the repository state at REV using one or
2759 2765 two parent hash identifiers, followed by a "+" if the working
2760 2766 directory has uncommitted changes, the branch name (if not default),
2761 2767 a list of tags, and a list of bookmarks.
2762 2768
2763 2769 When REV is not given, print a summary of the current state of the
2764 2770 repository.
2765 2771
2766 2772 Specifying a path to a repository root or Mercurial bundle will
2767 2773 cause lookup to operate on that repository/bundle.
2768 2774
2769 2775 .. container:: verbose
2770 2776
2771 2777 Examples:
2772 2778
2773 2779 - generate a build identifier for the working directory::
2774 2780
2775 2781 hg id --id > build-id.dat
2776 2782
2777 2783 - find the revision corresponding to a tag::
2778 2784
2779 2785 hg id -n -r 1.3
2780 2786
2781 2787 - check the most recent revision of a remote repository::
2782 2788
2783 2789 hg id -r tip https://www.mercurial-scm.org/repo/hg/
2784 2790
2785 2791 See :hg:`log` for generating more information about specific revisions,
2786 2792 including full hash identifiers.
2787 2793
2788 2794 Returns 0 if successful.
2789 2795 """
2790 2796
2791 2797 if not repo and not source:
2792 2798 raise error.Abort(_("there is no Mercurial repository here "
2793 2799 "(.hg not found)"))
2794 2800
2795 2801 if ui.debugflag:
2796 2802 hexfunc = hex
2797 2803 else:
2798 2804 hexfunc = short
2799 2805 default = not (num or id or branch or tags or bookmarks)
2800 2806 output = []
2801 2807 revs = []
2802 2808
2803 2809 if source:
2804 2810 source, branches = hg.parseurl(ui.expandpath(source))
2805 2811 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
2806 2812 repo = peer.local()
2807 2813 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
2808 2814
2809 2815 if not repo:
2810 2816 if num or branch or tags:
2811 2817 raise error.Abort(
2812 2818 _("can't query remote revision number, branch, or tags"))
2813 2819 if not rev and revs:
2814 2820 rev = revs[0]
2815 2821 if not rev:
2816 2822 rev = "tip"
2817 2823
2818 2824 remoterev = peer.lookup(rev)
2819 2825 if default or id:
2820 2826 output = [hexfunc(remoterev)]
2821 2827
2822 2828 def getbms():
2823 2829 bms = []
2824 2830
2825 2831 if 'bookmarks' in peer.listkeys('namespaces'):
2826 2832 hexremoterev = hex(remoterev)
2827 2833 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
2828 2834 if bmr == hexremoterev]
2829 2835
2830 2836 return sorted(bms)
2831 2837
2832 2838 if bookmarks:
2833 2839 output.extend(getbms())
2834 2840 elif default and not ui.quiet:
2835 2841 # multiple bookmarks for a single parent separated by '/'
2836 2842 bm = '/'.join(getbms())
2837 2843 if bm:
2838 2844 output.append(bm)
2839 2845 else:
2840 2846 ctx = scmutil.revsingle(repo, rev, None)
2841 2847
2842 2848 if ctx.rev() is None:
2843 2849 ctx = repo[None]
2844 2850 parents = ctx.parents()
2845 2851 taglist = []
2846 2852 for p in parents:
2847 2853 taglist.extend(p.tags())
2848 2854
2849 2855 changed = ""
2850 2856 if default or id or num:
2851 2857 if (any(repo.status())
2852 2858 or any(ctx.sub(s).dirty() for s in ctx.substate)):
2853 2859 changed = '+'
2854 2860 if default or id:
2855 2861 output = ["%s%s" %
2856 2862 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
2857 2863 if num:
2858 2864 output.append("%s%s" %
2859 2865 ('+'.join([str(p.rev()) for p in parents]), changed))
2860 2866 else:
2861 2867 if default or id:
2862 2868 output = [hexfunc(ctx.node())]
2863 2869 if num:
2864 2870 output.append(str(ctx.rev()))
2865 2871 taglist = ctx.tags()
2866 2872
2867 2873 if default and not ui.quiet:
2868 2874 b = ctx.branch()
2869 2875 if b != 'default':
2870 2876 output.append("(%s)" % b)
2871 2877
2872 2878 # multiple tags for a single parent separated by '/'
2873 2879 t = '/'.join(taglist)
2874 2880 if t:
2875 2881 output.append(t)
2876 2882
2877 2883 # multiple bookmarks for a single parent separated by '/'
2878 2884 bm = '/'.join(ctx.bookmarks())
2879 2885 if bm:
2880 2886 output.append(bm)
2881 2887 else:
2882 2888 if branch:
2883 2889 output.append(ctx.branch())
2884 2890
2885 2891 if tags:
2886 2892 output.extend(taglist)
2887 2893
2888 2894 if bookmarks:
2889 2895 output.extend(ctx.bookmarks())
2890 2896
2891 2897 ui.write("%s\n" % ' '.join(output))
2892 2898
2893 2899 @command('import|patch',
2894 2900 [('p', 'strip', 1,
2895 2901 _('directory strip option for patch. This has the same '
2896 2902 'meaning as the corresponding patch option'), _('NUM')),
2897 2903 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
2898 2904 ('e', 'edit', False, _('invoke editor on commit messages')),
2899 2905 ('f', 'force', None,
2900 2906 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
2901 2907 ('', 'no-commit', None,
2902 2908 _("don't commit, just update the working directory")),
2903 2909 ('', 'bypass', None,
2904 2910 _("apply patch without touching the working directory")),
2905 2911 ('', 'partial', None,
2906 2912 _('commit even if some hunks fail')),
2907 2913 ('', 'exact', None,
2908 2914 _('abort if patch would apply lossily')),
2909 2915 ('', 'prefix', '',
2910 2916 _('apply patch to subdirectory'), _('DIR')),
2911 2917 ('', 'import-branch', None,
2912 2918 _('use any branch information in patch (implied by --exact)'))] +
2913 2919 commitopts + commitopts2 + similarityopts,
2914 2920 _('[OPTION]... PATCH...'))
2915 2921 def import_(ui, repo, patch1=None, *patches, **opts):
2916 2922 """import an ordered set of patches
2917 2923
2918 2924 Import a list of patches and commit them individually (unless
2919 2925 --no-commit is specified).
2920 2926
2921 2927 To read a patch from standard input (stdin), use "-" as the patch
2922 2928 name. If a URL is specified, the patch will be downloaded from
2923 2929 there.
2924 2930
2925 2931 Import first applies changes to the working directory (unless
2926 2932 --bypass is specified), import will abort if there are outstanding
2927 2933 changes.
2928 2934
2929 2935 Use --bypass to apply and commit patches directly to the
2930 2936 repository, without affecting the working directory. Without
2931 2937 --exact, patches will be applied on top of the working directory
2932 2938 parent revision.
2933 2939
2934 2940 You can import a patch straight from a mail message. Even patches
2935 2941 as attachments work (to use the body part, it must have type
2936 2942 text/plain or text/x-patch). From and Subject headers of email
2937 2943 message are used as default committer and commit message. All
2938 2944 text/plain body parts before first diff are added to the commit
2939 2945 message.
2940 2946
2941 2947 If the imported patch was generated by :hg:`export`, user and
2942 2948 description from patch override values from message headers and
2943 2949 body. Values given on command line with -m/--message and -u/--user
2944 2950 override these.
2945 2951
2946 2952 If --exact is specified, import will set the working directory to
2947 2953 the parent of each patch before applying it, and will abort if the
2948 2954 resulting changeset has a different ID than the one recorded in
2949 2955 the patch. This will guard against various ways that portable
2950 2956 patch formats and mail systems might fail to transfer Mercurial
2951 2957 data or metadata. See :hg:`bundle` for lossless transmission.
2952 2958
2953 2959 Use --partial to ensure a changeset will be created from the patch
2954 2960 even if some hunks fail to apply. Hunks that fail to apply will be
2955 2961 written to a <target-file>.rej file. Conflicts can then be resolved
2956 2962 by hand before :hg:`commit --amend` is run to update the created
2957 2963 changeset. This flag exists to let people import patches that
2958 2964 partially apply without losing the associated metadata (author,
2959 2965 date, description, ...).
2960 2966
2961 2967 .. note::
2962 2968
2963 2969 When no hunks apply cleanly, :hg:`import --partial` will create
2964 2970 an empty changeset, importing only the patch metadata.
2965 2971
2966 2972 With -s/--similarity, hg will attempt to discover renames and
2967 2973 copies in the patch in the same way as :hg:`addremove`.
2968 2974
2969 2975 It is possible to use external patch programs to perform the patch
2970 2976 by setting the ``ui.patch`` configuration option. For the default
2971 2977 internal tool, the fuzz can also be configured via ``patch.fuzz``.
2972 2978 See :hg:`help config` for more information about configuration
2973 2979 files and how to use these options.
2974 2980
2975 2981 See :hg:`help dates` for a list of formats valid for -d/--date.
2976 2982
2977 2983 .. container:: verbose
2978 2984
2979 2985 Examples:
2980 2986
2981 2987 - import a traditional patch from a website and detect renames::
2982 2988
2983 2989 hg import -s 80 http://example.com/bugfix.patch
2984 2990
2985 2991 - import a changeset from an hgweb server::
2986 2992
2987 2993 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
2988 2994
2989 2995 - import all the patches in an Unix-style mbox::
2990 2996
2991 2997 hg import incoming-patches.mbox
2992 2998
2993 2999 - import patches from stdin::
2994 3000
2995 3001 hg import -
2996 3002
2997 3003 - attempt to exactly restore an exported changeset (not always
2998 3004 possible)::
2999 3005
3000 3006 hg import --exact proposed-fix.patch
3001 3007
3002 3008 - use an external tool to apply a patch which is too fuzzy for
3003 3009 the default internal tool.
3004 3010
3005 3011 hg import --config ui.patch="patch --merge" fuzzy.patch
3006 3012
3007 3013 - change the default fuzzing from 2 to a less strict 7
3008 3014
3009 3015 hg import --config ui.fuzz=7 fuzz.patch
3010 3016
3011 3017 Returns 0 on success, 1 on partial success (see --partial).
3012 3018 """
3013 3019
3014 3020 if not patch1:
3015 3021 raise error.Abort(_('need at least one patch to import'))
3016 3022
3017 3023 patches = (patch1,) + patches
3018 3024
3019 3025 date = opts.get('date')
3020 3026 if date:
3021 3027 opts['date'] = util.parsedate(date)
3022 3028
3023 3029 exact = opts.get('exact')
3024 3030 update = not opts.get('bypass')
3025 3031 if not update and opts.get('no_commit'):
3026 3032 raise error.Abort(_('cannot use --no-commit with --bypass'))
3027 3033 try:
3028 3034 sim = float(opts.get('similarity') or 0)
3029 3035 except ValueError:
3030 3036 raise error.Abort(_('similarity must be a number'))
3031 3037 if sim < 0 or sim > 100:
3032 3038 raise error.Abort(_('similarity must be between 0 and 100'))
3033 3039 if sim and not update:
3034 3040 raise error.Abort(_('cannot use --similarity with --bypass'))
3035 3041 if exact:
3036 3042 if opts.get('edit'):
3037 3043 raise error.Abort(_('cannot use --exact with --edit'))
3038 3044 if opts.get('prefix'):
3039 3045 raise error.Abort(_('cannot use --exact with --prefix'))
3040 3046
3041 3047 base = opts["base"]
3042 3048 wlock = dsguard = lock = tr = None
3043 3049 msgs = []
3044 3050 ret = 0
3045 3051
3046 3052
3047 3053 try:
3048 3054 wlock = repo.wlock()
3049 3055
3050 3056 if update:
3051 3057 cmdutil.checkunfinished(repo)
3052 3058 if (exact or not opts.get('force')):
3053 3059 cmdutil.bailifchanged(repo)
3054 3060
3055 3061 if not opts.get('no_commit'):
3056 3062 lock = repo.lock()
3057 3063 tr = repo.transaction('import')
3058 3064 else:
3059 3065 dsguard = dirstateguard.dirstateguard(repo, 'import')
3060 3066 parents = repo[None].parents()
3061 3067 for patchurl in patches:
3062 3068 if patchurl == '-':
3063 3069 ui.status(_('applying patch from stdin\n'))
3064 3070 patchfile = ui.fin
3065 3071 patchurl = 'stdin' # for error message
3066 3072 else:
3067 3073 patchurl = os.path.join(base, patchurl)
3068 3074 ui.status(_('applying %s\n') % patchurl)
3069 3075 patchfile = hg.openpath(ui, patchurl)
3070 3076
3071 3077 haspatch = False
3072 3078 for hunk in patch.split(patchfile):
3073 3079 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
3074 3080 parents, opts,
3075 3081 msgs, hg.clean)
3076 3082 if msg:
3077 3083 haspatch = True
3078 3084 ui.note(msg + '\n')
3079 3085 if update or exact:
3080 3086 parents = repo[None].parents()
3081 3087 else:
3082 3088 parents = [repo[node]]
3083 3089 if rej:
3084 3090 ui.write_err(_("patch applied partially\n"))
3085 3091 ui.write_err(_("(fix the .rej files and run "
3086 3092 "`hg commit --amend`)\n"))
3087 3093 ret = 1
3088 3094 break
3089 3095
3090 3096 if not haspatch:
3091 3097 raise error.Abort(_('%s: no diffs found') % patchurl)
3092 3098
3093 3099 if tr:
3094 3100 tr.close()
3095 3101 if msgs:
3096 3102 repo.savecommitmessage('\n* * *\n'.join(msgs))
3097 3103 if dsguard:
3098 3104 dsguard.close()
3099 3105 return ret
3100 3106 finally:
3101 3107 if tr:
3102 3108 tr.release()
3103 3109 release(lock, dsguard, wlock)
3104 3110
3105 3111 @command('incoming|in',
3106 3112 [('f', 'force', None,
3107 3113 _('run even if remote repository is unrelated')),
3108 3114 ('n', 'newest-first', None, _('show newest record first')),
3109 3115 ('', 'bundle', '',
3110 3116 _('file to store the bundles into'), _('FILE')),
3111 3117 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3112 3118 ('B', 'bookmarks', False, _("compare bookmarks")),
3113 3119 ('b', 'branch', [],
3114 3120 _('a specific branch you would like to pull'), _('BRANCH')),
3115 3121 ] + logopts + remoteopts + subrepoopts,
3116 3122 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3117 3123 def incoming(ui, repo, source="default", **opts):
3118 3124 """show new changesets found in source
3119 3125
3120 3126 Show new changesets found in the specified path/URL or the default
3121 3127 pull location. These are the changesets that would have been pulled
3122 3128 if a pull at the time you issued this command.
3123 3129
3124 3130 See pull for valid source format details.
3125 3131
3126 3132 .. container:: verbose
3127 3133
3128 3134 With -B/--bookmarks, the result of bookmark comparison between
3129 3135 local and remote repositories is displayed. With -v/--verbose,
3130 3136 status is also displayed for each bookmark like below::
3131 3137
3132 3138 BM1 01234567890a added
3133 3139 BM2 1234567890ab advanced
3134 3140 BM3 234567890abc diverged
3135 3141 BM4 34567890abcd changed
3136 3142
3137 3143 The action taken locally when pulling depends on the
3138 3144 status of each bookmark:
3139 3145
3140 3146 :``added``: pull will create it
3141 3147 :``advanced``: pull will update it
3142 3148 :``diverged``: pull will create a divergent bookmark
3143 3149 :``changed``: result depends on remote changesets
3144 3150
3145 3151 From the point of view of pulling behavior, bookmark
3146 3152 existing only in the remote repository are treated as ``added``,
3147 3153 even if it is in fact locally deleted.
3148 3154
3149 3155 .. container:: verbose
3150 3156
3151 3157 For remote repository, using --bundle avoids downloading the
3152 3158 changesets twice if the incoming is followed by a pull.
3153 3159
3154 3160 Examples:
3155 3161
3156 3162 - show incoming changes with patches and full description::
3157 3163
3158 3164 hg incoming -vp
3159 3165
3160 3166 - show incoming changes excluding merges, store a bundle::
3161 3167
3162 3168 hg in -vpM --bundle incoming.hg
3163 3169 hg pull incoming.hg
3164 3170
3165 3171 - briefly list changes inside a bundle::
3166 3172
3167 3173 hg in changes.hg -T "{desc|firstline}\\n"
3168 3174
3169 3175 Returns 0 if there are incoming changes, 1 otherwise.
3170 3176 """
3171 3177 if opts.get('graph'):
3172 3178 cmdutil.checkunsupportedgraphflags([], opts)
3173 3179 def display(other, chlist, displayer):
3174 3180 revdag = cmdutil.graphrevs(other, chlist, opts)
3175 3181 cmdutil.displaygraph(ui, repo, revdag, displayer,
3176 3182 graphmod.asciiedges)
3177 3183
3178 3184 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3179 3185 return 0
3180 3186
3181 3187 if opts.get('bundle') and opts.get('subrepos'):
3182 3188 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3183 3189
3184 3190 if opts.get('bookmarks'):
3185 3191 source, branches = hg.parseurl(ui.expandpath(source),
3186 3192 opts.get('branch'))
3187 3193 other = hg.peer(repo, opts, source)
3188 3194 if 'bookmarks' not in other.listkeys('namespaces'):
3189 3195 ui.warn(_("remote doesn't support bookmarks\n"))
3190 3196 return 0
3191 3197 ui.pager('incoming')
3192 3198 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3193 3199 return bookmarks.incoming(ui, repo, other)
3194 3200
3195 3201 repo._subtoppath = ui.expandpath(source)
3196 3202 try:
3197 3203 return hg.incoming(ui, repo, source, opts)
3198 3204 finally:
3199 3205 del repo._subtoppath
3200 3206
3201 3207
3202 3208 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3203 3209 norepo=True)
3204 3210 def init(ui, dest=".", **opts):
3205 3211 """create a new repository in the given directory
3206 3212
3207 3213 Initialize a new repository in the given directory. If the given
3208 3214 directory does not exist, it will be created.
3209 3215
3210 3216 If no directory is given, the current directory is used.
3211 3217
3212 3218 It is possible to specify an ``ssh://`` URL as the destination.
3213 3219 See :hg:`help urls` for more information.
3214 3220
3215 3221 Returns 0 on success.
3216 3222 """
3217 3223 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3218 3224
3219 3225 @command('locate',
3220 3226 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3221 3227 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3222 3228 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3223 3229 ] + walkopts,
3224 3230 _('[OPTION]... [PATTERN]...'))
3225 3231 def locate(ui, repo, *pats, **opts):
3226 3232 """locate files matching specific patterns (DEPRECATED)
3227 3233
3228 3234 Print files under Mercurial control in the working directory whose
3229 3235 names match the given patterns.
3230 3236
3231 3237 By default, this command searches all directories in the working
3232 3238 directory. To search just the current directory and its
3233 3239 subdirectories, use "--include .".
3234 3240
3235 3241 If no patterns are given to match, this command prints the names
3236 3242 of all files under Mercurial control in the working directory.
3237 3243
3238 3244 If you want to feed the output of this command into the "xargs"
3239 3245 command, use the -0 option to both this command and "xargs". This
3240 3246 will avoid the problem of "xargs" treating single filenames that
3241 3247 contain whitespace as multiple filenames.
3242 3248
3243 3249 See :hg:`help files` for a more versatile command.
3244 3250
3245 3251 Returns 0 if a match is found, 1 otherwise.
3246 3252 """
3247 3253 if opts.get('print0'):
3248 3254 end = '\0'
3249 3255 else:
3250 3256 end = '\n'
3251 3257 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3252 3258
3253 3259 ret = 1
3254 3260 ctx = repo[rev]
3255 3261 m = scmutil.match(ctx, pats, opts, default='relglob',
3256 3262 badfn=lambda x, y: False)
3257 3263
3258 3264 ui.pager('locate')
3259 3265 for abs in ctx.matches(m):
3260 3266 if opts.get('fullpath'):
3261 3267 ui.write(repo.wjoin(abs), end)
3262 3268 else:
3263 3269 ui.write(((pats and m.rel(abs)) or abs), end)
3264 3270 ret = 0
3265 3271
3266 3272 return ret
3267 3273
3268 3274 @command('^log|history',
3269 3275 [('f', 'follow', None,
3270 3276 _('follow changeset history, or file history across copies and renames')),
3271 3277 ('', 'follow-first', None,
3272 3278 _('only follow the first parent of merge changesets (DEPRECATED)')),
3273 3279 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3274 3280 ('C', 'copies', None, _('show copied files')),
3275 3281 ('k', 'keyword', [],
3276 3282 _('do case-insensitive search for a given text'), _('TEXT')),
3277 3283 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3278 3284 ('', 'removed', None, _('include revisions where files were removed')),
3279 3285 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3280 3286 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3281 3287 ('', 'only-branch', [],
3282 3288 _('show only changesets within the given named branch (DEPRECATED)'),
3283 3289 _('BRANCH')),
3284 3290 ('b', 'branch', [],
3285 3291 _('show changesets within the given named branch'), _('BRANCH')),
3286 3292 ('P', 'prune', [],
3287 3293 _('do not display revision or any of its ancestors'), _('REV')),
3288 3294 ] + logopts + walkopts,
3289 3295 _('[OPTION]... [FILE]'),
3290 3296 inferrepo=True)
3291 3297 def log(ui, repo, *pats, **opts):
3292 3298 """show revision history of entire repository or files
3293 3299
3294 3300 Print the revision history of the specified files or the entire
3295 3301 project.
3296 3302
3297 3303 If no revision range is specified, the default is ``tip:0`` unless
3298 3304 --follow is set, in which case the working directory parent is
3299 3305 used as the starting revision.
3300 3306
3301 3307 File history is shown without following rename or copy history of
3302 3308 files. Use -f/--follow with a filename to follow history across
3303 3309 renames and copies. --follow without a filename will only show
3304 3310 ancestors or descendants of the starting revision.
3305 3311
3306 3312 By default this command prints revision number and changeset id,
3307 3313 tags, non-trivial parents, user, date and time, and a summary for
3308 3314 each commit. When the -v/--verbose switch is used, the list of
3309 3315 changed files and full commit message are shown.
3310 3316
3311 3317 With --graph the revisions are shown as an ASCII art DAG with the most
3312 3318 recent changeset at the top.
3313 3319 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
3314 3320 and '+' represents a fork where the changeset from the lines below is a
3315 3321 parent of the 'o' merge on the same line.
3316 3322
3317 3323 .. note::
3318 3324
3319 3325 :hg:`log --patch` may generate unexpected diff output for merge
3320 3326 changesets, as it will only compare the merge changeset against
3321 3327 its first parent. Also, only files different from BOTH parents
3322 3328 will appear in files:.
3323 3329
3324 3330 .. note::
3325 3331
3326 3332 For performance reasons, :hg:`log FILE` may omit duplicate changes
3327 3333 made on branches and will not show removals or mode changes. To
3328 3334 see all such changes, use the --removed switch.
3329 3335
3330 3336 .. container:: verbose
3331 3337
3332 3338 Some examples:
3333 3339
3334 3340 - changesets with full descriptions and file lists::
3335 3341
3336 3342 hg log -v
3337 3343
3338 3344 - changesets ancestral to the working directory::
3339 3345
3340 3346 hg log -f
3341 3347
3342 3348 - last 10 commits on the current branch::
3343 3349
3344 3350 hg log -l 10 -b .
3345 3351
3346 3352 - changesets showing all modifications of a file, including removals::
3347 3353
3348 3354 hg log --removed file.c
3349 3355
3350 3356 - all changesets that touch a directory, with diffs, excluding merges::
3351 3357
3352 3358 hg log -Mp lib/
3353 3359
3354 3360 - all revision numbers that match a keyword::
3355 3361
3356 3362 hg log -k bug --template "{rev}\\n"
3357 3363
3358 3364 - the full hash identifier of the working directory parent::
3359 3365
3360 3366 hg log -r . --template "{node}\\n"
3361 3367
3362 3368 - list available log templates::
3363 3369
3364 3370 hg log -T list
3365 3371
3366 3372 - check if a given changeset is included in a tagged release::
3367 3373
3368 3374 hg log -r "a21ccf and ancestor(1.9)"
3369 3375
3370 3376 - find all changesets by some user in a date range::
3371 3377
3372 3378 hg log -k alice -d "may 2008 to jul 2008"
3373 3379
3374 3380 - summary of all changesets after the last tag::
3375 3381
3376 3382 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3377 3383
3378 3384 See :hg:`help dates` for a list of formats valid for -d/--date.
3379 3385
3380 3386 See :hg:`help revisions` for more about specifying and ordering
3381 3387 revisions.
3382 3388
3383 3389 See :hg:`help templates` for more about pre-packaged styles and
3384 3390 specifying custom templates.
3385 3391
3386 3392 Returns 0 on success.
3387 3393
3388 3394 """
3389 3395 if opts.get('follow') and opts.get('rev'):
3390 3396 opts['rev'] = [revsetlang.formatspec('reverse(::%lr)', opts.get('rev'))]
3391 3397 del opts['follow']
3392 3398
3393 3399 if opts.get('graph'):
3394 3400 return cmdutil.graphlog(ui, repo, *pats, **opts)
3395 3401
3396 3402 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
3397 3403 limit = cmdutil.loglimit(opts)
3398 3404 count = 0
3399 3405
3400 3406 getrenamed = None
3401 3407 if opts.get('copies'):
3402 3408 endrev = None
3403 3409 if opts.get('rev'):
3404 3410 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
3405 3411 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3406 3412
3407 3413 ui.pager('log')
3408 3414 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
3409 3415 for rev in revs:
3410 3416 if count == limit:
3411 3417 break
3412 3418 ctx = repo[rev]
3413 3419 copies = None
3414 3420 if getrenamed is not None and rev:
3415 3421 copies = []
3416 3422 for fn in ctx.files():
3417 3423 rename = getrenamed(fn, rev)
3418 3424 if rename:
3419 3425 copies.append((fn, rename[0]))
3420 3426 if filematcher:
3421 3427 revmatchfn = filematcher(ctx.rev())
3422 3428 else:
3423 3429 revmatchfn = None
3424 3430 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3425 3431 if displayer.flush(ctx):
3426 3432 count += 1
3427 3433
3428 3434 displayer.close()
3429 3435
3430 3436 @command('manifest',
3431 3437 [('r', 'rev', '', _('revision to display'), _('REV')),
3432 3438 ('', 'all', False, _("list files from all revisions"))]
3433 3439 + formatteropts,
3434 3440 _('[-r REV]'))
3435 3441 def manifest(ui, repo, node=None, rev=None, **opts):
3436 3442 """output the current or given revision of the project manifest
3437 3443
3438 3444 Print a list of version controlled files for the given revision.
3439 3445 If no revision is given, the first parent of the working directory
3440 3446 is used, or the null revision if no revision is checked out.
3441 3447
3442 3448 With -v, print file permissions, symlink and executable bits.
3443 3449 With --debug, print file revision hashes.
3444 3450
3445 3451 If option --all is specified, the list of all files from all revisions
3446 3452 is printed. This includes deleted and renamed files.
3447 3453
3448 3454 Returns 0 on success.
3449 3455 """
3450 3456 fm = ui.formatter('manifest', opts)
3451 3457
3452 3458 if opts.get('all'):
3453 3459 if rev or node:
3454 3460 raise error.Abort(_("can't specify a revision with --all"))
3455 3461
3456 3462 res = []
3457 3463 prefix = "data/"
3458 3464 suffix = ".i"
3459 3465 plen = len(prefix)
3460 3466 slen = len(suffix)
3461 3467 with repo.lock():
3462 3468 for fn, b, size in repo.store.datafiles():
3463 3469 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
3464 3470 res.append(fn[plen:-slen])
3465 3471 ui.pager('manifest')
3466 3472 for f in res:
3467 3473 fm.startitem()
3468 3474 fm.write("path", '%s\n', f)
3469 3475 fm.end()
3470 3476 return
3471 3477
3472 3478 if rev and node:
3473 3479 raise error.Abort(_("please specify just one revision"))
3474 3480
3475 3481 if not node:
3476 3482 node = rev
3477 3483
3478 3484 char = {'l': '@', 'x': '*', '': ''}
3479 3485 mode = {'l': '644', 'x': '755', '': '644'}
3480 3486 ctx = scmutil.revsingle(repo, node)
3481 3487 mf = ctx.manifest()
3482 3488 ui.pager('manifest')
3483 3489 for f in ctx:
3484 3490 fm.startitem()
3485 3491 fl = ctx[f].flags()
3486 3492 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3487 3493 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3488 3494 fm.write('path', '%s\n', f)
3489 3495 fm.end()
3490 3496
3491 3497 @command('^merge',
3492 3498 [('f', 'force', None,
3493 3499 _('force a merge including outstanding changes (DEPRECATED)')),
3494 3500 ('r', 'rev', '', _('revision to merge'), _('REV')),
3495 3501 ('P', 'preview', None,
3496 3502 _('review revisions to merge (no merge is performed)'))
3497 3503 ] + mergetoolopts,
3498 3504 _('[-P] [[-r] REV]'))
3499 3505 def merge(ui, repo, node=None, **opts):
3500 3506 """merge another revision into working directory
3501 3507
3502 3508 The current working directory is updated with all changes made in
3503 3509 the requested revision since the last common predecessor revision.
3504 3510
3505 3511 Files that changed between either parent are marked as changed for
3506 3512 the next commit and a commit must be performed before any further
3507 3513 updates to the repository are allowed. The next commit will have
3508 3514 two parents.
3509 3515
3510 3516 ``--tool`` can be used to specify the merge tool used for file
3511 3517 merges. It overrides the HGMERGE environment variable and your
3512 3518 configuration files. See :hg:`help merge-tools` for options.
3513 3519
3514 3520 If no revision is specified, the working directory's parent is a
3515 3521 head revision, and the current branch contains exactly one other
3516 3522 head, the other head is merged with by default. Otherwise, an
3517 3523 explicit revision with which to merge with must be provided.
3518 3524
3519 3525 See :hg:`help resolve` for information on handling file conflicts.
3520 3526
3521 3527 To undo an uncommitted merge, use :hg:`update --clean .` which
3522 3528 will check out a clean copy of the original merge parent, losing
3523 3529 all changes.
3524 3530
3525 3531 Returns 0 on success, 1 if there are unresolved files.
3526 3532 """
3527 3533
3528 3534 if opts.get('rev') and node:
3529 3535 raise error.Abort(_("please specify just one revision"))
3530 3536 if not node:
3531 3537 node = opts.get('rev')
3532 3538
3533 3539 if node:
3534 3540 node = scmutil.revsingle(repo, node).node()
3535 3541
3536 3542 if not node:
3537 3543 node = repo[destutil.destmerge(repo)].node()
3538 3544
3539 3545 if opts.get('preview'):
3540 3546 # find nodes that are ancestors of p2 but not of p1
3541 3547 p1 = repo.lookup('.')
3542 3548 p2 = repo.lookup(node)
3543 3549 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
3544 3550
3545 3551 displayer = cmdutil.show_changeset(ui, repo, opts)
3546 3552 for node in nodes:
3547 3553 displayer.show(repo[node])
3548 3554 displayer.close()
3549 3555 return 0
3550 3556
3551 3557 try:
3552 3558 # ui.forcemerge is an internal variable, do not document
3553 3559 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
3554 3560 force = opts.get('force')
3555 3561 labels = ['working copy', 'merge rev']
3556 3562 return hg.merge(repo, node, force=force, mergeforce=force,
3557 3563 labels=labels)
3558 3564 finally:
3559 3565 ui.setconfig('ui', 'forcemerge', '', 'merge')
3560 3566
3561 3567 @command('outgoing|out',
3562 3568 [('f', 'force', None, _('run even when the destination is unrelated')),
3563 3569 ('r', 'rev', [],
3564 3570 _('a changeset intended to be included in the destination'), _('REV')),
3565 3571 ('n', 'newest-first', None, _('show newest record first')),
3566 3572 ('B', 'bookmarks', False, _('compare bookmarks')),
3567 3573 ('b', 'branch', [], _('a specific branch you would like to push'),
3568 3574 _('BRANCH')),
3569 3575 ] + logopts + remoteopts + subrepoopts,
3570 3576 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
3571 3577 def outgoing(ui, repo, dest=None, **opts):
3572 3578 """show changesets not found in the destination
3573 3579
3574 3580 Show changesets not found in the specified destination repository
3575 3581 or the default push location. These are the changesets that would
3576 3582 be pushed if a push was requested.
3577 3583
3578 3584 See pull for details of valid destination formats.
3579 3585
3580 3586 .. container:: verbose
3581 3587
3582 3588 With -B/--bookmarks, the result of bookmark comparison between
3583 3589 local and remote repositories is displayed. With -v/--verbose,
3584 3590 status is also displayed for each bookmark like below::
3585 3591
3586 3592 BM1 01234567890a added
3587 3593 BM2 deleted
3588 3594 BM3 234567890abc advanced
3589 3595 BM4 34567890abcd diverged
3590 3596 BM5 4567890abcde changed
3591 3597
3592 3598 The action taken when pushing depends on the
3593 3599 status of each bookmark:
3594 3600
3595 3601 :``added``: push with ``-B`` will create it
3596 3602 :``deleted``: push with ``-B`` will delete it
3597 3603 :``advanced``: push will update it
3598 3604 :``diverged``: push with ``-B`` will update it
3599 3605 :``changed``: push with ``-B`` will update it
3600 3606
3601 3607 From the point of view of pushing behavior, bookmarks
3602 3608 existing only in the remote repository are treated as
3603 3609 ``deleted``, even if it is in fact added remotely.
3604 3610
3605 3611 Returns 0 if there are outgoing changes, 1 otherwise.
3606 3612 """
3607 3613 if opts.get('graph'):
3608 3614 cmdutil.checkunsupportedgraphflags([], opts)
3609 3615 o, other = hg._outgoing(ui, repo, dest, opts)
3610 3616 if not o:
3611 3617 cmdutil.outgoinghooks(ui, repo, other, opts, o)
3612 3618 return
3613 3619
3614 3620 revdag = cmdutil.graphrevs(repo, o, opts)
3615 3621 ui.pager('outgoing')
3616 3622 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
3617 3623 cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
3618 3624 cmdutil.outgoinghooks(ui, repo, other, opts, o)
3619 3625 return 0
3620 3626
3621 3627 if opts.get('bookmarks'):
3622 3628 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3623 3629 dest, branches = hg.parseurl(dest, opts.get('branch'))
3624 3630 other = hg.peer(repo, opts, dest)
3625 3631 if 'bookmarks' not in other.listkeys('namespaces'):
3626 3632 ui.warn(_("remote doesn't support bookmarks\n"))
3627 3633 return 0
3628 3634 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
3629 3635 ui.pager('outgoing')
3630 3636 return bookmarks.outgoing(ui, repo, other)
3631 3637
3632 3638 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
3633 3639 try:
3634 3640 return hg.outgoing(ui, repo, dest, opts)
3635 3641 finally:
3636 3642 del repo._subtoppath
3637 3643
3638 3644 @command('parents',
3639 3645 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
3640 3646 ] + templateopts,
3641 3647 _('[-r REV] [FILE]'),
3642 3648 inferrepo=True)
3643 3649 def parents(ui, repo, file_=None, **opts):
3644 3650 """show the parents of the working directory or revision (DEPRECATED)
3645 3651
3646 3652 Print the working directory's parent revisions. If a revision is
3647 3653 given via -r/--rev, the parent of that revision will be printed.
3648 3654 If a file argument is given, the revision in which the file was
3649 3655 last changed (before the working directory revision or the
3650 3656 argument to --rev if given) is printed.
3651 3657
3652 3658 This command is equivalent to::
3653 3659
3654 3660 hg log -r "p1()+p2()" or
3655 3661 hg log -r "p1(REV)+p2(REV)" or
3656 3662 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
3657 3663 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
3658 3664
3659 3665 See :hg:`summary` and :hg:`help revsets` for related information.
3660 3666
3661 3667 Returns 0 on success.
3662 3668 """
3663 3669
3664 3670 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3665 3671
3666 3672 if file_:
3667 3673 m = scmutil.match(ctx, (file_,), opts)
3668 3674 if m.anypats() or len(m.files()) != 1:
3669 3675 raise error.Abort(_('can only specify an explicit filename'))
3670 3676 file_ = m.files()[0]
3671 3677 filenodes = []
3672 3678 for cp in ctx.parents():
3673 3679 if not cp:
3674 3680 continue
3675 3681 try:
3676 3682 filenodes.append(cp.filenode(file_))
3677 3683 except error.LookupError:
3678 3684 pass
3679 3685 if not filenodes:
3680 3686 raise error.Abort(_("'%s' not found in manifest!") % file_)
3681 3687 p = []
3682 3688 for fn in filenodes:
3683 3689 fctx = repo.filectx(file_, fileid=fn)
3684 3690 p.append(fctx.node())
3685 3691 else:
3686 3692 p = [cp.node() for cp in ctx.parents()]
3687 3693
3688 3694 displayer = cmdutil.show_changeset(ui, repo, opts)
3689 3695 for n in p:
3690 3696 if n != nullid:
3691 3697 displayer.show(repo[n])
3692 3698 displayer.close()
3693 3699
3694 3700 @command('paths', formatteropts, _('[NAME]'), optionalrepo=True)
3695 3701 def paths(ui, repo, search=None, **opts):
3696 3702 """show aliases for remote repositories
3697 3703
3698 3704 Show definition of symbolic path name NAME. If no name is given,
3699 3705 show definition of all available names.
3700 3706
3701 3707 Option -q/--quiet suppresses all output when searching for NAME
3702 3708 and shows only the path names when listing all definitions.
3703 3709
3704 3710 Path names are defined in the [paths] section of your
3705 3711 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
3706 3712 repository, ``.hg/hgrc`` is used, too.
3707 3713
3708 3714 The path names ``default`` and ``default-push`` have a special
3709 3715 meaning. When performing a push or pull operation, they are used
3710 3716 as fallbacks if no location is specified on the command-line.
3711 3717 When ``default-push`` is set, it will be used for push and
3712 3718 ``default`` will be used for pull; otherwise ``default`` is used
3713 3719 as the fallback for both. When cloning a repository, the clone
3714 3720 source is written as ``default`` in ``.hg/hgrc``.
3715 3721
3716 3722 .. note::
3717 3723
3718 3724 ``default`` and ``default-push`` apply to all inbound (e.g.
3719 3725 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
3720 3726 and :hg:`bundle`) operations.
3721 3727
3722 3728 See :hg:`help urls` for more information.
3723 3729
3724 3730 Returns 0 on success.
3725 3731 """
3726 3732 ui.pager('paths')
3727 3733 if search:
3728 3734 pathitems = [(name, path) for name, path in ui.paths.iteritems()
3729 3735 if name == search]
3730 3736 else:
3731 3737 pathitems = sorted(ui.paths.iteritems())
3732 3738
3733 3739 fm = ui.formatter('paths', opts)
3734 3740 if fm.isplain():
3735 3741 hidepassword = util.hidepassword
3736 3742 else:
3737 3743 hidepassword = str
3738 3744 if ui.quiet:
3739 3745 namefmt = '%s\n'
3740 3746 else:
3741 3747 namefmt = '%s = '
3742 3748 showsubopts = not search and not ui.quiet
3743 3749
3744 3750 for name, path in pathitems:
3745 3751 fm.startitem()
3746 3752 fm.condwrite(not search, 'name', namefmt, name)
3747 3753 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
3748 3754 for subopt, value in sorted(path.suboptions.items()):
3749 3755 assert subopt not in ('name', 'url')
3750 3756 if showsubopts:
3751 3757 fm.plain('%s:%s = ' % (name, subopt))
3752 3758 fm.condwrite(showsubopts, subopt, '%s\n', value)
3753 3759
3754 3760 fm.end()
3755 3761
3756 3762 if search and not pathitems:
3757 3763 if not ui.quiet:
3758 3764 ui.warn(_("not found!\n"))
3759 3765 return 1
3760 3766 else:
3761 3767 return 0
3762 3768
3763 3769 @command('phase',
3764 3770 [('p', 'public', False, _('set changeset phase to public')),
3765 3771 ('d', 'draft', False, _('set changeset phase to draft')),
3766 3772 ('s', 'secret', False, _('set changeset phase to secret')),
3767 3773 ('f', 'force', False, _('allow to move boundary backward')),
3768 3774 ('r', 'rev', [], _('target revision'), _('REV')),
3769 3775 ],
3770 3776 _('[-p|-d|-s] [-f] [-r] [REV...]'))
3771 3777 def phase(ui, repo, *revs, **opts):
3772 3778 """set or show the current phase name
3773 3779
3774 3780 With no argument, show the phase name of the current revision(s).
3775 3781
3776 3782 With one of -p/--public, -d/--draft or -s/--secret, change the
3777 3783 phase value of the specified revisions.
3778 3784
3779 3785 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
3780 3786 lower phase to an higher phase. Phases are ordered as follows::
3781 3787
3782 3788 public < draft < secret
3783 3789
3784 3790 Returns 0 on success, 1 if some phases could not be changed.
3785 3791
3786 3792 (For more information about the phases concept, see :hg:`help phases`.)
3787 3793 """
3788 3794 # search for a unique phase argument
3789 3795 targetphase = None
3790 3796 for idx, name in enumerate(phases.phasenames):
3791 3797 if opts[name]:
3792 3798 if targetphase is not None:
3793 3799 raise error.Abort(_('only one phase can be specified'))
3794 3800 targetphase = idx
3795 3801
3796 3802 # look for specified revision
3797 3803 revs = list(revs)
3798 3804 revs.extend(opts['rev'])
3799 3805 if not revs:
3800 3806 # display both parents as the second parent phase can influence
3801 3807 # the phase of a merge commit
3802 3808 revs = [c.rev() for c in repo[None].parents()]
3803 3809
3804 3810 revs = scmutil.revrange(repo, revs)
3805 3811
3806 3812 lock = None
3807 3813 ret = 0
3808 3814 if targetphase is None:
3809 3815 # display
3810 3816 for r in revs:
3811 3817 ctx = repo[r]
3812 3818 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
3813 3819 else:
3814 3820 tr = None
3815 3821 lock = repo.lock()
3816 3822 try:
3817 3823 tr = repo.transaction("phase")
3818 3824 # set phase
3819 3825 if not revs:
3820 3826 raise error.Abort(_('empty revision set'))
3821 3827 nodes = [repo[r].node() for r in revs]
3822 3828 # moving revision from public to draft may hide them
3823 3829 # We have to check result on an unfiltered repository
3824 3830 unfi = repo.unfiltered()
3825 3831 getphase = unfi._phasecache.phase
3826 3832 olddata = [getphase(unfi, r) for r in unfi]
3827 3833 phases.advanceboundary(repo, tr, targetphase, nodes)
3828 3834 if opts['force']:
3829 3835 phases.retractboundary(repo, tr, targetphase, nodes)
3830 3836 tr.close()
3831 3837 finally:
3832 3838 if tr is not None:
3833 3839 tr.release()
3834 3840 lock.release()
3835 3841 getphase = unfi._phasecache.phase
3836 3842 newdata = [getphase(unfi, r) for r in unfi]
3837 3843 changes = sum(newdata[r] != olddata[r] for r in unfi)
3838 3844 cl = unfi.changelog
3839 3845 rejected = [n for n in nodes
3840 3846 if newdata[cl.rev(n)] < targetphase]
3841 3847 if rejected:
3842 3848 ui.warn(_('cannot move %i changesets to a higher '
3843 3849 'phase, use --force\n') % len(rejected))
3844 3850 ret = 1
3845 3851 if changes:
3846 3852 msg = _('phase changed for %i changesets\n') % changes
3847 3853 if ret:
3848 3854 ui.status(msg)
3849 3855 else:
3850 3856 ui.note(msg)
3851 3857 else:
3852 3858 ui.warn(_('no phases changed\n'))
3853 3859 return ret
3854 3860
3855 3861 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
3856 3862 """Run after a changegroup has been added via pull/unbundle
3857 3863
3858 3864 This takes arguments below:
3859 3865
3860 3866 :modheads: change of heads by pull/unbundle
3861 3867 :optupdate: updating working directory is needed or not
3862 3868 :checkout: update destination revision (or None to default destination)
3863 3869 :brev: a name, which might be a bookmark to be activated after updating
3864 3870 """
3865 3871 if modheads == 0:
3866 3872 return
3867 3873 if optupdate:
3868 3874 try:
3869 3875 return hg.updatetotally(ui, repo, checkout, brev)
3870 3876 except error.UpdateAbort as inst:
3871 3877 msg = _("not updating: %s") % str(inst)
3872 3878 hint = inst.hint
3873 3879 raise error.UpdateAbort(msg, hint=hint)
3874 3880 if modheads > 1:
3875 3881 currentbranchheads = len(repo.branchheads())
3876 3882 if currentbranchheads == modheads:
3877 3883 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
3878 3884 elif currentbranchheads > 1:
3879 3885 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
3880 3886 "merge)\n"))
3881 3887 else:
3882 3888 ui.status(_("(run 'hg heads' to see heads)\n"))
3883 3889 else:
3884 3890 ui.status(_("(run 'hg update' to get a working copy)\n"))
3885 3891
3886 3892 @command('^pull',
3887 3893 [('u', 'update', None,
3888 3894 _('update to new branch head if changesets were pulled')),
3889 3895 ('f', 'force', None, _('run even when remote repository is unrelated')),
3890 3896 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3891 3897 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
3892 3898 ('b', 'branch', [], _('a specific branch you would like to pull'),
3893 3899 _('BRANCH')),
3894 3900 ] + remoteopts,
3895 3901 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
3896 3902 def pull(ui, repo, source="default", **opts):
3897 3903 """pull changes from the specified source
3898 3904
3899 3905 Pull changes from a remote repository to a local one.
3900 3906
3901 3907 This finds all changes from the repository at the specified path
3902 3908 or URL and adds them to a local repository (the current one unless
3903 3909 -R is specified). By default, this does not update the copy of the
3904 3910 project in the working directory.
3905 3911
3906 3912 Use :hg:`incoming` if you want to see what would have been added
3907 3913 by a pull at the time you issued this command. If you then decide
3908 3914 to add those changes to the repository, you should use :hg:`pull
3909 3915 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
3910 3916
3911 3917 If SOURCE is omitted, the 'default' path will be used.
3912 3918 See :hg:`help urls` for more information.
3913 3919
3914 3920 Specifying bookmark as ``.`` is equivalent to specifying the active
3915 3921 bookmark's name.
3916 3922
3917 3923 Returns 0 on success, 1 if an update had unresolved files.
3918 3924 """
3919 3925 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
3920 3926 ui.status(_('pulling from %s\n') % util.hidepassword(source))
3921 3927 other = hg.peer(repo, opts, source)
3922 3928 try:
3923 3929 revs, checkout = hg.addbranchrevs(repo, other, branches,
3924 3930 opts.get('rev'))
3925 3931
3926 3932
3927 3933 pullopargs = {}
3928 3934 if opts.get('bookmark'):
3929 3935 if not revs:
3930 3936 revs = []
3931 3937 # The list of bookmark used here is not the one used to actually
3932 3938 # update the bookmark name. This can result in the revision pulled
3933 3939 # not ending up with the name of the bookmark because of a race
3934 3940 # condition on the server. (See issue 4689 for details)
3935 3941 remotebookmarks = other.listkeys('bookmarks')
3936 3942 pullopargs['remotebookmarks'] = remotebookmarks
3937 3943 for b in opts['bookmark']:
3938 3944 b = repo._bookmarks.expandname(b)
3939 3945 if b not in remotebookmarks:
3940 3946 raise error.Abort(_('remote bookmark %s not found!') % b)
3941 3947 revs.append(remotebookmarks[b])
3942 3948
3943 3949 if revs:
3944 3950 try:
3945 3951 # When 'rev' is a bookmark name, we cannot guarantee that it
3946 3952 # will be updated with that name because of a race condition
3947 3953 # server side. (See issue 4689 for details)
3948 3954 oldrevs = revs
3949 3955 revs = [] # actually, nodes
3950 3956 for r in oldrevs:
3951 3957 node = other.lookup(r)
3952 3958 revs.append(node)
3953 3959 if r == checkout:
3954 3960 checkout = node
3955 3961 except error.CapabilityError:
3956 3962 err = _("other repository doesn't support revision lookup, "
3957 3963 "so a rev cannot be specified.")
3958 3964 raise error.Abort(err)
3959 3965
3960 3966 pullopargs.update(opts.get('opargs', {}))
3961 3967 modheads = exchange.pull(repo, other, heads=revs,
3962 3968 force=opts.get('force'),
3963 3969 bookmarks=opts.get('bookmark', ()),
3964 3970 opargs=pullopargs).cgresult
3965 3971
3966 3972 # brev is a name, which might be a bookmark to be activated at
3967 3973 # the end of the update. In other words, it is an explicit
3968 3974 # destination of the update
3969 3975 brev = None
3970 3976
3971 3977 if checkout:
3972 3978 checkout = str(repo.changelog.rev(checkout))
3973 3979
3974 3980 # order below depends on implementation of
3975 3981 # hg.addbranchrevs(). opts['bookmark'] is ignored,
3976 3982 # because 'checkout' is determined without it.
3977 3983 if opts.get('rev'):
3978 3984 brev = opts['rev'][0]
3979 3985 elif opts.get('branch'):
3980 3986 brev = opts['branch'][0]
3981 3987 else:
3982 3988 brev = branches[0]
3983 3989 repo._subtoppath = source
3984 3990 try:
3985 3991 ret = postincoming(ui, repo, modheads, opts.get('update'),
3986 3992 checkout, brev)
3987 3993
3988 3994 finally:
3989 3995 del repo._subtoppath
3990 3996
3991 3997 finally:
3992 3998 other.close()
3993 3999 return ret
3994 4000
3995 4001 @command('^push',
3996 4002 [('f', 'force', None, _('force push')),
3997 4003 ('r', 'rev', [],
3998 4004 _('a changeset intended to be included in the destination'),
3999 4005 _('REV')),
4000 4006 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4001 4007 ('b', 'branch', [],
4002 4008 _('a specific branch you would like to push'), _('BRANCH')),
4003 4009 ('', 'new-branch', False, _('allow pushing a new branch')),
4004 4010 ] + remoteopts,
4005 4011 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4006 4012 def push(ui, repo, dest=None, **opts):
4007 4013 """push changes to the specified destination
4008 4014
4009 4015 Push changesets from the local repository to the specified
4010 4016 destination.
4011 4017
4012 4018 This operation is symmetrical to pull: it is identical to a pull
4013 4019 in the destination repository from the current one.
4014 4020
4015 4021 By default, push will not allow creation of new heads at the
4016 4022 destination, since multiple heads would make it unclear which head
4017 4023 to use. In this situation, it is recommended to pull and merge
4018 4024 before pushing.
4019 4025
4020 4026 Use --new-branch if you want to allow push to create a new named
4021 4027 branch that is not present at the destination. This allows you to
4022 4028 only create a new branch without forcing other changes.
4023 4029
4024 4030 .. note::
4025 4031
4026 4032 Extra care should be taken with the -f/--force option,
4027 4033 which will push all new heads on all branches, an action which will
4028 4034 almost always cause confusion for collaborators.
4029 4035
4030 4036 If -r/--rev is used, the specified revision and all its ancestors
4031 4037 will be pushed to the remote repository.
4032 4038
4033 4039 If -B/--bookmark is used, the specified bookmarked revision, its
4034 4040 ancestors, and the bookmark will be pushed to the remote
4035 4041 repository. Specifying ``.`` is equivalent to specifying the active
4036 4042 bookmark's name.
4037 4043
4038 4044 Please see :hg:`help urls` for important details about ``ssh://``
4039 4045 URLs. If DESTINATION is omitted, a default path will be used.
4040 4046
4041 4047 Returns 0 if push was successful, 1 if nothing to push.
4042 4048 """
4043 4049
4044 4050 if opts.get('bookmark'):
4045 4051 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4046 4052 for b in opts['bookmark']:
4047 4053 # translate -B options to -r so changesets get pushed
4048 4054 b = repo._bookmarks.expandname(b)
4049 4055 if b in repo._bookmarks:
4050 4056 opts.setdefault('rev', []).append(b)
4051 4057 else:
4052 4058 # if we try to push a deleted bookmark, translate it to null
4053 4059 # this lets simultaneous -r, -b options continue working
4054 4060 opts.setdefault('rev', []).append("null")
4055 4061
4056 4062 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4057 4063 if not path:
4058 4064 raise error.Abort(_('default repository not configured!'),
4059 4065 hint=_("see 'hg help config.paths'"))
4060 4066 dest = path.pushloc or path.loc
4061 4067 branches = (path.branch, opts.get('branch') or [])
4062 4068 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4063 4069 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4064 4070 other = hg.peer(repo, opts, dest)
4065 4071
4066 4072 if revs:
4067 4073 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
4068 4074 if not revs:
4069 4075 raise error.Abort(_("specified revisions evaluate to an empty set"),
4070 4076 hint=_("use different revision arguments"))
4071 4077 elif path.pushrev:
4072 4078 # It doesn't make any sense to specify ancestor revisions. So limit
4073 4079 # to DAG heads to make discovery simpler.
4074 4080 expr = revsetlang.formatspec('heads(%r)', path.pushrev)
4075 4081 revs = scmutil.revrange(repo, [expr])
4076 4082 revs = [repo[rev].node() for rev in revs]
4077 4083 if not revs:
4078 4084 raise error.Abort(_('default push revset for path evaluates to an '
4079 4085 'empty set'))
4080 4086
4081 4087 repo._subtoppath = dest
4082 4088 try:
4083 4089 # push subrepos depth-first for coherent ordering
4084 4090 c = repo['']
4085 4091 subs = c.substate # only repos that are committed
4086 4092 for s in sorted(subs):
4087 4093 result = c.sub(s).push(opts)
4088 4094 if result == 0:
4089 4095 return not result
4090 4096 finally:
4091 4097 del repo._subtoppath
4092 4098 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4093 4099 newbranch=opts.get('new_branch'),
4094 4100 bookmarks=opts.get('bookmark', ()),
4095 4101 opargs=opts.get('opargs'))
4096 4102
4097 4103 result = not pushop.cgresult
4098 4104
4099 4105 if pushop.bkresult is not None:
4100 4106 if pushop.bkresult == 2:
4101 4107 result = 2
4102 4108 elif not result and pushop.bkresult:
4103 4109 result = 2
4104 4110
4105 4111 return result
4106 4112
4107 4113 @command('recover', [])
4108 4114 def recover(ui, repo):
4109 4115 """roll back an interrupted transaction
4110 4116
4111 4117 Recover from an interrupted commit or pull.
4112 4118
4113 4119 This command tries to fix the repository status after an
4114 4120 interrupted operation. It should only be necessary when Mercurial
4115 4121 suggests it.
4116 4122
4117 4123 Returns 0 if successful, 1 if nothing to recover or verify fails.
4118 4124 """
4119 4125 if repo.recover():
4120 4126 return hg.verify(repo)
4121 4127 return 1
4122 4128
4123 4129 @command('^remove|rm',
4124 4130 [('A', 'after', None, _('record delete for missing files')),
4125 4131 ('f', 'force', None,
4126 4132 _('forget added files, delete modified files')),
4127 4133 ] + subrepoopts + walkopts,
4128 4134 _('[OPTION]... FILE...'),
4129 4135 inferrepo=True)
4130 4136 def remove(ui, repo, *pats, **opts):
4131 4137 """remove the specified files on the next commit
4132 4138
4133 4139 Schedule the indicated files for removal from the current branch.
4134 4140
4135 4141 This command schedules the files to be removed at the next commit.
4136 4142 To undo a remove before that, see :hg:`revert`. To undo added
4137 4143 files, see :hg:`forget`.
4138 4144
4139 4145 .. container:: verbose
4140 4146
4141 4147 -A/--after can be used to remove only files that have already
4142 4148 been deleted, -f/--force can be used to force deletion, and -Af
4143 4149 can be used to remove files from the next revision without
4144 4150 deleting them from the working directory.
4145 4151
4146 4152 The following table details the behavior of remove for different
4147 4153 file states (columns) and option combinations (rows). The file
4148 4154 states are Added [A], Clean [C], Modified [M] and Missing [!]
4149 4155 (as reported by :hg:`status`). The actions are Warn, Remove
4150 4156 (from branch) and Delete (from disk):
4151 4157
4152 4158 ========= == == == ==
4153 4159 opt/state A C M !
4154 4160 ========= == == == ==
4155 4161 none W RD W R
4156 4162 -f R RD RD R
4157 4163 -A W W W R
4158 4164 -Af R R R R
4159 4165 ========= == == == ==
4160 4166
4161 4167 .. note::
4162 4168
4163 4169 :hg:`remove` never deletes files in Added [A] state from the
4164 4170 working directory, not even if ``--force`` is specified.
4165 4171
4166 4172 Returns 0 on success, 1 if any warnings encountered.
4167 4173 """
4168 4174
4169 4175 after, force = opts.get('after'), opts.get('force')
4170 4176 if not pats and not after:
4171 4177 raise error.Abort(_('no files specified'))
4172 4178
4173 4179 m = scmutil.match(repo[None], pats, opts)
4174 4180 subrepos = opts.get('subrepos')
4175 4181 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
4176 4182
4177 4183 @command('rename|move|mv',
4178 4184 [('A', 'after', None, _('record a rename that has already occurred')),
4179 4185 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4180 4186 ] + walkopts + dryrunopts,
4181 4187 _('[OPTION]... SOURCE... DEST'))
4182 4188 def rename(ui, repo, *pats, **opts):
4183 4189 """rename files; equivalent of copy + remove
4184 4190
4185 4191 Mark dest as copies of sources; mark sources for deletion. If dest
4186 4192 is a directory, copies are put in that directory. If dest is a
4187 4193 file, there can only be one source.
4188 4194
4189 4195 By default, this command copies the contents of files as they
4190 4196 exist in the working directory. If invoked with -A/--after, the
4191 4197 operation is recorded, but no copying is performed.
4192 4198
4193 4199 This command takes effect at the next commit. To undo a rename
4194 4200 before that, see :hg:`revert`.
4195 4201
4196 4202 Returns 0 on success, 1 if errors are encountered.
4197 4203 """
4198 4204 with repo.wlock(False):
4199 4205 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4200 4206
4201 4207 @command('resolve',
4202 4208 [('a', 'all', None, _('select all unresolved files')),
4203 4209 ('l', 'list', None, _('list state of files needing merge')),
4204 4210 ('m', 'mark', None, _('mark files as resolved')),
4205 4211 ('u', 'unmark', None, _('mark files as unresolved')),
4206 4212 ('n', 'no-status', None, _('hide status prefix'))]
4207 4213 + mergetoolopts + walkopts + formatteropts,
4208 4214 _('[OPTION]... [FILE]...'),
4209 4215 inferrepo=True)
4210 4216 def resolve(ui, repo, *pats, **opts):
4211 4217 """redo merges or set/view the merge status of files
4212 4218
4213 4219 Merges with unresolved conflicts are often the result of
4214 4220 non-interactive merging using the ``internal:merge`` configuration
4215 4221 setting, or a command-line merge tool like ``diff3``. The resolve
4216 4222 command is used to manage the files involved in a merge, after
4217 4223 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4218 4224 working directory must have two parents). See :hg:`help
4219 4225 merge-tools` for information on configuring merge tools.
4220 4226
4221 4227 The resolve command can be used in the following ways:
4222 4228
4223 4229 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4224 4230 files, discarding any previous merge attempts. Re-merging is not
4225 4231 performed for files already marked as resolved. Use ``--all/-a``
4226 4232 to select all unresolved files. ``--tool`` can be used to specify
4227 4233 the merge tool used for the given files. It overrides the HGMERGE
4228 4234 environment variable and your configuration files. Previous file
4229 4235 contents are saved with a ``.orig`` suffix.
4230 4236
4231 4237 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4232 4238 (e.g. after having manually fixed-up the files). The default is
4233 4239 to mark all unresolved files.
4234 4240
4235 4241 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4236 4242 default is to mark all resolved files.
4237 4243
4238 4244 - :hg:`resolve -l`: list files which had or still have conflicts.
4239 4245 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4240 4246 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
4241 4247 the list. See :hg:`help filesets` for details.
4242 4248
4243 4249 .. note::
4244 4250
4245 4251 Mercurial will not let you commit files with unresolved merge
4246 4252 conflicts. You must use :hg:`resolve -m ...` before you can
4247 4253 commit after a conflicting merge.
4248 4254
4249 4255 Returns 0 on success, 1 if any files fail a resolve attempt.
4250 4256 """
4251 4257
4252 4258 flaglist = 'all mark unmark list no_status'.split()
4253 4259 all, mark, unmark, show, nostatus = \
4254 4260 [opts.get(o) for o in flaglist]
4255 4261
4256 4262 if (show and (mark or unmark)) or (mark and unmark):
4257 4263 raise error.Abort(_("too many options specified"))
4258 4264 if pats and all:
4259 4265 raise error.Abort(_("can't specify --all and patterns"))
4260 4266 if not (all or pats or show or mark or unmark):
4261 4267 raise error.Abort(_('no files or directories specified'),
4262 4268 hint=('use --all to re-merge all unresolved files'))
4263 4269
4264 4270 if show:
4265 4271 ui.pager('resolve')
4266 4272 fm = ui.formatter('resolve', opts)
4267 4273 ms = mergemod.mergestate.read(repo)
4268 4274 m = scmutil.match(repo[None], pats, opts)
4269 4275 for f in ms:
4270 4276 if not m(f):
4271 4277 continue
4272 4278 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved',
4273 4279 'd': 'driverresolved'}[ms[f]]
4274 4280 fm.startitem()
4275 4281 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
4276 4282 fm.write('path', '%s\n', f, label=l)
4277 4283 fm.end()
4278 4284 return 0
4279 4285
4280 4286 with repo.wlock():
4281 4287 ms = mergemod.mergestate.read(repo)
4282 4288
4283 4289 if not (ms.active() or repo.dirstate.p2() != nullid):
4284 4290 raise error.Abort(
4285 4291 _('resolve command not applicable when not merging'))
4286 4292
4287 4293 wctx = repo[None]
4288 4294
4289 4295 if ms.mergedriver and ms.mdstate() == 'u':
4290 4296 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4291 4297 ms.commit()
4292 4298 # allow mark and unmark to go through
4293 4299 if not mark and not unmark and not proceed:
4294 4300 return 1
4295 4301
4296 4302 m = scmutil.match(wctx, pats, opts)
4297 4303 ret = 0
4298 4304 didwork = False
4299 4305 runconclude = False
4300 4306
4301 4307 tocomplete = []
4302 4308 for f in ms:
4303 4309 if not m(f):
4304 4310 continue
4305 4311
4306 4312 didwork = True
4307 4313
4308 4314 # don't let driver-resolved files be marked, and run the conclude
4309 4315 # step if asked to resolve
4310 4316 if ms[f] == "d":
4311 4317 exact = m.exact(f)
4312 4318 if mark:
4313 4319 if exact:
4314 4320 ui.warn(_('not marking %s as it is driver-resolved\n')
4315 4321 % f)
4316 4322 elif unmark:
4317 4323 if exact:
4318 4324 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4319 4325 % f)
4320 4326 else:
4321 4327 runconclude = True
4322 4328 continue
4323 4329
4324 4330 if mark:
4325 4331 ms.mark(f, "r")
4326 4332 elif unmark:
4327 4333 ms.mark(f, "u")
4328 4334 else:
4329 4335 # backup pre-resolve (merge uses .orig for its own purposes)
4330 4336 a = repo.wjoin(f)
4331 4337 try:
4332 4338 util.copyfile(a, a + ".resolve")
4333 4339 except (IOError, OSError) as inst:
4334 4340 if inst.errno != errno.ENOENT:
4335 4341 raise
4336 4342
4337 4343 try:
4338 4344 # preresolve file
4339 4345 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4340 4346 'resolve')
4341 4347 complete, r = ms.preresolve(f, wctx)
4342 4348 if not complete:
4343 4349 tocomplete.append(f)
4344 4350 elif r:
4345 4351 ret = 1
4346 4352 finally:
4347 4353 ui.setconfig('ui', 'forcemerge', '', 'resolve')
4348 4354 ms.commit()
4349 4355
4350 4356 # replace filemerge's .orig file with our resolve file, but only
4351 4357 # for merges that are complete
4352 4358 if complete:
4353 4359 try:
4354 4360 util.rename(a + ".resolve",
4355 4361 scmutil.origpath(ui, repo, a))
4356 4362 except OSError as inst:
4357 4363 if inst.errno != errno.ENOENT:
4358 4364 raise
4359 4365
4360 4366 for f in tocomplete:
4361 4367 try:
4362 4368 # resolve file
4363 4369 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4364 4370 'resolve')
4365 4371 r = ms.resolve(f, wctx)
4366 4372 if r:
4367 4373 ret = 1
4368 4374 finally:
4369 4375 ui.setconfig('ui', 'forcemerge', '', 'resolve')
4370 4376 ms.commit()
4371 4377
4372 4378 # replace filemerge's .orig file with our resolve file
4373 4379 a = repo.wjoin(f)
4374 4380 try:
4375 4381 util.rename(a + ".resolve", scmutil.origpath(ui, repo, a))
4376 4382 except OSError as inst:
4377 4383 if inst.errno != errno.ENOENT:
4378 4384 raise
4379 4385
4380 4386 ms.commit()
4381 4387 ms.recordactions()
4382 4388
4383 4389 if not didwork and pats:
4384 4390 hint = None
4385 4391 if not any([p for p in pats if p.find(':') >= 0]):
4386 4392 pats = ['path:%s' % p for p in pats]
4387 4393 m = scmutil.match(wctx, pats, opts)
4388 4394 for f in ms:
4389 4395 if not m(f):
4390 4396 continue
4391 4397 flags = ''.join(['-%s ' % o[0] for o in flaglist
4392 4398 if opts.get(o)])
4393 4399 hint = _("(try: hg resolve %s%s)\n") % (
4394 4400 flags,
4395 4401 ' '.join(pats))
4396 4402 break
4397 4403 ui.warn(_("arguments do not match paths that need resolving\n"))
4398 4404 if hint:
4399 4405 ui.warn(hint)
4400 4406 elif ms.mergedriver and ms.mdstate() != 's':
4401 4407 # run conclude step when either a driver-resolved file is requested
4402 4408 # or there are no driver-resolved files
4403 4409 # we can't use 'ret' to determine whether any files are unresolved
4404 4410 # because we might not have tried to resolve some
4405 4411 if ((runconclude or not list(ms.driverresolved()))
4406 4412 and not list(ms.unresolved())):
4407 4413 proceed = mergemod.driverconclude(repo, ms, wctx)
4408 4414 ms.commit()
4409 4415 if not proceed:
4410 4416 return 1
4411 4417
4412 4418 # Nudge users into finishing an unfinished operation
4413 4419 unresolvedf = list(ms.unresolved())
4414 4420 driverresolvedf = list(ms.driverresolved())
4415 4421 if not unresolvedf and not driverresolvedf:
4416 4422 ui.status(_('(no more unresolved files)\n'))
4417 4423 cmdutil.checkafterresolved(repo)
4418 4424 elif not unresolvedf:
4419 4425 ui.status(_('(no more unresolved files -- '
4420 4426 'run "hg resolve --all" to conclude)\n'))
4421 4427
4422 4428 return ret
4423 4429
4424 4430 @command('revert',
4425 4431 [('a', 'all', None, _('revert all changes when no arguments given')),
4426 4432 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4427 4433 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4428 4434 ('C', 'no-backup', None, _('do not save backup copies of files')),
4429 4435 ('i', 'interactive', None,
4430 4436 _('interactively select the changes (EXPERIMENTAL)')),
4431 4437 ] + walkopts + dryrunopts,
4432 4438 _('[OPTION]... [-r REV] [NAME]...'))
4433 4439 def revert(ui, repo, *pats, **opts):
4434 4440 """restore files to their checkout state
4435 4441
4436 4442 .. note::
4437 4443
4438 4444 To check out earlier revisions, you should use :hg:`update REV`.
4439 4445 To cancel an uncommitted merge (and lose your changes),
4440 4446 use :hg:`update --clean .`.
4441 4447
4442 4448 With no revision specified, revert the specified files or directories
4443 4449 to the contents they had in the parent of the working directory.
4444 4450 This restores the contents of files to an unmodified
4445 4451 state and unschedules adds, removes, copies, and renames. If the
4446 4452 working directory has two parents, you must explicitly specify a
4447 4453 revision.
4448 4454
4449 4455 Using the -r/--rev or -d/--date options, revert the given files or
4450 4456 directories to their states as of a specific revision. Because
4451 4457 revert does not change the working directory parents, this will
4452 4458 cause these files to appear modified. This can be helpful to "back
4453 4459 out" some or all of an earlier change. See :hg:`backout` for a
4454 4460 related method.
4455 4461
4456 4462 Modified files are saved with a .orig suffix before reverting.
4457 4463 To disable these backups, use --no-backup. It is possible to store
4458 4464 the backup files in a custom directory relative to the root of the
4459 4465 repository by setting the ``ui.origbackuppath`` configuration
4460 4466 option.
4461 4467
4462 4468 See :hg:`help dates` for a list of formats valid for -d/--date.
4463 4469
4464 4470 See :hg:`help backout` for a way to reverse the effect of an
4465 4471 earlier changeset.
4466 4472
4467 4473 Returns 0 on success.
4468 4474 """
4469 4475
4470 4476 if opts.get("date"):
4471 4477 if opts.get("rev"):
4472 4478 raise error.Abort(_("you can't specify a revision and a date"))
4473 4479 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
4474 4480
4475 4481 parent, p2 = repo.dirstate.parents()
4476 4482 if not opts.get('rev') and p2 != nullid:
4477 4483 # revert after merge is a trap for new users (issue2915)
4478 4484 raise error.Abort(_('uncommitted merge with no revision specified'),
4479 4485 hint=_("use 'hg update' or see 'hg help revert'"))
4480 4486
4481 4487 ctx = scmutil.revsingle(repo, opts.get('rev'))
4482 4488
4483 4489 if (not (pats or opts.get('include') or opts.get('exclude') or
4484 4490 opts.get('all') or opts.get('interactive'))):
4485 4491 msg = _("no files or directories specified")
4486 4492 if p2 != nullid:
4487 4493 hint = _("uncommitted merge, use --all to discard all changes,"
4488 4494 " or 'hg update -C .' to abort the merge")
4489 4495 raise error.Abort(msg, hint=hint)
4490 4496 dirty = any(repo.status())
4491 4497 node = ctx.node()
4492 4498 if node != parent:
4493 4499 if dirty:
4494 4500 hint = _("uncommitted changes, use --all to discard all"
4495 4501 " changes, or 'hg update %s' to update") % ctx.rev()
4496 4502 else:
4497 4503 hint = _("use --all to revert all files,"
4498 4504 " or 'hg update %s' to update") % ctx.rev()
4499 4505 elif dirty:
4500 4506 hint = _("uncommitted changes, use --all to discard all changes")
4501 4507 else:
4502 4508 hint = _("use --all to revert all files")
4503 4509 raise error.Abort(msg, hint=hint)
4504 4510
4505 4511 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
4506 4512
4507 4513 @command('rollback', dryrunopts +
4508 4514 [('f', 'force', False, _('ignore safety measures'))])
4509 4515 def rollback(ui, repo, **opts):
4510 4516 """roll back the last transaction (DANGEROUS) (DEPRECATED)
4511 4517
4512 4518 Please use :hg:`commit --amend` instead of rollback to correct
4513 4519 mistakes in the last commit.
4514 4520
4515 4521 This command should be used with care. There is only one level of
4516 4522 rollback, and there is no way to undo a rollback. It will also
4517 4523 restore the dirstate at the time of the last transaction, losing
4518 4524 any dirstate changes since that time. This command does not alter
4519 4525 the working directory.
4520 4526
4521 4527 Transactions are used to encapsulate the effects of all commands
4522 4528 that create new changesets or propagate existing changesets into a
4523 4529 repository.
4524 4530
4525 4531 .. container:: verbose
4526 4532
4527 4533 For example, the following commands are transactional, and their
4528 4534 effects can be rolled back:
4529 4535
4530 4536 - commit
4531 4537 - import
4532 4538 - pull
4533 4539 - push (with this repository as the destination)
4534 4540 - unbundle
4535 4541
4536 4542 To avoid permanent data loss, rollback will refuse to rollback a
4537 4543 commit transaction if it isn't checked out. Use --force to
4538 4544 override this protection.
4539 4545
4540 4546 The rollback command can be entirely disabled by setting the
4541 4547 ``ui.rollback`` configuration setting to false. If you're here
4542 4548 because you want to use rollback and it's disabled, you can
4543 4549 re-enable the command by setting ``ui.rollback`` to true.
4544 4550
4545 4551 This command is not intended for use on public repositories. Once
4546 4552 changes are visible for pull by other users, rolling a transaction
4547 4553 back locally is ineffective (someone else may already have pulled
4548 4554 the changes). Furthermore, a race is possible with readers of the
4549 4555 repository; for example an in-progress pull from the repository
4550 4556 may fail if a rollback is performed.
4551 4557
4552 4558 Returns 0 on success, 1 if no rollback data is available.
4553 4559 """
4554 4560 if not ui.configbool('ui', 'rollback', True):
4555 4561 raise error.Abort(_('rollback is disabled because it is unsafe'),
4556 4562 hint=('see `hg help -v rollback` for information'))
4557 4563 return repo.rollback(dryrun=opts.get('dry_run'),
4558 4564 force=opts.get('force'))
4559 4565
4560 4566 @command('root', [])
4561 4567 def root(ui, repo):
4562 4568 """print the root (top) of the current working directory
4563 4569
4564 4570 Print the root directory of the current repository.
4565 4571
4566 4572 Returns 0 on success.
4567 4573 """
4568 4574 ui.write(repo.root + "\n")
4569 4575
4570 4576 @command('^serve',
4571 4577 [('A', 'accesslog', '', _('name of access log file to write to'),
4572 4578 _('FILE')),
4573 4579 ('d', 'daemon', None, _('run server in background')),
4574 4580 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
4575 4581 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
4576 4582 # use string type, then we can check if something was passed
4577 4583 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
4578 4584 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
4579 4585 _('ADDR')),
4580 4586 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
4581 4587 _('PREFIX')),
4582 4588 ('n', 'name', '',
4583 4589 _('name to show in web pages (default: working directory)'), _('NAME')),
4584 4590 ('', 'web-conf', '',
4585 4591 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
4586 4592 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
4587 4593 _('FILE')),
4588 4594 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
4589 4595 ('', 'stdio', None, _('for remote clients (ADVANCED)')),
4590 4596 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
4591 4597 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
4592 4598 ('', 'style', '', _('template style to use'), _('STYLE')),
4593 4599 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4594 4600 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
4595 4601 _('[OPTION]...'),
4596 4602 optionalrepo=True)
4597 4603 def serve(ui, repo, **opts):
4598 4604 """start stand-alone webserver
4599 4605
4600 4606 Start a local HTTP repository browser and pull server. You can use
4601 4607 this for ad-hoc sharing and browsing of repositories. It is
4602 4608 recommended to use a real web server to serve a repository for
4603 4609 longer periods of time.
4604 4610
4605 4611 Please note that the server does not implement access control.
4606 4612 This means that, by default, anybody can read from the server and
4607 4613 nobody can write to it by default. Set the ``web.allow_push``
4608 4614 option to ``*`` to allow everybody to push to the server. You
4609 4615 should use a real web server if you need to authenticate users.
4610 4616
4611 4617 By default, the server logs accesses to stdout and errors to
4612 4618 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
4613 4619 files.
4614 4620
4615 4621 To have the server choose a free port number to listen on, specify
4616 4622 a port number of 0; in this case, the server will print the port
4617 4623 number it uses.
4618 4624
4619 4625 Returns 0 on success.
4620 4626 """
4621 4627
4622 4628 if opts["stdio"] and opts["cmdserver"]:
4623 4629 raise error.Abort(_("cannot use --stdio with --cmdserver"))
4624 4630
4625 4631 if opts["stdio"]:
4626 4632 if repo is None:
4627 4633 raise error.RepoError(_("there is no Mercurial repository here"
4628 4634 " (.hg not found)"))
4629 4635 s = sshserver.sshserver(ui, repo)
4630 4636 s.serve_forever()
4631 4637
4632 4638 service = server.createservice(ui, repo, opts)
4633 4639 return server.runservice(opts, initfn=service.init, runfn=service.run)
4634 4640
4635 4641 @command('^status|st',
4636 4642 [('A', 'all', None, _('show status of all files')),
4637 4643 ('m', 'modified', None, _('show only modified files')),
4638 4644 ('a', 'added', None, _('show only added files')),
4639 4645 ('r', 'removed', None, _('show only removed files')),
4640 4646 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4641 4647 ('c', 'clean', None, _('show only files without changes')),
4642 4648 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4643 4649 ('i', 'ignored', None, _('show only ignored files')),
4644 4650 ('n', 'no-status', None, _('hide status prefix')),
4645 4651 ('C', 'copies', None, _('show source of copied files')),
4646 4652 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4647 4653 ('', 'rev', [], _('show difference from revision'), _('REV')),
4648 4654 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
4649 4655 ] + walkopts + subrepoopts + formatteropts,
4650 4656 _('[OPTION]... [FILE]...'),
4651 4657 inferrepo=True)
4652 4658 def status(ui, repo, *pats, **opts):
4653 4659 """show changed files in the working directory
4654 4660
4655 4661 Show status of files in the repository. If names are given, only
4656 4662 files that match are shown. Files that are clean or ignored or
4657 4663 the source of a copy/move operation, are not listed unless
4658 4664 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
4659 4665 Unless options described with "show only ..." are given, the
4660 4666 options -mardu are used.
4661 4667
4662 4668 Option -q/--quiet hides untracked (unknown and ignored) files
4663 4669 unless explicitly requested with -u/--unknown or -i/--ignored.
4664 4670
4665 4671 .. note::
4666 4672
4667 4673 :hg:`status` may appear to disagree with diff if permissions have
4668 4674 changed or a merge has occurred. The standard diff format does
4669 4675 not report permission changes and diff only reports changes
4670 4676 relative to one merge parent.
4671 4677
4672 4678 If one revision is given, it is used as the base revision.
4673 4679 If two revisions are given, the differences between them are
4674 4680 shown. The --change option can also be used as a shortcut to list
4675 4681 the changed files of a revision from its first parent.
4676 4682
4677 4683 The codes used to show the status of files are::
4678 4684
4679 4685 M = modified
4680 4686 A = added
4681 4687 R = removed
4682 4688 C = clean
4683 4689 ! = missing (deleted by non-hg command, but still tracked)
4684 4690 ? = not tracked
4685 4691 I = ignored
4686 4692 = origin of the previous file (with --copies)
4687 4693
4688 4694 .. container:: verbose
4689 4695
4690 4696 Examples:
4691 4697
4692 4698 - show changes in the working directory relative to a
4693 4699 changeset::
4694 4700
4695 4701 hg status --rev 9353
4696 4702
4697 4703 - show changes in the working directory relative to the
4698 4704 current directory (see :hg:`help patterns` for more information)::
4699 4705
4700 4706 hg status re:
4701 4707
4702 4708 - show all changes including copies in an existing changeset::
4703 4709
4704 4710 hg status --copies --change 9353
4705 4711
4706 4712 - get a NUL separated list of added files, suitable for xargs::
4707 4713
4708 4714 hg status -an0
4709 4715
4710 4716 Returns 0 on success.
4711 4717 """
4712 4718
4713 4719 revs = opts.get('rev')
4714 4720 change = opts.get('change')
4715 4721
4716 4722 if revs and change:
4717 4723 msg = _('cannot specify --rev and --change at the same time')
4718 4724 raise error.Abort(msg)
4719 4725 elif change:
4720 4726 node2 = scmutil.revsingle(repo, change, None).node()
4721 4727 node1 = repo[node2].p1().node()
4722 4728 else:
4723 4729 node1, node2 = scmutil.revpair(repo, revs)
4724 4730
4725 4731 if pats:
4726 4732 cwd = repo.getcwd()
4727 4733 else:
4728 4734 cwd = ''
4729 4735
4730 4736 if opts.get('print0'):
4731 4737 end = '\0'
4732 4738 else:
4733 4739 end = '\n'
4734 4740 copy = {}
4735 4741 states = 'modified added removed deleted unknown ignored clean'.split()
4736 4742 show = [k for k in states if opts.get(k)]
4737 4743 if opts.get('all'):
4738 4744 show += ui.quiet and (states[:4] + ['clean']) or states
4739 4745 if not show:
4740 4746 if ui.quiet:
4741 4747 show = states[:4]
4742 4748 else:
4743 4749 show = states[:5]
4744 4750
4745 4751 m = scmutil.match(repo[node2], pats, opts)
4746 4752 stat = repo.status(node1, node2, m,
4747 4753 'ignored' in show, 'clean' in show, 'unknown' in show,
4748 4754 opts.get('subrepos'))
4749 4755 changestates = zip(states, 'MAR!?IC', stat)
4750 4756
4751 4757 if (opts.get('all') or opts.get('copies')
4752 4758 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
4753 4759 copy = copies.pathcopies(repo[node1], repo[node2], m)
4754 4760
4755 4761 ui.pager('status')
4756 4762 fm = ui.formatter('status', opts)
4757 4763 fmt = '%s' + end
4758 4764 showchar = not opts.get('no_status')
4759 4765
4760 4766 for state, char, files in changestates:
4761 4767 if state in show:
4762 4768 label = 'status.' + state
4763 4769 for f in files:
4764 4770 fm.startitem()
4765 4771 fm.condwrite(showchar, 'status', '%s ', char, label=label)
4766 4772 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
4767 4773 if f in copy:
4768 4774 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
4769 4775 label='status.copied')
4770 4776 fm.end()
4771 4777
4772 4778 @command('^summary|sum',
4773 4779 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
4774 4780 def summary(ui, repo, **opts):
4775 4781 """summarize working directory state
4776 4782
4777 4783 This generates a brief summary of the working directory state,
4778 4784 including parents, branch, commit status, phase and available updates.
4779 4785
4780 4786 With the --remote option, this will check the default paths for
4781 4787 incoming and outgoing changes. This can be time-consuming.
4782 4788
4783 4789 Returns 0 on success.
4784 4790 """
4785 4791
4786 4792 ui.pager('summary')
4787 4793 ctx = repo[None]
4788 4794 parents = ctx.parents()
4789 4795 pnode = parents[0].node()
4790 4796 marks = []
4791 4797
4792 4798 ms = None
4793 4799 try:
4794 4800 ms = mergemod.mergestate.read(repo)
4795 4801 except error.UnsupportedMergeRecords as e:
4796 4802 s = ' '.join(e.recordtypes)
4797 4803 ui.warn(
4798 4804 _('warning: merge state has unsupported record types: %s\n') % s)
4799 4805 unresolved = 0
4800 4806 else:
4801 4807 unresolved = [f for f in ms if ms[f] == 'u']
4802 4808
4803 4809 for p in parents:
4804 4810 # label with log.changeset (instead of log.parent) since this
4805 4811 # shows a working directory parent *changeset*:
4806 4812 # i18n: column positioning for "hg summary"
4807 4813 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
4808 4814 label=cmdutil._changesetlabels(p))
4809 4815 ui.write(' '.join(p.tags()), label='log.tag')
4810 4816 if p.bookmarks():
4811 4817 marks.extend(p.bookmarks())
4812 4818 if p.rev() == -1:
4813 4819 if not len(repo):
4814 4820 ui.write(_(' (empty repository)'))
4815 4821 else:
4816 4822 ui.write(_(' (no revision checked out)'))
4817 4823 if p.troubled():
4818 4824 ui.write(' ('
4819 4825 + ', '.join(ui.label(trouble, 'trouble.%s' % trouble)
4820 4826 for trouble in p.troubles())
4821 4827 + ')')
4822 4828 ui.write('\n')
4823 4829 if p.description():
4824 4830 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
4825 4831 label='log.summary')
4826 4832
4827 4833 branch = ctx.branch()
4828 4834 bheads = repo.branchheads(branch)
4829 4835 # i18n: column positioning for "hg summary"
4830 4836 m = _('branch: %s\n') % branch
4831 4837 if branch != 'default':
4832 4838 ui.write(m, label='log.branch')
4833 4839 else:
4834 4840 ui.status(m, label='log.branch')
4835 4841
4836 4842 if marks:
4837 4843 active = repo._activebookmark
4838 4844 # i18n: column positioning for "hg summary"
4839 4845 ui.write(_('bookmarks:'), label='log.bookmark')
4840 4846 if active is not None:
4841 4847 if active in marks:
4842 4848 ui.write(' *' + active, label=activebookmarklabel)
4843 4849 marks.remove(active)
4844 4850 else:
4845 4851 ui.write(' [%s]' % active, label=activebookmarklabel)
4846 4852 for m in marks:
4847 4853 ui.write(' ' + m, label='log.bookmark')
4848 4854 ui.write('\n', label='log.bookmark')
4849 4855
4850 4856 status = repo.status(unknown=True)
4851 4857
4852 4858 c = repo.dirstate.copies()
4853 4859 copied, renamed = [], []
4854 4860 for d, s in c.iteritems():
4855 4861 if s in status.removed:
4856 4862 status.removed.remove(s)
4857 4863 renamed.append(d)
4858 4864 else:
4859 4865 copied.append(d)
4860 4866 if d in status.added:
4861 4867 status.added.remove(d)
4862 4868
4863 4869 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
4864 4870
4865 4871 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
4866 4872 (ui.label(_('%d added'), 'status.added'), status.added),
4867 4873 (ui.label(_('%d removed'), 'status.removed'), status.removed),
4868 4874 (ui.label(_('%d renamed'), 'status.copied'), renamed),
4869 4875 (ui.label(_('%d copied'), 'status.copied'), copied),
4870 4876 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
4871 4877 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
4872 4878 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
4873 4879 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
4874 4880 t = []
4875 4881 for l, s in labels:
4876 4882 if s:
4877 4883 t.append(l % len(s))
4878 4884
4879 4885 t = ', '.join(t)
4880 4886 cleanworkdir = False
4881 4887
4882 4888 if repo.vfs.exists('graftstate'):
4883 4889 t += _(' (graft in progress)')
4884 4890 if repo.vfs.exists('updatestate'):
4885 4891 t += _(' (interrupted update)')
4886 4892 elif len(parents) > 1:
4887 4893 t += _(' (merge)')
4888 4894 elif branch != parents[0].branch():
4889 4895 t += _(' (new branch)')
4890 4896 elif (parents[0].closesbranch() and
4891 4897 pnode in repo.branchheads(branch, closed=True)):
4892 4898 t += _(' (head closed)')
4893 4899 elif not (status.modified or status.added or status.removed or renamed or
4894 4900 copied or subs):
4895 4901 t += _(' (clean)')
4896 4902 cleanworkdir = True
4897 4903 elif pnode not in bheads:
4898 4904 t += _(' (new branch head)')
4899 4905
4900 4906 if parents:
4901 4907 pendingphase = max(p.phase() for p in parents)
4902 4908 else:
4903 4909 pendingphase = phases.public
4904 4910
4905 4911 if pendingphase > phases.newcommitphase(ui):
4906 4912 t += ' (%s)' % phases.phasenames[pendingphase]
4907 4913
4908 4914 if cleanworkdir:
4909 4915 # i18n: column positioning for "hg summary"
4910 4916 ui.status(_('commit: %s\n') % t.strip())
4911 4917 else:
4912 4918 # i18n: column positioning for "hg summary"
4913 4919 ui.write(_('commit: %s\n') % t.strip())
4914 4920
4915 4921 # all ancestors of branch heads - all ancestors of parent = new csets
4916 4922 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
4917 4923 bheads))
4918 4924
4919 4925 if new == 0:
4920 4926 # i18n: column positioning for "hg summary"
4921 4927 ui.status(_('update: (current)\n'))
4922 4928 elif pnode not in bheads:
4923 4929 # i18n: column positioning for "hg summary"
4924 4930 ui.write(_('update: %d new changesets (update)\n') % new)
4925 4931 else:
4926 4932 # i18n: column positioning for "hg summary"
4927 4933 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
4928 4934 (new, len(bheads)))
4929 4935
4930 4936 t = []
4931 4937 draft = len(repo.revs('draft()'))
4932 4938 if draft:
4933 4939 t.append(_('%d draft') % draft)
4934 4940 secret = len(repo.revs('secret()'))
4935 4941 if secret:
4936 4942 t.append(_('%d secret') % secret)
4937 4943
4938 4944 if draft or secret:
4939 4945 ui.status(_('phases: %s\n') % ', '.join(t))
4940 4946
4941 4947 if obsolete.isenabled(repo, obsolete.createmarkersopt):
4942 4948 for trouble in ("unstable", "divergent", "bumped"):
4943 4949 numtrouble = len(repo.revs(trouble + "()"))
4944 4950 # We write all the possibilities to ease translation
4945 4951 troublemsg = {
4946 4952 "unstable": _("unstable: %d changesets"),
4947 4953 "divergent": _("divergent: %d changesets"),
4948 4954 "bumped": _("bumped: %d changesets"),
4949 4955 }
4950 4956 if numtrouble > 0:
4951 4957 ui.status(troublemsg[trouble] % numtrouble + "\n")
4952 4958
4953 4959 cmdutil.summaryhooks(ui, repo)
4954 4960
4955 4961 if opts.get('remote'):
4956 4962 needsincoming, needsoutgoing = True, True
4957 4963 else:
4958 4964 needsincoming, needsoutgoing = False, False
4959 4965 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
4960 4966 if i:
4961 4967 needsincoming = True
4962 4968 if o:
4963 4969 needsoutgoing = True
4964 4970 if not needsincoming and not needsoutgoing:
4965 4971 return
4966 4972
4967 4973 def getincoming():
4968 4974 source, branches = hg.parseurl(ui.expandpath('default'))
4969 4975 sbranch = branches[0]
4970 4976 try:
4971 4977 other = hg.peer(repo, {}, source)
4972 4978 except error.RepoError:
4973 4979 if opts.get('remote'):
4974 4980 raise
4975 4981 return source, sbranch, None, None, None
4976 4982 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
4977 4983 if revs:
4978 4984 revs = [other.lookup(rev) for rev in revs]
4979 4985 ui.debug('comparing with %s\n' % util.hidepassword(source))
4980 4986 repo.ui.pushbuffer()
4981 4987 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
4982 4988 repo.ui.popbuffer()
4983 4989 return source, sbranch, other, commoninc, commoninc[1]
4984 4990
4985 4991 if needsincoming:
4986 4992 source, sbranch, sother, commoninc, incoming = getincoming()
4987 4993 else:
4988 4994 source = sbranch = sother = commoninc = incoming = None
4989 4995
4990 4996 def getoutgoing():
4991 4997 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
4992 4998 dbranch = branches[0]
4993 4999 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
4994 5000 if source != dest:
4995 5001 try:
4996 5002 dother = hg.peer(repo, {}, dest)
4997 5003 except error.RepoError:
4998 5004 if opts.get('remote'):
4999 5005 raise
5000 5006 return dest, dbranch, None, None
5001 5007 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5002 5008 elif sother is None:
5003 5009 # there is no explicit destination peer, but source one is invalid
5004 5010 return dest, dbranch, None, None
5005 5011 else:
5006 5012 dother = sother
5007 5013 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5008 5014 common = None
5009 5015 else:
5010 5016 common = commoninc
5011 5017 if revs:
5012 5018 revs = [repo.lookup(rev) for rev in revs]
5013 5019 repo.ui.pushbuffer()
5014 5020 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5015 5021 commoninc=common)
5016 5022 repo.ui.popbuffer()
5017 5023 return dest, dbranch, dother, outgoing
5018 5024
5019 5025 if needsoutgoing:
5020 5026 dest, dbranch, dother, outgoing = getoutgoing()
5021 5027 else:
5022 5028 dest = dbranch = dother = outgoing = None
5023 5029
5024 5030 if opts.get('remote'):
5025 5031 t = []
5026 5032 if incoming:
5027 5033 t.append(_('1 or more incoming'))
5028 5034 o = outgoing.missing
5029 5035 if o:
5030 5036 t.append(_('%d outgoing') % len(o))
5031 5037 other = dother or sother
5032 5038 if 'bookmarks' in other.listkeys('namespaces'):
5033 5039 counts = bookmarks.summary(repo, other)
5034 5040 if counts[0] > 0:
5035 5041 t.append(_('%d incoming bookmarks') % counts[0])
5036 5042 if counts[1] > 0:
5037 5043 t.append(_('%d outgoing bookmarks') % counts[1])
5038 5044
5039 5045 if t:
5040 5046 # i18n: column positioning for "hg summary"
5041 5047 ui.write(_('remote: %s\n') % (', '.join(t)))
5042 5048 else:
5043 5049 # i18n: column positioning for "hg summary"
5044 5050 ui.status(_('remote: (synced)\n'))
5045 5051
5046 5052 cmdutil.summaryremotehooks(ui, repo, opts,
5047 5053 ((source, sbranch, sother, commoninc),
5048 5054 (dest, dbranch, dother, outgoing)))
5049 5055
5050 5056 @command('tag',
5051 5057 [('f', 'force', None, _('force tag')),
5052 5058 ('l', 'local', None, _('make the tag local')),
5053 5059 ('r', 'rev', '', _('revision to tag'), _('REV')),
5054 5060 ('', 'remove', None, _('remove a tag')),
5055 5061 # -l/--local is already there, commitopts cannot be used
5056 5062 ('e', 'edit', None, _('invoke editor on commit messages')),
5057 5063 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5058 5064 ] + commitopts2,
5059 5065 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5060 5066 def tag(ui, repo, name1, *names, **opts):
5061 5067 """add one or more tags for the current or given revision
5062 5068
5063 5069 Name a particular revision using <name>.
5064 5070
5065 5071 Tags are used to name particular revisions of the repository and are
5066 5072 very useful to compare different revisions, to go back to significant
5067 5073 earlier versions or to mark branch points as releases, etc. Changing
5068 5074 an existing tag is normally disallowed; use -f/--force to override.
5069 5075
5070 5076 If no revision is given, the parent of the working directory is
5071 5077 used.
5072 5078
5073 5079 To facilitate version control, distribution, and merging of tags,
5074 5080 they are stored as a file named ".hgtags" which is managed similarly
5075 5081 to other project files and can be hand-edited if necessary. This
5076 5082 also means that tagging creates a new commit. The file
5077 5083 ".hg/localtags" is used for local tags (not shared among
5078 5084 repositories).
5079 5085
5080 5086 Tag commits are usually made at the head of a branch. If the parent
5081 5087 of the working directory is not a branch head, :hg:`tag` aborts; use
5082 5088 -f/--force to force the tag commit to be based on a non-head
5083 5089 changeset.
5084 5090
5085 5091 See :hg:`help dates` for a list of formats valid for -d/--date.
5086 5092
5087 5093 Since tag names have priority over branch names during revision
5088 5094 lookup, using an existing branch name as a tag name is discouraged.
5089 5095
5090 5096 Returns 0 on success.
5091 5097 """
5092 5098 wlock = lock = None
5093 5099 try:
5094 5100 wlock = repo.wlock()
5095 5101 lock = repo.lock()
5096 5102 rev_ = "."
5097 5103 names = [t.strip() for t in (name1,) + names]
5098 5104 if len(names) != len(set(names)):
5099 5105 raise error.Abort(_('tag names must be unique'))
5100 5106 for n in names:
5101 5107 scmutil.checknewlabel(repo, n, 'tag')
5102 5108 if not n:
5103 5109 raise error.Abort(_('tag names cannot consist entirely of '
5104 5110 'whitespace'))
5105 5111 if opts.get('rev') and opts.get('remove'):
5106 5112 raise error.Abort(_("--rev and --remove are incompatible"))
5107 5113 if opts.get('rev'):
5108 5114 rev_ = opts['rev']
5109 5115 message = opts.get('message')
5110 5116 if opts.get('remove'):
5111 5117 if opts.get('local'):
5112 5118 expectedtype = 'local'
5113 5119 else:
5114 5120 expectedtype = 'global'
5115 5121
5116 5122 for n in names:
5117 5123 if not repo.tagtype(n):
5118 5124 raise error.Abort(_("tag '%s' does not exist") % n)
5119 5125 if repo.tagtype(n) != expectedtype:
5120 5126 if expectedtype == 'global':
5121 5127 raise error.Abort(_("tag '%s' is not a global tag") % n)
5122 5128 else:
5123 5129 raise error.Abort(_("tag '%s' is not a local tag") % n)
5124 5130 rev_ = 'null'
5125 5131 if not message:
5126 5132 # we don't translate commit messages
5127 5133 message = 'Removed tag %s' % ', '.join(names)
5128 5134 elif not opts.get('force'):
5129 5135 for n in names:
5130 5136 if n in repo.tags():
5131 5137 raise error.Abort(_("tag '%s' already exists "
5132 5138 "(use -f to force)") % n)
5133 5139 if not opts.get('local'):
5134 5140 p1, p2 = repo.dirstate.parents()
5135 5141 if p2 != nullid:
5136 5142 raise error.Abort(_('uncommitted merge'))
5137 5143 bheads = repo.branchheads()
5138 5144 if not opts.get('force') and bheads and p1 not in bheads:
5139 5145 raise error.Abort(_('working directory is not at a branch head '
5140 5146 '(use -f to force)'))
5141 5147 r = scmutil.revsingle(repo, rev_).node()
5142 5148
5143 5149 if not message:
5144 5150 # we don't translate commit messages
5145 5151 message = ('Added tag %s for changeset %s' %
5146 5152 (', '.join(names), short(r)))
5147 5153
5148 5154 date = opts.get('date')
5149 5155 if date:
5150 5156 date = util.parsedate(date)
5151 5157
5152 5158 if opts.get('remove'):
5153 5159 editform = 'tag.remove'
5154 5160 else:
5155 5161 editform = 'tag.add'
5156 5162 editor = cmdutil.getcommiteditor(editform=editform, **opts)
5157 5163
5158 5164 # don't allow tagging the null rev
5159 5165 if (not opts.get('remove') and
5160 5166 scmutil.revsingle(repo, rev_).rev() == nullrev):
5161 5167 raise error.Abort(_("cannot tag null revision"))
5162 5168
5163 5169 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
5164 5170 editor=editor)
5165 5171 finally:
5166 5172 release(lock, wlock)
5167 5173
5168 5174 @command('tags', formatteropts, '')
5169 5175 def tags(ui, repo, **opts):
5170 5176 """list repository tags
5171 5177
5172 5178 This lists both regular and local tags. When the -v/--verbose
5173 5179 switch is used, a third column "local" is printed for local tags.
5174 5180 When the -q/--quiet switch is used, only the tag name is printed.
5175 5181
5176 5182 Returns 0 on success.
5177 5183 """
5178 5184
5179 5185 ui.pager('tags')
5180 5186 fm = ui.formatter('tags', opts)
5181 5187 hexfunc = fm.hexfunc
5182 5188 tagtype = ""
5183 5189
5184 5190 for t, n in reversed(repo.tagslist()):
5185 5191 hn = hexfunc(n)
5186 5192 label = 'tags.normal'
5187 5193 tagtype = ''
5188 5194 if repo.tagtype(t) == 'local':
5189 5195 label = 'tags.local'
5190 5196 tagtype = 'local'
5191 5197
5192 5198 fm.startitem()
5193 5199 fm.write('tag', '%s', t, label=label)
5194 5200 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5195 5201 fm.condwrite(not ui.quiet, 'rev node', fmt,
5196 5202 repo.changelog.rev(n), hn, label=label)
5197 5203 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5198 5204 tagtype, label=label)
5199 5205 fm.plain('\n')
5200 5206 fm.end()
5201 5207
5202 5208 @command('tip',
5203 5209 [('p', 'patch', None, _('show patch')),
5204 5210 ('g', 'git', None, _('use git extended diff format')),
5205 5211 ] + templateopts,
5206 5212 _('[-p] [-g]'))
5207 5213 def tip(ui, repo, **opts):
5208 5214 """show the tip revision (DEPRECATED)
5209 5215
5210 5216 The tip revision (usually just called the tip) is the changeset
5211 5217 most recently added to the repository (and therefore the most
5212 5218 recently changed head).
5213 5219
5214 5220 If you have just made a commit, that commit will be the tip. If
5215 5221 you have just pulled changes from another repository, the tip of
5216 5222 that repository becomes the current tip. The "tip" tag is special
5217 5223 and cannot be renamed or assigned to a different changeset.
5218 5224
5219 5225 This command is deprecated, please use :hg:`heads` instead.
5220 5226
5221 5227 Returns 0 on success.
5222 5228 """
5223 5229 displayer = cmdutil.show_changeset(ui, repo, opts)
5224 5230 displayer.show(repo['tip'])
5225 5231 displayer.close()
5226 5232
5227 5233 @command('unbundle',
5228 5234 [('u', 'update', None,
5229 5235 _('update to new branch head if changesets were unbundled'))],
5230 5236 _('[-u] FILE...'))
5231 5237 def unbundle(ui, repo, fname1, *fnames, **opts):
5232 5238 """apply one or more changegroup files
5233 5239
5234 5240 Apply one or more compressed changegroup files generated by the
5235 5241 bundle command.
5236 5242
5237 5243 Returns 0 on success, 1 if an update has unresolved files.
5238 5244 """
5239 5245 fnames = (fname1,) + fnames
5240 5246
5241 5247 with repo.lock():
5242 5248 for fname in fnames:
5243 5249 f = hg.openpath(ui, fname)
5244 5250 gen = exchange.readbundle(ui, f, fname)
5245 5251 if isinstance(gen, bundle2.unbundle20):
5246 5252 tr = repo.transaction('unbundle')
5247 5253 try:
5248 5254 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
5249 5255 url='bundle:' + fname)
5250 5256 tr.close()
5251 5257 except error.BundleUnknownFeatureError as exc:
5252 5258 raise error.Abort(_('%s: unknown bundle feature, %s')
5253 5259 % (fname, exc),
5254 5260 hint=_("see https://mercurial-scm.org/"
5255 5261 "wiki/BundleFeature for more "
5256 5262 "information"))
5257 5263 finally:
5258 5264 if tr:
5259 5265 tr.release()
5260 5266 changes = [r.get('return', 0)
5261 5267 for r in op.records['changegroup']]
5262 5268 modheads = changegroup.combineresults(changes)
5263 5269 elif isinstance(gen, streamclone.streamcloneapplier):
5264 5270 raise error.Abort(
5265 5271 _('packed bundles cannot be applied with '
5266 5272 '"hg unbundle"'),
5267 5273 hint=_('use "hg debugapplystreamclonebundle"'))
5268 5274 else:
5269 5275 modheads = gen.apply(repo, 'unbundle', 'bundle:' + fname)
5270 5276
5271 5277 return postincoming(ui, repo, modheads, opts.get('update'), None, None)
5272 5278
5273 5279 @command('^update|up|checkout|co',
5274 5280 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5275 5281 ('c', 'check', None, _('require clean working directory')),
5276 5282 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5277 5283 ('r', 'rev', '', _('revision'), _('REV'))
5278 5284 ] + mergetoolopts,
5279 5285 _('[-C|-c] [-d DATE] [[-r] REV]'))
5280 5286 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
5281 5287 tool=None):
5282 5288 """update working directory (or switch revisions)
5283 5289
5284 5290 Update the repository's working directory to the specified
5285 5291 changeset. If no changeset is specified, update to the tip of the
5286 5292 current named branch and move the active bookmark (see :hg:`help
5287 5293 bookmarks`).
5288 5294
5289 5295 Update sets the working directory's parent revision to the specified
5290 5296 changeset (see :hg:`help parents`).
5291 5297
5292 5298 If the changeset is not a descendant or ancestor of the working
5293 5299 directory's parent and there are uncommitted changes, the update is
5294 5300 aborted. With the -c/--check option, the working directory is checked
5295 5301 for uncommitted changes; if none are found, the working directory is
5296 5302 updated to the specified changeset.
5297 5303
5298 5304 .. container:: verbose
5299 5305
5300 5306 The -C/--clean and -c/--check options control what happens if the
5301 5307 working directory contains uncommitted changes.
5302 5308 At most of one of them can be specified.
5303 5309
5304 5310 1. If no option is specified, and if
5305 5311 the requested changeset is an ancestor or descendant of
5306 5312 the working directory's parent, the uncommitted changes
5307 5313 are merged into the requested changeset and the merged
5308 5314 result is left uncommitted. If the requested changeset is
5309 5315 not an ancestor or descendant (that is, it is on another
5310 5316 branch), the update is aborted and the uncommitted changes
5311 5317 are preserved.
5312 5318
5313 5319 2. With the -c/--check option, the update is aborted and the
5314 5320 uncommitted changes are preserved.
5315 5321
5316 5322 3. With the -C/--clean option, uncommitted changes are discarded and
5317 5323 the working directory is updated to the requested changeset.
5318 5324
5319 5325 To cancel an uncommitted merge (and lose your changes), use
5320 5326 :hg:`update --clean .`.
5321 5327
5322 5328 Use null as the changeset to remove the working directory (like
5323 5329 :hg:`clone -U`).
5324 5330
5325 5331 If you want to revert just one file to an older revision, use
5326 5332 :hg:`revert [-r REV] NAME`.
5327 5333
5328 5334 See :hg:`help dates` for a list of formats valid for -d/--date.
5329 5335
5330 5336 Returns 0 on success, 1 if there are unresolved files.
5331 5337 """
5332 5338 if rev and node:
5333 5339 raise error.Abort(_("please specify just one revision"))
5334 5340
5335 5341 if rev is None or rev == '':
5336 5342 rev = node
5337 5343
5338 5344 if date and rev is not None:
5339 5345 raise error.Abort(_("you can't specify a revision and a date"))
5340 5346
5341 5347 if check and clean:
5342 5348 raise error.Abort(_("cannot specify both -c/--check and -C/--clean"))
5343 5349
5344 5350 with repo.wlock():
5345 5351 cmdutil.clearunfinished(repo)
5346 5352
5347 5353 if date:
5348 5354 rev = cmdutil.finddate(ui, repo, date)
5349 5355
5350 5356 # if we defined a bookmark, we have to remember the original name
5351 5357 brev = rev
5352 5358 rev = scmutil.revsingle(repo, rev, rev).rev()
5353 5359
5354 5360 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
5355 5361
5356 5362 return hg.updatetotally(ui, repo, rev, brev, clean=clean, check=check)
5357 5363
5358 5364 @command('verify', [])
5359 5365 def verify(ui, repo):
5360 5366 """verify the integrity of the repository
5361 5367
5362 5368 Verify the integrity of the current repository.
5363 5369
5364 5370 This will perform an extensive check of the repository's
5365 5371 integrity, validating the hashes and checksums of each entry in
5366 5372 the changelog, manifest, and tracked files, as well as the
5367 5373 integrity of their crosslinks and indices.
5368 5374
5369 5375 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
5370 5376 for more information about recovery from corruption of the
5371 5377 repository.
5372 5378
5373 5379 Returns 0 on success, 1 if errors are encountered.
5374 5380 """
5375 5381 return hg.verify(repo)
5376 5382
5377 5383 @command('version', [] + formatteropts, norepo=True)
5378 5384 def version_(ui, **opts):
5379 5385 """output version and copyright information"""
5380 5386 if ui.verbose:
5381 5387 ui.pager('version')
5382 5388 fm = ui.formatter("version", opts)
5383 5389 fm.startitem()
5384 5390 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
5385 5391 util.version())
5386 5392 license = _(
5387 5393 "(see https://mercurial-scm.org for more information)\n"
5388 5394 "\nCopyright (C) 2005-2017 Matt Mackall and others\n"
5389 5395 "This is free software; see the source for copying conditions. "
5390 5396 "There is NO\nwarranty; "
5391 5397 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5392 5398 )
5393 5399 if not ui.quiet:
5394 5400 fm.plain(license)
5395 5401
5396 5402 if ui.verbose:
5397 5403 fm.plain(_("\nEnabled extensions:\n\n"))
5398 5404 # format names and versions into columns
5399 5405 names = []
5400 5406 vers = []
5401 5407 isinternals = []
5402 5408 for name, module in extensions.extensions():
5403 5409 names.append(name)
5404 5410 vers.append(extensions.moduleversion(module) or None)
5405 5411 isinternals.append(extensions.ismoduleinternal(module))
5406 5412 fn = fm.nested("extensions")
5407 5413 if names:
5408 5414 namefmt = " %%-%ds " % max(len(n) for n in names)
5409 5415 places = [_("external"), _("internal")]
5410 5416 for n, v, p in zip(names, vers, isinternals):
5411 5417 fn.startitem()
5412 5418 fn.condwrite(ui.verbose, "name", namefmt, n)
5413 5419 if ui.verbose:
5414 5420 fn.plain("%s " % places[p])
5415 5421 fn.data(bundled=p)
5416 5422 fn.condwrite(ui.verbose and v, "ver", "%s", v)
5417 5423 if ui.verbose:
5418 5424 fn.plain("\n")
5419 5425 fn.end()
5420 5426 fm.end()
5421 5427
5422 5428 def loadcmdtable(ui, name, cmdtable):
5423 5429 """Load command functions from specified cmdtable
5424 5430 """
5425 5431 overrides = [cmd for cmd in cmdtable if cmd in table]
5426 5432 if overrides:
5427 5433 ui.warn(_("extension '%s' overrides commands: %s\n")
5428 5434 % (name, " ".join(overrides)))
5429 5435 table.update(cmdtable)
@@ -1,356 +1,358 b''
1 1 Show all commands except debug commands
2 2 $ hg debugcomplete
3 3 add
4 4 addremove
5 5 annotate
6 6 archive
7 7 backout
8 8 bisect
9 9 bookmarks
10 10 branch
11 11 branches
12 12 bundle
13 13 cat
14 14 clone
15 15 commit
16 16 config
17 17 copy
18 18 diff
19 19 export
20 20 files
21 21 forget
22 22 graft
23 23 grep
24 24 heads
25 25 help
26 26 identify
27 27 import
28 28 incoming
29 29 init
30 30 locate
31 31 log
32 32 manifest
33 33 merge
34 34 outgoing
35 35 parents
36 36 paths
37 37 phase
38 38 pull
39 39 push
40 40 recover
41 41 remove
42 42 rename
43 43 resolve
44 44 revert
45 45 rollback
46 46 root
47 47 serve
48 48 status
49 49 summary
50 50 tag
51 51 tags
52 52 tip
53 53 unbundle
54 54 update
55 55 verify
56 56 version
57 57
58 58 Show all commands that start with "a"
59 59 $ hg debugcomplete a
60 60 add
61 61 addremove
62 62 annotate
63 63 archive
64 64
65 65 Do not show debug commands if there are other candidates
66 66 $ hg debugcomplete d
67 67 diff
68 68
69 69 Show debug commands if there are no other candidates
70 70 $ hg debugcomplete debug
71 71 debugancestor
72 72 debugapplystreamclonebundle
73 73 debugbuilddag
74 74 debugbundle
75 75 debugcheckstate
76 76 debugcommands
77 77 debugcomplete
78 78 debugconfig
79 79 debugcreatestreamclonebundle
80 80 debugdag
81 81 debugdata
82 82 debugdate
83 83 debugdeltachain
84 84 debugdirstate
85 85 debugdiscovery
86 86 debugextensions
87 87 debugfileset
88 88 debugfsinfo
89 89 debuggetbundle
90 90 debugignore
91 91 debugindex
92 92 debugindexdot
93 93 debuginstall
94 94 debugknown
95 95 debuglabelcomplete
96 96 debuglocks
97 97 debugmergestate
98 98 debugnamecomplete
99 99 debugobsolete
100 100 debugpathcomplete
101 101 debugpushkey
102 102 debugpvec
103 103 debugrebuilddirstate
104 104 debugrebuildfncache
105 105 debugrename
106 106 debugrevlog
107 107 debugrevspec
108 108 debugsetparents
109 109 debugsub
110 110 debugsuccessorssets
111 111 debugtemplate
112 112 debugupgraderepo
113 113 debugwalk
114 114 debugwireargs
115 115
116 116 Do not show the alias of a debug command if there are other candidates
117 117 (this should hide rawcommit)
118 118 $ hg debugcomplete r
119 119 recover
120 120 remove
121 121 rename
122 122 resolve
123 123 revert
124 124 rollback
125 125 root
126 126 Show the alias of a debug command if there are no other candidates
127 127 $ hg debugcomplete rawc
128 128
129 129
130 130 Show the global options
131 131 $ hg debugcomplete --options | sort
132 --color
132 133 --config
133 134 --cwd
134 135 --debug
135 136 --debugger
136 137 --encoding
137 138 --encodingmode
138 139 --help
139 140 --hidden
140 141 --noninteractive
141 142 --pager
142 143 --profile
143 144 --quiet
144 145 --repository
145 146 --time
146 147 --traceback
147 148 --verbose
148 149 --version
149 150 -R
150 151 -h
151 152 -q
152 153 -v
153 154 -y
154 155
155 156 Show the options for the "serve" command
156 157 $ hg debugcomplete --options serve | sort
157 158 --accesslog
158 159 --address
159 160 --certificate
160 161 --cmdserver
162 --color
161 163 --config
162 164 --cwd
163 165 --daemon
164 166 --daemon-postexec
165 167 --debug
166 168 --debugger
167 169 --encoding
168 170 --encodingmode
169 171 --errorlog
170 172 --help
171 173 --hidden
172 174 --ipv6
173 175 --name
174 176 --noninteractive
175 177 --pager
176 178 --pid-file
177 179 --port
178 180 --prefix
179 181 --profile
180 182 --quiet
181 183 --repository
182 184 --stdio
183 185 --style
184 186 --templates
185 187 --time
186 188 --traceback
187 189 --verbose
188 190 --version
189 191 --web-conf
190 192 -6
191 193 -A
192 194 -E
193 195 -R
194 196 -a
195 197 -d
196 198 -h
197 199 -n
198 200 -p
199 201 -q
200 202 -t
201 203 -v
202 204 -y
203 205
204 206 Show an error if we use --options with an ambiguous abbreviation
205 207 $ hg debugcomplete --options s
206 208 hg: command 's' is ambiguous:
207 209 serve showconfig status summary
208 210 [255]
209 211
210 212 Show all commands + options
211 213 $ hg debugcommands
212 214 add: include, exclude, subrepos, dry-run
213 215 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude, template
214 216 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
215 217 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
216 218 diff: rev, change, text, git, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, root, include, exclude, subrepos
217 219 export: output, switch-parent, rev, text, git, nodates
218 220 forget: include, exclude
219 221 init: ssh, remotecmd, insecure
220 222 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
221 223 merge: force, rev, preview, tool
222 224 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
223 225 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
224 226 remove: after, force, subrepos, include, exclude
225 227 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
226 228 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
227 229 summary: remote
228 230 update: clean, check, date, rev, tool
229 231 addremove: similarity, subrepos, include, exclude, dry-run
230 232 archive: no-decode, prefix, rev, type, subrepos, include, exclude
231 233 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
232 234 bisect: reset, good, bad, skip, extend, command, noupdate
233 235 bookmarks: force, rev, delete, rename, inactive, template
234 236 branch: force, clean
235 237 branches: active, closed, template
236 238 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
237 239 cat: output, rev, decode, include, exclude
238 240 config: untrusted, edit, local, global, template
239 241 copy: after, force, include, exclude, dry-run
240 242 debugancestor:
241 243 debugapplystreamclonebundle:
242 244 debugbuilddag: mergeable-file, overwritten-file, new-file
243 245 debugbundle: all, spec
244 246 debugcheckstate:
245 247 debugcommands:
246 248 debugcomplete: options
247 249 debugcreatestreamclonebundle:
248 250 debugdag: tags, branches, dots, spaces
249 251 debugdata: changelog, manifest, dir
250 252 debugdate: extended
251 253 debugdeltachain: changelog, manifest, dir, template
252 254 debugdirstate: nodates, datesort
253 255 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
254 256 debugextensions: template
255 257 debugfileset: rev
256 258 debugfsinfo:
257 259 debuggetbundle: head, common, type
258 260 debugignore:
259 261 debugindex: changelog, manifest, dir, format
260 262 debugindexdot: changelog, manifest, dir
261 263 debuginstall: template
262 264 debugknown:
263 265 debuglabelcomplete:
264 266 debuglocks: force-lock, force-wlock
265 267 debugmergestate:
266 268 debugnamecomplete:
267 269 debugobsolete: flags, record-parents, rev, index, delete, date, user, template
268 270 debugpathcomplete: full, normal, added, removed
269 271 debugpushkey:
270 272 debugpvec:
271 273 debugrebuilddirstate: rev, minimal
272 274 debugrebuildfncache:
273 275 debugrename: rev
274 276 debugrevlog: changelog, manifest, dir, dump
275 277 debugrevspec: optimize, show-stage, no-optimized, verify-optimized
276 278 debugsetparents:
277 279 debugsub: rev
278 280 debugsuccessorssets:
279 281 debugtemplate: rev, define
280 282 debugupgraderepo: optimize, run
281 283 debugwalk: include, exclude
282 284 debugwireargs: three, four, five, ssh, remotecmd, insecure
283 285 files: rev, print0, include, exclude, template, subrepos
284 286 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
285 287 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, template, include, exclude
286 288 heads: rev, topo, active, closed, style, template
287 289 help: extension, command, keyword, system
288 290 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
289 291 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
290 292 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
291 293 locate: rev, print0, fullpath, include, exclude
292 294 manifest: rev, all, template
293 295 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
294 296 parents: rev, style, template
295 297 paths: template
296 298 phase: public, draft, secret, force, rev
297 299 recover:
298 300 rename: after, force, include, exclude, dry-run
299 301 resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
300 302 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
301 303 rollback: dry-run, force
302 304 root:
303 305 tag: force, local, rev, remove, edit, message, date, user
304 306 tags: template
305 307 tip: patch, git, style, template
306 308 unbundle: update
307 309 verify:
308 310 version: template
309 311
310 312 $ hg init a
311 313 $ cd a
312 314 $ echo fee > fee
313 315 $ hg ci -q -Amfee
314 316 $ hg tag fee
315 317 $ mkdir fie
316 318 $ echo dead > fie/dead
317 319 $ echo live > fie/live
318 320 $ hg bookmark fo
319 321 $ hg branch -q fie
320 322 $ hg ci -q -Amfie
321 323 $ echo fo > fo
322 324 $ hg branch -qf default
323 325 $ hg ci -q -Amfo
324 326 $ echo Fum > Fum
325 327 $ hg ci -q -AmFum
326 328 $ hg bookmark Fum
327 329
328 330 Test debugpathcomplete
329 331
330 332 $ hg debugpathcomplete f
331 333 fee
332 334 fie
333 335 fo
334 336 $ hg debugpathcomplete -f f
335 337 fee
336 338 fie/dead
337 339 fie/live
338 340 fo
339 341
340 342 $ hg rm Fum
341 343 $ hg debugpathcomplete -r F
342 344 Fum
343 345
344 346 Test debugnamecomplete
345 347
346 348 $ hg debugnamecomplete
347 349 Fum
348 350 default
349 351 fee
350 352 fie
351 353 fo
352 354 tip
353 355 $ hg debugnamecomplete f
354 356 fee
355 357 fie
356 358 fo
@@ -1,1539 +1,1551 b''
1 1 Test basic extension support
2 2
3 3 $ cat > foobar.py <<EOF
4 4 > import os
5 5 > from mercurial import cmdutil, commands
6 6 > cmdtable = {}
7 7 > command = cmdutil.command(cmdtable)
8 8 > def uisetup(ui):
9 9 > ui.write("uisetup called\\n")
10 10 > ui.flush()
11 11 > def reposetup(ui, repo):
12 12 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
13 13 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
14 14 > ui.flush()
15 15 > @command('foo', [], 'hg foo')
16 16 > def foo(ui, *args, **kwargs):
17 17 > ui.write("Foo\\n")
18 18 > @command('bar', [], 'hg bar', norepo=True)
19 19 > def bar(ui, *args, **kwargs):
20 20 > ui.write("Bar\\n")
21 21 > EOF
22 22 $ abspath=`pwd`/foobar.py
23 23
24 24 $ mkdir barfoo
25 25 $ cp foobar.py barfoo/__init__.py
26 26 $ barfoopath=`pwd`/barfoo
27 27
28 28 $ hg init a
29 29 $ cd a
30 30 $ echo foo > file
31 31 $ hg add file
32 32 $ hg commit -m 'add file'
33 33
34 34 $ echo '[extensions]' >> $HGRCPATH
35 35 $ echo "foobar = $abspath" >> $HGRCPATH
36 36 $ hg foo
37 37 uisetup called
38 38 reposetup called for a
39 39 ui == repo.ui
40 40 Foo
41 41
42 42 $ cd ..
43 43 $ hg clone a b
44 44 uisetup called
45 45 reposetup called for a
46 46 ui == repo.ui
47 47 reposetup called for b
48 48 ui == repo.ui
49 49 updating to branch default
50 50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 51
52 52 $ hg bar
53 53 uisetup called
54 54 Bar
55 55 $ echo 'foobar = !' >> $HGRCPATH
56 56
57 57 module/__init__.py-style
58 58
59 59 $ echo "barfoo = $barfoopath" >> $HGRCPATH
60 60 $ cd a
61 61 $ hg foo
62 62 uisetup called
63 63 reposetup called for a
64 64 ui == repo.ui
65 65 Foo
66 66 $ echo 'barfoo = !' >> $HGRCPATH
67 67
68 68 Check that extensions are loaded in phases:
69 69
70 70 $ cat > foo.py <<EOF
71 71 > import os
72 72 > name = os.path.basename(__file__).rsplit('.', 1)[0]
73 73 > print "1) %s imported" % name
74 74 > def uisetup(ui):
75 75 > print "2) %s uisetup" % name
76 76 > def extsetup():
77 77 > print "3) %s extsetup" % name
78 78 > def reposetup(ui, repo):
79 79 > print "4) %s reposetup" % name
80 80 > EOF
81 81
82 82 $ cp foo.py bar.py
83 83 $ echo 'foo = foo.py' >> $HGRCPATH
84 84 $ echo 'bar = bar.py' >> $HGRCPATH
85 85
86 86 Command with no output, we just want to see the extensions loaded:
87 87
88 88 $ hg paths
89 89 1) foo imported
90 90 1) bar imported
91 91 2) foo uisetup
92 92 2) bar uisetup
93 93 3) foo extsetup
94 94 3) bar extsetup
95 95 4) foo reposetup
96 96 4) bar reposetup
97 97
98 98 Check hgweb's load order:
99 99
100 100 $ cat > hgweb.cgi <<EOF
101 101 > #!/usr/bin/env python
102 102 > from mercurial import demandimport; demandimport.enable()
103 103 > from mercurial.hgweb import hgweb
104 104 > from mercurial.hgweb import wsgicgi
105 105 > application = hgweb('.', 'test repo')
106 106 > wsgicgi.launch(application)
107 107 > EOF
108 108
109 109 $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
110 110 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
111 111 > | grep '^[0-9]) ' # ignores HTML output
112 112 1) foo imported
113 113 1) bar imported
114 114 2) foo uisetup
115 115 2) bar uisetup
116 116 3) foo extsetup
117 117 3) bar extsetup
118 118 4) foo reposetup
119 119 4) bar reposetup
120 120
121 121 $ echo 'foo = !' >> $HGRCPATH
122 122 $ echo 'bar = !' >> $HGRCPATH
123 123
124 124 Check "from __future__ import absolute_import" support for external libraries
125 125
126 126 #if windows
127 127 $ PATHSEP=";"
128 128 #else
129 129 $ PATHSEP=":"
130 130 #endif
131 131 $ export PATHSEP
132 132
133 133 $ mkdir $TESTTMP/libroot
134 134 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
135 135 $ mkdir $TESTTMP/libroot/mod
136 136 $ touch $TESTTMP/libroot/mod/__init__.py
137 137 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
138 138
139 139 #if absimport
140 140 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
141 141 > from __future__ import absolute_import
142 142 > import ambig # should load "libroot/ambig.py"
143 143 > s = ambig.s
144 144 > EOF
145 145 $ cat > loadabs.py <<EOF
146 146 > import mod.ambigabs as ambigabs
147 147 > def extsetup():
148 148 > print 'ambigabs.s=%s' % ambigabs.s
149 149 > EOF
150 150 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
151 151 ambigabs.s=libroot/ambig.py
152 152 $TESTTMP/a (glob)
153 153 #endif
154 154
155 155 #if no-py3k
156 156 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
157 157 > import ambig # should load "libroot/mod/ambig.py"
158 158 > s = ambig.s
159 159 > EOF
160 160 $ cat > loadrel.py <<EOF
161 161 > import mod.ambigrel as ambigrel
162 162 > def extsetup():
163 163 > print 'ambigrel.s=%s' % ambigrel.s
164 164 > EOF
165 165 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
166 166 ambigrel.s=libroot/mod/ambig.py
167 167 $TESTTMP/a (glob)
168 168 #endif
169 169
170 170 Check absolute/relative import of extension specific modules
171 171
172 172 $ mkdir $TESTTMP/extroot
173 173 $ cat > $TESTTMP/extroot/bar.py <<EOF
174 174 > s = 'this is extroot.bar'
175 175 > EOF
176 176 $ mkdir $TESTTMP/extroot/sub1
177 177 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
178 178 > s = 'this is extroot.sub1.__init__'
179 179 > EOF
180 180 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
181 181 > s = 'this is extroot.sub1.baz'
182 182 > EOF
183 183 $ cat > $TESTTMP/extroot/__init__.py <<EOF
184 184 > s = 'this is extroot.__init__'
185 185 > import foo
186 186 > def extsetup(ui):
187 187 > ui.write('(extroot) ', foo.func(), '\n')
188 188 > ui.flush()
189 189 > EOF
190 190
191 191 $ cat > $TESTTMP/extroot/foo.py <<EOF
192 192 > # test absolute import
193 193 > buf = []
194 194 > def func():
195 195 > # "not locals" case
196 196 > import extroot.bar
197 197 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
198 198 > return '\n(extroot) '.join(buf)
199 199 > # "fromlist == ('*',)" case
200 200 > from extroot.bar import *
201 201 > buf.append('from extroot.bar import *: %s' % s)
202 202 > # "not fromlist" and "if '.' in name" case
203 203 > import extroot.sub1.baz
204 204 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
205 205 > # "not fromlist" and NOT "if '.' in name" case
206 206 > import extroot
207 207 > buf.append('import extroot: %s' % extroot.s)
208 208 > # NOT "not fromlist" and NOT "level != -1" case
209 209 > from extroot.bar import s
210 210 > buf.append('from extroot.bar import s: %s' % s)
211 211 > EOF
212 212 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.extroot=$TESTTMP/extroot root)
213 213 (extroot) from extroot.bar import *: this is extroot.bar
214 214 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
215 215 (extroot) import extroot: this is extroot.__init__
216 216 (extroot) from extroot.bar import s: this is extroot.bar
217 217 (extroot) import extroot.bar in func(): this is extroot.bar
218 218 $TESTTMP/a (glob)
219 219
220 220 #if no-py3k
221 221 $ rm "$TESTTMP"/extroot/foo.*
222 222 $ cat > $TESTTMP/extroot/foo.py <<EOF
223 223 > # test relative import
224 224 > buf = []
225 225 > def func():
226 226 > # "not locals" case
227 227 > import bar
228 228 > buf.append('import bar in func(): %s' % bar.s)
229 229 > return '\n(extroot) '.join(buf)
230 230 > # "fromlist == ('*',)" case
231 231 > from bar import *
232 232 > buf.append('from bar import *: %s' % s)
233 233 > # "not fromlist" and "if '.' in name" case
234 234 > import sub1.baz
235 235 > buf.append('import sub1.baz: %s' % sub1.baz.s)
236 236 > # "not fromlist" and NOT "if '.' in name" case
237 237 > import sub1
238 238 > buf.append('import sub1: %s' % sub1.s)
239 239 > # NOT "not fromlist" and NOT "level != -1" case
240 240 > from bar import s
241 241 > buf.append('from bar import s: %s' % s)
242 242 > EOF
243 243 $ hg --config extensions.extroot=$TESTTMP/extroot root
244 244 (extroot) from bar import *: this is extroot.bar
245 245 (extroot) import sub1.baz: this is extroot.sub1.baz
246 246 (extroot) import sub1: this is extroot.sub1.__init__
247 247 (extroot) from bar import s: this is extroot.bar
248 248 (extroot) import bar in func(): this is extroot.bar
249 249 $TESTTMP/a (glob)
250 250 #endif
251 251
252 252 #if demandimport absimport
253 253
254 254 Examine whether module loading is delayed until actual referring, even
255 255 though module is imported with "absolute_import" feature.
256 256
257 257 Files below in each packages are used for described purpose:
258 258
259 259 - "called": examine whether "from MODULE import ATTR" works correctly
260 260 - "unused": examine whether loading is delayed correctly
261 261 - "used": examine whether "from PACKAGE import MODULE" works correctly
262 262
263 263 Package hierarchy is needed to examine whether demand importing works
264 264 as expected for "from SUB.PACK.AGE import MODULE".
265 265
266 266 Setup "external library" to be imported with "absolute_import"
267 267 feature.
268 268
269 269 $ mkdir -p $TESTTMP/extlibroot/lsub1/lsub2
270 270 $ touch $TESTTMP/extlibroot/__init__.py
271 271 $ touch $TESTTMP/extlibroot/lsub1/__init__.py
272 272 $ touch $TESTTMP/extlibroot/lsub1/lsub2/__init__.py
273 273
274 274 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/called.py <<EOF
275 275 > def func():
276 276 > return "this is extlibroot.lsub1.lsub2.called.func()"
277 277 > EOF
278 278 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/unused.py <<EOF
279 279 > raise Exception("extlibroot.lsub1.lsub2.unused is loaded unintentionally")
280 280 > EOF
281 281 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/used.py <<EOF
282 282 > detail = "this is extlibroot.lsub1.lsub2.used"
283 283 > EOF
284 284
285 285 Setup sub-package of "external library", which causes instantiation of
286 286 demandmod in "recurse down the module chain" code path. Relative
287 287 importing with "absolute_import" feature isn't tested, because "level
288 288 >=1 " doesn't cause instantiation of demandmod.
289 289
290 290 $ mkdir -p $TESTTMP/extlibroot/recursedown/abs
291 291 $ cat > $TESTTMP/extlibroot/recursedown/abs/used.py <<EOF
292 292 > detail = "this is extlibroot.recursedown.abs.used"
293 293 > EOF
294 294 $ cat > $TESTTMP/extlibroot/recursedown/abs/__init__.py <<EOF
295 295 > from __future__ import absolute_import
296 296 > from extlibroot.recursedown.abs.used import detail
297 297 > EOF
298 298
299 299 $ mkdir -p $TESTTMP/extlibroot/recursedown/legacy
300 300 $ cat > $TESTTMP/extlibroot/recursedown/legacy/used.py <<EOF
301 301 > detail = "this is extlibroot.recursedown.legacy.used"
302 302 > EOF
303 303 $ cat > $TESTTMP/extlibroot/recursedown/legacy/__init__.py <<EOF
304 304 > # legacy style (level == -1) import
305 305 > from extlibroot.recursedown.legacy.used import detail
306 306 > EOF
307 307
308 308 $ cat > $TESTTMP/extlibroot/recursedown/__init__.py <<EOF
309 309 > from __future__ import absolute_import
310 310 > from extlibroot.recursedown.abs import detail as absdetail
311 311 > from .legacy import detail as legacydetail
312 312 > EOF
313 313
314 314 Setup extension local modules to be imported with "absolute_import"
315 315 feature.
316 316
317 317 $ mkdir -p $TESTTMP/absextroot/xsub1/xsub2
318 318 $ touch $TESTTMP/absextroot/xsub1/__init__.py
319 319 $ touch $TESTTMP/absextroot/xsub1/xsub2/__init__.py
320 320
321 321 $ cat > $TESTTMP/absextroot/xsub1/xsub2/called.py <<EOF
322 322 > def func():
323 323 > return "this is absextroot.xsub1.xsub2.called.func()"
324 324 > EOF
325 325 $ cat > $TESTTMP/absextroot/xsub1/xsub2/unused.py <<EOF
326 326 > raise Exception("absextroot.xsub1.xsub2.unused is loaded unintentionally")
327 327 > EOF
328 328 $ cat > $TESTTMP/absextroot/xsub1/xsub2/used.py <<EOF
329 329 > detail = "this is absextroot.xsub1.xsub2.used"
330 330 > EOF
331 331
332 332 Setup extension local modules to examine whether demand importing
333 333 works as expected in "level > 1" case.
334 334
335 335 $ cat > $TESTTMP/absextroot/relimportee.py <<EOF
336 336 > detail = "this is absextroot.relimportee"
337 337 > EOF
338 338 $ cat > $TESTTMP/absextroot/xsub1/xsub2/relimporter.py <<EOF
339 339 > from __future__ import absolute_import
340 340 > from ... import relimportee
341 341 > detail = "this relimporter imports %r" % (relimportee.detail)
342 342 > EOF
343 343
344 344 Setup modules, which actually import extension local modules at
345 345 runtime.
346 346
347 347 $ cat > $TESTTMP/absextroot/absolute.py << EOF
348 348 > from __future__ import absolute_import
349 349 >
350 350 > # import extension local modules absolutely (level = 0)
351 351 > from absextroot.xsub1.xsub2 import used, unused
352 352 > from absextroot.xsub1.xsub2.called import func
353 353 >
354 354 > def getresult():
355 355 > result = []
356 356 > result.append(used.detail)
357 357 > result.append(func())
358 358 > return result
359 359 > EOF
360 360
361 361 $ cat > $TESTTMP/absextroot/relative.py << EOF
362 362 > from __future__ import absolute_import
363 363 >
364 364 > # import extension local modules relatively (level == 1)
365 365 > from .xsub1.xsub2 import used, unused
366 366 > from .xsub1.xsub2.called import func
367 367 >
368 368 > # import a module, which implies "importing with level > 1"
369 369 > from .xsub1.xsub2 import relimporter
370 370 >
371 371 > def getresult():
372 372 > result = []
373 373 > result.append(used.detail)
374 374 > result.append(func())
375 375 > result.append(relimporter.detail)
376 376 > return result
377 377 > EOF
378 378
379 379 Setup main procedure of extension.
380 380
381 381 $ cat > $TESTTMP/absextroot/__init__.py <<EOF
382 382 > from __future__ import absolute_import
383 383 > from mercurial import cmdutil
384 384 > cmdtable = {}
385 385 > command = cmdutil.command(cmdtable)
386 386 >
387 387 > # "absolute" and "relative" shouldn't be imported before actual
388 388 > # command execution, because (1) they import same modules, and (2)
389 389 > # preceding import (= instantiate "demandmod" object instead of
390 390 > # real "module" object) might hide problem of succeeding import.
391 391 >
392 392 > @command('showabsolute', [], norepo=True)
393 393 > def showabsolute(ui, *args, **opts):
394 394 > from absextroot import absolute
395 395 > ui.write('ABS: %s\n' % '\nABS: '.join(absolute.getresult()))
396 396 >
397 397 > @command('showrelative', [], norepo=True)
398 398 > def showrelative(ui, *args, **opts):
399 399 > from . import relative
400 400 > ui.write('REL: %s\n' % '\nREL: '.join(relative.getresult()))
401 401 >
402 402 > # import modules from external library
403 403 > from extlibroot.lsub1.lsub2 import used as lused, unused as lunused
404 404 > from extlibroot.lsub1.lsub2.called import func as lfunc
405 405 > from extlibroot.recursedown import absdetail, legacydetail
406 406 >
407 407 > def uisetup(ui):
408 408 > result = []
409 409 > result.append(lused.detail)
410 410 > result.append(lfunc())
411 411 > result.append(absdetail)
412 412 > result.append(legacydetail)
413 413 > ui.write('LIB: %s\n' % '\nLIB: '.join(result))
414 414 > EOF
415 415
416 416 Examine module importing.
417 417
418 418 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showabsolute)
419 419 LIB: this is extlibroot.lsub1.lsub2.used
420 420 LIB: this is extlibroot.lsub1.lsub2.called.func()
421 421 LIB: this is extlibroot.recursedown.abs.used
422 422 LIB: this is extlibroot.recursedown.legacy.used
423 423 ABS: this is absextroot.xsub1.xsub2.used
424 424 ABS: this is absextroot.xsub1.xsub2.called.func()
425 425
426 426 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showrelative)
427 427 LIB: this is extlibroot.lsub1.lsub2.used
428 428 LIB: this is extlibroot.lsub1.lsub2.called.func()
429 429 LIB: this is extlibroot.recursedown.abs.used
430 430 LIB: this is extlibroot.recursedown.legacy.used
431 431 REL: this is absextroot.xsub1.xsub2.used
432 432 REL: this is absextroot.xsub1.xsub2.called.func()
433 433 REL: this relimporter imports 'this is absextroot.relimportee'
434 434
435 435 Examine whether sub-module is imported relatively as expected.
436 436
437 437 See also issue5208 for detail about example case on Python 3.x.
438 438
439 439 $ f -q $TESTTMP/extlibroot/lsub1/lsub2/notexist.py
440 440 $TESTTMP/extlibroot/lsub1/lsub2/notexist.py: file not found
441 441
442 442 $ cat > $TESTTMP/notexist.py <<EOF
443 443 > text = 'notexist.py at root is loaded unintentionally\n'
444 444 > EOF
445 445
446 446 $ cat > $TESTTMP/checkrelativity.py <<EOF
447 447 > from mercurial import cmdutil
448 448 > cmdtable = {}
449 449 > command = cmdutil.command(cmdtable)
450 450 >
451 451 > # demand import avoids failure of importing notexist here
452 452 > import extlibroot.lsub1.lsub2.notexist
453 453 >
454 454 > @command('checkrelativity', [], norepo=True)
455 455 > def checkrelativity(ui, *args, **opts):
456 456 > try:
457 457 > ui.write(extlibroot.lsub1.lsub2.notexist.text)
458 458 > return 1 # unintentional success
459 459 > except ImportError:
460 460 > pass # intentional failure
461 461 > EOF
462 462
463 463 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.checkrelativity=$TESTTMP/checkrelativity.py checkrelativity)
464 464
465 465 #endif
466 466
467 467 $ cd ..
468 468
469 469 hide outer repo
470 470 $ hg init
471 471
472 472 $ cat > empty.py <<EOF
473 473 > '''empty cmdtable
474 474 > '''
475 475 > cmdtable = {}
476 476 > EOF
477 477 $ emptypath=`pwd`/empty.py
478 478 $ echo "empty = $emptypath" >> $HGRCPATH
479 479 $ hg help empty
480 480 empty extension - empty cmdtable
481 481
482 482 no commands defined
483 483
484 484
485 485 $ echo 'empty = !' >> $HGRCPATH
486 486
487 487 $ cat > debugextension.py <<EOF
488 488 > '''only debugcommands
489 489 > '''
490 490 > from mercurial import cmdutil
491 491 > cmdtable = {}
492 492 > command = cmdutil.command(cmdtable)
493 493 > @command('debugfoobar', [], 'hg debugfoobar')
494 494 > def debugfoobar(ui, repo, *args, **opts):
495 495 > "yet another debug command"
496 496 > pass
497 497 > @command('foo', [], 'hg foo')
498 498 > def foo(ui, repo, *args, **opts):
499 499 > """yet another foo command
500 500 > This command has been DEPRECATED since forever.
501 501 > """
502 502 > pass
503 503 > EOF
504 504 $ debugpath=`pwd`/debugextension.py
505 505 $ echo "debugextension = $debugpath" >> $HGRCPATH
506 506
507 507 $ hg help debugextension
508 508 hg debugextensions
509 509
510 510 show information about active extensions
511 511
512 512 options:
513 513
514 514 (some details hidden, use --verbose to show complete help)
515 515
516 516
517 517 $ hg --verbose help debugextension
518 518 hg debugextensions
519 519
520 520 show information about active extensions
521 521
522 522 options:
523 523
524 524 -T --template TEMPLATE display with template (EXPERIMENTAL)
525 525
526 526 global options ([+] can be repeated):
527 527
528 528 -R --repository REPO repository root directory or name of overlay bundle
529 529 file
530 530 --cwd DIR change working directory
531 531 -y --noninteractive do not prompt, automatically pick the first choice for
532 532 all prompts
533 533 -q --quiet suppress output
534 534 -v --verbose enable additional output
535 --color TYPE when to colorize (boolean, always, auto, never, or
536 debug) (EXPERIMENTAL) (default: never)
535 537 --config CONFIG [+] set/override config option (use 'section.name=value')
536 538 --debug enable debugging output
537 539 --debugger start debugger
538 540 --encoding ENCODE set the charset encoding (default: ascii)
539 541 --encodingmode MODE set the charset encoding mode (default: strict)
540 542 --traceback always print a traceback on exception
541 543 --time time how long the command takes
542 544 --profile print command execution profile
543 545 --version output version information and exit
544 546 -h --help display help and exit
545 547 --hidden consider hidden changesets
546 548 --pager TYPE when to paginate (boolean, always, auto, or never)
547 549 (default: auto)
548 550
549 551
550 552
551 553
552 554
553 555
554 556 $ hg --debug help debugextension
555 557 hg debugextensions
556 558
557 559 show information about active extensions
558 560
559 561 options:
560 562
561 563 -T --template TEMPLATE display with template (EXPERIMENTAL)
562 564
563 565 global options ([+] can be repeated):
564 566
565 567 -R --repository REPO repository root directory or name of overlay bundle
566 568 file
567 569 --cwd DIR change working directory
568 570 -y --noninteractive do not prompt, automatically pick the first choice for
569 571 all prompts
570 572 -q --quiet suppress output
571 573 -v --verbose enable additional output
574 --color TYPE when to colorize (boolean, always, auto, never, or
575 debug) (EXPERIMENTAL) (default: never)
572 576 --config CONFIG [+] set/override config option (use 'section.name=value')
573 577 --debug enable debugging output
574 578 --debugger start debugger
575 579 --encoding ENCODE set the charset encoding (default: ascii)
576 580 --encodingmode MODE set the charset encoding mode (default: strict)
577 581 --traceback always print a traceback on exception
578 582 --time time how long the command takes
579 583 --profile print command execution profile
580 584 --version output version information and exit
581 585 -h --help display help and exit
582 586 --hidden consider hidden changesets
583 587 --pager TYPE when to paginate (boolean, always, auto, or never)
584 588 (default: auto)
585 589
586 590
587 591
588 592
589 593
590 594 $ echo 'debugextension = !' >> $HGRCPATH
591 595
592 596 Asking for help about a deprecated extension should do something useful:
593 597
594 598 $ hg help glog
595 599 'glog' is provided by the following extension:
596 600
597 601 graphlog command to view revision graphs from a shell (DEPRECATED)
598 602
599 603 (use 'hg help extensions' for information on enabling extensions)
600 604
601 605 Extension module help vs command help:
602 606
603 607 $ echo 'extdiff =' >> $HGRCPATH
604 608 $ hg help extdiff
605 609 hg extdiff [OPT]... [FILE]...
606 610
607 611 use external program to diff repository (or selected files)
608 612
609 613 Show differences between revisions for the specified files, using an
610 614 external program. The default program used is diff, with default options
611 615 "-Npru".
612 616
613 617 To select a different program, use the -p/--program option. The program
614 618 will be passed the names of two directories to compare. To pass additional
615 619 options to the program, use -o/--option. These will be passed before the
616 620 names of the directories to compare.
617 621
618 622 When two revision arguments are given, then changes are shown between
619 623 those revisions. If only one revision is specified then that revision is
620 624 compared to the working directory, and, when no revisions are specified,
621 625 the working directory files are compared to its parent.
622 626
623 627 (use 'hg help -e extdiff' to show help for the extdiff extension)
624 628
625 629 options ([+] can be repeated):
626 630
627 631 -p --program CMD comparison program to run
628 632 -o --option OPT [+] pass option to comparison program
629 633 -r --rev REV [+] revision
630 634 -c --change REV change made by revision
631 635 --patch compare patches for two revisions
632 636 -I --include PATTERN [+] include names matching the given patterns
633 637 -X --exclude PATTERN [+] exclude names matching the given patterns
634 638 -S --subrepos recurse into subrepositories
635 639
636 640 (some details hidden, use --verbose to show complete help)
637 641
638 642
639 643
640 644
641 645
642 646
643 647
644 648
645 649
646 650
647 651 $ hg help --extension extdiff
648 652 extdiff extension - command to allow external programs to compare revisions
649 653
650 654 The extdiff Mercurial extension allows you to use external programs to compare
651 655 revisions, or revision with working directory. The external diff programs are
652 656 called with a configurable set of options and two non-option arguments: paths
653 657 to directories containing snapshots of files to compare.
654 658
655 659 The extdiff extension also allows you to configure new diff commands, so you
656 660 do not need to type 'hg extdiff -p kdiff3' always.
657 661
658 662 [extdiff]
659 663 # add new command that runs GNU diff(1) in 'context diff' mode
660 664 cdiff = gdiff -Nprc5
661 665 ## or the old way:
662 666 #cmd.cdiff = gdiff
663 667 #opts.cdiff = -Nprc5
664 668
665 669 # add new command called meld, runs meld (no need to name twice). If
666 670 # the meld executable is not available, the meld tool in [merge-tools]
667 671 # will be used, if available
668 672 meld =
669 673
670 674 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
671 675 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
672 676 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
673 677 # your .vimrc
674 678 vimdiff = gvim -f "+next" \
675 679 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
676 680
677 681 Tool arguments can include variables that are expanded at runtime:
678 682
679 683 $parent1, $plabel1 - filename, descriptive label of first parent
680 684 $child, $clabel - filename, descriptive label of child revision
681 685 $parent2, $plabel2 - filename, descriptive label of second parent
682 686 $root - repository root
683 687 $parent is an alias for $parent1.
684 688
685 689 The extdiff extension will look in your [diff-tools] and [merge-tools]
686 690 sections for diff tool arguments, when none are specified in [extdiff].
687 691
688 692 [extdiff]
689 693 kdiff3 =
690 694
691 695 [diff-tools]
692 696 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
693 697
694 698 You can use -I/-X and list of file or directory names like normal 'hg diff'
695 699 command. The extdiff extension makes snapshots of only needed files, so
696 700 running the external diff program will actually be pretty fast (at least
697 701 faster than having to compare the entire tree).
698 702
699 703 list of commands:
700 704
701 705 extdiff use external program to diff repository (or selected files)
702 706
703 707 (use 'hg help -v -e extdiff' to show built-in aliases and global options)
704 708
705 709
706 710
707 711
708 712
709 713
710 714
711 715
712 716
713 717
714 718
715 719
716 720
717 721
718 722
719 723
720 724 $ echo 'extdiff = !' >> $HGRCPATH
721 725
722 726 Test help topic with same name as extension
723 727
724 728 $ cat > multirevs.py <<EOF
725 729 > from mercurial import cmdutil, commands
726 730 > cmdtable = {}
727 731 > command = cmdutil.command(cmdtable)
728 732 > """multirevs extension
729 733 > Big multi-line module docstring."""
730 734 > @command('multirevs', [], 'ARG', norepo=True)
731 735 > def multirevs(ui, repo, arg, *args, **opts):
732 736 > """multirevs command"""
733 737 > pass
734 738 > EOF
735 739 $ echo "multirevs = multirevs.py" >> $HGRCPATH
736 740
737 741 $ hg help multirevs | tail
738 742 bookmark (this works because the last revision of the revset is used):
739 743
740 744 hg update :@
741 745
742 746 - Show diff between tags 1.3 and 1.5 (this works because the first and the
743 747 last revisions of the revset are used):
744 748
745 749 hg diff -r 1.3::1.5
746 750
747 751 use 'hg help -c multirevs' to see help for the multirevs command
748 752
749 753
750 754
751 755
752 756
753 757
754 758 $ hg help -c multirevs
755 759 hg multirevs ARG
756 760
757 761 multirevs command
758 762
759 763 (some details hidden, use --verbose to show complete help)
760 764
761 765
762 766
763 767 $ hg multirevs
764 768 hg multirevs: invalid arguments
765 769 hg multirevs ARG
766 770
767 771 multirevs command
768 772
769 773 (use 'hg multirevs -h' to show more help)
770 774 [255]
771 775
772 776
773 777
774 778 $ echo "multirevs = !" >> $HGRCPATH
775 779
776 780 Issue811: Problem loading extensions twice (by site and by user)
777 781
778 782 $ cat <<EOF >> $HGRCPATH
779 783 > mq =
780 784 > strip =
781 785 > hgext.mq =
782 786 > hgext/mq =
783 787 > EOF
784 788
785 789 Show extensions:
786 790 (note that mq force load strip, also checking it's not loaded twice)
787 791
788 792 $ hg debugextensions
789 793 mq
790 794 strip
791 795
792 796 For extensions, which name matches one of its commands, help
793 797 message should ask '-v -e' to get list of built-in aliases
794 798 along with extension help itself
795 799
796 800 $ mkdir $TESTTMP/d
797 801 $ cat > $TESTTMP/d/dodo.py <<EOF
798 802 > """
799 803 > This is an awesome 'dodo' extension. It does nothing and
800 804 > writes 'Foo foo'
801 805 > """
802 806 > from mercurial import cmdutil, commands
803 807 > cmdtable = {}
804 808 > command = cmdutil.command(cmdtable)
805 809 > @command('dodo', [], 'hg dodo')
806 810 > def dodo(ui, *args, **kwargs):
807 811 > """Does nothing"""
808 812 > ui.write("I do nothing. Yay\\n")
809 813 > @command('foofoo', [], 'hg foofoo')
810 814 > def foofoo(ui, *args, **kwargs):
811 815 > """Writes 'Foo foo'"""
812 816 > ui.write("Foo foo\\n")
813 817 > EOF
814 818 $ dodopath=$TESTTMP/d/dodo.py
815 819
816 820 $ echo "dodo = $dodopath" >> $HGRCPATH
817 821
818 822 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
819 823 $ hg help -e dodo
820 824 dodo extension -
821 825
822 826 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
823 827
824 828 list of commands:
825 829
826 830 dodo Does nothing
827 831 foofoo Writes 'Foo foo'
828 832
829 833 (use 'hg help -v -e dodo' to show built-in aliases and global options)
830 834
831 835 Make sure that '-v -e' prints list of built-in aliases along with
832 836 extension help itself
833 837 $ hg help -v -e dodo
834 838 dodo extension -
835 839
836 840 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
837 841
838 842 list of commands:
839 843
840 844 dodo Does nothing
841 845 foofoo Writes 'Foo foo'
842 846
843 847 global options ([+] can be repeated):
844 848
845 849 -R --repository REPO repository root directory or name of overlay bundle
846 850 file
847 851 --cwd DIR change working directory
848 852 -y --noninteractive do not prompt, automatically pick the first choice for
849 853 all prompts
850 854 -q --quiet suppress output
851 855 -v --verbose enable additional output
856 --color TYPE when to colorize (boolean, always, auto, never, or
857 debug) (EXPERIMENTAL) (default: never)
852 858 --config CONFIG [+] set/override config option (use 'section.name=value')
853 859 --debug enable debugging output
854 860 --debugger start debugger
855 861 --encoding ENCODE set the charset encoding (default: ascii)
856 862 --encodingmode MODE set the charset encoding mode (default: strict)
857 863 --traceback always print a traceback on exception
858 864 --time time how long the command takes
859 865 --profile print command execution profile
860 866 --version output version information and exit
861 867 -h --help display help and exit
862 868 --hidden consider hidden changesets
863 869 --pager TYPE when to paginate (boolean, always, auto, or never)
864 870 (default: auto)
865 871
866 872 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
867 873 $ hg help -v dodo
868 874 hg dodo
869 875
870 876 Does nothing
871 877
872 878 (use 'hg help -e dodo' to show help for the dodo extension)
873 879
874 880 options:
875 881
876 882 --mq operate on patch repository
877 883
878 884 global options ([+] can be repeated):
879 885
880 886 -R --repository REPO repository root directory or name of overlay bundle
881 887 file
882 888 --cwd DIR change working directory
883 889 -y --noninteractive do not prompt, automatically pick the first choice for
884 890 all prompts
885 891 -q --quiet suppress output
886 892 -v --verbose enable additional output
893 --color TYPE when to colorize (boolean, always, auto, never, or
894 debug) (EXPERIMENTAL) (default: never)
887 895 --config CONFIG [+] set/override config option (use 'section.name=value')
888 896 --debug enable debugging output
889 897 --debugger start debugger
890 898 --encoding ENCODE set the charset encoding (default: ascii)
891 899 --encodingmode MODE set the charset encoding mode (default: strict)
892 900 --traceback always print a traceback on exception
893 901 --time time how long the command takes
894 902 --profile print command execution profile
895 903 --version output version information and exit
896 904 -h --help display help and exit
897 905 --hidden consider hidden changesets
898 906 --pager TYPE when to paginate (boolean, always, auto, or never)
899 907 (default: auto)
900 908
901 909 In case when extension name doesn't match any of its commands,
902 910 help message should ask for '-v' to get list of built-in aliases
903 911 along with extension help
904 912 $ cat > $TESTTMP/d/dudu.py <<EOF
905 913 > """
906 914 > This is an awesome 'dudu' extension. It does something and
907 915 > also writes 'Beep beep'
908 916 > """
909 917 > from mercurial import cmdutil, commands
910 918 > cmdtable = {}
911 919 > command = cmdutil.command(cmdtable)
912 920 > @command('something', [], 'hg something')
913 921 > def something(ui, *args, **kwargs):
914 922 > """Does something"""
915 923 > ui.write("I do something. Yaaay\\n")
916 924 > @command('beep', [], 'hg beep')
917 925 > def beep(ui, *args, **kwargs):
918 926 > """Writes 'Beep beep'"""
919 927 > ui.write("Beep beep\\n")
920 928 > EOF
921 929 $ dudupath=$TESTTMP/d/dudu.py
922 930
923 931 $ echo "dudu = $dudupath" >> $HGRCPATH
924 932
925 933 $ hg help -e dudu
926 934 dudu extension -
927 935
928 936 This is an awesome 'dudu' extension. It does something and also writes 'Beep
929 937 beep'
930 938
931 939 list of commands:
932 940
933 941 beep Writes 'Beep beep'
934 942 something Does something
935 943
936 944 (use 'hg help -v dudu' to show built-in aliases and global options)
937 945
938 946 In case when extension name doesn't match any of its commands,
939 947 help options '-v' and '-v -e' should be equivalent
940 948 $ hg help -v dudu
941 949 dudu extension -
942 950
943 951 This is an awesome 'dudu' extension. It does something and also writes 'Beep
944 952 beep'
945 953
946 954 list of commands:
947 955
948 956 beep Writes 'Beep beep'
949 957 something Does something
950 958
951 959 global options ([+] can be repeated):
952 960
953 961 -R --repository REPO repository root directory or name of overlay bundle
954 962 file
955 963 --cwd DIR change working directory
956 964 -y --noninteractive do not prompt, automatically pick the first choice for
957 965 all prompts
958 966 -q --quiet suppress output
959 967 -v --verbose enable additional output
968 --color TYPE when to colorize (boolean, always, auto, never, or
969 debug) (EXPERIMENTAL) (default: never)
960 970 --config CONFIG [+] set/override config option (use 'section.name=value')
961 971 --debug enable debugging output
962 972 --debugger start debugger
963 973 --encoding ENCODE set the charset encoding (default: ascii)
964 974 --encodingmode MODE set the charset encoding mode (default: strict)
965 975 --traceback always print a traceback on exception
966 976 --time time how long the command takes
967 977 --profile print command execution profile
968 978 --version output version information and exit
969 979 -h --help display help and exit
970 980 --hidden consider hidden changesets
971 981 --pager TYPE when to paginate (boolean, always, auto, or never)
972 982 (default: auto)
973 983
974 984 $ hg help -v -e dudu
975 985 dudu extension -
976 986
977 987 This is an awesome 'dudu' extension. It does something and also writes 'Beep
978 988 beep'
979 989
980 990 list of commands:
981 991
982 992 beep Writes 'Beep beep'
983 993 something Does something
984 994
985 995 global options ([+] can be repeated):
986 996
987 997 -R --repository REPO repository root directory or name of overlay bundle
988 998 file
989 999 --cwd DIR change working directory
990 1000 -y --noninteractive do not prompt, automatically pick the first choice for
991 1001 all prompts
992 1002 -q --quiet suppress output
993 1003 -v --verbose enable additional output
1004 --color TYPE when to colorize (boolean, always, auto, never, or
1005 debug) (EXPERIMENTAL) (default: never)
994 1006 --config CONFIG [+] set/override config option (use 'section.name=value')
995 1007 --debug enable debugging output
996 1008 --debugger start debugger
997 1009 --encoding ENCODE set the charset encoding (default: ascii)
998 1010 --encodingmode MODE set the charset encoding mode (default: strict)
999 1011 --traceback always print a traceback on exception
1000 1012 --time time how long the command takes
1001 1013 --profile print command execution profile
1002 1014 --version output version information and exit
1003 1015 -h --help display help and exit
1004 1016 --hidden consider hidden changesets
1005 1017 --pager TYPE when to paginate (boolean, always, auto, or never)
1006 1018 (default: auto)
1007 1019
1008 1020 Disabled extension commands:
1009 1021
1010 1022 $ ORGHGRCPATH=$HGRCPATH
1011 1023 $ HGRCPATH=
1012 1024 $ export HGRCPATH
1013 1025 $ hg help email
1014 1026 'email' is provided by the following extension:
1015 1027
1016 1028 patchbomb command to send changesets as (a series of) patch emails
1017 1029
1018 1030 (use 'hg help extensions' for information on enabling extensions)
1019 1031
1020 1032
1021 1033 $ hg qdel
1022 1034 hg: unknown command 'qdel'
1023 1035 'qdelete' is provided by the following extension:
1024 1036
1025 1037 mq manage a stack of patches
1026 1038
1027 1039 (use 'hg help extensions' for information on enabling extensions)
1028 1040 [255]
1029 1041
1030 1042
1031 1043 $ hg churn
1032 1044 hg: unknown command 'churn'
1033 1045 'churn' is provided by the following extension:
1034 1046
1035 1047 churn command to display statistics about repository history
1036 1048
1037 1049 (use 'hg help extensions' for information on enabling extensions)
1038 1050 [255]
1039 1051
1040 1052
1041 1053
1042 1054 Disabled extensions:
1043 1055
1044 1056 $ hg help churn
1045 1057 churn extension - command to display statistics about repository history
1046 1058
1047 1059 (use 'hg help extensions' for information on enabling extensions)
1048 1060
1049 1061 $ hg help patchbomb
1050 1062 patchbomb extension - command to send changesets as (a series of) patch emails
1051 1063
1052 1064 The series is started off with a "[PATCH 0 of N]" introduction, which
1053 1065 describes the series as a whole.
1054 1066
1055 1067 Each patch email has a Subject line of "[PATCH M of N] ...", using the first
1056 1068 line of the changeset description as the subject text. The message contains
1057 1069 two or three body parts:
1058 1070
1059 1071 - The changeset description.
1060 1072 - [Optional] The result of running diffstat on the patch.
1061 1073 - The patch itself, as generated by 'hg export'.
1062 1074
1063 1075 Each message refers to the first in the series using the In-Reply-To and
1064 1076 References headers, so they will show up as a sequence in threaded mail and
1065 1077 news readers, and in mail archives.
1066 1078
1067 1079 To configure other defaults, add a section like this to your configuration
1068 1080 file:
1069 1081
1070 1082 [email]
1071 1083 from = My Name <my@email>
1072 1084 to = recipient1, recipient2, ...
1073 1085 cc = cc1, cc2, ...
1074 1086 bcc = bcc1, bcc2, ...
1075 1087 reply-to = address1, address2, ...
1076 1088
1077 1089 Use "[patchbomb]" as configuration section name if you need to override global
1078 1090 "[email]" address settings.
1079 1091
1080 1092 Then you can use the 'hg email' command to mail a series of changesets as a
1081 1093 patchbomb.
1082 1094
1083 1095 You can also either configure the method option in the email section to be a
1084 1096 sendmail compatible mailer or fill out the [smtp] section so that the
1085 1097 patchbomb extension can automatically send patchbombs directly from the
1086 1098 commandline. See the [email] and [smtp] sections in hgrc(5) for details.
1087 1099
1088 1100 By default, 'hg email' will prompt for a "To" or "CC" header if you do not
1089 1101 supply one via configuration or the command line. You can override this to
1090 1102 never prompt by configuring an empty value:
1091 1103
1092 1104 [email]
1093 1105 cc =
1094 1106
1095 1107 You can control the default inclusion of an introduction message with the
1096 1108 "patchbomb.intro" configuration option. The configuration is always
1097 1109 overwritten by command line flags like --intro and --desc:
1098 1110
1099 1111 [patchbomb]
1100 1112 intro=auto # include introduction message if more than 1 patch (default)
1101 1113 intro=never # never include an introduction message
1102 1114 intro=always # always include an introduction message
1103 1115
1104 1116 You can set patchbomb to always ask for confirmation by setting
1105 1117 "patchbomb.confirm" to true.
1106 1118
1107 1119 (use 'hg help extensions' for information on enabling extensions)
1108 1120
1109 1121
1110 1122 Broken disabled extension and command:
1111 1123
1112 1124 $ mkdir hgext
1113 1125 $ echo > hgext/__init__.py
1114 1126 $ cat > hgext/broken.py <<EOF
1115 1127 > "broken extension'
1116 1128 > EOF
1117 1129 $ cat > path.py <<EOF
1118 1130 > import os, sys
1119 1131 > sys.path.insert(0, os.environ['HGEXTPATH'])
1120 1132 > EOF
1121 1133 $ HGEXTPATH=`pwd`
1122 1134 $ export HGEXTPATH
1123 1135
1124 1136 $ hg --config extensions.path=./path.py help broken
1125 1137 broken extension - (no help text available)
1126 1138
1127 1139 (use 'hg help extensions' for information on enabling extensions)
1128 1140
1129 1141
1130 1142 $ cat > hgext/forest.py <<EOF
1131 1143 > cmdtable = None
1132 1144 > EOF
1133 1145 $ hg --config extensions.path=./path.py help foo > /dev/null
1134 1146 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
1135 1147 abort: no such help topic: foo
1136 1148 (try 'hg help --keyword foo')
1137 1149 [255]
1138 1150
1139 1151 $ cat > throw.py <<EOF
1140 1152 > from mercurial import cmdutil, commands, util
1141 1153 > cmdtable = {}
1142 1154 > command = cmdutil.command(cmdtable)
1143 1155 > class Bogon(Exception): pass
1144 1156 > @command('throw', [], 'hg throw', norepo=True)
1145 1157 > def throw(ui, **opts):
1146 1158 > """throws an exception"""
1147 1159 > raise Bogon()
1148 1160 > EOF
1149 1161
1150 1162 No declared supported version, extension complains:
1151 1163 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1152 1164 ** Unknown exception encountered with possibly-broken third-party extension throw
1153 1165 ** which supports versions unknown of Mercurial.
1154 1166 ** Please disable throw and try your action again.
1155 1167 ** If that fixes the bug please report it to the extension author.
1156 1168 ** Python * (glob)
1157 1169 ** Mercurial Distributed SCM * (glob)
1158 1170 ** Extensions loaded: throw
1159 1171
1160 1172 empty declaration of supported version, extension complains:
1161 1173 $ echo "testedwith = ''" >> throw.py
1162 1174 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1163 1175 ** Unknown exception encountered with possibly-broken third-party extension throw
1164 1176 ** which supports versions unknown of Mercurial.
1165 1177 ** Please disable throw and try your action again.
1166 1178 ** If that fixes the bug please report it to the extension author.
1167 1179 ** Python * (glob)
1168 1180 ** Mercurial Distributed SCM (*) (glob)
1169 1181 ** Extensions loaded: throw
1170 1182
1171 1183 If the extension specifies a buglink, show that:
1172 1184 $ echo 'buglink = "http://example.com/bts"' >> throw.py
1173 1185 $ rm -f throw.pyc throw.pyo
1174 1186 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1175 1187 ** Unknown exception encountered with possibly-broken third-party extension throw
1176 1188 ** which supports versions unknown of Mercurial.
1177 1189 ** Please disable throw and try your action again.
1178 1190 ** If that fixes the bug please report it to http://example.com/bts
1179 1191 ** Python * (glob)
1180 1192 ** Mercurial Distributed SCM (*) (glob)
1181 1193 ** Extensions loaded: throw
1182 1194
1183 1195 If the extensions declare outdated versions, accuse the older extension first:
1184 1196 $ echo "from mercurial import util" >> older.py
1185 1197 $ echo "util.version = lambda:'2.2'" >> older.py
1186 1198 $ echo "testedwith = '1.9.3'" >> older.py
1187 1199 $ echo "testedwith = '2.1.1'" >> throw.py
1188 1200 $ rm -f throw.pyc throw.pyo
1189 1201 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1190 1202 > throw 2>&1 | egrep '^\*\*'
1191 1203 ** Unknown exception encountered with possibly-broken third-party extension older
1192 1204 ** which supports versions 1.9 of Mercurial.
1193 1205 ** Please disable older and try your action again.
1194 1206 ** If that fixes the bug please report it to the extension author.
1195 1207 ** Python * (glob)
1196 1208 ** Mercurial Distributed SCM (version 2.2)
1197 1209 ** Extensions loaded: throw, older
1198 1210
1199 1211 One extension only tested with older, one only with newer versions:
1200 1212 $ echo "util.version = lambda:'2.1'" >> older.py
1201 1213 $ rm -f older.pyc older.pyo
1202 1214 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1203 1215 > throw 2>&1 | egrep '^\*\*'
1204 1216 ** Unknown exception encountered with possibly-broken third-party extension older
1205 1217 ** which supports versions 1.9 of Mercurial.
1206 1218 ** Please disable older and try your action again.
1207 1219 ** If that fixes the bug please report it to the extension author.
1208 1220 ** Python * (glob)
1209 1221 ** Mercurial Distributed SCM (version 2.1)
1210 1222 ** Extensions loaded: throw, older
1211 1223
1212 1224 Older extension is tested with current version, the other only with newer:
1213 1225 $ echo "util.version = lambda:'1.9.3'" >> older.py
1214 1226 $ rm -f older.pyc older.pyo
1215 1227 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1216 1228 > throw 2>&1 | egrep '^\*\*'
1217 1229 ** Unknown exception encountered with possibly-broken third-party extension throw
1218 1230 ** which supports versions 2.1 of Mercurial.
1219 1231 ** Please disable throw and try your action again.
1220 1232 ** If that fixes the bug please report it to http://example.com/bts
1221 1233 ** Python * (glob)
1222 1234 ** Mercurial Distributed SCM (version 1.9.3)
1223 1235 ** Extensions loaded: throw, older
1224 1236
1225 1237 Ability to point to a different point
1226 1238 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1227 1239 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
1228 1240 ** unknown exception encountered, please report by visiting
1229 1241 ** Your Local Goat Lenders
1230 1242 ** Python * (glob)
1231 1243 ** Mercurial Distributed SCM (*) (glob)
1232 1244 ** Extensions loaded: throw, older
1233 1245
1234 1246 Declare the version as supporting this hg version, show regular bts link:
1235 1247 $ hgver=`hg debuginstall -T '{hgver}'`
1236 1248 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
1237 1249 $ if [ -z "$hgver" ]; then
1238 1250 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
1239 1251 > fi
1240 1252 $ rm -f throw.pyc throw.pyo
1241 1253 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1242 1254 ** unknown exception encountered, please report by visiting
1243 1255 ** https://mercurial-scm.org/wiki/BugTracker
1244 1256 ** Python * (glob)
1245 1257 ** Mercurial Distributed SCM (*) (glob)
1246 1258 ** Extensions loaded: throw
1247 1259
1248 1260 Patch version is ignored during compatibility check
1249 1261 $ echo "testedwith = '3.2'" >> throw.py
1250 1262 $ echo "util.version = lambda:'3.2.2'" >> throw.py
1251 1263 $ rm -f throw.pyc throw.pyo
1252 1264 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1253 1265 ** unknown exception encountered, please report by visiting
1254 1266 ** https://mercurial-scm.org/wiki/BugTracker
1255 1267 ** Python * (glob)
1256 1268 ** Mercurial Distributed SCM (*) (glob)
1257 1269 ** Extensions loaded: throw
1258 1270
1259 1271 Test version number support in 'hg version':
1260 1272 $ echo '__version__ = (1, 2, 3)' >> throw.py
1261 1273 $ rm -f throw.pyc throw.pyo
1262 1274 $ hg version -v
1263 1275 Mercurial Distributed SCM (version *) (glob)
1264 1276 (see https://mercurial-scm.org for more information)
1265 1277
1266 1278 Copyright (C) 2005-* Matt Mackall and others (glob)
1267 1279 This is free software; see the source for copying conditions. There is NO
1268 1280 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1269 1281
1270 1282 Enabled extensions:
1271 1283
1272 1284
1273 1285 $ hg version -v --config extensions.throw=throw.py
1274 1286 Mercurial Distributed SCM (version *) (glob)
1275 1287 (see https://mercurial-scm.org for more information)
1276 1288
1277 1289 Copyright (C) 2005-* Matt Mackall and others (glob)
1278 1290 This is free software; see the source for copying conditions. There is NO
1279 1291 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1280 1292
1281 1293 Enabled extensions:
1282 1294
1283 1295 throw external 1.2.3
1284 1296 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1285 1297 $ rm -f throw.pyc throw.pyo
1286 1298 $ hg version -v --config extensions.throw=throw.py --config extensions.strip=
1287 1299 Mercurial Distributed SCM (version *) (glob)
1288 1300 (see https://mercurial-scm.org for more information)
1289 1301
1290 1302 Copyright (C) 2005-* Matt Mackall and others (glob)
1291 1303 This is free software; see the source for copying conditions. There is NO
1292 1304 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1293 1305
1294 1306 Enabled extensions:
1295 1307
1296 1308 throw external 1.twentythree
1297 1309 strip internal
1298 1310
1299 1311 $ hg version -q --config extensions.throw=throw.py
1300 1312 Mercurial Distributed SCM (version *) (glob)
1301 1313
1302 1314 Test JSON output of version:
1303 1315
1304 1316 $ hg version -Tjson
1305 1317 [
1306 1318 {
1307 1319 "extensions": [],
1308 1320 "ver": "*" (glob)
1309 1321 }
1310 1322 ]
1311 1323
1312 1324 $ hg version --config extensions.throw=throw.py -Tjson
1313 1325 [
1314 1326 {
1315 1327 "extensions": [{"bundled": false, "name": "throw", "ver": "1.twentythree"}],
1316 1328 "ver": "3.2.2"
1317 1329 }
1318 1330 ]
1319 1331
1320 1332 $ hg version --config extensions.strip= -Tjson
1321 1333 [
1322 1334 {
1323 1335 "extensions": [{"bundled": true, "name": "strip", "ver": null}],
1324 1336 "ver": "*" (glob)
1325 1337 }
1326 1338 ]
1327 1339
1328 1340 Test template output of version:
1329 1341
1330 1342 $ hg version --config extensions.throw=throw.py --config extensions.strip= \
1331 1343 > -T'{extensions % "{name} {pad(ver, 16)} ({if(bundled, "internal", "external")})\n"}'
1332 1344 throw 1.twentythree (external)
1333 1345 strip (internal)
1334 1346
1335 1347 Refuse to load extensions with minimum version requirements
1336 1348
1337 1349 $ cat > minversion1.py << EOF
1338 1350 > from mercurial import util
1339 1351 > util.version = lambda: '3.5.2'
1340 1352 > minimumhgversion = '3.6'
1341 1353 > EOF
1342 1354 $ hg --config extensions.minversion=minversion1.py version
1343 1355 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1344 1356 Mercurial Distributed SCM (version 3.5.2)
1345 1357 (see https://mercurial-scm.org for more information)
1346 1358
1347 1359 Copyright (C) 2005-* Matt Mackall and others (glob)
1348 1360 This is free software; see the source for copying conditions. There is NO
1349 1361 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1350 1362
1351 1363 $ cat > minversion2.py << EOF
1352 1364 > from mercurial import util
1353 1365 > util.version = lambda: '3.6'
1354 1366 > minimumhgversion = '3.7'
1355 1367 > EOF
1356 1368 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1357 1369 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1358 1370
1359 1371 Can load version that is only off by point release
1360 1372
1361 1373 $ cat > minversion2.py << EOF
1362 1374 > from mercurial import util
1363 1375 > util.version = lambda: '3.6.1'
1364 1376 > minimumhgversion = '3.6'
1365 1377 > EOF
1366 1378 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1367 1379 [1]
1368 1380
1369 1381 Can load minimum version identical to current
1370 1382
1371 1383 $ cat > minversion3.py << EOF
1372 1384 > from mercurial import util
1373 1385 > util.version = lambda: '3.5'
1374 1386 > minimumhgversion = '3.5'
1375 1387 > EOF
1376 1388 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1377 1389 [1]
1378 1390
1379 1391 Restore HGRCPATH
1380 1392
1381 1393 $ HGRCPATH=$ORGHGRCPATH
1382 1394 $ export HGRCPATH
1383 1395
1384 1396 Commands handling multiple repositories at a time should invoke only
1385 1397 "reposetup()" of extensions enabling in the target repository.
1386 1398
1387 1399 $ mkdir reposetup-test
1388 1400 $ cd reposetup-test
1389 1401
1390 1402 $ cat > $TESTTMP/reposetuptest.py <<EOF
1391 1403 > from mercurial import extensions
1392 1404 > def reposetup(ui, repo):
1393 1405 > ui.write('reposetup() for %s\n' % (repo.root))
1394 1406 > ui.flush()
1395 1407 > EOF
1396 1408 $ hg init src
1397 1409 $ echo a > src/a
1398 1410 $ hg -R src commit -Am '#0 at src/a'
1399 1411 adding a
1400 1412 $ echo '[extensions]' >> src/.hg/hgrc
1401 1413 $ echo '# enable extension locally' >> src/.hg/hgrc
1402 1414 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1403 1415 $ hg -R src status
1404 1416 reposetup() for $TESTTMP/reposetup-test/src (glob)
1405 1417
1406 1418 $ hg clone -U src clone-dst1
1407 1419 reposetup() for $TESTTMP/reposetup-test/src (glob)
1408 1420 $ hg init push-dst1
1409 1421 $ hg -q -R src push push-dst1
1410 1422 reposetup() for $TESTTMP/reposetup-test/src (glob)
1411 1423 $ hg init pull-src1
1412 1424 $ hg -q -R pull-src1 pull src
1413 1425 reposetup() for $TESTTMP/reposetup-test/src (glob)
1414 1426
1415 1427 $ cat <<EOF >> $HGRCPATH
1416 1428 > [extensions]
1417 1429 > # disable extension globally and explicitly
1418 1430 > reposetuptest = !
1419 1431 > EOF
1420 1432 $ hg clone -U src clone-dst2
1421 1433 reposetup() for $TESTTMP/reposetup-test/src (glob)
1422 1434 $ hg init push-dst2
1423 1435 $ hg -q -R src push push-dst2
1424 1436 reposetup() for $TESTTMP/reposetup-test/src (glob)
1425 1437 $ hg init pull-src2
1426 1438 $ hg -q -R pull-src2 pull src
1427 1439 reposetup() for $TESTTMP/reposetup-test/src (glob)
1428 1440
1429 1441 $ cat <<EOF >> $HGRCPATH
1430 1442 > [extensions]
1431 1443 > # enable extension globally
1432 1444 > reposetuptest = $TESTTMP/reposetuptest.py
1433 1445 > EOF
1434 1446 $ hg clone -U src clone-dst3
1435 1447 reposetup() for $TESTTMP/reposetup-test/src (glob)
1436 1448 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1437 1449 $ hg init push-dst3
1438 1450 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1439 1451 $ hg -q -R src push push-dst3
1440 1452 reposetup() for $TESTTMP/reposetup-test/src (glob)
1441 1453 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1442 1454 $ hg init pull-src3
1443 1455 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1444 1456 $ hg -q -R pull-src3 pull src
1445 1457 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1446 1458 reposetup() for $TESTTMP/reposetup-test/src (glob)
1447 1459
1448 1460 $ echo '[extensions]' >> src/.hg/hgrc
1449 1461 $ echo '# disable extension locally' >> src/.hg/hgrc
1450 1462 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1451 1463 $ hg clone -U src clone-dst4
1452 1464 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1453 1465 $ hg init push-dst4
1454 1466 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1455 1467 $ hg -q -R src push push-dst4
1456 1468 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1457 1469 $ hg init pull-src4
1458 1470 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1459 1471 $ hg -q -R pull-src4 pull src
1460 1472 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1461 1473
1462 1474 disabling in command line overlays with all configuration
1463 1475 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1464 1476 $ hg --config extensions.reposetuptest=! init push-dst5
1465 1477 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1466 1478 $ hg --config extensions.reposetuptest=! init pull-src5
1467 1479 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1468 1480
1469 1481 $ cat <<EOF >> $HGRCPATH
1470 1482 > [extensions]
1471 1483 > # disable extension globally and explicitly
1472 1484 > reposetuptest = !
1473 1485 > EOF
1474 1486 $ hg init parent
1475 1487 $ hg init parent/sub1
1476 1488 $ echo 1 > parent/sub1/1
1477 1489 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1478 1490 adding 1
1479 1491 $ hg init parent/sub2
1480 1492 $ hg init parent/sub2/sub21
1481 1493 $ echo 21 > parent/sub2/sub21/21
1482 1494 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1483 1495 adding 21
1484 1496 $ cat > parent/sub2/.hgsub <<EOF
1485 1497 > sub21 = sub21
1486 1498 > EOF
1487 1499 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1488 1500 adding .hgsub
1489 1501 $ hg init parent/sub3
1490 1502 $ echo 3 > parent/sub3/3
1491 1503 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1492 1504 adding 3
1493 1505 $ cat > parent/.hgsub <<EOF
1494 1506 > sub1 = sub1
1495 1507 > sub2 = sub2
1496 1508 > sub3 = sub3
1497 1509 > EOF
1498 1510 $ hg -R parent commit -Am '#0 at parent'
1499 1511 adding .hgsub
1500 1512 $ echo '[extensions]' >> parent/.hg/hgrc
1501 1513 $ echo '# enable extension locally' >> parent/.hg/hgrc
1502 1514 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1503 1515 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1504 1516 $ hg -R parent status -S -A
1505 1517 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1506 1518 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1507 1519 C .hgsub
1508 1520 C .hgsubstate
1509 1521 C sub1/1
1510 1522 C sub2/.hgsub
1511 1523 C sub2/.hgsubstate
1512 1524 C sub2/sub21/21
1513 1525 C sub3/3
1514 1526
1515 1527 $ cd ..
1516 1528
1517 1529 Test synopsis and docstring extending
1518 1530
1519 1531 $ hg init exthelp
1520 1532 $ cat > exthelp.py <<EOF
1521 1533 > from mercurial import commands, extensions
1522 1534 > def exbookmarks(orig, *args, **opts):
1523 1535 > return orig(*args, **opts)
1524 1536 > def uisetup(ui):
1525 1537 > synopsis = ' GREPME [--foo] [-x]'
1526 1538 > docstring = '''
1527 1539 > GREPME make sure that this is in the help!
1528 1540 > '''
1529 1541 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1530 1542 > synopsis, docstring)
1531 1543 > EOF
1532 1544 $ abspath=`pwd`/exthelp.py
1533 1545 $ echo '[extensions]' >> $HGRCPATH
1534 1546 $ echo "exthelp = $abspath" >> $HGRCPATH
1535 1547 $ cd exthelp
1536 1548 $ hg help bookmarks | grep GREPME
1537 1549 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1538 1550 GREPME make sure that this is in the help!
1539 1551
@@ -1,9 +1,9 b''
1 1 #require docutils gettext
2 2
3 3 Error: the current ro localization has some rst defects exposed by
4 4 moving pager to core. These two warnings about references are expected
5 5 until the localization is corrected.
6 6 $ $TESTDIR/check-gendoc ro
7 7 checking for parse errors
8 gendoc.txt:55: (WARNING/2) Inline interpreted text or phrase reference start-string without end-string.
9 gendoc.txt:55: (WARNING/2) Inline interpreted text or phrase reference start-string without end-string.
8 gendoc.txt:58: (WARNING/2) Inline interpreted text or phrase reference start-string without end-string.
9 gendoc.txt:58: (WARNING/2) Inline interpreted text or phrase reference start-string without end-string.
@@ -1,3205 +1,3215 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 $ hg help
48 48 Mercurial Distributed SCM
49 49
50 50 list of commands:
51 51
52 52 add add the specified files on the next commit
53 53 addremove add all new files, delete all missing files
54 54 annotate show changeset information by line for each file
55 55 archive create an unversioned archive of a repository revision
56 56 backout reverse effect of earlier changeset
57 57 bisect subdivision search of changesets
58 58 bookmarks create a new bookmark or list existing bookmarks
59 59 branch set or show the current branch name
60 60 branches list repository named branches
61 61 bundle create a changegroup file
62 62 cat output the current or given revision of files
63 63 clone make a copy of an existing repository
64 64 commit commit the specified files or all outstanding changes
65 65 config show combined config settings from all hgrc files
66 66 copy mark files as copied for the next commit
67 67 diff diff repository (or selected files)
68 68 export dump the header and diffs for one or more changesets
69 69 files list tracked files
70 70 forget forget the specified files on the next commit
71 71 graft copy changes from other branches onto the current branch
72 72 grep search revision history for a pattern in specified files
73 73 heads show branch heads
74 74 help show help for a given topic or a help overview
75 75 identify identify the working directory or specified revision
76 76 import import an ordered set of patches
77 77 incoming show new changesets found in source
78 78 init create a new repository in the given directory
79 79 log show revision history of entire repository or files
80 80 manifest output the current or given revision of the project manifest
81 81 merge merge another revision into working directory
82 82 outgoing show changesets not found in the destination
83 83 paths show aliases for remote repositories
84 84 phase set or show the current phase name
85 85 pull pull changes from the specified source
86 86 push push changes to the specified destination
87 87 recover roll back an interrupted transaction
88 88 remove remove the specified files on the next commit
89 89 rename rename files; equivalent of copy + remove
90 90 resolve redo merges or set/view the merge status of files
91 91 revert restore files to their checkout state
92 92 root print the root (top) of the current working directory
93 93 serve start stand-alone webserver
94 94 status show changed files in the working directory
95 95 summary summarize working directory state
96 96 tag add one or more tags for the current or given revision
97 97 tags list repository tags
98 98 unbundle apply one or more changegroup files
99 99 update update working directory (or switch revisions)
100 100 verify verify the integrity of the repository
101 101 version output version and copyright information
102 102
103 103 additional help topics:
104 104
105 105 config Configuration Files
106 106 dates Date Formats
107 107 diffs Diff Formats
108 108 environment Environment Variables
109 109 extensions Using Additional Features
110 110 filesets Specifying File Sets
111 111 glossary Glossary
112 112 hgignore Syntax for Mercurial Ignore Files
113 113 hgweb Configuring hgweb
114 114 internals Technical implementation topics
115 115 merge-tools Merge Tools
116 116 pager Pager Support
117 117 patterns File Name Patterns
118 118 phases Working with Phases
119 119 revisions Specifying Revisions
120 120 scripting Using Mercurial from scripts and automation
121 121 subrepos Subrepositories
122 122 templating Template Usage
123 123 urls URL Paths
124 124
125 125 (use 'hg help -v' to show built-in aliases and global options)
126 126
127 127 $ hg -q help
128 128 add add the specified files on the next commit
129 129 addremove add all new files, delete all missing files
130 130 annotate show changeset information by line for each file
131 131 archive create an unversioned archive of a repository revision
132 132 backout reverse effect of earlier changeset
133 133 bisect subdivision search of changesets
134 134 bookmarks create a new bookmark or list existing bookmarks
135 135 branch set or show the current branch name
136 136 branches list repository named branches
137 137 bundle create a changegroup file
138 138 cat output the current or given revision of files
139 139 clone make a copy of an existing repository
140 140 commit commit the specified files or all outstanding changes
141 141 config show combined config settings from all hgrc files
142 142 copy mark files as copied for the next commit
143 143 diff diff repository (or selected files)
144 144 export dump the header and diffs for one or more changesets
145 145 files list tracked files
146 146 forget forget the specified files on the next commit
147 147 graft copy changes from other branches onto the current branch
148 148 grep search revision history for a pattern in specified files
149 149 heads show branch heads
150 150 help show help for a given topic or a help overview
151 151 identify identify the working directory or specified revision
152 152 import import an ordered set of patches
153 153 incoming show new changesets found in source
154 154 init create a new repository in the given directory
155 155 log show revision history of entire repository or files
156 156 manifest output the current or given revision of the project manifest
157 157 merge merge another revision into working directory
158 158 outgoing show changesets not found in the destination
159 159 paths show aliases for remote repositories
160 160 phase set or show the current phase name
161 161 pull pull changes from the specified source
162 162 push push changes to the specified destination
163 163 recover roll back an interrupted transaction
164 164 remove remove the specified files on the next commit
165 165 rename rename files; equivalent of copy + remove
166 166 resolve redo merges or set/view the merge status of files
167 167 revert restore files to their checkout state
168 168 root print the root (top) of the current working directory
169 169 serve start stand-alone webserver
170 170 status show changed files in the working directory
171 171 summary summarize working directory state
172 172 tag add one or more tags for the current or given revision
173 173 tags list repository tags
174 174 unbundle apply one or more changegroup files
175 175 update update working directory (or switch revisions)
176 176 verify verify the integrity of the repository
177 177 version output version and copyright information
178 178
179 179 additional help topics:
180 180
181 181 config Configuration Files
182 182 dates Date Formats
183 183 diffs Diff Formats
184 184 environment Environment Variables
185 185 extensions Using Additional Features
186 186 filesets Specifying File Sets
187 187 glossary Glossary
188 188 hgignore Syntax for Mercurial Ignore Files
189 189 hgweb Configuring hgweb
190 190 internals Technical implementation topics
191 191 merge-tools Merge Tools
192 192 pager Pager Support
193 193 patterns File Name Patterns
194 194 phases Working with Phases
195 195 revisions Specifying Revisions
196 196 scripting Using Mercurial from scripts and automation
197 197 subrepos Subrepositories
198 198 templating Template Usage
199 199 urls URL Paths
200 200
201 201 Test extension help:
202 202 $ hg help extensions --config extensions.rebase= --config extensions.children=
203 203 Using Additional Features
204 204 """""""""""""""""""""""""
205 205
206 206 Mercurial has the ability to add new features through the use of
207 207 extensions. Extensions may add new commands, add options to existing
208 208 commands, change the default behavior of commands, or implement hooks.
209 209
210 210 To enable the "foo" extension, either shipped with Mercurial or in the
211 211 Python search path, create an entry for it in your configuration file,
212 212 like this:
213 213
214 214 [extensions]
215 215 foo =
216 216
217 217 You may also specify the full path to an extension:
218 218
219 219 [extensions]
220 220 myfeature = ~/.hgext/myfeature.py
221 221
222 222 See 'hg help config' for more information on configuration files.
223 223
224 224 Extensions are not loaded by default for a variety of reasons: they can
225 225 increase startup overhead; they may be meant for advanced usage only; they
226 226 may provide potentially dangerous abilities (such as letting you destroy
227 227 or modify history); they might not be ready for prime time; or they may
228 228 alter some usual behaviors of stock Mercurial. It is thus up to the user
229 229 to activate extensions as needed.
230 230
231 231 To explicitly disable an extension enabled in a configuration file of
232 232 broader scope, prepend its path with !:
233 233
234 234 [extensions]
235 235 # disabling extension bar residing in /path/to/extension/bar.py
236 236 bar = !/path/to/extension/bar.py
237 237 # ditto, but no path was supplied for extension baz
238 238 baz = !
239 239
240 240 enabled extensions:
241 241
242 242 children command to display child changesets (DEPRECATED)
243 243 rebase command to move sets of revisions to a different ancestor
244 244
245 245 disabled extensions:
246 246
247 247 acl hooks for controlling repository access
248 248 blackbox log repository events to a blackbox for debugging
249 249 bugzilla hooks for integrating with the Bugzilla bug tracker
250 250 censor erase file content at a given revision
251 251 churn command to display statistics about repository history
252 252 clonebundles advertise pre-generated bundles to seed clones
253 253 color colorize output from some commands
254 254 convert import revisions from foreign VCS repositories into
255 255 Mercurial
256 256 eol automatically manage newlines in repository files
257 257 extdiff command to allow external programs to compare revisions
258 258 factotum http authentication with factotum
259 259 gpg commands to sign and verify changesets
260 260 hgk browse the repository in a graphical way
261 261 highlight syntax highlighting for hgweb (requires Pygments)
262 262 histedit interactive history editing
263 263 keyword expand keywords in tracked files
264 264 largefiles track large binary files
265 265 mq manage a stack of patches
266 266 notify hooks for sending email push notifications
267 267 patchbomb command to send changesets as (a series of) patch emails
268 268 purge command to delete untracked files from the working
269 269 directory
270 270 relink recreates hardlinks between repository clones
271 271 schemes extend schemes with shortcuts to repository swarms
272 272 share share a common history between several working directories
273 273 shelve save and restore changes to the working directory
274 274 strip strip changesets and their descendants from history
275 275 transplant command to transplant changesets from another branch
276 276 win32mbcs allow the use of MBCS paths with problematic encodings
277 277 zeroconf discover and advertise repositories on the local network
278 278
279 279 Verify that extension keywords appear in help templates
280 280
281 281 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
282 282
283 283 Test short command list with verbose option
284 284
285 285 $ hg -v help shortlist
286 286 Mercurial Distributed SCM
287 287
288 288 basic commands:
289 289
290 290 add add the specified files on the next commit
291 291 annotate, blame
292 292 show changeset information by line for each file
293 293 clone make a copy of an existing repository
294 294 commit, ci commit the specified files or all outstanding changes
295 295 diff diff repository (or selected files)
296 296 export dump the header and diffs for one or more changesets
297 297 forget forget the specified files on the next commit
298 298 init create a new repository in the given directory
299 299 log, history show revision history of entire repository or files
300 300 merge merge another revision into working directory
301 301 pull pull changes from the specified source
302 302 push push changes to the specified destination
303 303 remove, rm remove the specified files on the next commit
304 304 serve start stand-alone webserver
305 305 status, st show changed files in the working directory
306 306 summary, sum summarize working directory state
307 307 update, up, checkout, co
308 308 update working directory (or switch revisions)
309 309
310 310 global options ([+] can be repeated):
311 311
312 312 -R --repository REPO repository root directory or name of overlay bundle
313 313 file
314 314 --cwd DIR change working directory
315 315 -y --noninteractive do not prompt, automatically pick the first choice for
316 316 all prompts
317 317 -q --quiet suppress output
318 318 -v --verbose enable additional output
319 --color TYPE when to colorize (boolean, always, auto, never, or
320 debug) (EXPERIMENTAL) (default: never)
319 321 --config CONFIG [+] set/override config option (use 'section.name=value')
320 322 --debug enable debugging output
321 323 --debugger start debugger
322 324 --encoding ENCODE set the charset encoding (default: ascii)
323 325 --encodingmode MODE set the charset encoding mode (default: strict)
324 326 --traceback always print a traceback on exception
325 327 --time time how long the command takes
326 328 --profile print command execution profile
327 329 --version output version information and exit
328 330 -h --help display help and exit
329 331 --hidden consider hidden changesets
330 332 --pager TYPE when to paginate (boolean, always, auto, or never)
331 333 (default: auto)
332 334
333 335 (use 'hg help' for the full list of commands)
334 336
335 337 $ hg add -h
336 338 hg add [OPTION]... [FILE]...
337 339
338 340 add the specified files on the next commit
339 341
340 342 Schedule files to be version controlled and added to the repository.
341 343
342 344 The files will be added to the repository at the next commit. To undo an
343 345 add before that, see 'hg forget'.
344 346
345 347 If no names are given, add all files to the repository (except files
346 348 matching ".hgignore").
347 349
348 350 Returns 0 if all files are successfully added.
349 351
350 352 options ([+] can be repeated):
351 353
352 354 -I --include PATTERN [+] include names matching the given patterns
353 355 -X --exclude PATTERN [+] exclude names matching the given patterns
354 356 -S --subrepos recurse into subrepositories
355 357 -n --dry-run do not perform actions, just print output
356 358
357 359 (some details hidden, use --verbose to show complete help)
358 360
359 361 Verbose help for add
360 362
361 363 $ hg add -hv
362 364 hg add [OPTION]... [FILE]...
363 365
364 366 add the specified files on the next commit
365 367
366 368 Schedule files to be version controlled and added to the repository.
367 369
368 370 The files will be added to the repository at the next commit. To undo an
369 371 add before that, see 'hg forget'.
370 372
371 373 If no names are given, add all files to the repository (except files
372 374 matching ".hgignore").
373 375
374 376 Examples:
375 377
376 378 - New (unknown) files are added automatically by 'hg add':
377 379
378 380 $ ls
379 381 foo.c
380 382 $ hg status
381 383 ? foo.c
382 384 $ hg add
383 385 adding foo.c
384 386 $ hg status
385 387 A foo.c
386 388
387 389 - Specific files to be added can be specified:
388 390
389 391 $ ls
390 392 bar.c foo.c
391 393 $ hg status
392 394 ? bar.c
393 395 ? foo.c
394 396 $ hg add bar.c
395 397 $ hg status
396 398 A bar.c
397 399 ? foo.c
398 400
399 401 Returns 0 if all files are successfully added.
400 402
401 403 options ([+] can be repeated):
402 404
403 405 -I --include PATTERN [+] include names matching the given patterns
404 406 -X --exclude PATTERN [+] exclude names matching the given patterns
405 407 -S --subrepos recurse into subrepositories
406 408 -n --dry-run do not perform actions, just print output
407 409
408 410 global options ([+] can be repeated):
409 411
410 412 -R --repository REPO repository root directory or name of overlay bundle
411 413 file
412 414 --cwd DIR change working directory
413 415 -y --noninteractive do not prompt, automatically pick the first choice for
414 416 all prompts
415 417 -q --quiet suppress output
416 418 -v --verbose enable additional output
419 --color TYPE when to colorize (boolean, always, auto, never, or
420 debug) (EXPERIMENTAL) (default: never)
417 421 --config CONFIG [+] set/override config option (use 'section.name=value')
418 422 --debug enable debugging output
419 423 --debugger start debugger
420 424 --encoding ENCODE set the charset encoding (default: ascii)
421 425 --encodingmode MODE set the charset encoding mode (default: strict)
422 426 --traceback always print a traceback on exception
423 427 --time time how long the command takes
424 428 --profile print command execution profile
425 429 --version output version information and exit
426 430 -h --help display help and exit
427 431 --hidden consider hidden changesets
428 432 --pager TYPE when to paginate (boolean, always, auto, or never)
429 433 (default: auto)
430 434
431 435 Test the textwidth config option
432 436
433 437 $ hg root -h --config ui.textwidth=50
434 438 hg root
435 439
436 440 print the root (top) of the current working
437 441 directory
438 442
439 443 Print the root directory of the current
440 444 repository.
441 445
442 446 Returns 0 on success.
443 447
444 448 (some details hidden, use --verbose to show
445 449 complete help)
446 450
447 451 Test help option with version option
448 452
449 453 $ hg add -h --version
450 454 Mercurial Distributed SCM (version *) (glob)
451 455 (see https://mercurial-scm.org for more information)
452 456
453 457 Copyright (C) 2005-* Matt Mackall and others (glob)
454 458 This is free software; see the source for copying conditions. There is NO
455 459 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
456 460
457 461 $ hg add --skjdfks
458 462 hg add: option --skjdfks not recognized
459 463 hg add [OPTION]... [FILE]...
460 464
461 465 add the specified files on the next commit
462 466
463 467 options ([+] can be repeated):
464 468
465 469 -I --include PATTERN [+] include names matching the given patterns
466 470 -X --exclude PATTERN [+] exclude names matching the given patterns
467 471 -S --subrepos recurse into subrepositories
468 472 -n --dry-run do not perform actions, just print output
469 473
470 474 (use 'hg add -h' to show more help)
471 475 [255]
472 476
473 477 Test ambiguous command help
474 478
475 479 $ hg help ad
476 480 list of commands:
477 481
478 482 add add the specified files on the next commit
479 483 addremove add all new files, delete all missing files
480 484
481 485 (use 'hg help -v ad' to show built-in aliases and global options)
482 486
483 487 Test command without options
484 488
485 489 $ hg help verify
486 490 hg verify
487 491
488 492 verify the integrity of the repository
489 493
490 494 Verify the integrity of the current repository.
491 495
492 496 This will perform an extensive check of the repository's integrity,
493 497 validating the hashes and checksums of each entry in the changelog,
494 498 manifest, and tracked files, as well as the integrity of their crosslinks
495 499 and indices.
496 500
497 501 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
498 502 information about recovery from corruption of the repository.
499 503
500 504 Returns 0 on success, 1 if errors are encountered.
501 505
502 506 (some details hidden, use --verbose to show complete help)
503 507
504 508 $ hg help diff
505 509 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
506 510
507 511 diff repository (or selected files)
508 512
509 513 Show differences between revisions for the specified files.
510 514
511 515 Differences between files are shown using the unified diff format.
512 516
513 517 Note:
514 518 'hg diff' may generate unexpected results for merges, as it will
515 519 default to comparing against the working directory's first parent
516 520 changeset if no revisions are specified.
517 521
518 522 When two revision arguments are given, then changes are shown between
519 523 those revisions. If only one revision is specified then that revision is
520 524 compared to the working directory, and, when no revisions are specified,
521 525 the working directory files are compared to its first parent.
522 526
523 527 Alternatively you can specify -c/--change with a revision to see the
524 528 changes in that changeset relative to its first parent.
525 529
526 530 Without the -a/--text option, diff will avoid generating diffs of files it
527 531 detects as binary. With -a, diff will generate a diff anyway, probably
528 532 with undesirable results.
529 533
530 534 Use the -g/--git option to generate diffs in the git extended diff format.
531 535 For more information, read 'hg help diffs'.
532 536
533 537 Returns 0 on success.
534 538
535 539 options ([+] can be repeated):
536 540
537 541 -r --rev REV [+] revision
538 542 -c --change REV change made by revision
539 543 -a --text treat all files as text
540 544 -g --git use git extended diff format
541 545 --nodates omit dates from diff headers
542 546 --noprefix omit a/ and b/ prefixes from filenames
543 547 -p --show-function show which function each change is in
544 548 --reverse produce a diff that undoes the changes
545 549 -w --ignore-all-space ignore white space when comparing lines
546 550 -b --ignore-space-change ignore changes in the amount of white space
547 551 -B --ignore-blank-lines ignore changes whose lines are all blank
548 552 -U --unified NUM number of lines of context to show
549 553 --stat output diffstat-style summary of changes
550 554 --root DIR produce diffs relative to subdirectory
551 555 -I --include PATTERN [+] include names matching the given patterns
552 556 -X --exclude PATTERN [+] exclude names matching the given patterns
553 557 -S --subrepos recurse into subrepositories
554 558
555 559 (some details hidden, use --verbose to show complete help)
556 560
557 561 $ hg help status
558 562 hg status [OPTION]... [FILE]...
559 563
560 564 aliases: st
561 565
562 566 show changed files in the working directory
563 567
564 568 Show status of files in the repository. If names are given, only files
565 569 that match are shown. Files that are clean or ignored or the source of a
566 570 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
567 571 -C/--copies or -A/--all are given. Unless options described with "show
568 572 only ..." are given, the options -mardu are used.
569 573
570 574 Option -q/--quiet hides untracked (unknown and ignored) files unless
571 575 explicitly requested with -u/--unknown or -i/--ignored.
572 576
573 577 Note:
574 578 'hg status' may appear to disagree with diff if permissions have
575 579 changed or a merge has occurred. The standard diff format does not
576 580 report permission changes and diff only reports changes relative to one
577 581 merge parent.
578 582
579 583 If one revision is given, it is used as the base revision. If two
580 584 revisions are given, the differences between them are shown. The --change
581 585 option can also be used as a shortcut to list the changed files of a
582 586 revision from its first parent.
583 587
584 588 The codes used to show the status of files are:
585 589
586 590 M = modified
587 591 A = added
588 592 R = removed
589 593 C = clean
590 594 ! = missing (deleted by non-hg command, but still tracked)
591 595 ? = not tracked
592 596 I = ignored
593 597 = origin of the previous file (with --copies)
594 598
595 599 Returns 0 on success.
596 600
597 601 options ([+] can be repeated):
598 602
599 603 -A --all show status of all files
600 604 -m --modified show only modified files
601 605 -a --added show only added files
602 606 -r --removed show only removed files
603 607 -d --deleted show only deleted (but tracked) files
604 608 -c --clean show only files without changes
605 609 -u --unknown show only unknown (not tracked) files
606 610 -i --ignored show only ignored files
607 611 -n --no-status hide status prefix
608 612 -C --copies show source of copied files
609 613 -0 --print0 end filenames with NUL, for use with xargs
610 614 --rev REV [+] show difference from revision
611 615 --change REV list the changed files of a revision
612 616 -I --include PATTERN [+] include names matching the given patterns
613 617 -X --exclude PATTERN [+] exclude names matching the given patterns
614 618 -S --subrepos recurse into subrepositories
615 619
616 620 (some details hidden, use --verbose to show complete help)
617 621
618 622 $ hg -q help status
619 623 hg status [OPTION]... [FILE]...
620 624
621 625 show changed files in the working directory
622 626
623 627 $ hg help foo
624 628 abort: no such help topic: foo
625 629 (try 'hg help --keyword foo')
626 630 [255]
627 631
628 632 $ hg skjdfks
629 633 hg: unknown command 'skjdfks'
630 634 Mercurial Distributed SCM
631 635
632 636 basic commands:
633 637
634 638 add add the specified files on the next commit
635 639 annotate show changeset information by line for each file
636 640 clone make a copy of an existing repository
637 641 commit commit the specified files or all outstanding changes
638 642 diff diff repository (or selected files)
639 643 export dump the header and diffs for one or more changesets
640 644 forget forget the specified files on the next commit
641 645 init create a new repository in the given directory
642 646 log show revision history of entire repository or files
643 647 merge merge another revision into working directory
644 648 pull pull changes from the specified source
645 649 push push changes to the specified destination
646 650 remove remove the specified files on the next commit
647 651 serve start stand-alone webserver
648 652 status show changed files in the working directory
649 653 summary summarize working directory state
650 654 update update working directory (or switch revisions)
651 655
652 656 (use 'hg help' for the full list of commands or 'hg -v' for details)
653 657 [255]
654 658
655 659
656 660 Make sure that we don't run afoul of the help system thinking that
657 661 this is a section and erroring out weirdly.
658 662
659 663 $ hg .log
660 664 hg: unknown command '.log'
661 665 (did you mean log?)
662 666 [255]
663 667
664 668 $ hg log.
665 669 hg: unknown command 'log.'
666 670 (did you mean log?)
667 671 [255]
668 672 $ hg pu.lh
669 673 hg: unknown command 'pu.lh'
670 674 (did you mean one of pull, push?)
671 675 [255]
672 676
673 677 $ cat > helpext.py <<EOF
674 678 > import os
675 679 > from mercurial import cmdutil, commands
676 680 >
677 681 > cmdtable = {}
678 682 > command = cmdutil.command(cmdtable)
679 683 >
680 684 > @command('nohelp',
681 685 > [('', 'longdesc', 3, 'x'*90),
682 686 > ('n', '', None, 'normal desc'),
683 687 > ('', 'newline', '', 'line1\nline2')],
684 688 > 'hg nohelp',
685 689 > norepo=True)
686 690 > @command('debugoptADV', [('', 'aopt', None, 'option is (ADVANCED)')])
687 691 > @command('debugoptDEP', [('', 'dopt', None, 'option is (DEPRECATED)')])
688 692 > @command('debugoptEXP', [('', 'eopt', None, 'option is (EXPERIMENTAL)')])
689 693 > def nohelp(ui, *args, **kwargs):
690 694 > pass
691 695 >
692 696 > def uisetup(ui):
693 697 > ui.setconfig('alias', 'shellalias', '!echo hi', 'helpext')
694 698 > ui.setconfig('alias', 'hgalias', 'summary', 'helpext')
695 699 >
696 700 > EOF
697 701 $ echo '[extensions]' >> $HGRCPATH
698 702 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
699 703
700 704 Test for aliases
701 705
702 706 $ hg help hgalias
703 707 hg hgalias [--remote]
704 708
705 709 alias for: hg summary
706 710
707 711 summarize working directory state
708 712
709 713 This generates a brief summary of the working directory state, including
710 714 parents, branch, commit status, phase and available updates.
711 715
712 716 With the --remote option, this will check the default paths for incoming
713 717 and outgoing changes. This can be time-consuming.
714 718
715 719 Returns 0 on success.
716 720
717 721 defined by: helpext
718 722
719 723 options:
720 724
721 725 --remote check for push and pull
722 726
723 727 (some details hidden, use --verbose to show complete help)
724 728
725 729 $ hg help shellalias
726 730 hg shellalias
727 731
728 732 shell alias for:
729 733
730 734 echo hi
731 735
732 736 defined by: helpext
733 737
734 738 (some details hidden, use --verbose to show complete help)
735 739
736 740 Test command with no help text
737 741
738 742 $ hg help nohelp
739 743 hg nohelp
740 744
741 745 (no help text available)
742 746
743 747 options:
744 748
745 749 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
746 750 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
747 751 -n -- normal desc
748 752 --newline VALUE line1 line2
749 753
750 754 (some details hidden, use --verbose to show complete help)
751 755
752 756 $ hg help -k nohelp
753 757 Commands:
754 758
755 759 nohelp hg nohelp
756 760
757 761 Extension Commands:
758 762
759 763 nohelp (no help text available)
760 764
761 765 Test that default list of commands omits extension commands
762 766
763 767 $ hg help
764 768 Mercurial Distributed SCM
765 769
766 770 list of commands:
767 771
768 772 add add the specified files on the next commit
769 773 addremove add all new files, delete all missing files
770 774 annotate show changeset information by line for each file
771 775 archive create an unversioned archive of a repository revision
772 776 backout reverse effect of earlier changeset
773 777 bisect subdivision search of changesets
774 778 bookmarks create a new bookmark or list existing bookmarks
775 779 branch set or show the current branch name
776 780 branches list repository named branches
777 781 bundle create a changegroup file
778 782 cat output the current or given revision of files
779 783 clone make a copy of an existing repository
780 784 commit commit the specified files or all outstanding changes
781 785 config show combined config settings from all hgrc files
782 786 copy mark files as copied for the next commit
783 787 diff diff repository (or selected files)
784 788 export dump the header and diffs for one or more changesets
785 789 files list tracked files
786 790 forget forget the specified files on the next commit
787 791 graft copy changes from other branches onto the current branch
788 792 grep search revision history for a pattern in specified files
789 793 heads show branch heads
790 794 help show help for a given topic or a help overview
791 795 identify identify the working directory or specified revision
792 796 import import an ordered set of patches
793 797 incoming show new changesets found in source
794 798 init create a new repository in the given directory
795 799 log show revision history of entire repository or files
796 800 manifest output the current or given revision of the project manifest
797 801 merge merge another revision into working directory
798 802 outgoing show changesets not found in the destination
799 803 paths show aliases for remote repositories
800 804 phase set or show the current phase name
801 805 pull pull changes from the specified source
802 806 push push changes to the specified destination
803 807 recover roll back an interrupted transaction
804 808 remove remove the specified files on the next commit
805 809 rename rename files; equivalent of copy + remove
806 810 resolve redo merges or set/view the merge status of files
807 811 revert restore files to their checkout state
808 812 root print the root (top) of the current working directory
809 813 serve start stand-alone webserver
810 814 status show changed files in the working directory
811 815 summary summarize working directory state
812 816 tag add one or more tags for the current or given revision
813 817 tags list repository tags
814 818 unbundle apply one or more changegroup files
815 819 update update working directory (or switch revisions)
816 820 verify verify the integrity of the repository
817 821 version output version and copyright information
818 822
819 823 enabled extensions:
820 824
821 825 helpext (no help text available)
822 826
823 827 additional help topics:
824 828
825 829 config Configuration Files
826 830 dates Date Formats
827 831 diffs Diff Formats
828 832 environment Environment Variables
829 833 extensions Using Additional Features
830 834 filesets Specifying File Sets
831 835 glossary Glossary
832 836 hgignore Syntax for Mercurial Ignore Files
833 837 hgweb Configuring hgweb
834 838 internals Technical implementation topics
835 839 merge-tools Merge Tools
836 840 pager Pager Support
837 841 patterns File Name Patterns
838 842 phases Working with Phases
839 843 revisions Specifying Revisions
840 844 scripting Using Mercurial from scripts and automation
841 845 subrepos Subrepositories
842 846 templating Template Usage
843 847 urls URL Paths
844 848
845 849 (use 'hg help -v' to show built-in aliases and global options)
846 850
847 851
848 852 Test list of internal help commands
849 853
850 854 $ hg help debug
851 855 debug commands (internal and unsupported):
852 856
853 857 debugancestor
854 858 find the ancestor revision of two revisions in a given index
855 859 debugapplystreamclonebundle
856 860 apply a stream clone bundle file
857 861 debugbuilddag
858 862 builds a repo with a given DAG from scratch in the current
859 863 empty repo
860 864 debugbundle lists the contents of a bundle
861 865 debugcheckstate
862 866 validate the correctness of the current dirstate
863 867 debugcommands
864 868 list all available commands and options
865 869 debugcomplete
866 870 returns the completion list associated with the given command
867 871 debugcreatestreamclonebundle
868 872 create a stream clone bundle file
869 873 debugdag format the changelog or an index DAG as a concise textual
870 874 description
871 875 debugdata dump the contents of a data file revision
872 876 debugdate parse and display a date
873 877 debugdeltachain
874 878 dump information about delta chains in a revlog
875 879 debugdirstate
876 880 show the contents of the current dirstate
877 881 debugdiscovery
878 882 runs the changeset discovery protocol in isolation
879 883 debugextensions
880 884 show information about active extensions
881 885 debugfileset parse and apply a fileset specification
882 886 debugfsinfo show information detected about current filesystem
883 887 debuggetbundle
884 888 retrieves a bundle from a repo
885 889 debugignore display the combined ignore pattern and information about
886 890 ignored files
887 891 debugindex dump the contents of an index file
888 892 debugindexdot
889 893 dump an index DAG as a graphviz dot file
890 894 debuginstall test Mercurial installation
891 895 debugknown test whether node ids are known to a repo
892 896 debuglocks show or modify state of locks
893 897 debugmergestate
894 898 print merge state
895 899 debugnamecomplete
896 900 complete "names" - tags, open branch names, bookmark names
897 901 debugobsolete
898 902 create arbitrary obsolete marker
899 903 debugoptADV (no help text available)
900 904 debugoptDEP (no help text available)
901 905 debugoptEXP (no help text available)
902 906 debugpathcomplete
903 907 complete part or all of a tracked path
904 908 debugpushkey access the pushkey key/value protocol
905 909 debugpvec (no help text available)
906 910 debugrebuilddirstate
907 911 rebuild the dirstate as it would look like for the given
908 912 revision
909 913 debugrebuildfncache
910 914 rebuild the fncache file
911 915 debugrename dump rename information
912 916 debugrevlog show data and statistics about a revlog
913 917 debugrevspec parse and apply a revision specification
914 918 debugsetparents
915 919 manually set the parents of the current working directory
916 920 debugsub (no help text available)
917 921 debugsuccessorssets
918 922 show set of successors for revision
919 923 debugtemplate
920 924 parse and apply a template
921 925 debugupgraderepo
922 926 upgrade a repository to use different features
923 927 debugwalk show how files match on given patterns
924 928 debugwireargs
925 929 (no help text available)
926 930
927 931 (use 'hg help -v debug' to show built-in aliases and global options)
928 932
929 933 internals topic renders index of available sub-topics
930 934
931 935 $ hg help internals
932 936 Technical implementation topics
933 937 """""""""""""""""""""""""""""""
934 938
935 939 bundles Bundles
936 940 changegroups Changegroups
937 941 requirements Repository Requirements
938 942 revlogs Revision Logs
939 943 wireprotocol Wire Protocol
940 944
941 945 sub-topics can be accessed
942 946
943 947 $ hg help internals.changegroups
944 948 Changegroups
945 949 """"""""""""
946 950
947 951 Changegroups are representations of repository revlog data, specifically
948 952 the changelog, manifest, and filelogs.
949 953
950 954 There are 3 versions of changegroups: "1", "2", and "3". From a high-
951 955 level, versions "1" and "2" are almost exactly the same, with the only
952 956 difference being a header on entries in the changeset segment. Version "3"
953 957 adds support for exchanging treemanifests and includes revlog flags in the
954 958 delta header.
955 959
956 960 Changegroups consists of 3 logical segments:
957 961
958 962 +---------------------------------+
959 963 | | | |
960 964 | changeset | manifest | filelogs |
961 965 | | | |
962 966 +---------------------------------+
963 967
964 968 The principle building block of each segment is a *chunk*. A *chunk* is a
965 969 framed piece of data:
966 970
967 971 +---------------------------------------+
968 972 | | |
969 973 | length | data |
970 974 | (32 bits) | <length> bytes |
971 975 | | |
972 976 +---------------------------------------+
973 977
974 978 Each chunk starts with a 32-bit big-endian signed integer indicating the
975 979 length of the raw data that follows.
976 980
977 981 There is a special case chunk that has 0 length ("0x00000000"). We call
978 982 this an *empty chunk*.
979 983
980 984 Delta Groups
981 985 ============
982 986
983 987 A *delta group* expresses the content of a revlog as a series of deltas,
984 988 or patches against previous revisions.
985 989
986 990 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
987 991 to signal the end of the delta group:
988 992
989 993 +------------------------------------------------------------------------+
990 994 | | | | | |
991 995 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
992 996 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
993 997 | | | | | |
994 998 +------------------------------------------------------------+-----------+
995 999
996 1000 Each *chunk*'s data consists of the following:
997 1001
998 1002 +-----------------------------------------+
999 1003 | | | |
1000 1004 | delta header | mdiff header | delta |
1001 1005 | (various) | (12 bytes) | (various) |
1002 1006 | | | |
1003 1007 +-----------------------------------------+
1004 1008
1005 1009 The *length* field is the byte length of the remaining 3 logical pieces of
1006 1010 data. The *delta* is a diff from an existing entry in the changelog.
1007 1011
1008 1012 The *delta header* is different between versions "1", "2", and "3" of the
1009 1013 changegroup format.
1010 1014
1011 1015 Version 1:
1012 1016
1013 1017 +------------------------------------------------------+
1014 1018 | | | | |
1015 1019 | node | p1 node | p2 node | link node |
1016 1020 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1017 1021 | | | | |
1018 1022 +------------------------------------------------------+
1019 1023
1020 1024 Version 2:
1021 1025
1022 1026 +------------------------------------------------------------------+
1023 1027 | | | | | |
1024 1028 | node | p1 node | p2 node | base node | link node |
1025 1029 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1026 1030 | | | | | |
1027 1031 +------------------------------------------------------------------+
1028 1032
1029 1033 Version 3:
1030 1034
1031 1035 +------------------------------------------------------------------------------+
1032 1036 | | | | | | |
1033 1037 | node | p1 node | p2 node | base node | link node | flags |
1034 1038 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1035 1039 | | | | | | |
1036 1040 +------------------------------------------------------------------------------+
1037 1041
1038 1042 The *mdiff header* consists of 3 32-bit big-endian signed integers
1039 1043 describing offsets at which to apply the following delta content:
1040 1044
1041 1045 +-------------------------------------+
1042 1046 | | | |
1043 1047 | offset | old length | new length |
1044 1048 | (32 bits) | (32 bits) | (32 bits) |
1045 1049 | | | |
1046 1050 +-------------------------------------+
1047 1051
1048 1052 In version 1, the delta is always applied against the previous node from
1049 1053 the changegroup or the first parent if this is the first entry in the
1050 1054 changegroup.
1051 1055
1052 1056 In version 2, the delta base node is encoded in the entry in the
1053 1057 changegroup. This allows the delta to be expressed against any parent,
1054 1058 which can result in smaller deltas and more efficient encoding of data.
1055 1059
1056 1060 Changeset Segment
1057 1061 =================
1058 1062
1059 1063 The *changeset segment* consists of a single *delta group* holding
1060 1064 changelog data. It is followed by an *empty chunk* to denote the boundary
1061 1065 to the *manifests segment*.
1062 1066
1063 1067 Manifest Segment
1064 1068 ================
1065 1069
1066 1070 The *manifest segment* consists of a single *delta group* holding manifest
1067 1071 data. It is followed by an *empty chunk* to denote the boundary to the
1068 1072 *filelogs segment*.
1069 1073
1070 1074 Filelogs Segment
1071 1075 ================
1072 1076
1073 1077 The *filelogs* segment consists of multiple sub-segments, each
1074 1078 corresponding to an individual file whose data is being described:
1075 1079
1076 1080 +--------------------------------------+
1077 1081 | | | | |
1078 1082 | filelog0 | filelog1 | filelog2 | ... |
1079 1083 | | | | |
1080 1084 +--------------------------------------+
1081 1085
1082 1086 In version "3" of the changegroup format, filelogs may include directory
1083 1087 logs when treemanifests are in use. directory logs are identified by
1084 1088 having a trailing '/' on their filename (see below).
1085 1089
1086 1090 The final filelog sub-segment is followed by an *empty chunk* to denote
1087 1091 the end of the segment and the overall changegroup.
1088 1092
1089 1093 Each filelog sub-segment consists of the following:
1090 1094
1091 1095 +------------------------------------------+
1092 1096 | | | |
1093 1097 | filename size | filename | delta group |
1094 1098 | (32 bits) | (various) | (various) |
1095 1099 | | | |
1096 1100 +------------------------------------------+
1097 1101
1098 1102 That is, a *chunk* consisting of the filename (not terminated or padded)
1099 1103 followed by N chunks constituting the *delta group* for this file.
1100 1104
1101 1105 Test list of commands with command with no help text
1102 1106
1103 1107 $ hg help helpext
1104 1108 helpext extension - no help text available
1105 1109
1106 1110 list of commands:
1107 1111
1108 1112 nohelp (no help text available)
1109 1113
1110 1114 (use 'hg help -v helpext' to show built-in aliases and global options)
1111 1115
1112 1116
1113 1117 test advanced, deprecated and experimental options are hidden in command help
1114 1118 $ hg help debugoptADV
1115 1119 hg debugoptADV
1116 1120
1117 1121 (no help text available)
1118 1122
1119 1123 options:
1120 1124
1121 1125 (some details hidden, use --verbose to show complete help)
1122 1126 $ hg help debugoptDEP
1123 1127 hg debugoptDEP
1124 1128
1125 1129 (no help text available)
1126 1130
1127 1131 options:
1128 1132
1129 1133 (some details hidden, use --verbose to show complete help)
1130 1134
1131 1135 $ hg help debugoptEXP
1132 1136 hg debugoptEXP
1133 1137
1134 1138 (no help text available)
1135 1139
1136 1140 options:
1137 1141
1138 1142 (some details hidden, use --verbose to show complete help)
1139 1143
1140 1144 test advanced, deprecated and experimental options are shown with -v
1141 1145 $ hg help -v debugoptADV | grep aopt
1142 1146 --aopt option is (ADVANCED)
1143 1147 $ hg help -v debugoptDEP | grep dopt
1144 1148 --dopt option is (DEPRECATED)
1145 1149 $ hg help -v debugoptEXP | grep eopt
1146 1150 --eopt option is (EXPERIMENTAL)
1147 1151
1148 1152 #if gettext
1149 1153 test deprecated option is hidden with translation with untranslated description
1150 1154 (use many globy for not failing on changed transaction)
1151 1155 $ LANGUAGE=sv hg help debugoptDEP
1152 1156 hg debugoptDEP
1153 1157
1154 1158 (*) (glob)
1155 1159
1156 1160 options:
1157 1161
1158 1162 (some details hidden, use --verbose to show complete help)
1159 1163 #endif
1160 1164
1161 1165 Test commands that collide with topics (issue4240)
1162 1166
1163 1167 $ hg config -hq
1164 1168 hg config [-u] [NAME]...
1165 1169
1166 1170 show combined config settings from all hgrc files
1167 1171 $ hg showconfig -hq
1168 1172 hg config [-u] [NAME]...
1169 1173
1170 1174 show combined config settings from all hgrc files
1171 1175
1172 1176 Test a help topic
1173 1177
1174 1178 $ hg help dates
1175 1179 Date Formats
1176 1180 """"""""""""
1177 1181
1178 1182 Some commands allow the user to specify a date, e.g.:
1179 1183
1180 1184 - backout, commit, import, tag: Specify the commit date.
1181 1185 - log, revert, update: Select revision(s) by date.
1182 1186
1183 1187 Many date formats are valid. Here are some examples:
1184 1188
1185 1189 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1186 1190 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1187 1191 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1188 1192 - "Dec 6" (midnight)
1189 1193 - "13:18" (today assumed)
1190 1194 - "3:39" (3:39AM assumed)
1191 1195 - "3:39pm" (15:39)
1192 1196 - "2006-12-06 13:18:29" (ISO 8601 format)
1193 1197 - "2006-12-6 13:18"
1194 1198 - "2006-12-6"
1195 1199 - "12-6"
1196 1200 - "12/6"
1197 1201 - "12/6/6" (Dec 6 2006)
1198 1202 - "today" (midnight)
1199 1203 - "yesterday" (midnight)
1200 1204 - "now" - right now
1201 1205
1202 1206 Lastly, there is Mercurial's internal format:
1203 1207
1204 1208 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1205 1209
1206 1210 This is the internal representation format for dates. The first number is
1207 1211 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1208 1212 is the offset of the local timezone, in seconds west of UTC (negative if
1209 1213 the timezone is east of UTC).
1210 1214
1211 1215 The log command also accepts date ranges:
1212 1216
1213 1217 - "<DATE" - at or before a given date/time
1214 1218 - ">DATE" - on or after a given date/time
1215 1219 - "DATE to DATE" - a date range, inclusive
1216 1220 - "-DAYS" - within a given number of days of today
1217 1221
1218 1222 Test repeated config section name
1219 1223
1220 1224 $ hg help config.host
1221 1225 "http_proxy.host"
1222 1226 Host name and (optional) port of the proxy server, for example
1223 1227 "myproxy:8000".
1224 1228
1225 1229 "smtp.host"
1226 1230 Host name of mail server, e.g. "mail.example.com".
1227 1231
1228 1232 Unrelated trailing paragraphs shouldn't be included
1229 1233
1230 1234 $ hg help config.extramsg | grep '^$'
1231 1235
1232 1236
1233 1237 Test capitalized section name
1234 1238
1235 1239 $ hg help scripting.HGPLAIN > /dev/null
1236 1240
1237 1241 Help subsection:
1238 1242
1239 1243 $ hg help config.charsets |grep "Email example:" > /dev/null
1240 1244 [1]
1241 1245
1242 1246 Show nested definitions
1243 1247 ("profiling.type"[break]"ls"[break]"stat"[break])
1244 1248
1245 1249 $ hg help config.type | egrep '^$'|wc -l
1246 1250 \s*3 (re)
1247 1251
1248 1252 Separate sections from subsections
1249 1253
1250 1254 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1251 1255 "format"
1252 1256 --------
1253 1257
1254 1258 "usegeneraldelta"
1255 1259
1256 1260 "dotencode"
1257 1261
1258 1262 "usefncache"
1259 1263
1260 1264 "usestore"
1261 1265
1262 1266 "profiling"
1263 1267 -----------
1264 1268
1265 1269 "format"
1266 1270
1267 1271 "progress"
1268 1272 ----------
1269 1273
1270 1274 "format"
1271 1275
1272 1276
1273 1277 Last item in help config.*:
1274 1278
1275 1279 $ hg help config.`hg help config|grep '^ "'| \
1276 1280 > tail -1|sed 's![ "]*!!g'`| \
1277 1281 > grep 'hg help -c config' > /dev/null
1278 1282 [1]
1279 1283
1280 1284 note to use help -c for general hg help config:
1281 1285
1282 1286 $ hg help config |grep 'hg help -c config' > /dev/null
1283 1287
1284 1288 Test templating help
1285 1289
1286 1290 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1287 1291 desc String. The text of the changeset description.
1288 1292 diffstat String. Statistics of changes with the following format:
1289 1293 firstline Any text. Returns the first line of text.
1290 1294 nonempty Any text. Returns '(none)' if the string is empty.
1291 1295
1292 1296 Test deprecated items
1293 1297
1294 1298 $ hg help -v templating | grep currentbookmark
1295 1299 currentbookmark
1296 1300 $ hg help templating | (grep currentbookmark || true)
1297 1301
1298 1302 Test help hooks
1299 1303
1300 1304 $ cat > helphook1.py <<EOF
1301 1305 > from mercurial import help
1302 1306 >
1303 1307 > def rewrite(ui, topic, doc):
1304 1308 > return doc + '\nhelphook1\n'
1305 1309 >
1306 1310 > def extsetup(ui):
1307 1311 > help.addtopichook('revisions', rewrite)
1308 1312 > EOF
1309 1313 $ cat > helphook2.py <<EOF
1310 1314 > from mercurial import help
1311 1315 >
1312 1316 > def rewrite(ui, topic, doc):
1313 1317 > return doc + '\nhelphook2\n'
1314 1318 >
1315 1319 > def extsetup(ui):
1316 1320 > help.addtopichook('revisions', rewrite)
1317 1321 > EOF
1318 1322 $ echo '[extensions]' >> $HGRCPATH
1319 1323 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1320 1324 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1321 1325 $ hg help revsets | grep helphook
1322 1326 helphook1
1323 1327 helphook2
1324 1328
1325 1329 help -c should only show debug --debug
1326 1330
1327 1331 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1328 1332 [1]
1329 1333
1330 1334 help -c should only show deprecated for -v
1331 1335
1332 1336 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1333 1337 [1]
1334 1338
1335 1339 Test -s / --system
1336 1340
1337 1341 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1338 1342 > wc -l | sed -e 's/ //g'
1339 1343 0
1340 1344 $ hg help config.files --system unix | grep 'USER' | \
1341 1345 > wc -l | sed -e 's/ //g'
1342 1346 0
1343 1347
1344 1348 Test -e / -c / -k combinations
1345 1349
1346 1350 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1347 1351 Commands:
1348 1352 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1349 1353 Extensions:
1350 1354 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1351 1355 Topics:
1352 1356 Commands:
1353 1357 Extensions:
1354 1358 Extension Commands:
1355 1359 $ hg help -c schemes
1356 1360 abort: no such help topic: schemes
1357 1361 (try 'hg help --keyword schemes')
1358 1362 [255]
1359 1363 $ hg help -e schemes |head -1
1360 1364 schemes extension - extend schemes with shortcuts to repository swarms
1361 1365 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1362 1366 Commands:
1363 1367 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1364 1368 Extensions:
1365 1369 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1366 1370 Extensions:
1367 1371 Commands:
1368 1372 $ hg help -c commit > /dev/null
1369 1373 $ hg help -e -c commit > /dev/null
1370 1374 $ hg help -e commit > /dev/null
1371 1375 abort: no such help topic: commit
1372 1376 (try 'hg help --keyword commit')
1373 1377 [255]
1374 1378
1375 1379 Test keyword search help
1376 1380
1377 1381 $ cat > prefixedname.py <<EOF
1378 1382 > '''matched against word "clone"
1379 1383 > '''
1380 1384 > EOF
1381 1385 $ echo '[extensions]' >> $HGRCPATH
1382 1386 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1383 1387 $ hg help -k clone
1384 1388 Topics:
1385 1389
1386 1390 config Configuration Files
1387 1391 extensions Using Additional Features
1388 1392 glossary Glossary
1389 1393 phases Working with Phases
1390 1394 subrepos Subrepositories
1391 1395 urls URL Paths
1392 1396
1393 1397 Commands:
1394 1398
1395 1399 bookmarks create a new bookmark or list existing bookmarks
1396 1400 clone make a copy of an existing repository
1397 1401 paths show aliases for remote repositories
1398 1402 update update working directory (or switch revisions)
1399 1403
1400 1404 Extensions:
1401 1405
1402 1406 clonebundles advertise pre-generated bundles to seed clones
1403 1407 prefixedname matched against word "clone"
1404 1408 relink recreates hardlinks between repository clones
1405 1409
1406 1410 Extension Commands:
1407 1411
1408 1412 qclone clone main and patch repository at same time
1409 1413
1410 1414 Test unfound topic
1411 1415
1412 1416 $ hg help nonexistingtopicthatwillneverexisteverever
1413 1417 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1414 1418 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1415 1419 [255]
1416 1420
1417 1421 Test unfound keyword
1418 1422
1419 1423 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1420 1424 abort: no matches
1421 1425 (try 'hg help' for a list of topics)
1422 1426 [255]
1423 1427
1424 1428 Test omit indicating for help
1425 1429
1426 1430 $ cat > addverboseitems.py <<EOF
1427 1431 > '''extension to test omit indicating.
1428 1432 >
1429 1433 > This paragraph is never omitted (for extension)
1430 1434 >
1431 1435 > .. container:: verbose
1432 1436 >
1433 1437 > This paragraph is omitted,
1434 1438 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1435 1439 >
1436 1440 > This paragraph is never omitted, too (for extension)
1437 1441 > '''
1438 1442 >
1439 1443 > from mercurial import help, commands
1440 1444 > testtopic = """This paragraph is never omitted (for topic).
1441 1445 >
1442 1446 > .. container:: verbose
1443 1447 >
1444 1448 > This paragraph is omitted,
1445 1449 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1446 1450 >
1447 1451 > This paragraph is never omitted, too (for topic)
1448 1452 > """
1449 1453 > def extsetup(ui):
1450 1454 > help.helptable.append((["topic-containing-verbose"],
1451 1455 > "This is the topic to test omit indicating.",
1452 1456 > lambda ui: testtopic))
1453 1457 > EOF
1454 1458 $ echo '[extensions]' >> $HGRCPATH
1455 1459 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1456 1460 $ hg help addverboseitems
1457 1461 addverboseitems extension - extension to test omit indicating.
1458 1462
1459 1463 This paragraph is never omitted (for extension)
1460 1464
1461 1465 This paragraph is never omitted, too (for extension)
1462 1466
1463 1467 (some details hidden, use --verbose to show complete help)
1464 1468
1465 1469 no commands defined
1466 1470 $ hg help -v addverboseitems
1467 1471 addverboseitems extension - extension to test omit indicating.
1468 1472
1469 1473 This paragraph is never omitted (for extension)
1470 1474
1471 1475 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1472 1476 extension)
1473 1477
1474 1478 This paragraph is never omitted, too (for extension)
1475 1479
1476 1480 no commands defined
1477 1481 $ hg help topic-containing-verbose
1478 1482 This is the topic to test omit indicating.
1479 1483 """"""""""""""""""""""""""""""""""""""""""
1480 1484
1481 1485 This paragraph is never omitted (for topic).
1482 1486
1483 1487 This paragraph is never omitted, too (for topic)
1484 1488
1485 1489 (some details hidden, use --verbose to show complete help)
1486 1490 $ hg help -v topic-containing-verbose
1487 1491 This is the topic to test omit indicating.
1488 1492 """"""""""""""""""""""""""""""""""""""""""
1489 1493
1490 1494 This paragraph is never omitted (for topic).
1491 1495
1492 1496 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1493 1497 topic)
1494 1498
1495 1499 This paragraph is never omitted, too (for topic)
1496 1500
1497 1501 Test section lookup
1498 1502
1499 1503 $ hg help revset.merge
1500 1504 "merge()"
1501 1505 Changeset is a merge changeset.
1502 1506
1503 1507 $ hg help glossary.dag
1504 1508 DAG
1505 1509 The repository of changesets of a distributed version control system
1506 1510 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1507 1511 of nodes and edges, where nodes correspond to changesets and edges
1508 1512 imply a parent -> child relation. This graph can be visualized by
1509 1513 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1510 1514 limited by the requirement for children to have at most two parents.
1511 1515
1512 1516
1513 1517 $ hg help hgrc.paths
1514 1518 "paths"
1515 1519 -------
1516 1520
1517 1521 Assigns symbolic names and behavior to repositories.
1518 1522
1519 1523 Options are symbolic names defining the URL or directory that is the
1520 1524 location of the repository. Example:
1521 1525
1522 1526 [paths]
1523 1527 my_server = https://example.com/my_repo
1524 1528 local_path = /home/me/repo
1525 1529
1526 1530 These symbolic names can be used from the command line. To pull from
1527 1531 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1528 1532 local_path'.
1529 1533
1530 1534 Options containing colons (":") denote sub-options that can influence
1531 1535 behavior for that specific path. Example:
1532 1536
1533 1537 [paths]
1534 1538 my_server = https://example.com/my_path
1535 1539 my_server:pushurl = ssh://example.com/my_path
1536 1540
1537 1541 The following sub-options can be defined:
1538 1542
1539 1543 "pushurl"
1540 1544 The URL to use for push operations. If not defined, the location
1541 1545 defined by the path's main entry is used.
1542 1546
1543 1547 "pushrev"
1544 1548 A revset defining which revisions to push by default.
1545 1549
1546 1550 When 'hg push' is executed without a "-r" argument, the revset defined
1547 1551 by this sub-option is evaluated to determine what to push.
1548 1552
1549 1553 For example, a value of "." will push the working directory's revision
1550 1554 by default.
1551 1555
1552 1556 Revsets specifying bookmarks will not result in the bookmark being
1553 1557 pushed.
1554 1558
1555 1559 The following special named paths exist:
1556 1560
1557 1561 "default"
1558 1562 The URL or directory to use when no source or remote is specified.
1559 1563
1560 1564 'hg clone' will automatically define this path to the location the
1561 1565 repository was cloned from.
1562 1566
1563 1567 "default-push"
1564 1568 (deprecated) The URL or directory for the default 'hg push' location.
1565 1569 "default:pushurl" should be used instead.
1566 1570
1567 1571 $ hg help glossary.mcguffin
1568 1572 abort: help section not found: glossary.mcguffin
1569 1573 [255]
1570 1574
1571 1575 $ hg help glossary.mc.guffin
1572 1576 abort: help section not found: glossary.mc.guffin
1573 1577 [255]
1574 1578
1575 1579 $ hg help template.files
1576 1580 files List of strings. All files modified, added, or removed by
1577 1581 this changeset.
1578 1582 files(pattern)
1579 1583 All files of the current changeset matching the pattern. See
1580 1584 'hg help patterns'.
1581 1585
1582 1586 Test section lookup by translated message
1583 1587
1584 1588 str.lower() instead of encoding.lower(str) on translated message might
1585 1589 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1586 1590 as the second or later byte of multi-byte character.
1587 1591
1588 1592 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1589 1593 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1590 1594 replacement makes message meaningless.
1591 1595
1592 1596 This tests that section lookup by translated string isn't broken by
1593 1597 such str.lower().
1594 1598
1595 1599 $ python <<EOF
1596 1600 > def escape(s):
1597 1601 > return ''.join('\u%x' % ord(uc) for uc in s.decode('cp932'))
1598 1602 > # translation of "record" in ja_JP.cp932
1599 1603 > upper = "\x8bL\x98^"
1600 1604 > # str.lower()-ed section name should be treated as different one
1601 1605 > lower = "\x8bl\x98^"
1602 1606 > with open('ambiguous.py', 'w') as fp:
1603 1607 > fp.write("""# ambiguous section names in ja_JP.cp932
1604 1608 > u'''summary of extension
1605 1609 >
1606 1610 > %s
1607 1611 > ----
1608 1612 >
1609 1613 > Upper name should show only this message
1610 1614 >
1611 1615 > %s
1612 1616 > ----
1613 1617 >
1614 1618 > Lower name should show only this message
1615 1619 >
1616 1620 > subsequent section
1617 1621 > ------------------
1618 1622 >
1619 1623 > This should be hidden at 'hg help ambiguous' with section name.
1620 1624 > '''
1621 1625 > """ % (escape(upper), escape(lower)))
1622 1626 > EOF
1623 1627
1624 1628 $ cat >> $HGRCPATH <<EOF
1625 1629 > [extensions]
1626 1630 > ambiguous = ./ambiguous.py
1627 1631 > EOF
1628 1632
1629 1633 $ python <<EOF | sh
1630 1634 > upper = "\x8bL\x98^"
1631 1635 > print "hg --encoding cp932 help -e ambiguous.%s" % upper
1632 1636 > EOF
1633 1637 \x8bL\x98^ (esc)
1634 1638 ----
1635 1639
1636 1640 Upper name should show only this message
1637 1641
1638 1642
1639 1643 $ python <<EOF | sh
1640 1644 > lower = "\x8bl\x98^"
1641 1645 > print "hg --encoding cp932 help -e ambiguous.%s" % lower
1642 1646 > EOF
1643 1647 \x8bl\x98^ (esc)
1644 1648 ----
1645 1649
1646 1650 Lower name should show only this message
1647 1651
1648 1652
1649 1653 $ cat >> $HGRCPATH <<EOF
1650 1654 > [extensions]
1651 1655 > ambiguous = !
1652 1656 > EOF
1653 1657
1654 1658 Show help content of disabled extensions
1655 1659
1656 1660 $ cat >> $HGRCPATH <<EOF
1657 1661 > [extensions]
1658 1662 > ambiguous = !./ambiguous.py
1659 1663 > EOF
1660 1664 $ hg help -e ambiguous
1661 1665 ambiguous extension - (no help text available)
1662 1666
1663 1667 (use 'hg help extensions' for information on enabling extensions)
1664 1668
1665 1669 Test dynamic list of merge tools only shows up once
1666 1670 $ hg help merge-tools
1667 1671 Merge Tools
1668 1672 """""""""""
1669 1673
1670 1674 To merge files Mercurial uses merge tools.
1671 1675
1672 1676 A merge tool combines two different versions of a file into a merged file.
1673 1677 Merge tools are given the two files and the greatest common ancestor of
1674 1678 the two file versions, so they can determine the changes made on both
1675 1679 branches.
1676 1680
1677 1681 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1678 1682 backout' and in several extensions.
1679 1683
1680 1684 Usually, the merge tool tries to automatically reconcile the files by
1681 1685 combining all non-overlapping changes that occurred separately in the two
1682 1686 different evolutions of the same initial base file. Furthermore, some
1683 1687 interactive merge programs make it easier to manually resolve conflicting
1684 1688 merges, either in a graphical way, or by inserting some conflict markers.
1685 1689 Mercurial does not include any interactive merge programs but relies on
1686 1690 external tools for that.
1687 1691
1688 1692 Available merge tools
1689 1693 =====================
1690 1694
1691 1695 External merge tools and their properties are configured in the merge-
1692 1696 tools configuration section - see hgrc(5) - but they can often just be
1693 1697 named by their executable.
1694 1698
1695 1699 A merge tool is generally usable if its executable can be found on the
1696 1700 system and if it can handle the merge. The executable is found if it is an
1697 1701 absolute or relative executable path or the name of an application in the
1698 1702 executable search path. The tool is assumed to be able to handle the merge
1699 1703 if it can handle symlinks if the file is a symlink, if it can handle
1700 1704 binary files if the file is binary, and if a GUI is available if the tool
1701 1705 requires a GUI.
1702 1706
1703 1707 There are some internal merge tools which can be used. The internal merge
1704 1708 tools are:
1705 1709
1706 1710 ":dump"
1707 1711 Creates three versions of the files to merge, containing the contents of
1708 1712 local, other and base. These files can then be used to perform a merge
1709 1713 manually. If the file to be merged is named "a.txt", these files will
1710 1714 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1711 1715 they will be placed in the same directory as "a.txt".
1712 1716
1713 1717 ":fail"
1714 1718 Rather than attempting to merge files that were modified on both
1715 1719 branches, it marks them as unresolved. The resolve command must be used
1716 1720 to resolve these conflicts.
1717 1721
1718 1722 ":local"
1719 1723 Uses the local 'p1()' version of files as the merged version.
1720 1724
1721 1725 ":merge"
1722 1726 Uses the internal non-interactive simple merge algorithm for merging
1723 1727 files. It will fail if there are any conflicts and leave markers in the
1724 1728 partially merged file. Markers will have two sections, one for each side
1725 1729 of merge.
1726 1730
1727 1731 ":merge-local"
1728 1732 Like :merge, but resolve all conflicts non-interactively in favor of the
1729 1733 local 'p1()' changes.
1730 1734
1731 1735 ":merge-other"
1732 1736 Like :merge, but resolve all conflicts non-interactively in favor of the
1733 1737 other 'p2()' changes.
1734 1738
1735 1739 ":merge3"
1736 1740 Uses the internal non-interactive simple merge algorithm for merging
1737 1741 files. It will fail if there are any conflicts and leave markers in the
1738 1742 partially merged file. Marker will have three sections, one from each
1739 1743 side of the merge and one for the base content.
1740 1744
1741 1745 ":other"
1742 1746 Uses the other 'p2()' version of files as the merged version.
1743 1747
1744 1748 ":prompt"
1745 1749 Asks the user which of the local 'p1()' or the other 'p2()' version to
1746 1750 keep as the merged version.
1747 1751
1748 1752 ":tagmerge"
1749 1753 Uses the internal tag merge algorithm (experimental).
1750 1754
1751 1755 ":union"
1752 1756 Uses the internal non-interactive simple merge algorithm for merging
1753 1757 files. It will use both left and right sides for conflict regions. No
1754 1758 markers are inserted.
1755 1759
1756 1760 Internal tools are always available and do not require a GUI but will by
1757 1761 default not handle symlinks or binary files.
1758 1762
1759 1763 Choosing a merge tool
1760 1764 =====================
1761 1765
1762 1766 Mercurial uses these rules when deciding which merge tool to use:
1763 1767
1764 1768 1. If a tool has been specified with the --tool option to merge or
1765 1769 resolve, it is used. If it is the name of a tool in the merge-tools
1766 1770 configuration, its configuration is used. Otherwise the specified tool
1767 1771 must be executable by the shell.
1768 1772 2. If the "HGMERGE" environment variable is present, its value is used and
1769 1773 must be executable by the shell.
1770 1774 3. If the filename of the file to be merged matches any of the patterns in
1771 1775 the merge-patterns configuration section, the first usable merge tool
1772 1776 corresponding to a matching pattern is used. Here, binary capabilities
1773 1777 of the merge tool are not considered.
1774 1778 4. If ui.merge is set it will be considered next. If the value is not the
1775 1779 name of a configured tool, the specified value is used and must be
1776 1780 executable by the shell. Otherwise the named tool is used if it is
1777 1781 usable.
1778 1782 5. If any usable merge tools are present in the merge-tools configuration
1779 1783 section, the one with the highest priority is used.
1780 1784 6. If a program named "hgmerge" can be found on the system, it is used -
1781 1785 but it will by default not be used for symlinks and binary files.
1782 1786 7. If the file to be merged is not binary and is not a symlink, then
1783 1787 internal ":merge" is used.
1784 1788 8. The merge of the file fails and must be resolved before commit.
1785 1789
1786 1790 Note:
1787 1791 After selecting a merge program, Mercurial will by default attempt to
1788 1792 merge the files using a simple merge algorithm first. Only if it
1789 1793 doesn't succeed because of conflicting changes Mercurial will actually
1790 1794 execute the merge program. Whether to use the simple merge algorithm
1791 1795 first can be controlled by the premerge setting of the merge tool.
1792 1796 Premerge is enabled by default unless the file is binary or a symlink.
1793 1797
1794 1798 See the merge-tools and ui sections of hgrc(5) for details on the
1795 1799 configuration of merge tools.
1796 1800
1797 1801 Test usage of section marks in help documents
1798 1802
1799 1803 $ cd "$TESTDIR"/../doc
1800 1804 $ python check-seclevel.py
1801 1805 $ cd $TESTTMP
1802 1806
1803 1807 #if serve
1804 1808
1805 1809 Test the help pages in hgweb.
1806 1810
1807 1811 Dish up an empty repo; serve it cold.
1808 1812
1809 1813 $ hg init "$TESTTMP/test"
1810 1814 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
1811 1815 $ cat hg.pid >> $DAEMON_PIDS
1812 1816
1813 1817 $ get-with-headers.py $LOCALIP:$HGPORT "help"
1814 1818 200 Script output follows
1815 1819
1816 1820 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1817 1821 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1818 1822 <head>
1819 1823 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1820 1824 <meta name="robots" content="index, nofollow" />
1821 1825 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1822 1826 <script type="text/javascript" src="/static/mercurial.js"></script>
1823 1827
1824 1828 <title>Help: Index</title>
1825 1829 </head>
1826 1830 <body>
1827 1831
1828 1832 <div class="container">
1829 1833 <div class="menu">
1830 1834 <div class="logo">
1831 1835 <a href="https://mercurial-scm.org/">
1832 1836 <img src="/static/hglogo.png" alt="mercurial" /></a>
1833 1837 </div>
1834 1838 <ul>
1835 1839 <li><a href="/shortlog">log</a></li>
1836 1840 <li><a href="/graph">graph</a></li>
1837 1841 <li><a href="/tags">tags</a></li>
1838 1842 <li><a href="/bookmarks">bookmarks</a></li>
1839 1843 <li><a href="/branches">branches</a></li>
1840 1844 </ul>
1841 1845 <ul>
1842 1846 <li class="active">help</li>
1843 1847 </ul>
1844 1848 </div>
1845 1849
1846 1850 <div class="main">
1847 1851 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1848 1852 <form class="search" action="/log">
1849 1853
1850 1854 <p><input name="rev" id="search1" type="text" size="30" /></p>
1851 1855 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1852 1856 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1853 1857 </form>
1854 1858 <table class="bigtable">
1855 1859 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
1856 1860
1857 1861 <tr><td>
1858 1862 <a href="/help/config">
1859 1863 config
1860 1864 </a>
1861 1865 </td><td>
1862 1866 Configuration Files
1863 1867 </td></tr>
1864 1868 <tr><td>
1865 1869 <a href="/help/dates">
1866 1870 dates
1867 1871 </a>
1868 1872 </td><td>
1869 1873 Date Formats
1870 1874 </td></tr>
1871 1875 <tr><td>
1872 1876 <a href="/help/diffs">
1873 1877 diffs
1874 1878 </a>
1875 1879 </td><td>
1876 1880 Diff Formats
1877 1881 </td></tr>
1878 1882 <tr><td>
1879 1883 <a href="/help/environment">
1880 1884 environment
1881 1885 </a>
1882 1886 </td><td>
1883 1887 Environment Variables
1884 1888 </td></tr>
1885 1889 <tr><td>
1886 1890 <a href="/help/extensions">
1887 1891 extensions
1888 1892 </a>
1889 1893 </td><td>
1890 1894 Using Additional Features
1891 1895 </td></tr>
1892 1896 <tr><td>
1893 1897 <a href="/help/filesets">
1894 1898 filesets
1895 1899 </a>
1896 1900 </td><td>
1897 1901 Specifying File Sets
1898 1902 </td></tr>
1899 1903 <tr><td>
1900 1904 <a href="/help/glossary">
1901 1905 glossary
1902 1906 </a>
1903 1907 </td><td>
1904 1908 Glossary
1905 1909 </td></tr>
1906 1910 <tr><td>
1907 1911 <a href="/help/hgignore">
1908 1912 hgignore
1909 1913 </a>
1910 1914 </td><td>
1911 1915 Syntax for Mercurial Ignore Files
1912 1916 </td></tr>
1913 1917 <tr><td>
1914 1918 <a href="/help/hgweb">
1915 1919 hgweb
1916 1920 </a>
1917 1921 </td><td>
1918 1922 Configuring hgweb
1919 1923 </td></tr>
1920 1924 <tr><td>
1921 1925 <a href="/help/internals">
1922 1926 internals
1923 1927 </a>
1924 1928 </td><td>
1925 1929 Technical implementation topics
1926 1930 </td></tr>
1927 1931 <tr><td>
1928 1932 <a href="/help/merge-tools">
1929 1933 merge-tools
1930 1934 </a>
1931 1935 </td><td>
1932 1936 Merge Tools
1933 1937 </td></tr>
1934 1938 <tr><td>
1935 1939 <a href="/help/pager">
1936 1940 pager
1937 1941 </a>
1938 1942 </td><td>
1939 1943 Pager Support
1940 1944 </td></tr>
1941 1945 <tr><td>
1942 1946 <a href="/help/patterns">
1943 1947 patterns
1944 1948 </a>
1945 1949 </td><td>
1946 1950 File Name Patterns
1947 1951 </td></tr>
1948 1952 <tr><td>
1949 1953 <a href="/help/phases">
1950 1954 phases
1951 1955 </a>
1952 1956 </td><td>
1953 1957 Working with Phases
1954 1958 </td></tr>
1955 1959 <tr><td>
1956 1960 <a href="/help/revisions">
1957 1961 revisions
1958 1962 </a>
1959 1963 </td><td>
1960 1964 Specifying Revisions
1961 1965 </td></tr>
1962 1966 <tr><td>
1963 1967 <a href="/help/scripting">
1964 1968 scripting
1965 1969 </a>
1966 1970 </td><td>
1967 1971 Using Mercurial from scripts and automation
1968 1972 </td></tr>
1969 1973 <tr><td>
1970 1974 <a href="/help/subrepos">
1971 1975 subrepos
1972 1976 </a>
1973 1977 </td><td>
1974 1978 Subrepositories
1975 1979 </td></tr>
1976 1980 <tr><td>
1977 1981 <a href="/help/templating">
1978 1982 templating
1979 1983 </a>
1980 1984 </td><td>
1981 1985 Template Usage
1982 1986 </td></tr>
1983 1987 <tr><td>
1984 1988 <a href="/help/urls">
1985 1989 urls
1986 1990 </a>
1987 1991 </td><td>
1988 1992 URL Paths
1989 1993 </td></tr>
1990 1994 <tr><td>
1991 1995 <a href="/help/topic-containing-verbose">
1992 1996 topic-containing-verbose
1993 1997 </a>
1994 1998 </td><td>
1995 1999 This is the topic to test omit indicating.
1996 2000 </td></tr>
1997 2001
1998 2002
1999 2003 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2000 2004
2001 2005 <tr><td>
2002 2006 <a href="/help/add">
2003 2007 add
2004 2008 </a>
2005 2009 </td><td>
2006 2010 add the specified files on the next commit
2007 2011 </td></tr>
2008 2012 <tr><td>
2009 2013 <a href="/help/annotate">
2010 2014 annotate
2011 2015 </a>
2012 2016 </td><td>
2013 2017 show changeset information by line for each file
2014 2018 </td></tr>
2015 2019 <tr><td>
2016 2020 <a href="/help/clone">
2017 2021 clone
2018 2022 </a>
2019 2023 </td><td>
2020 2024 make a copy of an existing repository
2021 2025 </td></tr>
2022 2026 <tr><td>
2023 2027 <a href="/help/commit">
2024 2028 commit
2025 2029 </a>
2026 2030 </td><td>
2027 2031 commit the specified files or all outstanding changes
2028 2032 </td></tr>
2029 2033 <tr><td>
2030 2034 <a href="/help/diff">
2031 2035 diff
2032 2036 </a>
2033 2037 </td><td>
2034 2038 diff repository (or selected files)
2035 2039 </td></tr>
2036 2040 <tr><td>
2037 2041 <a href="/help/export">
2038 2042 export
2039 2043 </a>
2040 2044 </td><td>
2041 2045 dump the header and diffs for one or more changesets
2042 2046 </td></tr>
2043 2047 <tr><td>
2044 2048 <a href="/help/forget">
2045 2049 forget
2046 2050 </a>
2047 2051 </td><td>
2048 2052 forget the specified files on the next commit
2049 2053 </td></tr>
2050 2054 <tr><td>
2051 2055 <a href="/help/init">
2052 2056 init
2053 2057 </a>
2054 2058 </td><td>
2055 2059 create a new repository in the given directory
2056 2060 </td></tr>
2057 2061 <tr><td>
2058 2062 <a href="/help/log">
2059 2063 log
2060 2064 </a>
2061 2065 </td><td>
2062 2066 show revision history of entire repository or files
2063 2067 </td></tr>
2064 2068 <tr><td>
2065 2069 <a href="/help/merge">
2066 2070 merge
2067 2071 </a>
2068 2072 </td><td>
2069 2073 merge another revision into working directory
2070 2074 </td></tr>
2071 2075 <tr><td>
2072 2076 <a href="/help/pull">
2073 2077 pull
2074 2078 </a>
2075 2079 </td><td>
2076 2080 pull changes from the specified source
2077 2081 </td></tr>
2078 2082 <tr><td>
2079 2083 <a href="/help/push">
2080 2084 push
2081 2085 </a>
2082 2086 </td><td>
2083 2087 push changes to the specified destination
2084 2088 </td></tr>
2085 2089 <tr><td>
2086 2090 <a href="/help/remove">
2087 2091 remove
2088 2092 </a>
2089 2093 </td><td>
2090 2094 remove the specified files on the next commit
2091 2095 </td></tr>
2092 2096 <tr><td>
2093 2097 <a href="/help/serve">
2094 2098 serve
2095 2099 </a>
2096 2100 </td><td>
2097 2101 start stand-alone webserver
2098 2102 </td></tr>
2099 2103 <tr><td>
2100 2104 <a href="/help/status">
2101 2105 status
2102 2106 </a>
2103 2107 </td><td>
2104 2108 show changed files in the working directory
2105 2109 </td></tr>
2106 2110 <tr><td>
2107 2111 <a href="/help/summary">
2108 2112 summary
2109 2113 </a>
2110 2114 </td><td>
2111 2115 summarize working directory state
2112 2116 </td></tr>
2113 2117 <tr><td>
2114 2118 <a href="/help/update">
2115 2119 update
2116 2120 </a>
2117 2121 </td><td>
2118 2122 update working directory (or switch revisions)
2119 2123 </td></tr>
2120 2124
2121 2125
2122 2126
2123 2127 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2124 2128
2125 2129 <tr><td>
2126 2130 <a href="/help/addremove">
2127 2131 addremove
2128 2132 </a>
2129 2133 </td><td>
2130 2134 add all new files, delete all missing files
2131 2135 </td></tr>
2132 2136 <tr><td>
2133 2137 <a href="/help/archive">
2134 2138 archive
2135 2139 </a>
2136 2140 </td><td>
2137 2141 create an unversioned archive of a repository revision
2138 2142 </td></tr>
2139 2143 <tr><td>
2140 2144 <a href="/help/backout">
2141 2145 backout
2142 2146 </a>
2143 2147 </td><td>
2144 2148 reverse effect of earlier changeset
2145 2149 </td></tr>
2146 2150 <tr><td>
2147 2151 <a href="/help/bisect">
2148 2152 bisect
2149 2153 </a>
2150 2154 </td><td>
2151 2155 subdivision search of changesets
2152 2156 </td></tr>
2153 2157 <tr><td>
2154 2158 <a href="/help/bookmarks">
2155 2159 bookmarks
2156 2160 </a>
2157 2161 </td><td>
2158 2162 create a new bookmark or list existing bookmarks
2159 2163 </td></tr>
2160 2164 <tr><td>
2161 2165 <a href="/help/branch">
2162 2166 branch
2163 2167 </a>
2164 2168 </td><td>
2165 2169 set or show the current branch name
2166 2170 </td></tr>
2167 2171 <tr><td>
2168 2172 <a href="/help/branches">
2169 2173 branches
2170 2174 </a>
2171 2175 </td><td>
2172 2176 list repository named branches
2173 2177 </td></tr>
2174 2178 <tr><td>
2175 2179 <a href="/help/bundle">
2176 2180 bundle
2177 2181 </a>
2178 2182 </td><td>
2179 2183 create a changegroup file
2180 2184 </td></tr>
2181 2185 <tr><td>
2182 2186 <a href="/help/cat">
2183 2187 cat
2184 2188 </a>
2185 2189 </td><td>
2186 2190 output the current or given revision of files
2187 2191 </td></tr>
2188 2192 <tr><td>
2189 2193 <a href="/help/config">
2190 2194 config
2191 2195 </a>
2192 2196 </td><td>
2193 2197 show combined config settings from all hgrc files
2194 2198 </td></tr>
2195 2199 <tr><td>
2196 2200 <a href="/help/copy">
2197 2201 copy
2198 2202 </a>
2199 2203 </td><td>
2200 2204 mark files as copied for the next commit
2201 2205 </td></tr>
2202 2206 <tr><td>
2203 2207 <a href="/help/files">
2204 2208 files
2205 2209 </a>
2206 2210 </td><td>
2207 2211 list tracked files
2208 2212 </td></tr>
2209 2213 <tr><td>
2210 2214 <a href="/help/graft">
2211 2215 graft
2212 2216 </a>
2213 2217 </td><td>
2214 2218 copy changes from other branches onto the current branch
2215 2219 </td></tr>
2216 2220 <tr><td>
2217 2221 <a href="/help/grep">
2218 2222 grep
2219 2223 </a>
2220 2224 </td><td>
2221 2225 search revision history for a pattern in specified files
2222 2226 </td></tr>
2223 2227 <tr><td>
2224 2228 <a href="/help/heads">
2225 2229 heads
2226 2230 </a>
2227 2231 </td><td>
2228 2232 show branch heads
2229 2233 </td></tr>
2230 2234 <tr><td>
2231 2235 <a href="/help/help">
2232 2236 help
2233 2237 </a>
2234 2238 </td><td>
2235 2239 show help for a given topic or a help overview
2236 2240 </td></tr>
2237 2241 <tr><td>
2238 2242 <a href="/help/hgalias">
2239 2243 hgalias
2240 2244 </a>
2241 2245 </td><td>
2242 2246 summarize working directory state
2243 2247 </td></tr>
2244 2248 <tr><td>
2245 2249 <a href="/help/identify">
2246 2250 identify
2247 2251 </a>
2248 2252 </td><td>
2249 2253 identify the working directory or specified revision
2250 2254 </td></tr>
2251 2255 <tr><td>
2252 2256 <a href="/help/import">
2253 2257 import
2254 2258 </a>
2255 2259 </td><td>
2256 2260 import an ordered set of patches
2257 2261 </td></tr>
2258 2262 <tr><td>
2259 2263 <a href="/help/incoming">
2260 2264 incoming
2261 2265 </a>
2262 2266 </td><td>
2263 2267 show new changesets found in source
2264 2268 </td></tr>
2265 2269 <tr><td>
2266 2270 <a href="/help/manifest">
2267 2271 manifest
2268 2272 </a>
2269 2273 </td><td>
2270 2274 output the current or given revision of the project manifest
2271 2275 </td></tr>
2272 2276 <tr><td>
2273 2277 <a href="/help/nohelp">
2274 2278 nohelp
2275 2279 </a>
2276 2280 </td><td>
2277 2281 (no help text available)
2278 2282 </td></tr>
2279 2283 <tr><td>
2280 2284 <a href="/help/outgoing">
2281 2285 outgoing
2282 2286 </a>
2283 2287 </td><td>
2284 2288 show changesets not found in the destination
2285 2289 </td></tr>
2286 2290 <tr><td>
2287 2291 <a href="/help/paths">
2288 2292 paths
2289 2293 </a>
2290 2294 </td><td>
2291 2295 show aliases for remote repositories
2292 2296 </td></tr>
2293 2297 <tr><td>
2294 2298 <a href="/help/phase">
2295 2299 phase
2296 2300 </a>
2297 2301 </td><td>
2298 2302 set or show the current phase name
2299 2303 </td></tr>
2300 2304 <tr><td>
2301 2305 <a href="/help/recover">
2302 2306 recover
2303 2307 </a>
2304 2308 </td><td>
2305 2309 roll back an interrupted transaction
2306 2310 </td></tr>
2307 2311 <tr><td>
2308 2312 <a href="/help/rename">
2309 2313 rename
2310 2314 </a>
2311 2315 </td><td>
2312 2316 rename files; equivalent of copy + remove
2313 2317 </td></tr>
2314 2318 <tr><td>
2315 2319 <a href="/help/resolve">
2316 2320 resolve
2317 2321 </a>
2318 2322 </td><td>
2319 2323 redo merges or set/view the merge status of files
2320 2324 </td></tr>
2321 2325 <tr><td>
2322 2326 <a href="/help/revert">
2323 2327 revert
2324 2328 </a>
2325 2329 </td><td>
2326 2330 restore files to their checkout state
2327 2331 </td></tr>
2328 2332 <tr><td>
2329 2333 <a href="/help/root">
2330 2334 root
2331 2335 </a>
2332 2336 </td><td>
2333 2337 print the root (top) of the current working directory
2334 2338 </td></tr>
2335 2339 <tr><td>
2336 2340 <a href="/help/shellalias">
2337 2341 shellalias
2338 2342 </a>
2339 2343 </td><td>
2340 2344 (no help text available)
2341 2345 </td></tr>
2342 2346 <tr><td>
2343 2347 <a href="/help/tag">
2344 2348 tag
2345 2349 </a>
2346 2350 </td><td>
2347 2351 add one or more tags for the current or given revision
2348 2352 </td></tr>
2349 2353 <tr><td>
2350 2354 <a href="/help/tags">
2351 2355 tags
2352 2356 </a>
2353 2357 </td><td>
2354 2358 list repository tags
2355 2359 </td></tr>
2356 2360 <tr><td>
2357 2361 <a href="/help/unbundle">
2358 2362 unbundle
2359 2363 </a>
2360 2364 </td><td>
2361 2365 apply one or more changegroup files
2362 2366 </td></tr>
2363 2367 <tr><td>
2364 2368 <a href="/help/verify">
2365 2369 verify
2366 2370 </a>
2367 2371 </td><td>
2368 2372 verify the integrity of the repository
2369 2373 </td></tr>
2370 2374 <tr><td>
2371 2375 <a href="/help/version">
2372 2376 version
2373 2377 </a>
2374 2378 </td><td>
2375 2379 output version and copyright information
2376 2380 </td></tr>
2377 2381
2378 2382
2379 2383 </table>
2380 2384 </div>
2381 2385 </div>
2382 2386
2383 2387
2384 2388
2385 2389 </body>
2386 2390 </html>
2387 2391
2388 2392
2389 2393 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2390 2394 200 Script output follows
2391 2395
2392 2396 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2393 2397 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2394 2398 <head>
2395 2399 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2396 2400 <meta name="robots" content="index, nofollow" />
2397 2401 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2398 2402 <script type="text/javascript" src="/static/mercurial.js"></script>
2399 2403
2400 2404 <title>Help: add</title>
2401 2405 </head>
2402 2406 <body>
2403 2407
2404 2408 <div class="container">
2405 2409 <div class="menu">
2406 2410 <div class="logo">
2407 2411 <a href="https://mercurial-scm.org/">
2408 2412 <img src="/static/hglogo.png" alt="mercurial" /></a>
2409 2413 </div>
2410 2414 <ul>
2411 2415 <li><a href="/shortlog">log</a></li>
2412 2416 <li><a href="/graph">graph</a></li>
2413 2417 <li><a href="/tags">tags</a></li>
2414 2418 <li><a href="/bookmarks">bookmarks</a></li>
2415 2419 <li><a href="/branches">branches</a></li>
2416 2420 </ul>
2417 2421 <ul>
2418 2422 <li class="active"><a href="/help">help</a></li>
2419 2423 </ul>
2420 2424 </div>
2421 2425
2422 2426 <div class="main">
2423 2427 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2424 2428 <h3>Help: add</h3>
2425 2429
2426 2430 <form class="search" action="/log">
2427 2431
2428 2432 <p><input name="rev" id="search1" type="text" size="30" /></p>
2429 2433 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2430 2434 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2431 2435 </form>
2432 2436 <div id="doc">
2433 2437 <p>
2434 2438 hg add [OPTION]... [FILE]...
2435 2439 </p>
2436 2440 <p>
2437 2441 add the specified files on the next commit
2438 2442 </p>
2439 2443 <p>
2440 2444 Schedule files to be version controlled and added to the
2441 2445 repository.
2442 2446 </p>
2443 2447 <p>
2444 2448 The files will be added to the repository at the next commit. To
2445 2449 undo an add before that, see 'hg forget'.
2446 2450 </p>
2447 2451 <p>
2448 2452 If no names are given, add all files to the repository (except
2449 2453 files matching &quot;.hgignore&quot;).
2450 2454 </p>
2451 2455 <p>
2452 2456 Examples:
2453 2457 </p>
2454 2458 <ul>
2455 2459 <li> New (unknown) files are added automatically by 'hg add':
2456 2460 <pre>
2457 2461 \$ ls (re)
2458 2462 foo.c
2459 2463 \$ hg status (re)
2460 2464 ? foo.c
2461 2465 \$ hg add (re)
2462 2466 adding foo.c
2463 2467 \$ hg status (re)
2464 2468 A foo.c
2465 2469 </pre>
2466 2470 <li> Specific files to be added can be specified:
2467 2471 <pre>
2468 2472 \$ ls (re)
2469 2473 bar.c foo.c
2470 2474 \$ hg status (re)
2471 2475 ? bar.c
2472 2476 ? foo.c
2473 2477 \$ hg add bar.c (re)
2474 2478 \$ hg status (re)
2475 2479 A bar.c
2476 2480 ? foo.c
2477 2481 </pre>
2478 2482 </ul>
2479 2483 <p>
2480 2484 Returns 0 if all files are successfully added.
2481 2485 </p>
2482 2486 <p>
2483 2487 options ([+] can be repeated):
2484 2488 </p>
2485 2489 <table>
2486 2490 <tr><td>-I</td>
2487 2491 <td>--include PATTERN [+]</td>
2488 2492 <td>include names matching the given patterns</td></tr>
2489 2493 <tr><td>-X</td>
2490 2494 <td>--exclude PATTERN [+]</td>
2491 2495 <td>exclude names matching the given patterns</td></tr>
2492 2496 <tr><td>-S</td>
2493 2497 <td>--subrepos</td>
2494 2498 <td>recurse into subrepositories</td></tr>
2495 2499 <tr><td>-n</td>
2496 2500 <td>--dry-run</td>
2497 2501 <td>do not perform actions, just print output</td></tr>
2498 2502 </table>
2499 2503 <p>
2500 2504 global options ([+] can be repeated):
2501 2505 </p>
2502 2506 <table>
2503 2507 <tr><td>-R</td>
2504 2508 <td>--repository REPO</td>
2505 2509 <td>repository root directory or name of overlay bundle file</td></tr>
2506 2510 <tr><td></td>
2507 2511 <td>--cwd DIR</td>
2508 2512 <td>change working directory</td></tr>
2509 2513 <tr><td>-y</td>
2510 2514 <td>--noninteractive</td>
2511 2515 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2512 2516 <tr><td>-q</td>
2513 2517 <td>--quiet</td>
2514 2518 <td>suppress output</td></tr>
2515 2519 <tr><td>-v</td>
2516 2520 <td>--verbose</td>
2517 2521 <td>enable additional output</td></tr>
2518 2522 <tr><td></td>
2523 <td>--color TYPE</td>
2524 <td>when to colorize (boolean, always, auto, never, or debug) (EXPERIMENTAL) (default: never)</td></tr>
2525 <tr><td></td>
2519 2526 <td>--config CONFIG [+]</td>
2520 2527 <td>set/override config option (use 'section.name=value')</td></tr>
2521 2528 <tr><td></td>
2522 2529 <td>--debug</td>
2523 2530 <td>enable debugging output</td></tr>
2524 2531 <tr><td></td>
2525 2532 <td>--debugger</td>
2526 2533 <td>start debugger</td></tr>
2527 2534 <tr><td></td>
2528 2535 <td>--encoding ENCODE</td>
2529 2536 <td>set the charset encoding (default: ascii)</td></tr>
2530 2537 <tr><td></td>
2531 2538 <td>--encodingmode MODE</td>
2532 2539 <td>set the charset encoding mode (default: strict)</td></tr>
2533 2540 <tr><td></td>
2534 2541 <td>--traceback</td>
2535 2542 <td>always print a traceback on exception</td></tr>
2536 2543 <tr><td></td>
2537 2544 <td>--time</td>
2538 2545 <td>time how long the command takes</td></tr>
2539 2546 <tr><td></td>
2540 2547 <td>--profile</td>
2541 2548 <td>print command execution profile</td></tr>
2542 2549 <tr><td></td>
2543 2550 <td>--version</td>
2544 2551 <td>output version information and exit</td></tr>
2545 2552 <tr><td>-h</td>
2546 2553 <td>--help</td>
2547 2554 <td>display help and exit</td></tr>
2548 2555 <tr><td></td>
2549 2556 <td>--hidden</td>
2550 2557 <td>consider hidden changesets</td></tr>
2551 2558 <tr><td></td>
2552 2559 <td>--pager TYPE</td>
2553 2560 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2554 2561 </table>
2555 2562
2556 2563 </div>
2557 2564 </div>
2558 2565 </div>
2559 2566
2560 2567
2561 2568
2562 2569 </body>
2563 2570 </html>
2564 2571
2565 2572
2566 2573 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2567 2574 200 Script output follows
2568 2575
2569 2576 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2570 2577 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2571 2578 <head>
2572 2579 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2573 2580 <meta name="robots" content="index, nofollow" />
2574 2581 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2575 2582 <script type="text/javascript" src="/static/mercurial.js"></script>
2576 2583
2577 2584 <title>Help: remove</title>
2578 2585 </head>
2579 2586 <body>
2580 2587
2581 2588 <div class="container">
2582 2589 <div class="menu">
2583 2590 <div class="logo">
2584 2591 <a href="https://mercurial-scm.org/">
2585 2592 <img src="/static/hglogo.png" alt="mercurial" /></a>
2586 2593 </div>
2587 2594 <ul>
2588 2595 <li><a href="/shortlog">log</a></li>
2589 2596 <li><a href="/graph">graph</a></li>
2590 2597 <li><a href="/tags">tags</a></li>
2591 2598 <li><a href="/bookmarks">bookmarks</a></li>
2592 2599 <li><a href="/branches">branches</a></li>
2593 2600 </ul>
2594 2601 <ul>
2595 2602 <li class="active"><a href="/help">help</a></li>
2596 2603 </ul>
2597 2604 </div>
2598 2605
2599 2606 <div class="main">
2600 2607 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2601 2608 <h3>Help: remove</h3>
2602 2609
2603 2610 <form class="search" action="/log">
2604 2611
2605 2612 <p><input name="rev" id="search1" type="text" size="30" /></p>
2606 2613 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2607 2614 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2608 2615 </form>
2609 2616 <div id="doc">
2610 2617 <p>
2611 2618 hg remove [OPTION]... FILE...
2612 2619 </p>
2613 2620 <p>
2614 2621 aliases: rm
2615 2622 </p>
2616 2623 <p>
2617 2624 remove the specified files on the next commit
2618 2625 </p>
2619 2626 <p>
2620 2627 Schedule the indicated files for removal from the current branch.
2621 2628 </p>
2622 2629 <p>
2623 2630 This command schedules the files to be removed at the next commit.
2624 2631 To undo a remove before that, see 'hg revert'. To undo added
2625 2632 files, see 'hg forget'.
2626 2633 </p>
2627 2634 <p>
2628 2635 -A/--after can be used to remove only files that have already
2629 2636 been deleted, -f/--force can be used to force deletion, and -Af
2630 2637 can be used to remove files from the next revision without
2631 2638 deleting them from the working directory.
2632 2639 </p>
2633 2640 <p>
2634 2641 The following table details the behavior of remove for different
2635 2642 file states (columns) and option combinations (rows). The file
2636 2643 states are Added [A], Clean [C], Modified [M] and Missing [!]
2637 2644 (as reported by 'hg status'). The actions are Warn, Remove
2638 2645 (from branch) and Delete (from disk):
2639 2646 </p>
2640 2647 <table>
2641 2648 <tr><td>opt/state</td>
2642 2649 <td>A</td>
2643 2650 <td>C</td>
2644 2651 <td>M</td>
2645 2652 <td>!</td></tr>
2646 2653 <tr><td>none</td>
2647 2654 <td>W</td>
2648 2655 <td>RD</td>
2649 2656 <td>W</td>
2650 2657 <td>R</td></tr>
2651 2658 <tr><td>-f</td>
2652 2659 <td>R</td>
2653 2660 <td>RD</td>
2654 2661 <td>RD</td>
2655 2662 <td>R</td></tr>
2656 2663 <tr><td>-A</td>
2657 2664 <td>W</td>
2658 2665 <td>W</td>
2659 2666 <td>W</td>
2660 2667 <td>R</td></tr>
2661 2668 <tr><td>-Af</td>
2662 2669 <td>R</td>
2663 2670 <td>R</td>
2664 2671 <td>R</td>
2665 2672 <td>R</td></tr>
2666 2673 </table>
2667 2674 <p>
2668 2675 <b>Note:</b>
2669 2676 </p>
2670 2677 <p>
2671 2678 'hg remove' never deletes files in Added [A] state from the
2672 2679 working directory, not even if &quot;--force&quot; is specified.
2673 2680 </p>
2674 2681 <p>
2675 2682 Returns 0 on success, 1 if any warnings encountered.
2676 2683 </p>
2677 2684 <p>
2678 2685 options ([+] can be repeated):
2679 2686 </p>
2680 2687 <table>
2681 2688 <tr><td>-A</td>
2682 2689 <td>--after</td>
2683 2690 <td>record delete for missing files</td></tr>
2684 2691 <tr><td>-f</td>
2685 2692 <td>--force</td>
2686 2693 <td>forget added files, delete modified files</td></tr>
2687 2694 <tr><td>-S</td>
2688 2695 <td>--subrepos</td>
2689 2696 <td>recurse into subrepositories</td></tr>
2690 2697 <tr><td>-I</td>
2691 2698 <td>--include PATTERN [+]</td>
2692 2699 <td>include names matching the given patterns</td></tr>
2693 2700 <tr><td>-X</td>
2694 2701 <td>--exclude PATTERN [+]</td>
2695 2702 <td>exclude names matching the given patterns</td></tr>
2696 2703 </table>
2697 2704 <p>
2698 2705 global options ([+] can be repeated):
2699 2706 </p>
2700 2707 <table>
2701 2708 <tr><td>-R</td>
2702 2709 <td>--repository REPO</td>
2703 2710 <td>repository root directory or name of overlay bundle file</td></tr>
2704 2711 <tr><td></td>
2705 2712 <td>--cwd DIR</td>
2706 2713 <td>change working directory</td></tr>
2707 2714 <tr><td>-y</td>
2708 2715 <td>--noninteractive</td>
2709 2716 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2710 2717 <tr><td>-q</td>
2711 2718 <td>--quiet</td>
2712 2719 <td>suppress output</td></tr>
2713 2720 <tr><td>-v</td>
2714 2721 <td>--verbose</td>
2715 2722 <td>enable additional output</td></tr>
2716 2723 <tr><td></td>
2724 <td>--color TYPE</td>
2725 <td>when to colorize (boolean, always, auto, never, or debug) (EXPERIMENTAL) (default: never)</td></tr>
2726 <tr><td></td>
2717 2727 <td>--config CONFIG [+]</td>
2718 2728 <td>set/override config option (use 'section.name=value')</td></tr>
2719 2729 <tr><td></td>
2720 2730 <td>--debug</td>
2721 2731 <td>enable debugging output</td></tr>
2722 2732 <tr><td></td>
2723 2733 <td>--debugger</td>
2724 2734 <td>start debugger</td></tr>
2725 2735 <tr><td></td>
2726 2736 <td>--encoding ENCODE</td>
2727 2737 <td>set the charset encoding (default: ascii)</td></tr>
2728 2738 <tr><td></td>
2729 2739 <td>--encodingmode MODE</td>
2730 2740 <td>set the charset encoding mode (default: strict)</td></tr>
2731 2741 <tr><td></td>
2732 2742 <td>--traceback</td>
2733 2743 <td>always print a traceback on exception</td></tr>
2734 2744 <tr><td></td>
2735 2745 <td>--time</td>
2736 2746 <td>time how long the command takes</td></tr>
2737 2747 <tr><td></td>
2738 2748 <td>--profile</td>
2739 2749 <td>print command execution profile</td></tr>
2740 2750 <tr><td></td>
2741 2751 <td>--version</td>
2742 2752 <td>output version information and exit</td></tr>
2743 2753 <tr><td>-h</td>
2744 2754 <td>--help</td>
2745 2755 <td>display help and exit</td></tr>
2746 2756 <tr><td></td>
2747 2757 <td>--hidden</td>
2748 2758 <td>consider hidden changesets</td></tr>
2749 2759 <tr><td></td>
2750 2760 <td>--pager TYPE</td>
2751 2761 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2752 2762 </table>
2753 2763
2754 2764 </div>
2755 2765 </div>
2756 2766 </div>
2757 2767
2758 2768
2759 2769
2760 2770 </body>
2761 2771 </html>
2762 2772
2763 2773
2764 2774 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
2765 2775 200 Script output follows
2766 2776
2767 2777 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2768 2778 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2769 2779 <head>
2770 2780 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2771 2781 <meta name="robots" content="index, nofollow" />
2772 2782 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2773 2783 <script type="text/javascript" src="/static/mercurial.js"></script>
2774 2784
2775 2785 <title>Help: dates</title>
2776 2786 </head>
2777 2787 <body>
2778 2788
2779 2789 <div class="container">
2780 2790 <div class="menu">
2781 2791 <div class="logo">
2782 2792 <a href="https://mercurial-scm.org/">
2783 2793 <img src="/static/hglogo.png" alt="mercurial" /></a>
2784 2794 </div>
2785 2795 <ul>
2786 2796 <li><a href="/shortlog">log</a></li>
2787 2797 <li><a href="/graph">graph</a></li>
2788 2798 <li><a href="/tags">tags</a></li>
2789 2799 <li><a href="/bookmarks">bookmarks</a></li>
2790 2800 <li><a href="/branches">branches</a></li>
2791 2801 </ul>
2792 2802 <ul>
2793 2803 <li class="active"><a href="/help">help</a></li>
2794 2804 </ul>
2795 2805 </div>
2796 2806
2797 2807 <div class="main">
2798 2808 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2799 2809 <h3>Help: dates</h3>
2800 2810
2801 2811 <form class="search" action="/log">
2802 2812
2803 2813 <p><input name="rev" id="search1" type="text" size="30" /></p>
2804 2814 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2805 2815 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2806 2816 </form>
2807 2817 <div id="doc">
2808 2818 <h1>Date Formats</h1>
2809 2819 <p>
2810 2820 Some commands allow the user to specify a date, e.g.:
2811 2821 </p>
2812 2822 <ul>
2813 2823 <li> backout, commit, import, tag: Specify the commit date.
2814 2824 <li> log, revert, update: Select revision(s) by date.
2815 2825 </ul>
2816 2826 <p>
2817 2827 Many date formats are valid. Here are some examples:
2818 2828 </p>
2819 2829 <ul>
2820 2830 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
2821 2831 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
2822 2832 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
2823 2833 <li> &quot;Dec 6&quot; (midnight)
2824 2834 <li> &quot;13:18&quot; (today assumed)
2825 2835 <li> &quot;3:39&quot; (3:39AM assumed)
2826 2836 <li> &quot;3:39pm&quot; (15:39)
2827 2837 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
2828 2838 <li> &quot;2006-12-6 13:18&quot;
2829 2839 <li> &quot;2006-12-6&quot;
2830 2840 <li> &quot;12-6&quot;
2831 2841 <li> &quot;12/6&quot;
2832 2842 <li> &quot;12/6/6&quot; (Dec 6 2006)
2833 2843 <li> &quot;today&quot; (midnight)
2834 2844 <li> &quot;yesterday&quot; (midnight)
2835 2845 <li> &quot;now&quot; - right now
2836 2846 </ul>
2837 2847 <p>
2838 2848 Lastly, there is Mercurial's internal format:
2839 2849 </p>
2840 2850 <ul>
2841 2851 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
2842 2852 </ul>
2843 2853 <p>
2844 2854 This is the internal representation format for dates. The first number
2845 2855 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
2846 2856 second is the offset of the local timezone, in seconds west of UTC
2847 2857 (negative if the timezone is east of UTC).
2848 2858 </p>
2849 2859 <p>
2850 2860 The log command also accepts date ranges:
2851 2861 </p>
2852 2862 <ul>
2853 2863 <li> &quot;&lt;DATE&quot; - at or before a given date/time
2854 2864 <li> &quot;&gt;DATE&quot; - on or after a given date/time
2855 2865 <li> &quot;DATE to DATE&quot; - a date range, inclusive
2856 2866 <li> &quot;-DAYS&quot; - within a given number of days of today
2857 2867 </ul>
2858 2868
2859 2869 </div>
2860 2870 </div>
2861 2871 </div>
2862 2872
2863 2873
2864 2874
2865 2875 </body>
2866 2876 </html>
2867 2877
2868 2878
2869 2879 Sub-topic indexes rendered properly
2870 2880
2871 2881 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
2872 2882 200 Script output follows
2873 2883
2874 2884 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2875 2885 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2876 2886 <head>
2877 2887 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2878 2888 <meta name="robots" content="index, nofollow" />
2879 2889 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2880 2890 <script type="text/javascript" src="/static/mercurial.js"></script>
2881 2891
2882 2892 <title>Help: internals</title>
2883 2893 </head>
2884 2894 <body>
2885 2895
2886 2896 <div class="container">
2887 2897 <div class="menu">
2888 2898 <div class="logo">
2889 2899 <a href="https://mercurial-scm.org/">
2890 2900 <img src="/static/hglogo.png" alt="mercurial" /></a>
2891 2901 </div>
2892 2902 <ul>
2893 2903 <li><a href="/shortlog">log</a></li>
2894 2904 <li><a href="/graph">graph</a></li>
2895 2905 <li><a href="/tags">tags</a></li>
2896 2906 <li><a href="/bookmarks">bookmarks</a></li>
2897 2907 <li><a href="/branches">branches</a></li>
2898 2908 </ul>
2899 2909 <ul>
2900 2910 <li><a href="/help">help</a></li>
2901 2911 </ul>
2902 2912 </div>
2903 2913
2904 2914 <div class="main">
2905 2915 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2906 2916 <form class="search" action="/log">
2907 2917
2908 2918 <p><input name="rev" id="search1" type="text" size="30" /></p>
2909 2919 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2910 2920 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2911 2921 </form>
2912 2922 <table class="bigtable">
2913 2923 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2914 2924
2915 2925 <tr><td>
2916 2926 <a href="/help/internals.bundles">
2917 2927 bundles
2918 2928 </a>
2919 2929 </td><td>
2920 2930 Bundles
2921 2931 </td></tr>
2922 2932 <tr><td>
2923 2933 <a href="/help/internals.changegroups">
2924 2934 changegroups
2925 2935 </a>
2926 2936 </td><td>
2927 2937 Changegroups
2928 2938 </td></tr>
2929 2939 <tr><td>
2930 2940 <a href="/help/internals.requirements">
2931 2941 requirements
2932 2942 </a>
2933 2943 </td><td>
2934 2944 Repository Requirements
2935 2945 </td></tr>
2936 2946 <tr><td>
2937 2947 <a href="/help/internals.revlogs">
2938 2948 revlogs
2939 2949 </a>
2940 2950 </td><td>
2941 2951 Revision Logs
2942 2952 </td></tr>
2943 2953 <tr><td>
2944 2954 <a href="/help/internals.wireprotocol">
2945 2955 wireprotocol
2946 2956 </a>
2947 2957 </td><td>
2948 2958 Wire Protocol
2949 2959 </td></tr>
2950 2960
2951 2961
2952 2962
2953 2963
2954 2964
2955 2965 </table>
2956 2966 </div>
2957 2967 </div>
2958 2968
2959 2969
2960 2970
2961 2971 </body>
2962 2972 </html>
2963 2973
2964 2974
2965 2975 Sub-topic topics rendered properly
2966 2976
2967 2977 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
2968 2978 200 Script output follows
2969 2979
2970 2980 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2971 2981 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2972 2982 <head>
2973 2983 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2974 2984 <meta name="robots" content="index, nofollow" />
2975 2985 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2976 2986 <script type="text/javascript" src="/static/mercurial.js"></script>
2977 2987
2978 2988 <title>Help: internals.changegroups</title>
2979 2989 </head>
2980 2990 <body>
2981 2991
2982 2992 <div class="container">
2983 2993 <div class="menu">
2984 2994 <div class="logo">
2985 2995 <a href="https://mercurial-scm.org/">
2986 2996 <img src="/static/hglogo.png" alt="mercurial" /></a>
2987 2997 </div>
2988 2998 <ul>
2989 2999 <li><a href="/shortlog">log</a></li>
2990 3000 <li><a href="/graph">graph</a></li>
2991 3001 <li><a href="/tags">tags</a></li>
2992 3002 <li><a href="/bookmarks">bookmarks</a></li>
2993 3003 <li><a href="/branches">branches</a></li>
2994 3004 </ul>
2995 3005 <ul>
2996 3006 <li class="active"><a href="/help">help</a></li>
2997 3007 </ul>
2998 3008 </div>
2999 3009
3000 3010 <div class="main">
3001 3011 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3002 3012 <h3>Help: internals.changegroups</h3>
3003 3013
3004 3014 <form class="search" action="/log">
3005 3015
3006 3016 <p><input name="rev" id="search1" type="text" size="30" /></p>
3007 3017 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3008 3018 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3009 3019 </form>
3010 3020 <div id="doc">
3011 3021 <h1>Changegroups</h1>
3012 3022 <p>
3013 3023 Changegroups are representations of repository revlog data, specifically
3014 3024 the changelog, manifest, and filelogs.
3015 3025 </p>
3016 3026 <p>
3017 3027 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3018 3028 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with
3019 3029 the only difference being a header on entries in the changeset
3020 3030 segment. Version &quot;3&quot; adds support for exchanging treemanifests and
3021 3031 includes revlog flags in the delta header.
3022 3032 </p>
3023 3033 <p>
3024 3034 Changegroups consists of 3 logical segments:
3025 3035 </p>
3026 3036 <pre>
3027 3037 +---------------------------------+
3028 3038 | | | |
3029 3039 | changeset | manifest | filelogs |
3030 3040 | | | |
3031 3041 +---------------------------------+
3032 3042 </pre>
3033 3043 <p>
3034 3044 The principle building block of each segment is a *chunk*. A *chunk*
3035 3045 is a framed piece of data:
3036 3046 </p>
3037 3047 <pre>
3038 3048 +---------------------------------------+
3039 3049 | | |
3040 3050 | length | data |
3041 3051 | (32 bits) | &lt;length&gt; bytes |
3042 3052 | | |
3043 3053 +---------------------------------------+
3044 3054 </pre>
3045 3055 <p>
3046 3056 Each chunk starts with a 32-bit big-endian signed integer indicating
3047 3057 the length of the raw data that follows.
3048 3058 </p>
3049 3059 <p>
3050 3060 There is a special case chunk that has 0 length (&quot;0x00000000&quot;). We
3051 3061 call this an *empty chunk*.
3052 3062 </p>
3053 3063 <h2>Delta Groups</h2>
3054 3064 <p>
3055 3065 A *delta group* expresses the content of a revlog as a series of deltas,
3056 3066 or patches against previous revisions.
3057 3067 </p>
3058 3068 <p>
3059 3069 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3060 3070 to signal the end of the delta group:
3061 3071 </p>
3062 3072 <pre>
3063 3073 +------------------------------------------------------------------------+
3064 3074 | | | | | |
3065 3075 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3066 3076 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
3067 3077 | | | | | |
3068 3078 +------------------------------------------------------------+-----------+
3069 3079 </pre>
3070 3080 <p>
3071 3081 Each *chunk*'s data consists of the following:
3072 3082 </p>
3073 3083 <pre>
3074 3084 +-----------------------------------------+
3075 3085 | | | |
3076 3086 | delta header | mdiff header | delta |
3077 3087 | (various) | (12 bytes) | (various) |
3078 3088 | | | |
3079 3089 +-----------------------------------------+
3080 3090 </pre>
3081 3091 <p>
3082 3092 The *length* field is the byte length of the remaining 3 logical pieces
3083 3093 of data. The *delta* is a diff from an existing entry in the changelog.
3084 3094 </p>
3085 3095 <p>
3086 3096 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3087 3097 &quot;3&quot; of the changegroup format.
3088 3098 </p>
3089 3099 <p>
3090 3100 Version 1:
3091 3101 </p>
3092 3102 <pre>
3093 3103 +------------------------------------------------------+
3094 3104 | | | | |
3095 3105 | node | p1 node | p2 node | link node |
3096 3106 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3097 3107 | | | | |
3098 3108 +------------------------------------------------------+
3099 3109 </pre>
3100 3110 <p>
3101 3111 Version 2:
3102 3112 </p>
3103 3113 <pre>
3104 3114 +------------------------------------------------------------------+
3105 3115 | | | | | |
3106 3116 | node | p1 node | p2 node | base node | link node |
3107 3117 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3108 3118 | | | | | |
3109 3119 +------------------------------------------------------------------+
3110 3120 </pre>
3111 3121 <p>
3112 3122 Version 3:
3113 3123 </p>
3114 3124 <pre>
3115 3125 +------------------------------------------------------------------------------+
3116 3126 | | | | | | |
3117 3127 | node | p1 node | p2 node | base node | link node | flags |
3118 3128 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3119 3129 | | | | | | |
3120 3130 +------------------------------------------------------------------------------+
3121 3131 </pre>
3122 3132 <p>
3123 3133 The *mdiff header* consists of 3 32-bit big-endian signed integers
3124 3134 describing offsets at which to apply the following delta content:
3125 3135 </p>
3126 3136 <pre>
3127 3137 +-------------------------------------+
3128 3138 | | | |
3129 3139 | offset | old length | new length |
3130 3140 | (32 bits) | (32 bits) | (32 bits) |
3131 3141 | | | |
3132 3142 +-------------------------------------+
3133 3143 </pre>
3134 3144 <p>
3135 3145 In version 1, the delta is always applied against the previous node from
3136 3146 the changegroup or the first parent if this is the first entry in the
3137 3147 changegroup.
3138 3148 </p>
3139 3149 <p>
3140 3150 In version 2, the delta base node is encoded in the entry in the
3141 3151 changegroup. This allows the delta to be expressed against any parent,
3142 3152 which can result in smaller deltas and more efficient encoding of data.
3143 3153 </p>
3144 3154 <h2>Changeset Segment</h2>
3145 3155 <p>
3146 3156 The *changeset segment* consists of a single *delta group* holding
3147 3157 changelog data. It is followed by an *empty chunk* to denote the
3148 3158 boundary to the *manifests segment*.
3149 3159 </p>
3150 3160 <h2>Manifest Segment</h2>
3151 3161 <p>
3152 3162 The *manifest segment* consists of a single *delta group* holding
3153 3163 manifest data. It is followed by an *empty chunk* to denote the boundary
3154 3164 to the *filelogs segment*.
3155 3165 </p>
3156 3166 <h2>Filelogs Segment</h2>
3157 3167 <p>
3158 3168 The *filelogs* segment consists of multiple sub-segments, each
3159 3169 corresponding to an individual file whose data is being described:
3160 3170 </p>
3161 3171 <pre>
3162 3172 +--------------------------------------+
3163 3173 | | | | |
3164 3174 | filelog0 | filelog1 | filelog2 | ... |
3165 3175 | | | | |
3166 3176 +--------------------------------------+
3167 3177 </pre>
3168 3178 <p>
3169 3179 In version &quot;3&quot; of the changegroup format, filelogs may include
3170 3180 directory logs when treemanifests are in use. directory logs are
3171 3181 identified by having a trailing '/' on their filename (see below).
3172 3182 </p>
3173 3183 <p>
3174 3184 The final filelog sub-segment is followed by an *empty chunk* to denote
3175 3185 the end of the segment and the overall changegroup.
3176 3186 </p>
3177 3187 <p>
3178 3188 Each filelog sub-segment consists of the following:
3179 3189 </p>
3180 3190 <pre>
3181 3191 +------------------------------------------+
3182 3192 | | | |
3183 3193 | filename size | filename | delta group |
3184 3194 | (32 bits) | (various) | (various) |
3185 3195 | | | |
3186 3196 +------------------------------------------+
3187 3197 </pre>
3188 3198 <p>
3189 3199 That is, a *chunk* consisting of the filename (not terminated or padded)
3190 3200 followed by N chunks constituting the *delta group* for this file.
3191 3201 </p>
3192 3202
3193 3203 </div>
3194 3204 </div>
3195 3205 </div>
3196 3206
3197 3207
3198 3208
3199 3209 </body>
3200 3210 </html>
3201 3211
3202 3212
3203 3213 $ killdaemons.py
3204 3214
3205 3215 #endif
General Comments 0
You need to be logged in to leave comments. Login now